diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2010-01-14 23:05:52 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-01-14 23:05:52 +0000 |
commit | a73165e47aefbea60312d284343660c9c962c9c3 (patch) | |
tree | b72fbea03a8063cf53264dbc4dc5d3b1a76cd0bd | |
parent | aa97d7051ed3517c7b64787bcb65ae04e1a52594 (diff) |
Patch to avoid duplicate declaration of byref structs
for __block variables of same name declared in multiple scopes.
Fixes radar 7540194
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93474 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Frontend/RewriteObjC.cpp | 44 | ||||
-rw-r--r-- | test/Rewriter/rewrite-byref-vars.mm | 35 |
2 files changed, 70 insertions, 9 deletions
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp index 87b1cd40e4..fc9401d290 100644 --- a/lib/Frontend/RewriteObjC.cpp +++ b/lib/Frontend/RewriteObjC.cpp @@ -126,6 +126,7 @@ namespace { // 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 @@ namespace { 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::SynthesizeMetaDataIntoBuffer(std::string &Result) { } } +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 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, 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 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 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 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) { 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 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) { 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 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) { 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 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { 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())) diff --git a/test/Rewriter/rewrite-byref-vars.mm b/test/Rewriter/rewrite-byref-vars.mm new file mode 100644 index 0000000000..581437b5a5 --- /dev/null +++ b/test/Rewriter/rewrite-byref-vars.mm @@ -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 |