r350003 - [AST] Store the arguments of CXXConstructExpr in a trailing array

Bruno Ricci via cfe-commits cfe-commits at lists.llvm.org
Sat Dec 22 06:39:30 PST 2018


Author: brunoricci
Date: Sat Dec 22 06:39:30 2018
New Revision: 350003

URL: http://llvm.org/viewvc/llvm-project?rev=350003&view=rev
Log:
[AST] Store the arguments of CXXConstructExpr in a trailing array

Store the arguments of CXXConstructExpr in a trailing array. This is very
similar to the CallExpr case in D55771, with the exception that there is
only one derived class (CXXTemporaryObjectExpr) and that we compute the
offset to the trailing array instead of storing it.

This saves one pointer per CXXConstructExpr and CXXTemporaryObjectExpr.

Reviewed By: rjmccall

Differential Revision: https://reviews.llvm.org/D56022


Modified:
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/include/clang/AST/Stmt.h
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/ExprCXX.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
    cfe/trunk/lib/Serialization/ASTWriterStmt.cpp

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=350003&r1=350002&r2=350003&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Sat Dec 22 06:39:30 2018
@@ -1280,6 +1280,8 @@ public:
 
 /// Represents a call to a C++ constructor.
 class CXXConstructExpr : public Expr {
+  friend class ASTStmtReader;
+
 public:
   enum ConstructionKind {
     CK_Complete,
@@ -1289,98 +1291,119 @@ public:
   };
 
 private:
-  CXXConstructorDecl *Constructor = nullptr;
-  SourceLocation Loc;
+  /// A pointer to the constructor which will be ultimately called.
+  CXXConstructorDecl *Constructor;
+
   SourceRange ParenOrBraceRange;
-  unsigned NumArgs : 16;
-  unsigned Elidable : 1;
-  unsigned HadMultipleCandidates : 1;
-  unsigned ListInitialization : 1;
-  unsigned StdInitListInitialization : 1;
-  unsigned ZeroInitialization : 1;
-  unsigned ConstructKind : 2;
-  Stmt **Args = nullptr;
 
-  void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
+  /// The number of arguments.
+  unsigned NumArgs;
+
+  // We would like to stash the arguments of the constructor call after
+  // CXXConstructExpr. However CXXConstructExpr is used as a base class of
+  // CXXTemporaryObjectExpr which makes the use of llvm::TrailingObjects
+  // impossible.
+  //
+  // Instead we manually stash the trailing object after the full object
+  // containing CXXConstructExpr (that is either CXXConstructExpr or
+  // CXXTemporaryObjectExpr).
+  //
+  // The trailing objects are:
+  //
+  // * An array of getNumArgs() "Stmt *" for the arguments of the
+  //   constructor call.
+
+  /// Return a pointer to the start of the trailing arguments.
+  /// Defined just after CXXTemporaryObjectExpr.
+  inline Stmt **getTrailingArgs();
+  const Stmt *const *getTrailingArgs() const {
+    return const_cast<CXXConstructExpr *>(this)->getTrailingArgs();
+  }
 
 protected:
-  CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T,
-                   SourceLocation Loc,
-                   CXXConstructorDecl *Ctor,
-                   bool Elidable,
-                   ArrayRef<Expr *> Args,
-                   bool HadMultipleCandidates,
-                   bool ListInitialization,
-                   bool StdInitListInitialization,
-                   bool ZeroInitialization,
-                   ConstructionKind ConstructKind,
+  /// Build a C++ construction expression.
+  CXXConstructExpr(StmtClass SC, QualType Ty, SourceLocation Loc,
+                   CXXConstructorDecl *Ctor, bool Elidable,
+                   ArrayRef<Expr *> Args, bool HadMultipleCandidates,
+                   bool ListInitialization, bool StdInitListInitialization,
+                   bool ZeroInitialization, ConstructionKind ConstructKind,
                    SourceRange ParenOrBraceRange);
 
-  /// Construct an empty C++ construction expression.
-  CXXConstructExpr(StmtClass SC, EmptyShell Empty)
-      : Expr(SC, Empty), NumArgs(0), Elidable(false),
-        HadMultipleCandidates(false), ListInitialization(false),
-        ZeroInitialization(false), ConstructKind(0) {}
+  /// Build an empty C++ construction expression.
+  CXXConstructExpr(StmtClass SC, EmptyShell Empty, unsigned NumArgs);
+
+  /// Return the size in bytes of the trailing objects. Used by
+  /// CXXTemporaryObjectExpr to allocate the right amount of storage.
+  static unsigned sizeOfTrailingObjects(unsigned NumArgs) {
+    return NumArgs * sizeof(Stmt *);
+  }
 
 public:
-  friend class ASTStmtReader;
+  /// Create a C++ construction expression.
+  static CXXConstructExpr *
+  Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc,
+         CXXConstructorDecl *Ctor, bool Elidable, ArrayRef<Expr *> Args,
+         bool HadMultipleCandidates, bool ListInitialization,
+         bool StdInitListInitialization, bool ZeroInitialization,
+         ConstructionKind ConstructKind, SourceRange ParenOrBraceRange);
 
