summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2011-12-20 01:50:37 +0000
committerEli Friedman <eli.friedman@gmail.com>2011-12-20 01:50:37 +0000
commit0ffc31c55b0981c4d15e6da2387035938f19ab26 (patch)
tree077c8bcbff08e6b768eeeab0b96b1cb2c35cbd46 /clang/lib
parentbc40eef82be626f97bb64da23b916021563b3449 (diff)
downloadbcm5719-llvm-0ffc31c55b0981c4d15e6da2387035938f19ab26.tar.gz
bcm5719-llvm-0ffc31c55b0981c4d15e6da2387035938f19ab26.zip
Fix tentative parsing so it knows how to handle an ambiguous for-range-declaration. PR11601.
llvm-svn: 146953
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Parse/ParseStmt.cpp2
-rw-r--r--clang/lib/Parse/ParseTentative.cpp19
2 files changed, 15 insertions, 6 deletions
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index da0e865862c..435bde33753 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -1306,7 +1306,7 @@ StmtResult Parser::ParseForStatement(ParsedAttributes &attrs) {
if (Tok.is(tok::semi)) { // for (;
// no first part, eat the ';'.
ConsumeToken();
- } else if (isSimpleDeclaration()) { // for (int X = 4;
+ } else if (isForInitDeclaration()) { // for (int X = 4;
// Parse declaration, which eats the ';'.
if (!C99orCXXorObjC) // Use of C99-style for loops in C90 mode?
Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index 7c280ff50be..2c9018316a6 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -62,7 +62,7 @@ bool Parser::isCXXDeclarationStatement() {
return true;
// simple-declaration
default:
- return isCXXSimpleDeclaration();
+ return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false);
}
}
@@ -75,7 +75,11 @@ bool Parser::isCXXDeclarationStatement() {
/// simple-declaration:
/// decl-specifier-seq init-declarator-list[opt] ';'
///
-bool Parser::isCXXSimpleDeclaration() {
+/// (if AllowForRangeDecl specified)
+/// for ( for-range-declaration : for-range-initializer ) statement
+/// for-range-declaration:
+/// attribute-specifier-seqopt type-specifier-seq declarator
+bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {
// C++ 6.8p1:
// There is an ambiguity in the grammar involving expression-statements and
// declarations: An expression-statement with a function-style explicit type
@@ -112,7 +116,7 @@ bool Parser::isCXXSimpleDeclaration() {
// We need tentative parsing...
TentativeParsingAction PA(*this);
- TPR = TryParseSimpleDeclaration();
+ TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
PA.Revert();
// In case of an error, let the declaration parsing code handle it.
@@ -130,7 +134,12 @@ bool Parser::isCXXSimpleDeclaration() {
/// simple-declaration:
/// decl-specifier-seq init-declarator-list[opt] ';'
///
-Parser::TPResult Parser::TryParseSimpleDeclaration() {
+/// (if AllowForRangeDecl specified)
+/// for ( for-range-declaration : for-range-initializer ) statement
+/// for-range-declaration:
+/// attribute-specifier-seqopt type-specifier-seq declarator
+///
+Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {
// We know that we have a simple-type-specifier/typename-specifier followed
// by a '('.
assert(isCXXDeclarationSpecifier() == TPResult::Ambiguous());
@@ -150,7 +159,7 @@ Parser::TPResult Parser::TryParseSimpleDeclaration() {
if (TPR != TPResult::Ambiguous())
return TPR;
- if (Tok.isNot(tok::semi))
+ if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))
return TPResult::False();
return TPResult::Ambiguous();
OpenPOWER on IntegriCloud