Instantiation of block literal expressions. wip.

llvm-svn: 108000
This commit is contained in:
Fariborz Jahanian 2010-07-09 18:44:02 +00:00
parent 79edde88ed
commit 1babe7778d
4 changed files with 103 additions and 9 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);
}
//===----------------------------------------------------------------------===//

View File

@ -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');
}