CXXConstructorDecl *Constructor;
SourceLocation Loc;
+ SourceRange ParenRange;
bool Elidable : 1;
bool ZeroInitialization : 1;
unsigned ConstructKind : 2;
CXXConstructorDecl *d, bool elidable,
Expr **args, unsigned numargs,
bool ZeroInitialization = false,
- ConstructionKind ConstructKind = CK_Complete);
+ ConstructionKind ConstructKind = CK_Complete,
+ SourceRange ParenRange = SourceRange());
/// \brief Construct an empty C++ construction expression.
CXXConstructExpr(StmtClass SC, EmptyShell Empty)
CXXConstructorDecl *D, bool Elidable,
Expr **Args, unsigned NumArgs,
bool ZeroInitialization = false,
- ConstructionKind ConstructKind = CK_Complete);
+ ConstructionKind ConstructKind = CK_Complete,
+ SourceRange ParenRange = SourceRange());
CXXConstructorDecl* getConstructor() const { return Constructor; }
}
virtual SourceRange getSourceRange() const;
+ SourceRange getParenRange() const { return ParenRange; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXConstructExprClass ||
/// };
/// @endcode
class CXXTemporaryObjectExpr : public CXXConstructExpr {
- SourceLocation RParenLoc;
TypeSourceInfo *Type;
public:
CXXTemporaryObjectExpr(ASTContext &C, CXXConstructorDecl *Cons,
TypeSourceInfo *Type,
Expr **Args,unsigned NumArgs,
- SourceLocation rParenLoc,
+ SourceRange parenRange,
bool ZeroInitialization = false);
explicit CXXTemporaryObjectExpr(EmptyShell Empty)
: CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { }
TypeSourceInfo *getTypeSourceInfo() const { return Type; }
- SourceLocation getRParenLoc() const { return RParenLoc; }
virtual SourceRange getSourceRange() const;
SourceLocation StartLoc;
SourceLocation EndLoc;
+ SourceLocation ConstructorLParen;
+ SourceLocation ConstructorRParen;
friend class ASTStmtReader;
public:
Expr **constructorArgs, unsigned numConsArgs,
FunctionDecl *operatorDelete, QualType ty,
TypeSourceInfo *AllocatedTypeInfo,
- SourceLocation startLoc, SourceLocation endLoc);
+ SourceLocation startLoc, SourceLocation endLoc,
+ SourceLocation constructorLParen,
+ SourceLocation constructorRParen);
explicit CXXNewExpr(EmptyShell Shell)
: Expr(CXXNewExprClass, Shell), SubExprs(0) { }
const_arg_iterator raw_arg_begin() const { return SubExprs; }
const_arg_iterator raw_arg_end() const { return constructor_arg_end(); }
-
SourceLocation getStartLoc() const { return StartLoc; }
- void setStartLoc(SourceLocation L) { StartLoc = L; }
SourceLocation getEndLoc() const { return EndLoc; }
- void setEndLoc(SourceLocation L) { EndLoc = L; }
-
+
+ SourceLocation getConstructorLParen() const { return ConstructorLParen; }
+ SourceLocation getConstructorRParen() const { return ConstructorRParen; }
+
virtual SourceRange getSourceRange() const {
return SourceRange(StartLoc, EndLoc);
}
ExprResult
BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
CXXConstructorDecl *Constructor, MultiExprArg Exprs,
- bool RequiresZeroInit, unsigned ConstructKind);
+ bool RequiresZeroInit, unsigned ConstructKind,
+ SourceRange ParenRange);
// FIXME: Can re remove this and have the above BuildCXXConstructExpr check if
// the constructor can be elidable?
BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
CXXConstructorDecl *Constructor, bool Elidable,
MultiExprArg Exprs, bool RequiresZeroInit,
- unsigned ConstructKind);
+ unsigned ConstructKind,
+ SourceRange ParenRange);
/// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
/// the default expr if needed.
Expr **constructorArgs, unsigned numConsArgs,
FunctionDecl *operatorDelete, QualType ty,
TypeSourceInfo *AllocatedTypeInfo,
- SourceLocation startLoc, SourceLocation endLoc)
+ SourceLocation startLoc, SourceLocation endLoc,
+ SourceLocation constructorLParen,
+ SourceLocation constructorRParen)
: Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()),
GlobalNew(globalNew),
Initializer(initializer), SubExprs(0), OperatorNew(operatorNew),
OperatorDelete(operatorDelete), Constructor(constructor),
AllocatedTypeInfo(AllocatedTypeInfo), TypeIdParens(TypeIdParens),
- StartLoc(startLoc), EndLoc(endLoc) {
-
+ StartLoc(startLoc), EndLoc(endLoc), ConstructorLParen(constructorLParen),
+ ConstructorRParen(constructorRParen) {
AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs);
unsigned i = 0;
if (Array)
return child_iterator();
}
-SourceRange CXXConstructExpr::getSourceRange() const {
- // FIXME: Should we know where the parentheses are, if there are any?
- for (std::reverse_iterator<Stmt**> I(&Args[NumArgs]), E(&Args[0]); I!=E;++I) {
- // Ignore CXXDefaultExprs when computing the range, as they don't
- // have a range.
- if (!isa<CXXDefaultArgExpr>(*I))
- return SourceRange(Loc, (*I)->getLocEnd());
- }
-
- return SourceRange(Loc);
+SourceRange CXXConstructExpr::getSourceRange() const {
+ return ParenRange.isValid() ?
+ SourceRange(Loc, ParenRange.getEnd()) :
+ SourceRange(Loc);
}
SourceRange CXXOperatorCallExpr::getSourceRange() const {
TypeSourceInfo *Type,
Expr **Args,
unsigned NumArgs,
- SourceLocation rParenLoc,
+ SourceRange parenRange,
bool ZeroInitialization)
: CXXConstructExpr(C, CXXTemporaryObjectExprClass,
Type->getType().getNonReferenceType(),
Type->getTypeLoc().getBeginLoc(),
- Cons, false, Args, NumArgs, ZeroInitialization),
- RParenLoc(rParenLoc), Type(Type) {
+ Cons, false, Args, NumArgs, ZeroInitialization,
+ CXXConstructExpr::CK_Complete, parenRange),
+ Type(Type) {
}
SourceRange CXXTemporaryObjectExpr::getSourceRange() const {
- return SourceRange(Type->getTypeLoc().getBeginLoc(), RParenLoc);
+ return SourceRange(Type->getTypeLoc().getBeginLoc(),
+ getParenRange().getEnd());
}
CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T,
CXXConstructorDecl *D, bool Elidable,
Expr **Args, unsigned NumArgs,
bool ZeroInitialization,
- ConstructionKind ConstructKind) {
+ ConstructionKind ConstructKind,
+ SourceRange ParenRange) {
return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D,
Elidable, Args, NumArgs, ZeroInitialization,
- ConstructKind);
+ ConstructKind, ParenRange);
}
CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
CXXConstructorDecl *D, bool elidable,
Expr **args, unsigned numargs,
bool ZeroInitialization,
- ConstructionKind ConstructKind)
+ ConstructionKind ConstructKind,
+ SourceRange ParenRange)
: Expr(SC, T,
T->isDependentType(),
(T->isDependentType() ||
CallExpr::hasAnyValueDependentArguments(args, numargs))),
- Constructor(D), Loc(Loc), Elidable(elidable),
+ Constructor(D), Loc(Loc), ParenRange(ParenRange), Elidable(elidable),
ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind),
Args(0), NumArgs(numargs)
{
CXXConstructorDecl *Constructor,
MultiExprArg ExprArgs,
bool RequiresZeroInit,
- unsigned ConstructKind) {
+ unsigned ConstructKind,
+ SourceRange ParenRange) {
bool Elidable = false;
// C++0x [class.copy]p34:
return BuildCXXConstructExpr(ConstructLoc, DeclInitType, Constructor,
Elidable, move(ExprArgs), RequiresZeroInit,
- ConstructKind);
+ ConstructKind, ParenRange);
}
/// BuildCXXConstructExpr - Creates a complete call to a constructor,
CXXConstructorDecl *Constructor, bool Elidable,
MultiExprArg ExprArgs,
bool RequiresZeroInit,
- unsigned ConstructKind) {
+ unsigned ConstructKind,
+ SourceRange ParenRange) {
unsigned NumExprs = ExprArgs.size();
Expr **Exprs = (Expr **)ExprArgs.release();
return Owned(CXXConstructExpr::Create(Context, DeclInitType, ConstructLoc,
Constructor, Elidable, Exprs, NumExprs,
RequiresZeroInit,
- static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind)));
+ static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind),
+ ParenRange));
}
bool Sema::InitializeVarWithConstructor(VarDecl *VD,
CXXConstructorDecl *Constructor,
MultiExprArg Exprs) {
+ // FIXME: Provide the correct paren SourceRange when available.
ExprResult TempResult =
BuildCXXConstructExpr(VD->getLocation(), VD->getType(), Constructor,
- move(Exprs), false, CXXConstructExpr::CK_Complete);
+ move(Exprs), false, CXXConstructExpr::CK_Complete,
+ SourceRange());
if (TempResult.isInvalid())
return true;
ResultType, AllocTypeInfo,
StartLoc,
Init ? ConstructorRParen :
- TypeRange.getEnd()));
+ TypeRange.getEnd(),
+ ConstructorLParen, ConstructorRParen));
}
/// CheckAllocatedType - Checks that a type is suitable as the allocated type
ExprResult Result =
S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method),
move_arg(ConstructorArgs),
- /*ZeroInit*/ false, CXXConstructExpr::CK_Complete);
+ /*ZeroInit*/ false, CXXConstructExpr::CK_Complete,
+ SourceRange());
if (Result.isInvalid())
return ExprError();
ToType, SCS.CopyConstructor,
move_arg(ConstructorArgs),
/*ZeroInit*/ false,
- CXXConstructExpr::CK_Complete);
+ CXXConstructExpr::CK_Complete,
+ SourceRange());
if (FromResult.isInvalid())
return true;
From = FromResult.takeAs<Expr>();
ToType, SCS.CopyConstructor,
MultiExprArg(*this, &From, 1),
/*ZeroInit*/ false,
- CXXConstructExpr::CK_Complete);
+ CXXConstructExpr::CK_Complete,
+ SourceRange());
if (FromResult.isInvalid())
return true;
CurInit = S.BuildCXXConstructExpr(Loc, T, Constructor, Elidable,
move_arg(ConstructorArgs),
/*ZeroInit*/ false,
- CXXConstructExpr::CK_Complete);
+ CXXConstructExpr::CK_Complete,
+ SourceRange());
// If we're supposed to bind temporaries, do so.
if (!CurInit.isInvalid() && shouldBindAsTemporary(Entity))
CurInit = S.BuildCXXConstructExpr(Loc, Step->Type, Constructor,
move_arg(ConstructorArgs),
/*ZeroInit*/ false,
- CXXConstructExpr::CK_Complete);
+ CXXConstructExpr::CK_Complete,
+ SourceRange());
if (CurInit.isInvalid())
return ExprError();
TSInfo,
Exprs,
NumExprs,
- Kind.getParenRange().getEnd(),
+ Kind.getParenRange(),
ConstructorInitRequiresZeroInit));
} else {
CXXConstructExpr::ConstructionKind ConstructKind =
CXXConstructExpr::CK_NonVirtualBase;
}
+ // Only get the parenthesis range if it is a direct construction.
+ SourceRange parenRange =
+ Kind.getKind() == InitializationKind::IK_Direct ?
+ Kind.getParenRange() : SourceRange();
+
// If the entity allows NRVO, mark the construction as elidable
// unconditionally.
if (Entity.allowsNRVO())
Constructor, /*Elidable=*/true,
move_arg(ConstructorArgs),
ConstructorInitRequiresZeroInit,
- ConstructKind);
+ ConstructKind,
+ parenRange);
else
CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
Constructor,
move_arg(ConstructorArgs),
ConstructorInitRequiresZeroInit,
- ConstructKind);
+ ConstructKind,
+ parenRange);
}
if (CurInit.isInvalid())
return ExprError();
bool IsElidable,
MultiExprArg Args,
bool RequiresZeroInit,
- CXXConstructExpr::ConstructionKind ConstructKind) {
+ CXXConstructExpr::ConstructionKind ConstructKind,
+ SourceRange ParenRange) {
ASTOwningVector<Expr*> ConvertedArgs(SemaRef);
if (getSema().CompleteConstructorCall(Constructor, move(Args), Loc,
ConvertedArgs))
return getSema().BuildCXXConstructExpr(Loc, T, Constructor, IsElidable,
move_arg(ConvertedArgs),
- RequiresZeroInit, ConstructKind);
+ RequiresZeroInit, ConstructKind,
+ ParenRange);
}
/// \brief Build a new object-construction expression.
Constructor, E->isElidable(),
move_arg(Args),
E->requiresZeroInitialization(),
- E->getConstructionKind());
+ E->getConstructionKind(),
+ E->getParenRange());
}
/// \brief Transform a C++ temporary-binding expression.
E->setElidable(Record[Idx++]);
E->setRequiresZeroInitialization(Record[Idx++]);
E->setConstructionKind((CXXConstructExpr::ConstructionKind)Record[Idx++]);
+ E->ParenRange = ReadSourceRange(Record, Idx);
}
void ASTStmtReader::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
VisitCXXConstructExpr(E);
E->Type = GetTypeSourceInfo(Record, Idx);
- E->RParenLoc = ReadSourceLocation(Record, Idx);
}
void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
TypeIdParens.setBegin(ReadSourceLocation(Record, Idx));
TypeIdParens.setEnd(ReadSourceLocation(Record, Idx));
E->TypeIdParens = TypeIdParens;
- E->setStartLoc(ReadSourceLocation(Record, Idx));
- E->setEndLoc(ReadSourceLocation(Record, Idx));
-
+ E->StartLoc = ReadSourceLocation(Record, Idx);
+ E->EndLoc = ReadSourceLocation(Record, Idx);
+ E->ConstructorLParen = ReadSourceLocation(Record, Idx);
+ E->ConstructorRParen = ReadSourceLocation(Record, Idx);
+
E->AllocateArgsArray(*Reader.getContext(), isArray, NumPlacementArgs,
NumCtorArgs);
Record.push_back(E->isElidable());
Record.push_back(E->requiresZeroInitialization());
Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
+ Writer.AddSourceRange(E->getParenRange(), Record);
Code = serialization::EXPR_CXX_CONSTRUCT;
}
void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
VisitCXXConstructExpr(E);
Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
- Writer.AddSourceLocation(E->getRParenLoc(), Record);
Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
}
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);
for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end();
I != e; ++I)
Writer.AddStmt(*I);
// CHECK: load-stmts.cpp:104:5: MemberRef=member:100:7 Extent=[104:5 - 104:11]
// CHECK: load-stmts.cpp:104:12: DeclRefExpr=x:103:22 Extent=[104:12 - 104:13]
// CHECK: load-stmts.cpp:104:16: TypeRef=struct Base:94:8 Extent=[104:16 - 104:2
-// CHECK: load-stmts.cpp:104:16: CallExpr= Extent=[104:16 - 104:22]
+// CHECK: load-stmts.cpp:104:16: CallExpr= Extent=[104:16 - 104:23]
// CHECK: load-stmts.cpp:104:21: DeclRefExpr=x:103:22 Extent=[104:21 - 104:22]
// CHECK: load-stmts.cpp:107:6: FunctionDecl=considered_harmful:107:6 (Definition)
// CHECK: load-stmts.cpp:108:2: LabelStmt=start_over Extent=[108:2 - 109:28]