Tyker created this revision.
Tyker added a reviewer: rsmith.
Herald added a reviewer: martong.
Herald added subscribers: cfe-commits, arphaman.
Herald added a reviewer: shafik.
Herald added a project: clang.

this patch refactor representation of materialized temporaries to prevent an 
issue raised by rsmith in https://reviews.llvm.org/D63640#inline-612718


Repository:
  rC Clang

https://reviews.llvm.org/D69360

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/DeclNodes.td
  clang/include/clang/Sema/Template.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/DeclBase.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Serialization/ASTCommon.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterDecl.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/tools/libclang/CIndex.cpp

Index: clang/tools/libclang/CIndex.cpp
===================================================================
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -6299,6 +6299,7 @@
   case Decl::PragmaDetectMismatch:
   case Decl::UsingPack:
   case Decl::Concept:
+  case Decl::MaterializeTemporary:
     return C;
 
   // Declaration kinds that don't make any sense here, but are
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===================================================================
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1835,9 +1835,11 @@
 
 void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
   VisitExpr(E);
-  Record.AddStmt(E->getTemporary());
-  Record.AddDeclRef(E->getExtendingDecl());
-  Record.push_back(E->getManglingNumber());
+  Record.push_back(static_cast<bool>(E->getMaterializeTemporaryDecl()));
+  if (E->getMaterializeTemporaryDecl())
+    Record.AddDeclRef(E->getMaterializeTemporaryDecl());
+  else
+    Record.AddStmt(E->getTemporary());
   Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
 }
 
Index: clang/lib/Serialization/ASTWriterDecl.cpp
===================================================================
--- clang/lib/Serialization/ASTWriterDecl.cpp
+++ clang/lib/Serialization/ASTWriterDecl.cpp
@@ -124,6 +124,7 @@
     void VisitBlockDecl(BlockDecl *D);
     void VisitCapturedDecl(CapturedDecl *D);
     void VisitEmptyDecl(EmptyDecl *D);
+    void VisitMaterializeTemporaryDecl(MaterializeTemporaryDecl* D);
 
     void VisitDeclContext(DeclContext *DC);
     template <typename T> void VisitRedeclarable(Redeclarable<T> *D);
@@ -1131,6 +1132,17 @@
   Code = serialization::DECL_EMPTY;
 }
 
+void ASTDeclWriter::VisitMaterializeTemporaryDecl(MaterializeTemporaryDecl *D) {
+  VisitDecl(D);
+  Record.AddDeclRef(D->getExtendingDecl());
+  Record.AddStmt(D->getStmtWithTemporary());
+  Record.push_back(static_cast<bool>(D->getValue()));
+  if (D->getValue())
+    Record.AddAPValue(*D->getValue());
+  Record.push_back(D->getManglingNumber());
+  Code = serialization::DECL_MATERIALIZE_TEMPORARY;
+}
+
 void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
   VisitDecl(D);
   Record.AddStmt(D->getBody());
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===================================================================
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1900,10 +1900,11 @@
 
 void ASTStmtReader::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
   VisitExpr(E);
-  E->State = Record.readSubExpr();
-  auto *VD = ReadDeclAs<ValueDecl>();
-  unsigned ManglingNumber = Record.readInt();
-  E->setExtendingDecl(VD, ManglingNumber);
+  bool HasMaterialzedDecl = Record.readInt();
+  if (HasMaterialzedDecl)
+    E->State = ReadDeclAs<MaterializeTemporaryDecl>();
+  else
+    E->State = Record.readSubExpr();
 }
 
 void ASTStmtReader::VisitCXXFoldExpr(CXXFoldExpr *E) {
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -405,6 +405,7 @@
     void VisitBlockDecl(BlockDecl *BD);
     void VisitCapturedDecl(CapturedDecl *CD);
     void VisitEmptyDecl(EmptyDecl *D);
+    void VisitMaterializeTemporaryDecl(MaterializeTemporaryDecl* D);
 
     std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
 
@@ -2346,6 +2347,15 @@
   VisitDecl(D);
 }
 
