aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseTentative.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2008-10-05 23:15:41 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2008-10-05 23:15:41 +0000
commitd3616a8d0b1506966cb669c19dbfc91bf42c810a (patch)
tree00ddf99dc1550abd64ac2b4d7bc318cb3ad9f418 /lib/Parse/ParseTentative.cpp
parentd29b6300a70576f5996f4137536e3ca1efa8eb83 (diff)
A tiny optimization; use isCXXFunctionDeclarator only when it's appropriate.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57141 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseTentative.cpp')
-rw-r--r--lib/Parse/ParseTentative.cpp37
1 files changed, 28 insertions, 9 deletions
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index bd2d106923..5dbc327b71 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -418,7 +418,11 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
// declarator-id
ConsumeToken();
} else if (Tok.is(tok::l_paren)) {
- if (mayBeAbstract && isCXXFunctionDeclarator()) {
+ ConsumeParen();
+ if (mayBeAbstract &&
+ (Tok.is(tok::r_paren) || // 'int()' is a function.
+ Tok.is(tok::ellipsis) || // 'int(...)' is a function.
+ isDeclarationSpecifier())) { // 'int(int)' is a function.
// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
// exception-specification[opt]
TPResult TPR = TryParseFunctionDeclarator();
@@ -428,7 +432,6 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
// '(' declarator ')'
// '(' attributes declarator ')'
// '(' abstract-declarator ')'
- ConsumeParen();
if (Tok.is(tok::kw___attribute))
return TPResult::True(); // attributes indicate declaration
TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
@@ -446,10 +449,16 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
TPResult TPR(TPResult::Ambiguous());
if (Tok.is(tok::l_paren)) {
+ // Check whether we have a function declarator or a possible ctor-style
+ // initializer that follows the declarator. Note that ctor-style
+ // initializers are not possible in contexts where abstract declarators
+ // are allowed.
+ if (!mayBeAbstract && !isCXXFunctionDeclarator())
+ break;
+
// direct-declarator '(' parameter-declaration-clause ')'
// cv-qualifier-seq[opt] exception-specification[opt]
- if (!isCXXFunctionDeclarator())
- break;
+ ConsumeParen();
TPR = TryParseFunctionDeclarator();
} else if (Tok.is(tok::l_square)) {
// direct-declarator '[' constant-expression[opt] ']'
@@ -809,9 +818,11 @@ Parser::TPResult Parser::TryParseParameterDeclarationClause() {
return TPResult::Ambiguous();
}
-/// TryParseFunctionDeclarator - We previously determined (using
-/// isCXXFunctionDeclarator) that we are at a function declarator. Now parse
-/// through it.
+/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
+/// parsing as a function declarator.
+/// If TryParseFunctionDeclarator fully parsed the function declarator, it will
+/// return TPResult::Ambiguous(), otherwise it will return either False() or
+/// Error().
///
/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
/// exception-specification[opt]
@@ -820,9 +831,17 @@ Parser::TPResult Parser::TryParseParameterDeclarationClause() {
/// 'throw' '(' type-id-list[opt] ')'
///
Parser::TPResult Parser::TryParseFunctionDeclarator() {
- assert(Tok.is(tok::l_paren));
+
+ // The '(' is already parsed.
+
+ TPResult TPR = TryParseParameterDeclarationClause();
+ if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))
+ TPR = TPResult::False();
+
+ if (TPR == TPResult::False() || TPR == TPResult::Error())
+ return TPR;
+
// Parse through the parens.
- ConsumeParen();
if (!SkipUntil(tok::r_paren))
return TPResult::Error();