]> granicus.if.org Git - clang/commitdiff
This patch introduces a new class to keep track of class implementation info. It...
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 25 Sep 2007 18:38:09 +0000 (18:38 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 25 Sep 2007 18:38:09 +0000 (18:38 +0000)
semantic checks for class and protocol declarations. Test cases are good indications of kind of
checking being done in this patch.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42311 91177308-0d34-0410-b5e6-96231b3b80d8

12 files changed:
AST/Decl.cpp
Parse/MinimalAction.cpp
Parse/ParseObjc.cpp
Sema/Sema.h
Sema/SemaDecl.cpp
clang.xcodeproj/project.pbxproj
include/clang/AST/ASTContext.h
include/clang/AST/Decl.h
include/clang/Basic/DiagnosticKinds.def
include/clang/Parse/Action.h
test/Sema/class-def-test-1.m [new file with mode: 0644]
test/Sema/class-impl-1.m [new file with mode: 0644]

index bde4b6b45b52b6c898ccbb9fb427cf37b55b31ef..c0a77a2faa58b9a0081602fb07202590448d760b 100644 (file)
@@ -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;
   }
 }
 
index c5be83b8fce99984fb11e42d9e18ebed8be748e8..d9fc5c539c199dbdef9dc3c9c4ce0a21841f0635 100644 (file)
@@ -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) {
   
index 116c2d81b2ec1b6a52f1f9dfddca29da91c262c7..eddbb4a2541893ed8b1e37bf78adeb0eecd0e356 100644 (file)
@@ -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;
 }
index d99b1fc12f9c8bc8ae4035d7e9e78d1176f77e7f..0891c66453e08241771b1477197ea88ef8c5ae28 100644 (file)
@@ -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);
index ff7620380b9d90cee413dbbeae7c5088835c6b65..9a52874f79d73d383530da84a97cc91c0d4a9255 100644 (file)
@@ -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");
index 5f0ee39dabebf6c32e24d5dd22df1473714177be..443e9245e0c93d6b5bd31b00df635087efc97d4d 100644 (file)
                08FB7793FE84155DC02AAC07 /* Project object */ = {
                        isa = PBXProject;
                        buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
+                       compatibilityVersion = "Xcode 2.4";
                        hasScannedForEncodings = 1;
                        mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
                        projectDirPath = "";
index fe7cc3c003f0c7af7f110f3b0d6e9c9c41d0eab8..91fa2abd97d0e2d6c9887a10d5809fe585f0b716 100644 (file)
@@ -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
   //===--------------------------------------------------------------------===//
index e0c7c88596f88559f2df3d8e7b8abec0692ab4e5..425e8711ea9029e2cc8b96a6ed11995ca5784466 100644 (file)
@@ -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
index 3a76a8bc880236c4e5662733b71e43ca39eb962b..bd41546cd3359d5902b746255fb026b76d780c3d 100644 (file)
@@ -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
index dca01000755a5a09d5f5a75383cad3b42a580acc..fe902fc00f2b5eea4120f2f97c2f929a195f49db 100644 (file)
@@ -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 (file)
index 0000000..d7734df
--- /dev/null
@@ -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 (file)
index 0000000..6bd7da1
--- /dev/null
@@ -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'}}
+