aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2012-02-16 10:58:10 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2012-02-16 10:58:10 +0000
commit5f688f4b15d02aa7ad159c46b1f78fe59d412f12 (patch)
tree8b67f7660948832957b76569958a3bda8d15fe75 /include/clang
parent13ca53473fd98520b236fb2dbfce228007ac4bed (diff)
Make CXXNewExpr contain only a single initialier, and not hold the used constructor itself.
Holding the constructor directly makes no sense when list-initialized arrays come into play. The constructor is now held in a CXXConstructExpr, if construction is what is done. The new design can also distinguish properly between list-initialization and direct-initialization, as well as implicit default-initialization constructors and explicit value-initialization constructors. Finally, doing it this way removes redundance from the AST because CXXNewExpr doesn't try to handle both the allocation and the initialization responsibilities. This breaks the static analysis of new expressions. I've filed PR12014 to track this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150682 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/ExprCXX.h135
-rw-r--r--include/clang/Sema/Sema.h9
2 files changed, 58 insertions, 86 deletions
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index c305faa8a9..458c96f3b5 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -1359,34 +1359,24 @@ public:
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 @@ class CXXNewExpr : public Expr {
/// 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 @@ public:
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,96 +1448,81 @@ public:
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; }
-
- /// 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;
- }
- unsigned getNumConstructorArgs() const { return NumConstructorArgs; }
+ /// \brief Whether this new-expression has any initializer at all.
+ bool hasInitializer() const { return StoredInitializationStyle > 0; }
- Expr **getConstructorArgs() {
- return reinterpret_cast<Expr **>(SubExprs + Array + NumPlacementArgs);
+ /// \brief The kind of initializer this new-expression has.
+ InitializationStyle getInitializationStyle() const {
+ if (StoredInitializationStyle == 0)
+ return NoInit;
+ return static_cast<InitializationStyle>(StoredInitializationStyle-1);
}
- Expr *getConstructorArg(unsigned i) {
- assert(i < NumConstructorArgs && "Index out of range");
- return cast<Expr>(SubExprs[Array + NumPlacementArgs + i]);
+ /// \brief The initializer of this new-expression.
+ Expr *getInitializer() {
+ return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
}
- const Expr *getConstructorArg(unsigned i) const {
- assert(i < NumConstructorArgs && "Index out of range");
- return cast<Expr>(SubExprs[Array + NumPlacementArgs + i]);
+ const Expr *getInitializer() const {
+ return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
}
- /// \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; }
+ /// 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;
+ }
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 @@ public:
// Iterators
child_range children() {
- return child_range(&SubExprs[0],
- &SubExprs[0] + Array + getNumPlacementArgs()
- + getNumConstructorArgs());
+ return child_range(raw_arg_begin(), raw_arg_end());
}
};
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 018acdcab4..1ef4ac67dd 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -3194,9 +3194,7 @@ public:
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 @@ public:
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,