[cfe-commits] r156447 - in /cfe/trunk: lib/Rewrite/RewriteModernObjC.cpp test/Rewriter/rewrite-modern-default-property-synthesis.mm

Fariborz Jahanian fjahanian at apple.com
Tue May 8 16:54:36 PDT 2012


Author: fjahanian
Date: Tue May  8 18:54:35 2012
New Revision: 156447

URL: http://llvm.org/viewvc/llvm-project?rev=156447&view=rev
Log:
Modern objective-c translation. Translating default
synthesis of property getter/setters. // rdar://11374235


Modified:
    cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
    cfe/trunk/test/Rewriter/rewrite-modern-default-property-synthesis.mm

Modified: cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp?rev=156447&r1=156446&r2=156447&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp (original)
+++ cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp Tue May  8 18:54:35 2012
@@ -307,6 +307,8 @@
     void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
     void RewriteTypeOfDecl(VarDecl *VD);
     void RewriteObjCQualifiedInterfaceTypes(Expr *E);
+    
+    std::string getIvarAccessString(ObjCIvarDecl *D);
   
     // Expression Rewriting.
     Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
@@ -771,13 +773,73 @@
   }
 }
 
-static std::string getIvarAccessString(ObjCIvarDecl *OID) {
-  const ObjCInterfaceDecl *ClassDecl = OID->getContainingInterface();
-  std::string S;
-  S = "((struct ";
-  S += ClassDecl->getIdentifier()->getName();
-  S += "_IMPL *)self)->";
-  S += OID->getName();
+static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl,
+                                  ObjCIvarDecl *IvarDecl, std::string &Result) {
+  Result += "OBJC_IVAR_$_";
+  Result += IDecl->getName();
+  Result += "$";
+  Result += IvarDecl->getName();
+}
+
+std::string 
+RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) {
+  const ObjCInterfaceDecl *ClassDecl = D->getContainingInterface();
+  
+  // Build name of symbol holding ivar offset.
+  std::string IvarOffsetName;
+  WriteInternalIvarName(ClassDecl, D, IvarOffsetName);
+  
+  
+  std::string S = "(*(";
+  QualType IvarT = D->getType();
+  
+  if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) {
+    RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl();
+    RD = RD->getDefinition();
+    if (RD && !RD->getDeclName().getAsIdentifierInfo()) {
+      // decltype(((Foo_IMPL*)0)->bar) *
+      ObjCContainerDecl *CDecl = 
+      dyn_cast<ObjCContainerDecl>(D->getDeclContext());
+      // ivar in class extensions requires special treatment.
+      if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
+        CDecl = CatDecl->getClassInterface();
+      std::string RecName = CDecl->getName();
+      RecName += "_IMPL";
+      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                          SourceLocation(), SourceLocation(),
+                                          &Context->Idents.get(RecName.c_str()));
+      QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
+      unsigned UnsignedIntSize = 
+      static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
+      Expr *Zero = IntegerLiteral::Create(*Context,
+                                          llvm::APInt(UnsignedIntSize, 0),
+                                          Context->UnsignedIntTy, SourceLocation());
+      Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
+      ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
+                                              Zero);
+      FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
+                                        SourceLocation(),
+                                        &Context->Idents.get(D->getNameAsString()),
+                                        IvarT, 0,
+                                        /*BitWidth=*/0, /*Mutable=*/true,
+                                        /*HasInit=*/false);
+      MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
+                                                FD->getType(), VK_LValue,
+                                                OK_Ordinary);
+      IvarT = Context->getDecltypeType(ME, ME->getType());
+    }
+  }
+  convertObjCTypeToCStyleType(IvarT);
+  QualType castT = Context->getPointerType(IvarT);
+  std::string TypeString(castT.getAsString(Context->getPrintingPolicy()));
+  S += TypeString;
+  S += ")";
+  
+  // ((char *)self + IVAR_OFFSET_SYMBOL_NAME)
+  S += "((char *)self + ";
+  S += IvarOffsetName;
+  S += "))";
+  ReferencedIvars[const_cast<ObjCInterfaceDecl *>(ClassDecl)].insert(D);
   return S;
 }
 
@@ -3721,14 +3783,6 @@
     llvm_unreachable("struct already synthesize- RewriteObjCInternalStruct");
 }
 
-static void WriteInternalIvarName(ObjCInterfaceDecl *IDecl,
-                                  ObjCIvarDecl *IvarDecl, std::string &Result) {
-  Result += "OBJC_IVAR_$_";
-  Result += IDecl->getName();
-  Result += "$";
-  Result += IvarDecl->getName();
-}
-
 /// RewriteIvarOffsetSymbols - Rewrite ivar offset symbols of those ivars which
 /// have been referenced in an ivar access expression.
 void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
@@ -5644,6 +5698,10 @@
   }
 
   InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
+  
+  if (ClassImplementation.size() || CategoryImplementation.size())
+    RewriteImplementations();
+  
   for (unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
     ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i];
     // Write struct declaration for the class matching its ivar declarations.
@@ -5652,9 +5710,6 @@
     // private ivars.
     RewriteInterfaceDecl(CDecl);
   }
-  
-  if (ClassImplementation.size() || CategoryImplementation.size())
-    RewriteImplementations();
 
   // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
   // we are done.
@@ -7293,7 +7348,7 @@
   
     if (BaseExpr->getType()->isObjCObjectPointerType()) {
       const ObjCInterfaceType *iFaceDecl =
-      dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
+        dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
       assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
       // lookup which class implements the instance variable.
       ObjCInterfaceDecl *clsDeclared = 0;

Modified: cfe/trunk/test/Rewriter/rewrite-modern-default-property-synthesis.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-modern-default-property-synthesis.mm?rev=156447&r1=156446&r2=156447&view=diff
==============================================================================
--- cfe/trunk/test/Rewriter/rewrite-modern-default-property-synthesis.mm (original)
+++ cfe/trunk/test/Rewriter/rewrite-modern-default-property-synthesis.mm Tue May  8 18:54:35 2012
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -x objective-c++ -fms-extensions -fobjc-default-synthesize-properties -rewrite-objc %s -o %t-rw.cpp 
+// RUN: %clang_cc1 -E %s -o %t.mm
+// RUN: %clang_cc1 -x objective-c++ -fms-extensions -fobjc-default-synthesize-properties -rewrite-objc %t.mm -o %t-rw.cpp 
+// RUN: FileCheck --input-file=%t-rw.cpp %s
 // RUN: %clang_cc1 -fsyntax-only  -DSEL="void *" -Did="struct objc_object *" -Wno-attributes -Wno-address-of-temporary -D"__declspec(X)=" %t-rw.cpp
 // rdar://11374235
 
@@ -58,3 +60,26 @@
 }
 @end
 
+typedef struct {
+        int x:1;
+        int y:1;
+} TBAR;
+
+ at interface NONAME
+{
+  TBAR _bar;
+}
+ at property TBAR bad;
+ at end
+
+ at implementation NONAME
+ at end
+
+// CHECK: static int _I_SynthGetter_howMany
+// CHECL: return (*(int *)((char *)self + OBJC_IVAR_$_SynthGetter$_howMany));
+// CHECK: static NSString * _I_SynthGetter_what 
+// CHECK: return (*(NSString **)((char *)self + OBJC_IVAR_$_SynthGetter$_what));
+// CHECK: static TBAR _I_NONAME_bad
+// CHECK: return (*(TBAR *)((char *)self + OBJC_IVAR_$_NONAME$_bad));
+// CHECK: static void _I_NONAME_setBad_
+// CHECK: (*(TBAR *)((char *)self + OBJC_IVAR_$_NONAME$_bad)) = bad;





More information about the cfe-commits mailing list