[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