+void ASTDeclReader::VisitMaterializeTemporaryDecl(MaterializeTemporaryDecl* D) {
+  VisitDecl(D);
+  D->ExtendingDecl = ReadDeclAs<ValueDecl>();
+  D->StmtWithTemporary = Record.readStmt();
+  if (Record.readInt())
+    D->Value = new (D->getASTContext()) APValue(Record.readAPValue());
+  D->ManglingNumber = Record.readInt();
+}
+
 std::pair<uint64_t, uint64_t>
 ASTDeclReader::VisitDeclContext(DeclContext *DC) {
   uint64_t LexicalOffset = ReadLocalOffset();
@@ -3836,6 +3846,9 @@
   case DECL_BLOCK:
     D = BlockDecl::CreateDeserialized(Context, ID);
     break;
+  case DECL_MATERIALIZE_TEMPORARY:
+    D = MaterializeTemporaryDecl::CreateDeserialized(Context, ID);
+    break;
   case DECL_MS_PROPERTY:
     D = MSPropertyDecl::CreateDeserialized(Context, ID);
     break;
Index: clang/lib/Serialization/ASTCommon.cpp
===================================================================
--- clang/lib/Serialization/ASTCommon.cpp
+++ clang/lib/Serialization/ASTCommon.cpp
@@ -401,6 +401,7 @@
   case Decl::Decomposition:
   case Decl::Binding:
   case Decl::Concept:
+  case Decl::MaterializeTemporary:
     return false;
 
   // These indirectly derive from Redeclarable<T> but are not actually
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -5022,7 +5022,7 @@
     // temporary. Note that this might have a different value from the value
     // computed by evaluating the initializer if the surrounding constant
     // expression modifies the temporary.
-    Value = getContext().getMaterializedTemporaryValue(E, false);
+    Value = E->getOrCreateValue(getContext(), false);
   }
 
   // Try evaluating it now, it might have a constant initializer.
Index: clang/lib/CodeGen/CGDecl.cpp
===================================================================
--- clang/lib/CodeGen/CGDecl.cpp
+++ clang/lib/CodeGen/CGDecl.cpp
@@ -109,6 +109,7 @@
   case Decl::OMPRequires:
   case Decl::Empty:
   case Decl::Concept:
+  case Decl::MaterializeTemporary:
     // None of these decls require codegen support.
     return;
 
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -2072,7 +2072,7 @@
         return false;
       }
 
