forked from OSchip/llvm-project
Sema and CodeGen support for attributes on blocks. Radar 6441502
llvm-svn: 70403
This commit is contained in:
parent
6bd78709f2
commit
88788feddd
|
@ -1609,6 +1609,8 @@ def ext_return_has_void_expr : Extension<
|
|||
"void %select{function|method}1 %0 should not return void expression">;
|
||||
def err_noreturn_function_has_return_expr : Error<
|
||||
"function %0 declared 'noreturn' should not return">;
|
||||
def err_noreturn_block_has_return_expr : Error<
|
||||
"block declared 'noreturn' should not return">;
|
||||
|
||||
def err_shufflevector_non_vector : Error<
|
||||
"first two arguments to __builtin_shufflevector must be vectors">;
|
||||
|
|
|
@ -1290,6 +1290,13 @@ void Parser::ParseBlockId() {
|
|||
// Parse the block-declarator.
|
||||
Declarator DeclaratorInfo(DS, Declarator::BlockLiteralContext);
|
||||
ParseDeclarator(DeclaratorInfo);
|
||||
|
||||
if (Tok.is(tok::kw___attribute)) {
|
||||
SourceLocation Loc;
|
||||
AttributeList *AttrList = ParseAttributes(&Loc);
|
||||
DeclaratorInfo.AddAttributes(AttrList, Loc);
|
||||
}
|
||||
|
||||
// Inform sema that we are starting a block.
|
||||
Actions.ActOnBlockArguments(DeclaratorInfo, CurScope);
|
||||
}
|
||||
|
@ -1345,6 +1352,13 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() {
|
|||
Actions.ActOnBlockError(CaretLoc, CurScope);
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
if (Tok.is(tok::kw___attribute)) {
|
||||
SourceLocation Loc;
|
||||
AttributeList *AttrList = ParseAttributes(&Loc);
|
||||
ParamInfo.AddAttributes(AttrList, Loc);
|
||||
}
|
||||
|
||||
// Inform sema that we are starting a block.
|
||||
Actions.ActOnBlockArguments(ParamInfo, CurScope);
|
||||
} else if (!Tok.is(tok::l_brace)) {
|
||||
|
@ -1357,6 +1371,13 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() {
|
|||
false, false, 0, 0,
|
||||
CaretLoc, ParamInfo),
|
||||
CaretLoc);
|
||||
|
||||
if (Tok.is(tok::kw___attribute)) {
|
||||
SourceLocation Loc;
|
||||
AttributeList *AttrList = ParseAttributes(&Loc);
|
||||
ParamInfo.AddAttributes(AttrList, Loc);
|
||||
}
|
||||
|
||||
// Inform sema that we are starting a block.
|
||||
Actions.ActOnBlockArguments(ParamInfo, CurScope);
|
||||
}
|
||||
|
|
|
@ -408,10 +408,13 @@ static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!isFunctionOrMethod(d)) {
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
|
||||
<< attrName << 0 /*function*/;
|
||||
return false;
|
||||
if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
|
||||
ValueDecl *VD = dyn_cast<ValueDecl>(d);
|
||||
if (VD == 0 || !VD->getType()->isBlockPointerType()) {
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
|
||||
<< attrName << 0 /*function*/;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -4773,6 +4773,7 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
|
|||
}
|
||||
CurBlock->TheDecl->setParams(Context, &CurBlock->Params[0],
|
||||
CurBlock->Params.size());
|
||||
ProcessDeclAttributes(CurBlock->TheDecl, ParamInfo);
|
||||
|
||||
for (BlockDecl::param_iterator AI = CurBlock->TheDecl->param_begin(),
|
||||
E = CurBlock->TheDecl->param_end(); AI != E; ++AI)
|
||||
|
|
|
@ -707,6 +707,12 @@ Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
|
|||
Action::OwningStmtResult
|
||||
Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
|
||||
|
||||
if (CurBlock->TheDecl->hasAttr<NoReturnAttr>()) {
|
||||
Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr)
|
||||
<< getCurFunctionOrMethodDecl()->getDeclName();
|
||||
return StmtError();
|
||||
}
|
||||
|
||||
// If this is the first return we've seen in the block, infer the type of
|
||||
// the block from it.
|
||||
if (CurBlock->ReturnType == 0) {
|
||||
|
|
|
@ -95,3 +95,9 @@ bptr foo5(int j) {
|
|||
|
||||
int (*funcptr3[5])(long);
|
||||
int sz8 = sizeof(^int (*[5])(long) {return funcptr3;}); // expected-error {{block declared as returning an array}}
|
||||
|
||||
void foo6() {
|
||||
void (^b)(int) __attribute__((noreturn));
|
||||
b = ^ (int i) __attribute__((noreturn)) { return 1; }; // expected-error {{block declared 'noreturn' should not return}}
|
||||
b(1);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue