summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/Sema.cpp5
-rw-r--r--clang/lib/Sema/SemaCast.cpp8
-rw-r--r--clang/lib/Sema/SemaCoroutine.cpp4
-rw-r--r--clang/lib/Sema/SemaDecl.cpp2
-rw-r--r--clang/lib/Sema/SemaExpr.cpp35
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp16
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp4
-rw-r--r--clang/lib/Sema/SemaInit.cpp30
-rw-r--r--clang/lib/Sema/SemaLambda.cpp11
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp8
-rw-r--r--clang/lib/Sema/SemaStmt.cpp8
11 files changed, 48 insertions, 83 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index d7697bfc9be..e7708e044d2 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -88,7 +88,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
ConstSegStack(nullptr), CodeSegStack(nullptr), CurInitSeg(nullptr),
VisContext(nullptr),
IsBuildingRecoveryCallExpr(false),
- Cleanup{}, LateTemplateParser(nullptr),
+ ExprNeedsCleanups(false), LateTemplateParser(nullptr),
LateTemplateParserCleanup(nullptr),
OpaqueParser(nullptr), IdResolver(pp), StdInitializerList(nullptr),
CXXTypeInfoDecl(nullptr), MSVCGuidDecl(nullptr),
@@ -124,8 +124,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
// Tell diagnostics how to render things from the AST library.
Diags.SetArgToStringFn(&FormatASTNodeDiagnosticArgument, &Context);
- ExprEvalContexts.emplace_back(PotentiallyEvaluated, 0, CleanupInfo{}, nullptr,
- false);
+ ExprEvalContexts.emplace_back(PotentiallyEvaluated, 0, false, nullptr, false);
FunctionScopes.push_back(new FunctionScopeInfo(Diags));
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index d27500d3f13..df32dbdb150 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -641,8 +641,8 @@ void CastOperation::CheckDynamicCast() {
// If we're dynamic_casting from a prvalue to an rvalue reference, we need
// to materialize the prvalue before we bind the reference to it.
if (SrcExpr.get()->isRValue())
- SrcExpr = Self.CreateMaterializeTemporaryExpr(
- SrcType, SrcExpr.get(), /*IsLValueReference*/ false);
+ SrcExpr = new (Self.Context) MaterializeTemporaryExpr(
+ SrcType, SrcExpr.get(), /*IsLValueReference*/false);
SrcPointee = SrcType;
}
@@ -1649,8 +1649,8 @@ static TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr,
if (NeedToMaterializeTemporary)
// This is a const_cast from a class prvalue to an rvalue reference type.
// Materialize a temporary to store the result of the conversion.
- SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcType, SrcExpr.get(),
- /*IsLValueReference*/ false);
+ SrcExpr = new (Self.Context) MaterializeTemporaryExpr(
+ SrcType, SrcExpr.get(), /*IsLValueReference*/ false);
return TC_Success;
}
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index c8715fff415..4b4fd6b16a0 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -244,7 +244,7 @@ ExprResult Sema::BuildCoawaitExpr(SourceLocation Loc, Expr *E) {
// If the expression is a temporary, materialize it as an lvalue so that we
// can use it multiple times.
if (E->getValueKind() == VK_RValue)
- E = CreateMaterializeTemporaryExpr(E->getType(), E, true);
+ E = new (Context) MaterializeTemporaryExpr(E->getType(), E, true);
// Build the await_ready, await_suspend, await_resume calls.
ReadySuspendResumeResult RSS = buildCoawaitCalls(*this, Loc, E);
@@ -311,7 +311,7 @@ ExprResult Sema::BuildCoyieldExpr(SourceLocation Loc, Expr *E) {
// If the expression is a temporary, materialize it as an lvalue so that we
// can use it multiple times.
if (E->getValueKind() == VK_RValue)
- E = CreateMaterializeTemporaryExpr(E->getType(), E, true);
+ E = new (Context) MaterializeTemporaryExpr(E->getType(), E, true);
// Build the await_ready, await_suspend, await_resume calls.
ReadySuspendResumeResult RSS = buildCoawaitCalls(*this, Loc, E);
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 632532ad44e..fab72f36605 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11648,7 +11648,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
assert(ExprCleanupObjects.size() ==
ExprEvalContexts.back().NumCleanupObjects &&
"Leftover temporaries in function");
- assert(!Cleanup.exprNeedsCleanups() && "Unaccounted cleanups in function");
+ assert(!ExprNeedsCleanups && "Unaccounted cleanups in function");
assert(MaybeODRUseExprs.empty() &&
"Leftover expressions for odr-use checking");
}
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 784dd7c4537..f4a5dea8f94 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -712,7 +712,7 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
// balance that.
if (getLangOpts().ObjCAutoRefCount &&
E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
- Cleanup.setExprNeedsCleanups(true);
+ ExprNeedsCleanups = true;
ExprResult Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E,
nullptr, VK_RValue);
@@ -4573,15 +4573,15 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
// bound temporaries; see the comment in PR5810.
// We don't need to do that with block decls, though, because
// blocks in default argument expression can never capture anything.
- if (auto Init = dyn_cast<ExprWithCleanups>(Param->getInit())) {
+ if (isa<ExprWithCleanups>(Param->getInit())) {
// Set the "needs cleanups" bit regardless of whether there are
// any explicit objects.
- Cleanup.setExprNeedsCleanups(Init->cleanupsHaveSideEffects());
+ ExprNeedsCleanups = true;
// Append all the objects to the cleanup list. Right now, this
// should always be a no-op, because blocks in default argument
// expressions should never be able to capture anything.
- assert(!Init->getNumObjects() &&
+ assert(!cast<ExprWithCleanups>(Param->getInit())->getNumObjects() &&
"default argument expression has capturing blocks?");
}
@@ -5596,7 +5596,7 @@ void Sema::maybeExtendBlockObject(ExprResult &E) {
E = ImplicitCastExpr::Create(Context, E.get()->getType(),
CK_ARCExtendBlockObject, E.get(),
/*base path*/ nullptr, VK_RValue);
- Cleanup.setExprNeedsCleanups(true);
+ ExprNeedsCleanups = true;
}
/// Prepare a conversion of the given expression to an ObjC object
@@ -10382,8 +10382,8 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) {
if (sfinae)
return QualType();
// Materialize the temporary as an lvalue so that we can take its address.
- OrigOp = op =
- CreateMaterializeTemporaryExpr(op->getType(), OrigOp.get(), true);
+ OrigOp = op = new (Context)
+ MaterializeTemporaryExpr(op->getType(), OrigOp.get(), true);
} else if (isa<ObjCSelectorExpr>(op)) {
return Context.getPointerType(op->getType());
} else if (lval == Expr::LV_MemberFunction) {
@@ -11596,8 +11596,7 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
if (hasAnyUnrecoverableErrorsInThisFunction())
DiscardCleanupsInEvaluationContext();
- assert(!Cleanup.exprNeedsCleanups() &&
- "cleanups within StmtExpr not correctly bound!");
+ assert(!ExprNeedsCleanups && "cleanups within StmtExpr not correctly bound!");
PopExpressionEvaluationContext();
// FIXME: there are a variety of strange constraints to enforce here, for
@@ -12065,8 +12064,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
// Leave the expression-evaluation context.
if (hasAnyUnrecoverableErrorsInThisFunction())
DiscardCleanupsInEvaluationContext();
- assert(!Cleanup.exprNeedsCleanups() &&
- "cleanups within block not correctly bound!");
+ assert(!ExprNeedsCleanups && "cleanups within block not correctly bound!");
PopExpressionEvaluationContext();
BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back());
@@ -12157,7 +12155,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
if (Result->getBlockDecl()->hasCaptures()) {
// First, this expression has a new cleanup object.
ExprCleanupObjects.push_back(Result->getBlockDecl());
- Cleanup.setExprNeedsCleanups(true);
+ ExprNeedsCleanups = true;
// It also gets a branch-protected scope if any of the captured
// variables needs destruction.
@@ -12794,9 +12792,10 @@ void
Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
Decl *LambdaContextDecl,
bool IsDecltype) {
- ExprEvalContexts.emplace_back(NewContext, ExprCleanupObjects.size(), Cleanup,
- LambdaContextDecl, IsDecltype);
- Cleanup.reset();
+ ExprEvalContexts.emplace_back(NewContext, ExprCleanupObjects.size(),
+ ExprNeedsCleanups, LambdaContextDecl,
+ IsDecltype);
+ ExprNeedsCleanups = false;
if (!MaybeODRUseExprs.empty())
std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs);
}
@@ -12847,12 +12846,12 @@ void Sema::PopExpressionEvaluationContext() {
if (Rec.isUnevaluated() || Rec.Context == ConstantEvaluated) {
ExprCleanupObjects.erase(ExprCleanupObjects.begin() + Rec.NumCleanupObjects,
ExprCleanupObjects.end());
- Cleanup = Rec.ParentCleanup;
+ ExprNeedsCleanups = Rec.ParentNeedsCleanups;
CleanupVarDeclMarking();
std::swap(MaybeODRUseExprs, Rec.SavedMaybeODRUseExprs);
// Otherwise, merge the contexts together.
} else {
- Cleanup.mergeFrom(Rec.ParentCleanup);
+ ExprNeedsCleanups |= Rec.ParentNeedsCleanups;
MaybeODRUseExprs.insert(Rec.SavedMaybeODRUseExprs.begin(),
Rec.SavedMaybeODRUseExprs.end());
}
@@ -12871,7 +12870,7 @@ void Sema::DiscardCleanupsInEvaluationContext() {
ExprCleanupObjects.erase(
ExprCleanupObjects.begin() + ExprEvalContexts.back().NumCleanupObjects,
ExprCleanupObjects.end());
- Cleanup.reset();
+ ExprNeedsCleanups = false;
MaybeODRUseExprs.clear();
}
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 7562a178e2e..4b1be6483c4 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5551,7 +5551,7 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) {
if (!ReturnsRetained && E->getType()->isObjCARCImplicitlyUnretainedType())
return E;
- Cleanup.setExprNeedsCleanups(true);
+ ExprNeedsCleanups = true;
CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject
: CK_ARCReclaimReturnedObject);
@@ -5604,7 +5604,7 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) {
return E;
// We need a cleanup, but we don't need to remember the temporary.
- Cleanup.setExprNeedsCleanups(true);
+ ExprNeedsCleanups = true;
}
CXXTemporary *Temp = CXXTemporary::Create(Context, Destructor);
@@ -5631,16 +5631,14 @@ Expr *Sema::MaybeCreateExprWithCleanups(Expr *SubExpr) {
unsigned FirstCleanup = ExprEvalContexts.back().NumCleanupObjects;
assert(ExprCleanupObjects.size() >= FirstCleanup);
- assert(Cleanup.exprNeedsCleanups() ||
- ExprCleanupObjects.size() == FirstCleanup);
- if (!Cleanup.exprNeedsCleanups())
+ assert(ExprNeedsCleanups || ExprCleanupObjects.size() == FirstCleanup);
+ if (!ExprNeedsCleanups)
return SubExpr;
auto Cleanups = llvm::makeArrayRef(ExprCleanupObjects.begin() + FirstCleanup,
ExprCleanupObjects.size() - FirstCleanup);
- auto *E = ExprWithCleanups::Create(
- Context, SubExpr, Cleanup.cleanupsHaveSideEffects(), Cleanups);
+ Expr *E = ExprWithCleanups::Create(Context, SubExpr, Cleanups);
DiscardCleanupsInEvaluationContext();
return E;
@@ -5651,7 +5649,7 @@ Stmt *Sema::MaybeCreateStmtWithCleanups(Stmt *SubStmt) {
CleanupVarDeclMarking();
- if (!Cleanup.exprNeedsCleanups())
+ if (!ExprNeedsCleanups)
return SubStmt;
// FIXME: In order to attach the temporaries, wrap the statement into
@@ -5757,7 +5755,7 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) {
return ExprError();
// We need a cleanup, but we don't need to remember the temporary.
- Cleanup.setExprNeedsCleanups(true);
+ ExprNeedsCleanups = true;
}
// Possibly strip off the top CXXBindTemporaryExpr.
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index 598ae2098aa..56161c7a4d2 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -4067,7 +4067,7 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
castExpr = ImplicitCastExpr::Create(Context, castExpr->getType(),
CK_ARCConsumeObject, castExpr,
nullptr, VK_RValue);
- Cleanup.setExprNeedsCleanups(true);
+ ExprNeedsCleanups = true;
return ACR_okay;
}
@@ -4310,7 +4310,7 @@ ExprResult Sema::BuildObjCBridgedCast(SourceLocation LParenLoc,
TSInfo, SubExpr);
if (MustConsume) {
- Cleanup.setExprNeedsCleanups(true);
+ ExprNeedsCleanups = true;
Result = ImplicitCastExpr::Create(Context, T, CK_ARCConsumeObject, Result,
nullptr, VK_RValue);
}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 2c4cfab0548..c162007349c 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -4807,8 +4807,8 @@ static void checkIndirectCopyRestoreSource(Sema &S, Expr *src) {
// If isWeakAccess to true, there will be an implicit
// load which requires a cleanup.
if (S.getLangOpts().ObjCAutoRefCount && isWeakAccess)
- S.Cleanup.setExprNeedsCleanups(true);
-
+ S.ExprNeedsCleanups = true;
+
if (iik == IIK_okay) return;
S.Diag(src->getExprLoc(), diag::err_arc_nonlocal_writeback)
@@ -6182,22 +6182,6 @@ static void CheckForNullPointerDereference(Sema &S, const Expr *E) {
}
}
-MaterializeTemporaryExpr *
-Sema::CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary,
- bool BoundToLvalueReference) {
- auto MTE = new (Context)
- MaterializeTemporaryExpr(T, Temporary, BoundToLvalueReference);
-
- // Order an ExprWithCleanups for lifetime marks.
- //
- // TODO: It'll be good to have a single place to check the access of the
- // destructor and generate ExprWithCleanups for various uses. Currently these
- // are done in both CreateMaterializeTemporaryExpr and MaybeBindToTemporary,
- // but there may be a chance to merge them.
- Cleanup.setExprNeedsCleanups(false);
- return MTE;
-}
-
ExprResult
InitializationSequence::Perform(Sema &S,
const InitializedEntity &Entity,
@@ -6462,7 +6446,7 @@ InitializationSequence::Perform(Sema &S,
return ExprError();
// Materialize the temporary into memory.
- MaterializeTemporaryExpr *MTE = S.CreateMaterializeTemporaryExpr(
+ MaterializeTemporaryExpr *MTE = new (S.Context) MaterializeTemporaryExpr(
Entity.getType().getNonReferenceType(), CurInit.get(),
Entity.getType()->isLValueReferenceType());
@@ -6482,7 +6466,7 @@ InitializationSequence::Perform(Sema &S,
MTE->getType()->isObjCLifetimeType()) ||
(MTE->getStorageDuration() == SD_Automatic &&
MTE->getType().isDestructedType()))
- S.Cleanup.setExprNeedsCleanups(true);
+ S.ExprNeedsCleanups = true;
CurInit = MTE;
break;
@@ -6874,9 +6858,9 @@ InitializationSequence::Perform(Sema &S,
<< CurInit.get()->getSourceRange();
// Materialize the temporary into memory.
- MaterializeTemporaryExpr *MTE = S.CreateMaterializeTemporaryExpr(
- CurInit.get()->getType(), CurInit.get(),
- /*BoundToLvalueReference=*/false);
+ MaterializeTemporaryExpr *MTE = new (S.Context)
+ MaterializeTemporaryExpr(CurInit.get()->getType(), CurInit.get(),
+ /*BoundToLvalueReference=*/false);
// Maybe lifetime-extend the array temporary's subobjects to match the
// entity's lifetime.
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index ae768b62677..d1d002b5d41 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1500,7 +1500,7 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
SourceRange IntroducerRange;
bool ExplicitParams;
bool ExplicitResultType;
- CleanupInfo LambdaCleanup;
+ bool LambdaExprNeedsCleanups;
bool ContainsUnexpandedParameterPack;
SmallVector<VarDecl *, 4> ArrayIndexVars;
SmallVector<unsigned, 4> ArrayIndexStarts;
@@ -1510,7 +1510,7 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
IntroducerRange = LSI->IntroducerRange;
ExplicitParams = LSI->ExplicitParams;
ExplicitResultType = !LSI->HasImplicitReturnType;
- LambdaCleanup = LSI->Cleanup;
+ LambdaExprNeedsCleanups = LSI->ExprNeedsCleanups;
ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack;
CallOperator->setLexicalDeclContext(Class);
@@ -1591,8 +1591,9 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
CheckCompletedCXXClass(Class);
}
- Cleanup.mergeFrom(LambdaCleanup);
-
+ if (LambdaExprNeedsCleanups)
+ ExprNeedsCleanups = true;
+
LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange,
CaptureDefault, CaptureDefaultLoc,
Captures,
@@ -1713,7 +1714,7 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
// Create the block literal expression.
Expr *BuildBlock = new (Context) BlockExpr(Block, Conv->getConversionType());
ExprCleanupObjects.push_back(Block);
- Cleanup.setExprNeedsCleanups(true);
+ ExprNeedsCleanups = true;
return BuildBlock;
}
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index b8160e0b60e..36ad9e80e37 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -3801,10 +3801,6 @@ bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) {
}
return true;
}
- if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
- if (!ExprTemp->cleanupsHaveSideEffects())
- S = ExprTemp->getSubExpr();
-
InitSrcRange = S->getSourceRange();
if (Expr *E = dyn_cast<Expr>(S))
S = E->IgnoreParens();
@@ -3992,10 +3988,6 @@ bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
return true;
}
- if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
- if (!ExprTemp->cleanupsHaveSideEffects())
- S = ExprTemp->getSubExpr();
-
IncrementSrcRange = S->getSourceRange();
S = S->IgnoreParens();
if (auto UO = dyn_cast<UnaryOperator>(S)) {
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 7156cd2a9ad..d2d4098d177 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -1518,10 +1518,6 @@ namespace {
// variables Increment and DRE.
bool ProcessIterationStmt(Sema &S, Stmt* Statement, bool &Increment,
DeclRefExpr *&DRE) {
- if (auto Cleanups = dyn_cast<ExprWithCleanups>(Statement))
- if (!Cleanups->cleanupsHaveSideEffects())
- Statement = Cleanups->getSubExpr();
-
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(Statement)) {
switch (UO->getOpcode()) {
default: return false;
@@ -2476,10 +2472,6 @@ static void DiagnoseForRangeReferenceVariableCopies(Sema &SemaRef,
QualType VariableType = VD->getType();
- if (auto Cleanups = dyn_cast<ExprWithCleanups>(InitExpr))
- if (!Cleanups->cleanupsHaveSideEffects())
- InitExpr = Cleanups->getSubExpr();
-
const MaterializeTemporaryExpr *MTE =
dyn_cast<MaterializeTemporaryExpr>(InitExpr);
OpenPOWER on IntegriCloud