[cfe-commits] r121159 - in /cfe/trunk: include/clang/Basic/DiagnosticASTKinds.td lib/AST/ASTImporter.cpp test/ASTMerge/Inputs/property1.m test/ASTMerge/Inputs/property2.m test/ASTMerge/property.m

Douglas Gregor dgregor at apple.com
Tue Dec 7 10:32:03 PST 2010


Author: dgregor
Date: Tue Dec  7 12:32:03 2010
New Revision: 121159

URL: http://llvm.org/viewvc/llvm-project?rev=121159&view=rev
Log:
Implement AST import for Objective-C property implementations
(@synthesize and @dynamic).

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/test/ASTMerge/Inputs/property1.m
    cfe/trunk/test/ASTMerge/Inputs/property2.m
    cfe/trunk/test/ASTMerge/property.m

Modified: cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td?rev=121159&r1=121158&r2=121159&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td Tue Dec  7 12:32:03 2010
@@ -56,6 +56,8 @@
   "class has %0 base %plural{1:class|:classes}0">;
 def note_odr_enumerator : Note<"enumerator %0 with value %1 here">;
 def note_odr_missing_enumerator : Note<"no corresponding enumerator here">;
+
+// Importing Objective-C ASTs
 def err_odr_ivar_type_inconsistent : Error<
   "instance variable %0 declared with incompatible types in different "
   "translation units (%1 vs. %2)">;
@@ -80,6 +82,18 @@
 def err_odr_objc_property_type_inconsistent : Error<
   "property %0 declared with incompatible types in different "
   "translation units (%1 vs. %2)">;
+def err_odr_objc_property_impl_kind_inconsistent : Error<
+  "property %0 is implemented with %select{@synthesize|@dynamic}1 in one "
+  "translation but %select{@dynamic|@synthesize}1 in another translation unit">;
+def note_odr_objc_property_impl_kind : Note<
+  "property %0 is implemented with %select{@synthesize|@dynamic}1 here">;
+def err_odr_objc_synthesize_ivar_inconsistent : Error<
+  "property %0 is synthesized to different ivars in different translation "
+  "units (%1 vs. %2)">;
+def note_odr_objc_synthesize_ivar_here : Note<
+  "property is synthesized to ivar %0 here">;
+
+// Importing C++ ASTs
 def err_odr_different_num_template_parameters : Error<
   "template parameter lists have a different number of parameters (%0 vs %1)">;
 def note_odr_template_parameter_list : Note<

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=121159&r1=121158&r2=121159&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Dec  7 12:32:03 2010
@@ -118,6 +118,7 @@
     Decl *VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
     Decl *VisitObjCImplementationDecl(ObjCImplementationDecl *D);
     Decl *VisitObjCPropertyDecl(ObjCPropertyDecl *D);
+    Decl *VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
     Decl *VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
     Decl *VisitObjCClassDecl(ObjCClassDecl *D);
     Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
@@ -3195,6 +3196,87 @@
   return ToProperty;
 }
 
+Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+  ObjCPropertyDecl *Property = cast_or_null<ObjCPropertyDecl>(
+                                        Importer.Import(D->getPropertyDecl()));
+  if (!Property)
+    return 0;
+
+  DeclContext *DC = Importer.ImportContext(D->getDeclContext());
+  if (!DC)
+    return 0;
+  
+  // Import the lexical declaration context.
+  DeclContext *LexicalDC = DC;
+  if (D->getDeclContext() != D->getLexicalDeclContext()) {
+    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
+    if (!LexicalDC)
+      return 0;
+  }
+
+  ObjCImplDecl *InImpl = dyn_cast<ObjCImplDecl>(LexicalDC);
+  if (!InImpl)
+    return 0;
+
+  // Import the ivar (for an @synthesize).
+  ObjCIvarDecl *Ivar = 0;
+  if (D->getPropertyIvarDecl()) {
+    Ivar = cast_or_null<ObjCIvarDecl>(
+                                    Importer.Import(D->getPropertyIvarDecl()));
+    if (!Ivar)
+      return 0;
+  }
+
+  ObjCPropertyImplDecl *ToImpl
+    = InImpl->FindPropertyImplDecl(Property->getIdentifier());
+  if (!ToImpl) {    
+    ToImpl = ObjCPropertyImplDecl::Create(Importer.getToContext(), DC,
+                                          Importer.Import(D->getLocStart()),
+                                          Importer.Import(D->getLocation()),
+                                          Property,
+                                          D->getPropertyImplementation(),
+                                          Ivar, 
+                                  Importer.Import(D->getPropertyIvarDeclLoc()));
+    ToImpl->setLexicalDeclContext(LexicalDC);
+    Importer.Imported(D, ToImpl);
+    LexicalDC->addDecl(ToImpl);
+  } else {
+    // Check that we have the same kind of property implementation (@synthesize
+    // vs. @dynamic).
+    if (D->getPropertyImplementation() != ToImpl->getPropertyImplementation()) {
+      Importer.ToDiag(ToImpl->getLocation(), 
+                      diag::err_odr_objc_property_impl_kind_inconsistent)
+        << Property->getDeclName() 
+        << (ToImpl->getPropertyImplementation() 
+                                              == ObjCPropertyImplDecl::Dynamic);
+      Importer.FromDiag(D->getLocation(),
+                        diag::note_odr_objc_property_impl_kind)
+        << D->getPropertyDecl()->getDeclName()
+        << (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
+      return 0;
+    }
+    
+    // For @synthesize, check that we have the same 
+    if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize &&
+        Ivar != ToImpl->getPropertyIvarDecl()) {
+      Importer.ToDiag(ToImpl->getPropertyIvarDeclLoc(), 
+                      diag::err_odr_objc_synthesize_ivar_inconsistent)
+        << Property->getDeclName()
+        << ToImpl->getPropertyIvarDecl()->getDeclName()
+        << Ivar->getDeclName();
+      Importer.FromDiag(D->getPropertyIvarDeclLoc(), 
+                        diag::note_odr_objc_synthesize_ivar_here)
+        << D->getPropertyIvarDecl()->getDeclName();
+      return 0;
+    }
+    
+    // Merge the existing implementation with the new implementation.
+    Importer.Imported(D, ToImpl);
+  }
+  
+  return ToImpl;
+}
+
 Decl *
 ASTNodeImporter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
   // Import the context of this declaration.

