summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/DeclObjC.h28
-rw-r--r--clang/lib/AST/DeclObjC.cpp16
-rw-r--r--clang/lib/Sema/Sema.cpp5
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp39
-rw-r--r--clang/test/Sema/objc-interface-1.m8
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
+
OpenPOWER on IntegriCloud