objective-c modern translation. Correct rewriting of

block meta-data of block literals declared inside
of extern "C" functions.
// rdar://1131490

llvm-svn: 154939
This commit is contained in:
Fariborz Jahanian 2012-04-17 18:40:53 +00:00
parent c9aeef24c7
commit 88773764e9
2 changed files with 64 additions and 34 deletions

View File

@ -304,7 +304,6 @@ namespace {
void RewriteFunctionDecl(FunctionDecl *FD);
void RewriteBlockPointerType(std::string& Str, QualType Type);
void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD);
void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
void RewriteTypeOfDecl(VarDecl *VD);
void RewriteObjCQualifiedInterfaceTypes(Expr *E);
@ -2246,30 +2245,6 @@ void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
}
}
void RewriteModernObjC::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(Context->getPrintingPolicy());
FdStr += " ";
FdStr += FD->getName();
FdStr += "(";
unsigned numArgs = proto->getNumArgs();
for (unsigned i = 0; i < numArgs; i++) {
QualType ArgType = proto->getArgType(i);
RewriteBlockPointerType(FdStr, ArgType);
if (i+1 < numArgs)
FdStr += ", ";
}
FdStr += ");\n";
InsertText(FunLocStart, FdStr);
CurFunctionDeclToDeclareForBlock = 0;
}
// SynthSuperContructorFunctionDecl - id __rw_objc_super(id obj, id super);
void RewriteModernObjC::SynthSuperContructorFunctionDecl() {
if (SuperContructorFunctionDecl)
@ -4008,11 +3983,25 @@ std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag,
return S;
}
/// getFunctionSourceLocation - returns start location of a function
/// definition. Complication arises when function has declared as
/// extern "C" or extern "C" {...}
static SourceLocation getFunctionSourceLocation (FunctionDecl *FD) {
if (!FD->isExternC() || FD->isMain())
return FD->getTypeSpecStartLoc();
const DeclContext *DC = FD->getDeclContext();
if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC)) {
SourceLocation BodyRBrace = LSD->getRBraceLoc();
// if it is extern "C" {...}, return function decl's own location.
if (BodyRBrace.isValid())
return FD->getTypeSpecStartLoc();
return LSD->getExternLoc();
}
return FD->getTypeSpecStartLoc();
}
void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
StringRef FunName) {
// Insert declaration for the function in which block literal is used.
if (CurFunctionDeclToDeclareForBlock && !Blocks.empty())
RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
bool RewriteSC = (GlobalVarDecl &&
!Blocks.empty() &&
GlobalVarDecl->getStorageClass() == SC_Static &&
@ -4121,7 +4110,7 @@ void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
}
void RewriteModernObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
SourceLocation FunLocStart = getFunctionSourceLocation(FD);
StringRef FuncName = FD->getName();
SynthesizeBlockLiterals(FunLocStart, FuncName);
@ -4731,10 +4720,6 @@ std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD,
///
///
void RewriteModernObjC::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();
@ -4773,7 +4758,7 @@ void RewriteModernObjC::RewriteByRefVar(VarDecl *ND) {
// Insert this type in global scope. It is needed by helper function.
SourceLocation FunLocStart;
if (CurFunctionDef)
FunLocStart = CurFunctionDef->getTypeSpecStartLoc();
FunLocStart = getFunctionSourceLocation(CurFunctionDef);
else {
assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null");
FunLocStart = CurMethodDef->getLocStart();

View File

@ -0,0 +1,45 @@
// RUN: %clang_cc1 -fms-extensions -rewrite-objc -x objective-c++ -fblocks -o %t-rw.cpp %s
// RUN: %clang_cc1 -fsyntax-only -Werror -Wno-address-of-temporary -Wno-attributes -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
// rdar://11131490
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;
};
}
int
__declspec (dllexport)
main (int argc, char *argv[])
{
__block int bBlockVariable = 0;
void (^aBlock)(void) = ^ {
bBlockVariable = 42;
};
}