blob: de9391cddd7f45f9ecea43707bfa1f418cc781ff [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 {
Bruno Ricci70ad3962019-03-25 17:08:51 +00001150class TentativeParseCCC final : public CorrectionCandidateCallback {
Kaelyn Takata445b0652014-11-05 00:09:29 +00001151public:
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 }
Bruno Ricci70ad3962019-03-25 17:08:51 +00001168
1169 std::unique_ptr<CorrectionCandidateCallback> clone() override {
1170 return llvm::make_unique<TentativeParseCCC>(*this);
1171 }
Kaelyn Takata445b0652014-11-05 00:09:29 +00001172};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001173}
Richard Smithee390432014-05-16 01:56:53 +00001174/// isCXXDeclarationSpecifier - Returns TPResult::True if it is a declaration
1175/// specifier, TPResult::False if it is not, TPResult::Ambiguous if it could
1176/// be either a decl-specifier or a function-style cast, and TPResult::Error
Guy Benyei11169dd2012-12-18 14:30:41 +00001177/// if a parsing error was found and reported.
1178///
1179/// If HasMissingTypename is provided, a name with a dependent scope specifier
1180/// will be treated as ambiguous if the 'typename' keyword is missing. If this
1181/// happens, *HasMissingTypename will be set to 'true'. This will also be used
1182/// as an indicator that undeclared identifiers (which will trigger a later
Richard Smithee390432014-05-16 01:56:53 +00001183/// parse error) should be treated as types. Returns TPResult::Ambiguous in
Guy Benyei11169dd2012-12-18 14:30:41 +00001184/// such cases.
1185///
1186/// decl-specifier:
1187/// storage-class-specifier
1188/// type-specifier
1189/// function-specifier
1190/// 'friend'
1191/// 'typedef'
Richard Smithb4a9e862013-04-12 22:46:28 +00001192/// [C++11] 'constexpr'
Guy Benyei11169dd2012-12-18 14:30:41 +00001193/// [GNU] attributes declaration-specifiers[opt]
1194///
1195/// storage-class-specifier:
1196/// 'register'
1197/// 'static'
1198/// 'extern'
1199/// 'mutable'
1200/// 'auto'
1201/// [GNU] '__thread'
Richard Smithb4a9e862013-04-12 22:46:28 +00001202/// [C++11] 'thread_local'
1203/// [C11] '_Thread_local'
Guy Benyei11169dd2012-12-18 14:30:41 +00001204///
1205/// function-specifier:
1206/// 'inline'
1207/// 'virtual'
1208/// 'explicit'
1209///
1210/// typedef-name:
1211/// identifier
1212///
1213/// type-specifier:
1214/// simple-type-specifier
1215/// class-specifier
1216/// enum-specifier
1217/// elaborated-type-specifier
1218/// typename-specifier
1219/// cv-qualifier
1220///
1221/// simple-type-specifier:
1222/// '::'[opt] nested-name-specifier[opt] type-name
1223/// '::'[opt] nested-name-specifier 'template'
1224/// simple-template-id [TODO]
1225/// 'char'
1226/// 'wchar_t'
1227/// 'bool'
1228/// 'short'
1229/// 'int'
1230/// 'long'
1231/// 'signed'
1232/// 'unsigned'
1233/// 'float'
1234/// 'double'
1235/// 'void'
1236/// [GNU] typeof-specifier
1237/// [GNU] '_Complex'
Richard Smithb4a9e862013-04-12 22:46:28 +00001238/// [C++11] 'auto'
Richard Smithe301ba22015-11-11 02:02:15 +00001239/// [GNU] '__auto_type'
Richard Smithb4a9e862013-04-12 22:46:28 +00001240/// [C++11] 'decltype' ( expression )
Richard Smith74aeef52013-04-26 16:15:35 +00001241/// [C++1y] 'decltype' ( 'auto' )
Guy Benyei11169dd2012-12-18 14:30:41 +00001242///
1243/// type-name:
1244/// class-name
1245/// enum-name
1246/// typedef-name
1247///
1248/// elaborated-type-specifier:
1249/// class-key '::'[opt] nested-name-specifier[opt] identifier
1250/// class-key '::'[opt] nested-name-specifier[opt] 'template'[opt]
1251/// simple-template-id
1252/// 'enum' '::'[opt] nested-name-specifier[opt] identifier
1253///
1254/// enum-name:
1255/// identifier
1256///
1257/// enum-specifier:
1258/// 'enum' identifier[opt] '{' enumerator-list[opt] '}'
1259/// 'enum' identifier[opt] '{' enumerator-list ',' '}'
1260///
1261/// class-specifier:
1262/// class-head '{' member-specification[opt] '}'
1263///
1264/// class-head:
1265/// class-key identifier[opt] base-clause[opt]
1266/// class-key nested-name-specifier identifier base-clause[opt]
1267/// class-key nested-name-specifier[opt] simple-template-id
1268/// base-clause[opt]
1269///
1270/// class-key:
1271/// 'class'
1272/// 'struct'
1273/// 'union'
1274///
1275/// cv-qualifier:
1276/// 'const'
1277/// 'volatile'
1278/// [GNU] restrict
1279///
1280Parser::TPResult
1281Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
1282 bool *HasMissingTypename) {
1283 switch (Tok.getKind()) {
1284 case tok::identifier: {
1285 // Check for need to substitute AltiVec __vector keyword
1286 // for "vector" identifier.
1287 if (TryAltiVecVectorToken())
Richard Smithee390432014-05-16 01:56:53 +00001288 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001289
1290 const Token &Next = NextToken();
1291 // In 'foo bar', 'foo' is always a type name outside of Objective-C.
Erik Pilkingtonfa983902018-10-30 20:31:30 +00001292 if (!getLangOpts().ObjC && Next.is(tok::identifier))
Richard Smithee390432014-05-16 01:56:53 +00001293 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001294
1295 if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {
1296 // Determine whether this is a valid expression. If not, we will hit
1297 // a parse error one way or another. In that case, tell the caller that
1298 // this is ambiguous. Typo-correct to type and expression keywords and
1299 // to types and identifiers, in order to try to recover from errors.
Bruno Ricci70ad3962019-03-25 17:08:51 +00001300 TentativeParseCCC CCC(Next);
1301 switch (TryAnnotateName(false /* no nested name specifier */, &CCC)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001302 case ANK_Error:
Richard Smithee390432014-05-16 01:56:53 +00001303 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001304 case ANK_TentativeDecl:
Richard Smithee390432014-05-16 01:56:53 +00001305 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001306 case ANK_TemplateName:
Richard Smith77a9c602018-02-28 03:02:23 +00001307 // In C++17, this could be a type template for class template argument
1308 // deduction. Try to form a type annotation for it. If we're in a
1309 // template template argument, we'll undo this when checking the
1310 // validity of the argument.
1311 if (getLangOpts().CPlusPlus17) {
1312 if (TryAnnotateTypeOrScopeToken())
1313 return TPResult::Error;
1314 if (Tok.isNot(tok::identifier))
1315 break;
1316 }
1317
Guy Benyei11169dd2012-12-18 14:30:41 +00001318 // A bare type template-name which can't be a template template
1319 // argument is an error, and was probably intended to be a type.
Richard Smithee390432014-05-16 01:56:53 +00001320 return GreaterThanIsOperator ? TPResult::True : TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001321 case ANK_Unresolved:
Richard Smithee390432014-05-16 01:56:53 +00001322 return HasMissingTypename ? TPResult::Ambiguous : TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001323 case ANK_Success:
1324 break;
1325 }
1326 assert(Tok.isNot(tok::identifier) &&
1327 "TryAnnotateName succeeded without producing an annotation");
1328 } else {
1329 // This might possibly be a type with a dependent scope specifier and
1330 // a missing 'typename' keyword. Don't use TryAnnotateName in this case,
1331 // since it will annotate as a primary expression, and we want to use the
1332 // "missing 'typename'" logic.
1333 if (TryAnnotateTypeOrScopeToken())
Richard Smithee390432014-05-16 01:56:53 +00001334 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001335 // If annotation failed, assume it's a non-type.
1336 // FIXME: If this happens due to an undeclared identifier, treat it as
1337 // ambiguous.
1338 if (Tok.is(tok::identifier))
Richard Smithee390432014-05-16 01:56:53 +00001339 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001340 }
1341
1342 // We annotated this token as something. Recurse to handle whatever we got.
1343 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1344 }
1345
1346 case tok::kw_typename: // typename T::type
1347 // Annotate typenames and C++ scope specifiers. If we get one, just
1348 // recurse to handle whatever we get.
1349 if (TryAnnotateTypeOrScopeToken())
Richard Smithee390432014-05-16 01:56:53 +00001350 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001351 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1352
1353 case tok::coloncolon: { // ::foo::bar
1354 const Token &Next = NextToken();
Daniel Marjamakie59f8d72015-06-18 10:59:26 +00001355 if (Next.isOneOf(tok::kw_new, // ::new
1356 tok::kw_delete)) // ::delete
Richard Smithee390432014-05-16 01:56:53 +00001357 return TPResult::False;
Reid Kleckner4dc0b1a2018-11-01 19:54:45 +00001358 LLVM_FALLTHROUGH;
Guy Benyei11169dd2012-12-18 14:30:41 +00001359 }
Nikola Smiljanic67860242014-09-26 00:28:20 +00001360 case tok::kw___super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001361 case tok::kw_decltype:
1362 // Annotate typenames and C++ scope specifiers. If we get one, just
1363 // recurse to handle whatever we get.
1364 if (TryAnnotateTypeOrScopeToken())
Richard Smithee390432014-05-16 01:56:53 +00001365 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001366 return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
1367
1368 // decl-specifier:
1369 // storage-class-specifier
1370 // type-specifier
1371 // function-specifier
1372 // 'friend'
1373 // 'typedef'
1374 // 'constexpr'
1375 case tok::kw_friend:
1376 case tok::kw_typedef:
1377 case tok::kw_constexpr:
1378 // storage-class-specifier
1379 case tok::kw_register:
1380 case tok::kw_static:
1381 case tok::kw_extern:
1382 case tok::kw_mutable:
1383 case tok::kw_auto:
1384 case tok::kw___thread:
Richard Smithb4a9e862013-04-12 22:46:28 +00001385 case tok::kw_thread_local:
1386 case tok::kw__Thread_local:
Guy Benyei11169dd2012-12-18 14:30:41 +00001387 // function-specifier
1388 case tok::kw_inline:
1389 case tok::kw_virtual:
1390 case tok::kw_explicit:
1391
1392 // Modules
1393 case tok::kw___module_private__:
1394
1395 // Debugger support
1396 case tok::kw___unknown_anytype:
Fangrui Song6907ce22018-07-30 19:24:48 +00001397
Guy Benyei11169dd2012-12-18 14:30:41 +00001398 // type-specifier:
1399 // simple-type-specifier
1400 // class-specifier
1401 // enum-specifier
1402 // elaborated-type-specifier
1403 // typename-specifier
1404 // cv-qualifier
1405
1406 // class-specifier
1407 // elaborated-type-specifier
1408 case tok::kw_class:
1409 case tok::kw_struct:
1410 case tok::kw_union:
Richard Smith1fff95c2013-09-12 23:28:08 +00001411 case tok::kw___interface:
Guy Benyei11169dd2012-12-18 14:30:41 +00001412 // enum-specifier
1413 case tok::kw_enum:
1414 // cv-qualifier
1415 case tok::kw_const:
1416 case tok::kw_volatile:
Anastasia Stulova314fab62019-03-28 11:47:14 +00001417 return TPResult::True;
1418
Anastasia Stulova2c4730d2019-02-15 12:07:57 +00001419 // OpenCL address space qualifiers
Anastasia Stulova948e37c2019-03-25 11:54:02 +00001420 case tok::kw_private:
Anastasia Stulova314fab62019-03-28 11:47:14 +00001421 if (!getLangOpts().OpenCL)
1422 return TPResult::False;
1423 LLVM_FALLTHROUGH;
Anastasia Stulova7f785bb2018-06-22 16:20:21 +00001424 case tok::kw___private:
1425 case tok::kw___local:
1426 case tok::kw___global:
1427 case tok::kw___constant:
1428 case tok::kw___generic:
Anastasia Stulova2c4730d2019-02-15 12:07:57 +00001429 // OpenCL access qualifiers
1430 case tok::kw___read_only:
1431 case tok::kw___write_only:
1432 case tok::kw___read_write:
Guy Benyei11169dd2012-12-18 14:30:41 +00001433
1434 // GNU
1435 case tok::kw_restrict:
1436 case tok::kw__Complex:
1437 case tok::kw___attribute:
Richard Smithe301ba22015-11-11 02:02:15 +00001438 case tok::kw___auto_type:
Richard Smithee390432014-05-16 01:56:53 +00001439 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001440
1441 // Microsoft
1442 case tok::kw___declspec:
1443 case tok::kw___cdecl:
1444 case tok::kw___stdcall:
1445 case tok::kw___fastcall:
1446 case tok::kw___thiscall:
Erich Keane757d3172016-11-02 18:29:35 +00001447 case tok::kw___regcall:
Reid Klecknerd7857f02014-10-24 17:42:17 +00001448 case tok::kw___vectorcall:
Guy Benyei11169dd2012-12-18 14:30:41 +00001449 case tok::kw___w64:
Aaron Ballman317a77f2013-05-22 23:25:32 +00001450 case tok::kw___sptr:
1451 case tok::kw___uptr:
Guy Benyei11169dd2012-12-18 14:30:41 +00001452 case tok::kw___ptr64:
1453 case tok::kw___ptr32:
1454 case tok::kw___forceinline:
1455 case tok::kw___unaligned:
Douglas Gregoraea7afd2015-06-24 22:02:08 +00001456 case tok::kw__Nonnull:
1457 case tok::kw__Nullable:
1458 case tok::kw__Null_unspecified:
Douglas Gregorab209d82015-07-07 03:58:42 +00001459 case tok::kw___kindof:
Richard Smithee390432014-05-16 01:56:53 +00001460 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001461
1462 // Borland
1463 case tok::kw___pascal:
Richard Smithee390432014-05-16 01:56:53 +00001464 return TPResult::True;
Fangrui Song6907ce22018-07-30 19:24:48 +00001465
Guy Benyei11169dd2012-12-18 14:30:41 +00001466 // AltiVec
1467 case tok::kw___vector:
Richard Smithee390432014-05-16 01:56:53 +00001468 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001469
1470 case tok::annot_template_id: {
1471 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
1472 if (TemplateId->Kind != TNK_Type_template)
Richard Smithee390432014-05-16 01:56:53 +00001473 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001474 CXXScopeSpec SS;
1475 AnnotateTemplateIdTokenAsType();
1476 assert(Tok.is(tok::annot_typename));
1477 goto case_typename;
1478 }
1479
1480 case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed
1481 // We've already annotated a scope; try to annotate a type.
1482 if (TryAnnotateTypeOrScopeToken())
Richard Smithee390432014-05-16 01:56:53 +00001483 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001484 if (!Tok.is(tok::annot_typename)) {
1485 // If the next token is an identifier or a type qualifier, then this
1486 // can't possibly be a valid expression either.
1487 if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) {
1488 CXXScopeSpec SS;
1489 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
1490 Tok.getAnnotationRange(),
1491 SS);
1492 if (SS.getScopeRep() && SS.getScopeRep()->isDependent()) {
Richard Smith4556ebe2016-06-29 21:12:37 +00001493 RevertingTentativeParsingAction PA(*this);
Richard Smithaf3b3252017-05-18 19:21:48 +00001494 ConsumeAnnotationToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00001495 ConsumeToken();
1496 bool isIdentifier = Tok.is(tok::identifier);
Richard Smithee390432014-05-16 01:56:53 +00001497 TPResult TPR = TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001498 if (!isIdentifier)
1499 TPR = isCXXDeclarationSpecifier(BracedCastResult,
1500 HasMissingTypename);
Guy Benyei11169dd2012-12-18 14:30:41 +00001501
1502 if (isIdentifier ||
Richard Smithee390432014-05-16 01:56:53 +00001503 TPR == TPResult::True || TPR == TPResult::Error)
1504 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001505
1506 if (HasMissingTypename) {
1507 // We can't tell whether this is a missing 'typename' or a valid
1508 // expression.
1509 *HasMissingTypename = true;
Richard Smithee390432014-05-16 01:56:53 +00001510 return TPResult::Ambiguous;
Reid Kleckner2bc58bd2019-02-26 02:22:17 +00001511 } else {
1512 // In MS mode, if HasMissingTypename is not provided, and the tokens
1513 // are or the form *) or &) *> or &> &&>, this can't be an expression.
1514 // The typename must be missing.
1515 if (getLangOpts().MSVCCompat) {
1516 if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&
1517 (NextToken().is(tok::r_paren) ||
1518 NextToken().is(tok::greater))) ||
1519 (Tok.is(tok::ampamp) && NextToken().is(tok::greater)))
1520 return TPResult::True;
1521 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001522 }
1523 } else {
1524 // Try to resolve the name. If it doesn't exist, assume it was
1525 // intended to name a type and keep disambiguating.
1526 switch (TryAnnotateName(false /* SS is not dependent */)) {
1527 case ANK_Error:
Richard Smithee390432014-05-16 01:56:53 +00001528 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001529 case ANK_TentativeDecl:
Richard Smithee390432014-05-16 01:56:53 +00001530 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001531 case ANK_TemplateName:
Richard Smith77a9c602018-02-28 03:02:23 +00001532 // In C++17, this could be a type template for class template
1533 // argument deduction.
1534 if (getLangOpts().CPlusPlus17) {
1535 if (TryAnnotateTypeOrScopeToken())
1536 return TPResult::Error;
1537 if (Tok.isNot(tok::identifier))
1538 break;
1539 }
1540
Guy Benyei11169dd2012-12-18 14:30:41 +00001541 // A bare type template-name which can't be a template template
1542 // argument is an error, and was probably intended to be a type.
Richard Smith77a9c602018-02-28 03:02:23 +00001543 // In C++17, this could be class template argument deduction.
1544 return (getLangOpts().CPlusPlus17 || GreaterThanIsOperator)
1545 ? TPResult::True
1546 : TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001547 case ANK_Unresolved:
Richard Smithee390432014-05-16 01:56:53 +00001548 return HasMissingTypename ? TPResult::Ambiguous
1549 : TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001550 case ANK_Success:
Richard Smith77a9c602018-02-28 03:02:23 +00001551 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00001552 }
Richard Smith77a9c602018-02-28 03:02:23 +00001553
1554 // Annotated it, check again.
1555 assert(Tok.isNot(tok::annot_cxxscope) ||
1556 NextToken().isNot(tok::identifier));
1557 return isCXXDeclarationSpecifier(BracedCastResult,
1558 HasMissingTypename);
Guy Benyei11169dd2012-12-18 14:30:41 +00001559 }
1560 }
Richard Smithee390432014-05-16 01:56:53 +00001561 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001562 }
1563 // If that succeeded, fallthrough into the generic simple-type-id case.
Galina Kistanova53ab4242017-06-01 21:29:45 +00001564 LLVM_FALLTHROUGH;
Guy Benyei11169dd2012-12-18 14:30:41 +00001565
1566 // The ambiguity resides in a simple-type-specifier/typename-specifier
1567 // followed by a '('. The '(' could either be the start of:
1568 //
1569 // direct-declarator:
1570 // '(' declarator ')'
1571 //
1572 // direct-abstract-declarator:
1573 // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
1574 // exception-specification[opt]
1575 // '(' abstract-declarator ')'
1576 //
1577 // or part of a function-style cast expression:
1578 //
1579 // simple-type-specifier '(' expression-list[opt] ')'
1580 //
1581
1582 // simple-type-specifier:
1583
1584 case tok::annot_typename:
1585 case_typename:
1586 // In Objective-C, we might have a protocol-qualified type.
Erik Pilkingtonfa983902018-10-30 20:31:30 +00001587 if (getLangOpts().ObjC && NextToken().is(tok::less)) {
Douglas Gregore9d95f12015-07-07 03:57:35 +00001588 // Tentatively parse the protocol qualifiers.
Richard Smith91b73f22016-06-29 21:06:51 +00001589 RevertingTentativeParsingAction PA(*this);
Richard Smithaf3b3252017-05-18 19:21:48 +00001590 ConsumeAnyToken(); // The type token
Fangrui Song6907ce22018-07-30 19:24:48 +00001591
Guy Benyei11169dd2012-12-18 14:30:41 +00001592 TPResult TPR = TryParseProtocolQualifiers();
1593 bool isFollowedByParen = Tok.is(tok::l_paren);
1594 bool isFollowedByBrace = Tok.is(tok::l_brace);
Fangrui Song6907ce22018-07-30 19:24:48 +00001595
Richard Smithee390432014-05-16 01:56:53 +00001596 if (TPR == TPResult::Error)
1597 return TPResult::Error;
Fangrui Song6907ce22018-07-30 19:24:48 +00001598
Guy Benyei11169dd2012-12-18 14:30:41 +00001599 if (isFollowedByParen)
Richard Smithee390432014-05-16 01:56:53 +00001600 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001601
Richard Smith2bf7fdb2013-01-02 11:42:31 +00001602 if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
Guy Benyei11169dd2012-12-18 14:30:41 +00001603 return BracedCastResult;
Fangrui Song6907ce22018-07-30 19:24:48 +00001604
Richard Smithee390432014-05-16 01:56:53 +00001605 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001606 }
Galina Kistanova53ab4242017-06-01 21:29:45 +00001607 LLVM_FALLTHROUGH;
Fangrui Song6907ce22018-07-30 19:24:48 +00001608
Guy Benyei11169dd2012-12-18 14:30:41 +00001609 case tok::kw_char:
1610 case tok::kw_wchar_t:
Richard Smith3a8244d2018-05-01 05:02:45 +00001611 case tok::kw_char8_t:
Guy Benyei11169dd2012-12-18 14:30:41 +00001612 case tok::kw_char16_t:
1613 case tok::kw_char32_t:
1614 case tok::kw_bool:
1615 case tok::kw_short:
1616 case tok::kw_int:
1617 case tok::kw_long:
1618 case tok::kw___int64:
1619 case tok::kw___int128:
1620 case tok::kw_signed:
1621 case tok::kw_unsigned:
1622 case tok::kw_half:
1623 case tok::kw_float:
1624 case tok::kw_double:
Sjoerd Meijercc623ad2017-09-08 15:15:00 +00001625 case tok::kw__Float16:
Nemanja Ivanovicbb1ea2d2016-05-09 08:52:33 +00001626 case tok::kw___float128:
Guy Benyei11169dd2012-12-18 14:30:41 +00001627 case tok::kw_void:
1628 case tok::annot_decltype:
Anastasia Stulova2c4730d2019-02-15 12:07:57 +00001629#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1630#include "clang/Basic/OpenCLImageTypes.def"
Guy Benyei11169dd2012-12-18 14:30:41 +00001631 if (NextToken().is(tok::l_paren))
Richard Smithee390432014-05-16 01:56:53 +00001632 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001633
1634 // This is a function-style cast in all cases we disambiguate other than
1635 // one:
1636 // struct S {
1637 // enum E : int { a = 4 }; // enum
1638 // enum E : int { 4 }; // bit-field
1639 // };
Richard Smith2bf7fdb2013-01-02 11:42:31 +00001640 if (getLangOpts().CPlusPlus11 && NextToken().is(tok::l_brace))
Guy Benyei11169dd2012-12-18 14:30:41 +00001641 return BracedCastResult;
1642
1643 if (isStartOfObjCClassMessageMissingOpenBracket())
Richard Smithee390432014-05-16 01:56:53 +00001644 return TPResult::False;
Fangrui Song6907ce22018-07-30 19:24:48 +00001645
Richard Smithee390432014-05-16 01:56:53 +00001646 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001647
1648 // GNU typeof support.
1649 case tok::kw_typeof: {
1650 if (NextToken().isNot(tok::l_paren))
Richard Smithee390432014-05-16 01:56:53 +00001651 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001652
Richard Smith91b73f22016-06-29 21:06:51 +00001653 RevertingTentativeParsingAction PA(*this);
Guy Benyei11169dd2012-12-18 14:30:41 +00001654
1655 TPResult TPR = TryParseTypeofSpecifier();
1656 bool isFollowedByParen = Tok.is(tok::l_paren);
1657 bool isFollowedByBrace = Tok.is(tok::l_brace);
1658
Richard Smithee390432014-05-16 01:56:53 +00001659 if (TPR == TPResult::Error)
1660 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001661
1662 if (isFollowedByParen)
Richard Smithee390432014-05-16 01:56:53 +00001663 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001664
Richard Smith2bf7fdb2013-01-02 11:42:31 +00001665 if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
Guy Benyei11169dd2012-12-18 14:30:41 +00001666 return BracedCastResult;
1667
Richard Smithee390432014-05-16 01:56:53 +00001668 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001669 }
1670
1671 // C++0x type traits support
1672 case tok::kw___underlying_type:
Richard Smithee390432014-05-16 01:56:53 +00001673 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001674
1675 // C11 _Atomic
1676 case tok::kw__Atomic:
Richard Smithee390432014-05-16 01:56:53 +00001677 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001678
1679 default:
Richard Smithee390432014-05-16 01:56:53 +00001680 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001681 }
1682}
1683
Richard Smith1fff95c2013-09-12 23:28:08 +00001684bool Parser::isCXXDeclarationSpecifierAType() {
1685 switch (Tok.getKind()) {
1686 // typename-specifier
1687 case tok::annot_decltype:
1688 case tok::annot_template_id:
1689 case tok::annot_typename:
1690 case tok::kw_typeof:
1691 case tok::kw___underlying_type:
1692 return true;
1693
1694 // elaborated-type-specifier
1695 case tok::kw_class:
1696 case tok::kw_struct:
1697 case tok::kw_union:
1698 case tok::kw___interface:
1699 case tok::kw_enum:
1700 return true;
1701
1702 // simple-type-specifier
1703 case tok::kw_char:
1704 case tok::kw_wchar_t:
Richard Smith3a8244d2018-05-01 05:02:45 +00001705 case tok::kw_char8_t:
Richard Smith1fff95c2013-09-12 23:28:08 +00001706 case tok::kw_char16_t:
1707 case tok::kw_char32_t:
1708 case tok::kw_bool:
1709 case tok::kw_short:
1710 case tok::kw_int:
1711 case tok::kw_long:
1712 case tok::kw___int64:
1713 case tok::kw___int128:
1714 case tok::kw_signed:
1715 case tok::kw_unsigned:
1716 case tok::kw_half:
1717 case tok::kw_float:
1718 case tok::kw_double:
Sjoerd Meijercc623ad2017-09-08 15:15:00 +00001719 case tok::kw__Float16:
Nemanja Ivanovicbb1ea2d2016-05-09 08:52:33 +00001720 case tok::kw___float128:
Richard Smith1fff95c2013-09-12 23:28:08 +00001721 case tok::kw_void:
1722 case tok::kw___unknown_anytype:
Richard Smithe301ba22015-11-11 02:02:15 +00001723 case tok::kw___auto_type:
Anastasia Stulova2c4730d2019-02-15 12:07:57 +00001724#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
1725#include "clang/Basic/OpenCLImageTypes.def"
Richard Smith1fff95c2013-09-12 23:28:08 +00001726 return true;
1727
1728 case tok::kw_auto:
1729 return getLangOpts().CPlusPlus11;
1730
1731 case tok::kw__Atomic:
1732 // "_Atomic foo"
1733 return NextToken().is(tok::l_paren);
1734
1735 default:
1736 return false;
1737 }
1738}
1739
Guy Benyei11169dd2012-12-18 14:30:41 +00001740/// [GNU] typeof-specifier:
1741/// 'typeof' '(' expressions ')'
1742/// 'typeof' '(' type-name ')'
1743///
1744Parser::TPResult Parser::TryParseTypeofSpecifier() {
1745 assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");
1746 ConsumeToken();
1747
1748 assert(Tok.is(tok::l_paren) && "Expected '('");
1749 // Parse through the parens after 'typeof'.
1750 ConsumeParen();
Alexey Bataevee6507d2013-11-18 08:17:37 +00001751 if (!SkipUntil(tok::r_paren, StopAtSemi))
Richard Smithee390432014-05-16 01:56:53 +00001752 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001753
Richard Smithee390432014-05-16 01:56:53 +00001754 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001755}
1756
1757/// [ObjC] protocol-qualifiers:
1758//// '<' identifier-list '>'
1759Parser::TPResult Parser::TryParseProtocolQualifiers() {
1760 assert(Tok.is(tok::less) && "Expected '<' for qualifier list");
1761 ConsumeToken();
1762 do {
1763 if (Tok.isNot(tok::identifier))
Richard Smithee390432014-05-16 01:56:53 +00001764 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001765 ConsumeToken();
Fangrui Song6907ce22018-07-30 19:24:48 +00001766
Guy Benyei11169dd2012-12-18 14:30:41 +00001767 if (Tok.is(tok::comma)) {
1768 ConsumeToken();
1769 continue;
1770 }
Fangrui Song6907ce22018-07-30 19:24:48 +00001771
Guy Benyei11169dd2012-12-18 14:30:41 +00001772 if (Tok.is(tok::greater)) {
1773 ConsumeToken();
Richard Smithee390432014-05-16 01:56:53 +00001774 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001775 }
1776 } while (false);
Fangrui Song6907ce22018-07-30 19:24:48 +00001777
Richard Smithee390432014-05-16 01:56:53 +00001778 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001779}
1780
Guy Benyei11169dd2012-12-18 14:30:41 +00001781/// isCXXFunctionDeclarator - Disambiguates between a function declarator or
1782/// a constructor-style initializer, when parsing declaration statements.
1783/// Returns true for function declarator and false for constructor-style
1784/// initializer.
1785/// If during the disambiguation process a parsing error is encountered,
1786/// the function returns true to let the declaration parsing code handle it.
1787///
1788/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
1789/// exception-specification[opt]
1790///
1791bool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) {
1792
1793 // C++ 8.2p1:
1794 // The ambiguity arising from the similarity between a function-style cast and
1795 // a declaration mentioned in 6.8 can also occur in the context of a
1796 // declaration. In that context, the choice is between a function declaration
1797 // with a redundant set of parentheses around a parameter name and an object
1798 // declaration with a function-style cast as the initializer. Just as for the
1799 // ambiguities mentioned in 6.8, the resolution is to consider any construct
1800 // that could possibly be a declaration a declaration.
1801
Richard Smith91b73f22016-06-29 21:06:51 +00001802 RevertingTentativeParsingAction PA(*this);
Guy Benyei11169dd2012-12-18 14:30:41 +00001803
1804 ConsumeParen();
1805 bool InvalidAsDeclaration = false;
1806 TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);
Richard Smithee390432014-05-16 01:56:53 +00001807 if (TPR == TPResult::Ambiguous) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001808 if (Tok.isNot(tok::r_paren))
Richard Smithee390432014-05-16 01:56:53 +00001809 TPR = TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001810 else {
1811 const Token &Next = NextToken();
Daniel Marjamakie59f8d72015-06-18 10:59:26 +00001812 if (Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,
1813 tok::kw_throw, tok::kw_noexcept, tok::l_square,
1814 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||
1815 isCXX11VirtSpecifier(Next))
Guy Benyei11169dd2012-12-18 14:30:41 +00001816 // The next token cannot appear after a constructor-style initializer,
1817 // and can appear next in a function definition. This must be a function
1818 // declarator.
Richard Smithee390432014-05-16 01:56:53 +00001819 TPR = TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001820 else if (InvalidAsDeclaration)
1821 // Use the absence of 'typename' as a tie-breaker.
Richard Smithee390432014-05-16 01:56:53 +00001822 TPR = TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001823 }
1824 }
1825
Richard Smithee390432014-05-16 01:56:53 +00001826 if (IsAmbiguous && TPR == TPResult::Ambiguous)
Guy Benyei11169dd2012-12-18 14:30:41 +00001827 *IsAmbiguous = true;
1828
1829 // In case of an error, let the declaration parsing code handle it.
Richard Smithee390432014-05-16 01:56:53 +00001830 return TPR != TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001831}
1832
1833/// parameter-declaration-clause:
1834/// parameter-declaration-list[opt] '...'[opt]
1835/// parameter-declaration-list ',' '...'
1836///
1837/// parameter-declaration-list:
1838/// parameter-declaration
1839/// parameter-declaration-list ',' parameter-declaration
1840///
1841/// parameter-declaration:
1842/// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]
1843/// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt]
1844/// '=' assignment-expression
1845/// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]
1846/// attributes[opt]
1847/// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt]
1848/// attributes[opt] '=' assignment-expression
1849///
1850Parser::TPResult
Richard Smith1fff95c2013-09-12 23:28:08 +00001851Parser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration,
1852 bool VersusTemplateArgument) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001853
1854 if (Tok.is(tok::r_paren))
Richard Smithee390432014-05-16 01:56:53 +00001855 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001856
1857 // parameter-declaration-list[opt] '...'[opt]
1858 // parameter-declaration-list ',' '...'
1859 //
1860 // parameter-declaration-list:
1861 // parameter-declaration
1862 // parameter-declaration-list ',' parameter-declaration
1863 //
1864 while (1) {
1865 // '...'[opt]
1866 if (Tok.is(tok::ellipsis)) {
1867 ConsumeToken();
1868 if (Tok.is(tok::r_paren))
Richard Smithee390432014-05-16 01:56:53 +00001869 return TPResult::True; // '...)' is a sign of a function declarator.
Guy Benyei11169dd2012-12-18 14:30:41 +00001870 else
Richard Smithee390432014-05-16 01:56:53 +00001871 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001872 }
1873
1874 // An attribute-specifier-seq here is a sign of a function declarator.
1875 if (isCXX11AttributeSpecifier(/*Disambiguate*/false,
1876 /*OuterMightBeMessageSend*/true))
Richard Smithee390432014-05-16 01:56:53 +00001877 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001878
1879 ParsedAttributes attrs(AttrFactory);
1880 MaybeParseMicrosoftAttributes(attrs);
1881
1882 // decl-specifier-seq
1883 // A parameter-declaration's initializer must be preceded by an '=', so
1884 // decl-specifier-seq '{' is not a parameter in C++11.
Richard Smithee390432014-05-16 01:56:53 +00001885 TPResult TPR = isCXXDeclarationSpecifier(TPResult::False,
Richard Smith1fff95c2013-09-12 23:28:08 +00001886 InvalidAsDeclaration);
Richard Smithb3065792019-05-07 07:36:07 +00001887 // A declaration-specifier (not followed by '(' or '{') means this can't be
1888 // an expression, but it could still be a template argument.
1889 if (TPR != TPResult::Ambiguous &&
1890 !(VersusTemplateArgument && TPR == TPResult::True))
1891 return TPR;
Richard Smith1fff95c2013-09-12 23:28:08 +00001892
Richard Smithb3065792019-05-07 07:36:07 +00001893 bool SeenType = false;
1894 do {
1895 SeenType |= isCXXDeclarationSpecifierAType();
Richard Smithee390432014-05-16 01:56:53 +00001896 if (TryConsumeDeclarationSpecifier() == TPResult::Error)
1897 return TPResult::Error;
Richard Smithb3065792019-05-07 07:36:07 +00001898
1899 // If we see a parameter name, this can't be a template argument.
1900 if (SeenType && Tok.is(tok::identifier))
1901 return TPResult::True;
1902
1903 TPR = isCXXDeclarationSpecifier(TPResult::False,
1904 InvalidAsDeclaration);
1905 if (TPR == TPResult::Error)
1906 return TPR;
1907
1908 // Two declaration-specifiers means this can't be an expression.
1909 if (TPR == TPResult::True && !VersusTemplateArgument)
1910 return TPR;
1911 } while (TPR != TPResult::False);
Guy Benyei11169dd2012-12-18 14:30:41 +00001912
1913 // declarator
1914 // abstract-declarator[opt]
Justin Bognerd26f95b2015-02-23 22:36:28 +00001915 TPR = TryParseDeclarator(true/*mayBeAbstract*/);
Richard Smithee390432014-05-16 01:56:53 +00001916 if (TPR != TPResult::Ambiguous)
Guy Benyei11169dd2012-12-18 14:30:41 +00001917 return TPR;
1918
1919 // [GNU] attributes[opt]
1920 if (Tok.is(tok::kw___attribute))
Richard Smithee390432014-05-16 01:56:53 +00001921 return TPResult::True;
Guy Benyei11169dd2012-12-18 14:30:41 +00001922
Richard Smith1fff95c2013-09-12 23:28:08 +00001923 // If we're disambiguating a template argument in a default argument in
1924 // a class definition versus a parameter declaration, an '=' here
1925 // disambiguates the parse one way or the other.
1926 // If this is a parameter, it must have a default argument because
1927 // (a) the previous parameter did, and
1928 // (b) this must be the first declaration of the function, so we can't
1929 // inherit any default arguments from elsewhere.
1930 // If we see an ')', then we've reached the end of a
1931 // parameter-declaration-clause, and the last param is missing its default
1932 // argument.
1933 if (VersusTemplateArgument)
Daniel Marjamakie59f8d72015-06-18 10:59:26 +00001934 return Tok.isOneOf(tok::equal, tok::r_paren) ? TPResult::True
1935 : TPResult::False;
Richard Smith1fff95c2013-09-12 23:28:08 +00001936
Guy Benyei11169dd2012-12-18 14:30:41 +00001937 if (Tok.is(tok::equal)) {
1938 // '=' assignment-expression
1939 // Parse through assignment-expression.
Richard Smith1fff95c2013-09-12 23:28:08 +00001940 // FIXME: assignment-expression may contain an unparenthesized comma.
Alexey Bataevee6507d2013-11-18 08:17:37 +00001941 if (!SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch))
Richard Smithee390432014-05-16 01:56:53 +00001942 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001943 }
1944
1945 if (Tok.is(tok::ellipsis)) {
1946 ConsumeToken();
1947 if (Tok.is(tok::r_paren))
Richard Smithee390432014-05-16 01:56:53 +00001948 return TPResult::True; // '...)' is a sign of a function declarator.
Guy Benyei11169dd2012-12-18 14:30:41 +00001949 else
Richard Smithee390432014-05-16 01:56:53 +00001950 return TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001951 }
1952
Alp Toker97650562014-01-10 11:19:30 +00001953 if (!TryConsumeToken(tok::comma))
Guy Benyei11169dd2012-12-18 14:30:41 +00001954 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00001955 }
1956
Richard Smithee390432014-05-16 01:56:53 +00001957 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00001958}
1959
1960/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
1961/// parsing as a function declarator.
1962/// If TryParseFunctionDeclarator fully parsed the function declarator, it will
Justin Bognerd26f95b2015-02-23 22:36:28 +00001963/// return TPResult::Ambiguous, otherwise it will return either False() or
1964/// Error().
Guy Benyei11169dd2012-12-18 14:30:41 +00001965///
1966/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
1967/// exception-specification[opt]
1968///
1969/// exception-specification:
1970/// 'throw' '(' type-id-list[opt] ')'
1971///
Justin Bognerd26f95b2015-02-23 22:36:28 +00001972Parser::TPResult Parser::TryParseFunctionDeclarator() {
Guy Benyei11169dd2012-12-18 14:30:41 +00001973
1974 // The '(' is already parsed.
1975
1976 TPResult TPR = TryParseParameterDeclarationClause();
Richard Smithee390432014-05-16 01:56:53 +00001977 if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
1978 TPR = TPResult::False;
Guy Benyei11169dd2012-12-18 14:30:41 +00001979
Justin Bognerd26f95b2015-02-23 22:36:28 +00001980 if (TPR == TPResult::False || TPR == TPResult::Error)
1981 return TPR;
Guy Benyei11169dd2012-12-18 14:30:41 +00001982
1983 // Parse through the parens.
Alexey Bataevee6507d2013-11-18 08:17:37 +00001984 if (!SkipUntil(tok::r_paren, StopAtSemi))
Richard Smithee390432014-05-16 01:56:53 +00001985 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00001986
1987 // cv-qualifier-seq
Reid Klecknerc6663b72018-03-07 23:26:02 +00001988 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,
1989 tok::kw_restrict))
Guy Benyei11169dd2012-12-18 14:30:41 +00001990 ConsumeToken();
1991
1992 // ref-qualifier[opt]
Daniel Marjamakie59f8d72015-06-18 10:59:26 +00001993 if (Tok.isOneOf(tok::amp, tok::ampamp))
Guy Benyei11169dd2012-12-18 14:30:41 +00001994 ConsumeToken();
Fangrui Song6907ce22018-07-30 19:24:48 +00001995
Guy Benyei11169dd2012-12-18 14:30:41 +00001996 // exception-specification
1997 if (Tok.is(tok::kw_throw)) {
1998 ConsumeToken();
1999 if (Tok.isNot(tok::l_paren))
Richard Smithee390432014-05-16 01:56:53 +00002000 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00002001
2002 // Parse through the parens after 'throw'.
2003 ConsumeParen();
Alexey Bataevee6507d2013-11-18 08:17:37 +00002004 if (!SkipUntil(tok::r_paren, StopAtSemi))
Richard Smithee390432014-05-16 01:56:53 +00002005 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00002006 }
2007 if (Tok.is(tok::kw_noexcept)) {
2008 ConsumeToken();
2009 // Possibly an expression as well.
2010 if (Tok.is(tok::l_paren)) {
2011 // Find the matching rparen.
2012 ConsumeParen();
Alexey Bataevee6507d2013-11-18 08:17:37 +00002013 if (!SkipUntil(tok::r_paren, StopAtSemi))
Richard Smithee390432014-05-16 01:56:53 +00002014 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00002015 }
2016 }
2017
Richard Smithee390432014-05-16 01:56:53 +00002018 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00002019}
2020
2021/// '[' constant-expression[opt] ']'
2022///
2023Parser::TPResult Parser::TryParseBracketDeclarator() {
2024 ConsumeBracket();
Alexey Bataevee6507d2013-11-18 08:17:37 +00002025 if (!SkipUntil(tok::r_square, StopAtSemi))
Richard Smithee390432014-05-16 01:56:53 +00002026 return TPResult::Error;
Guy Benyei11169dd2012-12-18 14:30:41 +00002027
Richard Smithee390432014-05-16 01:56:53 +00002028 return TPResult::Ambiguous;
Guy Benyei11169dd2012-12-18 14:30:41 +00002029}