[cfe-commits] r121097 - in /cfe/trunk: lib/AST/ASTImporter.cpp test/ASTMerge/Inputs/interface1.m test/ASTMerge/Inputs/interface2.m test/ASTMerge/interface.m

Douglas Gregor dgregor at apple.com
Mon Dec 6 17:26:03 PST 2010


Author: dgregor
Date: Mon Dec  6 19:26:03 2010
New Revision: 121097

URL: http://llvm.org/viewvc/llvm-project?rev=121097&view=rev
Log:
Extern the ASTImporter to import @implementation declarations.

Modified:
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/test/ASTMerge/Inputs/interface1.m
    cfe/trunk/test/ASTMerge/Inputs/interface2.m
    cfe/trunk/test/ASTMerge/interface.m

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=121097&r1=121096&r2=121097&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Dec  6 19:26:03 2010
@@ -115,6 +115,7 @@
     Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D);
     Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D);
     Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
+    Decl *VisitObjCImplementationDecl(ObjCImplementationDecl *D);
     Decl *VisitObjCPropertyDecl(ObjCPropertyDecl *D);
     Decl *VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
     Decl *VisitObjCClassDecl(ObjCClassDecl *D);
@@ -3012,8 +3013,8 @@
   
   // If we have an @implementation, import it as well.
   if (D->getImplementation()) {
-    ObjCImplementationDecl *Impl
-      = cast<ObjCImplementationDecl>(Importer.Import(D->getImplementation()));
+    ObjCImplementationDecl *Impl = cast_or_null<ObjCImplementationDecl>(
+                                       Importer.Import(D->getImplementation()));
     if (!Impl)
       return 0;
     
@@ -3023,6 +3024,79 @@
   return ToIface;
 }
 
+Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+  // Find the corresponding interface.
+  ObjCInterfaceDecl *Iface = cast_or_null<ObjCInterfaceDecl>(
+                                       Importer.Import(D->getClassInterface()));
+  if (!Iface)
+    return 0;
+
+  // Import the superclass, if any.
+  ObjCInterfaceDecl *Super = 0;
+  if (D->getSuperClass()) {
+    Super = cast_or_null<ObjCInterfaceDecl>(
+                                          Importer.Import(D->getSuperClass()));
+    if (!Super)
+      return 0;
+  }
+
+  ObjCImplementationDecl *Impl = Iface->getImplementation();
+  if (!Impl) {
+    // We haven't imported an implementation yet. Create a new @implementation
+    // now.
+    Impl = ObjCImplementationDecl::Create(Importer.getToContext(),
+                                  Importer.ImportContext(D->getDeclContext()),
+                                          Importer.Import(D->getLocation()),
+                                          Iface, Super);
+    
+    if (D->getDeclContext() != D->getLexicalDeclContext()) {
+      DeclContext *LexicalDC
+        = Importer.ImportContext(D->getLexicalDeclContext());
+      if (!LexicalDC)
+        return 0;
+      Impl->setLexicalDeclContext(LexicalDC);
+    }
+    
+    // Associate the implementation with the class it implements.
+    Iface->setImplementation(Impl);
+    Importer.Imported(D, Iface->getImplementation());
+  } else {
+    Importer.Imported(D, Iface->getImplementation());
+
+    // Verify that the existing @implementation has the same superclass.
+    if ((Super && !Impl->getSuperClass()) ||
+        (!Super && Impl->getSuperClass()) ||
+        (Super && Impl->getSuperClass() && 
+         Super->getCanonicalDecl() != Impl->getSuperClass())) {
+        Importer.ToDiag(Impl->getLocation(), 
+                        diag::err_odr_objc_superclass_inconsistent)
+          << Iface->getDeclName();
+        // FIXME: It would be nice to have the location of the superclass
+        // below.
+        if (Impl->getSuperClass())
+          Importer.ToDiag(Impl->getLocation(), 
+                          diag::note_odr_objc_superclass)
+          << Impl->getSuperClass()->getDeclName();
+        else
+          Importer.ToDiag(Impl->getLocation(), 
+                          diag::note_odr_objc_missing_superclass);
+        if (D->getSuperClass())
+          Importer.FromDiag(D->getLocation(), 
+                            diag::note_odr_objc_superclass)
+          << D->getSuperClass()->getDeclName();
+        else
+          Importer.FromDiag(D->getLocation(), 
+                            diag::note_odr_objc_missing_superclass);
+      return 0;
+    }
+  }
+    
+  // Import all of the members of this @implementation.
+  ImportDeclContext(D);
+
+  return Impl;
+}
+
 Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
   // Import the major distinguishing characteristics of an @property.
   DeclContext *DC, *LexicalDC;

Modified: cfe/trunk/test/ASTMerge/Inputs/interface1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/interface1.m?rev=121097&r1=121096&r2=121097&view=diff
==============================================================================
--- cfe/trunk/test/ASTMerge/Inputs/interface1.m (original)
+++ cfe/trunk/test/ASTMerge/Inputs/interface1.m Mon Dec  6 19:26:03 2010
@@ -79,3 +79,25 @@
 @protocol P4
 - (double)honk:(int)a;
 @end
+
+// Interface with implementation
+ at interface I13
+ at end
+
+ at implementation I13
+ at end
+
+ at interface I13a
+ at end
+
+ at implementation I13a
+ at end
+
+// Implementation by itself
+ at implementation I14 : I12
+ at end
+
+ at implementation I15 : I12
+ at end
+
+

Modified: cfe/trunk/test/ASTMerge/Inputs/interface2.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/interface2.m?rev=121097&r1=121096&r2=121097&view=diff
==============================================================================
--- cfe/trunk/test/ASTMerge/Inputs/interface2.m (original)
+++ cfe/trunk/test/ASTMerge/Inputs/interface2.m Mon Dec  6 19:26:03 2010
@@ -78,3 +78,23 @@
 @protocol P5
 - (double)honk:(int)a;
 @end
+
+// Interface with implementation
+ at interface I13
+ at end
+
+ at implementation I13
+ at end
+
+ at interface I13b
+ at end
+
+ at implementation I13b
+ at end
+
+// Implementation by itself
+ at implementation I14 : I12
+ at end
+
+ at implementation I15 : I11
+ at end

Modified: cfe/trunk/test/ASTMerge/interface.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/interface.m?rev=121097&r1=121096&r2=121097&view=diff
==============================================================================
--- cfe/trunk/test/ASTMerge/interface.m (original)
+++ cfe/trunk/test/ASTMerge/interface.m Mon Dec  6 19:26:03 2010
@@ -15,5 +15,8 @@
 // CHECK: interface1.m:46:1: note: class method 'bar:' also declared here
 // CHECK: interface2.m:57:20: error: instance method 'bar:' has a parameter with a different types in different translation units ('double' vs. 'float')
 // CHECK: interface1.m:58:19: note: declared here with type 'float'
-// CHECK: 6 errors generated
+// CHECK: interface1.m:100:1: error: class 'I15' has incompatible superclasses
+// CHECK: interface1.m:100:1: note: inherits from superclass 'I12' here
+// CHECK: interface2.m:99:1: note: inherits from superclass 'I11' here
+// CHECK: 8 errors generated
 





More information about the cfe-commits mailing list