aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/TreeTransform.h
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-19 21:32:01 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-19 21:32:01 +0000
commita779d9ca2fdf1247f65de0e6acf2870d8be53ccd (patch)
tree27cf930e8bc8c5e61bce4279af3d65a4584dc66d /lib/Sema/TreeTransform.h
parentba73adafabb1c0af8bec70a1673edc11e6d30a89 (diff)
Implement basic support for the use of variadic templates and blocks
together. In particular: - Handle the use of captured parameter pack names within blocks (BlockDeclRefExpr understands parameter packs now) - Handle the declaration and expansion of parameter packs within a block's parameter list, e.g., ^(Args ...args) { ... }) - Handle instantiation of blocks where the return type was not explicitly specified. (unrelated, but necessary for my tests). Together, these fixes should make blocks and variadic templates work reasonably well together. Note that BlockDeclRefExpr is still broken w.r.t. its computation of type and value dependence, which will still cause problems for blocks in templates. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123849 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/TreeTransform.h')
-rw-r--r--lib/Sema/TreeTransform.h38
1 files changed, 27 insertions, 11 deletions
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index ebc34d0f35..1cb24e70bf 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -7122,16 +7122,13 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
llvm::SmallVector<QualType, 4> ParamTypes;
// Parameter substitution.
- // FIXME: Variadic templates
- 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,
- llvm::Optional<unsigned>());
- Params.push_back(NewParm);
- ParamTypes.push_back(NewParm->getType());
- }
+ BlockDecl *BD = E->getBlockDecl();
+ if (getDerived().TransformFunctionTypeParams(E->getLocStart(),
+ BD->param_begin(),
+ BD->param_size(), 0, ParamTypes,
+ &Params))
+ return true;
+
const FunctionType *BExprFunctionType = E->getFunctionType();
QualType BExprResultType = BExprFunctionType->getResultType();
@@ -7141,6 +7138,19 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
else if (BExprResultType != SemaRef.Context.DependentTy)
CurBlock->ReturnType = getDerived().TransformType(BExprResultType);
}
+
+ // If the return type has not been determined yet, leave it as a dependent
+ // type; it'll get set when we process the body.
+ if (CurBlock->ReturnType.isNull())
+ CurBlock->ReturnType = getSema().Context.DependentTy;
+
+ // Don't allow returning a objc interface by value.
+ if (CurBlock->ReturnType->isObjCObjectType()) {
+ getSema().Diag(E->getLocStart(),
+ diag::err_object_cannot_be_passed_returned_by_value)
+ << 0 << CurBlock->ReturnType;
+ return ExprError();
+ }
QualType FunctionType = getDerived().RebuildFunctionProtoType(
CurBlock->ReturnType,
@@ -7154,7 +7164,13 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
// Set the parameters on the block decl.
if (!Params.empty())
CurBlock->TheDecl->setParams(Params.data(), Params.size());
-
+
+ // If the return type wasn't explicitly set, it will have been marked as a
+ // dependent type (DependentTy); clear out the return type setting so
+ // we will deduce the return type when type-checking the block's body.
+ if (CurBlock->ReturnType == getSema().Context.DependentTy)
+ CurBlock->ReturnType = QualType();
+
// Transform the body
StmtResult Body = getDerived().TransformStmt(E->getBody());
if (Body.isInvalid())