[cfe-commits] r103123 - in /cfe/trunk: include/clang/AST/DeclObjC.h include/clang/Parse/Action.h lib/CodeGen/CGObjC.cpp lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriterDecl.cpp lib/Parse/ParseObjc.cpp lib/Sema/Sema.h lib/Sema/SemaDeclObjC.cpp lib/Sema/SemaObjCProperty.cpp

Fariborz Jahanian fjahanian at apple.com
Wed May 5 14:52:17 PDT 2010


Author: fjahanian
Date: Wed May  5 16:52:17 2010
New Revision: 103123

URL: http://llvm.org/viewvc/llvm-project?rev=103123&view=rev
Log:
This patch deals with Sema Part of Setter/Getter synthesis
of properties which are of C++ objects. Code Gen to follow
(Radar 7468090).

Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
    cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
    cfe/trunk/lib/Parse/ParseObjc.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaObjCProperty.cpp

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=103123&r1=103122&r2=103123&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Wed May  5 16:52:17 2010
@@ -1421,13 +1421,21 @@
 
   /// Null for @dynamic. Required for @synthesize.
   ObjCIvarDecl *PropertyIvarDecl;
+  
+  /// Null for @dynamic. Non-null if property must be copy-constructed in getter
+  Expr *GetterCXXConstructor;
+  
+  /// Null for @dynamic. Non-null if property has assignment operator to call
+  /// in Setter synthesis.
+  Expr *SetterCXXAssignment;
 
   ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L,
                        ObjCPropertyDecl *property,
                        Kind PK,
                        ObjCIvarDecl *ivarDecl)
     : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
-      PropertyDecl(property), PropertyIvarDecl(ivarDecl) {
+      PropertyDecl(property), PropertyIvarDecl(ivarDecl),
+      GetterCXXConstructor(0), SetterCXXAssignment(0) {
     assert (PK == Dynamic || PropertyIvarDecl);
   }
 
@@ -1457,7 +1465,21 @@
     return PropertyIvarDecl;
   }
   void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; }
+  
+  Expr *getGetterCXXConstructor() const {
+    return GetterCXXConstructor;
+  }
+  void setGetterCXXConstructor(Expr *getterCXXConstructor) {
+    GetterCXXConstructor = getterCXXConstructor;
+  }
 
+  Expr *getSetterCXXAssignment() const {
+    return SetterCXXAssignment;
+  }
+  void setSetterCXXAssignment(Expr *setterCXXAssignment) {
+    SetterCXXAssignment = setterCXXAssignment;
+  }
+  
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classof(const ObjCPropertyImplDecl *D) { return true; }
   static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; }

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=103123&r1=103122&r2=103123&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Wed May  5 16:52:17 2010
@@ -2303,6 +2303,7 @@
   }
   // ActOnPropertyImplDecl - called for every property implementation
   virtual DeclPtrTy ActOnPropertyImplDecl(
+   Scope *S,
    SourceLocation AtLoc,              // location of the @synthesize/@dynamic
    SourceLocation PropertyNameLoc,    // location for the property name
    bool ImplKind,                     // true for @synthesize, false for
@@ -2346,7 +2347,7 @@
   // protocols, categories), the parser passes all methods/properties.
   // For class implementations, these values default to 0. For implementations,
   // methods are processed incrementally (by ActOnMethodDeclaration above).
-  virtual void ActOnAtEnd(SourceRange AtEnd,
+  virtual void ActOnAtEnd(Scope *S, SourceRange AtEnd,
                           DeclPtrTy classDecl,
                           DeclPtrTy *allMethods = 0,
                           unsigned allNum = 0,

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=103123&r1=103122&r2=103123&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Wed May  5 16:52:17 2010
@@ -157,9 +157,6 @@
     !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
   ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
   assert(OMD && "Invalid call to generate getter (empty method)");
-  // FIXME: This is rather murky, we create this here since they will not have
-  // been created by Sema for us.
-  OMD->createImplicitParams(getContext(), IMP->getClassInterface());
   StartObjCMethod(OMD, IMP->getClassInterface());
   
   // Determine if we should use an objc_getProperty call for
@@ -274,9 +271,6 @@
   const ObjCPropertyDecl *PD = PID->getPropertyDecl();
   ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
   assert(OMD && "Invalid call to generate setter (empty method)");
-  // FIXME: This is rather murky, we create this here since they will not have
-  // been created by Sema for us.
-  OMD->createImplicitParams(getContext(), IMP->getClassInterface());
   StartObjCMethod(OMD, IMP->getClassInterface());
 
   bool IsCopy = PD->getSetterKind() == ObjCPropertyDecl::Copy;

Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=103123&r1=103122&r2=103123&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Wed May  5 16:52:17 2010
@@ -394,6 +394,7 @@
                cast_or_null<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++])));
   D->setPropertyIvarDecl(
                    cast_or_null<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
+  // FIXME. read GetterCXXConstructor and SetterCXXAssignment
 }
 
 void PCHDeclReader::VisitFieldDecl(FieldDecl *FD) {

Modified: cfe/trunk/lib/Frontend/PCHWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterDecl.cpp?rev=103123&r1=103122&r2=103123&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterDecl.cpp Wed May  5 16:52:17 2010
@@ -370,6 +370,7 @@
   Writer.AddSourceLocation(D->getLocStart(), Record);
   Writer.AddDeclRef(D->getPropertyDecl(), Record);
   Writer.AddDeclRef(D->getPropertyIvarDecl(), Record);
+  // FIXME. write GetterCXXConstructor and SetterCXXAssignment.
   Code = pch::DECL_OBJC_PROPERTY_IMPL;
 }
 

Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=103123&r1=103122&r2=103123&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Wed May  5 16:52:17 2010
@@ -446,7 +446,7 @@
 
   // Insert collected methods declarations into the @interface object.
   // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit.
