diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2010-01-14 00:35:56 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2010-01-14 00:35:56 +0000 |
commit | abfd83e74ca8a7553e375dd4631d2570f33648b4 (patch) | |
tree | 341c07d13e20b97e7aff2423a1abf71c0772b794 | |
parent | e495b7f7b4fffbba7e61229d2a4205a0b164cbe8 (diff) |
Fix a bug in rewrite whereby functions using blocks put extern "C" in wrong place.
Fixes radar 7284618.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93382 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Frontend/RewriteObjC.cpp | 40 | ||||
-rw-r--r-- | test/Rewriter/rewrite-function-decl.mm | 31 |
2 files changed, 69 insertions, 2 deletions
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp index e9072d62e7..87b1cd40e4 100644 --- a/lib/Frontend/RewriteObjC.cpp +++ b/lib/Frontend/RewriteObjC.cpp @@ -142,6 +142,7 @@ namespace { llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes; FunctionDecl *CurFunctionDef; + FunctionDecl *CurFunctionDeclToDeclareForBlock; VarDecl *GlobalVarDecl; bool DisableReplaceStmt; @@ -257,6 +258,7 @@ namespace { void RewriteMethodDeclaration(ObjCMethodDecl *Method); void RewriteProperty(ObjCPropertyDecl *prop); void RewriteFunctionDecl(FunctionDecl *FD); + void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD); void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl); void RewriteObjCQualifiedInterfaceTypes(Expr *E); bool needToScanForQualifiers(QualType T); @@ -367,7 +369,7 @@ namespace { unsigned hasCopy); Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp); void SynthesizeBlockLiterals(SourceLocation FunLocStart, - const char *FunName); + const char *FunName); void RewriteRecordBody(RecordDecl *RD); void CollectBlockDeclRefInfo(BlockExpr *Exp); @@ -488,6 +490,7 @@ void RewriteObjC::Initialize(ASTContext &context) { NSStringRecord = 0; CurMethodDef = 0; CurFunctionDef = 0; + CurFunctionDeclToDeclareForBlock = 0; GlobalVarDecl = 0; SuperStructDecl = 0; ProtocolTypeDecl = 0; @@ -2115,6 +2118,30 @@ void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) { RewriteObjCQualifiedInterfaceTypes(FD); } +void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) { + SourceLocation FunLocStart = FD->getTypeSpecStartLoc(); + const FunctionType *funcType = FD->getType()->getAs<FunctionType>(); + const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType); + if (!proto) + return; + QualType Type = proto->getResultType(); + std::string FdStr = Type.getAsString(); + FdStr += " "; + FdStr += FD->getNameAsCString(); + FdStr += "("; + unsigned numArgs = proto->getNumArgs(); + for (unsigned i = 0; i < numArgs; i++) { + QualType ArgType = proto->getArgType(i); + FdStr += ArgType.getAsString(); + + if (i+1 < numArgs) + FdStr += ", "; + } + FdStr += ");\n"; + InsertText(FunLocStart, FdStr.c_str(), FdStr.size()); + CurFunctionDeclToDeclareForBlock = 0; +} + // SynthSuperContructorFunctionDecl - id objc_super(id obj, id super); void RewriteObjC::SynthSuperContructorFunctionDecl() { if (SuperContructorFunctionDecl) @@ -3999,7 +4026,10 @@ std::string RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag, } void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart, - const char *FunName) { + const char *FunName) { + // Insert declaration for the function in which block literal is used. + if (CurFunctionDeclToDeclareForBlock) + RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); // Insert closures that were part of the function. for (unsigned i = 0; i < Blocks.size(); i++) { @@ -4479,6 +4509,10 @@ std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD, /// /// void RewriteObjC::RewriteByRefVar(VarDecl *ND) { + // Insert declaration for the function in which block literal is + // used. + if (CurFunctionDeclToDeclareForBlock) + RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock); int flag = 0; int isa = 0; SourceLocation DeclLoc = ND->getTypeSpecStartLoc(); @@ -5027,6 +5061,7 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) { // FIXME: If this should support Obj-C++, support CXXTryStmt if (CompoundStmt *Body = FD->getCompoundBody()) { CurFunctionDef = FD; + CurFunctionDeclToDeclareForBlock = FD; CollectPropertySetters(Body); CurrentBody = Body; Body = @@ -5041,6 +5076,7 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) { // and any copy/dispose helper functions. InsertBlockLiteralsWithinFunction(FD); CurFunctionDef = 0; + CurFunctionDeclToDeclareForBlock = 0; } return; } diff --git a/test/Rewriter/rewrite-function-decl.mm b/test/Rewriter/rewrite-function-decl.mm new file mode 100644 index 0000000000..023e55db4b --- /dev/null +++ b/test/Rewriter/rewrite-function-decl.mm @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks -o - %s + +extern "C" __declspec(dllexport) void BreakTheRewriter(void) { + __block int aBlockVariable = 0; + void (^aBlock)(void) = ^ { + aBlockVariable = 42; + }; + aBlockVariable++; + void (^bBlocks)(void) = ^ { + aBlockVariable = 43; + }; + void (^c)(void) = ^ { + aBlockVariable = 44; + }; + +} +__declspec(dllexport) extern "C" void AnotherBreakTheRewriter(int *p1, double d) { + + __block int bBlockVariable = 0; + void (^aBlock)(void) = ^ { + bBlockVariable = 42; + }; + bBlockVariable++; + void (^bBlocks)(void) = ^ { + bBlockVariable = 43; + }; + void (^c)(void) = ^ { + bBlockVariable = 44; + }; + +} |