-      APValue *V = Info.Ctx.getMaterializedTemporaryValue(MTE, false);
+      APValue *V = MTE->getOrCreateValue(Info.Ctx, false);
       assert(V && "evasluation result refers to uninitialised temporary");
       if (!CheckEvaluationResult(CheckEvaluationResultKind::ConstantExpression,
                                  Info, MTE->getExprLoc(), TempType, *V,
@@ -3676,7 +3676,7 @@
           return CompleteObject();
         }
 
-        BaseVal = Info.Ctx.getMaterializedTemporaryValue(MTE, false);
+        BaseVal = MTE->getOrCreateValue(Info.Ctx, false);
         assert(BaseVal && "got reference to unevaluated temporary");
       } else {
         if (!IsAccess)
@@ -7473,7 +7473,7 @@
   // value for use outside this evaluation.
   APValue *Value;
   if (E->getStorageDuration() == SD_Static) {
-    Value = Info.Ctx.getMaterializedTemporaryValue(E, true);
+    Value = E->getOrCreateValue(Info.Ctx, true);
     *Value = APValue();
     Result.set(E);
   } else {
Index: clang/lib/AST/ExprCXX.cpp
===================================================================
--- clang/lib/AST/ExprCXX.cpp
+++ clang/lib/AST/ExprCXX.cpp
@@ -1653,7 +1653,35 @@
       FunctionParmPackExpr(QualType(), nullptr, SourceLocation(), 0, nullptr);
 }
 
-void MaterializeTemporaryExpr::setExtendingDecl(const ValueDecl *ExtendedBy,
+MaterializeTemporaryExpr::MaterializeTemporaryExpr(
+    QualType T, Expr *Temporary, bool BoundToLvalueReference,
+    MaterializeTemporaryDecl *MTD)
+    : Expr(MaterializeTemporaryExprClass, T,
+           BoundToLvalueReference ? VK_LValue : VK_XValue, OK_Ordinary,
+           Temporary->isTypeDependent(), Temporary->isValueDependent(),
+           Temporary->isInstantiationDependent(),
+           Temporary->containsUnexpandedParameterPack()) {
+  if (MTD) {
+    State = MTD;
+    MTD->StmtWithTemporary = Temporary;
+    return;
+  }
+  State = Temporary;
+}
+
+APValue *MaterializeTemporaryExpr::getOrCreateValue(ASTContext &Ctx,
+                                                    bool MayCreate) const {
+  assert(getStorageDuration() == SD_Static &&
+         "don't need to cache the computed value for this temporary");
+  const MaterializeTemporaryDecl* D = getMaterializeTemporaryDecl();
+  assert(D && "must not be null");
+  if (MayCreate && !D->getValue())
+    D->Value = new (Ctx) APValue;
+  assert(D->getValue() && "may not be null");
+  return D->getValue();
+}
+
+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 +1689,11 @@
 
   // 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<MaterializeTemporaryDecl *>())
+    State = MaterializeTemporaryDecl::Create(State.get<Stmt *>(), ExtendedBy,
+                                             ManglingNumber);
 
-  auto ES = State.get<ExtraState *>();
+  auto ES = State.get<MaterializeTemporaryDecl *>();
   ES->ExtendingDecl = ExtendedBy;
   ES->ManglingNumber = ManglingNumber;
 }
Index: clang/lib/AST/DeclCXX.cpp
===================================================================
--- clang/lib/AST/DeclCXX.cpp
+++ clang/lib/AST/DeclCXX.cpp
@@ -2796,6 +2796,8 @@
                                         SourceLocation(), nullptr);
 }
 
+void MaterializeTemporaryDecl::anchor() {}
+
 void UsingShadowDecl::anchor() {}
 
 UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, DeclContext *DC,
Index: clang/lib/AST/DeclBase.cpp
===================================================================
--- clang/lib/AST/DeclBase.cpp
+++ clang/lib/AST/DeclBase.cpp
@@ -803,6 +803,7 @@
     case OMPRequires:
     case OMPCapturedExpr:
     case Empty:
+    case MaterializeTemporary:
       // Never looked up by name.
       return 0;
   }
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -483,6 +483,7 @@
     ExpectedDecl VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
     ExpectedDecl VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
     ExpectedDecl VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
+    ExpectedDecl VisitMaterializeTemporaryDecl(MaterializeTemporaryDecl *D);
 
     Expected<ObjCTypeParamList *>
     ImportObjCTypeParamList(ObjCTypeParamList *list);
@@ -6989,23 +6990,42 @@
       E->requiresZeroInitialization());
 }
 
+ExpectedDecl
+ASTNodeImporter::VisitMaterializeTemporaryDecl(MaterializeTemporaryDecl *D) {
+  auto Imp = importSeq(D->getStmtWithTemporary(), D->getExtendingDecl());
+  // FIXME: the APValue should be imported as well if present.
+  if (!Imp)
+    return Imp.takeError();
+
+  Stmt *Temporary;
+  ValueDecl *ExtendingDecl;
+  std::tie(Temporary, ExtendingDecl) = *Imp;
+  // FIXME: Should ManglingNumber get numbers associated with 'to' context?
+  auto* To = MaterializeTemporaryDecl::Create(Temporary, ExtendingDecl,
+                                          D->getManglingNumber());
+  Importer.MapImported(D, To);
+  return To;
+}
+
 ExpectedStmt
 ASTNodeImporter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
