1 //===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the tentative parsing portions of the Parser
11 // interfaces, for ambiguity resolution.
13 //===----------------------------------------------------------------------===//
15 #include "clang/Parse/Parser.h"
16 #include "clang/Parse/ParseDiagnostic.h"
17 using namespace clang;
19 /// isCXXDeclarationStatement - C++-specialized function that disambiguates
20 /// between a declaration or an expression statement, when parsing function
21 /// bodies. Returns true for declaration, false for expression.
23 /// declaration-statement:
26 /// block-declaration:
27 /// simple-declaration
29 /// namespace-alias-definition
32 /// [C++0x] static_assert-declaration
35 /// 'asm' '(' string-literal ')' ';'
37 /// namespace-alias-definition:
38 /// 'namespace' identifier = qualified-namespace-specifier ';'
40 /// using-declaration:
41 /// 'using' typename[opt] '::'[opt] nested-name-specifier
42 /// unqualified-id ';'
43 /// 'using' '::' unqualified-id ;
46 /// 'using' 'namespace' '::'[opt] nested-name-specifier[opt]
47 /// namespace-name ';'
49 bool Parser::isCXXDeclarationStatement() {
50 switch (Tok.getKind()) {
53 // namespace-alias-definition
54 case tok::kw_namespace:
58 // static_assert-declaration
59 case tok::kw_static_assert:
63 return isCXXSimpleDeclaration();
67 /// isCXXSimpleDeclaration - C++-specialized function that disambiguates
68 /// between a simple-declaration or an expression-statement.
69 /// If during the disambiguation process a parsing error is encountered,
70 /// the function returns true to let the declaration parsing code handle it.
71 /// Returns false if the statement is disambiguated as expression.
73 /// simple-declaration:
74 /// decl-specifier-seq init-declarator-list[opt] ';'
76 bool Parser::isCXXSimpleDeclaration() {
78 // There is an ambiguity in the grammar involving expression-statements and
79 // declarations: An expression-statement with a function-style explicit type
80 // conversion (5.2.3) as its leftmost subexpression can be indistinguishable
81 // from a declaration where the first declarator starts with a '('. In those
82 // cases the statement is a declaration. [Note: To disambiguate, the whole
83 // statement might have to be examined to determine if it is an
84 // expression-statement or a declaration].
87 // The disambiguation is purely syntactic; that is, the meaning of the names
88 // occurring in such a statement, beyond whether they are type-names or not,
89 // is not generally used in or changed by the disambiguation. Class
90 // templates are instantiated as necessary to determine if a qualified name
91 // is a type-name. Disambiguation precedes parsing, and a statement
92 // disambiguated as a declaration may be an ill-formed declaration.
94 // We don't have to parse all of the decl-specifier-seq part. There's only
95 // an ambiguity if the first decl-specifier is
96 // simple-type-specifier/typename-specifier followed by a '(', which may
97 // indicate a function-style cast expression.
98 // isCXXDeclarationSpecifier will return TPResult::Ambiguous() only in such
101 TPResult TPR = isCXXDeclarationSpecifier();
102 if (TPR != TPResult::Ambiguous())
103 return TPR != TPResult::False(); // Returns true for TPResult::True() or
104 // TPResult::Error().
106 // FIXME: Add statistics about the number of ambiguous statements encountered
107 // and how they were resolved (number of declarations+number of expressions).
109 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
110 // We need tentative parsing...
112 TentativeParsingAction PA(*this);
114 TPR = TryParseSimpleDeclaration();
115 SourceLocation TentativeParseLoc = Tok.getLocation();
119 // In case of an error, let the declaration parsing code handle it.
120 if (TPR == TPResult::Error())
123 // Declarations take precedence over expressions.
124 if (TPR == TPResult::Ambiguous())
125 TPR = TPResult::True();
127 assert(TPR == TPResult::True() || TPR == TPResult::False());
128 return TPR == TPResult::True();
131 /// simple-declaration:
132 /// decl-specifier-seq init-declarator-list[opt] ';'
134 Parser::TPResult Parser::TryParseSimpleDeclaration() {
135 // We know that we have a simple-type-specifier/typename-specifier followed
137 assert(isCXXDeclarationSpecifier() == TPResult::Ambiguous());
139 if (Tok.is(tok::kw_typeof))
140 TryParseTypeofSpecifier();
144 assert(Tok.is(tok::l_paren) && "Expected '('");
146 TPResult TPR = TryParseInitDeclaratorList();
147 if (TPR != TPResult::Ambiguous())
150 if (Tok.isNot(tok::semi))
151 return TPResult::False();
153 return TPResult::Ambiguous();
156 /// init-declarator-list:
158 /// init-declarator-list ',' init-declarator
161 /// declarator initializer[opt]
162 /// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt]
165 /// '=' initializer-clause
166 /// '(' expression-list ')'
168 /// initializer-clause:
169 /// assignment-expression
170 /// '{' initializer-list ','[opt] '}'
173 Parser::TPResult Parser::TryParseInitDeclaratorList() {
174 // GCC only examines the first declarator for disambiguation:
176 // int(x), ++x; // GCC regards it as ill-formed declaration.
178 // Comeau and MSVC will regard the above statement as correct expression.
179 // Clang examines all of the declarators and also regards the above statement
180 // as correct expression.
184 TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/);
185 if (TPR != TPResult::Ambiguous())
188 // [GNU] simple-asm-expr[opt] attributes[opt]
189 if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
190 return TPResult::True();
193 if (Tok.is(tok::l_paren)) {
194 // Parse through the parens.
196 if (!SkipUntil(tok::r_paren))
197 return TPResult::Error();
198 } else if (Tok.is(tok::equal)) {
199 // MSVC won't examine the rest of declarators if '=' is encountered, it
200 // will conclude that it is a declaration.
201 // Comeau and Clang will examine the rest of declarators.
202 // Note that "int(x) = {0}, ++x;" will be interpreted as ill-formed
205 // Parse through the initializer-clause.
206 SkipUntil(tok::comma, true/*StopAtSemi*/, true/*DontConsume*/);
209 if (Tok.isNot(tok::comma))
211 ConsumeToken(); // the comma.
214 return TPResult::Ambiguous();
217 /// isCXXConditionDeclaration - Disambiguates between a declaration or an
218 /// expression for a condition of a if/switch/while/for statement.
219 /// If during the disambiguation process a parsing error is encountered,
220 /// the function returns true to let the declaration parsing code handle it.
224 /// type-specifier-seq declarator '=' assignment-expression
225 /// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
226 /// '=' assignment-expression
228 bool Parser::isCXXConditionDeclaration() {
229 TPResult TPR = isCXXDeclarationSpecifier();
230 if (TPR != TPResult::Ambiguous())
231 return TPR != TPResult::False(); // Returns true for TPResult::True() or
232 // TPResult::Error().
234 // FIXME: Add statistics about the number of ambiguous statements encountered
235 // and how they were resolved (number of declarations+number of expressions).
237 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
238 // We need tentative parsing...
240 TentativeParsingAction PA(*this);
242 // type-specifier-seq
243 if (Tok.is(tok::kw_typeof))
244 TryParseTypeofSpecifier();
247 assert(Tok.is(tok::l_paren) && "Expected '('");
250 TPR = TryParseDeclarator(false/*mayBeAbstract*/);
252 // In case of an error, let the declaration parsing code handle it.
253 if (TPR == TPResult::Error())
254 TPR = TPResult::True();
256 if (TPR == TPResult::Ambiguous()) {
258 // [GNU] simple-asm-expr[opt] attributes[opt]
259 if (Tok.is(tok::equal) ||
260 Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
261 TPR = TPResult::True();
263 TPR = TPResult::False();
268 assert(TPR == TPResult::True() || TPR == TPResult::False());
269 return TPR == TPResult::True();
272 /// \brief Determine whether the next set of tokens contains a type-id.
274 /// The context parameter states what context we're parsing right
275 /// now, which affects how this routine copes with the token
276 /// following the type-id. If the context is TypeIdInParens, we have
277 /// already parsed the '(' and we will cease lookahead when we hit
278 /// the corresponding ')'. If the context is
279 /// TypeIdAsTemplateArgument, we've already parsed the '<' or ','
280 /// before this template argument, and will cease lookahead when we
281 /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id
282 /// and false for an expression. If during the disambiguation
283 /// process a parsing error is encountered, the function returns
284 /// true to let the declaration parsing code handle it.
287 /// type-specifier-seq abstract-declarator[opt]
289 bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
294 // The ambiguity arising from the similarity between a function-style cast and
295 // a type-id can occur in different contexts. The ambiguity appears as a
296 // choice between a function-style cast expression and a declaration of a
297 // type. The resolution is that any construct that could possibly be a type-id
298 // in its syntactic context shall be considered a type-id.
300 TPResult TPR = isCXXDeclarationSpecifier();
301 if (TPR != TPResult::Ambiguous())
302 return TPR != TPResult::False(); // Returns true for TPResult::True() or
303 // TPResult::Error().
305 // FIXME: Add statistics about the number of ambiguous statements encountered
306 // and how they were resolved (number of declarations+number of expressions).
308 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
309 // We need tentative parsing...
311 TentativeParsingAction PA(*this);
313 // type-specifier-seq
314 if (Tok.is(tok::kw_typeof))
315 TryParseTypeofSpecifier();
318 assert(Tok.is(tok::l_paren) && "Expected '('");
321 TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/);
323 // In case of an error, let the declaration parsing code handle it.
324 if (TPR == TPResult::Error())
325 TPR = TPResult::True();
327 if (TPR == TPResult::Ambiguous()) {
328 // We are supposed to be inside parens, so if after the abstract declarator
329 // we encounter a ')' this is a type-id, otherwise it's an expression.
330 if (Context == TypeIdInParens && Tok.is(tok::r_paren)) {
331 TPR = TPResult::True();
334 // We are supposed to be inside a template argument, so if after
335 // the abstract declarator we encounter a '>', '>>' (in C++0x), or
336 // ',', this is a type-id. Otherwise, it's an expression.
337 } else if (Context == TypeIdAsTemplateArgument &&
338 (Tok.is(tok::greater) || Tok.is(tok::comma) ||
339 (getLang().CPlusPlus0x && Tok.is(tok::greatergreater)))) {
340 TPR = TPResult::True();
344 TPR = TPResult::False();
349 assert(TPR == TPResult::True() || TPR == TPResult::False());
350 return TPR == TPResult::True();
353 /// isCXX0XAttributeSpecifier - returns true if this is a C++0x
354 /// attribute-specifier. By default, unless in Obj-C++, only a cursory check is
355 /// performed that will simply return true if a [[ is seen. Currently C++ has no
356 /// syntactical ambiguities from this check, but it may inhibit error recovery.
357 /// If CheckClosing is true, a check is made for closing ]] brackets.
359 /// If given, After is set to the token after the attribute-specifier so that
360 /// appropriate parsing decisions can be made; it is left untouched if false is
363 /// FIXME: If an error is in the closing ]] brackets, the program assumes
364 /// the absence of an attribute-specifier, which can cause very yucky errors
367 /// [C++0x] attribute-specifier:
368 /// '[' '[' attribute-list ']' ']'
370 /// [C++0x] attribute-list:
372 /// attribute-list ',' attribute[opt]
374 /// [C++0x] attribute:
375 /// attribute-token attribute-argument-clause[opt]
377 /// [C++0x] attribute-token:
379 /// attribute-scoped-token
381 /// [C++0x] attribute-scoped-token:
382 /// attribute-namespace '::' identifier
384 /// [C++0x] attribute-namespace:
387 /// [C++0x] attribute-argument-clause:
388 /// '(' balanced-token-seq ')'
390 /// [C++0x] balanced-token-seq:
392 /// balanced-token-seq balanced-token
394 /// [C++0x] balanced-token:
395 /// '(' balanced-token-seq ')'
396 /// '[' balanced-token-seq ']'
397 /// '{' balanced-token-seq '}'
398 /// any token but '(', ')', '[', ']', '{', or '}'
399 bool Parser::isCXX0XAttributeSpecifier (bool CheckClosing,
400 tok::TokenKind *After) {
401 if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square))
404 // No tentative parsing if we don't need to look for ]]
405 if (!CheckClosing && !getLang().ObjC1)
408 struct TentativeReverter {
409 TentativeParsingAction PA;
411 TentativeReverter (Parser& P)
414 ~TentativeReverter () {
419 // Opening brackets were checked for above.
423 // SkipUntil will handle balanced tokens, which are guaranteed in attributes.
424 SkipUntil(tok::r_square, false);
426 if (Tok.isNot(tok::r_square))
431 *After = Tok.getKind();
437 /// direct-declarator
438 /// ptr-operator declarator
440 /// direct-declarator:
442 /// direct-declarator '(' parameter-declaration-clause ')'
443 /// cv-qualifier-seq[opt] exception-specification[opt]
444 /// direct-declarator '[' constant-expression[opt] ']'
445 /// '(' declarator ')'
446 /// [GNU] '(' attributes declarator ')'
448 /// abstract-declarator:
449 /// ptr-operator abstract-declarator[opt]
450 /// direct-abstract-declarator
452 /// direct-abstract-declarator:
453 /// direct-abstract-declarator[opt]
454 /// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
455 /// exception-specification[opt]
456 /// direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
457 /// '(' abstract-declarator ')'
460 /// '*' cv-qualifier-seq[opt]
462 /// [C++0x] '&&' [TODO]
463 /// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
465 /// cv-qualifier-seq:
466 /// cv-qualifier cv-qualifier-seq[opt]
477 /// qualified-id [TODO]
481 /// operator-function-id [TODO]
482 /// conversion-function-id [TODO]
483 /// '~' class-name [TODO]
484 /// template-id [TODO]
486 Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
487 bool mayHaveIdentifier) {
490 // ptr-operator declarator
493 if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier))
494 TryAnnotateCXXScopeToken(true);
496 if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) ||
497 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) {
500 while (Tok.is(tok::kw_const) ||
501 Tok.is(tok::kw_volatile) ||
502 Tok.is(tok::kw_restrict))
509 // direct-declarator:
510 // direct-abstract-declarator:
512 if ((Tok.is(tok::identifier) ||
513 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) &&
516 if (Tok.is(tok::annot_cxxscope))
519 } else if (Tok.is(tok::l_paren)) {
522 (Tok.is(tok::r_paren) || // 'int()' is a function.
523 Tok.is(tok::ellipsis) || // 'int(...)' is a function.
524 isDeclarationSpecifier())) { // 'int(int)' is a function.
525 // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
526 // exception-specification[opt]
527 TPResult TPR = TryParseFunctionDeclarator();
528 if (TPR != TPResult::Ambiguous())
531 // '(' declarator ')'
532 // '(' attributes declarator ')'
533 // '(' abstract-declarator ')'
534 if (Tok.is(tok::kw___attribute))
535 return TPResult::True(); // attributes indicate declaration
536 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
537 if (TPR != TPResult::Ambiguous())
539 if (Tok.isNot(tok::r_paren))
540 return TPResult::False();
543 } else if (!mayBeAbstract) {
544 return TPResult::False();
548 TPResult TPR(TPResult::Ambiguous());
550 if (Tok.is(tok::l_paren)) {
551 // Check whether we have a function declarator or a possible ctor-style
552 // initializer that follows the declarator. Note that ctor-style
553 // initializers are not possible in contexts where abstract declarators
555 if (!mayBeAbstract && !isCXXFunctionDeclarator(false/*warnIfAmbiguous*/))
558 // direct-declarator '(' parameter-declaration-clause ')'
559 // cv-qualifier-seq[opt] exception-specification[opt]
561 TPR = TryParseFunctionDeclarator();
562 } else if (Tok.is(tok::l_square)) {
563 // direct-declarator '[' constant-expression[opt] ']'
564 // direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
565 TPR = TryParseBracketDeclarator();
570 if (TPR != TPResult::Ambiguous())
574 return TPResult::Ambiguous();
577 /// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration
578 /// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could
579 /// be either a decl-specifier or a function-style cast, and TPResult::Error()
580 /// if a parsing error was found and reported.
583 /// storage-class-specifier
585 /// function-specifier
588 /// [C++0x] 'constexpr'
589 /// [GNU] attributes declaration-specifiers[opt]
591 /// storage-class-specifier:
599 /// function-specifier:
608 /// simple-type-specifier
611 /// elaborated-type-specifier
612 /// typename-specifier
615 /// simple-type-specifier:
616 /// '::'[opt] nested-name-specifier[opt] type-name
617 /// '::'[opt] nested-name-specifier 'template'
618 /// simple-template-id [TODO]
630 /// [GNU] typeof-specifier
632 /// [C++0x] 'auto' [TODO]
633 /// [C++0x] 'decltype' ( expression )
640 /// elaborated-type-specifier:
641 /// class-key '::'[opt] nested-name-specifier[opt] identifier
642 /// class-key '::'[opt] nested-name-specifier[opt] 'template'[opt]
643 /// simple-template-id
644 /// 'enum' '::'[opt] nested-name-specifier[opt] identifier
650 /// 'enum' identifier[opt] '{' enumerator-list[opt] '}'
651 /// 'enum' identifier[opt] '{' enumerator-list ',' '}'
654 /// class-head '{' member-specification[opt] '}'
657 /// class-key identifier[opt] base-clause[opt]
658 /// class-key nested-name-specifier identifier base-clause[opt]
659 /// class-key nested-name-specifier[opt] simple-template-id
672 Parser::TPResult Parser::isCXXDeclarationSpecifier() {
673 switch (Tok.getKind()) {
674 case tok::identifier: // foo::bar
675 case tok::kw_typename: // typename T::type
676 // Annotate typenames and C++ scope specifiers. If we get one, just
677 // recurse to handle whatever we get.
678 if (TryAnnotateTypeOrScopeToken())
679 return isCXXDeclarationSpecifier();
680 // Otherwise, not a typename.
681 return TPResult::False();
683 case tok::coloncolon: { // ::foo::bar
684 const Token &Next = NextToken();
685 if (Next.is(tok::kw_new) || // ::new
686 Next.is(tok::kw_delete)) // ::delete
687 return TPResult::False();
689 // Annotate typenames and C++ scope specifiers. If we get one, just
690 // recurse to handle whatever we get.
691 if (TryAnnotateTypeOrScopeToken())
692 return isCXXDeclarationSpecifier();
693 // Otherwise, not a typename.
694 return TPResult::False();
698 // storage-class-specifier
700 // function-specifier
705 case tok::kw_typedef:
706 case tok::kw_constexpr:
707 // storage-class-specifier
708 case tok::kw_register:
711 case tok::kw_mutable:
713 case tok::kw___thread:
714 // function-specifier
716 case tok::kw_virtual:
717 case tok::kw_explicit:
720 // simple-type-specifier
723 // elaborated-type-specifier
724 // typename-specifier
728 // elaborated-type-specifier
736 case tok::kw_volatile:
739 case tok::kw_restrict:
740 case tok::kw__Complex:
741 case tok::kw___attribute:
742 return TPResult::True();
745 case tok::kw___declspec:
746 case tok::kw___cdecl:
747 case tok::kw___stdcall:
748 case tok::kw___fastcall:
750 case tok::kw___ptr64:
751 case tok::kw___forceinline:
752 return TPResult::True();
754 case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed
755 // We've already annotated a scope; try to annotate a type.
756 if (!(TryAnnotateTypeOrScopeToken() && Tok.is(tok::annot_typename)))
757 return TPResult::False();
758 // If that succeeded, fallthrough into the generic simple-type-id case.
760 // The ambiguity resides in a simple-type-specifier/typename-specifier
761 // followed by a '('. The '(' could either be the start of:
763 // direct-declarator:
764 // '(' declarator ')'
766 // direct-abstract-declarator:
767 // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
768 // exception-specification[opt]
769 // '(' abstract-declarator ')'
771 // or part of a function-style cast expression:
773 // simple-type-specifier '(' expression-list[opt] ')'
776 // simple-type-specifier:
779 case tok::kw_wchar_t:
780 case tok::kw_char16_t:
781 case tok::kw_char32_t:
787 case tok::kw_unsigned:
791 case tok::annot_typename:
792 if (NextToken().is(tok::l_paren))
793 return TPResult::Ambiguous();
795 return TPResult::True();
797 // GNU typeof support.
798 case tok::kw_typeof: {
799 if (NextToken().isNot(tok::l_paren))
800 return TPResult::True();
802 TentativeParsingAction PA(*this);
804 TPResult TPR = TryParseTypeofSpecifier();
805 bool isFollowedByParen = Tok.is(tok::l_paren);
809 if (TPR == TPResult::Error())
810 return TPResult::Error();
812 if (isFollowedByParen)
813 return TPResult::Ambiguous();
815 return TPResult::True();
818 // C++0x decltype support.
819 case tok::kw_decltype:
820 return TPResult::True();
823 return TPResult::False();
827 /// [GNU] typeof-specifier:
828 /// 'typeof' '(' expressions ')'
829 /// 'typeof' '(' type-name ')'
831 Parser::TPResult Parser::TryParseTypeofSpecifier() {
832 assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");
835 assert(Tok.is(tok::l_paren) && "Expected '('");
836 // Parse through the parens after 'typeof'.
838 if (!SkipUntil(tok::r_paren))
839 return TPResult::Error();
841 return TPResult::Ambiguous();
844 Parser::TPResult Parser::TryParseDeclarationSpecifier() {
845 TPResult TPR = isCXXDeclarationSpecifier();
846 if (TPR != TPResult::Ambiguous())
849 if (Tok.is(tok::kw_typeof))
850 TryParseTypeofSpecifier();
854 assert(Tok.is(tok::l_paren) && "Expected '('!");
855 return TPResult::Ambiguous();
858 /// isCXXFunctionDeclarator - Disambiguates between a function declarator or
859 /// a constructor-style initializer, when parsing declaration statements.
860 /// Returns true for function declarator and false for constructor-style
862 /// If during the disambiguation process a parsing error is encountered,
863 /// the function returns true to let the declaration parsing code handle it.
865 /// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
866 /// exception-specification[opt]
868 bool Parser::isCXXFunctionDeclarator(bool warnIfAmbiguous) {
871 // The ambiguity arising from the similarity between a function-style cast and
872 // a declaration mentioned in 6.8 can also occur in the context of a
873 // declaration. In that context, the choice is between a function declaration
874 // with a redundant set of parentheses around a parameter name and an object
875 // declaration with a function-style cast as the initializer. Just as for the
876 // ambiguities mentioned in 6.8, the resolution is to consider any construct
877 // that could possibly be a declaration a declaration.
879 TentativeParsingAction PA(*this);
882 TPResult TPR = TryParseParameterDeclarationClause();
883 if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))
884 TPR = TPResult::False();
886 SourceLocation TPLoc = Tok.getLocation();
889 // In case of an error, let the declaration parsing code handle it.
890 if (TPR == TPResult::Error())
893 if (TPR == TPResult::Ambiguous()) {
894 // Function declarator has precedence over constructor-style initializer.
895 // Emit a warning just in case the author intended a variable definition.
897 Diag(Tok, diag::warn_parens_disambiguated_as_function_decl)
898 << SourceRange(Tok.getLocation(), TPLoc);
902 return TPR == TPResult::True();
905 /// parameter-declaration-clause:
906 /// parameter-declaration-list[opt] '...'[opt]
907 /// parameter-declaration-list ',' '...'
909 /// parameter-declaration-list:
910 /// parameter-declaration
911 /// parameter-declaration-list ',' parameter-declaration
913 /// parameter-declaration:
914 /// decl-specifier-seq declarator
915 /// decl-specifier-seq declarator '=' assignment-expression
916 /// decl-specifier-seq abstract-declarator[opt]
917 /// decl-specifier-seq abstract-declarator[opt] '=' assignment-expression
919 Parser::TPResult Parser::TryParseParameterDeclarationClause() {
921 if (Tok.is(tok::r_paren))
922 return TPResult::True();
924 // parameter-declaration-list[opt] '...'[opt]
925 // parameter-declaration-list ',' '...'
927 // parameter-declaration-list:
928 // parameter-declaration
929 // parameter-declaration-list ',' parameter-declaration
933 if (Tok.is(tok::ellipsis)) {
935 return TPResult::True(); // '...' is a sign of a function declarator.
938 // decl-specifier-seq
939 TPResult TPR = TryParseDeclarationSpecifier();
940 if (TPR != TPResult::Ambiguous())
944 // abstract-declarator[opt]
945 TPR = TryParseDeclarator(true/*mayBeAbstract*/);
946 if (TPR != TPResult::Ambiguous())
949 if (Tok.is(tok::equal)) {
950 // '=' assignment-expression
951 // Parse through assignment-expression.
952 tok::TokenKind StopToks[3] ={ tok::comma, tok::ellipsis, tok::r_paren };
953 if (!SkipUntil(StopToks, 3, true/*StopAtSemi*/, true/*DontConsume*/))
954 return TPResult::Error();
957 if (Tok.is(tok::ellipsis)) {
959 return TPResult::True(); // '...' is a sign of a function declarator.
962 if (Tok.isNot(tok::comma))
964 ConsumeToken(); // the comma.
967 return TPResult::Ambiguous();
970 /// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
971 /// parsing as a function declarator.
972 /// If TryParseFunctionDeclarator fully parsed the function declarator, it will
973 /// return TPResult::Ambiguous(), otherwise it will return either False() or
976 /// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
977 /// exception-specification[opt]
979 /// exception-specification:
980 /// 'throw' '(' type-id-list[opt] ')'
982 Parser::TPResult Parser::TryParseFunctionDeclarator() {
984 // The '(' is already parsed.
986 TPResult TPR = TryParseParameterDeclarationClause();
987 if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))
988 TPR = TPResult::False();
990 if (TPR == TPResult::False() || TPR == TPResult::Error())
993 // Parse through the parens.
994 if (!SkipUntil(tok::r_paren))
995 return TPResult::Error();
998 while (Tok.is(tok::kw_const) ||
999 Tok.is(tok::kw_volatile) ||
1000 Tok.is(tok::kw_restrict) )
1003 // exception-specification
1004 if (Tok.is(tok::kw_throw)) {
1006 if (Tok.isNot(tok::l_paren))
1007 return TPResult::Error();
1009 // Parse through the parens after 'throw'.
1011 if (!SkipUntil(tok::r_paren))
1012 return TPResult::Error();
1015 return TPResult::Ambiguous();
1018 /// '[' constant-expression[opt] ']'
1020 Parser::TPResult Parser::TryParseBracketDeclarator() {
1022 if (!SkipUntil(tok::r_square))
1023 return TPResult::Error();
1025 return TPResult::Ambiguous();