[cfe-commits] r96478 - 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
Wed Feb 17 08:12:01 PST 2010
Author: dgregor
Date: Wed Feb 17 10:12:00 2010
New Revision: 96478
URL: http://llvm.org/viewvc/llvm-project?rev=96478&view=rev
Log:
AST import for Objective-C protocols
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=96478&r1=96477&r2=96478&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Feb 17 10:12:00 2010
@@ -94,6 +94,7 @@
Decl *VisitVarDecl(VarDecl *D);
Decl *VisitParmVarDecl(ParmVarDecl *D);
Decl *VisitObjCMethodDecl(ObjCMethodDecl *D);
+ Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D);
Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
// Importing statements
@@ -2130,6 +2131,70 @@
return ToMethod;
}
+Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
+ // Import the major distinguishing characteristics of an @protocol.
+ DeclContext *DC, *LexicalDC;
+ DeclarationName Name;
+ SourceLocation Loc;
+ if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
+ return 0;
+
+ ObjCProtocolDecl *MergeWithProtocol = 0;
+ for (DeclContext::lookup_result Lookup = DC->lookup(Name);
+ Lookup.first != Lookup.second;
+ ++Lookup.first) {
+ if (!(*Lookup.first)->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
+ continue;
+
+ if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(*Lookup.first)))
+ break;
+ }
+
+ ObjCProtocolDecl *ToProto = MergeWithProtocol;
+ if (!ToProto || ToProto->isForwardDecl()) {
+ if (!ToProto) {
+ ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC, Loc,
+ Name.getAsIdentifierInfo());
+ ToProto->setForwardDecl(D->isForwardDecl());
+ ToProto->setLexicalDeclContext(LexicalDC);
+ LexicalDC->addDecl(ToProto);
+ }
+ Importer.Imported(D, ToProto);
+
+ // Import protocols
+ llvm::SmallVector<ObjCProtocolDecl *, 4> Protocols;
+ llvm::SmallVector<SourceLocation, 4> ProtocolLocs;
+ ObjCProtocolDecl::protocol_loc_iterator
+ FromProtoLoc = D->protocol_loc_begin();
+ for (ObjCProtocolDecl::protocol_iterator FromProto = D->protocol_begin(),
+ FromProtoEnd = D->protocol_end();
+ FromProto != FromProtoEnd;
+ ++FromProto, ++FromProtoLoc) {
+ ObjCProtocolDecl *ToProto
+ = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
+ if (!ToProto)
+ return 0;
+ Protocols.push_back(ToProto);
+ ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
+ }
+
+ // FIXME: If we're merging, make sure that the protocol list is the same.
+ ToProto->setProtocolList(Protocols.data(), Protocols.size(),
+ ProtocolLocs.data(), Importer.getToContext());
+ } else {
+ Importer.Imported(D, ToProto);
+ }
+
+ // Import all of the members of this class.
+ for (DeclContext::decl_iterator FromMem = D->decls_begin(),
+ FromMemEnd = D->decls_end();
+ FromMem != FromMemEnd;
+ ++FromMem)
+ Importer.Import(*FromMem);
+
+ return ToProto;
+}
+
Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
// Import the major distinguishing characteristics of an @interface.
DeclContext *DC, *LexicalDC;
@@ -2158,6 +2223,7 @@
Importer.Import(D->getClassLoc()),
D->isForwardDecl(),
D->isImplicitInterfaceDecl());
+ ToIface->setForwardDecl(D->isForwardDecl());
ToIface->setLexicalDeclContext(LexicalDC);
LexicalDC->addDecl(ToIface);
}
@@ -2246,7 +2312,7 @@
ToIface->setImplementation(Impl);
}
- return 0;
+ return ToIface;
}
//----------------------------------------------------------------------------
Modified: cfe/trunk/test/ASTMerge/Inputs/interface1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/interface1.m?rev=96478&r1=96477&r2=96478&view=diff
==============================================================================
--- cfe/trunk/test/ASTMerge/Inputs/interface1.m (original)
+++ cfe/trunk/test/ASTMerge/Inputs/interface1.m Wed Feb 17 10:12:00 2010
@@ -45,3 +45,26 @@
- (int)foo;
+ (int)bar:(float)x;
@end
+
+// Matching protocol
+ at protocol P0
++ (int)foo;
+- (int)bar:(float)x;
+ at end
+
+// Protocol with mismatching method
+ at protocol P1
++ (int)foo;
+- (int)bar:(float)x;
+ at end
+
+// Interface with protocol
+ at interface I9 <P0>
++ (int)foo;
+- (int)bar:(float)x;
+ at end
+
+// Protocol with protocol
+ at protocol P2 <P0>
+- (float)wibble:(int)a1 second:(int)a2;
+ 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=96478&r1=96477&r2=96478&view=diff
==============================================================================
--- cfe/trunk/test/ASTMerge/Inputs/interface2.m (original)
+++ cfe/trunk/test/ASTMerge/Inputs/interface2.m Wed Feb 17 10:12:00 2010
@@ -44,3 +44,26 @@
- (int)foo;
+ (int)bar:(float)x, ...;
@end
+
+// Matching protocol
+ at protocol P0
++ (int)foo;
+- (int)bar:(float)x;
+ at end
+
+// Protocol with mismatching method
+ at protocol P1
++ (int)foo;
+- (int)bar:(double)x;
+ at end
+
+// Interface with protocol
+ at interface I9 <P0>
++ (int)foo;
+- (int)bar:(float)x;
+ at end
+
+// Protocol with protocol
+ at protocol P2 <P0>
+- (float)wibble:(int)a1 second:(int)a2;
+ at end
Modified: cfe/trunk/test/ASTMerge/interface.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/interface.m?rev=96478&r1=96477&r2=96478&view=diff
==============================================================================
--- cfe/trunk/test/ASTMerge/interface.m (original)
+++ cfe/trunk/test/ASTMerge/interface.m Wed Feb 17 10:12:00 2010
@@ -13,5 +13,7 @@
// CHECK: interface1.m:40:17: note: declared here with type 'int'
// CHECK: interface2.m:45:1: error: class method 'bar:' is variadic in one translation unit and not variadic in another
// CHECK: interface1.m:46:1: note: class method 'bar:' also declared here
-// CHECK: 11 diagnostics generated
+// 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: 13 diagnostics generated
More information about the cfe-commits
mailing list