aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-03-16 20:47:45 +0000
committerChris Lattner <sabre@nondot.org>2008-03-16 20:47:45 +0000
commit68c82cf61228102aba1194efef222fa1478af2a8 (patch)
tree494b30fcfa056a98dd5c9958661d1529da69fc9e
parent61f9d41036e30ff80130f99b31c0626e3ef057cc (diff)
simplify the way ObjCCategoryDecl's get their referenced protocols list
specified. Previously, the ctor would allocate memory for the list and then it would get filled in later. Move the allocation+filling in to be more consistent with other stuff, e.g. the addMethods method. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48427 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/DeclObjC.h29
-rw-r--r--lib/AST/DeclObjC.cpp14
-rw-r--r--lib/Sema/SemaDeclObjC.cpp13
3 files changed, 32 insertions, 24 deletions
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index a01d62b6e0..35bc0146d0 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -610,14 +610,14 @@ public:
/// several files (a feature more naturally supported in C++).
///
/// Categories were originally inspired by dynamic languages such as Common
-/// Lisp and Smalltalk. More traditional class-based languages (C++, Java)
+/// Lisp and Smalltalk. More traditional class-based languages (C++, Java)
/// don't support this level of dynamism, which is both powerful and dangerous.
///
class ObjCCategoryDecl : public NamedDecl {
/// Interface belonging to this category
ObjCInterfaceDecl *ClassInterface;
- /// referenced protocols in this category
+ /// referenced protocols in this category.
ObjCProtocolDecl **ReferencedProtocols; // Null if none
unsigned NumReferencedProtocols; // 0 if none
@@ -635,28 +635,23 @@ class ObjCCategoryDecl : public NamedDecl {
SourceLocation EndLoc; // marks the '>' or identifier.
SourceLocation AtEndLoc; // marks the end of the entire interface.
- ObjCCategoryDecl(SourceLocation L, unsigned numRefProtocol,IdentifierInfo *Id)
+ ObjCCategoryDecl(SourceLocation L, IdentifierInfo *Id)
: NamedDecl(ObjCCategory, L, Id),
ClassInterface(0), ReferencedProtocols(0), NumReferencedProtocols(0),
InstanceMethods(0), NumInstanceMethods(0),
ClassMethods(0), NumClassMethods(0),
NextClassCategory(0) {
- if (numRefProtocol) {
- ReferencedProtocols = new ObjCProtocolDecl*[numRefProtocol];
- memset(ReferencedProtocols, '\0',
- numRefProtocol*sizeof(ObjCProtocolDecl*));
- NumReferencedProtocols = numRefProtocol;
- }
}
public:
static ObjCCategoryDecl *Create(ASTContext &C, SourceLocation L,
- unsigned numRefProtocol, IdentifierInfo *Id);
-
+ IdentifierInfo *Id);
ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; }
void setClassInterface(ObjCInterfaceDecl *IDecl) { ClassInterface = IDecl; }
+ void setReferencedProtocolList(ObjCProtocolDecl **List, unsigned NumRPs);
+
void setCatReferencedProtocols(unsigned idx, ObjCProtocolDecl *OID) {
assert((idx < NumReferencedProtocols) && "index out of range");
ReferencedProtocols[idx] = OID;
@@ -682,22 +677,22 @@ public:
}
// Get the local instance method declared in this interface.
- ObjCMethodDecl *getInstanceMethod(const Selector &Sel) {
+ ObjCMethodDecl *getInstanceMethod(Selector Sel) {
for (instmeth_iterator I = instmeth_begin(), E = instmeth_end();
- I != E; ++I) {
+ I != E; ++I) {
if ((*I)->getSelector() == Sel)
return *I;
}
- return 0;
+ return 0;
}
// Get the local class method declared in this interface.
- ObjCMethodDecl *getClassMethod(const Selector &Sel) {
+ ObjCMethodDecl *getClassMethod(Selector Sel) {
for (classmeth_iterator I = classmeth_begin(), E = classmeth_end();
- I != E; ++I) {
+ I != E; ++I) {
if ((*I)->getSelector() == Sel)
return *I;
}
- return 0;
+ return 0;
}
void addMethods(ObjCMethodDecl **insMethods, unsigned numInsMembers,
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 2ec9395644..cd4c6fff9f 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -68,10 +68,9 @@ ObjCForwardProtocolDecl::Create(ASTContext &C, SourceLocation L,
}
ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, SourceLocation L,
- unsigned numRefProtocol,
IdentifierInfo *Id) {
void *Mem = C.getAllocator().Allocate<ObjCCategoryDecl>();
- return new (Mem) ObjCCategoryDecl(L, numRefProtocol, Id);
+ return new (Mem) ObjCCategoryDecl(L, Id);
}
@@ -164,6 +163,17 @@ void ObjCProtocolDecl::addMethods(ObjCMethodDecl **insMethods,
AtEndLoc = endLoc;
}
+void ObjCCategoryDecl::setReferencedProtocolList(ObjCProtocolDecl **List,
+ unsigned NumRPs) {
+ assert(NumReferencedProtocols == 0 && "Protocol list already set");
+ if (NumRPs == 0) return;
+
+ ReferencedProtocols = new ObjCProtocolDecl*[NumRPs];
+ memcpy(ReferencedProtocols, List, NumRPs*sizeof(ObjCProtocolDecl*));
+ NumReferencedProtocols = NumRPs;
+}
+
+
/// addMethods - Insert instance and methods declarations into
/// ObjCCategoryDecl's CatInsMethods and CatClsMethods fields.
///
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 7bdfd9e014..e07d3c59e6 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -281,8 +281,7 @@ Sema::DeclTy *Sema::ActOnStartCategoryInterface(
ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
ObjCCategoryDecl *CDecl =
- ObjCCategoryDecl::Create(Context, AtInterfaceLoc, NumProtoRefs,
- CategoryName);
+ ObjCCategoryDecl::Create(Context, AtInterfaceLoc, CategoryName);
CDecl->setClassInterface(IDecl);
/// Check that class of this category is already completely declared.
@@ -304,7 +303,8 @@ Sema::DeclTy *Sema::ActOnStartCategoryInterface(
}
if (NumProtoRefs) {
- /// Check then save referenced protocols
+ llvm::SmallVector<ObjCProtocolDecl*, 32> RefProtocols;
+ /// Check and then save the referenced protocols.
for (unsigned int i = 0; i != NumProtoRefs; i++) {
ObjCProtocolDecl* RefPDecl = ObjCProtocols[ProtoRefNames[i]];
if (!RefPDecl || RefPDecl->isForwardDecl()) {
@@ -312,10 +312,13 @@ Sema::DeclTy *Sema::ActOnStartCategoryInterface(
ProtoRefNames[i]->getName(),
CategoryName->getName());
}
- CDecl->setCatReferencedProtocols(i, RefPDecl);
+ if (RefPDecl)
+ RefProtocols.push_back(RefPDecl);
}
- CDecl->setLocEnd(EndProtoLoc);
+ if (!RefProtocols.empty())
+ CDecl->setReferencedProtocolList(&RefProtocols[0], RefProtocols.size());
}
+ CDecl->setLocEnd(EndProtoLoc);
return CDecl;
}