diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index cfc51cb15d0e..25aa8613768b 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1487,6 +1487,7 @@ private: //===----------------------------------------------------------------------===// /// BlockExpr - Common base class between BlockStmtExpr and BlockExprExpr. +/// FIXME: Combine with BlockStmtExpr...no more need for a common base. class BlockExpr : public Expr { SourceLocation CaretLocation; llvm::SmallVector Args; @@ -1508,8 +1509,7 @@ public: arg_iterator arg_end() const { return Args.end(); } static bool classof(const Stmt *T) { - return T->getStmtClass() == BlockStmtExprClass || - T->getStmtClass() == BlockExprExprClass; + return T->getStmtClass() == BlockStmtExprClass; } static bool classof(const BlockExpr *) { return true; } }; @@ -1544,33 +1544,6 @@ public: static BlockStmtExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); }; -/// BlockExprExpr - Represents a block literal with syntax: -/// ^(expression) or ^(int arg1, float arg2)(expression) -class BlockExprExpr : public BlockExpr { - Expr *BodyExpr; -public: - BlockExprExpr(SourceLocation CaretLoc, QualType Ty, ParmVarDecl **args, - unsigned numargs, Expr *body) : - BlockExpr(BlockExprExprClass, Ty, CaretLoc, - args, numargs), BodyExpr(body) {} - - const Expr *getExpr() const { return BodyExpr; } - Expr *getExpr() { return BodyExpr; } - - virtual SourceRange getSourceRange() const { - return SourceRange(getCaretLocation(), BodyExpr->getLocEnd()); - } - - // Iterators - virtual child_iterator child_begin(); - virtual child_iterator child_end(); - - static bool classof(const Stmt *T) { - return T->getStmtClass() == BlockExprExprClass; - } - static bool classof(const BlockExprExpr *) { return true; } -}; - /// BlockDeclRefExpr - A reference to a declared variable, function, /// enum, etc. class BlockDeclRefExpr : public Expr { diff --git a/clang/include/clang/AST/StmtNodes.def b/clang/include/clang/AST/StmtNodes.def index 697aa9d70973..ce74fea5dc3e 100644 --- a/clang/include/clang/AST/StmtNodes.def +++ b/clang/include/clang/AST/StmtNodes.def @@ -111,10 +111,9 @@ STMT(77, OverloadExpr , Expr) STMT(78, ShuffleVectorExpr , Expr) STMT(79, BlockExpr , Expr) STMT(80, BlockStmtExpr , BlockExpr) -STMT(81, BlockExprExpr , BlockExpr) -STMT(82, BlockDeclRefExpr , Expr) +STMT(81, BlockDeclRefExpr , Expr) -LAST_EXPR(82) +LAST_EXPR(81) #undef STMT #undef FIRST_STMT diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 8bf4afefbb81..a66d97dcb0d5 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -549,11 +549,6 @@ public: virtual ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *Body, Scope *CurScope) { return 0; } - /// ActOnBlockExprExpr - This is called when the body of a block - /// expression literal was successfully completed. ^(int x)[foo bar: x] - virtual ExprResult ActOnBlockExprExpr(SourceLocation CaretLoc, ExprTy *Body, - Scope *CurScope) { return 0; } - //===------------------------- C++ Declarations -------------------------===// /// ActOnStartNamespaceDef - This is called at the start of a namespace diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index ca92c815b96b..8a545d6f401f 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1455,12 +1455,6 @@ Stmt::child_iterator BlockStmtExpr::child_end() { return reinterpret_cast(&Body)+1; } -Stmt::child_iterator BlockExprExpr::child_begin() { - return reinterpret_cast(&BodyExpr); -} -Stmt::child_iterator BlockExprExpr::child_end() { - return reinterpret_cast(&BodyExpr)+1; -} Stmt::child_iterator BlockDeclRefExpr::child_begin(){return child_iterator();} Stmt::child_iterator BlockDeclRefExpr::child_end() { return child_iterator();} diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 566ab717ea2f..fbff987b07d5 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -912,11 +912,6 @@ void StmtPrinter::VisitBlockStmtExpr(BlockStmtExpr *Node) { PrintRawCompoundStmt(Node->getBody()); } -void StmtPrinter::VisitBlockExprExpr(BlockExprExpr *Node) { - VisitBlockExpr(Node); - PrintExpr(Node->getExpr()); -} - void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) { OS << Node->getDecl()->getName(); } diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index b532078d40cd..64f31ddbc806 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1077,11 +1077,10 @@ bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs) { } /// ParseBlockLiteralExpression - Parse a block literal, which roughly looks -/// like ^(int x){ return x+1; } or ^(int y)foo(4, y, z) +/// like ^(int x){ return x+1; } /// /// block-literal: /// [clang] '^' block-args[opt] compound-statement -/// [clang] '^' block-args cast-expression /// [clang] block-args: /// [clang] '(' parameter-list ')' /// @@ -1122,26 +1121,15 @@ Parser::ExprResult Parser::ParseBlockLiteralExpression() { // Inform sema that we are starting a block. Actions.ActOnBlockStart(CaretLoc, CurScope, ParamInfo); - ExprResult Result; + ExprResult Result = true; if (Tok.is(tok::l_brace)) { StmtResult Stmt = ParseCompoundStatementBody(); if (!Stmt.isInvalid) { Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.Val, CurScope); } else { Actions.ActOnBlockError(CaretLoc, CurScope); - Result = true; - } - } else { - ExprResult Expr = ParseCastExpression(false); - if (!Expr.isInvalid) { - Result = Actions.ActOnBlockExprExpr(CaretLoc, Expr.Val, CurScope); - } else { - Actions.ActOnBlockError(CaretLoc, CurScope); - Diag(Tok, diag::err_expected_block_lbrace); - Result = true; } } - ExitScope(); return Result; } diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index e562547a8ee2..99ce5a742931 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -574,11 +574,6 @@ public: virtual ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *Body, Scope *CurScope); - /// ActOnBlockExprExpr - This is called when the body of a block - /// expression literal was successfully completed. ^(int x)[foo bar: x] - virtual ExprResult ActOnBlockExprExpr(SourceLocation CaretLoc, ExprTy *Body, - Scope *CurScope); - // Act on C++ namespaces virtual DeclTy *ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc, IdentifierInfo *Ident, diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index f0765d538d69..0df91d51a950 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2890,40 +2890,6 @@ Sema::ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *body, &BSI->Params[0], BSI->Params.size(), Body.take()); } -/// ActOnBlockExprExpr - This is called when the body of a block -/// expression literal was successfully completed. ^(int x)[foo bar: x] -Sema::ExprResult Sema::ActOnBlockExprExpr(SourceLocation CaretLoc, ExprTy *body, - Scope *CurScope) { - // Ensure that CurBlock is deleted. - llvm::OwningPtr BSI(CurBlock); - llvm::OwningPtr Body(static_cast(body)); - - // Pop off CurBlock, handle nested blocks. - CurBlock = CurBlock->PrevBlockInfo; - - if (BSI->ReturnType) { - Diag(CaretLoc, diag::err_return_in_block_expression); - return true; - } - - QualType RetTy = Body->getType(); - - llvm::SmallVector ArgTypes; - for (unsigned i = 0, e = BSI->Params.size(); i != e; ++i) - ArgTypes.push_back(BSI->Params[i]->getType()); - - QualType BlockTy; - if (!BSI->hasPrototype) - BlockTy = Context.getFunctionTypeNoProto(RetTy); - else - BlockTy = Context.getFunctionType(RetTy, &ArgTypes[0], ArgTypes.size(), - BSI->isVariadic); - - BlockTy = Context.getBlockPointerType(BlockTy); - return new BlockExprExpr(CaretLoc, BlockTy, - &BSI->Params[0], BSI->Params.size(), Body.take()); -} - /// ExprsMatchFnType - return true if the Exprs in array Args have /// QualTypes that match the QualTypes of the arguments of the FnType. /// The number of arguments has already been validated to match the number of diff --git a/clang/test/Sema/block-literal.c b/clang/test/Sema/block-literal.c index a3b9562ee9de..235bb7e23d0f 100644 --- a/clang/test/Sema/block-literal.c +++ b/clang/test/Sema/block-literal.c @@ -21,8 +21,6 @@ T somefunction() { I(^{ }); - noop = ^noop; // expected-error {{incompatible block pointer types}} - return ^{printf("\nClosure\n"); }; // expected-error {{returning block that lives on the local stack}} } void test2() { @@ -42,10 +40,6 @@ void test2() { foo: takeclosure(^{ x = 4; }); // expected-error {{expression is not assignable}} - - takeclosure(^test2()); - takeclosure(^(void)(void)printf("hello world!\n")); - } @@ -61,17 +55,7 @@ void test4() { void *X; void test_arguments() { - takeintint(^(int x)(x+1)); - - // Closure expr of statement expr. - takeintint(^(int x)({ return 42; })); // expected-error {{return not allowed in block expression literal}} - int y; - takeintint(^(int x)(x+y)); -#if 0 - // FIXME: this causes clang to crash. - X = ^(x+r); // expected-error {{expected ')' in argument list}} -#endif int (^c)(char); (1 ? c : 0)('x'); (1 ? 0 : c)('x');