Index: include/clang/AST/ExprCXX.h =================================================================== --- include/clang/AST/ExprCXX.h +++ include/clang/AST/ExprCXX.h @@ -1280,6 +1280,8 @@ /// Represents a call to a C++ constructor. class CXXConstructExpr : public Expr { + friend class ASTStmtReader; + public: enum ConstructionKind { CK_Complete, @@ -1289,98 +1291,119 @@ }; 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(this)->getTrailingArgs(); + } protected: - CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T, - SourceLocation Loc, - CXXConstructorDecl *Ctor, - bool Elidable, - ArrayRef 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 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 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 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 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(CXXConstructExprBits.ConstructionKind); } void setConstructionKind(ConstructionKind CK) { - ConstructKind = CK; + CXXConstructExprBits.ConstructionKind = CK; } using arg_iterator = ExprIterator; @@ -1393,31 +1416,33 @@ 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(Args); } + Expr **getArgs() { return reinterpret_cast(getTrailingArgs()); } const Expr *const *getArgs() const { - return const_cast(this)->getArgs(); + return reinterpret_cast(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(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(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 @@ 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 @@ /// 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 Args, + // CXXTemporaryObjectExpr has some trailing objects belonging + // to CXXConstructExpr. See the comment inside CXXConstructExpr + // for more details. + + TypeSourceInfo *TSI = nullptr; + + CXXTemporaryObjectExpr(CXXConstructorDecl *Cons, QualType Ty, + TypeSourceInfo *TSI, ArrayRef 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 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 @@ } }; +Stmt **CXXConstructExpr::getTrailingArgs() { + if (auto *E = dyn_cast(this)) + return reinterpret_cast(E + 1); + assert((getStmtClass() == CXXConstructExprClass) && + "Unexpected class deriving from CXXConstructExpr!"); + return reinterpret_cast(this + 1); +} + /// A C++ lambda expression, which produces a function object /// (of unspecified type) that can be invoked later. /// Index: include/clang/AST/Stmt.h =================================================================== --- include/clang/AST/Stmt.h +++ include/clang/AST/Stmt.h @@ -655,6 +655,22 @@ 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 @@ CXXDefaultInitExprBitfields CXXDefaultInitExprBits; CXXDeleteExprBitfields CXXDeleteExprBits; TypeTraitExprBitfields TypeTraitExprBits; + CXXConstructExprBitfields CXXConstructExprBits; ExprWithCleanupsBitfields ExprWithCleanupsBits; // C++ Coroutines TS expressions Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -6816,7 +6816,7 @@ 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(), Index: lib/AST/ExprCXX.cpp =================================================================== --- lib/AST/ExprCXX.cpp +++ lib/AST/ExprCXX.cpp @@ -453,7 +453,7 @@ SourceLocation CXXConstructExpr::getBeginLoc() const { if (isa(this)) return cast(this)->getBeginLoc(); - return Loc; + return getLocation(); } SourceLocation CXXConstructExpr::getEndLoc() const { @@ -463,7 +463,7 @@ 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()) { @@ -891,25 +891,47 @@ return new (C) CXXBindTemporaryExpr(Temp, SubExpr); } -CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(const ASTContext &C, - CXXConstructorDecl *Cons, - QualType Type, - TypeSourceInfo *TSI, - ArrayRef 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 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 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 { @@ -919,64 +941,68 @@ return Loc; } -CXXConstructExpr *CXXConstructExpr::Create(const ASTContext &C, QualType T, - SourceLocation Loc, - CXXConstructorDecl *Ctor, - bool Elidable, - ArrayRef 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 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 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 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!"); - this->Args[i] = Args[i]; - } + if (Args[I]->isValueDependent()) + ExprBits.ValueDependent = true; + if (Args[I]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; + if (Args[I]->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + + 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) Index: lib/Sema/SemaInit.cpp =================================================================== --- lib/Sema/SemaInit.cpp +++ lib/Sema/SemaInit.cpp @@ -6199,7 +6199,7 @@ } S.MarkFunctionReferenced(Loc, Constructor); - CurInit = new (S.Context) CXXTemporaryObjectExpr( + CurInit = CXXTemporaryObjectExpr::Create( S.Context, Constructor, Entity.getType().getNonLValueExprType(S.Context), TSInfo, ConstructorArgs, ParenOrBraceRange, HadMultipleCandidates, Index: lib/Serialization/ASTReaderStmt.cpp =================================================================== --- lib/Serialization/ASTReaderStmt.cpp +++ lib/Serialization/ASTReaderStmt.cpp @@ -1353,20 +1353,22 @@ 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()); - 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(); 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::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) { VisitCXXConstructExpr(E); - E->Type = GetTypeSourceInfo(); + E->TSI = GetTypeSourceInfo(); } void ASTStmtReader::VisitLambdaExpr(LambdaExpr *E) { @@ -3082,7 +3084,9 @@ 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 @@ 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: Index: lib/Serialization/ASTWriterStmt.cpp =================================================================== --- lib/Serialization/ASTWriterStmt.cpp +++ lib/Serialization/ASTWriterStmt.cpp @@ -1315,18 +1315,21 @@ 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; }