[cfe-commits] r57109 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseExprCXX.cpp lib/Parse/ParseTentative.cpp test/SemaCXX/decl-expr-ambiguity.cpp

Argiris Kirtzidis akyrtzi at gmail.com
Sun Oct 5 08:03:51 PDT 2008


Author: akirtzidis
Date: Sun Oct  5 10:03:47 2008
New Revision: 57109

URL: http://llvm.org/viewvc/llvm-project?rev=57109&view=rev
Log:
Disambiguate between a declaration or expression for the 'condition' part of a if/switch/while/for statement.

Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Parse/ParseTentative.cpp
    cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=57109&r1=57108&r2=57109&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sun Oct  5 10:03:47 2008
@@ -610,6 +610,12 @@
   /// the function returns true to let the declaration parsing code handle it.
   bool isCXXFunctionDeclarator();
 
+  /// isCXXConditionDeclaration - Disambiguates between a declaration or an
+  /// expression for a condition of a if/switch/while/for statement.
+  /// If during the disambiguation process a parsing error is encountered,
+  /// the function returns true to let the declaration parsing code handle it.
+  bool isCXXConditionDeclaration();
+
   /// isCXXDeclarationSpecifier - Returns TPR_true if it is a declaration
   /// specifier, TPR_false if it is not, TPR_ambiguous if it could be either
   /// a decl-specifier or a function-style cast, and TPR_error if a parsing

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=57109&r1=57108&r2=57109&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Sun Oct  5 10:03:47 2008
@@ -162,7 +162,7 @@
 ///             '=' assignment-expression
 ///
 Parser::ExprResult Parser::ParseCXXCondition() {
-  if (!isDeclarationSpecifier())
+  if (!isCXXConditionDeclaration())
     return ParseExpression(); // expression
 
   SourceLocation StartLoc = Tok.getLocation();

Modified: cfe/trunk/lib/Parse/ParseTentative.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=57109&r1=57108&r2=57109&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseTentative.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTentative.cpp Sun Oct  5 10:03:47 2008
@@ -225,6 +225,60 @@
   return TPR_ambiguous;
 }
 
+/// isCXXConditionDeclaration - Disambiguates between a declaration or an
+/// expression for a condition of a if/switch/while/for statement.
+/// If during the disambiguation process a parsing error is encountered,
+/// the function returns true to let the declaration parsing code handle it.
+///
+///       condition:
+///         expression
+///         type-specifier-seq declarator '=' assignment-expression
+/// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
+///             '=' assignment-expression
+///
+bool Parser::isCXXConditionDeclaration() {
+  TentativeParsingResult TPR = isCXXDeclarationSpecifier();
+  if (TPR != TPR_ambiguous)
+    return TPR != TPR_false; // Returns true for TPR_true or TPR_error.
+
+  // FIXME: Add statistics about the number of ambiguous statements encountered
+  // and how they were resolved (number of declarations+number of expressions).
+
+  // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
+  // We need tentative parsing...
+
+  TentativeParsingAction PA(*this);
+
+  // type-specifier-seq
+  if (Tok.is(tok::kw_typeof))
+    TryParseTypeofSpecifier();
+  else
+    ConsumeToken();
+  assert(Tok.is(tok::l_paren) && "Expected '('");
+
+  // declarator
+  TPR = TryParseDeclarator(false/*mayBeAbstract*/);
+
+  PA.Revert();
+
+  // In case of an error, let the declaration parsing code handle it.
+  if (TPR == TPR_error)
+    return true;
+
+  if (TPR == TPR_ambiguous) {
+    // '='
+    // [GNU] simple-asm-expr[opt] attributes[opt]
+    if (Tok.is(tok::equal)  ||
+        Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
+      TPR = TPR_true;
+    else
+      TPR = TPR_false;
+  }
+
+  assert(TPR == TPR_true || TPR == TPR_false);
+  return TPR == TPR_true;
+}
+
 ///         declarator:
 ///           direct-declarator
 ///           ptr-operator declarator

Modified: cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp?rev=57109&r1=57108&r2=57109&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp (original)
+++ cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp Sun Oct  5 10:03:47 2008
@@ -11,6 +11,7 @@
   __extension__ int(a)++; // expected-error {{invalid lvalue in increment/decrement expression}}
   typeof(int)(a,5)<<a; // expected-error {{function-style cast to a builtin type can only take one argument}}
   void(a), ++a; // expected-warning {{statement was disambiguated as expression}} expected-warning {{expression result unused}}
+  if (int(a)+1) {}
 
   // Declarations.
   T(*d)(int(p)); // expected-warning {{statement was disambiguated as declaration}} expected-error {{previous definition is here}}





More information about the cfe-commits mailing list