Modified: cfe/trunk/test/ASTMerge/Inputs/property1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/property1.m?rev=121159&r1=121158&r2=121159&view=diff
==============================================================================
--- cfe/trunk/test/ASTMerge/Inputs/property1.m (original)
+++ cfe/trunk/test/ASTMerge/Inputs/property1.m Tue Dec  7 12:32:03 2010
@@ -10,3 +10,22 @@
 @property (readonly) float Prop1;
 @end
 
+// Properties with implementations
+ at interface I3 {
+  int ivar1;
+  int ivar2;
+  int ivar3;
+  int Prop4;
+}
+ at property int Prop1;
+ at property int Prop2;
+ at property int Prop3;
+ at property int Prop4;
+ at end
+
+ at implementation I3
+ at synthesize Prop1 = ivar1;
+ at synthesize Prop2 = ivar3;
+ at dynamic Prop3;
+ at synthesize Prop4;
+ at end

Modified: cfe/trunk/test/ASTMerge/Inputs/property2.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/Inputs/property2.m?rev=121159&r1=121158&r2=121159&view=diff
==============================================================================
--- cfe/trunk/test/ASTMerge/Inputs/property2.m (original)
+++ cfe/trunk/test/ASTMerge/Inputs/property2.m Tue Dec  7 12:32:03 2010
@@ -11,3 +11,23 @@
 @interface I2
 @property (readonly) int Prop1;
 @end
+
+// Properties with implementations
+ at interface I3 {
+  int ivar1;
+  int ivar2;
+  int ivar3;
+  int Prop4;
+}
+ at property int Prop1;
+ at property int Prop2;
+ at property int Prop3;
+ at property int Prop4;
+ at end
+
+ at implementation I3
+ at synthesize Prop2 = ivar2;
+ at synthesize Prop1 = ivar1;
+ at synthesize Prop3 = ivar3;
+ at synthesize Prop4 = Prop4;
+ at end

Modified: cfe/trunk/test/ASTMerge/property.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/property.m?rev=121159&r1=121158&r2=121159&view=diff
==============================================================================
--- cfe/trunk/test/ASTMerge/property.m (original)
+++ cfe/trunk/test/ASTMerge/property.m Tue Dec  7 12:32:03 2010
@@ -6,4 +6,8 @@
 // CHECK: property1.m:10:28: note: declared here with type 'float'
 // CHECK: property2.m:12:26: error: instance method 'Prop1' has incompatible result types in different translation units ('int' vs. 'float')
 // CHECK: property1.m:10:28: note: instance method 'Prop1' also declared here
-// CHECK: 2 errors generated.
+// CHECK: property1.m:28:21: error: property 'Prop2' is synthesized to different ivars in different translation units ('ivar3' vs. 'ivar2')
+// CHECK: property2.m:29:21: note: property is synthesized to ivar 'ivar2' here
+// CHECK: property1.m:29:10: error: property 'Prop3' is implemented with @dynamic in one translation but @synthesize in another translation unit
+// CHECK: property2.m:31:13: note: property 'Prop3' is implemented with @synthesize here
+// CHECK: 4 errors generated.





More information about the cfe-commits mailing list