-  /// Construct an empty C++ construction expression.
-  explicit CXXConstructExpr(EmptyShell Empty)
-      : CXXConstructExpr(CXXConstructExprClass, Empty) {}
-
-  static CXXConstructExpr *Create(const ASTContext &C, QualType T,
-                                  SourceLocation Loc,
-                                  CXXConstructorDecl *Ctor,
-                                  bool Elidable,
-                                  ArrayRef<Expr *> Args,
-                                  bool HadMultipleCandidates,
-                                  bool ListInitialization,
-                                  bool StdInitListInitialization,
-                                  bool ZeroInitialization,
-                                  ConstructionKind ConstructKind,
-                                  SourceRange ParenOrBraceRange);
+  /// Create an empty C++ construction expression.
+  static CXXConstructExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs);
 
   /// Get the constructor that this expression will (ultimately) call.
   CXXConstructorDecl *getConstructor() const { return Constructor; }
 
-  SourceLocation getLocation() const { return Loc; }
-  void setLocation(SourceLocation Loc) { this->Loc = Loc; }
+  SourceLocation getLocation() const { return CXXConstructExprBits.Loc; }
+  void setLocation(SourceLocation Loc) { CXXConstructExprBits.Loc = Loc; }
 
   /// Whether this construction is elidable.
-  bool isElidable() const { return Elidable; }
-  void setElidable(bool E) { Elidable = E; }
+  bool isElidable() const { return CXXConstructExprBits.Elidable; }
+  void setElidable(bool E) { CXXConstructExprBits.Elidable = E; }
 
   /// Whether the referred constructor was resolved from
   /// an overloaded set having size greater than 1.
-  bool hadMultipleCandidates() const { return HadMultipleCandidates; }
-  void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; }
+  bool hadMultipleCandidates() const {
+    return CXXConstructExprBits.HadMultipleCandidates;
+  }
+  void setHadMultipleCandidates(bool V) {
+    CXXConstructExprBits.HadMultipleCandidates = V;
+  }
 
   /// Whether this constructor call was written as list-initialization.
-  bool isListInitialization() const { return ListInitialization; }
-  void setListInitialization(bool V) { ListInitialization = V; }
+  bool isListInitialization() const {
+    return CXXConstructExprBits.ListInitialization;
+  }
+  void setListInitialization(bool V) {
+    CXXConstructExprBits.ListInitialization = V;
+  }
 
   /// Whether this constructor call was written as list-initialization,
   /// but was interpreted as forming a std::initializer_list<T> from the list
   /// and passing that as a single constructor argument.
   /// See C++11 [over.match.list]p1 bullet 1.
-  bool isStdInitListInitialization() const { return StdInitListInitialization; }
-  void setStdInitListInitialization(bool V) { StdInitListInitialization = V; }
+  bool isStdInitListInitialization() const {
+    return CXXConstructExprBits.StdInitListInitialization;
+  }
+  void setStdInitListInitialization(bool V) {
+    CXXConstructExprBits.StdInitListInitialization = V;
+  }
 
   /// Whether this construction first requires
   /// zero-initialization before the initializer is called.
