[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