]> granicus.if.org Git - clang/commitdiff
Support for @dynamic AST build.
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 21 Apr 2008 21:05:54 +0000 (21:05 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 21 Apr 2008 21:05:54 +0000 (21:05 +0000)
More property semantics checking.
First test case for ObjC2's property implementation.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50057 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclObjC.h
include/clang/Basic/DiagnosticKinds.def
lib/Parse/ParseObjc.cpp
lib/Sema/SemaDeclObjC.cpp
test/Sema/objc-property-1.m [new file with mode: 0644]

index 6a34696462c3e83232c3db53d24aec2033809dfd..72c8e025a8118a714b60e4718871690c60b96098 100644 (file)
@@ -1066,6 +1066,8 @@ public:
   static ObjCPropertyDecl *Create(ASTContext &C, SourceLocation L, 
                                   IdentifierInfo *Id, QualType T);
   QualType getType() const { return DeclType; }
+  QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
+  
   PropertyAttributeKind getPropertyAttributes() const {
     return PropertyAttributeKind(PropertyAttributes);
   }
index 459121003226f2c4c247e14fc1d711a4384fbe41..4f46eaa02842178c682563af254e4b1b72f24a8d 100644 (file)
@@ -492,15 +492,21 @@ DIAG(error_missing_property_context, ERROR,
 DIAG(error_bad_property_context, ERROR,
      "property implementation must be in a class or category implementation")
 DIAG(error_bad_property_decl, ERROR,
-     "property implementation must have the declaration in the class '%0'")
+     "property implementation must have its declaration in the class '%0'")
+DIAG(error_bad_category_property_decl, ERROR,
+     "property implementation must have its declaration in the category '%0'")
 DIAG(error_property_ivar_decl, ERROR,
      "property synthesize requires specification of an ivar")
 DIAG(error_dynamic_property_ivar_decl, ERROR,
      "dynamic property can not have ivar specification")
 DIAG(error_missing_property_interface, ERROR,
-     "property implementation in a class/category implementation with no interface")
+     "property implementation in a category with no category declaration")
 DIAG(error_missing_property_ivar_decl, ERROR,
      "property synthesize requires a previously declared ivar")
+DIAG(error_synthesize_category_decl, ERROR,
+     "@synthesize not allowed in a category's implementation")
+DIAG(error_property_ivar_type, ERROR,
+     "type of property '%0'  does not match type of ivar '%1'") 
 
 //===----------------------------------------------------------------------===//
 // Semantic Analysis
index ede0edb354ac1f2254a455a26bd0b9b8ae763e94..0c5cf20ef8eb13ef61ca70ffe0bef1168722ca85 100644 (file)
@@ -1077,7 +1077,11 @@ Parser::DeclTy *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
     return 0;
   }
   while (Tok.is(tok::identifier)) {
-    ConsumeToken(); // consume property name
+    IdentifierInfo *propertyId = Tok.getIdentifierInfo();
+    SourceLocation propertyLoc = ConsumeToken(); // consume property name
+    Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl,
+                                  propertyId, 0);
+
     if (Tok.isNot(tok::comma))
       break;
     ConsumeToken(); // consume ','
index 21130a04fa023b0b7fdc9d07bfcfb14190407068..45d877778568eff4999818ea3a0dbf7bcfaba49e 100644 (file)
@@ -952,10 +952,11 @@ Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
   if (ObjCImplementationDecl *IC = 
         dyn_cast<ObjCImplementationDecl>(ClassImpDecl)) {
     IDecl = getObjCInterfaceDecl(IC->getIdentifier());
-    if (!IDecl) {
-      Diag(AtLoc, diag::error_missing_property_interface);
-      return 0;
-    }
+    // We always synthesize an interface for an implementation
+    // without an interface decl. So, IDecl is always non-zero.
+    assert(IDecl && 
+           "ActOnPropertyImplDecl - @implementation without @interface");
+    
     // Look for this property declaration in the @implementation's @interface
     property = IDecl->FindPropertyDeclaration(PropertyId);
     if (!property) {
@@ -965,6 +966,10 @@ Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
   }
   else if (ObjCCategoryImplDecl* CatImplClass = 
             dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl)) {
+    if (Synthesize) {
+      Diag(AtLoc, diag::error_synthesize_category_decl);
+      return 0;
+    }    
     IDecl = CatImplClass->getClassInterface();
     if (!IDecl) {
       Diag(AtLoc, diag::error_missing_property_interface);
@@ -980,7 +985,7 @@ Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
     // Look for this property declaration in @implementation's category
     property = Category->FindPropertyDeclaration(PropertyId);
     if (!property) {
-      Diag(PropertyLoc, diag::error_bad_property_decl, 
+      Diag(PropertyLoc, diag::error_bad_category_property_decl, 
            Category->getName());
       return 0;
     }
@@ -998,16 +1003,23 @@ Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
       return 0;
     }
     // Check that this is a previously declared 'ivar' in 'IDecl' interface
-    if (!IDecl->FindIvarDeclaration(PropertyIvar)) {
+    ObjCIvarDecl *Ivar = IDecl->FindIvarDeclaration(PropertyIvar);
+    if (!Ivar) {
       Diag(PropertyLoc, diag::error_missing_property_ivar_decl);
       return 0;
     }
+    // Check that type of property and its ivar match. 
+    if (Ivar->getCanonicalType() != property->getCanonicalType()) {
+      Diag(PropertyLoc, diag::error_property_ivar_type, property->getName(),
+           Ivar->getName());
+      return 0;
+    }
+      
   } else if (PropertyIvar) {
     // @dynamic
     Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl);
     return 0;
   }
-  // TODO: More diagnostics go here !!
   assert (property && "ActOnPropertyImplDecl - property declaration missing");
   // TODO: Build the property implementation AST, pushes it into its 
   // class/cateogory implementation's vector of property implementations
diff --git a/test/Sema/objc-property-1.m b/test/Sema/objc-property-1.m
new file mode 100644 (file)
index 0000000..d307d13
--- /dev/null
@@ -0,0 +1,36 @@
+// RUN: clang -fsyntax-only -verify %s
+
+@interface I 
+{
+       int IVAR;
+}
+@property int d1;
+@property id  prop_id;
+@end
+
+@interface I(CAT)
+@property int d1;
+@end
+
+@implementation I
+@synthesize d1;                // expected-error {{property synthesize requires specification of an ivar}}
+@dynamic    bad;       // expected-error {{property implementation must have its declaration in the class 'I'}}
+@synthesize prop_id;   // expected-error {{property synthesize requires specification of an ivar}}
+@synthesize prop_id = IVAR;    // expected-error {{type of property 'prop_id'  does not match type of ivar 'IVAR'}}
+@end
+
+@implementation I(CAT)
+@synthesize d1;                // expected-error {{@synthesize not allowed in a category's implementation}}
+@dynamic bad;          // expected-error {{property implementation must have its declaration in the category 'CAT'}}
+@end
+
+@implementation E      // expected-warning {{cannot find interface declaration for 'E'}}
+@dynamic d;            // expected-error {{property implementation must have its declaration in the class 'E'}}
+@end
+
+@implementation Q(MYCAT)  // expected-error {{cannot find interface declaration for 'Q'}}
+@dynamic d;            // expected-error {{property implementation in a category with no category declaration}}
+@end
+
+
+