[cfe-commits] r108000 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/TreeTransform.h test/CodeGenCXX/instantiate-blocks.cpp
Fariborz Jahanian
fjahanian at apple.com
Fri Jul 9 11:44:03 PDT 2010
Author: fjahanian
Date: Fri Jul 9 13:44:02 2010
New Revision: 108000
URL: http://llvm.org/viewvc/llvm-project?rev=108000&view=rev
Log:
Instantiation of block literal expressions. wip.
Added:
cfe/trunk/test/CodeGenCXX/instantiate-blocks.cpp
Modified:
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/TreeTransform.h
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=108000&r1=107999&r2=108000&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Jul 9 13:44:02 2010
@@ -158,7 +158,7 @@
bool hasBlockDeclRefExprs;
BlockDecl *TheDecl;
-
+
/// TheScope - This is the scope for the block itself, which contains
/// arguments etc.
Scope *TheScope;
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=108000&r1=107999&r2=108000&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jul 9 13:44:02 2010
@@ -7074,7 +7074,10 @@
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 @@
Diag(CaretLoc, diag::err_blocks_disable);
BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back());
-
+
PopDeclContext();
QualType RetTy = Context.VoidTy;
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=108000&r1=107999&r2=108000&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Fri Jul 9 13:44:02 2010
@@ -4198,6 +4198,10 @@
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 @@
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);
}
//===----------------------------------------------------------------------===//
Added: cfe/trunk/test/CodeGenCXX/instantiate-blocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/instantiate-blocks.cpp?rev=108000&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/instantiate-blocks.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/instantiate-blocks.cpp Fri Jul 9 13:44:02 2010
@@ -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');
+}
More information about the cfe-commits
mailing list