-  Actions.ActOnAtEnd(AtEnd, interfaceDecl,
+  Actions.ActOnAtEnd(CurScope, AtEnd, interfaceDecl,
                      allMethods.data(), allMethods.size(),
                      allProperties.data(), allProperties.size(),
                      allTUVariables.data(), allTUVariables.size());
@@ -1277,7 +1277,7 @@
   DeclPtrTy Result = ObjCImpDecl;
   ConsumeToken(); // the "end" identifier
   if (ObjCImpDecl) {
-    Actions.ActOnAtEnd(atEnd, ObjCImpDecl);
+    Actions.ActOnAtEnd(CurScope, atEnd, ObjCImpDecl);
     ObjCImpDecl = DeclPtrTy();
     PendingObjCImpDecl.pop_back();
   }
@@ -1292,7 +1292,7 @@
   if (PendingObjCImpDecl.empty())
     return Actions.ConvertDeclToDeclGroup(DeclPtrTy());
   DeclPtrTy ImpDecl = PendingObjCImpDecl.pop_back_val();
-  Actions.ActOnAtEnd(SourceRange(), ImpDecl);
+  Actions.ActOnAtEnd(CurScope, SourceRange(), ImpDecl);
   return Actions.ConvertDeclToDeclGroup(ImpDecl);
 }
 
@@ -1371,7 +1371,7 @@
       propertyIvar = Tok.getIdentifierInfo();
       ConsumeToken(); // consume ivar-name
     }
-    Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, true, ObjCImpDecl,
+    Actions.ActOnPropertyImplDecl(CurScope, atLoc, propertyLoc, true, ObjCImpDecl,
                                   propertyId, propertyIvar);
     if (Tok.isNot(tok::comma))
       break;
@@ -1411,7 +1411,7 @@
     
     IdentifierInfo *propertyId = Tok.getIdentifierInfo();
     SourceLocation propertyLoc = ConsumeToken(); // consume property name
-    Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl,
+    Actions.ActOnPropertyImplDecl(CurScope, atLoc, propertyLoc, false, ObjCImpDecl,
                                   propertyId, 0);
 
     if (Tok.isNot(tok::comma))

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=103123&r1=103122&r2=103123&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed May  5 16:52:17 2010
@@ -1528,13 +1528,13 @@
 
   /// ImplMethodsVsClassMethods - This is main routine to warn if any method
   /// remains unimplemented in the class or category @implementation.
