blob: 11f1aeb76ff0abdaff0bfb0f64e6d9e17b5891f1 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Guy Benyei11169dd2012-12-18 14:30:41 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the tentative parsing portions of the Parser
10// interfaces, for ambiguity resolution.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Parse/Parser.h"
15#include "clang/Parse/ParseDiagnostic.h"
16#include "clang/Sema/ParsedTemplate.h"
17using namespace clang;
18
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.
22///
23/// declaration-statement:
24/// block-declaration
25///
26/// block-declaration:
27/// simple-declaration
28/// asm-definition
29/// namespace-alias-definition
30/// using-declaration
31/// using-directive
32/// [C++0x] static_assert-declaration
33///
34/// asm-definition:
35/// 'asm' '(' string-literal ')' ';'
36///
37/// namespace-alias-definition:
38/// 'namespace' identifier = qualified-namespace-specifier ';'
39///
40/// using-declaration:
41/// 'using' typename[opt] '::'[opt] nested-name-specifier
42/// unqualified-id ';'
43/// 'using' '::' unqualified-id ;
44///
45/// using-directive:
46/// 'using' 'namespace' '::'[opt] nested-name-specifier[opt]
47/// namespace-name ';'
48///
49bool Parser::isCXXDeclarationStatement() {
50 switch (Tok.getKind()) {
51 // asm-definition
52 case tok::kw_asm:
53 // namespace-alias-definition
54 case tok::kw_namespace:
55 // using-declaration
56 // using-directive
57 case tok::kw_using:
58 // static_assert-declaration
59 case tok::kw_static_assert:
60 case tok::kw__Static_assert:
61 return true;
62 // simple-declaration
63 default:
64 return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false);
65 }
66}
67
68/// isCXXSimpleDeclaration - C++-specialized function that disambiguates
69/// between a simple-declaration or an expression-statement.
70/// If during the disambiguation process a parsing error is encountered,
71/// the function returns true to let the declaration parsing code handle it.
72/// Returns false if the statement is disambiguated as expression.
73///
74/// simple-declaration:
75/// decl-specifier-seq init-declarator-list[opt] ';'
Richard Smithbdb84f32016-07-22 23:36:59 +000076/// decl-specifier-seq ref-qualifier[opt] '[' identifier-list ']'
77/// brace-or-equal-initializer ';' [C++17]
Guy Benyei11169dd2012-12-18 14:30:41 +000078///
79/// (if AllowForRangeDecl specified)
80/// for ( for-range-declaration : for-range-initializer ) statement
Richard Smithbdb84f32016-07-22 23:36:59 +000081///
Fangrui Song6907ce22018-07-30 19:24:48 +000082/// for-range-declaration:
Richard Smithbdb84f32016-07-22 23:36:59 +000083/// decl-specifier-seq declarator
84/// decl-specifier-seq ref-qualifier[opt] '[' identifier-list ']'
Fangrui Song6907ce22018-07-30 19:24:48 +000085///
Richard Smithbdb84f32016-07-22 23:36:59 +000086/// In any of the above cases there can be a preceding attribute-specifier-seq,
87/// but the caller is expected to handle that.
Guy Benyei11169dd2012-12-18 14:30:41 +000088bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {
89 // C++ 6.8p1:
90 // There is an ambiguity in the grammar involving expression-statements and
91 // declarations: An expression-statement with a function-style explicit type
92 // conversion (5.2.3) as its leftmost subexpression can be indistinguishable
93 // from a declaration where the first declarator starts with a '('. In those
94 // cases the statement is a declaration. [Note: To disambiguate, the whole
95 // statement might have to be examined to determine if it is an
96 // expression-statement or a declaration].
97
98 // C++ 6.8p3:
99 // The disambiguation is purely syntactic; that is, the meaning of the names
100 // occurring in such a statement, beyond whether they are type-names or not,
101 // is not generally used in or changed by the disambiguation. Class
102 // templates are instantiated as necessary to determine if a qualified name
103 // is a type-name. Disambiguation precedes parsing, and a statement
104 // disambiguated as a declaration may be an ill-formed declaration.
105
106 // We don't have to parse all of the decl-specifier-seq part. There's only
107 // an ambiguity if the first decl-specifier is
108 // simple-type-specifier/typename-specifier followed by a '(', which may
109 // indicate a function-style cast expression.
Richard Smithee390432014-05-16 01:56:53 +0000110 // isCXXDeclarationSpecifier will return TPResult::Ambiguous only in such
Guy Benyei11169dd2012-12-18 14:30:41 +0000111 // a case.
112
113 bool InvalidAsDeclaration = false;
Richard Smithee390432014-05-16 01:56:53 +0000114 TPResult TPR = isCXXDeclarationSpecifier(TPResult::False,
Guy Benyei11169dd2012-12-18 14:30:41 +0000115 &InvalidAsDeclaration);
Richard Smithee390432014-05-16 01:56:53 +0000116 if (TPR != TPResult::Ambiguous)
117 return TPR != TPResult::False; // Returns true for TPResult::True or
118 // TPResult::Error.
Guy Benyei11169dd2012-12-18 14:30:41 +0000119
120 // FIXME: TryParseSimpleDeclaration doesn't look past the first initializer,
121 // and so gets some cases wrong. We can't carry on if we've already seen
122 // something which makes this statement invalid as a declaration in this case,
123 // since it can cause us to misparse valid code. Revisit this once
124 // TryParseInitDeclaratorList is fixed.
125 if (InvalidAsDeclaration)
126 return false;
127
128 // FIXME: Add statistics about the number of ambiguous statements encountered
129 // and how they were resolved (number of declarations+number of expressions).
130
131 // Ok, we have a simple-type-specifier/typename-specifier followed by a '(',
132 // or an identifier which doesn't resolve as anything. We need tentative
133 // parsing...
Fangrui Song6907ce22018-07-30 19:24:48 +0000134
Richard Smith91b73f22016-06-29 21:06:51 +0000135 {
136 RevertingTentativeParsingAction PA(*this);
137 TPR = TryParseSimpleDeclaration(AllowForRangeDecl);
138 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000139
140 // In case of an error, let the declaration parsing code handle it.
Richard Smithee390432014-05-16 01:56:53 +0000141 if (TPR == TPResult::Error)
Guy Benyei11169dd2012-12-18 14:30:41 +0000142 return true;
143
144 // Declarations take precedence over expressions.
Richard Smithee390432014-05-16 01:56:53 +0000145 if (TPR == TPResult::Ambiguous)
146 TPR = TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +0000147
Richard Smithee390432014-05-16 01:56:53 +0000148 assert(TPR == TPResult::True || TPR == TPResult::False);
149 return TPR == TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +0000150}
151
Richard Smith1fff95c2013-09-12 23:28:08 +0000152/// Try to consume a token sequence that we've already identified as
153/// (potentially) starting a decl-specifier.
154Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
155 switch (Tok.getKind()) {
156 case tok::kw__Atomic:
157 if (NextToken().isNot(tok::l_paren)) {
158 ConsumeToken();
159 break;
160 }
Reid Kleckner4dc0b1a2018-11-01 19:54:45 +0000161 LLVM_FALLTHROUGH;
Richard Smith1fff95c2013-09-12 23:28:08 +0000162 case tok::kw_typeof:
163 case tok::kw___attribute:
164 case tok::kw___underlying_type: {
165 ConsumeToken();
166 if (Tok.isNot(tok::l_paren))
Richard Smithee390432014-05-16 01:56:53 +0000167 return TPResult::Error;
Richard Smith1fff95c2013-09-12 23:28:08 +0000168 ConsumeParen();
Alexey Bataevee6507d2013-11-18 08:17:37 +0000169 if (!SkipUntil(tok::r_paren))
Richard Smithee390432014-05-16 01:56:53 +0000170 return TPResult::Error;
Richard Smith1fff95c2013-09-12 23:28:08 +0000171 break;
172 }
173
174 case tok::kw_class:
175 case tok::kw_struct:
176 case tok::kw_union:
177 case tok::kw___interface:
178 case tok::kw_enum:
179 // elaborated-type-specifier:
180 // class-key attribute-specifier-seq[opt]
181 // nested-name-specifier[opt] identifier
182 // class-key nested-name-specifier[opt] template[opt] simple-template-id
183 // enum nested-name-specifier[opt] identifier
184 //
185 // FIXME: We don't support class-specifiers nor enum-specifiers here.
186 ConsumeToken();
187
188 // Skip attributes.
Daniel Marjamakie59f8d72015-06-18 10:59:26 +0000189 while (Tok.isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,
190 tok::kw_alignas)) {
Richard Smith1fff95c2013-09-12 23:28:08 +0000191 if (Tok.is(tok::l_square)) {
192 ConsumeBracket();
Alexey Bataevee6507d2013-11-18 08:17:37 +0000193 if (!SkipUntil(tok::r_square))
Richard Smithee390432014-05-16 01:56:53 +0000194 return TPResult::Error;
Richard Smith1fff95c2013-09-12 23:28:08 +0000195 } else {
196 ConsumeToken();
197 if (Tok.isNot(tok::l_paren))
Richard Smithee390432014-05-16 01:56:53 +0000198 return TPResult::Error;
Richard Smith1fff95c2013-09-12 23:28:08 +0000199 ConsumeParen();
Alexey Bataevee6507d2013-11-18 08:17:37 +0000200 if (!SkipUntil(tok::r_paren))
Richard Smithee390432014-05-16 01:56:53 +0000201 return TPResult::Error;
Richard Smith1fff95c2013-09-12 23:28:08 +0000202 }
203 }
204
Daniel Marjamakie59f8d72015-06-18 10:59:26 +0000205 if (Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
206 tok::annot_template_id) &&
Nico Weberc29c4832014-12-28 23:24:02 +0000207 TryAnnotateCXXScopeToken())
Richard Smithee390432014-05-16 01:56:53 +0000208 return TPResult::Error;
Richard Smith1fff95c2013-09-12 23:28:08 +0000209 if (Tok.is(tok::annot_cxxscope))
Richard Smithaf3b3252017-05-18 19:21:48 +0000210 ConsumeAnnotationToken();
211 if (Tok.is(tok::identifier))
Richard Smith1fff95c2013-09-12 23:28:08 +0000212 ConsumeToken();
Richard Smithaf3b3252017-05-18 19:21:48 +0000213 else if (Tok.is(tok::annot_template_id))
214 ConsumeAnnotationToken();
215 else
Richard Smithee390432014-05-16 01:56:53 +0000216 return TPResult::Error;
Richard Smith1fff95c2013-09-12 23:28:08 +0000217 break;
218
219 case tok::annot_cxxscope:
Richard Smithaf3b3252017-05-18 19:21:48 +0000220 ConsumeAnnotationToken();
Reid Kleckner4dc0b1a2018-11-01 19:54:45 +0000221 LLVM_FALLTHROUGH;
Richard Smith1fff95c2013-09-12 23:28:08 +0000222 default:
Richard Smithaf3b3252017-05-18 19:21:48 +0000223 ConsumeAnyToken();
Richard Smith1fff95c2013-09-12 23:28:08 +0000224
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000225 if (getLangOpts().ObjC && Tok.is(tok::less))
Richard Smith1fff95c2013-09-12 23:28:08 +0000226 return TryParseProtocolQualifiers();
227 break;
228 }
229
Richard Smithee390432014-05-16 01:56:53 +0000230 return TPResult::Ambiguous;
Richard Smith1fff95c2013-09-12 23:28:08 +0000231}
232
Guy Benyei11169dd2012-12-18 14:30:41 +0000233/// simple-declaration:
234/// decl-specifier-seq init-declarator-list[opt] ';'
235///
236/// (if AllowForRangeDecl specified)
237/// for ( for-range-declaration : for-range-initializer ) statement
Fangrui Song6907ce22018-07-30 19:24:48 +0000238/// for-range-declaration:
Guy Benyei11169dd2012-12-18 14:30:41 +0000239/// attribute-specifier-seqopt type-specifier-seq declarator
240///
241Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {
Richard Smithee390432014-05-16 01:56:53 +0000242 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
243 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +0000244
245 // Two decl-specifiers in a row conclusively disambiguate this as being a
246 // simple-declaration. Don't bother calling isCXXDeclarationSpecifier in the
247 // overwhelmingly common case that the next token is a '('.
248 if (Tok.isNot(tok::l_paren)) {
249 TPResult TPR = isCXXDeclarationSpecifier();
Richard Smithee390432014-05-16 01:56:53 +0000250 if (TPR == TPResult::Ambiguous)
251 return TPResult::True;
252 if (TPR == TPResult::True || TPR == TPResult::Error)
Guy Benyei11169dd2012-12-18 14:30:41 +0000253 return TPR;
Richard Smithee390432014-05-16 01:56:53 +0000254 assert(TPR == TPResult::False);
Guy Benyei11169dd2012-12-18 14:30:41 +0000255 }
256
257 TPResult TPR = TryParseInitDeclaratorList();
Richard Smithee390432014-05-16 01:56:53 +0000258 if (TPR != TPResult::Ambiguous)
Guy Benyei11169dd2012-12-18 14:30:41 +0000259 return TPR;
260
261 if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))
Richard Smithee390432014-05-16 01:56:53 +0000262 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +0000263
Richard Smithee390432014-05-16 01:56:53 +0000264 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +0000265}
266
Richard Smith22c7c412013-03-20 03:35:02 +0000267/// Tentatively parse an init-declarator-list in order to disambiguate it from
268/// an expression.
269///
Guy Benyei11169dd2012-12-18 14:30:41 +0000270/// init-declarator-list:
271/// init-declarator
272/// init-declarator-list ',' init-declarator
273///
274/// init-declarator:
275/// declarator initializer[opt]
276/// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt]
277///
Richard Smith22c7c412013-03-20 03:35:02 +0000278/// initializer:
279/// brace-or-equal-initializer
280/// '(' expression-list ')'
Guy Benyei11169dd2012-12-18 14:30:41 +0000281///
Richard Smith22c7c412013-03-20 03:35:02 +0000282/// brace-or-equal-initializer:
283/// '=' initializer-clause
284/// [C++11] braced-init-list
285///
286/// initializer-clause:
287/// assignment-expression
288/// braced-init-list
289///
290/// braced-init-list:
291/// '{' initializer-list ','[opt] '}'
292/// '{' '}'
Guy Benyei11169dd2012-12-18 14:30:41 +0000293///
294Parser::TPResult Parser::TryParseInitDeclaratorList() {
295 while (1) {
296 // declarator
Justin Bognerd26f95b2015-02-23 22:36:28 +0000297 TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/);
Richard Smithee390432014-05-16 01:56:53 +0000298 if (TPR != TPResult::Ambiguous)
Guy Benyei11169dd2012-12-18 14:30:41 +0000299 return TPR;
300
301 // [GNU] simple-asm-expr[opt] attributes[opt]
Daniel Marjamakie59f8d72015-06-18 10:59:26 +0000302 if (Tok.isOneOf(tok::kw_asm, tok::kw___attribute))
Richard Smithee390432014-05-16 01:56:53 +0000303 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +0000304
305 // initializer[opt]
306 if (Tok.is(tok::l_paren)) {
307 // Parse through the parens.
308 ConsumeParen();
Alexey Bataevee6507d2013-11-18 08:17:37 +0000309 if (!SkipUntil(tok::r_paren, StopAtSemi))
Richard Smithee390432014-05-16 01:56:53 +0000310 return TPResult::Error;
Richard Smith22c7c412013-03-20 03:35:02 +0000311 } else if (Tok.is(tok::l_brace)) {
312 // A left-brace here is sufficient to disambiguate the parse; an
313 // expression can never be followed directly by a braced-init-list.
Richard Smithee390432014-05-16 01:56:53 +0000314 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +0000315 } else if (Tok.is(tok::equal) || isTokIdentifier_in()) {
Richard Smith1fff95c2013-09-12 23:28:08 +0000316 // MSVC and g++ won't examine the rest of declarators if '=' is
Guy Benyei11169dd2012-12-18 14:30:41 +0000317 // encountered; they just conclude that we have a declaration.
318 // EDG parses the initializer completely, which is the proper behavior
319 // for this case.
320 //
321 // At present, Clang follows MSVC and g++, since the parser does not have
322 // the ability to parse an expression fully without recording the
323 // results of that parse.
Richard Smith1fff95c2013-09-12 23:28:08 +0000324 // FIXME: Handle this case correctly.
325 //
326 // Also allow 'in' after an Objective-C declaration as in:
327 // for (int (^b)(void) in array). Ideally this should be done in the
Guy Benyei11169dd2012-12-18 14:30:41 +0000328 // context of parsing for-init-statement of a foreach statement only. But,
329 // in any other context 'in' is invalid after a declaration and parser
330 // issues the error regardless of outcome of this decision.
Richard Smith1fff95c2013-09-12 23:28:08 +0000331 // FIXME: Change if above assumption does not hold.
Richard Smithee390432014-05-16 01:56:53 +0000332 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +0000333 }
334
Alp Toker97650562014-01-10 11:19:30 +0000335 if (!TryConsumeToken(tok::comma))
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 break;
Guy Benyei11169dd2012-12-18 14:30:41 +0000337 }
338
Richard Smithee390432014-05-16 01:56:53 +0000339 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +0000340}
341
Richard Smithc7a05a92016-06-29 21:17:59 +0000342struct Parser::ConditionDeclarationOrInitStatementState {
343 Parser &P;
344 bool CanBeExpression = true;
345 bool CanBeCondition = true;
346 bool CanBeInitStatement;
Richard Smith8baa5002018-09-28 18:44:09 +0000347 bool CanBeForRangeDecl;
Richard Smithc7a05a92016-06-29 21:17:59 +0000348
Richard Smith8baa5002018-09-28 18:44:09 +0000349 ConditionDeclarationOrInitStatementState(Parser &P, bool CanBeInitStatement,
350 bool CanBeForRangeDecl)
351 : P(P), CanBeInitStatement(CanBeInitStatement),
352 CanBeForRangeDecl(CanBeForRangeDecl) {}
353
354 bool resolved() {
355 return CanBeExpression + CanBeCondition + CanBeInitStatement +
356 CanBeForRangeDecl < 2;
357 }
Richard Smithc7a05a92016-06-29 21:17:59 +0000358
359 void markNotExpression() {
360 CanBeExpression = false;
361
Richard Smith8baa5002018-09-28 18:44:09 +0000362 if (!resolved()) {
Richard Smithc7a05a92016-06-29 21:17:59 +0000363 // FIXME: Unify the parsing codepaths for condition variables and
364 // simple-declarations so that we don't need to eagerly figure out which
365 // kind we have here. (Just parse init-declarators until we reach a
366 // semicolon or right paren.)
367 RevertingTentativeParsingAction PA(P);
Richard Smith8baa5002018-09-28 18:44:09 +0000368 if (CanBeForRangeDecl) {
369 // Skip until we hit a ')', ';', or a ':' with no matching '?'.
370 // The final case is a for range declaration, the rest are not.
371 while (true) {
372 unsigned QuestionColonDepth = 0;
373 P.SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
374 StopBeforeMatch);
375 if (P.Tok.is(tok::question))
376 ++QuestionColonDepth;
377 else if (P.Tok.is(tok::colon)) {
378 if (QuestionColonDepth)
379 --QuestionColonDepth;
380 else {
381 CanBeCondition = CanBeInitStatement = false;
382 return;
383 }
384 } else {
385 CanBeForRangeDecl = false;
386 break;
387 }
388 P.ConsumeToken();
389 }
390 } else {
391 // Just skip until we hit a ')' or ';'.
392 P.SkipUntil(tok::r_paren, tok::semi, StopBeforeMatch);
393 }
Richard Smithc7a05a92016-06-29 21:17:59 +0000394 if (P.Tok.isNot(tok::r_paren))
Richard Smith8baa5002018-09-28 18:44:09 +0000395 CanBeCondition = CanBeForRangeDecl = false;
Richard Smithc7a05a92016-06-29 21:17:59 +0000396 if (P.Tok.isNot(tok::semi))
397 CanBeInitStatement = false;
398 }
399 }
400
401 bool markNotCondition() {
402 CanBeCondition = false;
Richard Smith8baa5002018-09-28 18:44:09 +0000403 return resolved();
404 }
405
406 bool markNotForRangeDecl() {
407 CanBeForRangeDecl = false;
408 return resolved();
Richard Smithc7a05a92016-06-29 21:17:59 +0000409 }
410
411 bool update(TPResult IsDecl) {
412 switch (IsDecl) {
413 case TPResult::True:
414 markNotExpression();
Richard Smith8baa5002018-09-28 18:44:09 +0000415 assert(resolved() && "can't continue after tentative parsing bails out");
416 break;
Richard Smithc7a05a92016-06-29 21:17:59 +0000417 case TPResult::False:
Richard Smith8baa5002018-09-28 18:44:09 +0000418 CanBeCondition = CanBeInitStatement = CanBeForRangeDecl = false;
419 break;
Richard Smithc7a05a92016-06-29 21:17:59 +0000420 case TPResult::Ambiguous:
Richard Smith8baa5002018-09-28 18:44:09 +0000421 break;
Richard Smithc7a05a92016-06-29 21:17:59 +0000422 case TPResult::Error:
Richard Smith8baa5002018-09-28 18:44:09 +0000423 CanBeExpression = CanBeCondition = CanBeInitStatement =
424 CanBeForRangeDecl = false;
425 break;
Richard Smithc7a05a92016-06-29 21:17:59 +0000426 }
Richard Smith8baa5002018-09-28 18:44:09 +0000427 return resolved();
Richard Smithc7a05a92016-06-29 21:17:59 +0000428 }
429
430 ConditionOrInitStatement result() const {
Richard Smith8baa5002018-09-28 18:44:09 +0000431 assert(CanBeExpression + CanBeCondition + CanBeInitStatement +
432 CanBeForRangeDecl < 2 &&
Richard Smithc7a05a92016-06-29 21:17:59 +0000433 "result called but not yet resolved");
434 if (CanBeExpression)
435 return ConditionOrInitStatement::Expression;
436 if (CanBeCondition)
437 return ConditionOrInitStatement::ConditionDecl;
438 if (CanBeInitStatement)
439 return ConditionOrInitStatement::InitStmtDecl;
Richard Smith8baa5002018-09-28 18:44:09 +0000440 if (CanBeForRangeDecl)
441 return ConditionOrInitStatement::ForRangeDecl;
Richard Smithc7a05a92016-06-29 21:17:59 +0000442 return ConditionOrInitStatement::Error;
443 }
444};
445
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000446/// Disambiguates between a declaration in a condition, a
Richard Smithc7a05a92016-06-29 21:17:59 +0000447/// simple-declaration in an init-statement, and an expression for
448/// a condition of a if/switch statement.
Guy Benyei11169dd2012-12-18 14:30:41 +0000449///
450/// condition:
451/// expression
452/// type-specifier-seq declarator '=' assignment-expression
453/// [C++11] type-specifier-seq declarator '=' initializer-clause
454/// [C++11] type-specifier-seq declarator braced-init-list
455/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
456/// '=' assignment-expression
Richard Smithc7a05a92016-06-29 21:17:59 +0000457/// simple-declaration:
458/// decl-specifier-seq init-declarator-list[opt] ';'
Guy Benyei11169dd2012-12-18 14:30:41 +0000459///
Richard Smithc7a05a92016-06-29 21:17:59 +0000460/// Note that, unlike isCXXSimpleDeclaration, we must disambiguate all the way
461/// to the ';' to disambiguate cases like 'int(x))' (an expression) from
462/// 'int(x);' (a simple-declaration in an init-statement).
463Parser::ConditionOrInitStatement
Richard Smith8baa5002018-09-28 18:44:09 +0000464Parser::isCXXConditionDeclarationOrInitStatement(bool CanBeInitStatement,
465 bool CanBeForRangeDecl) {
466 ConditionDeclarationOrInitStatementState State(*this, CanBeInitStatement,
467 CanBeForRangeDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000468
Richard Smithc7a05a92016-06-29 21:17:59 +0000469 if (State.update(isCXXDeclarationSpecifier()))
470 return State.result();
Guy Benyei11169dd2012-12-18 14:30:41 +0000471
Richard Smithc7a05a92016-06-29 21:17:59 +0000472 // It might be a declaration; we need tentative parsing.
Richard Smith91b73f22016-06-29 21:06:51 +0000473 RevertingTentativeParsingAction PA(*this);
Guy Benyei11169dd2012-12-18 14:30:41 +0000474
Richard Smithc7a05a92016-06-29 21:17:59 +0000475 // FIXME: A tag definition unambiguously tells us this is an init-statement.
476 if (State.update(TryConsumeDeclarationSpecifier()))
477 return State.result();
Guy Benyei11169dd2012-12-18 14:30:41 +0000478 assert(Tok.is(tok::l_paren) && "Expected '('");
479
Richard Smithc7a05a92016-06-29 21:17:59 +0000480 while (true) {
481 // Consume a declarator.
482 if (State.update(TryParseDeclarator(false/*mayBeAbstract*/)))
483 return State.result();
Guy Benyei11169dd2012-12-18 14:30:41 +0000484
Richard Smithc7a05a92016-06-29 21:17:59 +0000485 // Attributes, asm label, or an initializer imply this is not an expression.
486 // FIXME: Disambiguate properly after an = instead of assuming that it's a
487 // valid declaration.
488 if (Tok.isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||
489 (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))) {
490 State.markNotExpression();
491 return State.result();
492 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000493
Richard Smith8baa5002018-09-28 18:44:09 +0000494 // A colon here identifies a for-range declaration.
495 if (State.CanBeForRangeDecl && Tok.is(tok::colon))
496 return ConditionOrInitStatement::ForRangeDecl;
497
Richard Smithc7a05a92016-06-29 21:17:59 +0000498 // At this point, it can't be a condition any more, because a condition
499 // must have a brace-or-equal-initializer.
500 if (State.markNotCondition())
501 return State.result();
502
Richard Smith8baa5002018-09-28 18:44:09 +0000503 // Likewise, it can't be a for-range declaration any more.
504 if (State.markNotForRangeDecl())
505 return State.result();
506
Richard Smithc7a05a92016-06-29 21:17:59 +0000507 // A parenthesized initializer could be part of an expression or a
508 // simple-declaration.
509 if (Tok.is(tok::l_paren)) {
510 ConsumeParen();
511 SkipUntil(tok::r_paren, StopAtSemi);
512 }
513
514 if (!TryConsumeToken(tok::comma))
515 break;
Guy Benyei11169dd2012-12-18 14:30:41 +0000516 }
517
Richard Smithc7a05a92016-06-29 21:17:59 +0000518 // We reached the end. If it can now be some kind of decl, then it is.
519 if (State.CanBeCondition && Tok.is(tok::r_paren))
520 return ConditionOrInitStatement::ConditionDecl;
521 else if (State.CanBeInitStatement && Tok.is(tok::semi))
522 return ConditionOrInitStatement::InitStmtDecl;
523 else
524 return ConditionOrInitStatement::Expression;
Guy Benyei11169dd2012-12-18 14:30:41 +0000525}
526
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000527 /// Determine whether the next set of tokens contains a type-id.
Guy Benyei11169dd2012-12-18 14:30:41 +0000528 ///
529 /// The context parameter states what context we're parsing right
530 /// now, which affects how this routine copes with the token
531 /// following the type-id. If the context is TypeIdInParens, we have
532 /// already parsed the '(' and we will cease lookahead when we hit
533 /// the corresponding ')'. If the context is
534 /// TypeIdAsTemplateArgument, we've already parsed the '<' or ','
535 /// before this template argument, and will cease lookahead when we
Hubert Tong605eaca2017-05-20 00:21:55 +0000536 /// hit a '>', '>>' (in C++0x), or ','; or, in C++0x, an ellipsis immediately
537 /// preceding such. Returns true for a type-id and false for an expression.
538 /// If during the disambiguation process a parsing error is encountered,
539 /// the function returns true to let the declaration parsing code handle it.
Guy Benyei11169dd2012-12-18 14:30:41 +0000540 ///
541 /// type-id:
542 /// type-specifier-seq abstract-declarator[opt]
543 ///
544bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
545
546 isAmbiguous = false;
547
548 // C++ 8.2p2:
549 // The ambiguity arising from the similarity between a function-style cast and
550 // a type-id can occur in different contexts. The ambiguity appears as a
551 // choice between a function-style cast expression and a declaration of a
552 // type. The resolution is that any construct that could possibly be a type-id
553 // in its syntactic context shall be considered a type-id.
554
555 TPResult TPR = isCXXDeclarationSpecifier();
Richard Smithee390432014-05-16 01:56:53 +0000556 if (TPR != TPResult::Ambiguous)
557 return TPR != TPResult::False; // Returns true for TPResult::True or
558 // TPResult::Error.
Guy Benyei11169dd2012-12-18 14:30:41 +0000559
560 // FIXME: Add statistics about the number of ambiguous statements encountered
561 // and how they were resolved (number of declarations+number of expressions).
562
563 // Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
564 // We need tentative parsing...
565
Richard Smith91b73f22016-06-29 21:06:51 +0000566 RevertingTentativeParsingAction PA(*this);
Guy Benyei11169dd2012-12-18 14:30:41 +0000567
568 // type-specifier-seq
Richard Smith1fff95c2013-09-12 23:28:08 +0000569 TryConsumeDeclarationSpecifier();
Guy Benyei11169dd2012-12-18 14:30:41 +0000570 assert(Tok.is(tok::l_paren) && "Expected '('");
571
572 // declarator
Justin Bognerd26f95b2015-02-23 22:36:28 +0000573 TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/);
Guy Benyei11169dd2012-12-18 14:30:41 +0000574
575 // In case of an error, let the declaration parsing code handle it.
Richard Smithee390432014-05-16 01:56:53 +0000576 if (TPR == TPResult::Error)
577 TPR = TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +0000578
Richard Smithee390432014-05-16 01:56:53 +0000579 if (TPR == TPResult::Ambiguous) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000580 // We are supposed to be inside parens, so if after the abstract declarator
581 // we encounter a ')' this is a type-id, otherwise it's an expression.
582 if (Context == TypeIdInParens && Tok.is(tok::r_paren)) {
Richard Smithee390432014-05-16 01:56:53 +0000583 TPR = TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +0000584 isAmbiguous = true;
585
586 // We are supposed to be inside a template argument, so if after
587 // the abstract declarator we encounter a '>', '>>' (in C++0x), or
Hubert Tong605eaca2017-05-20 00:21:55 +0000588 // ','; or, in C++0x, an ellipsis immediately preceding such, this
589 // is a type-id. Otherwise, it's an expression.
Guy Benyei11169dd2012-12-18 14:30:41 +0000590 } else if (Context == TypeIdAsTemplateArgument &&
Daniel Marjamakie59f8d72015-06-18 10:59:26 +0000591 (Tok.isOneOf(tok::greater, tok::comma) ||
Hubert Tong605eaca2017-05-20 00:21:55 +0000592 (getLangOpts().CPlusPlus11 &&
593 (Tok.is(tok::greatergreater) ||
594 (Tok.is(tok::ellipsis) &&
595 NextToken().isOneOf(tok::greater, tok::greatergreater,
596 tok::comma)))))) {
Richard Smithee390432014-05-16 01:56:53 +0000597 TPR = TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +0000598 isAmbiguous = true;
599
600 } else
Richard Smithee390432014-05-16 01:56:53 +0000601 TPR = TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602 }
603
Richard Smithee390432014-05-16 01:56:53 +0000604 assert(TPR == TPResult::True || TPR == TPResult::False);
605 return TPR == TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +0000606}
607
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000608/// Returns true if this is a C++11 attribute-specifier. Per
Guy Benyei11169dd2012-12-18 14:30:41 +0000609/// C++11 [dcl.attr.grammar]p6, two consecutive left square bracket tokens
610/// always introduce an attribute. In Objective-C++11, this rule does not
611/// apply if either '[' begins a message-send.
612///
613/// If Disambiguate is true, we try harder to determine whether a '[[' starts
614/// an attribute-specifier, and return CAK_InvalidAttributeSpecifier if not.
615///
616/// If OuterMightBeMessageSend is true, we assume the outer '[' is either an
617/// Obj-C message send or the start of an attribute. Otherwise, we assume it
618/// is not an Obj-C message send.
619///
620/// C++11 [dcl.attr.grammar]:
621///
622/// attribute-specifier:
623/// '[' '[' attribute-list ']' ']'
624/// alignment-specifier
625///
626/// attribute-list:
627/// attribute[opt]
628/// attribute-list ',' attribute[opt]
629/// attribute '...'
630/// attribute-list ',' attribute '...'
631///
632/// attribute:
633/// attribute-token attribute-argument-clause[opt]
634///
635/// attribute-token:
636/// identifier
637/// identifier '::' identifier
638///
639/// attribute-argument-clause:
640/// '(' balanced-token-seq ')'
641Parser::CXX11AttributeKind
642Parser::isCXX11AttributeSpecifier(bool Disambiguate,
643 bool OuterMightBeMessageSend) {
644 if (Tok.is(tok::kw_alignas))
645 return CAK_AttributeSpecifier;
646
647 if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square))
648 return CAK_NotAttributeSpecifier;
649
650 // No tentative parsing if we don't need to look for ']]' or a lambda.
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000651 if (!Disambiguate && !getLangOpts().ObjC)
Guy Benyei11169dd2012-12-18 14:30:41 +0000652 return CAK_AttributeSpecifier;
653
Richard Smith91b73f22016-06-29 21:06:51 +0000654 RevertingTentativeParsingAction PA(*this);
Guy Benyei11169dd2012-12-18 14:30:41 +0000655
656 // Opening brackets were checked for above.
657 ConsumeBracket();
658
659 // Outside Obj-C++11, treat anything with a matching ']]' as an attribute.
Erik Pilkingtonfa983902018-10-30 20:31:30 +0000660 if (!getLangOpts().ObjC) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000661 ConsumeBracket();
662
Alexey Bataevee6507d2013-11-18 08:17:37 +0000663 bool IsAttribute = SkipUntil(tok::r_square);
Guy Benyei11169dd2012-12-18 14:30:41 +0000664 IsAttribute &= Tok.is(tok::r_square);
665
Guy Benyei11169dd2012-12-18 14:30:41 +0000666 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;
667 }
668
669 // In Obj-C++11, we need to distinguish four situations:
670 // 1a) int x[[attr]]; C++11 attribute.
671 // 1b) [[attr]]; C++11 statement attribute.
672 // 2) int x[[obj](){ return 1; }()]; Lambda in array size/index.
673 // 3a) int x[[obj get]]; Message send in array size/index.
674 // 3b) [[Class alloc] init]; Message send in message send.
675 // 4) [[obj]{ return self; }() doStuff]; Lambda in message send.
676 // (1) is an attribute, (2) is ill-formed, and (3) and (4) are accepted.
677
678 // If we have a lambda-introducer, then this is definitely not a message send.
679 // FIXME: If this disambiguation is too slow, fold the tentative lambda parse
680 // into the tentative attribute parse below.
681 LambdaIntroducer Intro;
682 if (!TryParseLambdaIntroducer(Intro)) {
683 // A lambda cannot end with ']]', and an attribute must.
684 bool IsAttribute = Tok.is(tok::r_square);
685
Guy Benyei11169dd2012-12-18 14:30:41 +0000686 if (IsAttribute)
687 // Case 1: C++11 attribute.
688 return CAK_AttributeSpecifier;
689
690 if (OuterMightBeMessageSend)
691 // Case 4: Lambda in message send.
692 return CAK_NotAttributeSpecifier;
693
694 // Case 2: Lambda in array size / index.
695 return CAK_InvalidAttributeSpecifier;
696 }
697
698 ConsumeBracket();
699
700 // If we don't have a lambda-introducer, then we have an attribute or a
701 // message-send.
702 bool IsAttribute = true;
703 while (Tok.isNot(tok::r_square)) {
704 if (Tok.is(tok::comma)) {
705 // Case 1: Stray commas can only occur in attributes.
Guy Benyei11169dd2012-12-18 14:30:41 +0000706 return CAK_AttributeSpecifier;
707 }
708
709 // Parse the attribute-token, if present.
710 // C++11 [dcl.attr.grammar]:
711 // If a keyword or an alternative token that satisfies the syntactic
712 // requirements of an identifier is contained in an attribute-token,
713 // it is considered an identifier.
714 SourceLocation Loc;
715 if (!TryParseCXX11AttributeIdentifier(Loc)) {
716 IsAttribute = false;
717 break;
718 }
719 if (Tok.is(tok::coloncolon)) {
720 ConsumeToken();
721 if (!TryParseCXX11AttributeIdentifier(Loc)) {
722 IsAttribute = false;
723 break;
724 }
725 }
726
727 // Parse the attribute-argument-clause, if present.
728 if (Tok.is(tok::l_paren)) {
729 ConsumeParen();
Alexey Bataevee6507d2013-11-18 08:17:37 +0000730 if (!SkipUntil(tok::r_paren)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000731 IsAttribute = false;
732 break;
733 }
734 }
735
Alp Toker97650562014-01-10 11:19:30 +0000736 TryConsumeToken(tok::ellipsis);
Guy Benyei11169dd2012-12-18 14:30:41 +0000737
Alp Toker97650562014-01-10 11:19:30 +0000738 if (!TryConsumeToken(tok::comma))
Guy Benyei11169dd2012-12-18 14:30:41 +0000739 break;
Guy Benyei11169dd2012-12-18 14:30:41 +0000740 }
741
742 // An attribute must end ']]'.
743 if (IsAttribute) {
744 if (Tok.is(tok::r_square)) {
745 ConsumeBracket();
746 IsAttribute = Tok.is(tok::r_square);
747 } else {
748 IsAttribute = false;
749 }
750 }
751
Guy Benyei11169dd2012-12-18 14:30:41 +0000752 if (IsAttribute)
753 // Case 1: C++11 statement attribute.
754 return CAK_AttributeSpecifier;
755
756 // Case 3: Message send.
757 return CAK_NotAttributeSpecifier;
758}
759
Richard Smith1fff95c2013-09-12 23:28:08 +0000760Parser::TPResult Parser::TryParsePtrOperatorSeq() {
761 while (true) {
Daniel Marjamakie59f8d72015-06-18 10:59:26 +0000762 if (Tok.isOneOf(tok::coloncolon, tok::identifier))
Richard Smith1fff95c2013-09-12 23:28:08 +0000763 if (TryAnnotateCXXScopeToken(true))
Richard Smithee390432014-05-16 01:56:53 +0000764 return TPResult::Error;
Richard Smith1fff95c2013-09-12 23:28:08 +0000765
Daniel Marjamakie59f8d72015-06-18 10:59:26 +0000766 if (Tok.isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||
Richard Smith1fff95c2013-09-12 23:28:08 +0000767 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) {
768 // ptr-operator
Richard Smithaf3b3252017-05-18 19:21:48 +0000769 ConsumeAnyToken();
Douglas Gregor261a89b2015-06-19 17:51:05 +0000770 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,
Douglas Gregoraea7afd2015-06-24 22:02:08 +0000771 tok::kw__Nonnull, tok::kw__Nullable,
772 tok::kw__Null_unspecified))
Richard Smith1fff95c2013-09-12 23:28:08 +0000773 ConsumeToken();
774 } else {
Justin Bognerd26f95b2015-02-23 22:36:28 +0000775 return TPResult::True;
Richard Smith1fff95c2013-09-12 23:28:08 +0000776 }
777 }
778}
779
780/// operator-function-id:
781/// 'operator' operator
782///
783/// operator: one of
784/// new delete new[] delete[] + - * / % ^ [...]
785///
786/// conversion-function-id:
787/// 'operator' conversion-type-id
788///
789/// conversion-type-id:
790/// type-specifier-seq conversion-declarator[opt]
791///
792/// conversion-declarator:
793/// ptr-operator conversion-declarator[opt]
794///
795/// literal-operator-id:
796/// 'operator' string-literal identifier
797/// 'operator' user-defined-string-literal
798Parser::TPResult Parser::TryParseOperatorId() {
799 assert(Tok.is(tok::kw_operator));
800 ConsumeToken();
801
802 // Maybe this is an operator-function-id.
803 switch (Tok.getKind()) {
804 case tok::kw_new: case tok::kw_delete:
805 ConsumeToken();
806 if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) {
807 ConsumeBracket();
808 ConsumeBracket();
809 }
Richard Smithee390432014-05-16 01:56:53 +0000810 return TPResult::True;
Richard Smith1fff95c2013-09-12 23:28:08 +0000811
812#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
813 case tok::Token:
814#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
815#include "clang/Basic/OperatorKinds.def"
816 ConsumeToken();
Richard Smithee390432014-05-16 01:56:53 +0000817 return TPResult::True;
Richard Smith1fff95c2013-09-12 23:28:08 +0000818
819 case tok::l_square:
820 if (NextToken().is(tok::r_square)) {
821 ConsumeBracket();
822 ConsumeBracket();
Richard Smithee390432014-05-16 01:56:53 +0000823 return TPResult::True;
Richard Smith1fff95c2013-09-12 23:28:08 +0000824 }
825 break;
826
827 case tok::l_paren:
828 if (NextToken().is(tok::r_paren)) {
829 ConsumeParen();
830 ConsumeParen();
Richard Smithee390432014-05-16 01:56:53 +0000831 return TPResult::True;
Richard Smith1fff95c2013-09-12 23:28:08 +0000832 }
833 break;
834
835 default:
836 break;
837 }
838
839 // Maybe this is a literal-operator-id.
840 if (getLangOpts().CPlusPlus11 && isTokenStringLiteral()) {
841 bool FoundUDSuffix = false;
842 do {
843 FoundUDSuffix |= Tok.hasUDSuffix();
844 ConsumeStringToken();
845 } while (isTokenStringLiteral());
846
847 if (!FoundUDSuffix) {
848 if (Tok.is(tok::identifier))
849 ConsumeToken();
850 else
Richard Smithee390432014-05-16 01:56:53 +0000851 return TPResult::Error;
Richard Smith1fff95c2013-09-12 23:28:08 +0000852 }
Richard Smithee390432014-05-16 01:56:53 +0000853 return TPResult::True;
Richard Smith1fff95c2013-09-12 23:28:08 +0000854 }
855
856 // Maybe this is a conversion-function-id.
857 bool AnyDeclSpecifiers = false;
858 while (true) {
859 TPResult TPR = isCXXDeclarationSpecifier();
Richard Smithee390432014-05-16 01:56:53 +0000860 if (TPR == TPResult::Error)
Richard Smith1fff95c2013-09-12 23:28:08 +0000861 return TPR;
Richard Smithee390432014-05-16 01:56:53 +0000862 if (TPR == TPResult::False) {
Richard Smith1fff95c2013-09-12 23:28:08 +0000863 if (!AnyDeclSpecifiers)
Richard Smithee390432014-05-16 01:56:53 +0000864 return TPResult::Error;
Richard Smith1fff95c2013-09-12 23:28:08 +0000865 break;
866 }
Richard Smithee390432014-05-16 01:56:53 +0000867 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
868 return TPResult::Error;
Richard Smith1fff95c2013-09-12 23:28:08 +0000869 AnyDeclSpecifiers = true;
870 }
Justin Bognerd26f95b2015-02-23 22:36:28 +0000871 return TryParsePtrOperatorSeq();
Richard Smith1fff95c2013-09-12 23:28:08 +0000872}
873
Guy Benyei11169dd2012-12-18 14:30:41 +0000874/// declarator:
875/// direct-declarator
876/// ptr-operator declarator
877///
878/// direct-declarator:
879/// declarator-id
880/// direct-declarator '(' parameter-declaration-clause ')'
881/// cv-qualifier-seq[opt] exception-specification[opt]
882/// direct-declarator '[' constant-expression[opt] ']'
883/// '(' declarator ')'
884/// [GNU] '(' attributes declarator ')'
885///
886/// abstract-declarator:
887/// ptr-operator abstract-declarator[opt]
888/// direct-abstract-declarator
Guy Benyei11169dd2012-12-18 14:30:41 +0000889///
890/// direct-abstract-declarator:
891/// direct-abstract-declarator[opt]
Hubert Tong605eaca2017-05-20 00:21:55 +0000892/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
Guy Benyei11169dd2012-12-18 14:30:41 +0000893/// exception-specification[opt]
894/// direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
895/// '(' abstract-declarator ')'
Hubert Tong605eaca2017-05-20 00:21:55 +0000896/// [C++0x] ...
Guy Benyei11169dd2012-12-18 14:30:41 +0000897///
898/// ptr-operator:
899/// '*' cv-qualifier-seq[opt]
900/// '&'
901/// [C++0x] '&&' [TODO]
902/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
903///
904/// cv-qualifier-seq:
905/// cv-qualifier cv-qualifier-seq[opt]
906///
907/// cv-qualifier:
908/// 'const'
909/// 'volatile'
910///
911/// declarator-id:
912/// '...'[opt] id-expression
913///
914/// id-expression:
915/// unqualified-id
916/// qualified-id [TODO]
917///
918/// unqualified-id:
919/// identifier
Richard Smith1fff95c2013-09-12 23:28:08 +0000920/// operator-function-id
921/// conversion-function-id
922/// literal-operator-id
Guy Benyei11169dd2012-12-18 14:30:41 +0000923/// '~' class-name [TODO]
Richard Smith1fff95c2013-09-12 23:28:08 +0000924/// '~' decltype-specifier [TODO]
Guy Benyei11169dd2012-12-18 14:30:41 +0000925/// template-id [TODO]
926///
Justin Bognerd26f95b2015-02-23 22:36:28 +0000927Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
Richard Smithe303e352018-02-02 22:24:54 +0000928 bool mayHaveIdentifier,
929 bool mayHaveDirectInit) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000930 // declarator:
931 // direct-declarator
932 // ptr-operator declarator
Justin Bognerd26f95b2015-02-23 22:36:28 +0000933 if (TryParsePtrOperatorSeq() == TPResult::Error)
934 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +0000935
936 // direct-declarator:
937 // direct-abstract-declarator:
938 if (Tok.is(tok::ellipsis))
939 ConsumeToken();
Richard Smith1fff95c2013-09-12 23:28:08 +0000940
Daniel Marjamakie59f8d72015-06-18 10:59:26 +0000941 if ((Tok.isOneOf(tok::identifier, tok::kw_operator) ||
Richard Smith1fff95c2013-09-12 23:28:08 +0000942 (Tok.is(tok::annot_cxxscope) && (NextToken().is(tok::identifier) ||
943 NextToken().is(tok::kw_operator)))) &&
Justin Bognerd26f95b2015-02-23 22:36:28 +0000944 mayHaveIdentifier) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000945 // declarator-id
946 if (Tok.is(tok::annot_cxxscope))
Richard Smithaf3b3252017-05-18 19:21:48 +0000947 ConsumeAnnotationToken();
Richard Smith1fff95c2013-09-12 23:28:08 +0000948 else if (Tok.is(tok::identifier))
Guy Benyei11169dd2012-12-18 14:30:41 +0000949 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
Richard Smith1fff95c2013-09-12 23:28:08 +0000950 if (Tok.is(tok::kw_operator)) {
Richard Smithee390432014-05-16 01:56:53 +0000951 if (TryParseOperatorId() == TPResult::Error)
952 return TPResult::Error;
Richard Smith1fff95c2013-09-12 23:28:08 +0000953 } else
954 ConsumeToken();
Guy Benyei11169dd2012-12-18 14:30:41 +0000955 } else if (Tok.is(tok::l_paren)) {
956 ConsumeParen();
Justin Bognerd26f95b2015-02-23 22:36:28 +0000957 if (mayBeAbstract &&
Guy Benyei11169dd2012-12-18 14:30:41 +0000958 (Tok.is(tok::r_paren) || // 'int()' is a function.
959 // 'int(...)' is a function.
960 (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren)) ||
961 isDeclarationSpecifier())) { // 'int(int)' is a function.
962 // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
963 // exception-specification[opt]
Justin Bognerd26f95b2015-02-23 22:36:28 +0000964 TPResult TPR = TryParseFunctionDeclarator();
Richard Smithee390432014-05-16 01:56:53 +0000965 if (TPR != TPResult::Ambiguous)
Guy Benyei11169dd2012-12-18 14:30:41 +0000966 return TPR;
967 } else {
968 // '(' declarator ')'
969 // '(' attributes declarator ')'
970 // '(' abstract-declarator ')'
Daniel Marjamakie59f8d72015-06-18 10:59:26 +0000971 if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,
972 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,
Erich Keane757d3172016-11-02 18:29:35 +0000973 tok::kw___regcall, tok::kw___vectorcall))
Richard Smithee390432014-05-16 01:56:53 +0000974 return TPResult::True; // attributes indicate declaration
Justin Bognerd26f95b2015-02-23 22:36:28 +0000975 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
Richard Smithee390432014-05-16 01:56:53 +0000976 if (TPR != TPResult::Ambiguous)
Guy Benyei11169dd2012-12-18 14:30:41 +0000977 return TPR;
978 if (Tok.isNot(tok::r_paren))
Richard Smithee390432014-05-16 01:56:53 +0000979 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +0000980 ConsumeParen();
981 }
Justin Bognerd26f95b2015-02-23 22:36:28 +0000982 } else if (!mayBeAbstract) {
Richard Smithee390432014-05-16 01:56:53 +0000983 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +0000984 }
985
Richard Smithe303e352018-02-02 22:24:54 +0000986 if (mayHaveDirectInit)
987 return TPResult::Ambiguous;
988
Guy Benyei11169dd2012-12-18 14:30:41 +0000989 while (1) {
Richard Smithee390432014-05-16 01:56:53 +0000990 TPResult TPR(TPResult::Ambiguous);
Guy Benyei11169dd2012-12-18 14:30:41 +0000991
Guy Benyei11169dd2012-12-18 14:30:41 +0000992 if (Tok.is(tok::l_paren)) {
993 // Check whether we have a function declarator or a possible ctor-style
994 // initializer that follows the declarator. Note that ctor-style
995 // initializers are not possible in contexts where abstract declarators
996 // are allowed.
Justin Bognerd26f95b2015-02-23 22:36:28 +0000997 if (!mayBeAbstract && !isCXXFunctionDeclarator())
Guy Benyei11169dd2012-12-18 14:30:41 +0000998 break;
999
1000 // direct-declarator '(' parameter-declaration-clause ')'
1001 // cv-qualifier-seq[opt] exception-specification[opt]
1002 ConsumeParen();
Justin Bognerd26f95b2015-02-23 22:36:28 +00001003 TPR = TryParseFunctionDeclarator();
Guy Benyei11169dd2012-12-18 14:30:41 +00001004 } else if (Tok.is(tok::l_square)) {
1005 // direct-declarator '[' constant-expression[opt] ']'
1006 // direct-abstract-declarator[opt] '[' constant-expression[opt] ']'
1007 TPR = TryParseBracketDeclarator();
1008 } else {
1009 break;
1010 }
1011
Richard Smithee390432014-05-16 01:56:53 +00001012 if (TPR != TPResult::Ambiguous)
Guy Benyei11169dd2012-12-18 14:30:41 +00001013 return TPR;
1014 }
1015
Richard Smithee390432014-05-16 01:56:53 +00001016 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001017}
1018
Fangrui Song6907ce22018-07-30 19:24:48 +00001019Parser::TPResult
Guy Benyei11169dd2012-12-18 14:30:41 +00001020Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
1021 switch (Kind) {
1022 // Obviously starts an expression.
1023 case tok::numeric_constant:
1024 case tok::char_constant:
1025 case tok::wide_char_constant:
Richard Smith3e3a7052014-11-08 06:08:42 +00001026 case tok::utf8_char_constant:
Guy Benyei11169dd2012-12-18 14:30:41 +00001027 case tok::utf16_char_constant:
1028 case tok::utf32_char_constant:
1029 case tok::string_literal:
1030 case tok::wide_string_literal:
1031 case tok::utf8_string_literal:
1032 case tok::utf16_string_literal:
1033 case tok::utf32_string_literal:
1034 case tok::l_square:
1035 case tok::l_paren:
1036 case tok::amp:
1037 case tok::ampamp:
1038 case tok::star:
1039 case tok::plus:
1040 case tok::plusplus:
1041 case tok::minus:
1042 case tok::minusminus:
1043 case tok::tilde:
1044 case tok::exclaim:
1045 case tok::kw_sizeof:
1046 case tok::kw___func__:
1047 case tok::kw_const_cast:
1048 case tok::kw_delete:
1049 case tok::kw_dynamic_cast:
1050 case tok::kw_false:
1051 case tok::kw_new:
1052 case tok::kw_operator:
1053 case tok::kw_reinterpret_cast:
1054 case tok::kw_static_cast:
1055 case tok::kw_this:
1056 case tok::kw_throw:
1057 case tok::kw_true:
1058 case tok::kw_typeid:
1059 case tok::kw_alignof:
1060 case tok::kw_noexcept:
1061 case tok::kw_nullptr:
1062 case tok::kw__Alignof:
1063 case tok::kw___null:
1064 case tok::kw___alignof:
1065 case tok::kw___builtin_choose_expr:
1066 case tok::kw___builtin_offsetof:
Guy Benyei11169dd2012-12-18 14:30:41 +00001067 case tok::kw___builtin_va_arg:
1068 case tok::kw___imag:
1069 case tok::kw___real:
1070 case tok::kw___FUNCTION__:
David Majnemerbed356a2013-11-06 23:31:56 +00001071 case tok::kw___FUNCDNAME__:
Reid Kleckner52eddda2014-04-08 18:13:24 +00001072 case tok::kw___FUNCSIG__:
Guy Benyei11169dd2012-12-18 14:30:41 +00001073 case tok::kw_L__FUNCTION__:
Reid Kleckner4a83f0a2018-07-26 23:18:44 +00001074 case tok::kw_L__FUNCSIG__:
Guy Benyei11169dd2012-12-18 14:30:41 +00001075 case tok::kw___PRETTY_FUNCTION__:
Guy Benyei11169dd2012-12-18 14:30:41 +00001076 case tok::kw___uuidof:
Alp Toker40f9b1c2013-12-12 21:23:03 +00001077#define TYPE_TRAIT(N,Spelling,K) \
1078 case tok::kw_##Spelling:
1079#include "clang/Basic/TokenKinds.def"
Richard Smithee390432014-05-16 01:56:53 +00001080 return TPResult::True;
Fangrui Song6907ce22018-07-30 19:24:48 +00001081
Guy Benyei11169dd2012-12-18 14:30:41 +00001082 // Obviously starts a type-specifier-seq:
1083 case tok::kw_char:
1084 case tok::kw_const:
1085 case tok::kw_double:
Sjoerd Meijercc623ad2017-09-08 15:15:00 +00001086 case tok::kw__Float16:
Nemanja Ivanovicbb1ea2d2016-05-09 08:52:33 +00001087 case tok::kw___float128:
Guy Benyei11169dd2012-12-18 14:30:41 +00001088 case tok::kw_enum:
1089 case tok::kw_half:
1090 case tok::kw_float:
1091 case tok::kw_int:
1092 case tok::kw_long:
1093 case tok::kw___int64:
1094 case tok::kw___int128:
1095 case tok::kw_restrict:
1096 case tok::kw_short:
1097 case tok::kw_signed:
1098 case tok::kw_struct:
1099 case tok::kw_union:
1100 case tok::kw_unsigned:
1101 case tok::kw_void:
1102 case tok::kw_volatile:
1103 case tok::kw__Bool:
1104 case tok::kw__Complex:
1105 case tok::kw_class:
1106 case tok::kw_typename:
1107 case tok::kw_wchar_t:
Richard Smith3a8244d2018-05-01 05:02:45 +00001108 case tok::kw_char8_t:
Guy Benyei11169dd2012-12-18 14:30:41 +00001109 case tok::kw_char16_t:
1110 case tok::kw_char32_t:
Guy Benyei11169dd2012-12-18 14:30:41 +00001111 case tok::kw__Decimal32:
1112 case tok::kw__Decimal64:
1113 case tok::kw__Decimal128:
Richard Smith1fff95c2013-09-12 23:28:08 +00001114 case tok::kw___interface:
Guy Benyei11169dd2012-12-18 14:30:41 +00001115 case tok::kw___thread:
Richard Smithb4a9e862013-04-12 22:46:28 +00001116 case tok::kw_thread_local:
1117 case tok::kw__Thread_local:
Guy Benyei11169dd2012-12-18 14:30:41 +00001118 case tok::kw_typeof:
Richard Smith1fff95c2013-09-12 23:28:08 +00001119 case tok::kw___underlying_type:
Guy Benyei11169dd2012-12-18 14:30:41 +00001120 case tok::kw___cdecl:
1121 case tok::kw___stdcall:
1122 case tok::kw___fastcall:
1123 case tok::kw___thiscall:
Erich Keane757d3172016-11-02 18:29:35 +00001124 case tok::kw___regcall:
Reid Klecknerd7857f02014-10-24 17:42:17 +00001125 case tok::kw___vectorcall:
Guy Benyei11169dd2012-12-18 14:30:41 +00001126 case tok::kw___unaligned:
1127 case tok::kw___vector:
1128 case tok::kw___pixel:
Bill Seurercf2c96b2015-01-12 19:35:51 +00001129 case tok::kw___bool:
Guy Benyei11169dd2012-12-18 14:30:41 +00001130 case tok::kw__Atomic:
Alexey Bader954ba212016-04-08 13:40:33 +00001131#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
Alexey Baderb62f1442016-04-13 08:33:41 +00001132#include "clang/Basic/OpenCLImageTypes.def"
Guy Benyei11169dd2012-12-18 14:30:41 +00001133 case tok::kw___unknown_anytype:
Richard Smithee390432014-05-16 01:56:53 +00001134 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001135
1136 default:
1137 break;
1138 }
Fangrui Song6907ce22018-07-30 19:24:48 +00001139
Richard Smithee390432014-05-16 01:56:53 +00001140 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001141}
1142
1143bool Parser::isTentativelyDeclared(IdentifierInfo *II) {
1144 return std::find(TentativelyDeclaredIdentifiers.begin(),
1145 TentativelyDeclaredIdentifiers.end(), II)
1146 != TentativelyDeclaredIdentifiers.end();
1147}
1148
Kaelyn Takata445b0652014-11-05 00:09:29 +00001149namespace {
1150class TentativeParseCCC : public CorrectionCandidateCallback {
1151public:
1152 TentativeParseCCC(const Token &Next) {
1153 WantRemainingKeywords = false;
Daniel Marjamakie59f8d72015-06-18 10:59:26 +00001154 WantTypeSpecifiers = Next.isOneOf(tok::l_paren, tok::r_paren, tok::greater,
1155 tok::l_brace, tok::identifier);
Kaelyn Takata445b0652014-11-05 00:09:29 +00001156 }
1157
1158 bool ValidateCandidate(const TypoCorrection &Candidate) override {
1159 // Reject any candidate that only resolves to instance members since they
1160 // aren't viable as standalone identifiers instead of member references.
1161 if (Candidate.isResolved() && !Candidate.isKeyword() &&
Fangrui Song3117b172018-10-20 17:53:42 +00001162 llvm::all_of(Candidate,
1163 [](NamedDecl *ND) { return ND->isCXXInstanceMember(); }))
Kaelyn Takata445b0652014-11-05 00:09:29 +00001164 return false;
1165
1166 return CorrectionCandidateCallback::ValidateCandidate(Candidate);
1167 }
1168};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001169}
Richard Smithee390432014-05-16 01:56:53 +00001170/// isCXXDeclarationSpecifier - Returns TPResult::True if it is a declaration
1171/// specifier, TPResult::False if it is not, TPResult::Ambiguous if it could
1172/// be either a decl-specifier or a function-style cast, and TPResult::Error
Guy Benyei11169dd2012-12-18 14:30:41 +00001173/// if a parsing error was found and reported.
1174///
1175/// If HasMissingTypename is provided, a name with a dependent scope specifier
1176/// will be treated as ambiguous if the 'typename' keyword is missing. If this
1177/// happens, *HasMissingTypename will be set to 'true'. This will also be used
1178/// as an indicator that undeclared identifiers (which will trigger a later
Richard Smithee390432014-05-16 01:56:53 +00001179/// parse error) should be treated as types. Returns TPResult::Ambiguous in
Guy Benyei11169dd2012-12-18 14:30:41 +00001180/// such cases.
1181///
1182/// decl-specifier:
1183/// storage-class-specifier
1184/// type-specifier
1185/// function-specifier
1186/// 'friend'
1187/// 'typedef'
Richard Smithb4a9e862013-04-12 22:46:28 +00001188/// [C++11] 'constexpr'
Guy Benyei11169dd2012-12-18 14:30:41 +00001189/// [GNU] attributes declaration-specifiers[opt]
1190///
1191/// storage-class-specifier:
1192/// 'register'
1193/// 'static'
1194/// 'extern'
1195/// 'mutable'
1196/// 'auto'
1197/// [GNU] '__thread'
Richard Smithb4a9e862013-04-12 22:46:28 +00001198/// [C++11] 'thread_local'
1199/// [C11] '_Thread_local'
Guy Benyei11169dd2012-12-18 14:30:41 +00001200///
1201/// function-specifier:
1202/// 'inline'
1203/// 'virtual'
1204/// 'explicit'
1205///
1206/// typedef-name:
1207/// identifier
1208///
1209/// type-specifier:
1210/// simple-type-specifier
1211/// class-specifier
1212/// enum-specifier
1213/// elaborated-type-specifier
1214/// typename-specifier
1215/// cv-qualifier
1216///
1217/// simple-type-specifier:
1218/// '::'[opt] nested-name-specifier[opt] type-name
1219/// '::'[opt] nested-name-specifier 'template'
1220/// simple-template-id [TODO]
1221/// 'char'
1222/// 'wchar_t'
1223/// 'bool'
1224/// 'short'
1225/// 'int'
1226/// 'long'
1227/// 'signed'
1228/// 'unsigned'
1229/// 'float'
1230/// 'double'
1231/// 'void'
1232/// [GNU] typeof-specifier
1233/// [GNU] '_Complex'
Richard Smithb4a9e862013-04-12 22:46:28 +00001234/// [C++11] 'auto'
Richard Smithe301ba22015-11-11 02:02:15 +00001235/// [GNU] '__auto_type'
Richard Smithb4a9e862013-04-12 22:46:28 +00001236/// [C++11] 'decltype' ( expression )
Richard Smith74aeef52013-04-26 16:15:35 +00001237/// [C++1y] 'decltype' ( 'auto' )
Guy Benyei11169dd2012-12-18 14:30:41 +00001238///
1239/// type-name:
1240/// class-name
1241/// enum-name
1242/// typedef-name
1243///
1244/// elaborated-type-specifier:
1245/// class-key '::'[opt] nested-name-specifier[opt] identifier
1246/// class-key '::'[opt] nested-name-specifier[opt] 'template'[opt]
1247/// simple-template-id
1248/// 'enum' '::'[opt] nested-name-specifier[opt] identifier
1249///
1250/// enum-name:
1251/// identifier
1252///
1253/// enum-specifier:
1254/// 'enum' identifier[opt] '{' enumerator-list[opt] '}'
1255/// 'enum' identifier[opt] '{' enumerator-list ',' '}'
1256///
1257/// class-specifier:
1258/// class-head '{' member-specification[opt] '}'
1259///
1260/// class-head:
1261/// class-key identifier[opt] base-clause[opt]
1262/// class-key nested-name-specifier identifier base-clause[opt]
1263/// class-key nested-name-specifier[opt] simple-template-id
1264/// base-clause[opt]
1265///
1266/// class-key:
1267/// 'class'
1268/// 'struct'
1269/// 'union'
1270///
1271/// cv-qualifier:
1272/// 'const'
1273/// 'volatile'
1274/// [GNU] restrict
1275///
1276Parser::TPResult
1277Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
1278 bool *HasMissingTypename) {
1279 switch (Tok.getKind()) {
1280 case tok::identifier: {
1281 // Check for need to substitute AltiVec __vector keyword
1282 // for "vector" identifier.
1283 if (TryAltiVecVectorToken())
Richard Smithee390432014-05-16 01:56:53 +00001284 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001285
1286 const Token &Next = NextToken();
1287 // In 'foo bar', 'foo' is always a type name outside of Objective-C.
Erik Pilkingtonfa983902018-10-30 20:31:30 +00001288 if (!getLangOpts().ObjC && Next.is(tok::identifier))
Richard Smithee390432014-05-16 01:56:53 +00001289 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001290
1291 if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {
1292 // Determine whether this is a valid expression. If not, we will hit
1293 // a parse error one way or another. In that case, tell the caller that
1294 // this is ambiguous. Typo-correct to type and expression keywords and
1295 // to types and identifiers, in order to try to recover from errors.
Guy Benyei11169dd2012-12-18 14:30:41 +00001296 switch (TryAnnotateName(false /* no nested name specifier */,
Kaelyn Takata445b0652014-11-05 00:09:29 +00001297 llvm::make_unique<TentativeParseCCC>(Next))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001298 case ANK_Error:
Richard Smithee390432014-05-16 01:56:53 +00001299 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001300 case ANK_TentativeDecl:
Richard Smithee390432014-05-16 01:56:53 +00001301 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001302 case ANK_TemplateName:
Richard Smith77a9c602018-02-28 03:02:23 +00001303 // In C++17, this could be a type template for class template argument
1304 // deduction. Try to form a type annotation for it. If we're in a
1305 // template template argument, we'll undo this when checking the
1306 // validity of the argument.
1307 if (getLangOpts().CPlusPlus17) {
1308 if (TryAnnotateTypeOrScopeToken())
1309 return TPResult::Error;
1310 if (Tok.isNot(tok::identifier))
1311 break;
1312 }
1313
Guy Benyei11169dd2012-12-18 14:30:41 +00001314 // A bare type template-name which can't be a template template
1315 // argument is an error, and was probably intended to be a type.
Richard Smithee390432014-05-16 01:56:53 +00001316 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001317 case ANK_Unresolved:
Richard Smithee390432014-05-16 01:56:53 +00001318 return HasMissingTypename ? TPResult::Ambiguous : TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001319 case ANK_Success:
1320 break;
1321 }
1322 assert(Tok.isNot(tok::identifier) &&
1323 "TryAnnotateName succeeded without producing an annotation");
1324 } else {
1325 // This might possibly be a type with a dependent scope specifier and
1326 // a missing 'typename' keyword. Don't use TryAnnotateName in this case,
1327 // since it will annotate as a primary expression, and we want to use the
1328 // "missing 'typename'" logic.
1329 if (TryAnnotateTypeOrScopeToken())
Richard Smithee390432014-05-16 01:56:53 +00001330 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001331 // If annotation failed, assume it's a non-type.
1332 // FIXME: If this happens due to an undeclared identifier, treat it as
1333 // ambiguous.
1334 if (Tok.is(tok::identifier))
Richard Smithee390432014-05-16 01:56:53 +00001335 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001336 }
1337
1338 // We annotated this token as something. Recurse to handle whatever we got.
1339 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1340 }
1341
1342 case tok::kw_typename: // typename T::type
1343 // Annotate typenames and C++ scope specifiers. If we get one, just
1344 // recurse to handle whatever we get.
1345 if (TryAnnotateTypeOrScopeToken())
Richard Smithee390432014-05-16 01:56:53 +00001346 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001347 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1348
1349 case tok::coloncolon: { // ::foo::bar
1350 const Token &Next = NextToken();
Daniel Marjamakie59f8d72015-06-18 10:59:26 +00001351 if (Next.isOneOf(tok::kw_new, // ::new
1352 tok::kw_delete)) // ::delete
Richard Smithee390432014-05-16 01:56:53 +00001353 return TPResult::False;
Reid Kleckner4dc0b1a2018-11-01 19:54:45 +00001354 LLVM_FALLTHROUGH;
Guy Benyei11169dd2012-12-18 14:30:41 +00001355 }
Nikola Smiljanic67860242014-09-26 00:28:20 +00001356 case tok::kw___super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001357 case tok::kw_decltype:
1358 // Annotate typenames and C++ scope specifiers. If we get one, just
1359 // recurse to handle whatever we get.
1360 if (TryAnnotateTypeOrScopeToken())
Richard Smithee390432014-05-16 01:56:53 +00001361 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001362 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1363
1364 // decl-specifier:
1365 // storage-class-specifier
1366 // type-specifier
1367 // function-specifier
1368 // 'friend'
1369 // 'typedef'
1370 // 'constexpr'
1371 case tok::kw_friend:
1372 case tok::kw_typedef:
1373 case tok::kw_constexpr:
1374 // storage-class-specifier
1375 case tok::kw_register:
1376 case tok::kw_static:
1377 case tok::kw_extern:
1378 case tok::kw_mutable:
1379 case tok::kw_auto:
1380 case tok::kw___thread:
Richard Smithb4a9e862013-04-12 22:46:28 +00001381 case tok::kw_thread_local:
1382 case tok::kw__Thread_local:
Guy Benyei11169dd2012-12-18 14:30:41 +00001383 // function-specifier
1384 case tok::kw_inline:
1385 case tok::kw_virtual:
1386 case tok::kw_explicit:
1387
1388 // Modules
1389 case tok::kw___module_private__:
1390
1391 // Debugger support
1392 case tok::kw___unknown_anytype:
Fangrui Song6907ce22018-07-30 19:24:48 +00001393
Guy Benyei11169dd2012-12-18 14:30:41 +00001394 // type-specifier:
1395 // simple-type-specifier
1396 // class-specifier
1397 // enum-specifier
1398 // elaborated-type-specifier
1399 // typename-specifier
1400 // cv-qualifier
1401
1402 // class-specifier
1403 // elaborated-type-specifier
1404 case tok::kw_class:
1405 case tok::kw_struct:
1406 case tok::kw_union:
Richard Smith1fff95c2013-09-12 23:28:08 +00001407 case tok::kw___interface:
Guy Benyei11169dd2012-12-18 14:30:41 +00001408 // enum-specifier
1409 case tok::kw_enum:
1410 // cv-qualifier
1411 case tok::kw_const:
1412 case tok::kw_volatile:
Anastasia Stulova2c4730d2019-02-15 12:07:57 +00001413 // OpenCL address space qualifiers
Anastasia Stulova7f785bb2018-06-22 16:20:21 +00001414 case tok::kw___private:
1415 case tok::kw___local:
1416 case tok::kw___global:
1417 case tok::kw___constant:
1418 case tok::kw___generic:
Anastasia Stulova2c4730d2019-02-15 12:07:57 +00001419 // OpenCL access qualifiers
1420 case tok::kw___read_only:
1421 case tok::kw___write_only:
1422 case tok::kw___read_write:
Guy Benyei11169dd2012-12-18 14:30:41 +00001423
1424 // GNU
1425 case tok::kw_restrict:
1426 case tok::kw__Complex:
1427 case tok::kw___attribute:
Richard Smithe301ba22015-11-11 02:02:15 +00001428 case tok::kw___auto_type:
Richard Smithee390432014-05-16 01:56:53 +00001429 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001430
1431 // Microsoft
1432 case tok::kw___declspec:
1433 case tok::kw___cdecl:
1434 case tok::kw___stdcall:
1435 case tok::kw___fastcall:
1436 case tok::kw___thiscall:
Erich Keane757d3172016-11-02 18:29:35 +00001437 case tok::kw___regcall:
Reid Klecknerd7857f02014-10-24 17:42:17 +00001438 case tok::kw___vectorcall:
Guy Benyei11169dd2012-12-18 14:30:41 +00001439 case tok::kw___w64:
Aaron Ballman317a77f2013-05-22 23:25:32 +00001440 case tok::kw___sptr:
1441 case tok::kw___uptr:
Guy Benyei11169dd2012-12-18 14:30:41 +00001442 case tok::kw___ptr64:
1443 case tok::kw___ptr32:
1444 case tok::kw___forceinline:
1445 case tok::kw___unaligned:
Douglas Gregoraea7afd2015-06-24 22:02:08 +00001446 case tok::kw__Nonnull:
1447 case tok::kw__Nullable:
1448 case tok::kw__Null_unspecified:
Douglas Gregorab209d82015-07-07 03:58:42 +00001449 case tok::kw___kindof:
Richard Smithee390432014-05-16 01:56:53 +00001450 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001451
1452 // Borland
1453 case tok::kw___pascal:
Richard Smithee390432014-05-16 01:56:53 +00001454 return TPResult::True;
Fangrui Song6907ce22018-07-30 19:24:48 +00001455
Guy Benyei11169dd2012-12-18 14:30:41 +00001456 // AltiVec
1457 case tok::kw___vector:
Richard Smithee390432014-05-16 01:56:53 +00001458 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001459
1460 case tok::annot_template_id: {
1461 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1462 if (TemplateId->Kind != TNK_Type_template)
Richard Smithee390432014-05-16 01:56:53 +00001463 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001464 CXXScopeSpec SS;
1465 AnnotateTemplateIdTokenAsType();
1466 assert(Tok.is(tok::annot_typename));
1467 goto case_typename;
1468 }
1469
1470 case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed
1471 // We've already annotated a scope; try to annotate a type.
1472 if (TryAnnotateTypeOrScopeToken())
Richard Smithee390432014-05-16 01:56:53 +00001473 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001474 if (!Tok.is(tok::annot_typename)) {
1475 // If the next token is an identifier or a type qualifier, then this
1476 // can't possibly be a valid expression either.
1477 if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) {
1478 CXXScopeSpec SS;
1479 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1480 Tok.getAnnotationRange(),
1481 SS);
1482 if (SS.getScopeRep() && SS.getScopeRep()->isDependent()) {
Richard Smith4556ebe2016-06-29 21:12:37 +00001483 RevertingTentativeParsingAction PA(*this);
Richard Smithaf3b3252017-05-18 19:21:48 +00001484 ConsumeAnnotationToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00001485 ConsumeToken();
1486 bool isIdentifier = Tok.is(tok::identifier);
Richard Smithee390432014-05-16 01:56:53 +00001487 TPResult TPR = TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001488 if (!isIdentifier)
1489 TPR = isCXXDeclarationSpecifier(BracedCastResult,
1490 HasMissingTypename);
Guy Benyei11169dd2012-12-18 14:30:41 +00001491
1492 if (isIdentifier ||
Richard Smithee390432014-05-16 01:56:53 +00001493 TPR == TPResult::True || TPR == TPResult::Error)
1494 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001495
1496 if (HasMissingTypename) {
1497 // We can't tell whether this is a missing 'typename' or a valid
1498 // expression.
1499 *HasMissingTypename = true;
Richard Smithee390432014-05-16 01:56:53 +00001500 return TPResult::Ambiguous;
Reid Kleckner2bc58bd2019-02-26 02:22:17 +00001501 } else {
1502 // In MS mode, if HasMissingTypename is not provided, and the tokens
1503 // are or the form *) or &) *> or &> &&>, this can't be an expression.
1504 // The typename must be missing.
1505 if (getLangOpts().MSVCCompat) {
1506 if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&
1507 (NextToken().is(tok::r_paren) ||
1508 NextToken().is(tok::greater))) ||
1509 (Tok.is(tok::ampamp) && NextToken().is(tok::greater)))
1510 return TPResult::True;
1511 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001512 }
1513 } else {
1514 // Try to resolve the name. If it doesn't exist, assume it was
1515 // intended to name a type and keep disambiguating.
1516 switch (TryAnnotateName(false /* SS is not dependent */)) {
1517 case ANK_Error:
Richard Smithee390432014-05-16 01:56:53 +00001518 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001519 case ANK_TentativeDecl:
Richard Smithee390432014-05-16 01:56:53 +00001520 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001521 case ANK_TemplateName:
Richard Smith77a9c602018-02-28 03:02:23 +00001522 // In C++17, this could be a type template for class template
1523 // argument deduction.
1524 if (getLangOpts().CPlusPlus17) {
1525 if (TryAnnotateTypeOrScopeToken())
1526 return TPResult::Error;
1527 if (Tok.isNot(tok::identifier))
1528 break;
1529 }
1530
Guy Benyei11169dd2012-12-18 14:30:41 +00001531 // A bare type template-name which can't be a template template
1532 // argument is an error, and was probably intended to be a type.
Richard Smith77a9c602018-02-28 03:02:23 +00001533 // In C++17, this could be class template argument deduction.
1534 return (getLangOpts().CPlusPlus17 || GreaterThanIsOperator)
1535 ? TPResult::True
1536 : TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001537 case ANK_Unresolved:
Richard Smithee390432014-05-16 01:56:53 +00001538 return HasMissingTypename ? TPResult::Ambiguous
1539 : TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001540 case ANK_Success:
Richard Smith77a9c602018-02-28 03:02:23 +00001541 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00001542 }
Richard Smith77a9c602018-02-28 03:02:23 +00001543
1544 // Annotated it, check again.
1545 assert(Tok.isNot(tok::annot_cxxscope) ||
1546 NextToken().isNot(tok::identifier));
1547 return isCXXDeclarationSpecifier(BracedCastResult,
1548 HasMissingTypename);
Guy Benyei11169dd2012-12-18 14:30:41 +00001549 }
1550 }
Richard Smithee390432014-05-16 01:56:53 +00001551 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001552 }
1553 // If that succeeded, fallthrough into the generic simple-type-id case.
Galina Kistanova53ab4242017-06-01 21:29:45 +00001554 LLVM_FALLTHROUGH;
Guy Benyei11169dd2012-12-18 14:30:41 +00001555
1556 // The ambiguity resides in a simple-type-specifier/typename-specifier
1557 // followed by a '('. The '(' could either be the start of:
1558 //
1559 // direct-declarator:
1560 // '(' declarator ')'
1561 //
1562 // direct-abstract-declarator:
1563 // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
1564 // exception-specification[opt]
1565 // '(' abstract-declarator ')'
1566 //
1567 // or part of a function-style cast expression:
1568 //
1569 // simple-type-specifier '(' expression-list[opt] ')'
1570 //
1571
1572 // simple-type-specifier:
1573
1574 case tok::annot_typename:
1575 case_typename:
1576 // In Objective-C, we might have a protocol-qualified type.
Erik Pilkingtonfa983902018-10-30 20:31:30 +00001577 if (getLangOpts().ObjC && NextToken().is(tok::less)) {
Douglas Gregore9d95f12015-07-07 03:57:35 +00001578 // Tentatively parse the protocol qualifiers.
Richard Smith91b73f22016-06-29 21:06:51 +00001579 RevertingTentativeParsingAction PA(*this);
Richard Smithaf3b3252017-05-18 19:21:48 +00001580 ConsumeAnyToken(); // The type token
Fangrui Song6907ce22018-07-30 19:24:48 +00001581
Guy Benyei11169dd2012-12-18 14:30:41 +00001582 TPResult TPR = TryParseProtocolQualifiers();
1583 bool isFollowedByParen = Tok.is(tok::l_paren);
1584 bool isFollowedByBrace = Tok.is(tok::l_brace);
Fangrui Song6907ce22018-07-30 19:24:48 +00001585
Richard Smithee390432014-05-16 01:56:53 +00001586 if (TPR == TPResult::Error)
1587 return TPResult::Error;
Fangrui Song6907ce22018-07-30 19:24:48 +00001588
Guy Benyei11169dd2012-12-18 14:30:41 +00001589 if (isFollowedByParen)
Richard Smithee390432014-05-16 01:56:53 +00001590 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001591
Richard Smith2bf7fdb2013-01-02 11:42:31 +00001592 if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
Guy Benyei11169dd2012-12-18 14:30:41 +00001593 return BracedCastResult;
Fangrui Song6907ce22018-07-30 19:24:48 +00001594
Richard Smithee390432014-05-16 01:56:53 +00001595 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001596 }
Galina Kistanova53ab4242017-06-01 21:29:45 +00001597 LLVM_FALLTHROUGH;
Fangrui Song6907ce22018-07-30 19:24:48 +00001598
Guy Benyei11169dd2012-12-18 14:30:41 +00001599 case tok::kw_char:
1600 case tok::kw_wchar_t:
Richard Smith3a8244d2018-05-01 05:02:45 +00001601 case tok::kw_char8_t:
Guy Benyei11169dd2012-12-18 14:30:41 +00001602 case tok::kw_char16_t:
1603 case tok::kw_char32_t:
1604 case tok::kw_bool:
1605 case tok::kw_short:
1606 case tok::kw_int:
1607 case tok::kw_long:
1608 case tok::kw___int64:
1609 case tok::kw___int128:
1610 case tok::kw_signed:
1611 case tok::kw_unsigned:
1612 case tok::kw_half:
1613 case tok::kw_float:
1614 case tok::kw_double:
Sjoerd Meijercc623ad2017-09-08 15:15:00 +00001615 case tok::kw__Float16:
Nemanja Ivanovicbb1ea2d2016-05-09 08:52:33 +00001616 case tok::kw___float128:
Guy Benyei11169dd2012-12-18 14:30:41 +00001617 case tok::kw_void:
1618 case tok::annot_decltype:
Anastasia Stulova2c4730d2019-02-15 12:07:57 +00001619#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1620#include "clang/Basic/OpenCLImageTypes.def"
Guy Benyei11169dd2012-12-18 14:30:41 +00001621 if (NextToken().is(tok::l_paren))
Richard Smithee390432014-05-16 01:56:53 +00001622 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001623
1624 // This is a function-style cast in all cases we disambiguate other than
1625 // one:
1626 // struct S {
1627 // enum E : int { a = 4 }; // enum
1628 // enum E : int { 4 }; // bit-field
1629 // };
Richard Smith2bf7fdb2013-01-02 11:42:31 +00001630 if (getLangOpts().CPlusPlus11 && NextToken().is(tok::l_brace))
Guy Benyei11169dd2012-12-18 14:30:41 +00001631 return BracedCastResult;
1632
1633 if (isStartOfObjCClassMessageMissingOpenBracket())
Richard Smithee390432014-05-16 01:56:53 +00001634 return TPResult::False;
Fangrui Song6907ce22018-07-30 19:24:48 +00001635
Richard Smithee390432014-05-16 01:56:53 +00001636 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001637
1638 // GNU typeof support.
1639 case tok::kw_typeof: {
1640 if (NextToken().isNot(tok::l_paren))
Richard Smithee390432014-05-16 01:56:53 +00001641 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001642
Richard Smith91b73f22016-06-29 21:06:51 +00001643 RevertingTentativeParsingAction PA(*this);
Guy Benyei11169dd2012-12-18 14:30:41 +00001644
1645 TPResult TPR = TryParseTypeofSpecifier();
1646 bool isFollowedByParen = Tok.is(tok::l_paren);
1647 bool isFollowedByBrace = Tok.is(tok::l_brace);
1648
Richard Smithee390432014-05-16 01:56:53 +00001649 if (TPR == TPResult::Error)
1650 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001651
1652 if (isFollowedByParen)
Richard Smithee390432014-05-16 01:56:53 +00001653 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001654
Richard Smith2bf7fdb2013-01-02 11:42:31 +00001655 if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
Guy Benyei11169dd2012-12-18 14:30:41 +00001656 return BracedCastResult;
1657
Richard Smithee390432014-05-16 01:56:53 +00001658 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001659 }
1660
1661 // C++0x type traits support
1662 case tok::kw___underlying_type:
Richard Smithee390432014-05-16 01:56:53 +00001663 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001664
1665 // C11 _Atomic
1666 case tok::kw__Atomic:
Richard Smithee390432014-05-16 01:56:53 +00001667 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001668
1669 default:
Richard Smithee390432014-05-16 01:56:53 +00001670 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001671 }
1672}
1673
Richard Smith1fff95c2013-09-12 23:28:08 +00001674bool Parser::isCXXDeclarationSpecifierAType() {
1675 switch (Tok.getKind()) {
1676 // typename-specifier
1677 case tok::annot_decltype:
1678 case tok::annot_template_id:
1679 case tok::annot_typename:
1680 case tok::kw_typeof:
1681 case tok::kw___underlying_type:
1682 return true;
1683
1684 // elaborated-type-specifier
1685 case tok::kw_class:
1686 case tok::kw_struct:
1687 case tok::kw_union:
1688 case tok::kw___interface:
1689 case tok::kw_enum:
1690 return true;
1691
1692 // simple-type-specifier
1693 case tok::kw_char:
1694 case tok::kw_wchar_t:
Richard Smith3a8244d2018-05-01 05:02:45 +00001695 case tok::kw_char8_t:
Richard Smith1fff95c2013-09-12 23:28:08 +00001696 case tok::kw_char16_t:
1697 case tok::kw_char32_t:
1698 case tok::kw_bool:
1699 case tok::kw_short:
1700 case tok::kw_int:
1701 case tok::kw_long:
1702 case tok::kw___int64:
1703 case tok::kw___int128:
1704 case tok::kw_signed:
1705 case tok::kw_unsigned:
1706 case tok::kw_half:
1707 case tok::kw_float:
1708 case tok::kw_double:
Sjoerd Meijercc623ad2017-09-08 15:15:00 +00001709 case tok::kw__Float16:
Nemanja Ivanovicbb1ea2d2016-05-09 08:52:33 +00001710 case tok::kw___float128:
Richard Smith1fff95c2013-09-12 23:28:08 +00001711 case tok::kw_void:
1712 case tok::kw___unknown_anytype:
Richard Smithe301ba22015-11-11 02:02:15 +00001713 case tok::kw___auto_type:
Anastasia Stulova2c4730d2019-02-15 12:07:57 +00001714#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1715#include "clang/Basic/OpenCLImageTypes.def"
Richard Smith1fff95c2013-09-12 23:28:08 +00001716 return true;
1717
1718 case tok::kw_auto:
1719 return getLangOpts().CPlusPlus11;
1720
1721 case tok::kw__Atomic:
1722 // "_Atomic foo"
1723 return NextToken().is(tok::l_paren);
1724
1725 default:
1726 return false;
1727 }
1728}
1729
Guy Benyei11169dd2012-12-18 14:30:41 +00001730/// [GNU] typeof-specifier:
1731/// 'typeof' '(' expressions ')'
1732/// 'typeof' '(' type-name ')'
1733///
1734Parser::TPResult Parser::TryParseTypeofSpecifier() {
1735 assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");
1736 ConsumeToken();
1737
1738 assert(Tok.is(tok::l_paren) && "Expected '('");
1739 // Parse through the parens after 'typeof'.
1740 ConsumeParen();
Alexey Bataevee6507d2013-11-18 08:17:37 +00001741 if (!SkipUntil(tok::r_paren, StopAtSemi))
Richard Smithee390432014-05-16 01:56:53 +00001742 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001743
Richard Smithee390432014-05-16 01:56:53 +00001744 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001745}
1746
1747/// [ObjC] protocol-qualifiers:
1748//// '<' identifier-list '>'
1749Parser::TPResult Parser::TryParseProtocolQualifiers() {
1750 assert(Tok.is(tok::less) && "Expected '<' for qualifier list");
1751 ConsumeToken();
1752 do {
1753 if (Tok.isNot(tok::identifier))
Richard Smithee390432014-05-16 01:56:53 +00001754 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001755 ConsumeToken();
Fangrui Song6907ce22018-07-30 19:24:48 +00001756
Guy Benyei11169dd2012-12-18 14:30:41 +00001757 if (Tok.is(tok::comma)) {
1758 ConsumeToken();
1759 continue;
1760 }
Fangrui Song6907ce22018-07-30 19:24:48 +00001761
Guy Benyei11169dd2012-12-18 14:30:41 +00001762 if (Tok.is(tok::greater)) {
1763 ConsumeToken();
Richard Smithee390432014-05-16 01:56:53 +00001764 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001765 }
1766 } while (false);
Fangrui Song6907ce22018-07-30 19:24:48 +00001767
Richard Smithee390432014-05-16 01:56:53 +00001768 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001769}
1770
Guy Benyei11169dd2012-12-18 14:30:41 +00001771/// isCXXFunctionDeclarator - Disambiguates between a function declarator or
1772/// a constructor-style initializer, when parsing declaration statements.
1773/// Returns true for function declarator and false for constructor-style
1774/// initializer.
1775/// If during the disambiguation process a parsing error is encountered,
1776/// the function returns true to let the declaration parsing code handle it.
1777///
1778/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
1779/// exception-specification[opt]
1780///
1781bool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) {
1782
1783 // C++ 8.2p1:
1784 // The ambiguity arising from the similarity between a function-style cast and
1785 // a declaration mentioned in 6.8 can also occur in the context of a
1786 // declaration. In that context, the choice is between a function declaration
1787 // with a redundant set of parentheses around a parameter name and an object
1788 // declaration with a function-style cast as the initializer. Just as for the
1789 // ambiguities mentioned in 6.8, the resolution is to consider any construct
1790 // that could possibly be a declaration a declaration.
1791
Richard Smith91b73f22016-06-29 21:06:51 +00001792 RevertingTentativeParsingAction PA(*this);
Guy Benyei11169dd2012-12-18 14:30:41 +00001793
1794 ConsumeParen();
1795 bool InvalidAsDeclaration = false;
1796 TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);
Richard Smithee390432014-05-16 01:56:53 +00001797 if (TPR == TPResult::Ambiguous) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001798 if (Tok.isNot(tok::r_paren))
Richard Smithee390432014-05-16 01:56:53 +00001799 TPR = TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001800 else {
1801 const Token &Next = NextToken();
Daniel Marjamakie59f8d72015-06-18 10:59:26 +00001802 if (Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1803 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1804 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1805 isCXX11VirtSpecifier(Next))
Guy Benyei11169dd2012-12-18 14:30:41 +00001806 // The next token cannot appear after a constructor-style initializer,
1807 // and can appear next in a function definition. This must be a function
1808 // declarator.
Richard Smithee390432014-05-16 01:56:53 +00001809 TPR = TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001810 else if (InvalidAsDeclaration)
1811 // Use the absence of 'typename' as a tie-breaker.
Richard Smithee390432014-05-16 01:56:53 +00001812 TPR = TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001813 }
1814 }
1815
Richard Smithee390432014-05-16 01:56:53 +00001816 if (IsAmbiguous && TPR == TPResult::Ambiguous)
Guy Benyei11169dd2012-12-18 14:30:41 +00001817 *IsAmbiguous = true;
1818
1819 // In case of an error, let the declaration parsing code handle it.
Richard Smithee390432014-05-16 01:56:53 +00001820 return TPR != TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001821}
1822
1823/// parameter-declaration-clause:
1824/// parameter-declaration-list[opt] '...'[opt]
1825/// parameter-declaration-list ',' '...'
1826///
1827/// parameter-declaration-list:
1828/// parameter-declaration
1829/// parameter-declaration-list ',' parameter-declaration
1830///
1831/// parameter-declaration:
1832/// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]
1833/// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]
1834/// '=' assignment-expression
1835/// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]
1836/// attributes[opt]
1837/// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]
1838/// attributes[opt] '=' assignment-expression
1839///
1840Parser::TPResult
Richard Smith1fff95c2013-09-12 23:28:08 +00001841Parser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration,
1842 bool VersusTemplateArgument) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001843
1844 if (Tok.is(tok::r_paren))
Richard Smithee390432014-05-16 01:56:53 +00001845 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001846
1847 // parameter-declaration-list[opt] '...'[opt]
1848 // parameter-declaration-list ',' '...'
1849 //
1850 // parameter-declaration-list:
1851 // parameter-declaration
1852 // parameter-declaration-list ',' parameter-declaration
1853 //
1854 while (1) {
1855 // '...'[opt]
1856 if (Tok.is(tok::ellipsis)) {
1857 ConsumeToken();
1858 if (Tok.is(tok::r_paren))
Richard Smithee390432014-05-16 01:56:53 +00001859 return TPResult::True; // '...)' is a sign of a function declarator.
Guy Benyei11169dd2012-12-18 14:30:41 +00001860 else
Richard Smithee390432014-05-16 01:56:53 +00001861 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001862 }
1863
1864 // An attribute-specifier-seq here is a sign of a function declarator.
1865 if (isCXX11AttributeSpecifier(/*Disambiguate*/false,
1866 /*OuterMightBeMessageSend*/true))
Richard Smithee390432014-05-16 01:56:53 +00001867 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001868
1869 ParsedAttributes attrs(AttrFactory);
1870 MaybeParseMicrosoftAttributes(attrs);
1871
1872 // decl-specifier-seq
1873 // A parameter-declaration's initializer must be preceded by an '=', so
1874 // decl-specifier-seq '{' is not a parameter in C++11.
Richard Smithee390432014-05-16 01:56:53 +00001875 TPResult TPR = isCXXDeclarationSpecifier(TPResult::False,
Richard Smith1fff95c2013-09-12 23:28:08 +00001876 InvalidAsDeclaration);
1877
Richard Smithee390432014-05-16 01:56:53 +00001878 if (VersusTemplateArgument && TPR == TPResult::True) {
Richard Smith1fff95c2013-09-12 23:28:08 +00001879 // Consume the decl-specifier-seq. We have to look past it, since a
1880 // type-id might appear here in a template argument.
1881 bool SeenType = false;
1882 do {
1883 SeenType |= isCXXDeclarationSpecifierAType();
Richard Smithee390432014-05-16 01:56:53 +00001884 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1885 return TPResult::Error;
Richard Smith1fff95c2013-09-12 23:28:08 +00001886
1887 // If we see a parameter name, this can't be a template argument.
1888 if (SeenType && Tok.is(tok::identifier))
Richard Smithee390432014-05-16 01:56:53 +00001889 return TPResult::True;
Richard Smith1fff95c2013-09-12 23:28:08 +00001890
Richard Smithee390432014-05-16 01:56:53 +00001891 TPR = isCXXDeclarationSpecifier(TPResult::False,
Richard Smith1fff95c2013-09-12 23:28:08 +00001892 InvalidAsDeclaration);
Richard Smithee390432014-05-16 01:56:53 +00001893 if (TPR == TPResult::Error)
Richard Smith1fff95c2013-09-12 23:28:08 +00001894 return TPR;
Richard Smithee390432014-05-16 01:56:53 +00001895 } while (TPR != TPResult::False);
1896 } else if (TPR == TPResult::Ambiguous) {
Richard Smith1fff95c2013-09-12 23:28:08 +00001897 // Disambiguate what follows the decl-specifier.
Richard Smithee390432014-05-16 01:56:53 +00001898 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1899 return TPResult::Error;
Richard Smith1fff95c2013-09-12 23:28:08 +00001900 } else
Guy Benyei11169dd2012-12-18 14:30:41 +00001901 return TPR;
1902
1903 // declarator
1904 // abstract-declarator[opt]
Justin Bognerd26f95b2015-02-23 22:36:28 +00001905 TPR = TryParseDeclarator(true/*mayBeAbstract*/);
Richard Smithee390432014-05-16 01:56:53 +00001906 if (TPR != TPResult::Ambiguous)
Guy Benyei11169dd2012-12-18 14:30:41 +00001907 return TPR;
1908
1909 // [GNU] attributes[opt]
1910 if (Tok.is(tok::kw___attribute))
Richard Smithee390432014-05-16 01:56:53 +00001911 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001912
Richard Smith1fff95c2013-09-12 23:28:08 +00001913 // If we're disambiguating a template argument in a default argument in
1914 // a class definition versus a parameter declaration, an '=' here
1915 // disambiguates the parse one way or the other.
1916 // If this is a parameter, it must have a default argument because
1917 // (a) the previous parameter did, and
1918 // (b) this must be the first declaration of the function, so we can't
1919 // inherit any default arguments from elsewhere.
1920 // If we see an ')', then we've reached the end of a
1921 // parameter-declaration-clause, and the last param is missing its default
1922 // argument.
1923 if (VersusTemplateArgument)
Daniel Marjamakie59f8d72015-06-18 10:59:26 +00001924 return Tok.isOneOf(tok::equal, tok::r_paren) ? TPResult::True
1925 : TPResult::False;
Richard Smith1fff95c2013-09-12 23:28:08 +00001926
Guy Benyei11169dd2012-12-18 14:30:41 +00001927 if (Tok.is(tok::equal)) {
1928 // '=' assignment-expression
1929 // Parse through assignment-expression.
Richard Smith1fff95c2013-09-12 23:28:08 +00001930 // FIXME: assignment-expression may contain an unparenthesized comma.
Alexey Bataevee6507d2013-11-18 08:17:37 +00001931 if (!SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch))
Richard Smithee390432014-05-16 01:56:53 +00001932 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001933 }
1934
1935 if (Tok.is(tok::ellipsis)) {
1936 ConsumeToken();
1937 if (Tok.is(tok::r_paren))
Richard Smithee390432014-05-16 01:56:53 +00001938 return TPResult::True; // '...)' is a sign of a function declarator.
Guy Benyei11169dd2012-12-18 14:30:41 +00001939 else
Richard Smithee390432014-05-16 01:56:53 +00001940 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001941 }
1942
Alp Toker97650562014-01-10 11:19:30 +00001943 if (!TryConsumeToken(tok::comma))
Guy Benyei11169dd2012-12-18 14:30:41 +00001944 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00001945 }
1946
Richard Smithee390432014-05-16 01:56:53 +00001947 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001948}
1949
1950/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
1951/// parsing as a function declarator.
1952/// If TryParseFunctionDeclarator fully parsed the function declarator, it will
Justin Bognerd26f95b2015-02-23 22:36:28 +00001953/// return TPResult::Ambiguous, otherwise it will return either False() or
1954/// Error().
Guy Benyei11169dd2012-12-18 14:30:41 +00001955///
1956/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
1957/// exception-specification[opt]
1958///
1959/// exception-specification:
1960/// 'throw' '(' type-id-list[opt] ')'
1961///
Justin Bognerd26f95b2015-02-23 22:36:28 +00001962Parser::TPResult Parser::TryParseFunctionDeclarator() {
Guy Benyei11169dd2012-12-18 14:30:41 +00001963
1964 // The '(' is already parsed.
1965
1966 TPResult TPR = TryParseParameterDeclarationClause();
Richard Smithee390432014-05-16 01:56:53 +00001967 if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
1968 TPR = TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001969
Justin Bognerd26f95b2015-02-23 22:36:28 +00001970 if (TPR == TPResult::False || TPR == TPResult::Error)
1971 return TPR;
Guy Benyei11169dd2012-12-18 14:30:41 +00001972
1973 // Parse through the parens.
Alexey Bataevee6507d2013-11-18 08:17:37 +00001974 if (!SkipUntil(tok::r_paren, StopAtSemi))
Richard Smithee390432014-05-16 01:56:53 +00001975 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001976
1977 // cv-qualifier-seq
Reid Klecknerc6663b72018-03-07 23:26:02 +00001978 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
1979 tok::kw_restrict))
Guy Benyei11169dd2012-12-18 14:30:41 +00001980 ConsumeToken();
1981
1982 // ref-qualifier[opt]
Daniel Marjamakie59f8d72015-06-18 10:59:26 +00001983 if (Tok.isOneOf(tok::amp, tok::ampamp))
Guy Benyei11169dd2012-12-18 14:30:41 +00001984 ConsumeToken();
Fangrui Song6907ce22018-07-30 19:24:48 +00001985
Guy Benyei11169dd2012-12-18 14:30:41 +00001986 // exception-specification
1987 if (Tok.is(tok::kw_throw)) {
1988 ConsumeToken();
1989 if (Tok.isNot(tok::l_paren))
Richard Smithee390432014-05-16 01:56:53 +00001990 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001991
1992 // Parse through the parens after 'throw'.
1993 ConsumeParen();
Alexey Bataevee6507d2013-11-18 08:17:37 +00001994 if (!SkipUntil(tok::r_paren, StopAtSemi))
Richard Smithee390432014-05-16 01:56:53 +00001995 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001996 }
1997 if (Tok.is(tok::kw_noexcept)) {
1998 ConsumeToken();
1999 // Possibly an expression as well.
2000 if (Tok.is(tok::l_paren)) {
2001 // Find the matching rparen.
2002 ConsumeParen();
Alexey Bataevee6507d2013-11-18 08:17:37 +00002003 if (!SkipUntil(tok::r_paren, StopAtSemi))
Richard Smithee390432014-05-16 01:56:53 +00002004 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00002005 }
2006 }
2007
Richard Smithee390432014-05-16 01:56:53 +00002008 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00002009}
2010
2011/// '[' constant-expression[opt] ']'
2012///
2013Parser::TPResult Parser::TryParseBracketDeclarator() {
2014 ConsumeBracket();
Alexey Bataevee6507d2013-11-18 08:17:37 +00002015 if (!SkipUntil(tok::r_square, StopAtSemi))
Richard Smithee390432014-05-16 01:56:53 +00002016 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00002017
Richard Smithee390432014-05-16 01:56:53 +00002018 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00002019}