From: Chris Lattner Date: Sun, 16 Mar 2008 20:47:45 +0000 (+0000) Subject: simplify the way ObjCCategoryDecl's get their referenced protocols list X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=68c82cf61228102aba1194efef222fa1478af2a8;p=clang 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 --- 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(); - 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 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; }