aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-04-02 04:16:50 +0000
committerChris Lattner <sabre@nondot.org>2009-04-02 04:16:50 +0000
commit97144fc41a9419bf6d74fc9450e8ef3f6e11f7e0 (patch)
treefa4999c1dd962098ab138210b5268e02b340acbc
parent0ddaff3a558cca0d1157c3f63e3ad82b72cf625a (diff)
fix a FIXME, providing accurate source range info for DeclStmt's. The end
of the range is now the ';' location. For something like this: $ cat t2.c #define bool int void f(int x, int y) { bool b = !x && y; } We used to produce: $ clang-cc t2.c -ast-dump typedef char *__builtin_va_list; void f(int x, int y) (CompoundStmt 0x2201f10 <t2.c:3:22, line:5:1> (DeclStmt 0x2201ef0 <line:2:14> <---- 0x2201a20 "int b = (BinaryOperator 0x2201ed0 <line:4:10, col:16> 'int' '&&' (UnaryOperator 0x2201e90 <col:10, col:11> 'int' prefix '!' (DeclRefExpr 0x2201c90 <col:11> 'int' ParmVar='x' 0x2201a50)) (DeclRefExpr 0x2201eb0 <col:16> 'int' ParmVar='y' 0x2201e10))") Now we produce: $ clang-cc t2.c -ast-dump typedef char *__builtin_va_list; void f(int x, int y) (CompoundStmt 0x2201f10 <t2.c:3:22, line:5:1> (DeclStmt 0x2201ef0 <line:2:14, line:4:17> <------ 0x2201a20 "int b = (BinaryOperator 0x2201ed0 <col:10, col:16> 'int' '&&' (UnaryOperator 0x2201e90 <col:10, col:11> 'int' prefix '!' (DeclRefExpr 0x2201c90 <col:11> 'int' ParmVar='x' 0x2201a50)) (DeclRefExpr 0x2201eb0 <col:16> 'int' ParmVar='y' 0x2201e10))") git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68288 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Parse/Parser.h20
-rw-r--r--lib/Parse/ParseDecl.cpp19
-rw-r--r--lib/Parse/ParseDeclCXX.cpp38
-rw-r--r--lib/Parse/ParseStmt.cpp21
-rw-r--r--lib/Parse/ParseTemplate.cpp4
-rw-r--r--lib/Parse/Parser.cpp5
6 files changed, 68 insertions, 39 deletions
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 3969cf4765..85f6d50ebb 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -809,8 +809,9 @@ private:
//===--------------------------------------------------------------------===//
// C99 6.7: Declarations.
- DeclGroupPtrTy ParseDeclaration(unsigned Context);
+ DeclGroupPtrTy ParseDeclaration(unsigned Context, SourceLocation &DeclEnd);
DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context,
+ SourceLocation &DeclEnd,
bool RequireSemi = true);
DeclGroupPtrTy ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
DeclPtrTy ParseFunctionStatementBody(DeclPtrTy Decl);
@@ -994,14 +995,18 @@ private:
//===--------------------------------------------------------------------===//
// C++ 7: Declarations [dcl.dcl]
- DeclPtrTy ParseNamespace(unsigned Context);
+ DeclPtrTy ParseNamespace(unsigned Context, SourceLocation &DeclEnd);
DeclPtrTy ParseLinkage(unsigned Context);
- DeclPtrTy ParseUsingDirectiveOrDeclaration(unsigned Context);
- DeclPtrTy ParseUsingDirective(unsigned Context, SourceLocation UsingLoc);
- DeclPtrTy ParseUsingDeclaration(unsigned Context, SourceLocation UsingLoc);
- DeclPtrTy ParseStaticAssertDeclaration();
+ DeclPtrTy ParseUsingDirectiveOrDeclaration(unsigned Context,
+ SourceLocation &DeclEnd);
+ DeclPtrTy ParseUsingDirective(unsigned Context, SourceLocation UsingLoc,
+ SourceLocation &DeclEnd);
+ DeclPtrTy ParseUsingDeclaration(unsigned Context, SourceLocation UsingLoc,
+ SourceLocation &DeclEnd);
+ DeclPtrTy ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
DeclPtrTy ParseNamespaceAlias(SourceLocation NamespaceLoc,
- SourceLocation AliasLoc, IdentifierInfo *Alias);
+ SourceLocation AliasLoc, IdentifierInfo *Alias,
+ SourceLocation &DeclEnd);
//===--------------------------------------------------------------------===//
// C++ 9: classes [class] and C structs/unions.
@@ -1035,6 +1040,7 @@ private:
// C++ 14.1: Template Parameters [temp.param]
DeclPtrTy ParseTemplateDeclarationOrSpecialization(unsigned Context,
+ SourceLocation &DeclEnd,
AccessSpecifier AS=AS_none);
bool ParseTemplateParameters(unsigned Depth,
TemplateParameterList &TemplateParams,
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 104ca0336b..1f8d473891 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -215,7 +215,8 @@ void Parser::FuzzyParseMicrosoftDeclSpec() {
/// ParseDeclaration - Parse a full 'declaration', which consists of
/// declaration-specifiers, some number of declarators, and a semicolon.
-/// 'Context' should be a Declarator::TheContext value.
+/// 'Context' should be a Declarator::TheContext value. This returns the
+/// location of the semicolon in DeclEnd.
///
/// declaration: [C99 6.7]
/// block-declaration ->
@@ -228,24 +229,25 @@ void Parser::FuzzyParseMicrosoftDeclSpec() {
/// [C++0x] static_assert-declaration
/// others... [FIXME]
///
-Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context) {
+Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
+ SourceLocation &DeclEnd) {
DeclPtrTy SingleDecl;
switch (Tok.getKind()) {
case tok::kw_export:
case tok::kw_template:
- SingleDecl = ParseTemplateDeclarationOrSpecialization(Context);
+ SingleDecl = ParseTemplateDeclarationOrSpecialization(Context, DeclEnd);
break;
case tok::kw_namespace:
- SingleDecl = ParseNamespace(Context);
+ SingleDecl = ParseNamespace(Context, DeclEnd);
break;
case tok::kw_using:
- SingleDecl = ParseUsingDirectiveOrDeclaration(Context);
+ SingleDecl = ParseUsingDirectiveOrDeclaration(Context, DeclEnd);
break;
case tok::kw_static_assert:
- SingleDecl = ParseStaticAssertDeclaration();
+ SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
break;
default:
- return ParseSimpleDeclaration(Context);
+ return ParseSimpleDeclaration(Context, DeclEnd);
}
// This routine returns a DeclGroup, if the thing we parsed only contains a
@@ -261,6 +263,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context) {
/// If RequireSemi is false, this does not check for a ';' at the end of the
/// declaration.
Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context,
+ SourceLocation &DeclEnd,
bool RequireSemi) {
// Parse the common declaration-specifiers piece.
DeclSpec DS;
@@ -280,6 +283,8 @@ Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context,
DeclGroupPtrTy DG =
ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
+ DeclEnd = Tok.getLocation();
+
// If the client wants to check what comes after the declaration, just return
// immediately without checking anything!
if (!RequireSemi) return DG;
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 1cf4a8fe5f..bef1fb71d4 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -42,7 +42,8 @@ using namespace clang;
/// namespace-alias-definition: [C++ 7.3.2: namespace.alias]
/// 'namespace' identifier '=' qualified-namespace-specifier ';'
///
-Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context) {
+Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context,
+ SourceLocation &DeclEnd) {
assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'.
@@ -62,7 +63,7 @@ Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context) {
if (Tok.is(tok::equal))
// FIXME: Verify no attributes were present.
- return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident);
+ return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
if (Tok.isNot(tok::l_brace)) {
Diag(Tok, Ident ? diag::err_expected_lbrace :
@@ -88,9 +89,10 @@ Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context) {
// Leave the namespace scope.
NamespaceScope.Exit();
- SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
- Actions.ActOnFinishNamespaceDef(NamespcDecl, RBrace);
+ SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBrace);
+ Actions.ActOnFinishNamespaceDef(NamespcDecl, RBraceLoc);
+ DeclEnd = RBraceLoc;
return NamespcDecl;
}
@@ -99,7 +101,8 @@ Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context) {
///
Parser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
SourceLocation AliasLoc,
- IdentifierInfo *Alias) {
+ IdentifierInfo *Alias,
+ SourceLocation &DeclEnd) {
assert(Tok.is(tok::equal) && "Not equal token");
ConsumeToken(); // eat the '='.
@@ -120,6 +123,7 @@ Parser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
SourceLocation IdentLoc = ConsumeToken();
// Eat the ';'.
+ DeclEnd = Tok.getLocation();
ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
"namespace name", tok::semi);
@@ -169,7 +173,8 @@ Parser::DeclPtrTy Parser::ParseLinkage(unsigned Context) {
/// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
/// using-directive. Assumes that current token is 'using'.
-Parser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context) {
+Parser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
+ SourceLocation &DeclEnd) {
assert(Tok.is(tok::kw_using) && "Not using token");
// Eat 'using'.
@@ -177,10 +182,10 @@ Parser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context) {
if (Tok.is(tok::kw_namespace))
// Next token after 'using' is 'namespace' so it must be using-directive
- return ParseUsingDirective(Context, UsingLoc);
+ return ParseUsingDirective(Context, UsingLoc, DeclEnd);
// Otherwise, it must be using-declaration.
- return ParseUsingDeclaration(Context, UsingLoc);
+ return ParseUsingDeclaration(Context, UsingLoc, DeclEnd);
}
/// ParseUsingDirective - Parse C++ using-directive, assumes
@@ -194,7 +199,8 @@ Parser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context) {
/// namespace-name attributes[opt] ;
///
Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context,
- SourceLocation UsingLoc) {
+ SourceLocation UsingLoc,
+ SourceLocation &DeclEnd) {
assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
// Eat 'namespace'.
@@ -226,6 +232,7 @@ Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context,
AttrList = ParseAttributes();
// Eat ';'.
+ DeclEnd = Tok.getLocation();
ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
AttrList ? "attributes list" : "namespace name", tok::semi);
@@ -242,7 +249,8 @@ Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context,
/// 'using' :: unqualified-id [TODO]
///
Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
- SourceLocation UsingLoc) {
+ SourceLocation UsingLoc,
+ SourceLocation &DeclEnd) {
assert(false && "Not implemented");
// FIXME: Implement parsing.
return DeclPtrTy();
@@ -253,7 +261,7 @@ Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
/// static_assert-declaration:
/// static_assert ( constant-expression , string-literal ) ;
///
-Parser::DeclPtrTy Parser::ParseStaticAssertDeclaration() {
+Parser::DeclPtrTy Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration");
SourceLocation StaticAssertLoc = ConsumeToken();
@@ -285,6 +293,7 @@ Parser::DeclPtrTy Parser::ParseStaticAssertDeclaration() {
MatchRHSPunctuation(tok::r_paren, LParenLoc);
+ DeclEnd = Tok.getLocation();
ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert);
return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, move(AssertExpr),
@@ -668,12 +677,15 @@ AccessSpecifier Parser::getAccessSpecifierIfPresent() const
void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
// static_assert-declaration
if (Tok.is(tok::kw_static_assert)) {
- ParseStaticAssertDeclaration();
+ SourceLocation DeclEnd;
+ ParseStaticAssertDeclaration(DeclEnd);
return;
}
if (Tok.is(tok::kw_template)) {
- ParseTemplateDeclarationOrSpecialization(Declarator::MemberContext, AS);
+ SourceLocation DeclEnd;
+ ParseTemplateDeclarationOrSpecialization(Declarator::MemberContext, DeclEnd,
+ AS);
return;
}
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index b11ffbe82e..b87ede9388 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -100,10 +100,9 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
default: {
if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
- SourceLocation DeclStart = Tok.getLocation();
- DeclGroupPtrTy Decl = ParseDeclaration(Declarator::BlockContext);
- // FIXME: Pass in the right location for the end of the declstmt.
- return Actions.ActOnDeclStmt(Decl, DeclStart, DeclStart);
+ SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
+ DeclGroupPtrTy Decl = ParseDeclaration(Declarator::BlockContext, DeclEnd);
+ return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
}
if (Tok.is(tok::r_brace)) {
@@ -442,11 +441,10 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
// If this is the start of a declaration, parse it as such.
if (isDeclarationStatement()) {
- // FIXME: Save the __extension__ on the decl as a node somehow.
- SourceLocation DeclStart = Tok.getLocation();
- DeclGroupPtrTy Res = ParseDeclaration(Declarator::BlockContext);
- // FIXME: Pass in the right location for the end of the declstmt.
- R = Actions.ActOnDeclStmt(Res, DeclStart, DeclStart);
+ // FIXME: Save the __extension__ on the decl as a node somehow?
+ SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
+ DeclGroupPtrTy Res = ParseDeclaration(Declarator::BlockContext,DeclEnd);
+ R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
} else {
// Otherwise this was a unary __extension__ marker.
OwningExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
@@ -911,8 +909,9 @@ Parser::OwningStmtResult Parser::ParseForStatement() {
if (!C99orCXX) // Use of C99-style for loops in C90 mode?
Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
- SourceLocation DeclStart = Tok.getLocation();
- DeclGroupPtrTy DG = ParseSimpleDeclaration(Declarator::ForContext, false);
+ SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
+ DeclGroupPtrTy DG = ParseSimpleDeclaration(Declarator::ForContext, DeclEnd,
+ false);
FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
if (Tok.is(tok::semi)) { // for (int x = 4;
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index 0f9bcd2219..d38df93ace 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -35,6 +35,7 @@ using namespace clang;
/// 'template' '<' '>' declaration
Parser::DeclPtrTy
Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
+ SourceLocation &DeclEnd,
AccessSpecifier AS) {
assert((Tok.is(tok::kw_export) || Tok.is(tok::kw_template)) &&
"Token does not start a template declaration.");
@@ -99,6 +100,9 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
// FIXME: Converting DeclGroupPtr to DeclPtr like this is an insanely gruesome
// hack, will bring up on cfe-dev.
DeclGroupPtrTy DG = ParseDeclarationOrFunctionDefinition(&ParamLists, AS);
+ // FIXME: Should be ';' location not the token after it. Resolve with above
+ // fixmes.
+ DeclEnd = Tok.getLocation();
return DeclPtrTy::make(DG.get());
}
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 495d5e51dd..a245ac2156 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -423,7 +423,10 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration() {
case tok::kw_export: // As in 'export template'
case tok::kw_static_assert:
// A function definition cannot start with a these keywords.
- return ParseDeclaration(Declarator::FileContext);
+ {
+ SourceLocation DeclEnd;
+ return ParseDeclaration(Declarator::FileContext, DeclEnd);
+ }
default:
// We can't tell whether this is a function-definition or declaration yet.
return ParseDeclarationOrFunctionDefinition();