[cfe-commits] r93474 - in /cfe/trunk: lib/Frontend/RewriteObjC.cpp test/Rewriter/rewrite-byref-vars.mm

Fariborz Jahanian fjahanian at apple.com
Thu Jan 14 15:05:53 PST 2010


Author: fjahanian
Date: Thu Jan 14 17:05:52 2010
New Revision: 93474

URL: http://llvm.org/viewvc/llvm-project?rev=93474&view=rev
Log:
Patch to avoid duplicate declaration of byref structs
for __block variables of same name declared in multiple scopes.
Fixes radar 7540194

Added:
    cfe/trunk/test/Rewriter/rewrite-byref-vars.mm
Modified:
    cfe/trunk/lib/Frontend/RewriteObjC.cpp

Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteObjC.cpp?rev=93474&r1=93473&r2=93474&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Thu Jan 14 17:05:52 2010
@@ -126,6 +126,7 @@
     // Block related declarations.
     llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDecls;
     llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDecls;
+    llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
     llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
 
     llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
@@ -252,6 +253,8 @@
     void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
     void RewriteImplementationDecl(Decl *Dcl);
     void RewriteObjCMethodDecl(ObjCMethodDecl *MDecl, std::string &ResultStr);
+    void RewriteByRefString(std::string &ResultStr, const std::string &Name,
+                            ValueDecl *VD);
     void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
     void RewriteProtocolDecl(ObjCProtocolDecl *Dcl);
     void RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *Dcl);
@@ -3760,6 +3763,15 @@
   }
 }
 
+void RewriteObjC::RewriteByRefString(std::string &ResultStr, 
+                                     const std::string &Name,
+                                     ValueDecl *VD) {
+  assert(BlockByRefDeclNo.count(VD) && 
+         "RewriteByRefString: ByRef decl missing");
+  ResultStr += "struct __Block_byref_" + Name + 
+    "_" + utostr(BlockByRefDeclNo[VD]) ;
+}
+
 std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
                                                    const char *funcName,
                                                    std::string Tag) {
@@ -3805,7 +3817,9 @@
        E = BlockByRefDecls.end(); I != E; ++I) {
     S += "  ";
     std::string Name = (*I)->getNameAsString();
-    std::string TypeString = "struct __Block_byref_" + Name + " *";
+    std::string TypeString;
+    RewriteByRefString(TypeString, Name, (*I));
+    TypeString += " *";
     Name = TypeString + Name;
     S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
   }
@@ -3940,7 +3954,8 @@
         S += "struct __block_impl *";
         Constructor += ", void *" + ArgName;
       } else {
-        std::string TypeString = "struct __Block_byref_" + FieldName;
+        std::string TypeString;
+        RewriteByRefString(TypeString, FieldName, (*I));
         TypeString += " *";
         FieldName = TypeString + FieldName;
         ArgName = TypeString + ArgName;
@@ -4521,11 +4536,12 @@
   X = SM->getInstantiationLoc(X);
   const char *endBuf = SM->getCharacterData(X);
   std::string Name(ND->getNameAsString());
-  std::string ByrefType = "struct __Block_byref_";
-  ByrefType += Name;
+  std::string ByrefType;
+  RewriteByRefString(ByrefType, Name, ND);
   ByrefType += " {\n";
   ByrefType += "  void *__isa;\n";
-  ByrefType += " struct __Block_byref_" + Name + " *__forwarding;\n";
+  RewriteByRefString(ByrefType, Name, ND);
+  ByrefType += " *__forwarding;\n";
   ByrefType += " int __flags;\n";
   ByrefType += " int __size;\n";
   // Add void *__Block_byref_id_object_copy; 
@@ -4570,14 +4586,17 @@
   if (HasCopyAndDispose)
     flags |= BLOCK_HAS_COPY_DISPOSE;
   Name = ND->getNameAsString();
-  ByrefType = "struct __Block_byref_" + Name;
+  ByrefType.clear();
+  RewriteByRefString(ByrefType, Name, ND);
   if (!hasInit) {
     ByrefType += " " + Name + " = {(void*)";
     ByrefType += utostr(isa);
     ByrefType += ", &" + Name + ", ";
     ByrefType += utostr(flags);
     ByrefType += ", ";
-    ByrefType += "sizeof(struct __Block_byref_" + Name + ")";
+    ByrefType += "sizeof(";
+    RewriteByRefString(ByrefType, Name, ND);
+    ByrefType += ")";
     if (HasCopyAndDispose) {
       ByrefType += ", __Block_byref_id_object_copy_";
       ByrefType += utostr(flag);
@@ -4599,7 +4618,9 @@
     ByrefType += ", &" + Name + ", ";
     ByrefType += utostr(flags);
     ByrefType += ", ";
-    ByrefType += "sizeof(struct __Block_byref_" + Name + "), ";
+    ByrefType += "sizeof(";
+    RewriteByRefString(ByrefType, Name, ND);
+    ByrefType += "), ";
     if (HasCopyAndDispose) {
       ByrefType += "__Block_byref_id_object_copy_";
       ByrefType += utostr(flag);
@@ -4971,8 +4992,13 @@
         else if (ND->getType()->isFunctionPointerType())
           CheckFunctionPointerDecl(ND->getType(), ND);
         if (VarDecl *VD = dyn_cast<VarDecl>(SD)) 
-          if (VD->hasAttr<BlocksAttr>())
+          if (VD->hasAttr<BlocksAttr>()) {
+            static unsigned uniqueByrefDeclCount = 0;
+            assert(!BlockByRefDeclNo.count(ND) &&
+              "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
+            BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
             RewriteByRefVar(VD);
+          }
       }
       if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
         if (isTopLevelBlockPointerType(TD->getUnderlyingType()))

Added: cfe/trunk/test/Rewriter/rewrite-byref-vars.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-byref-vars.mm?rev=93474&view=auto

==============================================================================
--- cfe/trunk/test/Rewriter/rewrite-byref-vars.mm (added)
+++ cfe/trunk/test/Rewriter/rewrite-byref-vars.mm Thu Jan 14 17:05:52 2010
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks -o - %s
+// radar 7540194
+
+extern "C" __declspec(dllexport) void BreakTheRewriter(int i) {
+        __block int aBlockVariable = 0;
+        void (^aBlock)(void) = ^ {
+                aBlockVariable = 42;
+        };
+        aBlockVariable++;
+	if (i) {
+	  __block int bbBlockVariable = 0;
+	  void (^aBlock)(void) = ^ {
+                bbBlockVariable = 42;
+          };
+        }
+}
+
+__declspec(dllexport) extern "C" __declspec(dllexport) void XXXXBreakTheRewriter(void) {
+
+        __block int aBlockVariable = 0;
+        void (^aBlock)(void) = ^ {
+                aBlockVariable = 42;
+        };
+        aBlockVariable++;
+        void (^bBlocks)(void) = ^ {
+                aBlockVariable = 43;
+        };
+        void (^c)(void) = ^ {
+                aBlockVariable = 44;
+        };
+
+}
+
+// $CLANG -cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks bug.mm
+// g++ -c -D"__declspec(X)=" bug.cpp





More information about the cfe-commits mailing list