[cfe-commits] r150685 - in /cfe/trunk: include/clang/AST/ExprCXX.h include/clang/Sema/Sema.h lib/AST/Expr.cpp lib/AST/ExprCXX.cpp lib/AST/ItaniumMangle.cpp lib/AST/StmtPrinter.cpp lib/AST/StmtProfile.cpp lib/CodeGen/CGExprCXX.cpp lib/Parse/ParseE
Matt Beaumont-Gay
matthewbg at google.com
Fri Feb 17 17:10:16 PST 2012
I'm updating some code to for these API changes, and I'm starting to
think it might be nice to add a little method like this to CXXNewExpr:
const CXXConstructExpr* getConstructExpr() {
return dyn_cast_or_null<CXXConstructExpr>(getInitializer());
}
It seems to be pretty common that code that was looking into 'new'
exprs mostly wanted to dig out information about the constructor (if
any). What do you think?
-Matt
On Thu, Feb 16, 2012 at 04:22, Sebastian Redl
<sebastian.redl at getdesigned.at> wrote:
> Author: cornedbee
> Date: Thu Feb 16 06:22:20 2012
> New Revision: 150685
>
> URL: http://llvm.org/viewvc/llvm-project?rev=150685&view=rev
> Log:
> Revert "Revert "Make CXXNewExpr contain only a single initialier, and not hold the used constructor itself.""
>
> This reintroduces commit r150682 with a fix for the Bullet benchmark crash.
>
> Modified:
> cfe/trunk/include/clang/AST/ExprCXX.h
> cfe/trunk/include/clang/Sema/Sema.h
> cfe/trunk/lib/AST/Expr.cpp
> cfe/trunk/lib/AST/ExprCXX.cpp
> cfe/trunk/lib/AST/ItaniumMangle.cpp
> cfe/trunk/lib/AST/StmtPrinter.cpp
> cfe/trunk/lib/AST/StmtProfile.cpp
> cfe/trunk/lib/CodeGen/CGExprCXX.cpp
> cfe/trunk/lib/Parse/ParseExprCXX.cpp
> cfe/trunk/lib/Sema/SemaExpr.cpp
> cfe/trunk/lib/Sema/SemaExprCXX.cpp
> cfe/trunk/lib/Sema/TreeTransform.h
> cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
> cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
> cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
> cfe/trunk/test/Analysis/new.cpp
> cfe/trunk/test/SemaCXX/new-delete.cpp
> cfe/trunk/tools/libclang/CIndex.cpp
>
> Modified: cfe/trunk/include/clang/AST/ExprCXX.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ExprCXX.h (original)
> +++ cfe/trunk/include/clang/AST/ExprCXX.h Thu Feb 16 06:22:20 2012
> @@ -1359,34 +1359,24 @@
> class CXXNewExpr : public Expr {
> // Was the usage ::new, i.e. is the global new to be used?
> bool GlobalNew : 1;
> - // Is there an initializer? If not, built-ins are uninitialized, else they're
> - // value-initialized.
> - bool Initializer : 1;
> // Do we allocate an array? If so, the first SubExpr is the size expression.
> bool Array : 1;
> // If this is an array allocation, does the usual deallocation
> // function for the allocated type want to know the allocated size?
> bool UsualArrayDeleteWantsSize : 1;
> - // Whether the referred constructor (if any) was resolved from an
> - // overload set having size greater than 1.
> - bool HadMultipleCandidates : 1;
> // The number of placement new arguments.
> unsigned NumPlacementArgs : 13;
> - // The number of constructor arguments. This may be 1 even for non-class
> - // types; use the pseudo copy constructor.
> - unsigned NumConstructorArgs : 14;
> - // Contains an optional array size expression, any number of optional
> - // placement arguments, and any number of optional constructor arguments,
> - // in that order.
> + // 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;
> + // Contains an optional array size expression, an optional initialization
> + // expression, and any number of optional placement arguments, in that order.
> Stmt **SubExprs;
> // Points to the allocation function used.
> FunctionDecl *OperatorNew;
> // Points to the deallocation function used in case of error. May be null.
> FunctionDecl *OperatorDelete;
> - // Points to the constructor used. Cannot be null if AllocType is a record;
> - // it would still point at the default constructor (even an implicit one).
> - // Must be null for all other types.
> - CXXConstructorDecl *Constructor;
>
> /// \brief The allocated type-source information, as written in the source.
> TypeSourceInfo *AllocatedTypeInfo;
> @@ -1395,29 +1385,33 @@
> /// the source range covering the parenthesized type-id.
> SourceRange TypeIdParens;
>
> + /// \brief Location of the first token.
> SourceLocation StartLoc;
> - SourceLocation EndLoc;
> - SourceLocation ConstructorLParen;
> - SourceLocation ConstructorRParen;
> +
> + /// \brief Source-range of a paren-delimited initializer.
> + SourceRange DirectInitRange;
>
> friend class ASTStmtReader;
> + friend class ASTStmtWriter;
> public:
> + enum InitializationStyle {
> + NoInit, ///< New-expression has no initializer as written.
> + CallInit, ///< New-expression has a C++98 paren-delimited initializer.
> + ListInit ///< New-expression has a C++11 list-initializer.
> + };
> +
> CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
> - Expr **placementArgs, unsigned numPlaceArgs,
> - SourceRange TypeIdParens,
> - Expr *arraySize, CXXConstructorDecl *constructor, bool initializer,
> - Expr **constructorArgs, unsigned numConsArgs,
> - bool HadMultipleCandidates,
> FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize,
> + Expr **placementArgs, unsigned numPlaceArgs,
> + SourceRange typeIdParens, Expr *arraySize,
> + InitializationStyle initializationStyle, Expr *initializer,
> QualType ty, TypeSourceInfo *AllocatedTypeInfo,
> - SourceLocation startLoc, SourceLocation endLoc,
> - SourceLocation constructorLParen,
> - SourceLocation constructorRParen);
> + SourceLocation startLoc, SourceRange directInitRange);
> explicit CXXNewExpr(EmptyShell Shell)
> : Expr(CXXNewExprClass, Shell), SubExprs(0) { }
>
> void AllocateArgsArray(ASTContext &C, bool isArray, unsigned numPlaceArgs,
> - unsigned numConsArgs);
> + bool hasInitializer);
>
> QualType getAllocatedType() const {
> assert(getType()->isPointerType());
> @@ -1443,8 +1437,6 @@
> void setOperatorNew(FunctionDecl *D) { OperatorNew = D; }
> FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
> void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; }
> - CXXConstructorDecl *getConstructor() const { return Constructor; }
> - void setConstructor(CXXConstructorDecl *D) { Constructor = D; }
>
> bool isArray() const { return Array; }
> Expr *getArraySize() {
> @@ -1456,23 +1448,40 @@
>
> unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
> Expr **getPlacementArgs() {
> - return reinterpret_cast<Expr **>(SubExprs + Array);
> + return reinterpret_cast<Expr **>(SubExprs + Array + hasInitializer());
> }
>
> Expr *getPlacementArg(unsigned i) {
> assert(i < NumPlacementArgs && "Index out of range");
> - return cast<Expr>(SubExprs[Array + i]);
> + return getPlacementArgs()[i];
> }
> const Expr *getPlacementArg(unsigned i) const {
> assert(i < NumPlacementArgs && "Index out of range");
> - return cast<Expr>(SubExprs[Array + i]);
> + return const_cast<CXXNewExpr*>(this)->getPlacementArg(i);
> }
>
> bool isParenTypeId() const { return TypeIdParens.isValid(); }
> SourceRange getTypeIdParens() const { return TypeIdParens; }
>
> bool isGlobalNew() const { return GlobalNew; }
> - bool hasInitializer() const { return Initializer; }
> +
> + /// \brief Whether this new-expression has any initializer at all.
> + bool hasInitializer() const { return StoredInitializationStyle > 0; }
> +
> + /// \brief The kind of initializer this new-expression has.
> + InitializationStyle getInitializationStyle() const {
> + if (StoredInitializationStyle == 0)
> + return NoInit;
> + return static_cast<InitializationStyle>(StoredInitializationStyle-1);
> + }
> +
> + /// \brief The initializer of this new-expression.
> + Expr *getInitializer() {
> + return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
> + }
> + const Expr *getInitializer() const {
> + return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
> + }
>
> /// Answers whether the usual array deallocation function for the
> /// allocated type expects the size of the allocation as a
> @@ -1481,71 +1490,39 @@
> return UsualArrayDeleteWantsSize;
> }
>
> - unsigned getNumConstructorArgs() const { return NumConstructorArgs; }
> -
> - Expr **getConstructorArgs() {
> - return reinterpret_cast<Expr **>(SubExprs + Array + NumPlacementArgs);
> - }
> -
> - Expr *getConstructorArg(unsigned i) {
> - assert(i < NumConstructorArgs && "Index out of range");
> - return cast<Expr>(SubExprs[Array + NumPlacementArgs + i]);
> - }
> - const Expr *getConstructorArg(unsigned i) const {
> - assert(i < NumConstructorArgs && "Index out of range");
> - return cast<Expr>(SubExprs[Array + NumPlacementArgs + i]);
> - }
> -
> - /// \brief Whether the new expression refers a constructor that was
> - /// resolved from an overloaded set having size greater than 1.
> - bool hadMultipleCandidates() const { return HadMultipleCandidates; }
> - void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; }
> -
> typedef ExprIterator arg_iterator;
> typedef ConstExprIterator const_arg_iterator;
>
> arg_iterator placement_arg_begin() {
> - return SubExprs + Array;
> + return SubExprs + Array + hasInitializer();
> }
> arg_iterator placement_arg_end() {
> - return SubExprs + Array + getNumPlacementArgs();
> + return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
> }
> const_arg_iterator placement_arg_begin() const {
> - return SubExprs + Array;
> + return SubExprs + Array + hasInitializer();
> }
> const_arg_iterator placement_arg_end() const {
> - return SubExprs + Array + getNumPlacementArgs();
> - }
> -
> - arg_iterator constructor_arg_begin() {
> - return SubExprs + Array + getNumPlacementArgs();
> - }
> - arg_iterator constructor_arg_end() {
> - return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
> - }
> - const_arg_iterator constructor_arg_begin() const {
> - return SubExprs + Array + getNumPlacementArgs();
> - }
> - const_arg_iterator constructor_arg_end() const {
> - return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
> + return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
> }
>
> typedef Stmt **raw_arg_iterator;
> raw_arg_iterator raw_arg_begin() { return SubExprs; }
> raw_arg_iterator raw_arg_end() {
> - return SubExprs + Array + getNumPlacementArgs() + getNumConstructorArgs();
> + return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
> }
> const_arg_iterator raw_arg_begin() const { return SubExprs; }
> - const_arg_iterator raw_arg_end() const { return constructor_arg_end(); }
> + const_arg_iterator raw_arg_end() const {
> + return SubExprs + Array + hasInitializer() + getNumPlacementArgs();
> + }
>
> SourceLocation getStartLoc() const { return StartLoc; }
> - SourceLocation getEndLoc() const { return EndLoc; }
> + SourceLocation getEndLoc() const;
>
> - SourceLocation getConstructorLParen() const { return ConstructorLParen; }
> - SourceLocation getConstructorRParen() const { return ConstructorRParen; }
> + SourceRange getDirectInitRange() const { return DirectInitRange; }
>
> SourceRange getSourceRange() const {
> - return SourceRange(StartLoc, EndLoc);
> + return SourceRange(getStartLoc(), getEndLoc());
> }
>
> static bool classof(const Stmt *T) {
> @@ -1555,9 +1532,7 @@
>
> // Iterators
> child_range children() {
> - return child_range(&SubExprs[0],
> - &SubExprs[0] + Array + getNumPlacementArgs()
> - + getNumConstructorArgs());
> + return child_range(raw_arg_begin(), raw_arg_end());
> }
> };
>
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Thu Feb 16 06:22:20 2012
> @@ -3194,9 +3194,7 @@
> MultiExprArg PlacementArgs,
> SourceLocation PlacementRParen,
> SourceRange TypeIdParens, Declarator &D,
> - SourceLocation ConstructorLParen,
> - MultiExprArg ConstructorArgs,
> - SourceLocation ConstructorRParen);
> + Expr *Initializer);
> ExprResult BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
> SourceLocation PlacementLParen,
> MultiExprArg PlacementArgs,
> @@ -3205,9 +3203,8 @@
> QualType AllocType,
> TypeSourceInfo *AllocTypeInfo,
> Expr *ArraySize,
> - SourceLocation ConstructorLParen,
> - MultiExprArg ConstructorArgs,
> - SourceLocation ConstructorRParen,
> + SourceRange DirectInitRange,
> + Expr *Initializer,
> bool TypeMayContainAuto = true);
>
> bool CheckAllocatedType(QualType AllocType, SourceLocation Loc,
>
> Modified: cfe/trunk/lib/AST/Expr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/Expr.cpp (original)
> +++ cfe/trunk/lib/AST/Expr.cpp Thu Feb 16 06:22:20 2012
> @@ -2041,10 +2041,7 @@
> if (isTypeDependent())
> CT = CT_Dependent;
> else
> - CT = MergeCanThrow(
> - CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getOperatorNew()),
> - CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getConstructor(),
> - /*NullThrows*/false));
> + CT = CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getOperatorNew());
> if (CT == CT_Can)
> return CT;
> return MergeCanThrow(CT, CanSubExprsThrow(C, this));
>
> Modified: cfe/trunk/lib/AST/ExprCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ExprCXX.cpp (original)
> +++ cfe/trunk/lib/AST/ExprCXX.cpp Thu Feb 16 06:22:20 2012
> @@ -45,30 +45,26 @@
>
> // CXXNewExpr
> CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
> - Expr **placementArgs, unsigned numPlaceArgs,
> - SourceRange TypeIdParens, Expr *arraySize,
> - CXXConstructorDecl *constructor, bool initializer,
> - Expr **constructorArgs, unsigned numConsArgs,
> - bool HadMultipleCandidates,
> FunctionDecl *operatorDelete,
> - bool usualArrayDeleteWantsSize, QualType ty,
> - TypeSourceInfo *AllocatedTypeInfo,
> - SourceLocation startLoc, SourceLocation endLoc,
> - SourceLocation constructorLParen,
> - SourceLocation constructorRParen)
> + bool usualArrayDeleteWantsSize,
> + Expr **placementArgs, unsigned numPlaceArgs,
> + SourceRange typeIdParens, Expr *arraySize,
> + InitializationStyle initializationStyle,
> + Expr *initializer, QualType ty,
> + TypeSourceInfo *allocatedTypeInfo,
> + SourceLocation startLoc, SourceRange directInitRange)
> : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary,
> ty->isDependentType(), ty->isDependentType(),
> ty->isInstantiationDependentType(),
> ty->containsUnexpandedParameterPack()),
> - GlobalNew(globalNew), Initializer(initializer),
> - UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize),
> - HadMultipleCandidates(HadMultipleCandidates),
> - SubExprs(0), OperatorNew(operatorNew),
> - OperatorDelete(operatorDelete), Constructor(constructor),
> - AllocatedTypeInfo(AllocatedTypeInfo), TypeIdParens(TypeIdParens),
> - StartLoc(startLoc), EndLoc(endLoc), ConstructorLParen(constructorLParen),
> - ConstructorRParen(constructorRParen) {
> - AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs);
> + GlobalNew(globalNew), UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize),
> + SubExprs(0), OperatorNew(operatorNew), OperatorDelete(operatorDelete),
> + AllocatedTypeInfo(allocatedTypeInfo), TypeIdParens(typeIdParens),
> + StartLoc(startLoc), DirectInitRange(directInitRange) {
> + assert((initializer != 0 || initializationStyle == NoInit) &&
> + "Only NoInit can have no initializer.");
> + StoredInitializationStyle = initializer ? initializationStyle + 1 : 0;
> + AllocateArgsArray(C, arraySize != 0, numPlaceArgs, initializer != 0);
> unsigned i = 0;
> if (Array) {
> if (arraySize->isInstantiationDependent())
> @@ -80,33 +76,33 @@
> SubExprs[i++] = arraySize;
> }
>
> - for (unsigned j = 0; j < NumPlacementArgs; ++j) {
> - if (placementArgs[j]->isInstantiationDependent())
> + if (initializer) {
> + if (initializer->isInstantiationDependent())
> ExprBits.InstantiationDependent = true;
> - if (placementArgs[j]->containsUnexpandedParameterPack())
> +
> + if (initializer->containsUnexpandedParameterPack())
> ExprBits.ContainsUnexpandedParameterPack = true;
>
> - SubExprs[i++] = placementArgs[j];
> + SubExprs[i++] = initializer;
> }
>
> - for (unsigned j = 0; j < NumConstructorArgs; ++j) {
> - if (constructorArgs[j]->isInstantiationDependent())
> + for (unsigned j = 0; j < NumPlacementArgs; ++j) {
> + if (placementArgs[j]->isInstantiationDependent())
> ExprBits.InstantiationDependent = true;
> - if (constructorArgs[j]->containsUnexpandedParameterPack())
> + if (placementArgs[j]->containsUnexpandedParameterPack())
> ExprBits.ContainsUnexpandedParameterPack = true;
>
> - SubExprs[i++] = constructorArgs[j];
> + SubExprs[i++] = placementArgs[j];
> }
> }
>
> void CXXNewExpr::AllocateArgsArray(ASTContext &C, bool isArray,
> - unsigned numPlaceArgs, unsigned numConsArgs){
> + unsigned numPlaceArgs, bool hasInitializer){
> assert(SubExprs == 0 && "SubExprs already allocated");
> Array = isArray;
> NumPlacementArgs = numPlaceArgs;
> - NumConstructorArgs = numConsArgs;
> -
> - unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
> +
> + unsigned TotalSize = Array + hasInitializer + NumPlacementArgs;
> SubExprs = new (C) Stmt*[TotalSize];
> }
>
> @@ -115,6 +111,17 @@
> castAs<FunctionProtoType>()->isNothrow(Ctx);
> }
>
> +SourceLocation CXXNewExpr::getEndLoc() const {
> + switch (getInitializationStyle()) {
> + case NoInit:
> + return AllocatedTypeInfo->getTypeLoc().getEndLoc();
> + case CallInit:
> + return DirectInitRange.getEnd();
> + case ListInit:
> + return getInitializer()->getSourceRange().getEnd();
> + }
> +}
> +
> // CXXDeleteExpr
> QualType CXXDeleteExpr::getDestroyedType() const {
> const Expr *Arg = getArgument();
>
> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Thu Feb 16 06:22:20 2012
> @@ -2351,10 +2351,20 @@
> Out << '_';
> mangleType(New->getAllocatedType());
> if (New->hasInitializer()) {
> + // FIXME: Does this mean "parenthesized initializer"?
> Out << "pi";
> - for (CXXNewExpr::const_arg_iterator I = New->constructor_arg_begin(),
> - E = New->constructor_arg_end(); I != E; ++I)
> - mangleExpression(*I);
> + const Expr *Init = New->getInitializer();
> + if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init)) {
> + // Directly inline the initializers.
> + for (CXXConstructExpr::const_arg_iterator I = CCE->arg_begin(),
> + E = CCE->arg_end();
> + I != E; ++I)
> + mangleExpression(*I);
> + } else if (const ParenListExpr *PLE = dyn_cast<ParenListExpr>(Init)) {
> + for (unsigned i = 0, e = PLE->getNumExprs(); i != e; ++i)
> + mangleExpression(PLE->getExpr(i));
> + } else
> + mangleExpression(Init);
> }
> Out << 'E';
> break;
>
> Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
> +++ cfe/trunk/lib/AST/StmtPrinter.cpp Thu Feb 16 06:22:20 2012
> @@ -1390,17 +1390,13 @@
> if (E->isParenTypeId())
> OS << ")";
>
> - if (E->hasInitializer()) {
> - OS << "(";
> - unsigned NumCons = E->getNumConstructorArgs();
> - if (NumCons > 0) {
> - PrintExpr(E->getConstructorArg(0));
> - for (unsigned i = 1; i < NumCons; ++i) {
> - OS << ", ";
> - PrintExpr(E->getConstructorArg(i));
> - }
> - }
> - OS << ")";
> + CXXNewExpr::InitializationStyle InitStyle = E->getInitializationStyle();
> + if (InitStyle) {
> + if (InitStyle == CXXNewExpr::CallInit)
> + OS << "(";
> + PrintExpr(E->getInitializer());
> + if (InitStyle == CXXNewExpr::CallInit)
> + OS << ")";
> }
> }
>
>
> Modified: cfe/trunk/lib/AST/StmtProfile.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/StmtProfile.cpp (original)
> +++ cfe/trunk/lib/AST/StmtProfile.cpp Thu Feb 16 06:22:20 2012
> @@ -825,13 +825,11 @@
> VisitType(S->getAllocatedType());
> VisitDecl(S->getOperatorNew());
> VisitDecl(S->getOperatorDelete());
> - VisitDecl(S->getConstructor());
> ID.AddBoolean(S->isArray());
> ID.AddInteger(S->getNumPlacementArgs());
> ID.AddBoolean(S->isGlobalNew());
> ID.AddBoolean(S->isParenTypeId());
> - ID.AddBoolean(S->hasInitializer());
> - ID.AddInteger(S->getNumConstructorArgs());
> + ID.AddInteger(S->getInitializationStyle());
> }
>
> void
>
> Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Thu Feb 16 06:22:20 2012
> @@ -743,11 +743,8 @@
>
> static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const CXXNewExpr *E,
> llvm::Value *NewPtr) {
> -
> - assert(E->getNumConstructorArgs() == 1 &&
> - "Can only have one argument to initializer of POD type.");
> -
> - const Expr *Init = E->getConstructorArg(0);
> +
> + const Expr *Init = E->getInitializer();
> QualType AllocType = E->getAllocatedType();
>
> CharUnits Alignment = CGF.getContext().getTypeAlignInChars(AllocType);
> @@ -773,9 +770,8 @@
> QualType elementType,
> llvm::Value *beginPtr,
> llvm::Value *numElements) {
> - // We have a POD type.
> - if (E->getNumConstructorArgs() == 0)
> - return;
> + if (!E->hasInitializer())
> + return; // We have a POD type.
>
> // Check if the number of elements is constant.
> bool checkZero = true;
> @@ -858,13 +854,15 @@
> llvm::Value *NewPtr,
> llvm::Value *NumElements,
> llvm::Value *AllocSizeWithoutCookie) {
> + const Expr *Init = E->getInitializer();
> if (E->isArray()) {
> - if (CXXConstructorDecl *Ctor = E->getConstructor()) {
> + if (const CXXConstructExpr *CCE = dyn_cast_or_null<CXXConstructExpr>(Init)){
> + CXXConstructorDecl *Ctor = CCE->getConstructor();
> bool RequiresZeroInitialization = false;
> if (Ctor->getParent()->hasTrivialDefaultConstructor()) {
> // If new expression did not specify value-initialization, then there
> // is no initialization.
> - if (!E->hasInitializer() || Ctor->getParent()->isEmpty())
> + if (!CCE->requiresZeroInitialization() || Ctor->getParent()->isEmpty())
> return;
>
> if (CGF.CGM.getTypes().isZeroInitializable(ElementType)) {
> @@ -877,43 +875,38 @@
> RequiresZeroInitialization = true;
> }
>
> - CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr,
> - E->constructor_arg_begin(),
> - E->constructor_arg_end(),
> + CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr,
> + CCE->arg_begin(), CCE->arg_end(),
> RequiresZeroInitialization);
> return;
> - } else if (E->getNumConstructorArgs() == 1 &&
> - isa<ImplicitValueInitExpr>(E->getConstructorArg(0)) &&
> + } else if (Init && isa<ImplicitValueInitExpr>(Init) &&
> CGF.CGM.getTypes().isZeroInitializable(ElementType)) {
> // Optimization: since zero initialization will just set the memory
> // to all zeroes, generate a single memset to do it in one shot.
> EmitZeroMemSet(CGF, ElementType, NewPtr, AllocSizeWithoutCookie);
> return;
> - } else {
> - CGF.EmitNewArrayInitializer(E, ElementType, NewPtr, NumElements);
> - return;
> }
> + CGF.EmitNewArrayInitializer(E, ElementType, NewPtr, NumElements);
> + return;
> }
>
> - if (CXXConstructorDecl *Ctor = E->getConstructor()) {
> + if (const CXXConstructExpr *CCE = dyn_cast_or_null<CXXConstructExpr>(Init)) {
> + CXXConstructorDecl *Ctor = CCE->getConstructor();
> // Per C++ [expr.new]p15, if we have an initializer, then we're performing
> // direct initialization. C++ [dcl.init]p5 requires that we
> // zero-initialize storage if there are no user-declared constructors.
> - if (E->hasInitializer() &&
> - !Ctor->getParent()->hasUserDeclaredConstructor() &&
> + if (!Ctor->getParent()->hasUserDeclaredConstructor() &&
> !Ctor->getParent()->isEmpty())
> CGF.EmitNullInitialization(NewPtr, ElementType);
> -
> - CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, /*ForVirtualBase=*/false,
> - NewPtr, E->constructor_arg_begin(),
> - E->constructor_arg_end());
>
> + CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, /*ForVirtualBase=*/false,
> + NewPtr, CCE->arg_begin(), CCE->arg_end());
> return;
> }
> // We have a POD type.
> - if (E->getNumConstructorArgs() == 0)
> + if (!Init)
> return;
> -
> +
> StoreAnyExprIntoOneUnit(CGF, E, NewPtr);
> }
>
> @@ -1145,7 +1138,7 @@
> // CXXNewExpr::shouldNullCheckAllocation()) and we have an
> // interesting initializer.
> bool nullCheck = allocatorType->isNothrow(getContext()) &&
> - !(allocType.isPODType(getContext()) && !E->hasInitializer());
> + (!allocType.isPODType(getContext()) || E->hasInitializer());
>
> llvm::BasicBlock *nullCheckBB = 0;
> llvm::BasicBlock *contBB = 0;
> @@ -1211,7 +1204,7 @@
> DeactivateCleanupBlock(operatorDeleteCleanup, cleanupDominator);
> cleanupDominator->eraseFromParent();
> }
> -
> +
> if (nullCheck) {
> conditional.end(*this);
>
>
> Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu Feb 16 06:22:20 2012
> @@ -2193,10 +2193,11 @@
> return ExprError();
> }
>
> - ExprVector ConstructorArgs(Actions);
> - SourceLocation ConstructorLParen, ConstructorRParen;
> + ExprResult Initializer;
>
> if (Tok.is(tok::l_paren)) {
> + SourceLocation ConstructorLParen, ConstructorRParen;
> + ExprVector ConstructorArgs(Actions);
> BalancedDelimiterTracker T(*this, tok::l_paren);
> T.consumeOpen();
> ConstructorLParen = T.getOpenLocation();
> @@ -2213,19 +2214,20 @@
> SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
> return ExprError();
> }
> + Initializer = Actions.ActOnParenListExpr(ConstructorLParen,
> + ConstructorRParen,
> + move_arg(ConstructorArgs));
> } else if (Tok.is(tok::l_brace) && getLang().CPlusPlus0x) {
> Diag(Tok.getLocation(),
> diag::warn_cxx98_compat_generalized_initializer_lists);
> - ExprResult InitList = ParseBraceInitializer();
> - if (InitList.isInvalid())
> - return InitList;
> - ConstructorArgs.push_back(InitList.take());
> + Initializer = ParseBraceInitializer();
> }
> + if (Initializer.isInvalid())
> + return Initializer;
>
> return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
> move_arg(PlacementArgs), PlacementRParen,
> - TypeIdParens, DeclaratorInfo, ConstructorLParen,
> - move_arg(ConstructorArgs), ConstructorRParen);
> + TypeIdParens, DeclaratorInfo, Initializer.take());
> }
>
> /// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Feb 16 06:22:20 2012
> @@ -10148,15 +10148,13 @@
> }
>
> void VisitCXXNewExpr(CXXNewExpr *E) {
> - if (E->getConstructor())
> - S.MarkFunctionReferenced(E->getLocStart(), E->getConstructor());
> if (E->getOperatorNew())
> S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorNew());
> if (E->getOperatorDelete())
> S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorDelete());
> Inherited::VisitCXXNewExpr(E);
> }
> -
> +
> void VisitCXXDeleteExpr(CXXDeleteExpr *E) {
> if (E->getOperatorDelete())
> S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorDelete());
>
> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Feb 16 06:22:20 2012
> @@ -914,9 +914,7 @@
> Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
> SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
> SourceLocation PlacementRParen, SourceRange TypeIdParens,
> - Declarator &D, SourceLocation ConstructorLParen,
> - MultiExprArg ConstructorArgs,
> - SourceLocation ConstructorRParen) {
> + Declarator &D, Expr *Initializer) {
> bool TypeContainsAuto = D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
>
> Expr *ArraySize = 0;
> @@ -961,6 +959,10 @@
> if (D.isInvalidType())
> return ExprError();
>
> + SourceRange DirectInitRange;
> + if (ParenListExpr *List = dyn_cast_or_null<ParenListExpr>(Initializer))
> + DirectInitRange = List->getSourceRange();
> +
> return BuildCXXNew(StartLoc, UseGlobal,
> PlacementLParen,
> move(PlacementArgs),
> @@ -969,12 +971,27 @@
> AllocType,
> TInfo,
> ArraySize,
> - ConstructorLParen,
> - move(ConstructorArgs),
> - ConstructorRParen,
> + DirectInitRange,
> + Initializer,
> TypeContainsAuto);
> }
>
> +static bool isLegalArrayNewInitializer(Expr *Init) {
> + if (!Init)
> + return true;
> + if (ParenListExpr *PLE = dyn_cast<ParenListExpr>(Init)) {
> + if (PLE->getNumExprs() != 1)
> + return PLE->getNumExprs() == 0;
> + Init = PLE->getExpr(0);
> + }
> + if (isa<ImplicitValueInitExpr>(Init))
> + return true;
> + else if (CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init))
> + return !CCE->isListInitialization() &&
> + CCE->getConstructor()->isDefaultConstructor();
> + return false;
> +}
> +
> ExprResult
> Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
> SourceLocation PlacementLParen,
> @@ -984,29 +1001,56 @@
> QualType AllocType,
> TypeSourceInfo *AllocTypeInfo,
> Expr *ArraySize,
> - SourceLocation ConstructorLParen,
> - MultiExprArg ConstructorArgs,
> - SourceLocation ConstructorRParen,
> + SourceRange DirectInitRange,
> + Expr *Initializer,
> bool TypeMayContainAuto) {
> SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange();
>
> + CXXNewExpr::InitializationStyle initStyle;
> + if (DirectInitRange.isValid()) {
> + assert(Initializer && "Have parens but no initializer.");
> + initStyle = CXXNewExpr::CallInit;
> + } else if (Initializer && isa<InitListExpr>(Initializer))
> + initStyle = CXXNewExpr::ListInit;
> + else {
> + assert((!Initializer || isa<ImplicitValueInitExpr>(Initializer) ||
> + isa<CXXConstructExpr>(Initializer)) &&
> + "Initializer expression that cannot have been implicitly created.");
> + initStyle = CXXNewExpr::NoInit;
> + }
> +
> + Expr **Inits = &Initializer;
> + unsigned NumInits = Initializer ? 1 : 0;
> + if (initStyle == CXXNewExpr::CallInit) {
> + if (ParenListExpr *List = dyn_cast<ParenListExpr>(Initializer)) {
> + Inits = List->getExprs();
> + NumInits = List->getNumExprs();
> + } else if (CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Initializer)){
> + if (!isa<CXXTemporaryObjectExpr>(CCE)) {
> + // Can happen in template instantiation. Since this is just an implicit
> + // construction, we just take it apart and rebuild it.
> + Inits = CCE->getArgs();
> + NumInits = CCE->getNumArgs();
> + }
> + }
> + }
> +
> // C++0x [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
> if (TypeMayContainAuto && AllocType->getContainedAutoType()) {
> - if (ConstructorArgs.size() == 0)
> + if (initStyle == CXXNewExpr::NoInit || NumInits == 0)
> return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
> << AllocType << TypeRange);
> - if (ConstructorArgs.size() != 1) {
> - Expr *FirstBad = ConstructorArgs.get()[1];
> + if (initStyle == CXXNewExpr::ListInit)
> + return ExprError(Diag(Inits[0]->getSourceRange().getBegin(),
> + diag::err_auto_new_requires_parens)
> + << AllocType << TypeRange);
> + if (NumInits > 1) {
> + Expr *FirstBad = Inits[1];
> return ExprError(Diag(FirstBad->getSourceRange().getBegin(),
> diag::err_auto_new_ctor_multiple_expressions)
> << AllocType << TypeRange);
> }
> - Expr *Deduce = ConstructorArgs.get()[0];
> - if (ConstructorLParen.isInvalid()) {
> - return ExprError(Diag(Deduce->getSourceRange().getBegin(),
> - diag::err_auto_new_requires_parens)
> - << AllocType << TypeRange);
> - }
> + Expr *Deduce = Inits[0];
> TypeSourceInfo *DeducedType = 0;
> if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) ==
> DAR_Failed)
> @@ -1035,15 +1079,10 @@
> if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange))
> return ExprError();
>
> - bool ListInitialization = ConstructorLParen.isInvalid() &&
> - ConstructorArgs.size() > 0;
> - assert((!ListInitialization || (ConstructorArgs.size() == 1 &&
> - isa<InitListExpr>(ConstructorArgs.get()[0])))
> - && "List initialization means a braced-init-list for arguments.");
> - if (ListInitialization && isStdInitializerList(AllocType, 0)) {
> + if (initStyle == CXXNewExpr::ListInit && isStdInitializerList(AllocType, 0)) {
> Diag(AllocTypeInfo->getTypeLoc().getBeginLoc(),
> diag::warn_dangling_std_initializer_list)
> - << /*at end of FE*/0 << ConstructorArgs.get()[0]->getSourceRange();
> + << /*at end of FE*/0 << Inits[0]->getSourceRange();
> }
>
> // In ARC, infer 'retaining' for the allocated
> @@ -1201,25 +1240,18 @@
> }
> }
>
> - bool Init = ConstructorLParen.isValid() || ConstructorArgs.size() > 0;
> - // --- Choosing a constructor ---
> - CXXConstructorDecl *Constructor = 0;
> - bool HadMultipleCandidates = false;
> - Expr **ConsArgs = (Expr**)ConstructorArgs.get();
> - unsigned NumConsArgs = ConstructorArgs.size();
> - ASTOwningVector<Expr*> ConvertedConstructorArgs(*this);
> -
> - // Array 'new' can't have any initializers.
> - if (NumConsArgs && (ResultType->isArrayType() || ArraySize)) {
> - SourceRange InitRange(ConsArgs[0]->getLocStart(),
> - ConsArgs[NumConsArgs - 1]->getLocEnd());
> + // Array 'new' can't have any initializers except empty parentheses.
> + if (!isLegalArrayNewInitializer(Initializer) &&
> + (ResultType->isArrayType() || ArraySize)) {
> + SourceRange InitRange(Inits[0]->getLocStart(),
> + Inits[NumInits - 1]->getLocEnd());
>
> Diag(StartLoc, diag::err_new_array_init_args) << InitRange;
> return ExprError();
> }
>
> if (!AllocType->isDependentType() &&
> - !Expr::hasAnyTypeDependentArguments(ConsArgs, NumConsArgs)) {
> + !Expr::hasAnyTypeDependentArguments(Inits, NumInits)) {
> // C++11 [expr.new]p15:
> // A new-expression that creates an object of type T initializes that
> // object as follows:
> @@ -1227,49 +1259,31 @@
> // - If the new-initializer is omitted, the object is default-
> // initialized (8.5); if no initialization is performed,
> // the object has indeterminate value
> - = !Init? InitializationKind::CreateDefault(TypeRange.getBegin())
> + = initStyle == CXXNewExpr::NoInit
> + ? InitializationKind::CreateDefault(TypeRange.getBegin())
> // - Otherwise, the new-initializer is interpreted according to the
> // initialization rules of 8.5 for direct-initialization.
> - : ListInitialization ? InitializationKind::CreateDirectList(
> - TypeRange.getBegin())
> - : InitializationKind::CreateDirect(
> - TypeRange.getBegin(),
> - ConstructorLParen,
> - ConstructorRParen);
> + : initStyle == CXXNewExpr::ListInit
> + ? InitializationKind::CreateDirectList(TypeRange.getBegin())
> + : InitializationKind::CreateDirect(TypeRange.getBegin(),
> + DirectInitRange.getBegin(),
> + DirectInitRange.getEnd());
>
> InitializedEntity Entity
> = InitializedEntity::InitializeNew(StartLoc, AllocType);
> - InitializationSequence InitSeq(*this, Entity, Kind, ConsArgs, NumConsArgs);
> + InitializationSequence InitSeq(*this, Entity, Kind, Inits, NumInits);
> ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind,
> - move(ConstructorArgs));
> + MultiExprArg(Inits, NumInits));
> if (FullInit.isInvalid())
> return ExprError();
>
> - // FullInit is our initializer; walk through it to determine if it's a
> - // constructor call, which CXXNewExpr handles directly.
> - if (Expr *FullInitExpr = (Expr *)FullInit.get()) {
> - if (CXXBindTemporaryExpr *Binder
> - = dyn_cast<CXXBindTemporaryExpr>(FullInitExpr))
> - FullInitExpr = Binder->getSubExpr();
> - if (CXXConstructExpr *Construct
> - = dyn_cast<CXXConstructExpr>(FullInitExpr)) {
> - Constructor = Construct->getConstructor();
> - HadMultipleCandidates = Construct->hadMultipleCandidates();
> - for (CXXConstructExpr::arg_iterator A = Construct->arg_begin(),
> - AEnd = Construct->arg_end();
> - A != AEnd; ++A)
> - ConvertedConstructorArgs.push_back(*A);
> - } else {
> - // Take the converted initializer.
> - ConvertedConstructorArgs.push_back(FullInit.release());
> - }
> - } else {
> - // No initialization required.
> - }
> + // FullInit is our initializer; strip off CXXBindTemporaryExprs, because
> + // we don't want the initialized object to be destructed.
> + if (CXXBindTemporaryExpr *Binder =
> + dyn_cast_or_null<CXXBindTemporaryExpr>(FullInit.get()))
> + FullInit = Owned(Binder->getSubExpr());
>
> - // Take the converted arguments and use them for the new expression.
> - NumConsArgs = ConvertedConstructorArgs.size();
> - ConsArgs = (Expr **)ConvertedConstructorArgs.take();
> + Initializer = FullInit.take();
> }
>
> // Mark the new and delete operators as referenced.
> @@ -1281,8 +1295,9 @@
> // C++0x [expr.new]p17:
> // If the new expression creates an array of objects of class type,
> // access and ambiguity control are done for the destructor.
> - if (ArraySize && Constructor) {
> - if (CXXDestructorDecl *dtor = LookupDestructor(Constructor->getParent())) {
> + if (ArraySize && AllocType->isRecordType() && !AllocType->isDependentType()) {
> + if (CXXDestructorDecl *dtor = LookupDestructor(
> + cast<CXXRecordDecl>(AllocType->getAs<RecordType>()->getDecl()))) {
> MarkFunctionReferenced(StartLoc, dtor);
> CheckDestructorAccess(StartLoc, dtor,
> PDiag(diag::err_access_dtor)
> @@ -1291,25 +1306,18 @@
> }
>
> PlacementArgs.release();
> - ConstructorArgs.release();
>
> return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
> - PlaceArgs, NumPlaceArgs, TypeIdParens,
> - ArraySize, Constructor, Init,
> - ConsArgs, NumConsArgs,
> - HadMultipleCandidates,
> OperatorDelete,
> UsualArrayDeleteWantsSize,
> + PlaceArgs, NumPlaceArgs, TypeIdParens,
> + ArraySize, initStyle, Initializer,
> ResultType, AllocTypeInfo,
> - StartLoc,
> - Init ? ConstructorRParen :
> - TypeRange.getEnd(),
> - ConstructorLParen, ConstructorRParen));
> + StartLoc, DirectInitRange));
> }
>
> -/// CheckAllocatedType - Checks that a type is suitable as the allocated type
> +/// \brief Checks that a type is suitable as the allocated type
> /// in a new-expression.
> -/// dimension off and stores the size expression in ArraySize.
> bool Sema::CheckAllocatedType(QualType AllocType, SourceLocation Loc,
> SourceRange R) {
> // C++ 5.3.4p1: "[The] type shall be a complete object type, but not an
>
> Modified: cfe/trunk/lib/Sema/TreeTransform.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
> +++ cfe/trunk/lib/Sema/TreeTransform.h Thu Feb 16 06:22:20 2012
> @@ -1976,9 +1976,8 @@
> QualType AllocatedType,
> TypeSourceInfo *AllocatedTypeInfo,
> Expr *ArraySize,
> - SourceLocation ConstructorLParen,
> - MultiExprArg ConstructorArgs,
> - SourceLocation ConstructorRParen) {
> + SourceRange DirectInitRange,
> + Expr *Initializer) {
> return getSema().BuildCXXNew(StartLoc, UseGlobal,
> PlacementLParen,
> move(PlacementArgs),
> @@ -1987,9 +1986,8 @@
> AllocatedType,
> AllocatedTypeInfo,
> ArraySize,
> - ConstructorLParen,
> - move(ConstructorArgs),
> - ConstructorRParen);
> + DirectInitRange,
> + Initializer);
> }
>
> /// \brief Build a new C++ "delete" expression.
> @@ -7106,29 +7104,17 @@
> if (getDerived().TransformExprs(E->getPlacementArgs(),
> E->getNumPlacementArgs(), true,
> PlacementArgs, &ArgumentChanged))
> - return ExprError();
> + return ExprError();
>
> - // Transform the constructor arguments (if any).
> - // As an annoying corner case, we may have introduced an implicit value-
> - // initialization expression when allocating a new array, which we implicitly
> - // drop. It will be re-created during type checking.
> - ASTOwningVector<Expr*> ConstructorArgs(SemaRef);
> - if (!(E->isArray() && E->getNumConstructorArgs() == 1 &&
> - isa<ImplicitValueInitExpr>(E->getConstructorArgs()[0])) &&
> - TransformExprs(E->getConstructorArgs(), E->getNumConstructorArgs(), true,
> - ConstructorArgs, &ArgumentChanged))
> - return ExprError();
> -
> - // Transform constructor, new operator, and delete operator.
> - CXXConstructorDecl *Constructor = 0;
> - if (E->getConstructor()) {
> - Constructor = cast_or_null<CXXConstructorDecl>(
> - getDerived().TransformDecl(E->getLocStart(),
> - E->getConstructor()));
> - if (!Constructor)
> - return ExprError();
> - }
> + // Transform the initializer (if any).
> + Expr *OldInit = E->getInitializer();
> + ExprResult NewInit;
> + if (OldInit)
> + NewInit = getDerived().TransformExpr(OldInit);
> + if (NewInit.isInvalid())
> + return ExprError();
>
> + // Transform new operator and delete operator.
> FunctionDecl *OperatorNew = 0;
> if (E->getOperatorNew()) {
> OperatorNew = cast_or_null<FunctionDecl>(
> @@ -7150,21 +7136,18 @@
> if (!getDerived().AlwaysRebuild() &&
> AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
> ArraySize.get() == E->getArraySize() &&
> - Constructor == E->getConstructor() &&
> + NewInit.get() == OldInit &&
> OperatorNew == E->getOperatorNew() &&
> OperatorDelete == E->getOperatorDelete() &&
> !ArgumentChanged) {
> // Mark any declarations we need as referenced.
> // FIXME: instantiation-specific.
> - if (Constructor)
> - SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor);
> if (OperatorNew)
> SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorNew);
> if (OperatorDelete)
> SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorDelete);
>
> - if (E->isArray() && Constructor &&
> - !E->getAllocatedType()->isDependentType()) {
> + if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
> QualType ElementType
> = SemaRef.Context.getBaseElementType(E->getAllocatedType());
> if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
> @@ -7174,7 +7157,7 @@
> }
> }
> }
> -
> +
> return SemaRef.Owned(E);
> }
>
> @@ -7204,7 +7187,7 @@
> }
> }
> }
> -
> +
> return getDerived().RebuildCXXNewExpr(E->getLocStart(),
> E->isGlobalNew(),
> /*FIXME:*/E->getLocStart(),
> @@ -7214,9 +7197,8 @@
> AllocType,
> AllocTypeInfo,
> ArraySize.get(),
> - E->getConstructorLParen(),
> - move_arg(ConstructorArgs),
> - E->getConstructorRParen());
> + E->getDirectInitRange(),
> + NewInit.take());
> }
>
> template<typename Derived>
>
> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Thu Feb 16 06:22:20 2012
> @@ -1167,27 +1167,24 @@
> void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
> VisitExpr(E);
> E->GlobalNew = Record[Idx++];
> - E->Initializer = Record[Idx++];
> - E->UsualArrayDeleteWantsSize = Record[Idx++];
> bool isArray = Record[Idx++];
> - E->setHadMultipleCandidates(Record[Idx++]);
> + E->UsualArrayDeleteWantsSize = Record[Idx++];
> unsigned NumPlacementArgs = Record[Idx++];
> - unsigned NumCtorArgs = Record[Idx++];
> + E->StoredInitializationStyle = Record[Idx++];
> E->setOperatorNew(ReadDeclAs<FunctionDecl>(Record, Idx));
> E->setOperatorDelete(ReadDeclAs<FunctionDecl>(Record, Idx));
> - E->setConstructor(ReadDeclAs<CXXConstructorDecl>(Record, Idx));
> E->AllocatedTypeInfo = GetTypeSourceInfo(Record, Idx);
> SourceRange TypeIdParens;
> TypeIdParens.setBegin(ReadSourceLocation(Record, Idx));
> TypeIdParens.setEnd(ReadSourceLocation(Record, Idx));
> E->TypeIdParens = TypeIdParens;
> E->StartLoc = ReadSourceLocation(Record, Idx);
> - E->EndLoc = ReadSourceLocation(Record, Idx);
> - E->ConstructorLParen = ReadSourceLocation(Record, Idx);
> - E->ConstructorRParen = ReadSourceLocation(Record, Idx);
> + SourceRange DirectInitRange;
> + DirectInitRange.setBegin(ReadSourceLocation(Record, Idx));
> + DirectInitRange.setEnd(ReadSourceLocation(Record, Idx));
>
> E->AllocateArgsArray(Reader.getContext(), isArray, NumPlacementArgs,
> - NumCtorArgs);
> + E->StoredInitializationStyle != 0);
>
> // Install all the subexpressions.
> for (CXXNewExpr::raw_arg_iterator I = E->raw_arg_begin(),e = E->raw_arg_end();
>
> Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Thu Feb 16 06:22:20 2012
> @@ -1158,25 +1158,20 @@
> void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
> VisitExpr(E);
> Record.push_back(E->isGlobalNew());
> - Record.push_back(E->hasInitializer());
> - Record.push_back(E->doesUsualArrayDeleteWantSize());
> Record.push_back(E->isArray());
> - Record.push_back(E->hadMultipleCandidates());
> + Record.push_back(E->doesUsualArrayDeleteWantSize());
> Record.push_back(E->getNumPlacementArgs());
> - Record.push_back(E->getNumConstructorArgs());
> + Record.push_back(E->StoredInitializationStyle);
> Writer.AddDeclRef(E->getOperatorNew(), Record);
> Writer.AddDeclRef(E->getOperatorDelete(), Record);
> - Writer.AddDeclRef(E->getConstructor(), Record);
> Writer.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo(), Record);
> Writer.AddSourceRange(E->getTypeIdParens(), Record);
> Writer.AddSourceLocation(E->getStartLoc(), Record);
> - Writer.AddSourceLocation(E->getEndLoc(), Record);
> - Writer.AddSourceLocation(E->getConstructorLParen(), Record);
> - Writer.AddSourceLocation(E->getConstructorRParen(), Record);
> + Writer.AddSourceRange(E->getDirectInitRange(), Record);
> for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end();
> I != e; ++I)
> Writer.AddStmt(*I);
> -
> +
> Code = serialization::EXPR_CXX_NEW;
> }
>
>
> Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
> +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Thu Feb 16 06:22:20 2012
> @@ -268,6 +268,8 @@
> return;
> }
>
> + // FIXME: Update for AST changes.
> +#if 0
> // Evaluate constructor arguments.
> const FunctionProtoType *FnType = NULL;
> const CXXConstructorDecl *CD = CNE->getConstructor();
> @@ -327,6 +329,7 @@
> loc::MemRegionVal(EleReg));
> Bldr.generateNode(CNE, *I, state);
> }
> +#endif
> }
>
> void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE,
>
> Modified: cfe/trunk/test/Analysis/new.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/new.cpp?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/test/Analysis/new.cpp (original)
> +++ cfe/trunk/test/Analysis/new.cpp Thu Feb 16 06:22:20 2012
> @@ -1,4 +1,5 @@
> // RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -verify %s
> +// XFAIL: *
>
> void f1() {
> int *n = new int;
>
> Modified: cfe/trunk/test/SemaCXX/new-delete.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/new-delete.cpp?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/new-delete.cpp (original)
> +++ cfe/trunk/test/SemaCXX/new-delete.cpp Thu Feb 16 06:22:20 2012
> @@ -417,3 +417,32 @@
> };
> void f(A *x) { delete x; } // expected-warning {{delete called on 'PR10504::A' that is abstract but has non-virtual destructor}}
> }
> +
> +struct PlacementArg {};
> +inline void *operator new[](size_t, const PlacementArg &) throw () {
> + return 0;
> +}
> +inline void operator delete[](void *, const PlacementArg &) throw () {
> +}
> +
> +namespace r150682 {
> +
> + template <typename X>
> + struct S {
> + struct Inner {};
> + S() { new Inner[1]; }
> + };
> +
> + struct T {
> + };
> +
> + template<typename X>
> + void tfn() {
> + new (*(PlacementArg*)0) T[1];
> + }
> +
> + void fn() {
> + tfn<int>();
> + }
> +
> +}
>
> Modified: cfe/trunk/tools/libclang/CIndex.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=150685&r1=150684&r2=150685&view=diff
> ==============================================================================
> --- cfe/trunk/tools/libclang/CIndex.cpp (original)
> +++ cfe/trunk/tools/libclang/CIndex.cpp Thu Feb 16 06:22:20 2012
> @@ -1856,9 +1856,8 @@
> AddStmt(E->getBase());
> }
> void EnqueueVisitor::VisitCXXNewExpr(CXXNewExpr *E) {
> - // Enqueue the initializer or constructor arguments.
> - for (unsigned I = E->getNumConstructorArgs(); I > 0; --I)
> - AddStmt(E->getConstructorArg(I-1));
> + // Enqueue the initializer , if any.
> + AddStmt(E->getInitializer());
> // Enqueue the array size, if any.
> AddStmt(E->getArraySize());
> // Enqueue the allocated type.
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list