-  auto Imp = importSeq(
-      E->getType(), E->GetTemporaryExpr(), E->getExtendingDecl());
+  auto Imp =
+      importSeq(E->getType(),
+                E->getMaterializeTemporaryDecl() ? nullptr : E->GetTemporaryExpr(),
+                E->getMaterializeTemporaryDecl());
   if (!Imp)
     return Imp.takeError();
 
   QualType ToType;
   Expr *ToTemporaryExpr;
-  const ValueDecl *ToExtendingDecl;
-  std::tie(ToType, ToTemporaryExpr, ToExtendingDecl) = *Imp;
+  MaterializeTemporaryDecl *MaterialzedDecl;
+  std::tie(ToType, ToTemporaryExpr, MaterialzedDecl) = *Imp;
+  if (!ToTemporaryExpr)
+    ToTemporaryExpr = cast<Expr>(MaterialzedDecl->getStmtWithTemporary());
 
-  auto *ToMTE =  new (Importer.getToContext()) MaterializeTemporaryExpr(
-      ToType, ToTemporaryExpr, E->isBoundToLvalueReference());
+  auto *ToMTE = new (Importer.getToContext()) MaterializeTemporaryExpr(
+      ToType, ToTemporaryExpr, E->isBoundToLvalueReference(), MaterialzedDecl);
 
-  // FIXME: Should ManglingNumber get numbers associated with 'to' context?
-  ToMTE->setExtendingDecl(ToExtendingDecl, E->getManglingNumber());
   return ToMTE;
 }
 
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -875,10 +875,6 @@
        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();
 
@@ -10324,21 +10320,6 @@
   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).
Index: clang/include/clang/Serialization/ASTBitCodes.h
===================================================================
--- clang/include/clang/Serialization/ASTBitCodes.h
+++ clang/include/clang/Serialization/ASTBitCodes.h
@@ -1537,6 +1537,9 @@
       /// An EmptyDecl record.
       DECL_EMPTY,
 
+      /// An MaterializeTemporaryDecl record.
+      DECL_MATERIALIZE_TEMPORARY,
+
       /// An ObjCTypeParamDecl record.
       DECL_OBJC_TYPE_PARAM,
 
Index: clang/include/clang/Sema/Template.h
===================================================================
--- clang/include/clang/Sema/Template.h
+++ clang/include/clang/Sema/Template.h
@@ -464,6 +464,7 @@
 #define OBJCPROPERTY(DERIVED, BASE)
 #define OBJCPROPERTYIMPL(DERIVED, BASE)
 #define EMPTY(DERIVED, BASE)
+#define MATERIALIZETEMPORARY(DERIVED, BASE)
 
 // Decls which use special-case instantiation code.
 #define BLOCK(DERIVED, BASE)
Index: clang/include/clang/Basic/DeclNodes.td
===================================================================
--- clang/include/clang/Basic/DeclNodes.td
+++ clang/include/clang/Basic/DeclNodes.td
@@ -102,4 +102,5 @@
 def OMPAllocate : Decl;
 def OMPRequires : Decl;
 def Empty : Decl;
+def MaterializeTemporary : Decl;
 
Index: clang/include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- clang/include/clang/AST/RecursiveASTVisitor.h
+++ clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2121,6 +2121,11 @@
     TRY_TO(TraverseStmt(D->getDefaultArg()));
 })
 
+DEF_TRAVERSE_DECL(MaterializeTemporaryDecl, {
+  TRY_TO(TraverseDecl(D->getExtendingDecl()));
+  TRY_TO(TraverseStmt(D->getStmtWithTemporary()));
+})
+
 #undef DEF_TRAVERSE_DECL
 
 // ----------------- Stmt traversal -----------------
Index: clang/include/clang/AST/ExprCXX.h
===================================================================
--- clang/include/clang/AST/ExprCXX.h
+++ clang/include/clang/AST/ExprCXX.h
@@ -4421,35 +4421,20 @@
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
 
