improve DeclStmt to be able to store SourceRange info correctly.

Set the start of DeclStmt range.  Right now the end is meaningless 
though.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48330 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2008-03-13 06:29:04 +00:00
Родитель 3de54ffeb0
Коммит 81c018d948
9 изменённых файлов: 54 добавлений и 25 удалений

Просмотреть файл

@ -456,6 +456,8 @@ ContinueStmt* ContinueStmt::CreateImpl(Deserializer& D) {
void DeclStmt::EmitImpl(Serializer& S) const { void DeclStmt::EmitImpl(Serializer& S) const {
// FIXME: special handling for struct decls. // FIXME: special handling for struct decls.
S.EmitOwnedPtr(getDecl()); S.EmitOwnedPtr(getDecl());
S.Emit(StartLoc);
S.Emit(EndLoc);
} }
void DeclRefExpr::EmitImpl(Serializer& S) const { void DeclRefExpr::EmitImpl(Serializer& S) const {
@ -505,7 +507,9 @@ DeclRefExpr* DeclRefExpr::CreateImpl(Deserializer& D) {
DeclStmt* DeclStmt::CreateImpl(Deserializer& D) { DeclStmt* DeclStmt::CreateImpl(Deserializer& D) {
ScopedDecl* decl = cast<ScopedDecl>(D.ReadOwnedPtr<Decl>()); ScopedDecl* decl = cast<ScopedDecl>(D.ReadOwnedPtr<Decl>());
return new DeclStmt(decl); SourceLocation StartLoc = SourceLocation::ReadVal(D);
SourceLocation EndLoc = SourceLocation::ReadVal(D);
return new DeclStmt(decl, StartLoc, EndLoc);
} }
void DefaultStmt::EmitImpl(Serializer& S) const { void DefaultStmt::EmitImpl(Serializer& S) const {

Просмотреть файл

@ -388,7 +388,7 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS) {
/// [C99] 'inline' /// [C99] 'inline'
/// ///
void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) { void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {
DS.Range.setBegin(Tok.getLocation()); DS.SetRangeStart(Tok.getLocation());
while (1) { while (1) {
int isInvalid = false; int isInvalid = false;
const char *PrevSpec = 0; const char *PrevSpec = 0;
@ -409,7 +409,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {
if (isInvalid) if (isInvalid)
break; break;
// FIXME: restrict this to "id" and ObjC classnames. // FIXME: restrict this to "id" and ObjC classnames.
DS.Range.setEnd(Tok.getLocation()); DS.SetRangeEnd(Tok.getLocation());
ConsumeToken(); // The identifier ConsumeToken(); // The identifier
if (Tok.is(tok::less)) { if (Tok.is(tok::less)) {
SourceLocation endProtoLoc; SourceLocation endProtoLoc;
@ -555,7 +555,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {
else // extwarn. else // extwarn.
Diag(Tok, diag::ext_duplicate_declspec, PrevSpec); Diag(Tok, diag::ext_duplicate_declspec, PrevSpec);
} }
DS.Range.setEnd(Tok.getLocation()); DS.SetRangeEnd(Tok.getLocation());
ConsumeToken(); ConsumeToken();
} }
} }

Просмотреть файл

@ -1186,9 +1186,11 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
// FIXME: Is BlockContext right? // FIXME: Is BlockContext right?
Declarator DeclaratorInfo(DS, Declarator::BlockContext); Declarator DeclaratorInfo(DS, Declarator::BlockContext);
ParseDeclarator(DeclaratorInfo); ParseDeclarator(DeclaratorInfo);
DeclTy * aBlockVarDecl = Actions.ActOnDeclarator(CurScope, DeclTy *aBlockVarDecl = Actions.ActOnDeclarator(CurScope,
DeclaratorInfo, 0); DeclaratorInfo, 0);
StmtResult stmtResult = Actions.ActOnDeclStmt(aBlockVarDecl); StmtResult stmtResult =
Actions.ActOnDeclStmt(aBlockVarDecl, DS.getSourceRange().getBegin(),
DeclaratorInfo.getSourceRange().getEnd());
FirstPart = stmtResult.isInvalid ? 0 : stmtResult.Val; FirstPart = stmtResult.isInvalid ? 0 : stmtResult.Val;
} else } else
ConsumeToken(); // consume '...' ConsumeToken(); // consume '...'

Просмотреть файл

@ -93,7 +93,10 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
default: default:
if (!OnlyStatement && isDeclarationSpecifier()) { if (!OnlyStatement && isDeclarationSpecifier()) {
return Actions.ActOnDeclStmt(ParseDeclaration(Declarator::BlockContext)); SourceLocation DeclStart = Tok.getLocation();
DeclTy *Res = ParseDeclaration(Declarator::BlockContext);
// FIXME: Pass in the right location for the end of the declstmt.
return Actions.ActOnDeclStmt(Res, DeclStart, SourceLocation());
} else if (Tok.is(tok::r_brace)) { } else if (Tok.is(tok::r_brace)) {
Diag(Tok, diag::err_expected_statement); Diag(Tok, diag::err_expected_statement);
return true; return true;
@ -255,7 +258,9 @@ Parser::StmtResult Parser::ParseIdentifierStatement(bool OnlyStatement) {
ParseDeclarator(DeclaratorInfo); ParseDeclarator(DeclaratorInfo);
DeclTy *Decl = ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo); DeclTy *Decl = ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
return Decl ? Actions.ActOnDeclStmt(Decl) : 0; if (!Decl) return 0;
return Actions.ActOnDeclStmt(Decl, DS.getSourceRange().getBegin(),
DeclaratorInfo.getSourceRange().getEnd());
} }
// Otherwise, this is an expression. Seed it with II and parse it. // Otherwise, this is an expression. Seed it with II and parse it.
@ -430,7 +435,10 @@ Parser::StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
if (isDeclarationSpecifier()) { if (isDeclarationSpecifier()) {
// FIXME: Save the __extension__ on the decl as a node somehow. // FIXME: Save the __extension__ on the decl as a node somehow.
// FIXME: disable extwarns. // FIXME: disable extwarns.
R = Actions.ActOnDeclStmt(ParseDeclaration(Declarator::BlockContext)); SourceLocation DeclStart = Tok.getLocation();
DeclTy *Res = ParseDeclaration(Declarator::BlockContext);
// FIXME: Pass in the right location for the end of the declstmt.
R = Actions.ActOnDeclStmt(Res, DeclStart, SourceLocation());
} else { } else {
// Otherwise this was a unary __extension__ marker. Parse the // Otherwise this was a unary __extension__ marker. Parse the
// subexpression and add the __extension__ unary op. // subexpression and add the __extension__ unary op.
@ -743,8 +751,12 @@ Parser::StmtResult Parser::ParseForStatement() {
// Parse declaration, which eats the ';'. // Parse declaration, which eats the ';'.
if (!getLang().C99) // Use of C99-style for loops in C90 mode? if (!getLang().C99) // Use of C99-style for loops in C90 mode?
Diag(Tok, diag::ext_c99_variable_decl_in_for_loop); Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
SourceLocation DeclStart = Tok.getLocation();
DeclTy *aBlockVarDecl = ParseDeclaration(Declarator::ForContext); DeclTy *aBlockVarDecl = ParseDeclaration(Declarator::ForContext);
StmtResult stmtResult = Actions.ActOnDeclStmt(aBlockVarDecl); // FIXME: Pass in the right location for the end of the declstmt.
StmtResult stmtResult = Actions.ActOnDeclStmt(aBlockVarDecl, DeclStart,
SourceLocation());
FirstPart = stmtResult.isInvalid ? 0 : stmtResult.Val; FirstPart = stmtResult.isInvalid ? 0 : stmtResult.Val;
if ((ForEach = isTokIdentifier_in())) { if ((ForEach = isTokIdentifier_in())) {
ConsumeToken(); // consume 'in' ConsumeToken(); // consume 'in'

Просмотреть файл

@ -339,7 +339,8 @@ public:
virtual StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, virtual StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
StmtTy **Elts, unsigned NumElts, StmtTy **Elts, unsigned NumElts,
bool isStmtExpr); bool isStmtExpr);
virtual StmtResult ActOnDeclStmt(DeclTy *Decl); virtual StmtResult ActOnDeclStmt(DeclTy *Decl, SourceLocation StartLoc,
SourceLocation EndLoc);
virtual StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprTy *LHSVal, virtual StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprTy *LHSVal,
SourceLocation DotDotDotLoc, ExprTy *RHSVal, SourceLocation DotDotDotLoc, ExprTy *RHSVal,
SourceLocation ColonLoc, StmtTy *SubStmt); SourceLocation ColonLoc, StmtTy *SubStmt);

Просмотреть файл

@ -33,13 +33,13 @@ Sema::StmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc) {
return new NullStmt(SemiLoc); return new NullStmt(SemiLoc);
} }
Sema::StmtResult Sema::ActOnDeclStmt(DeclTy *decl) { Sema::StmtResult Sema::ActOnDeclStmt(DeclTy *decl, SourceLocation StartLoc,
if (decl) { SourceLocation EndLoc) {
ScopedDecl *SD = dyn_cast<ScopedDecl>(static_cast<Decl *>(decl)); if (decl == 0)
assert(SD && "Sema::ActOnDeclStmt(): expected ScopedDecl"); return true;
return new DeclStmt(SD);
} else ScopedDecl *SD = cast<ScopedDecl>(static_cast<Decl *>(decl));
return true; // error return new DeclStmt(SD, StartLoc, EndLoc);
} }
Action::StmtResult Action::StmtResult

Просмотреть файл

@ -132,13 +132,19 @@ public:
/// ///
class DeclStmt : public Stmt { class DeclStmt : public Stmt {
ScopedDecl *TheDecl; ScopedDecl *TheDecl;
SourceLocation StartLoc, EndLoc;
public: public:
DeclStmt(ScopedDecl *D) : Stmt(DeclStmtClass), TheDecl(D) {} DeclStmt(ScopedDecl *D, SourceLocation startLoc, SourceLocation endLoc)
: Stmt(DeclStmtClass), TheDecl(D), StartLoc(startLoc), EndLoc(endLoc) {}
const ScopedDecl *getDecl() const { return TheDecl; } const ScopedDecl *getDecl() const { return TheDecl; }
ScopedDecl *getDecl() { return TheDecl; } ScopedDecl *getDecl() { return TheDecl; }
virtual SourceRange getSourceRange() const { return SourceRange(); } SourceLocation getStartLoc() const { return StartLoc; }
SourceLocation getEndLoc() const { return EndLoc; }
virtual SourceRange getSourceRange() const {
return SourceRange(StartLoc, EndLoc);
}
static bool classof(const Stmt *T) { static bool classof(const Stmt *T) {
return T->getStmtClass() == DeclStmtClass; return T->getStmtClass() == DeclStmtClass;

Просмотреть файл

@ -220,7 +220,8 @@ public:
bool isStmtExpr) { bool isStmtExpr) {
return 0; return 0;
} }
virtual StmtResult ActOnDeclStmt(DeclTy *Decl) { virtual StmtResult ActOnDeclStmt(DeclTy *Decl, SourceLocation StartLoc,
SourceLocation EndLoc) {
return 0; return 0;
} }

Просмотреть файл

@ -28,9 +28,6 @@ namespace clang {
/// type-qualifiers, and function-specifiers. /// type-qualifiers, and function-specifiers.
class DeclSpec { class DeclSpec {
public: public:
SourceRange Range;
const SourceRange &getSourceRange() const { return Range; }
// storage-class-specifier // storage-class-specifier
enum SCS { enum SCS {
SCS_unspecified, SCS_unspecified,
@ -130,6 +127,8 @@ private:
// SourceLocation info. These are null if the item wasn't specified or if // SourceLocation info. These are null if the item wasn't specified or if
// the setting was synthesized. // the setting was synthesized.
SourceRange Range;
SourceLocation StorageClassSpecLoc, SCS_threadLoc; SourceLocation StorageClassSpecLoc, SCS_threadLoc;
SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc; SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc;
SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc; SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc;
@ -181,6 +180,7 @@ public:
TST getTypeSpecType() const { return (TST)TypeSpecType; } TST getTypeSpecType() const { return (TST)TypeSpecType; }
void *getTypeRep() const { return TypeRep; } void *getTypeRep() const { return TypeRep; }
const SourceRange &getSourceRange() const { return Range; }
SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; } SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; }
SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; } SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; }
SourceLocation getTypeSpecSignLoc() const { return TSSLoc; } SourceLocation getTypeSpecSignLoc() const { return TSSLoc; }
@ -222,6 +222,9 @@ public:
/// ///
unsigned getParsedSpecifiers() const; unsigned getParsedSpecifiers() const;
void SetRangeStart(SourceLocation Loc) { Range.setBegin(Loc); }
void SetRangeEnd(SourceLocation Loc) { Range.setEnd(Loc); }
/// These methods set the specified attribute of the DeclSpec, but return true /// These methods set the specified attribute of the DeclSpec, but return true
/// and ignore the request if invalid (e.g. "extern" then "auto" is /// and ignore the request if invalid (e.g. "extern" then "auto" is
/// specified). The name of the previous specifier is returned in prevspec. /// specified). The name of the previous specifier is returned in prevspec.