diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 6 | ||||
-rw-r--r-- | lib/AST/StmtSerialization.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 6 |
5 files changed, 21 insertions, 5 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 540a6377f2..51c581a708 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -260,7 +260,11 @@ public: APValue VisitAddrLabelExpr(AddrLabelExpr *E) { return APValue(E, 0); } APValue VisitCallExpr(CallExpr *E); - APValue VisitBlockExpr(BlockExpr *E) { return APValue(E, 0); } + APValue VisitBlockExpr(BlockExpr *E) { + if (!E->hasBlockDeclRefExprs()) + return APValue(E, 0); + return APValue(); + } APValue VisitConditionalOperator(ConditionalOperator *E); }; } // end anonymous namespace diff --git a/lib/AST/StmtSerialization.cpp b/lib/AST/StmtSerialization.cpp index a6cf01fe2b..009a2dd17a 100644 --- a/lib/AST/StmtSerialization.cpp +++ b/lib/AST/StmtSerialization.cpp @@ -1290,11 +1290,14 @@ ExtVectorElementExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C) { void BlockExpr::EmitImpl(Serializer& S) const { S.Emit(getType()); S.EmitOwnedPtr(TheBlock); + S.EmitBool(HasBlockDeclRefExprs); } BlockExpr* BlockExpr::CreateImpl(Deserializer& D, ASTContext& C) { QualType T = QualType::ReadVal(D); - return new BlockExpr(cast<BlockDecl>(D.ReadOwnedPtr<Decl>(C)),T); + BlockDecl *B = cast<BlockDecl>(D.ReadOwnedPtr<Decl>(C)); + bool H = D.ReadBool(); + return new BlockExpr(B,T,H); } void BlockDeclRefExpr::EmitImpl(Serializer& S) const { diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 523014f1fb..8cfd60ce5c 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -382,6 +382,8 @@ public: } llvm::Constant *VisitBlockExpr(const BlockExpr *E) { + assert (!E->hasBlockDeclRefExprs() && "global block with BlockDeclRefs"); + const char *Name = ""; if (const NamedDecl *ND = dyn_cast<NamedDecl>(CGF->CurFuncDecl)) Name = ND->getNameAsString().c_str(); @@ -615,7 +617,9 @@ public: return CGM.GetAddrOfConstantCFString(S); } case Expr::BlockExprClass: { - return CGF->BuildBlockLiteralTmp(cast<BlockExpr>(E)); + BlockExpr *B = cast<BlockExpr>(E); + if (!B->hasBlockDeclRefExprs()) + return CGF->BuildBlockLiteralTmp(B); } } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 3eb68b5059..2a4b4657be 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -2004,7 +2004,8 @@ struct BlockSemaInfo { llvm::SmallVector<ParmVarDecl*, 8> Params; bool hasPrototype; bool isVariadic; - + bool hasBlockDeclRefExprs; + BlockDecl *TheDecl; /// TheScope - This is the scope for the block itself, which contains diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 5d1d935386..c95b5ee52d 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -865,6 +865,9 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc, // as they do not get snapshotted. // if (CurBlock && ShouldSnapshotBlockValueReference(CurBlock, VD)) { + // Blocks that have these can't be constant. + CurBlock->hasBlockDeclRefExprs = true; + // The BlocksAttr indicates the variable is bound by-reference. if (VD->getAttr<BlocksAttr>()) return Owned(new (Context) BlockDeclRefExpr(VD, @@ -4331,6 +4334,7 @@ void Sema::ActOnBlockStart(SourceLocation CaretLoc, Scope *BlockScope) { BSI->ReturnType = 0; BSI->TheScope = BlockScope; + BSI->hasBlockDeclRefExprs = false; BSI->TheDecl = BlockDecl::Create(Context, CurContext, CaretLoc); PushDeclContext(BlockScope, BSI->TheDecl); @@ -4442,7 +4446,7 @@ Sema::ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *body, BlockTy = Context.getBlockPointerType(BlockTy); BSI->TheDecl->setBody(Body.take()); - return new (Context) BlockExpr(BSI->TheDecl, BlockTy); + return new (Context) BlockExpr(BSI->TheDecl, BlockTy, BSI->hasBlockDeclRefExprs); } Sema::ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc, |