Add the location of the right parenthesis of a C++ named cast

(static_cast, dynamic_cast, reinterpret_cast, or const_cast) to
improve source-location information. Fixes PR8960.

llvm-svn: 123336
This commit is contained in:
Douglas Gregor 2011-01-12 22:41:29 +00:00
parent 1a3534afc4
commit 4478f858b5
6 changed files with 61 additions and 31 deletions

View File

@ -126,26 +126,33 @@ public:
class CXXNamedCastExpr : public ExplicitCastExpr {
private:
SourceLocation Loc; // the location of the casting op
SourceLocation RParenLoc; // the location of the right parenthesis
protected:
CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK,
CastKind kind, Expr *op, unsigned PathSize,
TypeSourceInfo *writtenTy, SourceLocation l)
: ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l) {}
TypeSourceInfo *writtenTy, SourceLocation l,
SourceLocation RParenLoc)
: ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l),
RParenLoc(RParenLoc) {}
explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
: ExplicitCastExpr(SC, Shell, PathSize) { }
friend class ASTStmtReader;
public:
const char *getCastName() const;
/// \brief Retrieve the location of the cast operator keyword, e.g.,
/// "static_cast".
SourceLocation getOperatorLoc() const { return Loc; }
void setOperatorLoc(SourceLocation L) { Loc = L; }
/// \brief Retrieve the location of the closing parenthesis.
SourceLocation getRParenLoc() const { return RParenLoc; }
virtual SourceRange getSourceRange() const {
return SourceRange(Loc, getSubExpr()->getSourceRange().getEnd());
return SourceRange(Loc, RParenLoc);
}
static bool classof(const Stmt *T) {
switch (T->getStmtClass()) {
@ -168,9 +175,9 @@ public:
class CXXStaticCastExpr : public CXXNamedCastExpr {
CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
unsigned pathSize, TypeSourceInfo *writtenTy,
SourceLocation l)
SourceLocation l, SourceLocation RParenLoc)
: CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize,
writtenTy, l) {}
writtenTy, l, RParenLoc) {}
explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)
: CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) { }
@ -179,7 +186,8 @@ public:
static CXXStaticCastExpr *Create(ASTContext &Context, QualType T,
ExprValueKind VK, CastKind K, Expr *Op,
const CXXCastPath *Path,
TypeSourceInfo *Written, SourceLocation L);
TypeSourceInfo *Written, SourceLocation L,
SourceLocation RParenLoc);
static CXXStaticCastExpr *CreateEmpty(ASTContext &Context,
unsigned PathSize);
@ -198,9 +206,9 @@ public:
class CXXDynamicCastExpr : public CXXNamedCastExpr {
CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind,
Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy,
SourceLocation l)
SourceLocation l, SourceLocation RParenLoc)
: CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize,
writtenTy, l) {}
writtenTy, l, RParenLoc) {}
explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
: CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) { }
@ -209,7 +217,8 @@ public:
static CXXDynamicCastExpr *Create(ASTContext &Context, QualType T,
ExprValueKind VK, CastKind Kind, Expr *Op,
const CXXCastPath *Path,
TypeSourceInfo *Written, SourceLocation L);
TypeSourceInfo *Written, SourceLocation L,
SourceLocation RParenLoc);
static CXXDynamicCastExpr *CreateEmpty(ASTContext &Context,
unsigned pathSize);
@ -229,9 +238,10 @@ public:
class CXXReinterpretCastExpr : public CXXNamedCastExpr {
CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind,
Expr *op, unsigned pathSize,
TypeSourceInfo *writtenTy, SourceLocation l)
TypeSourceInfo *writtenTy, SourceLocation l,
SourceLocation RParenLoc)
: CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op,
pathSize, writtenTy, l) {}
pathSize, writtenTy, l, RParenLoc) {}
CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
: CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) { }
@ -240,7 +250,8 @@ public:
static CXXReinterpretCastExpr *Create(ASTContext &Context, QualType T,
ExprValueKind VK, CastKind Kind,
Expr *Op, const CXXCastPath *Path,
TypeSourceInfo *WrittenTy, SourceLocation L);
TypeSourceInfo *WrittenTy, SourceLocation L,
SourceLocation RParenLoc);
static CXXReinterpretCastExpr *CreateEmpty(ASTContext &Context,
unsigned pathSize);
@ -257,9 +268,10 @@ public:
/// @c const_cast<char*>(PtrToConstChar).
class CXXConstCastExpr : public CXXNamedCastExpr {
CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,
TypeSourceInfo *writtenTy, SourceLocation l)
TypeSourceInfo *writtenTy, SourceLocation l,
SourceLocation RParenLoc)
: CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op,
0, writtenTy, l) {}
0, writtenTy, l, RParenLoc) {}
explicit CXXConstCastExpr(EmptyShell Empty)
: CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) { }
@ -267,7 +279,8 @@ class CXXConstCastExpr : public CXXNamedCastExpr {
public:
static CXXConstCastExpr *Create(ASTContext &Context, QualType T,
ExprValueKind VK, Expr *Op,
TypeSourceInfo *WrittenTy, SourceLocation L);
TypeSourceInfo *WrittenTy, SourceLocation L,
SourceLocation RParenLoc);
static CXXConstCastExpr *CreateEmpty(ASTContext &Context);
static bool classof(const Stmt *T) {

View File

@ -525,12 +525,14 @@ CXXStaticCastExpr *CXXStaticCastExpr::Create(ASTContext &C, QualType T,
CastKind K, Expr *Op,
const CXXCastPath *BasePath,
TypeSourceInfo *WrittenTy,
SourceLocation L) {
SourceLocation L,
SourceLocation RParenLoc) {
unsigned PathSize = (BasePath ? BasePath->size() : 0);
void *Buffer = C.Allocate(sizeof(CXXStaticCastExpr)
+ PathSize * sizeof(CXXBaseSpecifier*));
CXXStaticCastExpr *E =
new (Buffer) CXXStaticCastExpr(T, VK, K, Op, PathSize, WrittenTy, L);
new (Buffer) CXXStaticCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,
RParenLoc);
if (PathSize) E->setCastPath(*BasePath);
return E;
}
@ -547,12 +549,14 @@ CXXDynamicCastExpr *CXXDynamicCastExpr::Create(ASTContext &C, QualType T,
CastKind K, Expr *Op,
const CXXCastPath *BasePath,
TypeSourceInfo *WrittenTy,
SourceLocation L) {
SourceLocation L,
SourceLocation RParenLoc) {
unsigned PathSize = (BasePath ? BasePath->size() : 0);
void *Buffer = C.Allocate(sizeof(CXXDynamicCastExpr)
+ PathSize * sizeof(CXXBaseSpecifier*));
CXXDynamicCastExpr *E =
new (Buffer) CXXDynamicCastExpr(T, VK, K, Op, PathSize, WrittenTy, L);
new (Buffer) CXXDynamicCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,
RParenLoc);
if (PathSize) E->setCastPath(*BasePath);
return E;
}
@ -568,12 +572,14 @@ CXXReinterpretCastExpr *
CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK,
CastKind K, Expr *Op,
const CXXCastPath *BasePath,
TypeSourceInfo *WrittenTy, SourceLocation L) {
TypeSourceInfo *WrittenTy, SourceLocation L,
SourceLocation RParenLoc) {
unsigned PathSize = (BasePath ? BasePath->size() : 0);
void *Buffer =
C.Allocate(sizeof(CXXReinterpretCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
CXXReinterpretCastExpr *E =
new (Buffer) CXXReinterpretCastExpr(T, VK, K, Op, PathSize, WrittenTy, L);
new (Buffer) CXXReinterpretCastExpr(T, VK, K, Op, PathSize, WrittenTy, L,
RParenLoc);
if (PathSize) E->setCastPath(*BasePath);
return E;
}
@ -588,8 +594,9 @@ CXXReinterpretCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
CXXConstCastExpr *CXXConstCastExpr::Create(ASTContext &C, QualType T,
ExprValueKind VK, Expr *Op,
TypeSourceInfo *WrittenTy,
SourceLocation L) {
return new (C) CXXConstCastExpr(T, VK, Op, WrittenTy, L);
SourceLocation L,
SourceLocation RParenLoc) {
return new (C) CXXConstCastExpr(T, VK, Op, WrittenTy, L, RParenLoc);
}
CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) {

View File

@ -172,7 +172,8 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
CheckConstCast(*this, Ex, DestType, VK, OpRange, DestRange);
return Owned(CXXConstCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
VK, Ex, DestTInfo, OpLoc));
VK, Ex, DestTInfo, OpLoc,
Parens.getEnd()));
case tok::kw_dynamic_cast: {
CastKind Kind = CK_Dependent;
@ -183,7 +184,7 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
return Owned(CXXDynamicCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
VK, Kind, Ex, &BasePath, DestTInfo,
OpLoc));
OpLoc, Parens.getEnd()));
}
case tok::kw_reinterpret_cast: {
CastKind Kind = CK_Dependent;
@ -192,7 +193,7 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
return Owned(CXXReinterpretCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
VK, Kind, Ex, 0,
DestTInfo, OpLoc));
DestTInfo, OpLoc, Parens.getEnd()));
}
case tok::kw_static_cast: {
CastKind Kind = CK_Dependent;
@ -203,7 +204,7 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
return Owned(CXXStaticCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
VK, Kind, Ex, &BasePath,
DestTInfo, OpLoc));
DestTInfo, OpLoc, Parens.getEnd()));
}
}