-  bool requiresZeroInitialization() const { return ZeroInitialization; }
+  bool requiresZeroInitialization() const {
+    return CXXConstructExprBits.ZeroInitialization;
+  }
   void setRequiresZeroInitialization(bool ZeroInit) {
-    ZeroInitialization = ZeroInit;
+    CXXConstructExprBits.ZeroInitialization = ZeroInit;
   }
 
   /// Determine whether this constructor is actually constructing
   /// a base class (rather than a complete object).
   ConstructionKind getConstructionKind() const {
-    return (ConstructionKind)ConstructKind;
+    return static_cast<ConstructionKind>(CXXConstructExprBits.ConstructionKind);
   }
   void setConstructionKind(ConstructionKind CK) {
-    ConstructKind = CK;
+    CXXConstructExprBits.ConstructionKind = CK;
   }
 
   using arg_iterator = ExprIterator;
@@ -1393,31 +1416,33 @@ public:
     return const_arg_range(arg_begin(), arg_end());
   }
 
-  arg_iterator arg_begin() { return Args; }
-  arg_iterator arg_end() { return Args + NumArgs; }
-  const_arg_iterator arg_begin() const { return Args; }
-  const_arg_iterator arg_end() const { return Args + NumArgs; }
+  arg_iterator arg_begin() { return getTrailingArgs(); }
+  arg_iterator arg_end() { return arg_begin() + getNumArgs(); }
+  const_arg_iterator arg_begin() const { return getTrailingArgs(); }
+  const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); }
 
-  Expr **getArgs() { return reinterpret_cast<Expr **>(Args); }
+  Expr **getArgs() { return reinterpret_cast<Expr **>(getTrailingArgs()); }
   const Expr *const *getArgs() const {
-    return const_cast<CXXConstructExpr *>(this)->getArgs();
+    return reinterpret_cast<const Expr *const *>(getTrailingArgs());
   }
+
+  /// Return the number of arguments to the constructor call.
   unsigned getNumArgs() const { return NumArgs; }
 
   /// Return the specified argument.
   Expr *getArg(unsigned Arg) {
-    assert(Arg < NumArgs && "Arg access out of range!");
-    return cast<Expr>(Args[Arg]);
+    assert(Arg < getNumArgs() && "Arg access out of range!");
+    return getArgs()[Arg];
   }
   const Expr *getArg(unsigned Arg) const {
-    assert(Arg < NumArgs && "Arg access out of range!");
-    return cast<Expr>(Args[Arg]);
+    assert(Arg < getNumArgs() && "Arg access out of range!");
+    return getArgs()[Arg];
   }
 
   /// Set the specified argument.
   void setArg(unsigned Arg, Expr *ArgExpr) {
-    assert(Arg < NumArgs && "Arg access out of range!");
-    Args[Arg] = ArgExpr;
+    assert(Arg < getNumArgs() && "Arg access out of range!");
+    getArgs()[Arg] = ArgExpr;
   }
 
   SourceLocation getBeginLoc() const LLVM_READONLY;
@@ -1427,12 +1452,12 @@ public:
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXConstructExprClass ||
-      T->getStmtClass() == CXXTemporaryObjectExprClass;
+           T->getStmtClass() == CXXTemporaryObjectExprClass;
   }
 
   // Iterators
   child_range children() {
-    return child_range(&Args[0], &Args[0]+NumArgs);
+    return child_range(getTrailingArgs(), getTrailingArgs() + getNumArgs());
   }
 };
 
@@ -1578,26 +1603,36 @@ public:
 ///   return X(1, 3.14f); // creates a CXXTemporaryObjectExpr
 /// };
 /// \endcode
