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:
parent
c9aeef24c7
commit
88773764e9
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue