зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
3de54ffeb0
Коммит
81c018d948
|
@ -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.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче