зеркало из https://github.com/microsoft/clang-1.git
Remove support for BlockExprExpr. For example...
^(expression) or ^(int arg1, float arg2)(expression) ...is no longer supported. All block literals now require a compound statement. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56257 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
c50a4a5f2e
Коммит
17dab4f616
|
@ -1487,6 +1487,7 @@ private:
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// BlockExpr - Common base class between BlockStmtExpr and BlockExprExpr.
|
/// BlockExpr - Common base class between BlockStmtExpr and BlockExprExpr.
|
||||||
|
/// FIXME: Combine with BlockStmtExpr...no more need for a common base.
|
||||||
class BlockExpr : public Expr {
|
class BlockExpr : public Expr {
|
||||||
SourceLocation CaretLocation;
|
SourceLocation CaretLocation;
|
||||||
llvm::SmallVector<ParmVarDecl*, 8> Args;
|
llvm::SmallVector<ParmVarDecl*, 8> Args;
|
||||||
|
@ -1508,8 +1509,7 @@ public:
|
||||||
arg_iterator arg_end() const { return Args.end(); }
|
arg_iterator arg_end() const { return Args.end(); }
|
||||||
|
|
||||||
static bool classof(const Stmt *T) {
|
static bool classof(const Stmt *T) {
|
||||||
return T->getStmtClass() == BlockStmtExprClass ||
|
return T->getStmtClass() == BlockStmtExprClass;
|
||||||
T->getStmtClass() == BlockExprExprClass;
|
|
||||||
}
|
}
|
||||||
static bool classof(const BlockExpr *) { return true; }
|
static bool classof(const BlockExpr *) { return true; }
|
||||||
};
|
};
|
||||||
|
@ -1544,33 +1544,6 @@ public:
|
||||||
static BlockStmtExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
|
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,
|
/// BlockDeclRefExpr - A reference to a declared variable, function,
|
||||||
/// enum, etc.
|
/// enum, etc.
|
||||||
class BlockDeclRefExpr : public Expr {
|
class BlockDeclRefExpr : public Expr {
|
||||||
|
|
|
@ -111,10 +111,9 @@ STMT(77, OverloadExpr , Expr)
|
||||||
STMT(78, ShuffleVectorExpr , Expr)
|
STMT(78, ShuffleVectorExpr , Expr)
|
||||||
STMT(79, BlockExpr , Expr)
|
STMT(79, BlockExpr , Expr)
|
||||||
STMT(80, BlockStmtExpr , BlockExpr)
|
STMT(80, BlockStmtExpr , BlockExpr)
|
||||||
STMT(81, BlockExprExpr , BlockExpr)
|
STMT(81, BlockDeclRefExpr , Expr)
|
||||||
STMT(82, BlockDeclRefExpr , Expr)
|
|
||||||
|
|
||||||
LAST_EXPR(82)
|
LAST_EXPR(81)
|
||||||
|
|
||||||
#undef STMT
|
#undef STMT
|
||||||
#undef FIRST_STMT
|
#undef FIRST_STMT
|
||||||
|
|
|
@ -549,11 +549,6 @@ public:
|
||||||
virtual ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *Body,
|
virtual ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *Body,
|
||||||
Scope *CurScope) { return 0; }
|
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 -------------------------===//
|
//===------------------------- C++ Declarations -------------------------===//
|
||||||
|
|
||||||
/// ActOnStartNamespaceDef - This is called at the start of a namespace
|
/// ActOnStartNamespaceDef - This is called at the start of a namespace
|
||||||
|
|
|
@ -1455,12 +1455,6 @@ Stmt::child_iterator BlockStmtExpr::child_end() {
|
||||||
return reinterpret_cast<Stmt**>(&Body)+1;
|
return reinterpret_cast<Stmt**>(&Body)+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stmt::child_iterator BlockExprExpr::child_begin() {
|
|
||||||
return reinterpret_cast<Stmt**>(&BodyExpr);
|
|
||||||
}
|
|
||||||
Stmt::child_iterator BlockExprExpr::child_end() {
|
|
||||||
return reinterpret_cast<Stmt**>(&BodyExpr)+1;
|
|
||||||
}
|
|
||||||
Stmt::child_iterator BlockDeclRefExpr::child_begin(){return child_iterator();}
|
Stmt::child_iterator BlockDeclRefExpr::child_begin(){return child_iterator();}
|
||||||
Stmt::child_iterator BlockDeclRefExpr::child_end() { return child_iterator();}
|
Stmt::child_iterator BlockDeclRefExpr::child_end() { return child_iterator();}
|
||||||
|
|
||||||
|
|
|
@ -912,11 +912,6 @@ void StmtPrinter::VisitBlockStmtExpr(BlockStmtExpr *Node) {
|
||||||
PrintRawCompoundStmt(Node->getBody());
|
PrintRawCompoundStmt(Node->getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
void StmtPrinter::VisitBlockExprExpr(BlockExprExpr *Node) {
|
|
||||||
VisitBlockExpr(Node);
|
|
||||||
PrintExpr(Node->getExpr());
|
|
||||||
}
|
|
||||||
|
|
||||||
void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
|
void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
|
||||||
OS << Node->getDecl()->getName();
|
OS << Node->getDecl()->getName();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1077,11 +1077,10 @@ bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseBlockLiteralExpression - Parse a block literal, which roughly looks
|
/// 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:
|
/// block-literal:
|
||||||
/// [clang] '^' block-args[opt] compound-statement
|
/// [clang] '^' block-args[opt] compound-statement
|
||||||
/// [clang] '^' block-args cast-expression
|
|
||||||
/// [clang] block-args:
|
/// [clang] block-args:
|
||||||
/// [clang] '(' parameter-list ')'
|
/// [clang] '(' parameter-list ')'
|
||||||
///
|
///
|
||||||
|
@ -1122,26 +1121,15 @@ Parser::ExprResult Parser::ParseBlockLiteralExpression() {
|
||||||
// Inform sema that we are starting a block.
|
// Inform sema that we are starting a block.
|
||||||
Actions.ActOnBlockStart(CaretLoc, CurScope, ParamInfo);
|
Actions.ActOnBlockStart(CaretLoc, CurScope, ParamInfo);
|
||||||
|
|
||||||
ExprResult Result;
|
ExprResult Result = true;
|
||||||
if (Tok.is(tok::l_brace)) {
|
if (Tok.is(tok::l_brace)) {
|
||||||
StmtResult Stmt = ParseCompoundStatementBody();
|
StmtResult Stmt = ParseCompoundStatementBody();
|
||||||
if (!Stmt.isInvalid) {
|
if (!Stmt.isInvalid) {
|
||||||
Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.Val, CurScope);
|
Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.Val, CurScope);
|
||||||
} else {
|
} else {
|
||||||
Actions.ActOnBlockError(CaretLoc, CurScope);
|
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();
|
ExitScope();
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -574,11 +574,6 @@ public:
|
||||||
virtual ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *Body,
|
virtual ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *Body,
|
||||||
Scope *CurScope);
|
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
|
// Act on C++ namespaces
|
||||||
virtual DeclTy *ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc,
|
virtual DeclTy *ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc,
|
||||||
IdentifierInfo *Ident,
|
IdentifierInfo *Ident,
|
||||||
|
|
|
@ -2890,40 +2890,6 @@ Sema::ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *body,
|
||||||
&BSI->Params[0], BSI->Params.size(), Body.take());
|
&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<BlockSemaInfo> BSI(CurBlock);
|
|
||||||
llvm::OwningPtr<Expr> Body(static_cast<Expr*>(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<QualType, 8> 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
|
/// ExprsMatchFnType - return true if the Exprs in array Args have
|
||||||
/// QualTypes that match the QualTypes of the arguments of the FnType.
|
/// QualTypes that match the QualTypes of the arguments of the FnType.
|
||||||
/// The number of arguments has already been validated to match the number of
|
/// The number of arguments has already been validated to match the number of
|
||||||
|
|
|
@ -21,8 +21,6 @@ T somefunction() {
|
||||||
|
|
||||||
I(^{ });
|
I(^{ });
|
||||||
|
|
||||||
noop = ^noop; // expected-error {{incompatible block pointer types}}
|
|
||||||
|
|
||||||
return ^{printf("\nClosure\n"); }; // expected-error {{returning block that lives on the local stack}}
|
return ^{printf("\nClosure\n"); }; // expected-error {{returning block that lives on the local stack}}
|
||||||
}
|
}
|
||||||
void test2() {
|
void test2() {
|
||||||
|
@ -42,10 +40,6 @@ void test2() {
|
||||||
|
|
||||||
foo:
|
foo:
|
||||||
takeclosure(^{ x = 4; }); // expected-error {{expression is not assignable}}
|
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 *X;
|
||||||
|
|
||||||
void test_arguments() {
|
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;
|
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);
|
int (^c)(char);
|
||||||
(1 ? c : 0)('x');
|
(1 ? c : 0)('x');
|
||||||
(1 ? 0 : c)('x');
|
(1 ? 0 : c)('x');
|
||||||
|
|
Загрузка…
Ссылка в новой задаче