-  struct ExtraState {
-    /// The temporary-generating expression whose value will be
-    /// materialized.
-    Stmt *Temporary;
-
-    /// The declaration which lifetime-extended this reference, if any.
-    /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
-    const ValueDecl *ExtendingDecl;
-
-    unsigned ManglingNumber;
-  };
-  llvm::PointerUnion<Stmt *, ExtraState *> State;
+  llvm::PointerUnion<Stmt *, MaterializeTemporaryDecl *> State;
 
 public:
   MaterializeTemporaryExpr(QualType T, Expr *Temporary,
-                           bool BoundToLvalueReference)
-      : Expr(MaterializeTemporaryExprClass, T,
-             BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
-             Temporary->isTypeDependent(), Temporary->isValueDependent(),
-             Temporary->isInstantiationDependent(),
-             Temporary->containsUnexpandedParameterPack()),
-        State(Temporary) {}
+                           bool BoundToLvalueReference,
+                           MaterializeTemporaryDecl *MTD = nullptr);
 
   MaterializeTemporaryExpr(EmptyShell Empty)
       : Expr(MaterializeTemporaryExprClass, Empty) {}
 
   Stmt *getTemporary() const {
     return State.is<Stmt *>() ? State.get<Stmt *>()
-                              : State.get<ExtraState *>()->Temporary;
+                              : State.get<MaterializeTemporaryDecl *>()
+                                    ->getStmtWithTemporary();
   }
 
   /// Retrieve the temporary-generating subexpression whose value will
@@ -4474,17 +4459,34 @@
     return cast<VarDecl>(ExtendingDecl)->getStorageDuration();
   }
 
+  MaterializeTemporaryDecl* getMaterializeTemporaryDecl() {
+    return State.dyn_cast<MaterializeTemporaryDecl*>();
+  }
+  const MaterializeTemporaryDecl* getMaterializeTemporaryDecl() const {
+    return State.dyn_cast<MaterializeTemporaryDecl*>();
+  }
+
+  /// Get the storage for the constant value of a materialized temporary
+  /// of static storage duration.
+  APValue *getOrCreateValue(ASTContext &Ctx, bool MayCreate) const;
+
   /// Get the declaration which triggered the lifetime-extension of this
   /// temporary, if any.
-  const ValueDecl *getExtendingDecl() const {
-    return State.is<Stmt *>() ? nullptr
-                              : State.get<ExtraState *>()->ExtendingDecl;
+  ValueDecl *getExtendingDecl() {
+    return State.is<Stmt *>()
+               ? nullptr
+               : State.get<MaterializeTemporaryDecl *>()->getExtendingDecl();
+  }
+  const ValueDecl* getExtendingDecl() const {
+    return const_cast<MaterializeTemporaryExpr*>(this)->getExtendingDecl();
   }
 
-  void setExtendingDecl(const ValueDecl *ExtendedBy, unsigned ManglingNumber);
+  void setExtendingDecl(ValueDecl *ExtendedBy, unsigned ManglingNumber);
 
   unsigned getManglingNumber() const {
-    return State.is<Stmt *>() ? 0 : State.get<ExtraState *>()->ManglingNumber;
+    return State.is<Stmt *>()
+               ? 0
+               : State.get<MaterializeTemporaryDecl *>()->getManglingNumber();
   }
 
   /// Determine whether this materialized temporary is bound to an
@@ -4510,8 +4512,8 @@
     if (State.is<Stmt *>())
       return child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1);
 
-    auto ES = State.get<ExtraState *>();
-    return child_range(&ES->Temporary, &ES->Temporary + 1);
+    auto ES = State.get<MaterializeTemporaryDecl *>();
+    return child_range(&ES->StmtWithTemporary, &ES->StmtWithTemporary + 1);
   }
 
   const_child_range children() const {
@@ -4519,8 +4521,8 @@
       return const_child_range(State.getAddrOfPtr1(),
                                State.getAddrOfPtr1() + 1);
 
-    auto ES = State.get<ExtraState *>();
-    return const_child_range(&ES->Temporary, &ES->Temporary + 1);
+    auto ES = State.get<MaterializeTemporaryDecl *>();
+    return const_child_range(&ES->StmtWithTemporary, &ES->StmtWithTemporary + 1);
   }
 };
 