View File

@ -1006,7 +1006,9 @@ void ASTStmtReader::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
VisitExplicitCastExpr(E);
E->setOperatorLoc(ReadSourceLocation(Record, Idx));
SourceRange R = ReadSourceRange(Record, Idx);
E->Loc = R.getBegin();
E->RParenLoc = R.getEnd();
}
void ASTStmtReader::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {

View File

@ -984,7 +984,8 @@ void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
VisitExplicitCastExpr(E);
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
Writer.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()),
Record);
}
void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {

View File

@ -113,6 +113,10 @@ void considered_harmful(int x) {
goto start_over;
}
void casts(int *ip) {
(void)reinterpret_cast<float *>(ip);
}
// RUN: c-index-test -test-load-source all %s | FileCheck %s
// CHECK: load-stmts.cpp:1:13: TypedefDecl=T:1:13 (Definition) Extent=[1:13 - 1:14]
// CHECK: load-stmts.cpp:2:8: StructDecl=X:2:8 (Definition) Extent=[2:1 - 2:23]
@ -221,3 +225,5 @@ void considered_harmful(int x) {
// CHECK: load-stmts.cpp:108:2: LabelStmt=start_over Extent=[108:2 - 109:28]
// CHECK: load-stmts.cpp:109:17: LabelRef=start_over:108:2 Extent=[109:17 - 109:27]
// CHECK: load-stmts.cpp:113:10: LabelRef=start_over:108:2 Extent=[113:10 - 113:20]
// CHECK: load-stmts.cpp:117:9: UnexposedExpr=ip:116:17 Extent=[117:9 - 117:38]