diff options
| author | Steve Naroff <snaroff@apple.com> | 2008-10-02 17:12:56 +0000 | 
|---|---|---|
| committer | Steve Naroff <snaroff@apple.com> | 2008-10-02 17:12:56 +0000 | 
| commit | d40a39626c8088c75fdd594dac68846ecd2b27a9 (patch) | |
| tree | 9ac04ce4ca5a3a6835db71fc1cfafc39d93c6c90 /clang | |
| parent | c3d16493ae9bc3d7018b0757a423570e2fdcb352 (diff) | |
| download | bcm5719-llvm-d40a39626c8088c75fdd594dac68846ecd2b27a9.tar.gz bcm5719-llvm-d40a39626c8088c75fdd594dac68846ecd2b27a9.zip | |
Changed Sema::CheckForConstantInitializer to allow global block literals.
This commit also includes some name changes in the blocks rewriter (no functionality change).
llvm-svn: 56955
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/Driver/RewriteBlocks.cpp | 30 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 4 | ||||
| -rw-r--r-- | clang/test/Sema/block-literal.c | 3 | 
3 files changed, 22 insertions, 15 deletions
| diff --git a/clang/Driver/RewriteBlocks.cpp b/clang/Driver/RewriteBlocks.cpp index 76d0ebd42cf..f885835bfa6 100644 --- a/clang/Driver/RewriteBlocks.cpp +++ b/clang/Driver/RewriteBlocks.cpp @@ -186,18 +186,18 @@ void RewriteBlocks::Initialize(ASTContext &context) {    Rewrite.setSourceMgr(Context->getSourceManager());    const char *s = "#pragma once\n" -  "#ifndef CLOSURE_IMPL\n" -  "struct __closure_impl {\n" -  "  long Reserved;\n" +  "#ifndef BLOCK_IMPL\n" +  "struct __block_impl {\n" +  "  void *isa;\n"    "  int Flags;\n"    "  int Size;\n" -  "  void *Invoke;\n" +  "  void *FuncPtr;\n"    "};\n"    "enum {\n" -  "  HAS_NONPOD = (1<<25),\n" -  "  HAS_BYREF = (1<<26)\n" +  "  BLOCK_HAS_COPY_DISPOSE = (1<<25),\n" +  "  BLOCK_IS_GLOBAL = (1<<28)\n"    "};\n" -  "#define CLOSURE_IMPL\n" +  "#define BLOCK_IMPL\n"    "#endif\n";    if (IsHeader) {      // insert the whole string when rewriting a header file @@ -243,7 +243,7 @@ void RewriteBlocks::RewriteMethodDecl(ObjCMethodDecl *Method) {    const char *endBuf = SM->getCharacterData(LocEnd);    const char *methodPtr = startBuf; -  std::string Tag = "struct __closure_impl *"; +  std::string Tag = "struct __block_impl *";    while (*methodPtr++ && (methodPtr != endBuf)) {      switch (*methodPtr) { @@ -405,7 +405,7 @@ std::string RewriteBlocks::SynthesizeBlockFunc(BlockExpr *CE, int i,      //   };      //      if (isBlockPointerType((*I)->getType())) -      S += "struct __closure_impl *"; +      S += "struct __block_impl *";      else        (*I)->getType().getAsStringInternal(Name);      S += Name + " = __cself->" + (*I)->getName() + "; // bound by copy\n"; @@ -471,7 +471,7 @@ std::string RewriteBlocks::SynthesizeBlockFunc(BlockExpr *CE, int i,  std::string RewriteBlocks::SynthesizeBlockImpl(BlockExpr *CE,                                                      std::string Tag) { -  std::string S = Tag + " {\n  struct __closure_impl impl;\n"; +  std::string S = Tag + " {\n  struct __block_impl impl;\n";    GetBlockDeclRefExprs(CE);    if (BlockDeclRefs.size()) { @@ -500,7 +500,7 @@ std::string RewriteBlocks::SynthesizeBlockImpl(BlockExpr *CE,        //   };        //        if (isBlockPointerType((*I)->getType())) -        S += "struct __closure_impl *"; +        S += "struct __block_impl *";        else           (*I)->getType().getAsStringInternal(Name);        S += Name + ";\n"; @@ -511,7 +511,7 @@ std::string RewriteBlocks::SynthesizeBlockImpl(BlockExpr *CE,        S += "  ";        std::string Name = (*I)->getName();        if (isBlockPointerType((*I)->getType())) -        S += "struct __closure_impl *"; +        S += "struct __block_impl *";        else           Context->getPointerType((*I)->getType()).getAsStringInternal(Name);        S += Name + "; // by ref\n"; @@ -702,7 +702,7 @@ std::string RewriteBlocks::SynthesizeBlockCall(CallExpr *Exp) {    // Synthesize the cast.      BlockCall += "(" + Exp->getType().getAsString() + "(*)"; -  BlockCall += "(struct __closure_impl *"; +  BlockCall += "(struct __block_impl *";    if (FTP) {      for (FunctionTypeProto::arg_type_iterator I = FTP->arg_type_begin(),            E = FTP->arg_type_end(); I && (I != E); ++I) @@ -755,7 +755,7 @@ void RewriteBlocks::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {    const char *topLevelCommaCursor = 0;    const char *argPtr = startArgList;    bool scannedBlockDecl = false; -  std::string Tag = "struct __closure_impl *"; +  std::string Tag = "struct __block_impl *";    while (*argPtr++ && parenCount) {      switch (*argPtr) { @@ -925,7 +925,7 @@ void RewriteBlocks::RewriteBlockExpr(BlockExpr *Exp) {    // Rewrite the closure block with a compound literal. The first cast is    // to prevent warnings from the C compiler. -  std::string Init = "(struct __closure_impl *)&(" + Tag + "){{0,"; +  std::string Init = "(struct __block_impl *)&(" + Tag + "){{0,";    // Initialize the Flags, Size, and Invoke fields.    Init += (haveByRefDecls ? "HAS_BYREF," : "0,"); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 800ffc57064..9c5c4f2d4bf 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1286,6 +1286,10 @@ bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {    if (Init->getType()->isFunctionType())      return false; +  // Allow block exprs at top level. +  if (Init->getType()->isBlockPointerType()) +    return false; +        Diag(Init->getExprLoc(), diag::err_init_element_not_constant,         Init->getSourceRange());    return true; diff --git a/clang/test/Sema/block-literal.c b/clang/test/Sema/block-literal.c index 3a091395d04..7f1579d0cc7 100644 --- a/clang/test/Sema/block-literal.c +++ b/clang/test/Sema/block-literal.c @@ -78,6 +78,9 @@ void test_arguments() {    (1 ? c : c)('x');  } +static int global_x = 10; +void (^global_block)(void) = ^{ printf("global x is %d\n", global_x); }; +  #if 0  // Old syntax. FIXME: convert/test.  void test_byref() { | 

