[cfe-commits] r49882 - in /cfe/trunk: include/clang/AST/DeclObjC.h include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Action.h lib/Parse/ParseObjc.cpp lib/Sema/Sema.h lib/Sema/SemaDeclObjC.cpp

Fariborz Jahanian fjahanian at apple.com
Thu Apr 17 17:19:31 PDT 2008


Author: fjahanian
Date: Thu Apr 17 19:19:30 2008
New Revision: 49882

URL: http://llvm.org/viewvc/llvm-project?rev=49882&view=rev
Log:
Initial work for property implementation declarations.
Mostly semantic checking in this patch. This is on going
and incomplete.


Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/lib/Parse/ParseObjc.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=49882&r1=49881&r2=49882&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Thu Apr 17 19:19:30 2008
@@ -27,6 +27,7 @@
 class ObjCProtocolDecl;
 class ObjCCategoryDecl;
 class ObjCPropertyDecl;
+class ObjCPropertyImplDecl;
 
 /// ObjCMethodDecl - Represents an instance or class method declaration.
 /// ObjC methods can be declared within 4 contexts: class interfaces,
@@ -807,6 +808,9 @@
   
   /// implemented class methods
   llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods;
+  
+  /// Propertys' being implemented
+  llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations;
 
   SourceLocation EndLoc;  
 
@@ -829,13 +833,20 @@
   }
   void addClassMethod(ObjCMethodDecl *method) {
     ClassMethods.push_back(method);
-  }    
+  }   
   // Get the instance method definition for this implementation.
   ObjCMethodDecl *getInstanceMethod(Selector Sel);
   
   // Get the class method definition for this implementation.
   ObjCMethodDecl *getClassMethod(Selector Sel);
+  
+  void addPropertyImplementation(ObjCPropertyImplDecl *property) {
+    PropertyImplementations.push_back(property);
+  }
 
+  unsigned getNumPropertyImplementations() const
+  { return PropertyImplementations.size(); }
+  
   typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
     instmeth_iterator;
   instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
@@ -888,6 +899,9 @@
   /// implemented class methods
   llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods;
 
+  /// Propertys' being implemented
+  llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations;
+  
   SourceLocation EndLoc;
 
   ObjCImplementationDecl(SourceLocation L, IdentifierInfo *Id,
@@ -912,6 +926,11 @@
   void addClassMethod(ObjCMethodDecl *method) {
     ClassMethods.push_back(method);
   }    
+  
+  void addPropertyImplementation(ObjCPropertyImplDecl *property) {
+    PropertyImplementations.push_back(property);
+  } 
+  
   // Location information, modeled after the Stmt API. 
   SourceLocation getLocStart() const { return getLocation(); }
   SourceLocation getLocEnd() const { return EndLoc; }
@@ -926,6 +945,9 @@
   
   unsigned getNumInstanceMethods() const { return InstanceMethods.size(); }
   unsigned getNumClassMethods() const { return ClassMethods.size(); }
+  
+  unsigned getNumPropertyImplementations() const 
+    { return PropertyImplementations.size(); }
 
   typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
        instmeth_iterator;
@@ -1041,14 +1063,15 @@
     OBJC_PR_IMPL_DYNAMIC
   };
 private:
+  SourceLocation AtLoc;   // location of @syntheisze or @dynamic
   /// Property declaration being implemented
   ObjCPropertyDecl *PropertyDecl;
   PropertyImplKind PropertyImplementation;
   /// Null for @dynamic. Required for @synthesize.
   ObjCIvarDecl *PropertyIvarDecl;
 public:
-  ObjCPropertyImplDecl(SourceLocation L)
-  : Decl(ObjCPropertyImpl, L), PropertyDecl(0), 
+  ObjCPropertyImplDecl(SourceLocation atLoc, SourceLocation L)
+  : Decl(ObjCPropertyImpl, L), AtLoc(atLoc), PropertyDecl(0), 
   PropertyImplementation(OBJC_PR_IMPL_None), PropertyIvarDecl(0) {}
 
   void setPropertyDecl(ObjCPropertyDecl *property) { PropertyDecl = property; }

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=49882&r1=49881&r2=49882&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Thu Apr 17 19:19:30 2008
@@ -487,6 +487,20 @@
      "bad receiver type '%0'")
 DIAG(error_no_super_class, ERROR,
      "no super class declared in @interface for '%0'")
+DIAG(error_missing_property_context, ERROR,
+     "missing context for property implementation declaration")
+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'")
+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")
+DIAG(error_missing_property_ivar_decl, ERROR,
+     "property synthesize requires a previously declared ivar")
 
 //===----------------------------------------------------------------------===//
 // Semantic Analysis

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=49882&r1=49881&r2=49882&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Thu Apr 17 19:19:30 2008
@@ -626,6 +626,18 @@
     SourceLocation CatLoc) {
     return 0;
   }  
+  // ActOnPropertyImplDecl - called for every property implementation
+  virtual DeclTy *ActOnPropertyImplDecl(
+   SourceLocation AtLoc,              // location of the @syntheize/@dynamic
+   SourceLocation PropertyNameLoc,    // location for the property name
+   bool ImplKind,                     // true for @synthesize, false for
+                                      // @dynamic
+   DeclTy *ClassImplDecl,             // class or category implementation
+   IdentifierInfo *propertyId,        // name of property
+   IdentifierInfo *propertyIvar) {    // name of the ivar
+    return 0;
+  }
+
   // ActOnMethodDeclaration - called for all method declarations. 
   virtual DeclTy *ActOnMethodDeclaration(
     SourceLocation BeginLoc,   // location of the + or -.

Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=49882&r1=49881&r2=49882&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Thu Apr 17 19:19:30 2008
@@ -1031,13 +1031,15 @@
 Parser::DeclTy *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
   assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
          "ParseObjCPropertyDynamic(): Expected '@synthesize'");
-  SourceLocation loc = ConsumeToken(); // consume dynamic
+  SourceLocation loc = ConsumeToken(); // consume synthesize
   if (Tok.isNot(tok::identifier)) {
     Diag(Tok, diag::err_expected_ident);
     return 0;
   }
   while (Tok.is(tok::identifier)) {
-    ConsumeToken(); // consume property name
+    IdentifierInfo *propertyIvar = 0;
+    IdentifierInfo *propertyId = Tok.getIdentifierInfo();
+    SourceLocation propertyLoc = ConsumeToken(); // consume property name
     if (Tok.is(tok::equal)) {
       // property '=' ivar-name
       ConsumeToken(); // consume '='
@@ -1045,8 +1047,11 @@
         Diag(Tok, diag::err_expected_ident);
         break;
       }
+      propertyIvar = Tok.getIdentifierInfo();
       ConsumeToken(); // consume ivar-name
     }
+    Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, true, ObjCImpDecl,
+                                  propertyId, propertyIvar);
     if (Tok.isNot(tok::comma))
       break;
     ConsumeToken(); // consume ','

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=49882&r1=49881&r2=49882&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Apr 17 19:19:30 2008
@@ -656,7 +656,13 @@
                       DeclTy **allProperties = 0, unsigned pNum = 0);
   
   virtual DeclTy *ActOnProperty(Scope *S, SourceLocation AtLoc,
-                                FieldDeclarator &FD, ObjCDeclSpec &ODS);  
+                                FieldDeclarator &FD, ObjCDeclSpec &ODS);
+  virtual DeclTy *ActOnPropertyImplDecl(SourceLocation AtLoc, 
+                                        SourceLocation PropertyLoc,
+                                        bool ImplKind, DeclTy *ClassImplDecl,
+                                        IdentifierInfo *PropertyId,
+                                        IdentifierInfo *PropertyIvar);
+  
   virtual DeclTy *ActOnMethodDeclaration(
     SourceLocation BeginLoc, // location of the + or -.
     SourceLocation EndLoc,   // location of the ; or {.

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=49882&r1=49881&r2=49882&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu Apr 17 19:19:30 2008
@@ -929,5 +929,116 @@
   return PDecl;
 }
 
