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
This commit is contained in:
Fariborz Jahanian 2010-01-14 00:35:56 +00:00
Родитель e495b7f7b4
Коммит abfd83e74c
2 изменённых файлов: 69 добавлений и 2 удалений

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;
};
}