return isDeclarationSpecifier();
}
+ /// isTypeIdInParens - Assumes that a '(' was parsed and now we want to know
+ /// whether the parens contain an expression or a type-id.
+ /// Returns true for a type-id and false for an expression.
+ bool isTypeIdInParens() {
+ if (getLang().CPlusPlus)
+ return isCXXTypeIdInParens();
+ return isTypeSpecifierQualifier();
+ }
+
/// isCXXDeclarationStatement - C++-specialized function that disambiguates
/// between a declaration or an expression statement, when parsing function
/// bodies. Returns true for declaration, false for expression.
/// the function returns true to let the declaration parsing code handle it.
bool isCXXConditionDeclaration();
+ /// isCXXTypeIdInParens - Assumes that a '(' was parsed and now we want to
+ /// know whether the parens contain an expression or a type-id.
+ /// Returns true for a type-id and false for an expression.
+ /// If during the disambiguation process a parsing error is encountered,
+ /// the function returns true to let the declaration parsing code handle it.
+ bool isCXXTypeIdInParens();
+
/// TPResult - Used as the result value for functions whose purpose is to
/// disambiguate C++ constructs by "tentatively parsing" them.
/// This is a class instead of a simple enum because the implicit enum-to-bool
TPResult TryParseSimpleDeclaration();
TPResult TryParseTypeofSpecifier();
TPResult TryParseInitDeclaratorList();
- TPResult TryParseDeclarator(bool mayBeAbstract);
+ TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier=true);
TPResult TryParseParameterDeclarationClause();
TPResult TryParseFunctionDeclarator();
TPResult TryParseBracketDeclarator();
return TPR == TPResult::True();
}
+/// isCXXTypeIdInParens - Assumes that a '(' was parsed and now we want to\r
+/// know whether the parens contain an expression or a type-id.\r
+/// Returns true for a type-id and false for an expression.\r
+/// If during the disambiguation process a parsing error is encountered,\r
+/// the function returns true to let the declaration parsing code handle it.\r
+///\r
+/// type-id:\r
+/// type-specifier-seq abstract-declarator[opt]
+///
+bool Parser::isCXXTypeIdInParens() {
+ TPResult TPR = isCXXDeclarationSpecifier();
+ if (TPR != TPResult::Ambiguous())
+ return TPR != TPResult::False(); // Returns true for TPResult::True() or
+ // TPResult::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(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/);
+
+ // In case of an error, let the declaration parsing code handle it.
+ if (TPR == TPResult::Error())
+ TPR = TPResult::True();
+
+ if (TPR == TPResult::Ambiguous()) {
+ // We are supposed to be inside parens, so if after the abstract declarator
+ // we encounter a ')' this is a type-id, otherwise it's an expression.
+ if (Tok.is(tok::r_paren))
+ TPR = TPResult::True();
+ else
+ TPR = TPResult::False();
+ }
+
+ PA.Revert();
+
+ assert(TPR == TPResult::True() || TPR == TPResult::False());
+ return TPR == TPResult::True();
+}
+
/// declarator:
/// direct-declarator
/// ptr-operator declarator
/// '~' class-name [TODO]
/// template-id [TODO]
///
-Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract) {
+Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
+ bool mayHaveIdentifier) {
// declarator:
// direct-declarator
// ptr-operator declarator
// direct-declarator:
// direct-abstract-declarator:
- if (Tok.is(tok::identifier)) {
+ if (Tok.is(tok::identifier) && mayHaveIdentifier) {
// declarator-id
ConsumeToken();
} else if (Tok.is(tok::l_paren)) {
ConsumeParen();
if (Tok.is(tok::kw___attribute))
return TPResult::True(); // attributes indicate declaration
- TPResult TPR = TryParseDeclarator(mayBeAbstract);
+ TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
if (TPR != TPResult::Ambiguous())
return TPR;
if (Tok.isNot(tok::r_paren))