[cfe-commits] r108599 - in /cfe/trunk: include/clang/AST/DeclObjC.h lib/AST/DeclObjC.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaObjCProperty.cpp test/SemaObjC/synth-provisional-ivars.m

Fariborz Jahanian fjahanian at apple.com
Fri Jul 16 17:59:30 PDT 2010


Author: fjahanian
Date: Fri Jul 16 19:59:30 2010
New Revision: 108599

URL: http://llvm.org/viewvc/llvm-project?rev=108599&view=rev
Log:
Patch to synthesize property ivars on demand as
part of the new property synthesis by default.
wip.

Added:
    cfe/trunk/test/SemaObjC/synth-provisional-ivars.m
Modified:
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExpr.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=108599&r1=108598&r2=108599&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Fri Jul 16 19:59:30 2010
@@ -650,15 +650,17 @@
 
 private:
   ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation L, IdentifierInfo *Id,
-               QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW)
+               QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
+               bool synthesized)
     : FieldDecl(ObjCIvar, DC, L, Id, T, TInfo, BW, /*Mutable=*/false),
-      DeclAccess(ac) {}
+      DeclAccess(ac),  Synthesized(synthesized) {}
 
 public:
   static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
                               SourceLocation L, IdentifierInfo *Id, QualType T,
                               TypeSourceInfo *TInfo,
-                              AccessControl ac, Expr *BW = NULL);
+                              AccessControl ac, Expr *BW = NULL,
+                              bool synthesized=false);
 
   /// \brief Return the class interface that this ivar is logically contained
   /// in; this is either the interface where the ivar was declared, or the
@@ -674,6 +676,8 @@
     return DeclAccess == None ? Protected : AccessControl(DeclAccess);
   }
 
+  bool getSynthesize() const { return Synthesized; }
+  
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classof(const ObjCIvarDecl *D) { return true; }
@@ -681,6 +685,7 @@
 private:
   // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
   unsigned DeclAccess : 3;
+  unsigned Synthesized : 1;
 };
 
 

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=108599&r1=108598&r2=108599&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Fri Jul 16 19:59:30 2010
@@ -575,7 +575,8 @@
 ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
                                    SourceLocation L, IdentifierInfo *Id,
                                    QualType T, TypeSourceInfo *TInfo,
-                                   AccessControl ac, Expr *BW) {
+                                   AccessControl ac, Expr *BW,
+                                   bool synthesized) {
   if (DC) {
     // Ivar's can only appear in interfaces, implementations (via synthesized
     // properties), and class extensions (via direct declaration, or synthesized
@@ -592,7 +593,7 @@
            "Invalid ivar decl context!");
   }
 
-  return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW);
+  return new (C) ObjCIvarDecl(DC, L, Id, T, TInfo, ac, BW, synthesized);
 }
 
 const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=108599&r1=108598&r2=108599&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jul 16 19:59:30 2010
@@ -1005,6 +1005,38 @@
   return true;
 }
 
+static ObjCIvarDecl *SynthesizeProvisionalIvar(Sema &SemaRef,
+                                               ASTContext &Context,
+                                               IdentifierInfo *II,
+                                               SourceLocation NameLoc) {
+  ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl();
+  ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface();
+  if (!IDecl)
+    return 0;
+  ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation();
+  assert(ClassImpDecl && "Method not inside @implementation");
+  bool DynamicImplSeen = false;
+  ObjCPropertyDecl *property = SemaRef.LookupPropertyDecl(IDecl, II);
+  if (!property)
+    return 0;
+  if (ObjCPropertyImplDecl *PIDecl = ClassImpDecl->FindPropertyImplDecl(II))
+    DynamicImplSeen = 
+      (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
+  if (!DynamicImplSeen) {
+    QualType PropType = Context.getCanonicalType(property->getType());
+    ObjCIvarDecl *Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, 
+                                              NameLoc,
+                                              II, PropType, /*Dinfo=*/0,
+                                              ObjCIvarDecl::Protected,
+                                              (Expr *)0, true);
+    ClassImpDecl->addDecl(Ivar);
+    IDecl->makeDeclVisibleInContext(Ivar, false);
+    property->setPropertyIvarDecl(Ivar);
+    return Ivar;
+  }
+  return 0;
+}
+
 Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
                                                CXXScopeSpec &SS,
                                                UnqualifiedId &Id,
