Author: brunoricci Date: Mon Jan 7 07:04:45 2019 New Revision: 350527 URL: http://llvm.org/viewvc/llvm-project?rev=350527&view=rev Log: [AST] Store some data of CXXNewExpr as trailing objects
Store the optional array size expression, optional initialization expression and optional placement new arguments in a trailing array. Additionally store the range for the parenthesized type-id in a trailing object if needed since in the vast majority of cases the type is not parenthesized (not a single new expression in the translation unit of SemaDecl.cpp has a parenthesized type-id). This saves 2 pointers per CXXNewExpr in all cases, and 2 pointers + 8 bytes per CXXNewExpr in the common case where the type is not parenthesized. Differential Revision: https://reviews.llvm.org/D56134 Reviewed By: rjmccall 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/CodeGen/CGExprCXX.cpp cfe/trunk/lib/Sema/SemaExprCXX.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=350527&r1=350526&r2=350527&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/ExprCXX.h (original) +++ cfe/trunk/include/clang/AST/ExprCXX.h Mon Jan 7 07:04:45 2019 @@ -1933,54 +1933,56 @@ public: /// Represents a new-expression for memory allocation and constructor /// calls, e.g: "new CXXNewExpr(foo)". -class CXXNewExpr : public Expr { +class CXXNewExpr final + : public Expr, + private llvm::TrailingObjects<CXXNewExpr, Stmt *, SourceRange> { friend class ASTStmtReader; friend class ASTStmtWriter; - - /// Contains an optional array size expression, an optional initialization - /// expression, and any number of optional placement arguments, in that order. - Stmt **SubExprs = nullptr; + friend TrailingObjects; /// Points to the allocation function used. FunctionDecl *OperatorNew; - /// Points to the deallocation function used in case of error. May be - /// null. + /// Points to the deallocation function used in case of error. May be null. FunctionDecl *OperatorDelete; /// The allocated type-source information, as written in the source. TypeSourceInfo *AllocatedTypeInfo; - /// If the allocated type was expressed as a parenthesized type-id, - /// the source range covering the parenthesized type-id. - SourceRange TypeIdParens; - /// Range of the entire new expression. SourceRange Range; /// Source-range of a paren-delimited initializer. SourceRange DirectInitRange; - /// Was the usage ::new, i.e. is the global new to be used? - unsigned GlobalNew : 1; - - /// Do we allocate an array? If so, the first SubExpr is the size expression. - unsigned Array : 1; + // CXXNewExpr is followed by several optional trailing objects. + // They are in order: + // + // * An optional "Stmt *" for the array size expression. + // Present if and ony if isArray(). + // + // * An optional "Stmt *" for the init expression. + // Present if and only if hasInitializer(). + // + // * An array of getNumPlacementArgs() "Stmt *" for the placement new + // arguments, if any. + // + // * An optional SourceRange for the range covering the parenthesized type-id + // if the allocated type was expressed as a parenthesized type-id. + // Present if and only if isParenTypeId(). + unsigned arraySizeOffset() const { return 0; } + unsigned initExprOffset() const { return arraySizeOffset() + isArray(); } + unsigned placementNewArgsOffset() const { + return initExprOffset() + hasInitializer(); + } - /// Should the alignment be passed to the allocation function? - unsigned PassAlignment : 1; + unsigned numTrailingObjects(OverloadToken<Stmt *>) const { + return isArray() + hasInitializer() + getNumPlacementArgs(); + } - /// If this is an array allocation, does the usual deallocation - /// function for the allocated type want to know the allocated size? - unsigned UsualArrayDeleteWantsSize : 1; - - /// The number of placement new arguments. - unsigned NumPlacementArgs : 26; - - /// What kind of initializer do we have? Could be none, parens, or braces. - /// In storage, we distinguish between "none, and no initializer expr", and - /// "none, but an implicit initializer expr". - unsigned StoredInitializationStyle : 2; + unsigned numTrailingObjects(OverloadToken<SourceRange>) const { + return isParenTypeId(); + } public: enum InitializationStyle { @@ -1994,18 +1996,35 @@ public: ListInit }; - CXXNewExpr(const ASTContext &C, bool globalNew, FunctionDecl *operatorNew, - FunctionDecl *operatorDelete, bool PassAlignment, - bool usualArrayDeleteWantsSize, ArrayRef<Expr*> placementArgs, - SourceRange typeIdParens, Expr *arraySize, - InitializationStyle initializationStyle, Expr *initializer, - QualType ty, TypeSourceInfo *AllocatedTypeInfo, - SourceRange Range, SourceRange directInitRange); - explicit CXXNewExpr(EmptyShell Shell) - : Expr(CXXNewExprClass, Shell) {} +private: + /// Build a c++ new expression. + CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew, + FunctionDecl *OperatorDelete, bool ShouldPassAlignment, + bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs, + SourceRange TypeIdParens, Expr *ArraySize, + InitializationStyle InitializationStyle, Expr *Initializer, + QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, + SourceRange DirectInitRange); + + /// Build an empty c++ new expression. + CXXNewExpr(EmptyShell Empty, bool IsArray, unsigned NumPlacementArgs, + bool IsParenTypeId); - void AllocateArgsArray(const ASTContext &C, bool isArray, - unsigned numPlaceArgs, bool hasInitializer); +public: + /// Create a c++ new expression. + static CXXNewExpr * + Create(const ASTContext &Ctx, bool IsGlobalNew, FunctionDecl *OperatorNew, + FunctionDecl *OperatorDelete, bool ShouldPassAlignment, + bool UsualArrayDeleteWantsSize, ArrayRef<Expr *> PlacementArgs, + SourceRange TypeIdParens, Expr *ArraySize, + InitializationStyle InitializationStyle, Expr *Initializer, + QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, + SourceRange DirectInitRange); + + /// Create an empty c++ new expression. + static CXXNewExpr *CreateEmpty(const ASTContext &Ctx, bool IsArray, + bool HasInit, unsigned NumPlacementArgs, + bool IsParenTypeId); QualType getAllocatedType() const { assert(getType()->isPointerType()); @@ -2031,58 +2050,74 @@ public: /// has a non-throwing exception-specification. The '03 rule is /// identical except that the definition of a non-throwing /// exception specification is just "is it throw()?". - bool shouldNullCheckAllocation(const ASTContext &Ctx) const; + bool shouldNullCheckAllocation() const; FunctionDecl *getOperatorNew() const { return OperatorNew; } void setOperatorNew(FunctionDecl *D) { OperatorNew = D; } FunctionDecl *getOperatorDelete() const { return OperatorDelete; } void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; } - bool isArray() const { return Array; } + bool isArray() const { return CXXNewExprBits.IsArray; } Expr *getArraySize() { - return Array ? cast<Expr>(SubExprs[0]) : nullptr; + return isArray() + ? cast<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]) + : nullptr; } const Expr *getArraySize() const { - return Array ? cast<Expr>(SubExprs[0]) : nullptr; + return isArray() + ? cast<Expr>(getTrailingObjects<Stmt *>()[arraySizeOffset()]) + : nullptr; } - unsigned getNumPlacementArgs() const { return NumPlacementArgs; } + unsigned getNumPlacementArgs() const { + return CXXNewExprBits.NumPlacementArgs; + } Expr **getPlacementArgs() { - return reinterpret_cast<Expr **>(SubExprs + Array + hasInitializer()); + return reinterpret_cast<Expr **>(getTrailingObjects<Stmt *>() + + placementNewArgsOffset()); } - Expr *getPlacementArg(unsigned i) { - assert(i < NumPlacementArgs && "Index out of range"); - return getPlacementArgs()[i]; + Expr *getPlacementArg(unsigned I) { + assert((I < getNumPlacementArgs()) && "Index out of range!"); + return getPlacementArgs()[I]; } - const Expr *getPlacementArg(unsigned i) const { - assert(i < NumPlacementArgs && "Index out of range"); - return const_cast<CXXNewExpr*>(this)->getPlacementArg(i); + const Expr *getPlacementArg(unsigned I) const { + return const_cast<CXXNewExpr *>(this)->getPlacementArg(I); } - bool isParenTypeId() const { return TypeIdParens.isValid(); } - SourceRange getTypeIdParens() const { return TypeIdParens; } + bool isParenTypeId() const { return CXXNewExprBits.IsParenTypeId; } + SourceRange getTypeIdParens() const { + return isParenTypeId() ? getTrailingObjects<SourceRange>()[0] + : SourceRange(); + } - bool isGlobalNew() const { return GlobalNew; } + bool isGlobalNew() const { return CXXNewExprBits.IsGlobalNew; } /// Whether this new-expression has any initializer at all. - bool hasInitializer() const { return StoredInitializationStyle > 0; } + bool hasInitializer() const { + return CXXNewExprBits.StoredInitializationStyle > 0; + } /// The kind of initializer this new-expression has. InitializationStyle getInitializationStyle() const { - if (StoredInitializationStyle == 0) + if (CXXNewExprBits.StoredInitializationStyle == 0) return NoInit; - return static_cast<InitializationStyle>(StoredInitializationStyle-1); + return static_cast<InitializationStyle>( + CXXNewExprBits.StoredInitializationStyle - 1); } /// The initializer of this new-expression. Expr *getInitializer() { - return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr; + return hasInitializer() + ? cast<Expr>(getTrailingObjects<Stmt *>()[initExprOffset()]) + : nullptr; } const Expr *getInitializer() const { - return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr; + return hasInitializer() + ? cast<Expr>(getTrailingObjects<Stmt *>()[initExprOffset()]) + : nullptr; } /// Returns the CXXConstructExpr from this new-expression, or null. @@ -2092,15 +2127,13 @@ public: /// Indicates whether the required alignment should be implicitly passed to /// the allocation function. - bool passAlignment() const { - return PassAlignment; - } + bool passAlignment() const { return CXXNewExprBits.ShouldPassAlignment; } /// Answers whether the usual array deallocation function for the /// allocated type expects the size of the allocation as a /// parameter. bool doesUsualArrayDeleteWantSize() const { - return UsualArrayDeleteWantsSize; + return CXXNewExprBits.UsualArrayDeleteWantsSize; } using arg_iterator = ExprIterator; @@ -2115,47 +2148,43 @@ public: } arg_iterator placement_arg_begin() { - return SubExprs + Array + hasInitializer(); + return getTrailingObjects<Stmt *>() + placementNewArgsOffset(); } arg_iterator placement_arg_end() { - return SubExprs + Array + hasInitializer() + getNumPlacementArgs(); + return placement_arg_begin() + getNumPlacementArgs(); } const_arg_iterator placement_arg_begin() const { - return SubExprs + Array + hasInitializer(); + return getTrailingObjects<Stmt *>() + placementNewArgsOffset(); } const_arg_iterator placement_arg_end() const { - return SubExprs + Array + hasInitializer() + getNumPlacementArgs(); + return placement_arg_begin() + getNumPlacementArgs(); } using raw_arg_iterator = Stmt **; - raw_arg_iterator raw_arg_begin() { return SubExprs; } + raw_arg_iterator raw_arg_begin() { return getTrailingObjects<Stmt *>(); } raw_arg_iterator raw_arg_end() { - return SubExprs + Array + hasInitializer() + getNumPlacementArgs(); + return raw_arg_begin() + numTrailingObjects(OverloadToken<Stmt *>()); + } + const_arg_iterator raw_arg_begin() const { + return getTrailingObjects<Stmt *>(); } - const_arg_iterator raw_arg_begin() const { return SubExprs; } const_arg_iterator raw_arg_end() const { - return SubExprs + Array + hasInitializer() + getNumPlacementArgs(); + return raw_arg_begin() + numTrailingObjects(OverloadToken<Stmt *>()); } SourceLocation getBeginLoc() const { return Range.getBegin(); } SourceLocation getEndLoc() const { return Range.getEnd(); } SourceRange getDirectInitRange() const { return DirectInitRange; } - - SourceRange getSourceRange() const LLVM_READONLY { - return Range; - } - + SourceRange getSourceRange() const { return Range; } static bool classof(const Stmt *T) { return T->getStmtClass() == CXXNewExprClass; } // Iterators - child_range children() { - return child_range(raw_arg_begin(), raw_arg_end()); - } + child_range children() { return child_range(raw_arg_begin(), raw_arg_end()); } }; /// Represents a \c delete expression for memory deallocation and Modified: cfe/trunk/include/clang/AST/Stmt.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=350527&r1=350526&r2=350527&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Stmt.h (original) +++ cfe/trunk/include/clang/AST/Stmt.h Mon Jan 7 07:04:45 2019 @@ -612,6 +612,39 @@ protected: SourceLocation Loc; }; + class CXXNewExprBitfields { + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend class CXXNewExpr; + + unsigned : NumExprBits; + + /// Was the usage ::new, i.e. is the global new to be used? + unsigned IsGlobalNew : 1; + + /// Do we allocate an array? If so, the first trailing "Stmt *" is the + /// size expression. + unsigned IsArray : 1; + + /// Should the alignment be passed to the allocation function? + unsigned ShouldPassAlignment : 1; + + /// If this is an array allocation, does the usual deallocation + /// function for the allocated type want to know the allocated size? + unsigned UsualArrayDeleteWantsSize : 1; + + /// What kind of initializer do we have? Could be none, parens, or braces. + /// In storage, we distinguish between "none, and no initializer expr", and + /// "none, but an implicit initializer expr". + unsigned StoredInitializationStyle : 2; + + /// True if the allocated type was expressed as a parenthesized type-id. + unsigned IsParenTypeId : 1; + + /// The number of placement new arguments. + unsigned NumPlacementArgs; + }; + class CXXDeleteExprBitfields { friend class ASTStmtReader; friend class CXXDeleteExpr; @@ -785,6 +818,7 @@ protected: CXXThrowExprBitfields CXXThrowExprBits; CXXDefaultArgExprBitfields CXXDefaultArgExprBits; CXXDefaultInitExprBitfields CXXDefaultInitExprBits; + CXXNewExprBitfields CXXNewExprBits; CXXDeleteExprBitfields CXXDeleteExprBits; TypeTraitExprBitfields TypeTraitExprBits; DependentScopeDeclRefExprBitfields DependentScopeDeclRefExprBits; Modified: cfe/trunk/lib/AST/ASTImporter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=350527&r1=350526&r2=350527&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTImporter.cpp (original) +++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Jan 7 07:04:45 2019 @@ -6910,7 +6910,7 @@ ExpectedStmt ASTNodeImporter::VisitCXXNe ImportContainerChecked(E->placement_arguments(), ToPlacementArgs)) return std::move(Err); - return new (Importer.getToContext()) CXXNewExpr( + return CXXNewExpr::Create( Importer.getToContext(), E->isGlobalNew(), ToOperatorNew, ToOperatorDelete, E->passAlignment(), E->doesUsualArrayDeleteWantSize(), ToPlacementArgs, ToTypeIdParens, ToArraySize, E->getInitializationStyle(), Modified: cfe/trunk/lib/AST/ExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=350527&r1=350526&r2=350527&view=diff ============================================================================== --- cfe/trunk/lib/AST/ExprCXX.cpp (original) +++ cfe/trunk/lib/AST/ExprCXX.cpp Mon Jan 7 07:04:45 2019 @@ -94,83 +94,127 @@ SourceLocation CXXScalarValueInitExpr::g } // CXXNewExpr -CXXNewExpr::CXXNewExpr(const ASTContext &C, bool globalNew, - FunctionDecl *operatorNew, FunctionDecl *operatorDelete, - bool PassAlignment, bool usualArrayDeleteWantsSize, - ArrayRef<Expr*> placementArgs, - SourceRange typeIdParens, Expr *arraySize, - InitializationStyle initializationStyle, - Expr *initializer, QualType ty, - TypeSourceInfo *allocatedTypeInfo, - SourceRange Range, SourceRange directInitRange) - : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary, ty->isDependentType(), - ty->isDependentType(), ty->isInstantiationDependentType(), - ty->containsUnexpandedParameterPack()), - OperatorNew(operatorNew), OperatorDelete(operatorDelete), - AllocatedTypeInfo(allocatedTypeInfo), TypeIdParens(typeIdParens), - Range(Range), DirectInitRange(directInitRange), GlobalNew(globalNew), - PassAlignment(PassAlignment), - UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) { - assert((initializer != nullptr || initializationStyle == NoInit) && - "Only NoInit can have no initializer."); - StoredInitializationStyle = initializer ? initializationStyle + 1 : 0; - AllocateArgsArray(C, arraySize != nullptr, placementArgs.size(), - initializer != nullptr); - unsigned i = 0; - if (Array) { - if (arraySize->isInstantiationDependent()) - ExprBits.InstantiationDependent = true; +CXXNewExpr::CXXNewExpr(bool IsGlobalNew, FunctionDecl *OperatorNew, + FunctionDecl *OperatorDelete, bool ShouldPassAlignment, + bool UsualArrayDeleteWantsSize, + ArrayRef<Expr *> PlacementArgs, SourceRange TypeIdParens, + Expr *ArraySize, InitializationStyle InitializationStyle, + Expr *Initializer, QualType Ty, + TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, + SourceRange DirectInitRange) + : Expr(CXXNewExprClass, Ty, VK_RValue, OK_Ordinary, Ty->isDependentType(), + Ty->isDependentType(), Ty->isInstantiationDependentType(), + Ty->containsUnexpandedParameterPack()), + OperatorNew(OperatorNew), OperatorDelete(OperatorDelete), + AllocatedTypeInfo(AllocatedTypeInfo), Range(Range), + DirectInitRange(DirectInitRange) { + + assert((Initializer != nullptr || InitializationStyle == NoInit) && + "Only NoInit can have no initializer!"); + + CXXNewExprBits.IsGlobalNew = IsGlobalNew; + CXXNewExprBits.IsArray = ArraySize != nullptr; + CXXNewExprBits.ShouldPassAlignment = ShouldPassAlignment; + CXXNewExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize; + CXXNewExprBits.StoredInitializationStyle = + Initializer ? InitializationStyle + 1 : 0; + bool IsParenTypeId = TypeIdParens.isValid(); + CXXNewExprBits.IsParenTypeId = IsParenTypeId; + CXXNewExprBits.NumPlacementArgs = PlacementArgs.size(); - if (arraySize->containsUnexpandedParameterPack()) + if (ArraySize) { + if (ArraySize->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; + if (ArraySize->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; - SubExprs[i++] = arraySize; + getTrailingObjects<Stmt *>()[arraySizeOffset()] = ArraySize; } - if (initializer) { - if (initializer->isInstantiationDependent()) + if (Initializer) { + if (Initializer->isInstantiationDependent()) ExprBits.InstantiationDependent = true; - - if (initializer->containsUnexpandedParameterPack()) + if (Initializer->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; - SubExprs[i++] = initializer; + getTrailingObjects<Stmt *>()[initExprOffset()] = Initializer; } - for (unsigned j = 0; j != placementArgs.size(); ++j) { - if (placementArgs[j]->isInstantiationDependent()) + for (unsigned I = 0; I != PlacementArgs.size(); ++I) { + if (PlacementArgs[I]->isInstantiationDependent()) ExprBits.InstantiationDependent = true; - if (placementArgs[j]->containsUnexpandedParameterPack()) + if (PlacementArgs[I]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; - SubExprs[i++] = placementArgs[j]; + getTrailingObjects<Stmt *>()[placementNewArgsOffset() + I] = + PlacementArgs[I]; } + if (IsParenTypeId) + getTrailingObjects<SourceRange>()[0] = TypeIdParens; + switch (getInitializationStyle()) { case CallInit: - this->Range.setEnd(DirectInitRange.getEnd()); break; + this->Range.setEnd(DirectInitRange.getEnd()); + break; case ListInit: - this->Range.setEnd(getInitializer()->getSourceRange().getEnd()); break; + this->Range.setEnd(getInitializer()->getSourceRange().getEnd()); + break; default: - if (TypeIdParens.isValid()) + if (IsParenTypeId) this->Range.setEnd(TypeIdParens.getEnd()); break; } } -void CXXNewExpr::AllocateArgsArray(const ASTContext &C, bool isArray, - unsigned numPlaceArgs, bool hasInitializer){ - assert(SubExprs == nullptr && "SubExprs already allocated"); - Array = isArray; - NumPlacementArgs = numPlaceArgs; - - unsigned TotalSize = Array + hasInitializer + NumPlacementArgs; - SubExprs = new (C) Stmt*[TotalSize]; +CXXNewExpr::CXXNewExpr(EmptyShell Empty, bool IsArray, + unsigned NumPlacementArgs, bool IsParenTypeId) + : Expr(CXXNewExprClass, Empty) { + CXXNewExprBits.IsArray = IsArray; + CXXNewExprBits.NumPlacementArgs = NumPlacementArgs; + CXXNewExprBits.IsParenTypeId = IsParenTypeId; +} + +CXXNewExpr * +CXXNewExpr::Create(const ASTContext &Ctx, bool IsGlobalNew, + FunctionDecl *OperatorNew, FunctionDecl *OperatorDelete, + bool ShouldPassAlignment, bool UsualArrayDeleteWantsSize, + ArrayRef<Expr *> PlacementArgs, SourceRange TypeIdParens, + Expr *ArraySize, InitializationStyle InitializationStyle, + Expr *Initializer, QualType Ty, + TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, + SourceRange DirectInitRange) { + bool IsArray = ArraySize != nullptr; + bool HasInit = Initializer != nullptr; + unsigned NumPlacementArgs = PlacementArgs.size(); + bool IsParenTypeId = TypeIdParens.isValid(); + void *Mem = + Ctx.Allocate(totalSizeToAlloc<Stmt *, SourceRange>( + IsArray + HasInit + NumPlacementArgs, IsParenTypeId), + alignof(CXXNewExpr)); + return new (Mem) + CXXNewExpr(IsGlobalNew, OperatorNew, OperatorDelete, ShouldPassAlignment, + UsualArrayDeleteWantsSize, PlacementArgs, TypeIdParens, + ArraySize, InitializationStyle, Initializer, Ty, + AllocatedTypeInfo, Range, DirectInitRange); +} + +CXXNewExpr *CXXNewExpr::CreateEmpty(const ASTContext &Ctx, bool IsArray, + bool HasInit, unsigned NumPlacementArgs, + bool IsParenTypeId) { + void *Mem = + Ctx.Allocate(totalSizeToAlloc<Stmt *, SourceRange>( + IsArray + HasInit + NumPlacementArgs, IsParenTypeId), + alignof(CXXNewExpr)); + return new (Mem) + CXXNewExpr(EmptyShell(), IsArray, NumPlacementArgs, IsParenTypeId); } -bool CXXNewExpr::shouldNullCheckAllocation(const ASTContext &Ctx) const { - return getOperatorNew()->getType()->castAs<FunctionProtoType>() - ->isNothrow() && +bool CXXNewExpr::shouldNullCheckAllocation() const { + return getOperatorNew() + ->getType() + ->castAs<FunctionProtoType>() + ->isNothrow() && !getOperatorNew()->isReservedGlobalPlacementOperator(); } Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=350527&r1=350526&r2=350527&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Mon Jan 7 07:04:45 2019 @@ -1657,8 +1657,8 @@ llvm::Value *CodeGenFunction::EmitCXXNew // function is allowed to return null (because it has a non-throwing // exception spec or is the reserved placement new) and we have an // interesting initializer. - bool nullCheck = E->shouldNullCheckAllocation(getContext()) && - (!allocType.isPODType(getContext()) || E->hasInitializer()); + bool nullCheck = E->shouldNullCheckAllocation() && + (!allocType.isPODType(getContext()) || E->hasInitializer()); llvm::BasicBlock *nullCheckBB = nullptr; llvm::BasicBlock *contBB = nullptr; Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=350527&r1=350526&r2=350527&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Jan 7 07:04:45 2019 @@ -2179,11 +2179,11 @@ Sema::BuildCXXNew(SourceRange Range, boo } } - return new (Context) - CXXNewExpr(Context, UseGlobal, OperatorNew, OperatorDelete, PassAlignment, - UsualArrayDeleteWantsSize, PlacementArgs, TypeIdParens, - ArraySize, initStyle, Initializer, ResultType, AllocTypeInfo, - Range, DirectInitRange); + return CXXNewExpr::Create(Context, UseGlobal, OperatorNew, OperatorDelete, + PassAlignment, UsualArrayDeleteWantsSize, + PlacementArgs, TypeIdParens, ArraySize, initStyle, + Initializer, ResultType, AllocTypeInfo, Range, + DirectInitRange); } /// Checks that a type is suitable as the allocated type Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=350527&r1=350526&r2=350527&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Mon Jan 7 07:04:45 2019 @@ -1507,25 +1507,38 @@ void ASTStmtReader::VisitCXXScalarValueI void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) { VisitExpr(E); - E->GlobalNew = Record.readInt(); - bool isArray = Record.readInt(); - E->PassAlignment = Record.readInt(); - E->UsualArrayDeleteWantsSize = Record.readInt(); + + bool IsArray = Record.readInt(); + bool HasInit = Record.readInt(); unsigned NumPlacementArgs = Record.readInt(); - E->StoredInitializationStyle = Record.readInt(); + bool IsParenTypeId = Record.readInt(); + + E->CXXNewExprBits.IsGlobalNew = Record.readInt(); + E->CXXNewExprBits.ShouldPassAlignment = Record.readInt(); + E->CXXNewExprBits.UsualArrayDeleteWantsSize = Record.readInt(); + E->CXXNewExprBits.StoredInitializationStyle = Record.readInt(); + + assert((IsArray == E->isArray()) && "Wrong IsArray!"); + assert((HasInit == E->hasInitializer()) && "Wrong HasInit!"); + assert((NumPlacementArgs == E->getNumPlacementArgs()) && + "Wrong NumPlacementArgs!"); + assert((IsParenTypeId == E->isParenTypeId()) && "Wrong IsParenTypeId!"); + (void)IsArray; + (void)HasInit; + (void)NumPlacementArgs; + E->setOperatorNew(ReadDeclAs<FunctionDecl>()); E->setOperatorDelete(ReadDeclAs<FunctionDecl>()); E->AllocatedTypeInfo = GetTypeSourceInfo(); - E->TypeIdParens = ReadSourceRange(); + if (IsParenTypeId) + E->getTrailingObjects<SourceRange>()[0] = ReadSourceRange(); E->Range = ReadSourceRange(); E->DirectInitRange = ReadSourceRange(); - E->AllocateArgsArray(Record.getContext(), isArray, NumPlacementArgs, - E->StoredInitializationStyle != 0); - // Install all the subexpressions. - for (CXXNewExpr::raw_arg_iterator I = E->raw_arg_begin(),e = E->raw_arg_end(); - I != e; ++I) + for (CXXNewExpr::raw_arg_iterator I = E->raw_arg_begin(), + N = E->raw_arg_end(); + I != N; ++I) *I = Record.readSubStmt(); } @@ -3189,7 +3202,12 @@ Stmt *ASTReader::ReadStmtFromStream(Modu break; case EXPR_CXX_NEW: - S = new (Context) CXXNewExpr(Empty); + S = CXXNewExpr::CreateEmpty( + Context, + /*IsArray=*/Record[ASTStmtReader::NumExprFields], + /*HasInit=*/Record[ASTStmtReader::NumExprFields + 1], + /*NumPlacementArgs=*/Record[ASTStmtReader::NumExprFields + 2], + /*IsParenTypeId=*/Record[ASTStmtReader::NumExprFields + 3]); break; case EXPR_CXX_DELETE: Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=350527&r1=350526&r2=350527&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Mon Jan 7 07:04:45 2019 @@ -1483,20 +1483,27 @@ void ASTStmtWriter::VisitCXXScalarValueI void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) { VisitExpr(E); - Record.push_back(E->isGlobalNew()); + Record.push_back(E->isArray()); + Record.push_back(E->hasInitializer()); + Record.push_back(E->getNumPlacementArgs()); + Record.push_back(E->isParenTypeId()); + + Record.push_back(E->isGlobalNew()); Record.push_back(E->passAlignment()); Record.push_back(E->doesUsualArrayDeleteWantSize()); - Record.push_back(E->getNumPlacementArgs()); - Record.push_back(E->StoredInitializationStyle); + Record.push_back(E->CXXNewExprBits.StoredInitializationStyle); + Record.AddDeclRef(E->getOperatorNew()); Record.AddDeclRef(E->getOperatorDelete()); Record.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo()); - Record.AddSourceRange(E->getTypeIdParens()); + if (E->isParenTypeId()) + Record.AddSourceRange(E->getTypeIdParens()); Record.AddSourceRange(E->getSourceRange()); Record.AddSourceRange(E->getDirectInitRange()); - for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end(); - I != e; ++I) + + for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), N = E->raw_arg_end(); + I != N; ++I) Record.AddStmt(*I); Code = serialization::EXPR_CXX_NEW; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits