forked from OSchip/llvm-project
Instantiation of block literal expressions. wip.
llvm-svn: 108000
This commit is contained in:
parent
79edde88ed
commit
1babe7778d
|
@ -158,7 +158,7 @@ struct BlockScopeInfo : FunctionScopeInfo {
|
|||
bool hasBlockDeclRefExprs;
|
||||
|
||||
BlockDecl *TheDecl;
|
||||
|
||||
|
||||
/// TheScope - This is the scope for the block itself, which contains
|
||||
/// arguments etc.
|
||||
Scope *TheScope;
|
||||
|
|
|
@ -7074,7 +7074,10 @@ void Sema::ActOnBlockStart(SourceLocation CaretLoc, Scope *BlockScope) {
|
|||
BlockDecl *Block = BlockDecl::Create(Context, CurContext, CaretLoc);
|
||||
PushBlockScope(BlockScope, Block);
|
||||
CurContext->addDecl(Block);
|
||||
PushDeclContext(BlockScope, Block);
|
||||
if (BlockScope)
|
||||
PushDeclContext(BlockScope, Block);
|
||||
else
|
||||
CurContext = Block;
|
||||
}
|
||||
|
||||
void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
|
||||
|
@ -7199,7 +7202,7 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
|
|||
Diag(CaretLoc, diag::err_blocks_disable);
|
||||
|
||||
BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back());
|
||||
|
||||
|
||||
PopDeclContext();
|
||||
|
||||
QualType RetTy = Context.VoidTy;
|
||||
|
|
|
@ -4198,6 +4198,10 @@ TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
|
|||
if (!ND)
|
||||
return SemaRef.ExprError();
|
||||
|
||||
// Set DeclContext if inside a Block.
|
||||
if (BlockScopeInfo *CurBlock = SemaRef.getCurBlock())
|
||||
ND->setDeclContext(CurBlock->TheDecl);
|
||||
|
||||
if (!getDerived().AlwaysRebuild() &&
|
||||
Qualifier == E->getQualifier() &&
|
||||
ND == E->getDecl() &&
|
||||
|
@ -6217,17 +6221,75 @@ TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
|
|||
template<typename Derived>
|
||||
Sema::OwningExprResult
|
||||
TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
|
||||
// FIXME: Implement this!
|
||||
assert(false && "Cannot transform block expressions yet");
|
||||
return SemaRef.Owned(E->Retain());
|
||||
SourceLocation CaretLoc(E->getExprLoc());
|
||||
|
||||
SemaRef.ActOnBlockStart(CaretLoc, /*Scope=*/0);
|
||||
BlockScopeInfo *CurBlock = SemaRef.getCurBlock();
|
||||
CurBlock->TheDecl->setIsVariadic(E->getBlockDecl()->isVariadic());
|
||||
llvm::SmallVector<ParmVarDecl*, 4> Params;
|
||||
llvm::SmallVector<QualType, 4> ParamTypes;
|
||||
|
||||
// Parameter substitution.
|
||||
const BlockDecl *BD = E->getBlockDecl();
|
||||
for (BlockDecl::param_const_iterator P = BD->param_begin(),
|
||||
EN = BD->param_end(); P != EN; ++P) {
|
||||
ParmVarDecl *OldParm = (*P);
|
||||
ParmVarDecl *NewParm = getDerived().TransformFunctionTypeParam(OldParm);
|
||||
QualType NewType = NewParm->getType();
|
||||
Params.push_back(NewParm);
|
||||
ParamTypes.push_back(NewParm->getType());
|
||||
}
|
||||
|
||||
const FunctionType *BExprFunctionType = E->getFunctionType();
|
||||
QualType BExprResultType = BExprFunctionType->getResultType();
|
||||
if (!BExprResultType.isNull()) {
|
||||
if (!BExprResultType->isDependentType())
|
||||
CurBlock->ReturnType = BExprResultType;
|
||||
else if (BExprResultType != SemaRef.Context.DependentTy)
|
||||
CurBlock->ReturnType = getDerived().TransformType(BExprResultType);
|
||||
}
|
||||
|
||||
// Transform the body
|
||||
OwningStmtResult Body = getDerived().TransformStmt(E->getBody());
|
||||
if (Body.isInvalid())
|
||||
return SemaRef.ExprError();
|
||||
// Set the parameters on the block decl.
|
||||
if (!Params.empty())
|
||||
CurBlock->TheDecl->setParams(Params.data(), Params.size());
|
||||
|
||||
QualType FunctionType = getDerived().RebuildFunctionProtoType(
|
||||
CurBlock->ReturnType,
|
||||
ParamTypes.data(),
|
||||
ParamTypes.size(),
|
||||
BD->isVariadic(),
|
||||
0);
|
||||
|
||||
CurBlock->FunctionType = FunctionType;
|
||||
return SemaRef.ActOnBlockStmtExpr(CaretLoc, move(Body), /*Scope=*/0);
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
Sema::OwningExprResult
|
||||
TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
|
||||
// FIXME: Implement this!
|
||||
assert(false && "Cannot transform block-related expressions yet");
|
||||
return SemaRef.Owned(E->Retain());
|
||||
NestedNameSpecifier *Qualifier = 0;
|
||||
|
||||
ValueDecl *ND
|
||||
= cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
|
||||
E->getDecl()));
|
||||
if (!ND)
|
||||
return SemaRef.ExprError();
|
||||
|
||||
if (!getDerived().AlwaysRebuild() &&
|
||||
ND == E->getDecl()) {
|
||||
// Mark it referenced in the new context regardless.
|
||||
// FIXME: this is a bit instantiation-specific.
|
||||
SemaRef.MarkDeclarationReferenced(E->getLocation(), ND);
|
||||
|
||||
return SemaRef.Owned(E->Retain());
|
||||
}
|
||||
|
||||
return getDerived().RebuildDeclRefExpr(Qualifier, SourceLocation(),
|
||||
ND, E->getLocation(), 0);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// RUN: %clang_cc1 -fblocks -emit-llvm -o - %s
|
||||
// rdar : // 6182276
|
||||
|
||||
template <typename T> T foo(T t)
|
||||
{
|
||||
void (^block)(int);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int test1(void)
|
||||
{
|
||||
int i = 1;
|
||||
int b = 2;
|
||||
i = foo(b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T, typename T1> void foo(T t, T1 r)
|
||||
{
|
||||
T block_arg;
|
||||
T1 (^block)(char, T, T1, double) = ^ T1 (char ch, T arg, T1 arg2, double d1) { return block_arg+arg; };
|
||||
|
||||
void (^block2)() = ^{};
|
||||
}
|
||||
|
||||
void test2(void)
|
||||
{
|
||||
foo(100, 'a');
|
||||
}
|
Loading…
Reference in New Issue