aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/TreeTransform.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/TreeTransform.h')
-rw-r--r--lib/Sema/TreeTransform.h72
1 files changed, 68 insertions, 4 deletions
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 8d66acbaf2..52f6c4d4c0 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -323,6 +323,15 @@ public:
/// \returns the transformed expression.
ExprResult TransformExpr(Expr *E);
+ /// \brief Transform the given initializer.
+ ///
+ /// By default, this routine transforms an initializer by stripping off the
+ /// semantic nodes added by initialization, then passing the result to
+ /// TransformExpr or TransformExprs.
+ ///
+ /// \returns the transformed initializer.
+ ExprResult TransformInitializer(Expr *Init, bool CXXDirectInit);
+
/// \brief Transform the given list of expressions.
///
/// This routine transforms a list of expressions by invoking
@@ -2113,6 +2122,7 @@ public:
bool IsElidable,
MultiExprArg Args,
bool HadMultipleCandidates,
+ bool ListInitialization,
bool RequiresZeroInit,
CXXConstructExpr::ConstructionKind ConstructKind,
SourceRange ParenRange) {
@@ -2124,6 +2134,7 @@ public:
return getSema().BuildCXXConstructExpr(Loc, T, Constructor, IsElidable,
ConvertedArgs,
HadMultipleCandidates,
+ ListInitialization,
RequiresZeroInit, ConstructKind,
ParenRange);
}
@@ -2575,6 +2586,53 @@ ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
}
template<typename Derived>
+ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
+ bool CXXDirectInit) {
+ // Initializers are instantiated like expressions, except that various outer
+ // layers are stripped.
+ if (!Init)
+ return SemaRef.Owned(Init);
+
+ if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
+ Init = ExprTemp->getSubExpr();
+
+ while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
+ Init = Binder->getSubExpr();
+
+ if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
+ Init = ICE->getSubExprAsWritten();
+
+ // If this is a direct-initializer, we take apart CXXConstructExprs.
+ // Everything else is passed through.
+ CXXConstructExpr *Construct;
+ if (!(Construct = dyn_cast<CXXConstructExpr>(Init)) ||
+ isa<CXXTemporaryObjectExpr>(Construct) ||
+ (!CXXDirectInit && !Construct->isListInitialization()))
+ return getDerived().TransformExpr(Init);
+
+ SmallVector<Expr*, 8> NewArgs;
+ bool ArgChanged = false;
+ if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
+ /*IsCall*/true, NewArgs, &ArgChanged))
+ return ExprError();
+
+ // If this was list initialization, revert to list form.
+ if (Construct->isListInitialization())
+ return getDerived().RebuildInitList(Construct->getLocStart(), NewArgs,
+ Construct->getLocEnd(),
+ Construct->getType());
+
+ // Treat an empty initializer like none.
+ if (NewArgs.empty())
+ return SemaRef.Owned((Expr*)0);
+
+ // Build a ParenListExpr to represent anything else.
+ SourceRange Parens = Construct->getParenRange();
+ return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
+ Parens.getEnd());
+}
+
+template<typename Derived>
bool TreeTransform<Derived>::TransformExprs(Expr **Inputs,
unsigned NumInputs,
bool IsCall,
@@ -2656,7 +2714,9 @@ bool TreeTransform<Derived>::TransformExprs(Expr **Inputs,
continue;
}
- ExprResult Result = getDerived().TransformExpr(Inputs[I]);
+ ExprResult Result =
+ IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
+ : getDerived().TransformExpr(Inputs[I]);
if (Result.isInvalid())
return true;
@@ -7747,11 +7807,13 @@ TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
- // CXXConstructExprs are always implicit, so when we have a
- // 1-argument construction we just transform that argument.
+ // CXXConstructExprs other than for list-initialization and
+ // CXXTemporaryObjectExpr are always implicit, so when we have
+ // a 1-argument construction we just transform that argument.
if ((E->getNumArgs() == 1 ||
(E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) &&
- (!getDerived().DropCallArgument(E->getArg(0))))
+ (!getDerived().DropCallArgument(E->getArg(0))) &&
+ !E->isListInitialization())
return getDerived().TransformExpr(E->getArg(0));
TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
@@ -7787,6 +7849,7 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
Constructor, E->isElidable(),
Args,
E->hadMultipleCandidates(),
+ E->isListInitialization(),
E->requiresZeroInitialization(),
E->getConstructionKind(),
E->getParenRange());
@@ -7844,6 +7907,7 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
return SemaRef.MaybeBindToTemporary(E);
}
+ // FIXME: Pass in E->isListInitialization().
return getDerived().RebuildCXXTemporaryObjectExpr(T,
/*FIXME:*/T->getTypeLoc().getEndLoc(),
Args,