Index: clang/include/clang/AST/DeclCXX.h
===================================================================
--- clang/include/clang/AST/DeclCXX.h
+++ clang/include/clang/AST/DeclCXX.h
@@ -3052,6 +3052,73 @@
   static bool classofKind(Kind K) { return K == NamespaceAlias; }
 };
 
+/// Implicit declartion of a temporary that was materialized by
+/// MaterializeTemporaryExpr
+class MaterializeTemporaryDecl final : public Decl {
+  friend class MaterializeTemporaryExpr;
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+
+  /// The temporary-generating expression whose value will be
+  /// materialized.
+  Stmt *StmtWithTemporary;
+
+  /// The declaration which lifetime-extended this reference, if any.
+  /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
+  ValueDecl *ExtendingDecl = nullptr;
+  unsigned ManglingNumber;
+
+  mutable APValue* Value = nullptr;
+
+  virtual void anchor();
+
+  MaterializeTemporaryDecl(Stmt *Temp, ValueDecl *EDecl, unsigned Mangling)
+      : Decl(Decl::MaterializeTemporary, EDecl->getDeclContext(),
+             EDecl->getLocation()),
+        StmtWithTemporary(Temp), ExtendingDecl(EDecl),
+        ManglingNumber(Mangling) {}
+
+  MaterializeTemporaryDecl(EmptyShell)
+      : Decl(Decl::MaterializeTemporary, EmptyShell{}) {}
+
+public:
+  static MaterializeTemporaryDecl *Create(Stmt *Temp, ValueDecl *EDec,
+                                          unsigned Mangling) {
+    return new (EDec->getASTContext(), EDec->getDeclContext())
+        MaterializeTemporaryDecl(Temp, EDec, Mangling);
+  }
+  static MaterializeTemporaryDecl *CreateDeserialized(ASTContext &C,
+                                                      unsigned ID) {
+    return new (C, ID) MaterializeTemporaryDecl(EmptyShell{});
+  }
+
+  ValueDecl* getExtendingDecl() {
+    return ExtendingDecl;
+  }
+  const ValueDecl* getExtendingDecl() const {
+    return ExtendingDecl;
+  }
+  Stmt* getStmtWithTemporary() {
+    return StmtWithTemporary;
+  }
+  const Stmt* getStmtWithTemporary() const {
+    return StmtWithTemporary;
+  }
+  
+  APValue* getValue() const {
+    return Value;
+  }
+
+  unsigned getManglingNumber() const {
+    return ManglingNumber;
+  }
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) {
+    return K == Decl::MaterializeTemporary;
+  }
+};
+
 /// Represents a shadow declaration introduced into a scope by a
 /// (resolved) using declaration.
 ///
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -272,12 +272,6 @@
   /// Mapping from __block VarDecls to BlockVarCopyInit.
   llvm::DenseMap<const VarDecl *, BlockVarCopyInit> BlockVarCopyInits;
 
-  /// Mapping from materialized temporaries with static storage duration
-  /// that appear in constant initializers to their evaluated values.  These are
-  /// allocated in a std::map because their address must be stable.
-  llvm::DenseMap<const MaterializeTemporaryExpr *, APValue *>
-    MaterializedTemporaryValues;
-
   /// Used to cleanups APValues stored in the AST.
   mutable llvm::SmallVector<APValue *, 0> APValueCleanups;
 
@@ -2827,11 +2821,6 @@
   /// index of the parameter when it exceeds the size of the normal bitfield.
   unsigned getParameterIndex(const ParmVarDecl *D) const;
 
-  /// Get the storage for the constant value of a materialized temporary
-  /// of static storage duration.
-  APValue *getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,
-                                         bool MayCreate);
-
   /// Return a string representing the human readable name for the specified
   /// function declaration or file name. Used by SourceLocExpr and
   /// PredefinedExpr to cache evaluated results.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to