-
+/// ActOnPropertyImplDecl - This routine performas semantic checks and
+/// build the AST node for a property implementation declaration; declared
+/// as @synthesize ot @dynamic
+///
+Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, 
+                                          SourceLocation PropertyLoc,
+                                          bool Synthesize, 
+                                          DeclTy *ClassCatImpDecl,
+                                          IdentifierInfo *PropertyId,
+                                          IdentifierInfo *PropertyIvar) {
+  Decl *ClassImpDecl = static_cast<Decl*>(ClassCatImpDecl);
+  // Make sure we have a context for the property implementation declaration.
+  if (!ClassImpDecl) {
+    Diag(AtLoc, diag::error_missing_property_context);
+    return 0;
+  }
+  ObjCPropertyDecl *property = 0;
+  ObjCInterfaceDecl* IDecl = 0;
+  // Find the class or category class where this property must have
+  // a declaration.
+  if (ObjCImplementationDecl *IC = 
+        dyn_cast<ObjCImplementationDecl>(ClassImpDecl)) {
+    IDecl = getObjCInterfaceDecl(IC->getIdentifier());
+    if (!IDecl) {
+      Diag(AtLoc, diag::error_missing_property_interface);
+      return 0;
+    }
+    // Look for this property declaration in the @implementation's @interface
+    ObjCInterfaceDecl::classprop_iterator I,E;
+    for (I = IDecl->classprop_begin(),
+         E = IDecl->classprop_end(); I != E; ++I) {
+      property = *I;
+      if (property->getIdentifier() == PropertyId)
+        break;
+    }
+    if (I == E) {
+      Diag(PropertyLoc, diag::error_bad_property_decl, IDecl->getName());
+      return 0;
+    }    
+  }
+  else if (ObjCCategoryImplDecl* CatImplClass = 
+            dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl)) {
+    IDecl = CatImplClass->getClassInterface();
+    if (!IDecl) {
+      Diag(AtLoc, diag::error_missing_property_interface);
+      return 0;
+    }
+    ObjCCategoryDecl *Categories;
+    for (ObjCCategoryDecl *Categories = IDecl->getCategoryList();
+         Categories; Categories = Categories->getNextClassCategory())
+      if (Categories->getIdentifier() == CatImplClass->getIdentifier())
+        break;
+    // If category for this implementation not found, it is an error which
+    // has already been reported eralier.
+    if (!Categories)
+      return 0;
+    // Look for this property declaration in @implementation's category
+    ObjCCategoryDecl::classprop_iterator I,E;
+    for (I = Categories->classprop_begin(),
+         E = Categories->classprop_end(); I != E; ++I) {
+      property = *I;
+      if (property->getIdentifier() == PropertyId)
+        break;
+    }
+    if (I == E) {
+      Diag(PropertyLoc, diag::error_bad_property_decl, 
+           Categories->getName());
+      return 0;
+    }
+  }
+  else {
+    Diag(AtLoc, diag::error_bad_property_context);
+    return 0;
+  }
+  
+  // Check that we have a valid, previously declared ivar for @synthesize
+  if (Synthesize) {
+    // @synthesize
+    if (!PropertyIvar) {
+      Diag(PropertyLoc, diag::error_property_ivar_decl);
+      return 0;
+    }
+    // Check that this is a previously declared 'ivar' in 'IDecl' interface
+    ObjCInterfaceDecl::ivar_iterator IVI, IVE;
+    for (IVI = IDecl->ivar_begin(), IVE = IDecl->ivar_end(); 
+         IVI != IVE; ++IVI) {
+      ObjCIvarDecl* ImplIvar = (*IVI);
+      if (ImplIvar->getIdentifier() == PropertyIvar)
+        break;
+    }
+    if (IVI == IVE) {
+      Diag(PropertyLoc, diag::error_missing_property_ivar_decl);
+      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
+#if 0
+  ObjCCategoryImplDecl *PIDecl = 
+    ObjCCategoryImplDecl::Create(AtLoc, PropertyLoc, property, 
+      Synthesize ? ObjCPropertyImplDecl::OBJC_PR_IMPL_SYNTHSIZE 
+                 : ObjCPropertyImplDecl::OBJC_PR_IMPL_DYNAMIC,
+                                 PropertyId, PropertyIvar);
+#endif
+  return 0;
+}
 





More information about the cfe-commits mailing list