diff options
-rw-r--r-- | AST/Decl.cpp | 8 | ||||
-rw-r--r-- | Parse/MinimalAction.cpp | 5 | ||||
-rw-r--r-- | Parse/ParseObjc.cpp | 18 | ||||
-rw-r--r-- | Sema/Sema.h | 12 | ||||
-rw-r--r-- | Sema/SemaDecl.cpp | 112 | ||||
-rw-r--r-- | clang.xcodeproj/project.pbxproj | 1 | ||||
-rw-r--r-- | include/clang/AST/ASTContext.h | 11 | ||||
-rw-r--r-- | include/clang/AST/Decl.h | 46 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticKinds.def | 6 | ||||
-rw-r--r-- | include/clang/Parse/Action.h | 17 | ||||
-rw-r--r-- | test/Sema/class-def-test-1.m | 23 | ||||
-rw-r--r-- | test/Sema/class-impl-1.m | 31 |
12 files changed, 266 insertions, 24 deletions
diff --git a/AST/Decl.cpp b/AST/Decl.cpp index bde4b6b45b..c0a77a2faa 100644 --- a/AST/Decl.cpp +++ b/AST/Decl.cpp @@ -32,6 +32,7 @@ static unsigned nProtocolDecls = 0; static unsigned nForwardProtocolDecls = 0; static unsigned nCategoryDecls = 0; static unsigned nIvarDecls = 0; +static unsigned nObjcImplementationDecls = 0; static bool StatSwitch = false; @@ -132,6 +133,10 @@ void Decl::PrintStats() { nCategoryDecls, (int)sizeof(ObjcCategoryDecl), int(nCategoryDecls*sizeof(ObjcCategoryDecl))); + fprintf(stderr, " %d class implementation decls, %d each (%d bytes)\n", + nObjcImplementationDecls, (int)sizeof(ObjcImplementationDecl), + int(nObjcImplementationDecls*sizeof(ObjcImplementationDecl))); + fprintf(stderr, "Total bytes = %d\n", int(nFuncs*sizeof(FunctionDecl)+nBlockVars*sizeof(BlockVarDecl)+ nFileVars*sizeof(FileVarDecl)+nParmVars*sizeof(ParmVarDecl)+ @@ -193,6 +198,9 @@ void Decl::addDeclKind(const Kind k) { case ObjcIvar: nIvarDecls++; break; + case ObjcImplementation: + nObjcImplementationDecls++; + break; } } diff --git a/Parse/MinimalAction.cpp b/Parse/MinimalAction.cpp index c5be83b8fc..d9fc5c539c 100644 --- a/Parse/MinimalAction.cpp +++ b/Parse/MinimalAction.cpp @@ -68,7 +68,7 @@ MinimalAction::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup) { } Action::DeclTy * -MinimalAction::ObjcStartClassInterface(SourceLocation AtInterafceLoc, +MinimalAction::ObjcStartClassInterface(Scope* S, SourceLocation AtInterafceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *SuperName, SourceLocation SuperLoc, IdentifierInfo **ProtocolNames, unsigned NumProtocols, @@ -81,7 +81,8 @@ MinimalAction::ObjcStartClassInterface(SourceLocation AtInterafceLoc, } Action::DeclTy * -MinimalAction::ObjcStartProtoInterface(SourceLocation AtProtoInterfaceLoc, +MinimalAction::ObjcStartProtoInterface(Scope* S, + SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs) { diff --git a/Parse/ParseObjc.cpp b/Parse/ParseObjc.cpp index 116c2d81b2..eddbb4a254 100644 --- a/Parse/ParseObjc.cpp +++ b/Parse/ParseObjc.cpp @@ -189,7 +189,8 @@ Parser::DeclTy *Parser::ParseObjCAtInterfaceDeclaration( if (ParseObjCProtocolReferences(ProtocolRefs)) return 0; } - DeclTy *ClsType = Actions.ObjcStartClassInterface(atLoc, nameId, nameLoc, + DeclTy *ClsType = Actions.ObjcStartClassInterface(CurScope, + atLoc, nameId, nameLoc, superClassId, superClassLoc, &ProtocolRefs[0], ProtocolRefs.size(), attrList); @@ -749,7 +750,7 @@ Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc) { return 0; } - DeclTy *ProtoType = Actions.ObjcStartProtoInterface(AtLoc, + DeclTy *ProtoType = Actions.ObjcStartProtoInterface(CurScope, AtLoc, protocolName, nameLoc, &ProtocolRefs[0], ProtocolRefs.size()); @@ -786,6 +787,7 @@ Parser::DeclTy *Parser::ParseObjCAtImplementationDeclaration( return 0; } // We have a class or category name - consume it. + IdentifierInfo *nameId = Tok.getIdentifierInfo(); SourceLocation nameLoc = ConsumeToken(); // consume class or category name if (Tok.getKind() == tok::l_paren) { @@ -810,6 +812,8 @@ Parser::DeclTy *Parser::ParseObjCAtImplementationDeclaration( return 0; } // We have a class implementation + SourceLocation superClassLoc; + IdentifierInfo *superClassId = 0; if (Tok.getKind() == tok::colon) { // We have a super class ConsumeToken(); @@ -817,10 +821,16 @@ Parser::DeclTy *Parser::ParseObjCAtImplementationDeclaration( Diag(Tok, diag::err_expected_ident); // missing super class name. return 0; } - ConsumeToken(); // Consume super class name + superClassId = Tok.getIdentifierInfo(); + superClassLoc = ConsumeToken(); // Consume super class name } + DeclTy *ImplClsType = Actions.ObjcStartClassImplementation(CurScope, + atLoc, + nameId, nameLoc, + superClassId, superClassLoc); + if (Tok.getKind() == tok::l_brace) - ParseObjCClassInstanceVariables(0/*FIXME*/); // we have ivars + ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/); // we have ivars return 0; } diff --git a/Sema/Sema.h b/Sema/Sema.h index d99b1fc12f..0891c66453 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -352,13 +352,15 @@ public: SourceLocation RParenLoc); // Objective-C declarations. - virtual DeclTy *ObjcStartClassInterface(SourceLocation AtInterafceLoc, + virtual DeclTy *ObjcStartClassInterface(Scope* S, + SourceLocation AtInterafceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *SuperName, SourceLocation SuperLoc, IdentifierInfo **ProtocolNames, unsigned NumProtocols, AttributeList *AttrList); - virtual DeclTy *ObjcStartProtoInterface(SourceLocation AtProtoInterfaceLoc, + virtual DeclTy *ObjcStartProtoInterface(Scope* S, + SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs); @@ -367,6 +369,12 @@ public: IdentifierInfo *CategoryName, SourceLocation CategoryLoc, IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs); + virtual DeclTy *ObjcStartClassImplementation(Scope* S, + SourceLocation AtClassImplLoc, + IdentifierInfo *ClassName, SourceLocation ClassLoc, + IdentifierInfo *SuperClassname, + SourceLocation SuperClassLoc); + virtual DeclTy *ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc, IdentifierInfo **IdentList, unsigned NumElts); diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index ff7620380b..9a52874f79 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -862,13 +862,24 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, return NewTD; } -Sema::DeclTy *Sema::ObjcStartClassInterface(SourceLocation AtInterfaceLoc, +Sema::DeclTy *Sema::ObjcStartClassInterface(Scope* S, + SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *SuperName, SourceLocation SuperLoc, IdentifierInfo **ProtocolNames, unsigned NumProtocols, AttributeList *AttrList) { assert(ClassName && "Missing class identifier"); - + + // Check for another declaration kind with the same name. + ScopedDecl *PrevDecl = LookupScopedDecl(ClassName, Decl::IDNS_Ordinary, + ClassLoc, S); + if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl) + && !isa<ObjcProtocolDecl>(PrevDecl)) { + Diag(ClassLoc, diag::err_redefinition_different_kind, + ClassName->getName()); + Diag(PrevDecl->getLocation(), diag::err_previous_definition); + } + ObjcInterfaceDecl* IDecl = Context.getObjCInterfaceDecl(ClassName); if (IDecl) { @@ -889,15 +900,26 @@ Sema::DeclTy *Sema::ObjcStartClassInterface(SourceLocation AtInterfaceLoc, } if (SuperName) { - ObjcInterfaceDecl* SuperClassEntry = - Context.getObjCInterfaceDecl(SuperName); + ObjcInterfaceDecl* SuperClassEntry = 0; + // Check if a different kind of symbol declared in this scope. + PrevDecl = LookupScopedDecl(SuperName, Decl::IDNS_Ordinary, + SuperLoc, S); + if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl) + && !isa<ObjcProtocolDecl>(PrevDecl)) { + Diag(SuperLoc, diag::err_redefinition_different_kind, + SuperName->getName()); + Diag(PrevDecl->getLocation(), diag::err_previous_definition); + } + else { + // Check that super class is previously defined + SuperClassEntry = Context.getObjCInterfaceDecl(SuperName); - if (!SuperClassEntry || SuperClassEntry->getIsForwardDecl()) { - Diag(AtInterfaceLoc, diag::err_undef_superclass, SuperName->getName(), - ClassName->getName()); + if (!SuperClassEntry || SuperClassEntry->getIsForwardDecl()) { + Diag(AtInterfaceLoc, diag::err_undef_superclass, SuperName->getName(), + ClassName->getName()); + } } - else - IDecl->setSuperClass(SuperClassEntry); + IDecl->setSuperClass(SuperClassEntry); } /// Check then save referenced protocols @@ -916,7 +938,8 @@ Sema::DeclTy *Sema::ObjcStartClassInterface(SourceLocation AtInterfaceLoc, return IDecl; } -Sema::DeclTy *Sema::ObjcStartProtoInterface(SourceLocation AtProtoInterfaceLoc, +Sema::DeclTy *Sema::ObjcStartProtoInterface(Scope* S, + SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs) { assert(ProtocolName && "Missing protocol identifier"); @@ -1032,6 +1055,72 @@ Sema::DeclTy *Sema::ObjcStartCatInterface(SourceLocation AtInterfaceLoc, return CDecl; } +Sema::DeclTy *Sema::ObjcStartClassImplementation(Scope *S, + SourceLocation AtClassImplLoc, + IdentifierInfo *ClassName, SourceLocation ClassLoc, + IdentifierInfo *SuperClassname, + SourceLocation SuperClassLoc) { + ObjcInterfaceDecl* IDecl = 0; + // Check for another declaration kind with the same name. + ScopedDecl *PrevDecl = LookupScopedDecl(ClassName, Decl::IDNS_Ordinary, + ClassLoc, S); + if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl)) { + Diag(ClassLoc, diag::err_redefinition_different_kind, + ClassName->getName()); + Diag(PrevDecl->getLocation(), diag::err_previous_definition); + } + else { + // Is there an interface declaration of this class; if not, warn! + IDecl = Context.getObjCInterfaceDecl(ClassName); + if (!IDecl) + Diag(ClassLoc, diag::warn_undef_interface, ClassName->getName()); + } + + // Check that super class name is valid class name + ObjcInterfaceDecl* SDecl = 0; + if (SuperClassname) { + // Check if a different kind of symbol declared in this scope. + PrevDecl = LookupScopedDecl(SuperClassname, Decl::IDNS_Ordinary, + SuperClassLoc, S); + if (PrevDecl && !isa<ObjcInterfaceDecl>(PrevDecl) + && !isa<ObjcProtocolDecl>(PrevDecl)) { + Diag(SuperClassLoc, diag::err_redefinition_different_kind, + SuperClassname->getName()); + Diag(PrevDecl->getLocation(), diag::err_previous_definition); + } + else { + SDecl = Context.getObjCInterfaceDecl(SuperClassname); + if (!SDecl) + Diag(SuperClassLoc, diag::err_undef_superclass, + SuperClassname->getName(), ClassName->getName()); + else if (IDecl && IDecl->getSuperClass() != SDecl) { + // This implementation and its interface do not have the same + // super class. + Diag(SuperClassLoc, diag::err_conflicting_super_class, + SuperClassname->getName()); + Diag(SDecl->getLocation(), diag::err_previous_definition); + } + } + } + + ObjcImplementationDecl* IMPDecl = + new ObjcImplementationDecl(AtClassImplLoc, ClassName, SDecl); + + // Check that there is no duplicate implementation of this class. + bool err = false; + for (unsigned i = 0; i != Context.sizeObjcImplementationClass(); i++) { + if (Context.getObjcImplementationClass(i)->getIdentifier() == ClassName) { + Diag(ClassLoc, diag::err_dup_implementation_class, ClassName->getName()); + err = true; + break; + } + } + if (!err) + Context.setObjcImplementationClass(IMPDecl); + + return IMPDecl; +} + /// ObjcClassDeclaration - /// Scope will always be top level file scope. Action::DeclTy * @@ -1204,7 +1293,8 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *TagDecl, if (isa<RecordDecl>(static_cast<Decl *>(TagDecl))) NewFD = new FieldDecl(Loc, II, T); - else if (isa<ObjcInterfaceDecl>(static_cast<Decl *>(TagDecl))) + else if (isa<ObjcInterfaceDecl>(static_cast<Decl *>(TagDecl)) + || isa<ObjcImplementationDecl>(static_cast<Decl *>(TagDecl))) NewFD = new ObjcIvarDecl(Loc, II, T); else assert(0 && "Sema::ActOnField(): Unknown TagDecl"); diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index 5f0ee39dab..443e9245e0 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -725,6 +725,7 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */; + compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 1; mainGroup = 08FB7794FE84155DC02AAC07 /* clang */; projectDirPath = ""; diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index fe7cc3c003..91fa2abd97 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -39,6 +39,7 @@ class ASTContext { llvm::DenseMap<const RecordDecl*, const RecordLayout*> RecordLayoutInfo; llvm::DenseMap<const IdentifierInfo*, ObjcInterfaceDecl*> ClassNameInfo; llvm::DenseMap<const IdentifierInfo*, ObjcProtocolDecl*> ProtocolNameInfo; + llvm::SmallVector<ObjcImplementationDecl*, 8> ImplementationClassInfo; RecordDecl *CFConstantStringTypeDecl; public: @@ -172,6 +173,16 @@ public: ObjcProtocolDecl* ProtocolDecl) { ProtocolNameInfo[ProtocolName] = ProtocolDecl; } + ObjcImplementationDecl* getObjcImplementationClass(unsigned ix) { + return ImplementationClassInfo[ix]; + } + void setObjcImplementationClass(ObjcImplementationDecl* ImplDecl) { + ImplementationClassInfo.push_back(ImplDecl); + } + unsigned sizeObjcImplementationClass() const { + return ImplementationClassInfo.size(); + } + //===--------------------------------------------------------------------===// // Type Operators //===--------------------------------------------------------------------===// diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index e0c7c88596..425e8711ea 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -29,7 +29,6 @@ class ObjcMethodDecl; class ObjcProtocolDecl; class ObjcCategoryDecl; - /// Decl - This represents one declaration (or definition), e.g. a variable, /// typedef, function, struct, etc. /// @@ -41,6 +40,7 @@ public: // Concrete sub-classes of TypeDecl Typedef, Struct, Union, Class, Enum, ObjcInterface, ObjcClass, ObjcMethod, ObjcProtoMethod, ObjcProtocol, ObjcForwardProtocol, ObjcCategory, + ObjcImplementation, // Concrete sub-class of Decl Field, ObjcIvar }; @@ -86,6 +86,7 @@ public: case ParmVariable: case EnumConstant: case ObjcInterface: + case ObjcProtocol: return IDNS_Ordinary; case Struct: case Union: @@ -856,6 +857,49 @@ public: } static bool classof(const ObjcCategoryDecl *D) { return true; } }; + +class ObjcImplementationDecl : public ScopedDecl { + + /// Implementation Class's super class. + ObjcInterfaceDecl *SuperClass; + + /// Optional Ivars/NumIvars - This is a new[]'d array of pointers to Decls. + ObjcIvarDecl **Ivars; // Null if not specified + int NumIvars; // -1 if not defined. + + /// implemented instance methods + ObjcMethodDecl **InsMethods; // Null if not defined + int NumInsMethods; // -1 if not defined + + /// implemented class methods + ObjcMethodDecl **ClsMethods; // Null if not defined + int NumClsMethods; // -1 if not defined + + public: + ObjcImplementationDecl(SourceLocation L, IdentifierInfo *Id, + ObjcInterfaceDecl* superDecl) + : ScopedDecl(ObjcImplementation, L, Id, 0), + SuperClass(superDecl), + Ivars(0), NumIvars(-1), + InsMethods(0), NumInsMethods(-1), ClsMethods(0), NumClsMethods(-1) {} + + void ObjcAddInstanceVariablesToClass(ObjcIvarDecl **ivars, + unsigned numIvars); + + void ObjcAddMethods(ObjcMethodDecl **insMethods, unsigned numInsMembers, + ObjcMethodDecl **clsMethods, unsigned numClsMembers); + + ObjcInterfaceDecl *getImplSuperClass() const { return SuperClass; } + + void setImplSuperClass(ObjcInterfaceDecl * superCls) + { SuperClass = superCls; } + + static bool classof(const Decl *D) { + return D->getKind() == ObjcImplementation; + } + static bool classof(const ObjcImplementationDecl *D) { return true; } +}; + } // end namespace clang #endif diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 3a76a8bc88..bd41546cd3 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -420,6 +420,12 @@ DIAG(err_undef_interface, ERROR, "cannot find interface declaration for '%0'") DIAG(err_dup_category_def, ERROR, "duplicate interface declaration for category '%0(%1)'") +DIAG(warn_undef_interface, WARNING, + "cannot find interface declaration for '%0'") +DIAG(err_dup_implementation_class, ERROR, + "reimplementation of class '%0'") +DIAG(err_conflicting_super_class, ERROR, + "conflicting super class name '%0'") //===----------------------------------------------------------------------===// // Semantic Analysis diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index dca0100075..fe902fc00f 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -437,7 +437,7 @@ public: } //===----------------------- Obj-C Declarations -------------------------===// - virtual DeclTy *ObjcStartClassInterface(SourceLocation AtInterafceLoc, + virtual DeclTy *ObjcStartClassInterface(Scope* S, SourceLocation AtInterafceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *SuperName, SourceLocation SuperLoc, IdentifierInfo **ProtocolNames, unsigned NumProtocols, @@ -448,7 +448,8 @@ public: DeclTy **allMethods, unsigned allNum) { return; } - virtual DeclTy *ObjcStartProtoInterface(SourceLocation AtProtoInterfaceLoc, + virtual DeclTy *ObjcStartProtoInterface(Scope* S, + SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs) { return 0; @@ -459,6 +460,13 @@ public: IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs) { return 0; } + virtual DeclTy *ObjcStartClassImplementation(Scope* S, + SourceLocation AtClassImplLoc, + IdentifierInfo *ClassName, SourceLocation ClassLoc, + IdentifierInfo *SuperClassname, + SourceLocation SuperClassLoc) { + return 0; + } virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc, tok::TokenKind MethodType, TypeTy *ReturnType, ObjcKeywordDecl *Keywords, unsigned NumKeywords, @@ -561,12 +569,13 @@ public: IdentifierInfo **IdentList, unsigned NumElts); - virtual DeclTy *ObjcStartClassInterface(SourceLocation AtInterafceLoc, + virtual DeclTy *ObjcStartClassInterface(Scope* S, SourceLocation AtInterafceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *SuperName, SourceLocation SuperLoc, IdentifierInfo **ProtocolNames, unsigned NumProtocols, AttributeList *AttrList); - virtual DeclTy *ObjcStartProtoInterface(SourceLocation AtProtoInterfaceLoc, + virtual DeclTy *ObjcStartProtoInterface(Scope *S, + SourceLocation AtProtoInterfaceLoc, IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc, IdentifierInfo **ProtoRefNames, unsigned NumProtoRefs); }; diff --git a/test/Sema/class-def-test-1.m b/test/Sema/class-def-test-1.m new file mode 100644 index 0000000000..d7734dfa56 --- /dev/null +++ b/test/Sema/class-def-test-1.m @@ -0,0 +1,23 @@ +@protocol SUPER; + +@interface SUPER <SUPER> @end // expected-error {{cannot find protocol definition for 'SUPER', referenced by 'SUPER'}} + +typedef int INTF; // expected-error {{previou sdefinition is here}} + +@interface INTF @end // expected-error {{redefinition of 'INTF' as different kind of symbol}} + +@interface OBJECT @end + +@interface INTF1 : OBJECT @end + +@interface INTF1 : OBJECT @end // expected-error {{duplicate interface declaration for class 'INTF1'} + +typedef int OBJECT; // expected-error {{previous definition is here}} + +@interface INTF2 : OBJECT @end // expected-error {{redefinition of 'OBJECT' as different kind of symbol}} + + +@protocol PROTO; + +@interface INTF3 : PROTO @end // expected-error {{cannot find interface declaration for 'PROTO', superclass of 'INTF3'}} + diff --git a/test/Sema/class-impl-1.m b/test/Sema/class-impl-1.m new file mode 100644 index 0000000000..6bd7da1944 --- /dev/null +++ b/test/Sema/class-impl-1.m @@ -0,0 +1,31 @@ +typedef int INTF3; // expected-error {{previous definition is here}} + +@interface SUPER @end // expected-error {{previous definition is here}} + +@interface OBJECT @end + +@interface INTF : OBJECT +@end + +@implementation INTF @end + +@implementation INTF // expected-error {{reimplementation of class 'INTF'}} +@end + + +@interface INTF1 : OBJECT +@end + +@implementation INTF1 : SUPER // expected-error {{conflicting super class name 'SUPER'}} +@end + +@interface INTF2 +@end + +@implementation INTF2 : SUPR // expected-error {{cannot find interface declaration for 'SUPR', superclass of 'INTF2'}} +@end + +@implementation INTF3 @end // expected-error {{redefinition of 'INTF3' as different kind of symbol}} + +@implementation INTF4 @end // expected-warning {{cannot find interface declaration for 'INTF4'}} + |