]> granicus.if.org Git - clang/commitdiff
Fix <rdar://problem/6552648> error: redefinition of 'XCElementAnchorDelegate' as...
authorSteve Naroff <snaroff@apple.com>
Wed, 4 Feb 2009 17:14:05 +0000 (17:14 +0000)
committerSteve Naroff <snaroff@apple.com>
Wed, 4 Feb 2009 17:14:05 +0000 (17:14 +0000)
At first glance, this looked like a recent regression (possibly created by http://llvm.org/viewvc/llvm-project?view=rev&revision=63354, which was the only recent change to this section of Sema::ActOnStartClassInterface()). After more investigation, it looks like an edge case bug that we didn't cover in our tests.

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

lib/Sema/SemaDeclObjC.cpp
test/SemaObjC/class-def-test-1.m

index 3b0265e7033f652c48812bbe44fbacc70e5fe3c8..7c76f162755065535bb1068ae3f86f8a8c9dc00c 100644 (file)
@@ -105,26 +105,41 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
   }
   
   if (SuperName) {
-    ObjCInterfaceDecl* SuperClassEntry = 0;
     // Check if a different kind of symbol declared in this scope.
     PrevDecl = LookupName(TUScope, SuperName, LookupOrdinaryName);
-    if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
-      Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
-      Diag(PrevDecl->getLocation(), diag::note_previous_definition);
-    }
-    else {
-      // Check that super class is previously defined
-      SuperClassEntry = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl); 
 
-      if (!SuperClassEntry)
+    ObjCInterfaceDecl *SuperClassDecl = 
+                                  dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
+    if (PrevDecl && SuperClassDecl == 0) {
+      // The previous declaration was not a class decl. Check if we have a
+      // typedef. If we do, get the underlying class type.
+      if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
+        QualType T = TDecl->getUnderlyingType();
+        if (T->isObjCInterfaceType()) {
+          if (NamedDecl *IDecl = T->getAsObjCInterfaceType()->getDecl())
+            SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
+        }
+      }
+      // This handles the following case:
+      //
+      // typedef int SuperClass;
+      // @interface MyClass : SuperClass {} @end
+      //
+      if (!SuperClassDecl) {
+        Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
+        Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+      }
+    }
+    if (!dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
+      if (!SuperClassDecl)
         Diag(SuperLoc, diag::err_undef_superclass)
           << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
-      else if (SuperClassEntry->isForwardDecl())
+      else if (SuperClassDecl->isForwardDecl())
         Diag(SuperLoc, diag::err_undef_superclass)
-          << SuperClassEntry->getDeclName() << ClassName
+          << SuperClassDecl->getDeclName() << ClassName
           << SourceRange(AtInterfaceLoc, ClassLoc);
     }
-    IDecl->setSuperClass(SuperClassEntry);
+    IDecl->setSuperClass(SuperClassDecl);
     IDecl->setSuperClassLoc(SuperLoc);
     IDecl->setLocEnd(SuperLoc);
   } else { // we have a root class.
index ef226a515f1c0da112bef6f94ef90667e81fb581..50493f1b8651e44773836bb86b69c2fb0a5cb338 100644 (file)
@@ -24,3 +24,10 @@ typedef int OBJECT; // expected-note {{previous definition is here}}  \
 
 @interface INTF3 : PROTO @end // expected-error {{cannot find interface declaration for 'PROTO', superclass of 'INTF3'}}
 
+// Make sure we allow the following (for GCC compatibility).
+@interface NSObject @end
+typedef NSObject TD_NSObject;
+@interface XCElementUnit : TD_NSObject {}
+@end
+
+