-class CXXTemporaryObjectExpr : public CXXConstructExpr {
-  TypeSourceInfo *Type = nullptr;
-
-public:
+class CXXTemporaryObjectExpr final : public CXXConstructExpr {
   friend class ASTStmtReader;
 
-  CXXTemporaryObjectExpr(const ASTContext &C,
-                         CXXConstructorDecl *Cons,
-                         QualType Type,
-                         TypeSourceInfo *TSI,
-                         ArrayRef<Expr *> Args,
+  // CXXTemporaryObjectExpr has some trailing objects belonging
+  // to CXXConstructExpr. See the comment inside CXXConstructExpr
+  // for more details.
+
+  TypeSourceInfo *TSI;
+
+  CXXTemporaryObjectExpr(CXXConstructorDecl *Cons, QualType Ty,
+                         TypeSourceInfo *TSI, ArrayRef<Expr *> Args,
                          SourceRange ParenOrBraceRange,
-                         bool HadMultipleCandidates,
-                         bool ListInitialization,
+                         bool HadMultipleCandidates, bool ListInitialization,
                          bool StdInitListInitialization,
                          bool ZeroInitialization);
-  explicit CXXTemporaryObjectExpr(EmptyShell Empty)
-      : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty) {}
 
-  TypeSourceInfo *getTypeSourceInfo() const { return Type; }
+  CXXTemporaryObjectExpr(EmptyShell Empty, unsigned NumArgs);
+
+public:
+  static CXXTemporaryObjectExpr *
+  Create(const ASTContext &Ctx, CXXConstructorDecl *Cons, QualType Ty,
+         TypeSourceInfo *TSI, ArrayRef<Expr *> Args,
+         SourceRange ParenOrBraceRange, bool HadMultipleCandidates,
+         bool ListInitialization, bool StdInitListInitialization,
+         bool ZeroInitialization);
+
+  static CXXTemporaryObjectExpr *CreateEmpty(const ASTContext &Ctx,
+                                             unsigned NumArgs);
+
+  TypeSourceInfo *getTypeSourceInfo() const { return TSI; }
 
   SourceLocation getBeginLoc() const LLVM_READONLY;
   SourceLocation getEndLoc() const LLVM_READONLY;
@@ -1607,6 +1642,14 @@ public:
   }
 };
 
+Stmt **CXXConstructExpr::getTrailingArgs() {
+  if (auto *E = dyn_cast<CXXTemporaryObjectExpr>(this))
+    return reinterpret_cast<Stmt **>(E + 1);
+  assert((getStmtClass() == CXXConstructExprClass) &&
+         "Unexpected class deriving from CXXConstructExpr!");
+  return reinterpret_cast<Stmt **>(this + 1);
+}
+
 /// A C++ lambda expression, which produces a function object
 /// (of unspecified type) that can be invoked later.
 ///

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=350003&r1=350002&r2=350003&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Sat Dec 22 06:39:30 2018
@@ -655,6 +655,22 @@ protected:
     unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
   };
 