@@ -1070,6 +1102,12 @@
 
       Expr *Ex = E.takeAs<Expr>();
       if (Ex) return Owned(Ex);
+      // Synthesize ivars lazily
+      if (getLangOptions().ObjCNonFragileABI2) {
+        if (SynthesizeProvisionalIvar(*this, Context, II, NameLoc))
+          return ActOnIdExpression(S, SS, Id, HasTrailingLParen,
+                                   isAddressOfOperand);
+      }
     }
   }
 

Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=108599&r1=108598&r2=108599&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Fri Jul 16 19:59:30 2010
@@ -372,7 +372,7 @@
       Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, PropertyLoc,
                                   PropertyIvar, PropType, /*Dinfo=*/0,
                                   ObjCIvarDecl::Protected,
-                                  (Expr *)0);
+                                  (Expr *)0, true);
       ClassImpDecl->addDecl(Ivar);
       IDecl->makeDeclVisibleInContext(Ivar, false);
       property->setPropertyIvarDecl(Ivar);
@@ -517,6 +517,24 @@
       return DeclPtrTy();
     }
     IC->addPropertyImplementation(PIDecl);
+    if (getLangOptions().ObjCNonFragileABI2) {
+      // Diagnose if an ivar was lazily synthesdized due to a previous
+      // use and if 1) property is @dynamic or 2) property is synthesized
+      // but it requires a dirreferently named ivar.
+      ObjCInterfaceDecl *ClassDeclared;
+      ObjCIvarDecl *Ivar = 0;
+      if (!Synthesize)
+        Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared);
+      else {
+        if (PropertyIvar && PropertyIvar != PropertyId)
+          Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared);
+      }
+      if (Ivar && Ivar->getSynthesize()) {
+        Diag(Ivar->getLocation(), diag::err_undeclared_var_use) 
+        << PropertyId;
+        Ivar->setInvalidDecl();
+      }
+    }
   } else {
     if (Synthesize)
       if (ObjCPropertyImplDecl *PPIDecl =

Added: cfe/trunk/test/SemaObjC/synth-provisional-ivars.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/synth-provisional-ivars.m?rev=108599&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/synth-provisional-ivars.m (added)
+++ cfe/trunk/test/SemaObjC/synth-provisional-ivars.m Fri Jul 16 19:59:30 2010
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
+
+int bar;
+
+ at interface I
+{
+    int _bar;
+}
+ at property int PROP;
+ at property int PROP1;
+ at property int PROP2;
+ at property int PROP3;
+ at property int PROP4;
+
+ at property int bar;
+ at property int bar1;
+
+ at end
+
+ at implementation I
+- (int) Meth { return PROP; }	// expected-note {{'PROP' declared here}}
+
+ at dynamic PROP1;
+- (int) Meth1 { return PROP1; }  // expected-error {{use of undeclared identifier 'PROP1'}}
+
+- (int) Meth2 { return PROP2; }  // expected-error {{use of undeclared identifier 'PROP2'}}
+ at dynamic PROP2;
+
+- (int) Meth3 { return PROP3; }  // expected-error {{use of undeclared identifier 'PROP3'}}
+ at synthesize PROP3=IVAR;
+
+- (int) Meth4 { return PROP4; }
+ at synthesize PROP4=PROP4;
+
+- (int) Meth5 { return bar; }  // expected-error {{use of undeclared identifier 'bar'}}
+ at synthesize bar = _bar;
+
+- (int) Meth6 { return bar1; }
+
+ at end





More information about the cfe-commits mailing list