From: Fariborz Jahanian Date: Thu, 20 Sep 2007 17:54:07 +0000 (+0000) Subject: Match to do some semantic analysis on objective-c class decl. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1d5b0e37cd569f3d1ddfc5cabff649ef7e42f3c6;p=clang Match to do some semantic analysis on objective-c class decl. 1. Detect used of undeclared/forward declared super class. 2. Detect duplicate definition of a class. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42168 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 42024b1adb..ca39e6e606 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -868,13 +868,30 @@ Sema::DeclTy *Sema::ObjcStartClassInterface(SourceLocation AtInterfaceLoc, IdentifierInfo **ProtocolNames, unsigned NumProtocols, AttributeList *AttrList) { assert(ClassName && "Missing class identifier"); - ObjcInterfaceDecl *IDecl; - + + ObjcInterfaceDecl* IDecl; + + if (Context.getObjCInterfaceDecl(ClassName)) + Diag(AtInterfaceLoc, diag::err_duplicate_class_def, ClassName->getName()); + IDecl = new ObjcInterfaceDecl(AtInterfaceLoc, ClassName); // Chain & install the interface decl into the identifier. IDecl->setNext(ClassName->getFETokenInfo()); ClassName->setFETokenInfo(IDecl); + + if (SuperName) { + const ObjcInterfaceDecl* SuperClassEntry = + Context.getObjCInterfaceDecl(SuperName); + + if (!SuperClassEntry) { + Diag(AtInterfaceLoc, diag::err_undef_superclass, SuperName->getName(), + ClassName->getName()); + } + } + + Context.setObjCInterfaceDecl(ClassName, IDecl); + return IDecl; } diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 76a51fc254..f9a33e5795 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -37,8 +37,10 @@ class ASTContext { llvm::FoldingSet FunctionTypeNoProtos; llvm::FoldingSet FunctionTypeProtos; llvm::DenseMap RecordLayoutInfo; + llvm::DenseMap ClassNameInfo; RecordDecl *CFConstantStringTypeDecl; public: + SourceManager &SourceMgr; TargetInfo &Target; IdentifierTable &Idents; @@ -157,6 +159,12 @@ public: /// position information. const RecordLayout &getRecordLayout(const RecordDecl *D, SourceLocation L); + const ObjcInterfaceDecl* getObjCInterfaceDecl(const IdentifierInfo* ClassName) + { return ClassNameInfo[ClassName]; } + void setObjCInterfaceDecl(const IdentifierInfo* ClassName, + const ObjcInterfaceDecl* InterfaceDecl) + { ClassNameInfo[ClassName] = InterfaceDecl; } + //===--------------------------------------------------------------------===// // Type Operators //===--------------------------------------------------------------------===// diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 059edecb86..445f3bf2b8 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -408,6 +408,11 @@ DIAG(err_objc_protocol_optional, ERROR, "@optional may be specified in protocols only") DIAG(err_missing_catch_finally, ERROR, "@try statment without a @catch and @finally clause") +DIAG(err_undef_superclass, ERROR, + "cannot find interface declaration for '%0', superclass of '%1'") +DIAG(err_duplicate_class_def, ERROR, + "duplicate interface declaration for class '%0'") + //===----------------------------------------------------------------------===// // Semantic Analysis diff --git a/test/Sema/undef-superclass-1.m b/test/Sema/undef-superclass-1.m new file mode 100644 index 0000000000..0b5b7c10d0 --- /dev/null +++ b/test/Sema/undef-superclass-1.m @@ -0,0 +1,18 @@ +@class SUPER, Y; + +@interface INTF :SUPER // expected-error {{cannot find interface declaration for 'SUPER', superclass of 'INTF'}} +@end + +@interface SUPER @end + +@interface INTF1 : SUPER +@end + +@interface INTF2 : INTF1 +@end + +@interface INTF3 : Y // expected-error {{cannot find interface declaration for 'Y', superclass of 'INTF3'}} +@end + +@interface INTF1 // expected-error {{duplicate interface declaration for class 'INTF1'}} +@end