+  class CXXConstructExprBitfields {
+    friend class ASTStmtReader;
+    friend class CXXConstructExpr;
+
+    unsigned : NumExprBits;
+
+    unsigned Elidable : 1;
+    unsigned HadMultipleCandidates : 1;
+    unsigned ListInitialization : 1;
+    unsigned StdInitListInitialization : 1;
+    unsigned ZeroInitialization : 1;
+    unsigned ConstructionKind : 3;
+
+    SourceLocation Loc;
+  };
+
   class ExprWithCleanupsBitfields {
     friend class ASTStmtReader; // deserialization
     friend class ExprWithCleanups;
@@ -746,6 +762,7 @@ protected:
     CXXDefaultInitExprBitfields CXXDefaultInitExprBits;
     CXXDeleteExprBitfields CXXDeleteExprBits;
     TypeTraitExprBitfields TypeTraitExprBits;
+    CXXConstructExprBitfields CXXConstructExprBits;
     ExprWithCleanupsBitfields ExprWithCleanupsBits;
 
     // C++ Coroutines TS expressions

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=350003&r1=350002&r2=350003&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Sat Dec 22 06:39:30 2018
@@ -6816,7 +6816,7 @@ ASTNodeImporter::VisitCXXTemporaryObject
   if (Error Err = ImportContainerChecked(E->arguments(), ToArgs))
     return std::move(Err);
 
-  return new (Importer.getToContext()) CXXTemporaryObjectExpr(
+  return CXXTemporaryObjectExpr::Create(
       Importer.getToContext(), ToConstructor, ToType, ToTypeSourceInfo, ToArgs,
       ToParenOrBraceRange, E->hadMultipleCandidates(),
       E->isListInitialization(), E->isStdInitListInitialization(),

Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=350003&r1=350002&r2=350003&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Sat Dec 22 06:39:30 2018
@@ -453,7 +453,7 @@ DependentScopeDeclRefExpr::CreateEmpty(c
 SourceLocation CXXConstructExpr::getBeginLoc() const {
   if (isa<CXXTemporaryObjectExpr>(this))
     return cast<CXXTemporaryObjectExpr>(this)->getBeginLoc();
-  return Loc;
+  return getLocation();
 }
 
 SourceLocation CXXConstructExpr::getEndLoc() const {
@@ -463,7 +463,7 @@ SourceLocation CXXConstructExpr::getEndL
   if (ParenOrBraceRange.isValid())
     return ParenOrBraceRange.getEnd();
 
-  SourceLocation End = Loc;
+  SourceLocation End = getLocation();
   for (unsigned I = getNumArgs(); I > 0; --I) {
     const Expr *Arg = getArg(I-1);
     if (!Arg->isDefaultArgument()) {
@@ -892,25 +892,47 @@ CXXBindTemporaryExpr *CXXBindTemporaryEx
   return new (C) CXXBindTemporaryExpr(Temp, SubExpr);
 }
 
-CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(const ASTContext &C,
-                                               CXXConstructorDecl *Cons,
-                                               QualType Type,
-                                               TypeSourceInfo *TSI,
-                                               ArrayRef<Expr*> Args,
-                                               SourceRange ParenOrBraceRange,
-                                               bool HadMultipleCandidates,
-                                               bool ListInitialization,
-                                               bool StdInitListInitialization,
-                                               bool ZeroInitialization)
-    : CXXConstructExpr(C, CXXTemporaryObjectExprClass, Type,
-                       TSI->getTypeLoc().getBeginLoc(), Cons, false, Args,
-                       HadMultipleCandidates, ListInitialization,
-                       StdInitListInitialization,  ZeroInitialization,
-                       CXXConstructExpr::CK_Complete, ParenOrBraceRange),
-      Type(TSI) {}
+CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(
+    CXXConstructorDecl *Cons, QualType Ty, TypeSourceInfo *TSI,
+    ArrayRef<Expr *> Args, SourceRange ParenOrBraceRange,
+    bool HadMultipleCandidates, bool ListInitialization,
+    bool StdInitListInitialization, bool ZeroInitialization)
+    : CXXConstructExpr(
+          CXXTemporaryObjectExprClass, Ty, TSI->getTypeLoc().getBeginLoc(),
+          Cons, /* Elidable=*/false, Args, HadMultipleCandidates,
+          ListInitialization, StdInitListInitialization, ZeroInitialization,
+          CXXConstructExpr::CK_Complete, ParenOrBraceRange),
+      TSI(TSI) {}
+
+CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(EmptyShell Empty,
+                                               unsigned NumArgs)
+    : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty, NumArgs) {}
+
+CXXTemporaryObjectExpr *CXXTemporaryObjectExpr::Create(
+    const ASTContext &Ctx, CXXConstructorDecl *Cons, QualType Ty,
+    TypeSourceInfo *TSI, ArrayRef<Expr *> Args, SourceRange ParenOrBraceRange,
+    bool HadMultipleCandidates, bool ListInitialization,
+    bool StdInitListInitialization, bool ZeroInitialization) {
+  unsigned SizeOfTrailingObjects = sizeOfTrailingObjects(Args.size());
+  void *Mem =
+      Ctx.Allocate(sizeof(CXXTemporaryObjectExpr) + SizeOfTrailingObjects,
+                   alignof(CXXTemporaryObjectExpr));
+  return new (Mem) CXXTemporaryObjectExpr(
+      Cons, Ty, TSI, Args, ParenOrBraceRange, HadMultipleCandidates,
+      ListInitialization, StdInitListInitialization, ZeroInitialization);
+}
+
+CXXTemporaryObjectExpr *
+CXXTemporaryObjectExpr::CreateEmpty(const ASTContext &Ctx, unsigned NumArgs) {
+  unsigned SizeOfTrailingObjects = sizeOfTrailingObjects(NumArgs);
+  void *Mem =
+      Ctx.Allocate(sizeof(CXXTemporaryObjectExpr) + SizeOfTrailingObjects,
+                   alignof(CXXTemporaryObjectExpr));
+  return new (Mem) CXXTemporaryObjectExpr(EmptyShell(), NumArgs);
+}
 
 SourceLocation CXXTemporaryObjectExpr::getBeginLoc() const {
-  return Type->getTypeLoc().getBeginLoc();
+  return getTypeSourceInfo()->getTypeLoc().getBeginLoc();
 }
 
 SourceLocation CXXTemporaryObjectExpr::getEndLoc() const {
@@ -920,64 +942,68 @@ SourceLocation CXXTemporaryObjectExpr::g
   return Loc;
 }
 
-CXXConstructExpr *CXXConstructExpr::Create(const ASTContext &C, QualType T,
-                                           SourceLocation Loc,
-                                           CXXConstructorDecl *Ctor,
-                                           bool Elidable,
-                                           ArrayRef<Expr*> Args,
-                                           bool HadMultipleCandidates,
-                                           bool ListInitialization,
-                                           bool StdInitListInitialization,
-                                           bool ZeroInitialization,
-                                           ConstructionKind ConstructKind,
-                                           SourceRange ParenOrBraceRange) {
-  return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc,
-                                  Ctor, Elidable, Args,
-                                  HadMultipleCandidates, ListInitialization,
-                                  StdInitListInitialization,
-                                  ZeroInitialization, ConstructKind,
-                                  ParenOrBraceRange);
-}
-
-CXXConstructExpr::CXXConstructExpr(const ASTContext &C, StmtClass SC,
-                                   QualType T, SourceLocation Loc,
-                                   CXXConstructorDecl *Ctor,
-                                   bool Elidable,
-                                   ArrayRef<Expr*> Args,
-                                   bool HadMultipleCandidates,
-                                   bool ListInitialization,
-                                   bool StdInitListInitialization,
-                                   bool ZeroInitialization,
-                                   ConstructionKind ConstructKind,
-                                   SourceRange ParenOrBraceRange)
-    : Expr(SC, T, VK_RValue, OK_Ordinary,
-           T->isDependentType(), T->isDependentType(),
-           T->isInstantiationDependentType(),
-           T->containsUnexpandedParameterPack()),
-      Constructor(Ctor), Loc(Loc), ParenOrBraceRange(ParenOrBraceRange),
-      NumArgs(Args.size()), Elidable(Elidable),
-      HadMultipleCandidates(HadMultipleCandidates),
-      ListInitialization(ListInitialization),
-      StdInitListInitialization(StdInitListInitialization),
-      ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind) {
-  if (NumArgs) {
-    this->Args = new (C) Stmt*[Args.size()];
-
-    for (unsigned i = 0; i != Args.size(); ++i) {
-      assert(Args[i] && "NULL argument in CXXConstructExpr");
-
-      if (Args[i]->isValueDependent())
-        ExprBits.ValueDependent = true;
-      if (Args[i]->isInstantiationDependent())
-        ExprBits.InstantiationDependent = true;
-      if (Args[i]->containsUnexpandedParameterPack())
-        ExprBits.ContainsUnexpandedParameterPack = true;
+CXXConstructExpr *CXXConstructExpr::Create(
+    const ASTContext &Ctx, QualType Ty, SourceLocation Loc,
+    CXXConstructorDecl *Ctor, bool Elidable, ArrayRef<Expr *> Args,
+    bool HadMultipleCandidates, bool ListInitialization,
+    bool StdInitListInitialization, bool ZeroInitialization,
+    ConstructionKind ConstructKind, SourceRange ParenOrBraceRange) {
+  unsigned SizeOfTrailingObjects = sizeOfTrailingObjects(Args.size());
+  void *Mem = Ctx.Allocate(sizeof(CXXConstructExpr) + SizeOfTrailingObjects,
+                           alignof(CXXConstructExpr));
+  return new (Mem) CXXConstructExpr(
+      CXXConstructExprClass, Ty, Loc, Ctor, Elidable, Args,
+      HadMultipleCandidates, ListInitialization, StdInitListInitialization,
+      ZeroInitialization, ConstructKind, ParenOrBraceRange);
+}
+
+CXXConstructExpr *CXXConstructExpr::CreateEmpty(const ASTContext &Ctx,
+                                                unsigned NumArgs) {
+  unsigned SizeOfTrailingObjects = sizeOfTrailingObjects(NumArgs);
+  void *Mem = Ctx.Allocate(sizeof(CXXConstructExpr) + SizeOfTrailingObjects,
+                           alignof(CXXConstructExpr));
+  return new (Mem)
+      CXXConstructExpr(CXXConstructExprClass, EmptyShell(), NumArgs);
+}
+
+CXXConstructExpr::CXXConstructExpr(
+    StmtClass SC, QualType Ty, SourceLocation Loc, CXXConstructorDecl *Ctor,
+    bool Elidable, ArrayRef<Expr *> Args, bool HadMultipleCandidates,
+    bool ListInitialization, bool StdInitListInitialization,
+    bool ZeroInitialization, ConstructionKind ConstructKind,
+    SourceRange ParenOrBraceRange)
+    : Expr(SC, Ty, VK_RValue, OK_Ordinary, Ty->isDependentType(),
+           Ty->isDependentType(), Ty->isInstantiationDependentType(),
+           Ty->containsUnexpandedParameterPack()),
+      Constructor(Ctor), ParenOrBraceRange(ParenOrBraceRange),
+      NumArgs(Args.size()) {
+  CXXConstructExprBits.Elidable = Elidable;
+  CXXConstructExprBits.HadMultipleCandidates = HadMultipleCandidates;
+  CXXConstructExprBits.ListInitialization = ListInitialization;
+  CXXConstructExprBits.StdInitListInitialization = StdInitListInitialization;
+  CXXConstructExprBits.ZeroInitialization = ZeroInitialization;
+  CXXConstructExprBits.ConstructionKind = ConstructKind;
+  CXXConstructExprBits.Loc = Loc;
+
+  Stmt **TrailingArgs = getTrailingArgs();
+  for (unsigned I = 0, N = Args.size(); I != N; ++I) {
+    assert(Args[I] && "NULL argument in CXXConstructExpr!");
+
+    if (Args[I]->isValueDependent())
+      ExprBits.ValueDependent = true;
+    if (Args[I]->isInstantiationDependent())
+      ExprBits.InstantiationDependent = true;
+    if (Args[I]->containsUnexpandedParameterPack())
+      ExprBits.ContainsUnexpandedParameterPack = true;
 
-      this->Args[i] = Args[i];
-    }
+    TrailingArgs[I] = Args[I];
   }
 }
 
+CXXConstructExpr::CXXConstructExpr(StmtClass SC, EmptyShell Empty,
+                                   unsigned NumArgs)
+    : Expr(SC, Empty), NumArgs(NumArgs) {}
+
 LambdaCapture::LambdaCapture(SourceLocation Loc, bool Implicit,
                              LambdaCaptureKind Kind, VarDecl *Var,
                              SourceLocation EllipsisLoc)

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=350003&r1=350002&r2=350003&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Sat Dec 22 06:39:30 2018
@@ -6199,7 +6199,7 @@ PerformConstructorInitialization(Sema &S
     }
     S.MarkFunctionReferenced(Loc, Constructor);
 
-    CurInit = new (S.Context) CXXTemporaryObjectExpr(
+    CurInit = CXXTemporaryObjectExpr::Create(
         S.Context, Constructor,
         Entity.getType().getNonLValueExprType(S.Context), TSInfo,
         ConstructorArgs, ParenOrBraceRange, HadMultipleCandidates,

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=350003&r1=350002&r2=350003&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Sat Dec 22 06:39:30 2018
@@ -1353,20 +1353,22 @@ void ASTStmtReader::VisitCXXOperatorCall
 
 void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) {
   VisitExpr(E);
-  E->NumArgs = Record.readInt();
-  if (E->NumArgs)
-    E->Args = new (Record.getContext()) Stmt*[E->NumArgs];
-  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
-    E->setArg(I, Record.readSubExpr());
-  E->setConstructor(ReadDeclAs<CXXConstructorDecl>());
-  E->setLocation(ReadSourceLocation());
-  E->setElidable(Record.readInt());
-  E->setHadMultipleCandidates(Record.readInt());
-  E->setListInitialization(Record.readInt());
-  E->setStdInitListInitialization(Record.readInt());
-  E->setRequiresZeroInitialization(Record.readInt());
-  E->setConstructionKind((CXXConstructExpr::ConstructionKind)Record.readInt());
+
+  unsigned NumArgs = Record.readInt();
+  assert((NumArgs == E->getNumArgs()) && "Wrong NumArgs!");
+
+  E->CXXConstructExprBits.Elidable = Record.readInt();
+  E->CXXConstructExprBits.HadMultipleCandidates = Record.readInt();
+  E->CXXConstructExprBits.ListInitialization = Record.readInt();
+  E->CXXConstructExprBits.StdInitListInitialization = Record.readInt();
+  E->CXXConstructExprBits.ZeroInitialization = Record.readInt();
+  E->CXXConstructExprBits.ConstructionKind = Record.readInt();
+  E->CXXConstructExprBits.Loc = ReadSourceLocation();
+  E->Constructor = ReadDeclAs<CXXConstructorDecl>();
   E->ParenOrBraceRange = ReadSourceRange();
+
+  for (unsigned I = 0; I != NumArgs; ++I)
+    E->setArg(I, Record.readSubExpr());
 }
 
 void ASTStmtReader::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
@@ -1379,7 +1381,7 @@ void ASTStmtReader::VisitCXXInheritedCto
 
 void ASTStmtReader::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
   VisitCXXConstructExpr(E);
-  E->Type = GetTypeSourceInfo();
+  E->TSI = GetTypeSourceInfo();
 }
 
 void ASTStmtReader::VisitLambdaExpr(LambdaExpr *E) {
@@ -3082,7 +3084,9 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
       break;
 
     case EXPR_CXX_CONSTRUCT:
-      S = new (Context) CXXConstructExpr(Empty);
+      S = CXXConstructExpr::CreateEmpty(
+          Context,
+          /* NumArgs=*/Record[ASTStmtReader::NumExprFields]);
       break;
 
     case EXPR_CXX_INHERITED_CTOR_INIT:
@@ -3090,7 +3094,9 @@ Stmt *ASTReader::ReadStmtFromStream(Modu
       break;
 
     case EXPR_CXX_TEMPORARY_OBJECT:
-      S = new (Context) CXXTemporaryObjectExpr(Empty);
+      S = CXXTemporaryObjectExpr::CreateEmpty(
+          Context,
+          /* NumArgs=*/Record[ASTStmtReader::NumExprFields]);
       break;
 
     case EXPR_CXX_STATIC_CAST:

Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=350003&r1=350002&r2=350003&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Sat Dec 22 06:39:30 2018
@@ -1315,18 +1315,21 @@ void ASTStmtWriter::VisitCXXMemberCallEx
 
 void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
   VisitExpr(E);
+
   Record.push_back(E->getNumArgs());
-  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
-    Record.AddStmt(E->getArg(I));
-  Record.AddDeclRef(E->getConstructor());
-  Record.AddSourceLocation(E->getLocation());
   Record.push_back(E->isElidable());
   Record.push_back(E->hadMultipleCandidates());
   Record.push_back(E->isListInitialization());
   Record.push_back(E->isStdInitListInitialization());
   Record.push_back(E->requiresZeroInitialization());
   Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
+  Record.AddSourceLocation(E->getLocation());
+  Record.AddDeclRef(E->getConstructor());
   Record.AddSourceRange(E->getParenOrBraceRange());
+
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
+    Record.AddStmt(E->getArg(I));
+
   Code = serialization::EXPR_CXX_CONSTRUCT;
 }
 




More information about the cfe-commits mailing list