summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTContext.cpp19
-rw-r--r--clang/lib/AST/ASTImporter.cpp47
-rw-r--r--clang/lib/AST/DeclBase.cpp1
-rw-r--r--clang/lib/AST/DeclCXX.cpp28
-rw-r--r--clang/lib/AST/Expr.cpp34
-rw-r--r--clang/lib/AST/ExprCXX.cpp28
-rw-r--r--clang/lib/AST/ExprConstant.cpp14
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp2
-rw-r--r--clang/lib/AST/StmtPrinter.cpp2
9 files changed, 116 insertions, 59 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 6a15f99eb7d..abfa33d0df0 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -877,10 +877,6 @@ ASTContext::~ASTContext() {
A != AEnd; ++A)
A->second->~AttrVec();
- for (std::pair<const MaterializeTemporaryExpr *, APValue *> &MTVPair :
- MaterializedTemporaryValues)
- MTVPair.second->~APValue();
-
for (const auto &Value : ModuleInitializers)
Value.second->~PerModuleInitializers();
@@ -10326,21 +10322,6 @@ unsigned ASTContext::getParameterIndex(const ParmVarDecl *D) const {
return I->second;
}
-APValue *
-ASTContext::getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,
- bool MayCreate) {
- assert(E && E->getStorageDuration() == SD_Static &&
- "don't need to cache the computed value for this temporary");
- if (MayCreate) {
- APValue *&MTVI = MaterializedTemporaryValues[E];
- if (!MTVI)
- MTVI = new (*this) APValue;
- return MTVI;
- }
-
- return MaterializedTemporaryValues.lookup(E);
-}
-
QualType ASTContext::getStringLiteralArrayType(QualType EltTy,
unsigned Length) const {
// A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 7034f411d73..7614da11a2f 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -485,6 +485,8 @@ namespace clang {
ExpectedDecl VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
ExpectedDecl VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
ExpectedDecl VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D);
+ ExpectedDecl
+ VisitLifetimeExtendedTemporaryDecl(LifetimeExtendedTemporaryDecl *D);
Expected<ObjCTypeParamList *>
ImportObjCTypeParamList(ObjCTypeParamList *list);
@@ -7007,23 +7009,52 @@ ASTNodeImporter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
E->requiresZeroInitialization());
}
+ExpectedDecl ASTNodeImporter::VisitLifetimeExtendedTemporaryDecl(
+ LifetimeExtendedTemporaryDecl *D) {
+ DeclContext *DC, *LexicalDC;
+ if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+ return std::move(Err);
+
+ auto Imp = importSeq(D->getTemporaryExpr(), D->getExtendingDecl());
+ // FIXME: the APValue should be imported as well if present.
+ if (!Imp)
+ return Imp.takeError();
+
+ Expr *Temporary;
+ ValueDecl *ExtendingDecl;
+ std::tie(Temporary, ExtendingDecl) = *Imp;
+ // FIXME: Should ManglingNumber get numbers associated with 'to' context?
+
+ LifetimeExtendedTemporaryDecl *To;
+ if (GetImportedOrCreateDecl(To, D, Temporary, ExtendingDecl,
+ D->getManglingNumber()))
+ return To;
+
+ To->setLexicalDeclContext(LexicalDC);
+ LexicalDC->addDeclInternal(To);
+ return To;
+}
+
ExpectedStmt
ASTNodeImporter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
- auto Imp = importSeq(
- E->getType(), E->GetTemporaryExpr(), E->getExtendingDecl());
+ auto Imp = importSeq(E->getType(),
+ E->getLifetimeExtendedTemporaryDecl() ? nullptr
+ : E->getSubExpr(),
+ E->getLifetimeExtendedTemporaryDecl());
if (!Imp)
return Imp.takeError();
QualType ToType;
Expr *ToTemporaryExpr;
- const ValueDecl *ToExtendingDecl;
- std::tie(ToType, ToTemporaryExpr, ToExtendingDecl) = *Imp;
+ LifetimeExtendedTemporaryDecl *ToMaterializedDecl;
+ std::tie(ToType, ToTemporaryExpr, ToMaterializedDecl) = *Imp;
+ if (!ToTemporaryExpr)
+ ToTemporaryExpr = cast<Expr>(ToMaterializedDecl->getTemporaryExpr());
- auto *ToMTE = new (Importer.getToContext()) MaterializeTemporaryExpr(
- ToType, ToTemporaryExpr, E->isBoundToLvalueReference());
+ auto *ToMTE = new (Importer.getToContext()) MaterializeTemporaryExpr(
+ ToType, ToTemporaryExpr, E->isBoundToLvalueReference(),
+ ToMaterializedDecl);
- // FIXME: Should ManglingNumber get numbers associated with 'to' context?
- ToMTE->setExtendingDecl(ToExtendingDecl, E->getManglingNumber());
return ToMTE;
}
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 77a3a4c679a..6ee767ccecf 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -803,6 +803,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case OMPRequires:
case OMPCapturedExpr:
case Empty:
+ case LifetimeExtendedTemporary:
// Never looked up by name.
return 0;
}
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 58b50de944e..bca560c40ae 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -2796,6 +2796,34 @@ NamespaceAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
SourceLocation(), nullptr);
}
+void LifetimeExtendedTemporaryDecl::anchor() {}
+
+/// Retrieve the storage duration for the materialized temporary.
+StorageDuration LifetimeExtendedTemporaryDecl::getStorageDuration() const {
+ const ValueDecl *ExtendingDecl = getExtendingDecl();
+ if (!ExtendingDecl)
+ return SD_FullExpression;
+ // FIXME: This is not necessarily correct for a temporary materialized
+ // within a default initializer.
+ if (isa<FieldDecl>(ExtendingDecl))
+ return SD_Automatic;
+ // FIXME: This only works because storage class specifiers are not allowed
+ // on decomposition declarations.
+ if (isa<BindingDecl>(ExtendingDecl))
+ return ExtendingDecl->getDeclContext()->isFunctionOrMethod() ? SD_Automatic
+ : SD_Static;
+ return cast<VarDecl>(ExtendingDecl)->getStorageDuration();
+}
+
+APValue *LifetimeExtendedTemporaryDecl::getOrCreateValue(bool MayCreate) const {
+ assert(getStorageDuration() == SD_Static &&
+ "don't need to cache the computed value for this temporary");
+ if (MayCreate && !Value)
+ Value = (new (getASTContext()) APValue);
+ assert(Value && "may not be null");
+ return Value;
+}
+
void UsingShadowDecl::anchor() {}
UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, DeclContext *DC,
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 4fd5fed5bee..d5c35e53059 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -49,7 +49,7 @@ const Expr *Expr::getBestDynamicClassTypeExpr() const {
// Step into initializer for materialized temporaries.
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) {
- E = MTE->GetTemporaryExpr();
+ E = MTE->getSubExpr();
continue;
}
@@ -1897,7 +1897,7 @@ namespace {
const Expr *skipImplicitTemporary(const Expr *E) {
// Skip through reference binding to temporary.
if (auto *Materialize = dyn_cast<MaterializeTemporaryExpr>(E))
- E = Materialize->GetTemporaryExpr();
+ E = Materialize->getSubExpr();
// Skip any temporary bindings; they're implicit.
if (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
@@ -2727,8 +2727,9 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
case CXXDeleteExprClass:
return false;
case MaterializeTemporaryExprClass:
- return cast<MaterializeTemporaryExpr>(this)->GetTemporaryExpr()
- ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
+ return cast<MaterializeTemporaryExpr>(this)
+ ->getSubExpr()
+ ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
case CXXBindTemporaryExprClass:
return cast<CXXBindTemporaryExpr>(this)->getSubExpr()
->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
@@ -2752,8 +2753,8 @@ bool Expr::isOBJCGCCandidate(ASTContext &Ctx) const {
case ImplicitCastExprClass:
return cast<ImplicitCastExpr>(E)->getSubExpr()->isOBJCGCCandidate(Ctx);
case MaterializeTemporaryExprClass:
- return cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr()
- ->isOBJCGCCandidate(Ctx);
+ return cast<MaterializeTemporaryExpr>(E)->getSubExpr()->isOBJCGCCandidate(
+ Ctx);
case CStyleCastExprClass:
return cast<CStyleCastExpr>(E)->getSubExpr()->isOBJCGCCandidate(Ctx);
case DeclRefExprClass: {
@@ -2828,7 +2829,7 @@ static Expr *IgnoreImpCastsExtraSingleStep(Expr *E) {
return SubE;
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
- return MTE->GetTemporaryExpr();
+ return MTE->getSubExpr();
if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
return NTTP->getReplacement();
@@ -2844,7 +2845,7 @@ static Expr *IgnoreCastsSingleStep(Expr *E) {
return FE->getSubExpr();
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
- return MTE->GetTemporaryExpr();
+ return MTE->getSubExpr();
if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
return NTTP->getReplacement();
@@ -2878,7 +2879,7 @@ static Expr *IgnoreImplicitSingleStep(Expr *E) {
return SubE;
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
- return MTE->GetTemporaryExpr();
+ return MTE->getSubExpr();
if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
return BTE->getSubExpr();
@@ -3005,7 +3006,7 @@ Expr *Expr::IgnoreParenNoopCasts(const ASTContext &Ctx) {
bool Expr::isDefaultArgument() const {
const Expr *E = this;
if (const MaterializeTemporaryExpr *M = dyn_cast<MaterializeTemporaryExpr>(E))
- E = M->GetTemporaryExpr();
+ E = M->getSubExpr();
while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
E = ICE->getSubExprAsWritten();
@@ -3017,7 +3018,7 @@ bool Expr::isDefaultArgument() const {
/// expressions.
static const Expr *skipTemporaryBindingsNoOpCastsAndParens(const Expr *E) {
if (const MaterializeTemporaryExpr *M = dyn_cast<MaterializeTemporaryExpr>(E))
- E = M->GetTemporaryExpr();
+ E = M->getSubExpr();
while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
if (ICE->getCastKind() == CK_NoOp)
@@ -3112,7 +3113,7 @@ bool Expr::isImplicitCXXThis() const {
if (const MaterializeTemporaryExpr *M
= dyn_cast<MaterializeTemporaryExpr>(E)) {
- E = M->GetTemporaryExpr();
+ E = M->getSubExpr();
continue;
}
@@ -3289,8 +3290,9 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
break;
}
case MaterializeTemporaryExprClass:
- return cast<MaterializeTemporaryExpr>(this)->GetTemporaryExpr()
- ->isConstantInitializer(Ctx, false, Culprit);
+ return cast<MaterializeTemporaryExpr>(this)
+ ->getSubExpr()
+ ->isConstantInitializer(Ctx, false, Culprit);
case SubstNonTypeTemplateParmExprClass:
return cast<SubstNonTypeTemplateParmExpr>(this)->getReplacement()
@@ -3757,7 +3759,7 @@ Expr::isNullPointerConstant(ASTContext &Ctx,
return NPCK_GNUNull;
} else if (const MaterializeTemporaryExpr *M
= dyn_cast<MaterializeTemporaryExpr>(this)) {
- return M->GetTemporaryExpr()->isNullPointerConstant(Ctx, NPC);
+ return M->getSubExpr()->isNullPointerConstant(Ctx, NPC);
} else if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(this)) {
if (const Expr *Source = OVE->getSourceExpr())
return Source->isNullPointerConstant(Ctx, NPC);
@@ -4466,7 +4468,7 @@ const OpaqueValueExpr *OpaqueValueExpr::findInCopyConstruct(const Expr *e) {
if (const ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(e))
e = ewc->getSubExpr();
if (const MaterializeTemporaryExpr *m = dyn_cast<MaterializeTemporaryExpr>(e))
- e = m->GetTemporaryExpr();
+ e = m->getSubExpr();
e = cast<CXXConstructExpr>(e)->getArg(0);
while (const ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
e = ice->getSubExpr();
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 904928bdf28..0fb132dbe3f 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1653,7 +1653,23 @@ FunctionParmPackExpr::CreateEmpty(const ASTContext &Context,
FunctionParmPackExpr(QualType(), nullptr, SourceLocation(), 0, nullptr);
}
-void MaterializeTemporaryExpr::setExtendingDecl(const ValueDecl *ExtendedBy,
+MaterializeTemporaryExpr::MaterializeTemporaryExpr(
+ QualType T, Expr *Temporary, bool BoundToLvalueReference,
+ LifetimeExtendedTemporaryDecl *MTD)
+ : Expr(MaterializeTemporaryExprClass, T,
+ BoundToLvalueReference ? VK_LValue : VK_XValue, OK_Ordinary,
+ Temporary->isTypeDependent(), Temporary->isValueDependent(),
+ Temporary->isInstantiationDependent(),
+ Temporary->containsUnexpandedParameterPack()) {
+ if (MTD) {
+ State = MTD;
+ MTD->ExprWithTemporary = Temporary;
+ return;
+ }
+ State = Temporary;
+}
+
+void MaterializeTemporaryExpr::setExtendingDecl(ValueDecl *ExtendedBy,
unsigned ManglingNumber) {
// We only need extra state if we have to remember more than just the Stmt.
if (!ExtendedBy)
@@ -1661,13 +1677,11 @@ void MaterializeTemporaryExpr::setExtendingDecl(const ValueDecl *ExtendedBy,
// We may need to allocate extra storage for the mangling number and the
// extended-by ValueDecl.
- if (!State.is<ExtraState *>()) {
- auto *ES = new (ExtendedBy->getASTContext()) ExtraState;
- ES->Temporary = State.get<Stmt *>();
- State = ES;
- }
+ if (!State.is<LifetimeExtendedTemporaryDecl *>())
+ State = LifetimeExtendedTemporaryDecl::Create(
+ cast<Expr>(State.get<Stmt *>()), ExtendedBy, ManglingNumber);
- auto ES = State.get<ExtraState *>();
+ auto ES = State.get<LifetimeExtendedTemporaryDecl *>();
ES->ExtendingDecl = ExtendedBy;
ES->ManglingNumber = ManglingNumber;
}
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index f4ca2284224..79659261388 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -107,7 +107,7 @@ namespace {
dyn_cast<MaterializeTemporaryExpr>(Base)) {
SmallVector<const Expr *, 2> CommaLHSs;
SmallVector<SubobjectAdjustment, 2> Adjustments;
- const Expr *Temp = MTE->GetTemporaryExpr();
+ const Expr *Temp = MTE->getSubExpr();
const Expr *Inner = Temp->skipRValueSubobjectAdjustments(CommaLHSs,
Adjustments);
// Keep any cv-qualifiers from the reference if we generated a temporary
@@ -2075,7 +2075,7 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc,
return false;
}
- APValue *V = Info.Ctx.getMaterializedTemporaryValue(MTE, false);
+ APValue *V = MTE->getOrCreateValue(false);
assert(V && "evasluation result refers to uninitialised temporary");
if (!CheckEvaluationResult(CheckEvaluationResultKind::ConstantExpression,
Info, MTE->getExprLoc(), TempType, *V,
@@ -3679,7 +3679,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
return CompleteObject();
}
- BaseVal = Info.Ctx.getMaterializedTemporaryValue(MTE, false);
+ BaseVal = MTE->getOrCreateValue(false);
assert(BaseVal && "got reference to unevaluated temporary");
} else {
if (!IsAccess)
@@ -7470,8 +7470,8 @@ bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
// Walk through the expression to find the materialized temporary itself.
SmallVector<const Expr *, 2> CommaLHSs;
SmallVector<SubobjectAdjustment, 2> Adjustments;
- const Expr *Inner = E->GetTemporaryExpr()->
- skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
+ const Expr *Inner =
+ E->getSubExpr()->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
// If we passed any comma operators, evaluate their LHSs.
for (unsigned I = 0, N = CommaLHSs.size(); I != N; ++I)
@@ -7483,7 +7483,7 @@ bool LValueExprEvaluator::VisitMaterializeTemporaryExpr(
// value for use outside this evaluation.
APValue *Value;
if (E->getStorageDuration() == SD_Static) {
- Value = Info.Ctx.getMaterializedTemporaryValue(E, true);
+ Value = E->getOrCreateValue(true);
*Value = APValue();
Result.set(E);
} else {
@@ -9031,7 +9031,7 @@ bool RecordExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E,
if (E->isElidable() && !ZeroInit)
if (const MaterializeTemporaryExpr *ME
= dyn_cast<MaterializeTemporaryExpr>(E->getArg(0)))
- return Visit(ME->GetTemporaryExpr());
+ return Visit(ME->getSubExpr());
if (ZeroInit && !ZeroInitialization(E, T))
return false;
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index c55a9013757..8c87c55c792 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4338,7 +4338,7 @@ recurse:
}
case Expr::MaterializeTemporaryExprClass: {
- mangleExpression(cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr());
+ mangleExpression(cast<MaterializeTemporaryExpr>(E)->getSubExpr());
break;
}
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 1602ef56760..1ef847a55b1 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -2235,7 +2235,7 @@ void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
}
void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
- PrintExpr(Node->GetTemporaryExpr());
+ PrintExpr(Node->getSubExpr());
}
void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
OpenPOWER on IntegriCloud