[cfe-commits] r42172 - in /cfe/trunk: Sema/SemaDecl.cpp include/clang/AST/ASTContext.h include/clang/AST/Decl.h test/Sema/forward-class-1.m
Fariborz Jahanian
fjahanian at apple.com
Thu Sep 20 13:26:45 PDT 2007
Author: fjahanian
Date: Thu Sep 20 15:26:44 2007
New Revision: 42172
URL: http://llvm.org/viewvc/llvm-project?rev=42172&view=rev
Log:
Handle forward declaration of classes and prevent re-instantiation of
ObjcInterfaceClass Objects.
Added:
cfe/trunk/test/Sema/forward-class-1.m
Modified:
cfe/trunk/Sema/SemaDecl.cpp
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/Decl.h
Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=42172&r1=42171&r2=42172&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Thu Sep 20 15:26:44 2007
@@ -869,22 +869,28 @@
AttributeList *AttrList) {
assert(ClassName && "Missing class identifier");
- ObjcInterfaceDecl* IDecl;
+ ObjcInterfaceDecl* IDecl = Context.getObjCInterfaceDecl(ClassName);
- if (Context.getObjCInterfaceDecl(ClassName))
- Diag(AtInterfaceLoc, diag::err_duplicate_class_def, ClassName->getName());
-
- IDecl = new ObjcInterfaceDecl(AtInterfaceLoc, ClassName);
+ if (IDecl) {
+ // Class already seen. Is it a forward declaration?
+ if (!IDecl->getIsForwardDecl())
+ Diag(AtInterfaceLoc, diag::err_duplicate_class_def, ClassName->getName());
+ else
+ IDecl->setIsForwardDecl(false);
+ }
+ else {
+ IDecl = new ObjcInterfaceDecl(AtInterfaceLoc, ClassName);
- // Chain & install the interface decl into the identifier.
- IDecl->setNext(ClassName->getFETokenInfo<ScopedDecl>());
- ClassName->setFETokenInfo(IDecl);
+ // Chain & install the interface decl into the identifier.
+ IDecl->setNext(ClassName->getFETokenInfo<ScopedDecl>());
+ ClassName->setFETokenInfo(IDecl);
+ }
if (SuperName) {
const ObjcInterfaceDecl* SuperClassEntry =
Context.getObjCInterfaceDecl(SuperName);
- if (!SuperClassEntry) {
+ if (!SuperClassEntry || SuperClassEntry->getIsForwardDecl()) {
Diag(AtInterfaceLoc, diag::err_undef_superclass, SuperName->getName(),
ClassName->getName());
}
@@ -925,6 +931,7 @@
cast<ObjcInterfaceDecl>(D)->setNext(CDecl);
return CDecl;
}
+
/// ObjcClassDeclaration -
/// Scope will always be top level file scope.
Action::DeclTy *
@@ -934,13 +941,14 @@
for (unsigned i = 0; i != NumElts; ++i) {
ObjcInterfaceDecl *IDecl;
-
- // FIXME: before we create one, look up the interface decl in a hash table.
- IDecl = new ObjcInterfaceDecl(SourceLocation(), IdentList[i], true);
- // Chain & install the interface decl into the identifier.
- IDecl->setNext(IdentList[i]->getFETokenInfo<ScopedDecl>());
- IdentList[i]->setFETokenInfo(IDecl);
-
+ IDecl = Context.getObjCInterfaceDecl(IdentList[i]);
+ if (!IDecl) {// Already seen?
+ IDecl = new ObjcInterfaceDecl(SourceLocation(), IdentList[i], true);
+ // Chain & install the interface decl into the identifier.
+ IDecl->setNext(IdentList[i]->getFETokenInfo<ScopedDecl>());
+ IdentList[i]->setFETokenInfo(IDecl);
+ Context.setObjCInterfaceDecl(IdentList[i], IDecl);
+ }
// Remember that this needs to be removed when the scope is popped.
S->AddDecl(IdentList[i]);
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=42172&r1=42171&r2=42172&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Sep 20 15:26:44 2007
@@ -37,7 +37,7 @@
llvm::FoldingSet<FunctionTypeNoProto> FunctionTypeNoProtos;
llvm::FoldingSet<FunctionTypeProto> FunctionTypeProtos;
llvm::DenseMap<const RecordDecl*, const RecordLayout*> RecordLayoutInfo;
- llvm::DenseMap<const IdentifierInfo*, const ObjcInterfaceDecl*> ClassNameInfo;
+ llvm::DenseMap<const IdentifierInfo*, ObjcInterfaceDecl*> ClassNameInfo;
RecordDecl *CFConstantStringTypeDecl;
public:
@@ -159,10 +159,10 @@
/// position information.
const RecordLayout &getRecordLayout(const RecordDecl *D, SourceLocation L);
- const ObjcInterfaceDecl* getObjCInterfaceDecl(const IdentifierInfo* ClassName)
- { return ClassNameInfo[ClassName]; }
+ ObjcInterfaceDecl* getObjCInterfaceDecl(const IdentifierInfo* ClassName)
+ { return ClassNameInfo[ClassName]; }
void setObjCInterfaceDecl(const IdentifierInfo* ClassName,
- const ObjcInterfaceDecl* InterfaceDecl)
+ ObjcInterfaceDecl* InterfaceDecl)
{ ClassNameInfo[ClassName] = InterfaceDecl; }
//===--------------------------------------------------------------------===//
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=42172&r1=42171&r2=42172&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Thu Sep 20 15:26:44 2007
@@ -564,6 +564,9 @@
void ObjcAddMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers,
ObjcMethodDecl **clsMethods, unsigned numClsMembers);
+ bool getIsForwardDecl() const { return isForwardDecl; }
+ void setIsForwardDecl(bool val) { isForwardDecl = val; }
+
static bool classof(const Decl *D) {
return D->getKind() == ObjcInterface;
}
Added: cfe/trunk/test/Sema/forward-class-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/forward-class-1.m?rev=42172&view=auto
==============================================================================
--- cfe/trunk/test/Sema/forward-class-1.m (added)
+++ cfe/trunk/test/Sema/forward-class-1.m Thu Sep 20 15:26:44 2007
@@ -0,0 +1,22 @@
+ at class FOO, BAR;
+ at class FOO, BAR;
+
+ at interface INTF : FOO // expected-error {{cannot find interface declaration for 'FOO', superclass of 'INTF'}}
+ at end
+
+ at interface FOO
+- (BAR*) Meth1;
+- (FOO*) Meth2;
+ at end
+
+ at interface INTF1 : FOO
+ at end
+
+ at interface INTF2 : INTF1
+ at end
+
+
+ at class INTF1, INTF2;
+
+ at interface INTF2 : INTF1 // expected-error {{duplicate interface declaration for class 'INTF2'}}
+ at end
More information about the cfe-commits
mailing list