[cfe-commits] r153293 - in /cfe/trunk: lib/Rewrite/RewriteModernObjC.cpp test/Rewriter/rewrite-block-literal.c test/Rewriter/rewrite-block-literal.mm
Fariborz Jahanian
fjahanian at apple.com
Thu Mar 22 17:01:04 PDT 2012
Author: fjahanian
Date: Thu Mar 22 19:00:49 2012
New Revision: 153293
URL: http://llvm.org/viewvc/llvm-project?rev=153293&view=rev
Log:
modern objc translation of block literal expressions
declared at file scope.
// rdar://11006566
Added:
cfe/trunk/test/Rewriter/rewrite-block-literal.mm
- copied, changed from r153271, cfe/trunk/test/Rewriter/rewrite-block-literal.c
Removed:
cfe/trunk/test/Rewriter/rewrite-block-literal.c
Modified:
cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
Modified: cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp?rev=153293&r1=153292&r2=153293&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp (original)
+++ cfe/trunk/lib/Rewrite/RewriteModernObjC.cpp Thu Mar 22 19:00:49 2012
@@ -73,6 +73,7 @@
TypeDecl *ProtocolTypeDecl;
VarDecl *GlobalVarDecl;
+ Expr *GlobalConstructionExp;
unsigned RewriteFailedDiag;
unsigned GlobalBlockRewriteFailedDiag;
// ObjC string constant support.
@@ -612,6 +613,7 @@
CurFunctionDef = 0;
CurFunctionDeclToDeclareForBlock = 0;
GlobalVarDecl = 0;
+ GlobalConstructionExp = 0;
SuperStructDecl = 0;
ProtocolTypeDecl = 0;
ConstantStringDecl = 0;
@@ -3269,7 +3271,7 @@
QualType RT = AFT->getResultType();
std::string StructRef = "struct " + Tag;
std::string S = "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" +
- funcName.str() + "_" + "block_func_" + utostr(i);
+ funcName.str() + "_block_func_" + utostr(i);
BlockDecl *BD = CE->getBlockDecl();
@@ -3632,7 +3634,27 @@
SC += "restrict ";
InsertText(FunLocStart, SC);
}
+ if (GlobalConstructionExp) {
+ // extra fancy dance for global literal expression.
+
+ // Always the latest block expression on the block stack.
+ std::string Tag = "__";
+ Tag += FunName;
+ Tag += "_block_impl_";
+ Tag += utostr(Blocks.size()-1);
+ std::string globalBuf = "static ";
+ globalBuf += Tag; globalBuf += " ";
+ std::string SStr;
+ llvm::raw_string_ostream constructorExprBuf(SStr);
+ GlobalConstructionExp->printPretty(constructorExprBuf, *Context, 0,
+ PrintingPolicy(LangOpts));
+ globalBuf += constructorExprBuf.str();
+ globalBuf += ";\n";
+ InsertText(FunLocStart, globalBuf);
+ GlobalConstructionExp = 0;
+ }
+
Blocks.clear();
InnerDeclRefsCount.clear();
InnerDeclRefs.clear();
@@ -4418,9 +4440,6 @@
const BlockDecl *block = Exp->getBlockDecl();
- if (block->getDeclContext()->getRedeclContext()->isFileContext())
- Diags.Report(block->getLocation(), GlobalBlockRewriteFailedDiag);
-
Blocks.push_back(Exp);
CollectBlockDeclRefInfo(Exp);
@@ -4465,9 +4484,16 @@
else if (GlobalVarDecl)
FuncName = std::string(GlobalVarDecl->getNameAsString());
+ bool GlobalBlockExpr =
+ block->getDeclContext()->getRedeclContext()->isFileContext();
+
+ if (GlobalBlockExpr && !GlobalVarDecl) {
+ Diags.Report(block->getLocation(), GlobalBlockRewriteFailedDiag);
+ GlobalBlockExpr = false;
+ }
+
std::string BlockNumber = utostr(Blocks.size()-1);
- std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber;
std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;
// Get a pointer to the function type so we can cast appropriately.
@@ -4478,6 +4504,14 @@
Expr *NewRep;
// Simulate a contructor call...
+ std::string Tag;
+
+ if (GlobalBlockExpr)
+ Tag = "__global_";
+ else
+ Tag = "__";
+ Tag += FuncName + "_block_impl_" + BlockNumber;
+
FD = SynthBlockInitFunctionDecl(Tag);
DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue,
SourceLocation());
@@ -4599,6 +4633,14 @@
}
NewRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], InitExprs.size(),
FType, VK_LValue, SourceLocation());
+
+ if (GlobalBlockExpr) {
+ assert (GlobalConstructionExp == 0 &&
+ "SynthBlockInitExpr - GlobalConstructionExp must be null");
+ GlobalConstructionExp = NewRep;
+ NewRep = DRE;
+ }
+
NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf,
Context->getPointerType(NewRep->getType()),
VK_RValue, OK_Ordinary, SourceLocation());
Removed: cfe/trunk/test/Rewriter/rewrite-block-literal.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-block-literal.c?rev=153292&view=auto
==============================================================================
--- cfe/trunk/test/Rewriter/rewrite-block-literal.c (original)
+++ cfe/trunk/test/Rewriter/rewrite-block-literal.c (removed)
@@ -1,80 +0,0 @@
-// RUN: %clang_cc1 -rewrite-objc %s -fblocks -o -
-
-void I( void (^)(void));
-void (^noop)(void);
-
-void nothing();
-int printf(const char*, ...);
-
-typedef void (^T) (void);
-
-void takeblock(T);
-int takeintint(int (^C)(int)) { return C(4); }
-
-T somefunction() {
- if (^{ })
- nothing();
-
- noop = ^{};
-
- noop = ^{printf("\nClosure\n"); };
-
- I(^{ });
-
- return ^{printf("\nClosure\n"); };
-}
-void test2() {
- int x = 4;
-
- takeblock(^{ printf("%d\n", x); });
-
- while (1) {
- takeblock(^{
- while(1) break; // ok
- });
- break;
- }
-}
-
-
-void (^test3())(void) {
- return ^{};
-}
-
-void test4() {
- void (^noop)(void) = ^{};
- void (*noop2)() = 0;
-}
-
-void myfunc(int (^block)(int)) {}
-
-void myfunc3(const int *x);
-
-void test5() {
- int a;
-
- myfunc(^(int abcd) {
- myfunc3(&a);
- return 1;
- });
-}
-
-void *X;
-
-void test_arguments() {
- int y;
- int (^c)(char);
- (1 ? c : 0)('x');
- (1 ? 0 : c)('x');
-
- (1 ? c : c)('x');
-}
-
-static int global_x = 10;
-void (^global_block)(void) = ^{ printf("global x is %d\n", global_x); }; // expected-warning {{rewriting block literal declared in global scope is not implemented}}
-
-typedef void (^void_block_t)(void);
-
-static const void_block_t myBlock = ^{ };
-
-static const void_block_t myBlock2 = ^ void(void) { };
Copied: cfe/trunk/test/Rewriter/rewrite-block-literal.mm (from r153271, cfe/trunk/test/Rewriter/rewrite-block-literal.c)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/rewrite-block-literal.mm?p2=cfe/trunk/test/Rewriter/rewrite-block-literal.mm&p1=cfe/trunk/test/Rewriter/rewrite-block-literal.c&r1=153271&r2=153293&rev=153293&view=diff
==============================================================================
--- cfe/trunk/test/Rewriter/rewrite-block-literal.c (original)
+++ cfe/trunk/test/Rewriter/rewrite-block-literal.mm Thu Mar 22 19:00:49 2012
@@ -1,4 +1,9 @@
-// RUN: %clang_cc1 -rewrite-objc %s -fblocks -o -
+// RUN: %clang_cc1 -E %s -o %t.mm
+// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %t.mm -o - | FileCheck %s
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc -fobjc-fragile-abi %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+
+// rdar: // 11006566
void I( void (^)(void));
void (^noop)(void);
@@ -36,11 +41,6 @@
}
}
-
-void (^test3())(void) {
- return ^{};
-}
-
void test4() {
void (^noop)(void) = ^{};
void (*noop2)() = 0;
@@ -61,17 +61,11 @@
void *X;
-void test_arguments() {
- int y;
- int (^c)(char);
- (1 ? c : 0)('x');
- (1 ? 0 : c)('x');
-
- (1 ? c : c)('x');
-}
-
static int global_x = 10;
-void (^global_block)(void) = ^{ printf("global x is %d\n", global_x); }; // expected-warning {{rewriting block literal declared in global scope is not implemented}}
+void (^global_block)(void) = ^{ printf("global x is %d\n", global_x); };
+
+// CHECK: static __global_block_block_impl_0 __global_global_block_block_impl_0((void *)__global_block_block_func_0, &__global_block_block_desc_0_DATA);
+// CHECK: void (*global_block)(void) = (void (*)())&__global_global_block_block_impl_0;
typedef void (^void_block_t)(void);
More information about the cfe-commits
mailing list