-  void ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
+  void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
                                  ObjCContainerDecl* IDecl,
                                  bool IncompleteImpl = false);
 
   /// DiagnoseUnimplementedProperties - This routine warns on those properties
   /// which must be implemented by this implementation.
-  void DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
+  void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
                                        ObjCContainerDecl *CDecl,
                                        const llvm::DenseSet<Selector>& InsMap);
 
@@ -3858,7 +3858,7 @@
   void MatchOneProtocolPropertiesInClass(Decl *CDecl,
                                          ObjCProtocolDecl *PDecl);
 
-  virtual void ActOnAtEnd(SourceRange AtEnd,
+  virtual void ActOnAtEnd(Scope *S, SourceRange AtEnd,
                           DeclPtrTy classDecl,
                           DeclPtrTy *allMethods = 0, unsigned allNum = 0,
                           DeclPtrTy *allProperties = 0, unsigned pNum = 0,
@@ -3871,7 +3871,8 @@
                                   bool *OverridingProperty,
                                   tok::ObjCKeywordKind MethodImplKind);
 
-  virtual DeclPtrTy ActOnPropertyImplDecl(SourceLocation AtLoc,
+  virtual DeclPtrTy ActOnPropertyImplDecl(Scope *S,
+                                          SourceLocation AtLoc,
                                           SourceLocation PropertyLoc,
                                           bool ImplKind,DeclPtrTy ClassImplDecl,
                                           IdentifierInfo *PropertyId,

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=103123&r1=103122&r2=103123&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Wed May  5 16:52:17 2010
@@ -925,7 +925,7 @@
   }
 }
 
-void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
+void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
                                      ObjCContainerDecl* CDecl,
                                      bool IncompleteImpl) {
   llvm::DenseSet<Selector> InsMap;
@@ -939,7 +939,7 @@
   // an implementation or 2) there is a @synthesize/@dynamic implementation
   // of the property in the @implementation.
   if (isa<ObjCInterfaceDecl>(CDecl))
-    DiagnoseUnimplementedProperties(IMPDecl, CDecl, InsMap);
+    DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, InsMap);
       
   llvm::DenseSet<Selector> ClsMap;
   for (ObjCImplementationDecl::classmeth_iterator
@@ -968,7 +968,7 @@
     for (ObjCCategoryDecl *Categories = I->getCategoryList();
          Categories; Categories = Categories->getNextClassCategory()) {
       if (Categories->IsClassExtension()) {
-        ImplMethodsVsClassMethods(IMPDecl, Categories, IncompleteImpl);
+        ImplMethodsVsClassMethods(S, IMPDecl, Categories, IncompleteImpl);
         break;
       }
     }
@@ -990,7 +990,7 @@
                I = IMP->instmeth_begin(), E = IMP->instmeth_end(); I!=E; ++I)
             InsMap.insert((*I)->getSelector());
         }
-      DiagnoseUnimplementedProperties(IMPDecl, CDecl, InsMap);      
+      DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, InsMap);      
     } 
   } else
     assert(false && "invalid ObjCContainerDecl type.");
@@ -1326,7 +1326,7 @@
 
 // Note: For class/category implemenations, allMethods/allProperties is
 // always null.
-void Sema::ActOnAtEnd(SourceRange AtEnd,
+void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
                       DeclPtrTy classDecl,
                       DeclPtrTy *allMethods, unsigned allNum,
                       DeclPtrTy *allProperties, unsigned pNum,
@@ -1433,7 +1433,7 @@
   if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
     IC->setAtEndRange(AtEnd);
     if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) {
-      ImplMethodsVsClassMethods(IC, IDecl);
+      ImplMethodsVsClassMethods(S, IC, IDecl);
       AtomicPropertySetterGetterRules(IC, IDecl);
       if (LangOpts.ObjCNonFragileABI2)
         while (IDecl->getSuperClass()) {
@@ -1452,7 +1452,7 @@
       for (ObjCCategoryDecl *Categories = IDecl->getCategoryList();
            Categories; Categories = Categories->getNextClassCategory()) {
         if (Categories->getIdentifier() == CatImplClass->getIdentifier()) {
-          ImplMethodsVsClassMethods(CatImplClass, Categories);
+          ImplMethodsVsClassMethods(S, CatImplClass, Categories);
           break;
         }
       }

Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=103123&r1=103122&r2=103123&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Wed May  5 16:52:17 2010
@@ -13,6 +13,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "Sema.h"
+#include "SemaInit.h"
+#include "clang/AST/ExprObjC.h"
 
 using namespace clang;
 
@@ -275,7 +277,8 @@
 /// builds the AST node for a property implementation declaration; declared
 /// as @synthesize or @dynamic.
 ///
-Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
+Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
+                                            SourceLocation AtLoc,
                                             SourceLocation PropertyLoc,
                                             bool Synthesize,
                                             DeclPtrTy ClassCatImpDecl,
@@ -427,6 +430,54 @@
                                 ObjCPropertyImplDecl::Synthesize
                                 : ObjCPropertyImplDecl::Dynamic),
                                Ivar);
+  if (ObjCMethodDecl *getterMethod = property->getGetterMethodDecl()) {
+    getterMethod->createImplicitParams(Context, IDecl);
+    if (getLangOptions().CPlusPlus && Synthesize) {
+      // For Objective-C++, need to synthesize the AST for the IVAR object to be
+      // returned by the getter as it must conform to C++'s copy-return rules.
+      // FIXME. Eventually we want to do this for Objective-C as well.
+      ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl();
+      DeclRefExpr *SelfExpr = 
+        new (Context) DeclRefExpr(SelfDecl,SelfDecl->getType(),
+                                  SourceLocation());
+      Expr *IvarRefExpr =
+        new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc,
+                                      SelfExpr, true, true);
+      OwningExprResult Res = 
+        PerformCopyInitialization(InitializedEntity::InitializeResult(
+                                  SourceLocation(),
+                                  getterMethod->getResultType()),
+                                  SourceLocation(),
+                                  Owned(IvarRefExpr));
+      if (!Res.isInvalid()) {
+        Expr *ResExpr = Res.takeAs<Expr>();
+        if (ResExpr)
+          ResExpr = MaybeCreateCXXExprWithTemporaries(ResExpr);
+        PIDecl->setGetterCXXConstructor(ResExpr);
+      }
+    }
+  }
+  if (ObjCMethodDecl *setterMethod = property->getSetterMethodDecl()) {
+    setterMethod->createImplicitParams(Context, IDecl);
+    if (getLangOptions().CPlusPlus && Synthesize) {
+      // FIXME. Eventually we want to do this for Objective-C as well.
+      ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl();
+      DeclRefExpr *SelfExpr = 
+        new (Context) DeclRefExpr(SelfDecl,SelfDecl->getType(),
+                                  SourceLocation());
+      Expr *lhs =
+        new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc,
+                                      SelfExpr, true, true);
+      ObjCMethodDecl::param_iterator P = setterMethod->param_begin();
+      ParmVarDecl *Param = (*P);
+      Expr *rhs = new (Context) DeclRefExpr(Param,Param->getType(),
+                                            SourceLocation());
+      OwningExprResult Res = BuildBinOp(S, SourceLocation(), 
+                                        BinaryOperator::Assign, lhs, rhs);
+      PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>());
+    }
+  }
+  
   if (IC) {
     if (Synthesize)
       if (ObjCPropertyImplDecl *PPIDecl =
@@ -818,7 +869,7 @@
 }
 
 
-void Sema::DiagnoseUnimplementedProperties(ObjCImplDecl* IMPDecl,
+void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
                                       ObjCContainerDecl *CDecl,
                                       const llvm::DenseSet<Selector>& InsMap) {
   llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*> PropMap;
@@ -841,7 +892,7 @@
         PropImplMap.count(Prop))
       continue;
     if (LangOpts.ObjCNonFragileABI2 && !isa<ObjCCategoryImplDecl>(IMPDecl)) {
-      ActOnPropertyImplDecl(IMPDecl->getLocation(),
+      ActOnPropertyImplDecl(S, IMPDecl->getLocation(),
                             IMPDecl->getLocation(),
                             true, DeclPtrTy::make(IMPDecl),
                             Prop->getIdentifier(),





More information about the cfe-commits mailing list