[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