diff options
-rw-r--r-- | clang/include/clang/AST/DeclObjC.h | 28 | ||||
-rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 39 | ||||
-rw-r--r-- | clang/test/Sema/objc-interface-1.m | 8 |
5 files changed, 50 insertions, 46 deletions
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index 89499f65a70..8c8325fb671 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -257,10 +257,8 @@ class ObjCInterfaceDecl : public NamedDecl, public DeclContext { SourceLocation EndLoc; // marks the '>', '}', or identifier. SourceLocation AtEndLoc; // marks the end of the entire interface. - ObjCInterfaceDecl(SourceLocation atLoc, - unsigned numRefProtos, - IdentifierInfo *Id, SourceLocation CLoc, - bool FD, bool isInternal) + ObjCInterfaceDecl(SourceLocation atLoc, IdentifierInfo *Id, + SourceLocation CLoc, bool FD, bool isInternal) : NamedDecl(ObjCInterface, atLoc, Id), DeclContext(ObjCInterface), TypeForDecl(0), SuperClass(0), ReferencedProtocols(0), NumReferencedProtocols(0), Ivars(0), @@ -270,7 +268,6 @@ class ObjCInterfaceDecl : public NamedDecl, public DeclContext { CategoryList(0), PropertyDecl(0), NumPropertyDecl(0), ForwardDecl(FD), InternalInterface(isInternal), ClassLoc(CLoc) { - AllocIntfRefProtocols(numRefProtos); } virtual ~ObjCInterfaceDecl(); @@ -282,22 +279,11 @@ public: static ObjCInterfaceDecl *Create(ASTContext &C, SourceLocation atLoc, - unsigned numRefProtos, IdentifierInfo *Id, SourceLocation ClassLoc = SourceLocation(), bool ForwardDecl = false, bool isInternal = false); - // This is necessary when converting a forward declaration to a definition. - void AllocIntfRefProtocols(unsigned numRefProtos) { - if (numRefProtos) { - ReferencedProtocols = new ObjCProtocolDecl*[numRefProtos]; - memset(ReferencedProtocols, '\0', - numRefProtos*sizeof(ObjCProtocolDecl*)); - NumReferencedProtocols = numRefProtos; - } - } - ObjCProtocolDecl **getReferencedProtocols() const { return ReferencedProtocols; } @@ -333,7 +319,12 @@ public: classmeth_iterator classmeth_end() const { return ClassMethods+NumClassMethods; } + + /// addReferencedProtocols - Set the list of protocols that this interface + /// implements. + void addReferencedProtocols(ObjCProtocolDecl **OID, unsigned numRefProtos); + void addInstanceVariablesToClass(ObjCIvarDecl **ivars, unsigned numIvars, SourceLocation RBracLoc); @@ -358,11 +349,6 @@ public: bool isForwardDecl() const { return ForwardDecl; } void setForwardDecl(bool val) { ForwardDecl = val; } - void setIntfRefProtocols(unsigned idx, ObjCProtocolDecl *OID) { - assert((idx < NumReferencedProtocols) && "index out of range"); - ReferencedProtocols[idx] = OID; - } - ObjCInterfaceDecl *getSuperClass() const { return SuperClass; } void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; } diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index ef3b2d74fb9..a1011b830e1 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -52,13 +52,11 @@ void ObjCMethodDecl::Destroy(ASTContext& C) { ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C, SourceLocation atLoc, - unsigned numRefProtos, IdentifierInfo *Id, SourceLocation ClassLoc, bool ForwardDecl, bool isInternal){ void *Mem = C.getAllocator().Allocate<ObjCInterfaceDecl>(); - return new (Mem) ObjCInterfaceDecl(atLoc, numRefProtos, - Id, ClassLoc, ForwardDecl, + return new (Mem) ObjCInterfaceDecl(atLoc, Id, ClassLoc, ForwardDecl, isInternal); } @@ -282,6 +280,18 @@ ObjCIvarDecl * return 0; } +/// addReferencedProtocols - Set the list of protocols that this interface +/// implements. +void ObjCInterfaceDecl::addReferencedProtocols(ObjCProtocolDecl **OID, + unsigned numRefProtos) { + assert(NumReferencedProtocols == 0 && "refproto already set!"); + NumReferencedProtocols = numRefProtos; + if (numRefProtos) { + ReferencedProtocols = new ObjCProtocolDecl*[numRefProtos]; + memcpy(ReferencedProtocols, OID, numRefProtos*sizeof(ObjCProtocolDecl*)); + } +} + /// ObjCAddInstanceVariablesToClass - Inserts instance variables /// into ObjCInterfaceDecl's fields. /// diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 61a8948e4d7..32c769b64d9 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -53,7 +53,8 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { if (!PP.getLangOptions().ObjC1) return; // Synthesize "typedef struct objc_selector *SEL;" - RecordDecl *SelTag = RecordDecl::Create(Context, TagDecl::TK_struct, CurContext, + RecordDecl *SelTag = RecordDecl::Create(Context, TagDecl::TK_struct, + CurContext, SourceLocation(), &Context.Idents.get("objc_selector"), 0); @@ -82,7 +83,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { Context.setObjCClassType(ClassTypedef); // Synthesize "@class Protocol; ObjCInterfaceDecl *ProtocolDecl = - ObjCInterfaceDecl::Create(Context, SourceLocation(), 0, + ObjCInterfaceDecl::Create(Context, SourceLocation(), &Context.Idents.get("Protocol"), SourceLocation(), true); Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl)); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 5b6bd104a90..2f12a6ffdad 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -92,11 +92,9 @@ Sema::DeclTy *Sema::ActOnStartClassInterface( else { IDecl->setLocation(AtInterfaceLoc); IDecl->setForwardDecl(false); - IDecl->AllocIntfRefProtocols(NumProtocols); } - } - else { - IDecl = ObjCInterfaceDecl::Create(Context, AtInterfaceLoc, NumProtocols, + } else { + IDecl = ObjCInterfaceDecl::Create(Context, AtInterfaceLoc, ClassName, ClassLoc); ObjCInterfaceDecls[ClassName] = IDecl; @@ -118,10 +116,10 @@ Sema::DeclTy *Sema::ActOnStartClassInterface( SuperClassEntry = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl); if (!SuperClassEntry || SuperClassEntry->isForwardDecl()) { - Diag(AtInterfaceLoc, diag::err_undef_superclass, + Diag(SuperLoc, diag::err_undef_superclass, SuperClassEntry ? SuperClassEntry->getName() : SuperName->getName(), - ClassName->getName()); + ClassName->getName(), SourceRange(AtInterfaceLoc, ClassLoc)); } } IDecl->setSuperClass(SuperClassEntry); @@ -133,14 +131,18 @@ Sema::DeclTy *Sema::ActOnStartClassInterface( /// Check then save referenced protocols if (NumProtocols) { + llvm::SmallVector<ObjCProtocolDecl*, 8> RefProtos; for (unsigned int i = 0; i != NumProtocols; i++) { ObjCProtocolDecl* RefPDecl = ObjCProtocols[ProtocolNames[i]]; if (!RefPDecl || RefPDecl->isForwardDecl()) - Diag(ClassLoc, diag::warn_undef_protocolref, + Diag(EndProtoLoc, diag::warn_undef_protocolref, ProtocolNames[i]->getName(), ClassName->getName()); - IDecl->setIntfRefProtocols(i, RefPDecl); + else + RefProtos.push_back(RefPDecl); } + if (!RefProtos.empty()) + IDecl->addReferencedProtocols(&RefProtos[0], RefProtos.size()); IDecl->setLocEnd(EndProtoLoc); } return IDecl; @@ -350,26 +352,23 @@ void Sema::MergeProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl, DeclTy *MergeItsProtocols) { Decl *ClassDecl = static_cast<Decl *>(MergeItsProtocols); - if (ObjCInterfaceDecl *MDecl = - dyn_cast<ObjCInterfaceDecl>(ClassDecl)) { + if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) { for (ObjCInterfaceDecl::protocol_iterator P = MDecl->protocol_begin(), E = MDecl->protocol_end(); P != E; ++P) - MergeOneProtocolPropertiesIntoClass(IDecl, (*P)); // Merge properties of class (*P) into IDECL's - ; + MergeOneProtocolPropertiesIntoClass(IDecl, *P); + // Go thru the list of protocols for this class and recursively merge // their properties into this class as well. for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(), E = IDecl->protocol_end(); P != E; ++P) - MergeProtocolPropertiesIntoClass(IDecl, (*P)); - } - else if (ObjCProtocolDecl *MDecl = - dyn_cast<ObjCProtocolDecl>(ClassDecl)) + MergeProtocolPropertiesIntoClass(IDecl, *P); + } else { + ObjCProtocolDecl *MDecl = cast<ObjCProtocolDecl>(ClassDecl); for (ObjCProtocolDecl::protocol_iterator P = MDecl->protocol_begin(), E = MDecl->protocol_end(); P != E; ++P) MergeOneProtocolPropertiesIntoClass(IDecl, (*P)); - else - assert(false && "MergeProtocolPropertiesIntoClass - bad object kind"); + } } /// ActOnForwardProtocolDeclaration - @@ -509,7 +508,7 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation( if (!IDecl) { // Legacy case of @implementation with no corresponding @interface. // Build, chain & install the interface decl into the identifier. - IDecl = ObjCInterfaceDecl::Create(Context, AtClassImplLoc, 0, ClassName, + IDecl = ObjCInterfaceDecl::Create(Context, AtClassImplLoc, ClassName, ClassLoc, false, true); ObjCInterfaceDecls[ClassName] = IDecl; IDecl->setSuperClass(SDecl); @@ -726,7 +725,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, } ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl); if (!IDecl) { // Not already seen? Make a forward decl. - IDecl = ObjCInterfaceDecl::Create(Context, AtClassLoc, 0, IdentList[i], + IDecl = ObjCInterfaceDecl::Create(Context, AtClassLoc, IdentList[i], SourceLocation(), true); ObjCInterfaceDecls[IdentList[i]] = IDecl; diff --git a/clang/test/Sema/objc-interface-1.m b/clang/test/Sema/objc-interface-1.m new file mode 100644 index 00000000000..0e025422519 --- /dev/null +++ b/clang/test/Sema/objc-interface-1.m @@ -0,0 +1,8 @@ +// RUN: clang %s -fsyntax-only -verify +// rdar://5957506 + +@interface NSWhatever : +NSObject // expected-error {{cannot find interface declaration for 'NSObject'}} +<NSCopying> // expected-error {{cannot find protocol definition for 'NSCopying'}} +@end + |