1 | //===--- ParseTentative.cpp - Ambiguity Resolution Parsing ----------------===// |
2 | // |
3 | // 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 |
6 | // |
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" |
17 | using 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 | /// |
49 | bool Parser::isCXXDeclarationStatement( |
50 | bool DisambiguatingWithExpression /*=false*/) { |
51 | assert(getLangOpts().CPlusPlus && "Must be called for C++ only." ); |
52 | |
53 | switch (Tok.getKind()) { |
54 | // asm-definition |
55 | case tok::kw_asm: |
56 | // namespace-alias-definition |
57 | case tok::kw_namespace: |
58 | // using-declaration |
59 | // using-directive |
60 | case tok::kw_using: |
61 | // static_assert-declaration |
62 | case tok::kw_static_assert: |
63 | case tok::kw__Static_assert: |
64 | return true; |
65 | case tok::coloncolon: |
66 | case tok::identifier: { |
67 | if (DisambiguatingWithExpression) { |
68 | RevertingTentativeParsingAction TPA(*this); |
69 | // Parse the C++ scope specifier. |
70 | CXXScopeSpec SS; |
71 | ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr, |
72 | /*ObjectHasErrors=*/false, |
73 | /*EnteringContext=*/true); |
74 | |
75 | switch (Tok.getKind()) { |
76 | case tok::identifier: { |
77 | IdentifierInfo *II = Tok.getIdentifierInfo(); |
78 | bool isDeductionGuide = Actions.isDeductionGuideName( |
79 | S: getCurScope(), Name: *II, NameLoc: Tok.getLocation(), SS, /*Template=*/nullptr); |
80 | if (Actions.isCurrentClassName(II: *II, S: getCurScope(), SS: &SS) || |
81 | isDeductionGuide) { |
82 | if (isConstructorDeclarator( |
83 | /*Unqualified=*/SS.isEmpty(), DeductionGuide: isDeductionGuide, |
84 | /*IsFriend=*/DeclSpec::FriendSpecified::No)) |
85 | return true; |
86 | } else if (SS.isNotEmpty()) { |
87 | // If the scope is not empty, it could alternatively be something like |
88 | // a typedef or using declaration. That declaration might be private |
89 | // in the global context, which would be diagnosed by calling into |
90 | // isCXXSimpleDeclaration, but may actually be fine in the context of |
91 | // member functions and static variable definitions. Check if the next |
92 | // token is also an identifier and assume a declaration. |
93 | // We cannot check if the scopes match because the declarations could |
94 | // involve namespaces and friend declarations. |
95 | if (NextToken().is(K: tok::identifier)) |
96 | return true; |
97 | } |
98 | break; |
99 | } |
100 | case tok::kw_operator: |
101 | return true; |
102 | case tok::tilde: |
103 | return true; |
104 | default: |
105 | break; |
106 | } |
107 | } |
108 | } |
109 | [[fallthrough]]; |
110 | // simple-declaration |
111 | default: |
112 | return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false); |
113 | } |
114 | } |
115 | |
116 | /// isCXXSimpleDeclaration - C++-specialized function that disambiguates |
117 | /// between a simple-declaration or an expression-statement. |
118 | /// If during the disambiguation process a parsing error is encountered, |
119 | /// the function returns true to let the declaration parsing code handle it. |
120 | /// Returns false if the statement is disambiguated as expression. |
121 | /// |
122 | /// simple-declaration: |
123 | /// decl-specifier-seq init-declarator-list[opt] ';' |
124 | /// decl-specifier-seq ref-qualifier[opt] '[' identifier-list ']' |
125 | /// brace-or-equal-initializer ';' [C++17] |
126 | /// |
127 | /// (if AllowForRangeDecl specified) |
128 | /// for ( for-range-declaration : for-range-initializer ) statement |
129 | /// |
130 | /// for-range-declaration: |
131 | /// decl-specifier-seq declarator |
132 | /// decl-specifier-seq ref-qualifier[opt] '[' identifier-list ']' |
133 | /// |
134 | /// In any of the above cases there can be a preceding attribute-specifier-seq, |
135 | /// but the caller is expected to handle that. |
136 | bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) { |
137 | // C++ 6.8p1: |
138 | // There is an ambiguity in the grammar involving expression-statements and |
139 | // declarations: An expression-statement with a function-style explicit type |
140 | // conversion (5.2.3) as its leftmost subexpression can be indistinguishable |
141 | // from a declaration where the first declarator starts with a '('. In those |
142 | // cases the statement is a declaration. [Note: To disambiguate, the whole |
143 | // statement might have to be examined to determine if it is an |
144 | // expression-statement or a declaration]. |
145 | |
146 | // C++ 6.8p3: |
147 | // The disambiguation is purely syntactic; that is, the meaning of the names |
148 | // occurring in such a statement, beyond whether they are type-names or not, |
149 | // is not generally used in or changed by the disambiguation. Class |
150 | // templates are instantiated as necessary to determine if a qualified name |
151 | // is a type-name. Disambiguation precedes parsing, and a statement |
152 | // disambiguated as a declaration may be an ill-formed declaration. |
153 | |
154 | // We don't have to parse all of the decl-specifier-seq part. There's only |
155 | // an ambiguity if the first decl-specifier is |
156 | // simple-type-specifier/typename-specifier followed by a '(', which may |
157 | // indicate a function-style cast expression. |
158 | // isCXXDeclarationSpecifier will return TPResult::Ambiguous only in such |
159 | // a case. |
160 | |
161 | bool InvalidAsDeclaration = false; |
162 | TPResult TPR = isCXXDeclarationSpecifier( |
163 | AllowImplicitTypename: ImplicitTypenameContext::No, BracedCastResult: TPResult::False, InvalidAsDeclSpec: &InvalidAsDeclaration); |
164 | if (TPR != TPResult::Ambiguous) |
165 | return TPR != TPResult::False; // Returns true for TPResult::True or |
166 | // TPResult::Error. |
167 | |
168 | // FIXME: TryParseSimpleDeclaration doesn't look past the first initializer, |
169 | // and so gets some cases wrong. We can't carry on if we've already seen |
170 | // something which makes this statement invalid as a declaration in this case, |
171 | // since it can cause us to misparse valid code. Revisit this once |
172 | // TryParseInitDeclaratorList is fixed. |
173 | if (InvalidAsDeclaration) |
174 | return false; |
175 | |
176 | // FIXME: Add statistics about the number of ambiguous statements encountered |
177 | // and how they were resolved (number of declarations+number of expressions). |
178 | |
179 | // Ok, we have a simple-type-specifier/typename-specifier followed by a '(', |
180 | // or an identifier which doesn't resolve as anything. We need tentative |
181 | // parsing... |
182 | |
183 | { |
184 | RevertingTentativeParsingAction PA(*this); |
185 | TPR = TryParseSimpleDeclaration(AllowForRangeDecl); |
186 | } |
187 | |
188 | // In case of an error, let the declaration parsing code handle it. |
189 | if (TPR == TPResult::Error) |
190 | return true; |
191 | |
192 | // Declarations take precedence over expressions. |
193 | if (TPR == TPResult::Ambiguous) |
194 | TPR = TPResult::True; |
195 | |
196 | assert(TPR == TPResult::True || TPR == TPResult::False); |
197 | return TPR == TPResult::True; |
198 | } |
199 | |
200 | /// Try to consume a token sequence that we've already identified as |
201 | /// (potentially) starting a decl-specifier. |
202 | Parser::TPResult Parser::TryConsumeDeclarationSpecifier() { |
203 | switch (Tok.getKind()) { |
204 | case tok::kw__Atomic: |
205 | if (NextToken().isNot(K: tok::l_paren)) { |
206 | ConsumeToken(); |
207 | break; |
208 | } |
209 | [[fallthrough]]; |
210 | case tok::kw_typeof: |
211 | case tok::kw___attribute: |
212 | #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: |
213 | #include "clang/Basic/TransformTypeTraits.def" |
214 | { |
215 | ConsumeToken(); |
216 | if (Tok.isNot(K: tok::l_paren)) |
217 | return TPResult::Error; |
218 | ConsumeParen(); |
219 | if (!SkipUntil(T: tok::r_paren)) |
220 | return TPResult::Error; |
221 | break; |
222 | } |
223 | |
224 | case tok::kw_class: |
225 | case tok::kw_struct: |
226 | case tok::kw_union: |
227 | case tok::kw___interface: |
228 | case tok::kw_enum: |
229 | // elaborated-type-specifier: |
230 | // class-key attribute-specifier-seq[opt] |
231 | // nested-name-specifier[opt] identifier |
232 | // class-key nested-name-specifier[opt] template[opt] simple-template-id |
233 | // enum nested-name-specifier[opt] identifier |
234 | // |
235 | // FIXME: We don't support class-specifiers nor enum-specifiers here. |
236 | ConsumeToken(); |
237 | |
238 | // Skip attributes. |
239 | if (!TrySkipAttributes()) |
240 | return TPResult::Error; |
241 | |
242 | if (TryAnnotateOptionalCXXScopeToken()) |
243 | return TPResult::Error; |
244 | if (Tok.is(K: tok::annot_cxxscope)) |
245 | ConsumeAnnotationToken(); |
246 | if (Tok.is(K: tok::identifier)) |
247 | ConsumeToken(); |
248 | else if (Tok.is(K: tok::annot_template_id)) |
249 | ConsumeAnnotationToken(); |
250 | else |
251 | return TPResult::Error; |
252 | break; |
253 | |
254 | case tok::annot_cxxscope: |
255 | ConsumeAnnotationToken(); |
256 | [[fallthrough]]; |
257 | default: |
258 | ConsumeAnyToken(); |
259 | |
260 | if (getLangOpts().ObjC && Tok.is(K: tok::less)) |
261 | return TryParseProtocolQualifiers(); |
262 | break; |
263 | } |
264 | |
265 | return TPResult::Ambiguous; |
266 | } |
267 | |
268 | /// simple-declaration: |
269 | /// decl-specifier-seq init-declarator-list[opt] ';' |
270 | /// |
271 | /// (if AllowForRangeDecl specified) |
272 | /// for ( for-range-declaration : for-range-initializer ) statement |
273 | /// for-range-declaration: |
274 | /// attribute-specifier-seqopt type-specifier-seq declarator |
275 | /// |
276 | Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) { |
277 | bool DeclSpecifierIsAuto = Tok.is(K: tok::kw_auto); |
278 | if (TryConsumeDeclarationSpecifier() == TPResult::Error) |
279 | return TPResult::Error; |
280 | |
281 | // Two decl-specifiers in a row conclusively disambiguate this as being a |
282 | // simple-declaration. Don't bother calling isCXXDeclarationSpecifier in the |
283 | // overwhelmingly common case that the next token is a '('. |
284 | if (Tok.isNot(K: tok::l_paren)) { |
285 | TPResult TPR = isCXXDeclarationSpecifier(AllowImplicitTypename: ImplicitTypenameContext::No); |
286 | if (TPR == TPResult::Ambiguous) |
287 | return TPResult::True; |
288 | if (TPR == TPResult::True || TPR == TPResult::Error) |
289 | return TPR; |
290 | assert(TPR == TPResult::False); |
291 | } |
292 | |
293 | TPResult TPR = TryParseInitDeclaratorList( |
294 | /*mayHaveTrailingReturnType=*/MayHaveTrailingReturnType: DeclSpecifierIsAuto); |
295 | if (TPR != TPResult::Ambiguous) |
296 | return TPR; |
297 | |
298 | if (Tok.isNot(K: tok::semi) && (!AllowForRangeDecl || Tok.isNot(K: tok::colon))) |
299 | return TPResult::False; |
300 | |
301 | return TPResult::Ambiguous; |
302 | } |
303 | |
304 | /// Tentatively parse an init-declarator-list in order to disambiguate it from |
305 | /// an expression. |
306 | /// |
307 | /// init-declarator-list: |
308 | /// init-declarator |
309 | /// init-declarator-list ',' init-declarator |
310 | /// |
311 | /// init-declarator: |
312 | /// declarator initializer[opt] |
313 | /// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt] |
314 | /// |
315 | /// initializer: |
316 | /// brace-or-equal-initializer |
317 | /// '(' expression-list ')' |
318 | /// |
319 | /// brace-or-equal-initializer: |
320 | /// '=' initializer-clause |
321 | /// [C++11] braced-init-list |
322 | /// |
323 | /// initializer-clause: |
324 | /// assignment-expression |
325 | /// braced-init-list |
326 | /// |
327 | /// braced-init-list: |
328 | /// '{' initializer-list ','[opt] '}' |
329 | /// '{' '}' |
330 | /// |
331 | Parser::TPResult |
332 | Parser::TryParseInitDeclaratorList(bool MayHaveTrailingReturnType) { |
333 | while (true) { |
334 | // declarator |
335 | TPResult TPR = TryParseDeclarator( |
336 | /*mayBeAbstract=*/false, |
337 | /*mayHaveIdentifier=*/true, |
338 | /*mayHaveDirectInit=*/false, |
339 | /*mayHaveTrailingReturnType=*/MayHaveTrailingReturnType); |
340 | if (TPR != TPResult::Ambiguous) |
341 | return TPR; |
342 | |
343 | // [GNU] simple-asm-expr[opt] attributes[opt] |
344 | if (Tok.isOneOf(K1: tok::kw_asm, K2: tok::kw___attribute)) |
345 | return TPResult::True; |
346 | |
347 | // initializer[opt] |
348 | if (Tok.is(K: tok::l_paren)) { |
349 | // Parse through the parens. |
350 | ConsumeParen(); |
351 | if (!SkipUntil(T: tok::r_paren, Flags: StopAtSemi)) |
352 | return TPResult::Error; |
353 | } else if (Tok.is(K: tok::l_brace)) { |
354 | // A left-brace here is sufficient to disambiguate the parse; an |
355 | // expression can never be followed directly by a braced-init-list. |
356 | return TPResult::True; |
357 | } else if (Tok.is(K: tok::equal) || isTokIdentifier_in()) { |
358 | // MSVC and g++ won't examine the rest of declarators if '=' is |
359 | // encountered; they just conclude that we have a declaration. |
360 | // EDG parses the initializer completely, which is the proper behavior |
361 | // for this case. |
362 | // |
363 | // At present, Clang follows MSVC and g++, since the parser does not have |
364 | // the ability to parse an expression fully without recording the |
365 | // results of that parse. |
366 | // FIXME: Handle this case correctly. |
367 | // |
368 | // Also allow 'in' after an Objective-C declaration as in: |
369 | // for (int (^b)(void) in array). Ideally this should be done in the |
370 | // context of parsing for-init-statement of a foreach statement only. But, |
371 | // in any other context 'in' is invalid after a declaration and parser |
372 | // issues the error regardless of outcome of this decision. |
373 | // FIXME: Change if above assumption does not hold. |
374 | return TPResult::True; |
375 | } |
376 | |
377 | if (!TryConsumeToken(Expected: tok::comma)) |
378 | break; |
379 | } |
380 | |
381 | return TPResult::Ambiguous; |
382 | } |
383 | |
384 | struct Parser::ConditionDeclarationOrInitStatementState { |
385 | Parser &P; |
386 | bool CanBeExpression = true; |
387 | bool CanBeCondition = true; |
388 | bool CanBeInitStatement; |
389 | bool CanBeForRangeDecl; |
390 | |
391 | ConditionDeclarationOrInitStatementState(Parser &P, bool CanBeInitStatement, |
392 | bool CanBeForRangeDecl) |
393 | : P(P), CanBeInitStatement(CanBeInitStatement), |
394 | CanBeForRangeDecl(CanBeForRangeDecl) {} |
395 | |
396 | bool resolved() { |
397 | return CanBeExpression + CanBeCondition + CanBeInitStatement + |
398 | CanBeForRangeDecl < 2; |
399 | } |
400 | |
401 | void markNotExpression() { |
402 | CanBeExpression = false; |
403 | |
404 | if (!resolved()) { |
405 | // FIXME: Unify the parsing codepaths for condition variables and |
406 | // simple-declarations so that we don't need to eagerly figure out which |
407 | // kind we have here. (Just parse init-declarators until we reach a |
408 | // semicolon or right paren.) |
409 | RevertingTentativeParsingAction PA(P); |
410 | if (CanBeForRangeDecl) { |
411 | // Skip until we hit a ')', ';', or a ':' with no matching '?'. |
412 | // The final case is a for range declaration, the rest are not. |
413 | unsigned QuestionColonDepth = 0; |
414 | while (true) { |
415 | P.SkipUntil(Toks: {tok::r_paren, tok::semi, tok::question, tok::colon}, |
416 | Flags: StopBeforeMatch); |
417 | if (P.Tok.is(K: tok::question)) |
418 | ++QuestionColonDepth; |
419 | else if (P.Tok.is(K: tok::colon)) { |
420 | if (QuestionColonDepth) |
421 | --QuestionColonDepth; |
422 | else { |
423 | CanBeCondition = CanBeInitStatement = false; |
424 | return; |
425 | } |
426 | } else { |
427 | CanBeForRangeDecl = false; |
428 | break; |
429 | } |
430 | P.ConsumeToken(); |
431 | } |
432 | } else { |
433 | // Just skip until we hit a ')' or ';'. |
434 | P.SkipUntil(T1: tok::r_paren, T2: tok::semi, Flags: StopBeforeMatch); |
435 | } |
436 | if (P.Tok.isNot(K: tok::r_paren)) |
437 | CanBeCondition = CanBeForRangeDecl = false; |
438 | if (P.Tok.isNot(K: tok::semi)) |
439 | CanBeInitStatement = false; |
440 | } |
441 | } |
442 | |
443 | bool markNotCondition() { |
444 | CanBeCondition = false; |
445 | return resolved(); |
446 | } |
447 | |
448 | bool markNotForRangeDecl() { |
449 | CanBeForRangeDecl = false; |
450 | return resolved(); |
451 | } |
452 | |
453 | bool update(TPResult IsDecl) { |
454 | switch (IsDecl) { |
455 | case TPResult::True: |
456 | markNotExpression(); |
457 | assert(resolved() && "can't continue after tentative parsing bails out" ); |
458 | break; |
459 | case TPResult::False: |
460 | CanBeCondition = CanBeInitStatement = CanBeForRangeDecl = false; |
461 | break; |
462 | case TPResult::Ambiguous: |
463 | break; |
464 | case TPResult::Error: |
465 | CanBeExpression = CanBeCondition = CanBeInitStatement = |
466 | CanBeForRangeDecl = false; |
467 | break; |
468 | } |
469 | return resolved(); |
470 | } |
471 | |
472 | ConditionOrInitStatement result() const { |
473 | assert(CanBeExpression + CanBeCondition + CanBeInitStatement + |
474 | CanBeForRangeDecl < 2 && |
475 | "result called but not yet resolved" ); |
476 | if (CanBeExpression) |
477 | return ConditionOrInitStatement::Expression; |
478 | if (CanBeCondition) |
479 | return ConditionOrInitStatement::ConditionDecl; |
480 | if (CanBeInitStatement) |
481 | return ConditionOrInitStatement::InitStmtDecl; |
482 | if (CanBeForRangeDecl) |
483 | return ConditionOrInitStatement::ForRangeDecl; |
484 | return ConditionOrInitStatement::Error; |
485 | } |
486 | }; |
487 | |
488 | bool Parser::isEnumBase(bool AllowSemi) { |
489 | assert(Tok.is(tok::colon) && "should be looking at the ':'" ); |
490 | |
491 | RevertingTentativeParsingAction PA(*this); |
492 | // ':' |
493 | ConsumeToken(); |
494 | |
495 | // type-specifier-seq |
496 | bool InvalidAsDeclSpec = false; |
497 | // FIXME: We could disallow non-type decl-specifiers here, but it makes no |
498 | // difference: those specifiers are ill-formed regardless of the |
499 | // interpretation. |
500 | TPResult R = isCXXDeclarationSpecifier(AllowImplicitTypename: ImplicitTypenameContext::No, |
501 | /*BracedCastResult=*/TPResult::True, |
502 | InvalidAsDeclSpec: &InvalidAsDeclSpec); |
503 | if (R == TPResult::Ambiguous) { |
504 | // We either have a decl-specifier followed by '(' or an undeclared |
505 | // identifier. |
506 | if (TryConsumeDeclarationSpecifier() == TPResult::Error) |
507 | return true; |
508 | |
509 | // If we get to the end of the enum-base, we hit either a '{' or a ';'. |
510 | // Don't bother checking the enumerator-list. |
511 | if (Tok.is(K: tok::l_brace) || (AllowSemi && Tok.is(K: tok::semi))) |
512 | return true; |
513 | |
514 | // A second decl-specifier unambiguously indicatges an enum-base. |
515 | R = isCXXDeclarationSpecifier(AllowImplicitTypename: ImplicitTypenameContext::No, BracedCastResult: TPResult::True, |
516 | InvalidAsDeclSpec: &InvalidAsDeclSpec); |
517 | } |
518 | |
519 | return R != TPResult::False; |
520 | } |
521 | |
522 | /// Disambiguates between a declaration in a condition, a |
523 | /// simple-declaration in an init-statement, and an expression for |
524 | /// a condition of a if/switch statement. |
525 | /// |
526 | /// condition: |
527 | /// expression |
528 | /// type-specifier-seq declarator '=' assignment-expression |
529 | /// [C++11] type-specifier-seq declarator '=' initializer-clause |
530 | /// [C++11] type-specifier-seq declarator braced-init-list |
531 | /// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt] |
532 | /// '=' assignment-expression |
533 | /// simple-declaration: |
534 | /// decl-specifier-seq init-declarator-list[opt] ';' |
535 | /// |
536 | /// Note that, unlike isCXXSimpleDeclaration, we must disambiguate all the way |
537 | /// to the ';' to disambiguate cases like 'int(x))' (an expression) from |
538 | /// 'int(x);' (a simple-declaration in an init-statement). |
539 | Parser::ConditionOrInitStatement |
540 | Parser::isCXXConditionDeclarationOrInitStatement(bool CanBeInitStatement, |
541 | bool CanBeForRangeDecl) { |
542 | ConditionDeclarationOrInitStatementState State(*this, CanBeInitStatement, |
543 | CanBeForRangeDecl); |
544 | |
545 | if (CanBeInitStatement && Tok.is(K: tok::kw_using)) |
546 | return ConditionOrInitStatement::InitStmtDecl; |
547 | if (State.update(IsDecl: isCXXDeclarationSpecifier(AllowImplicitTypename: ImplicitTypenameContext::No))) |
548 | return State.result(); |
549 | |
550 | // It might be a declaration; we need tentative parsing. |
551 | RevertingTentativeParsingAction PA(*this); |
552 | |
553 | // FIXME: A tag definition unambiguously tells us this is an init-statement. |
554 | bool MayHaveTrailingReturnType = Tok.is(K: tok::kw_auto); |
555 | if (State.update(IsDecl: TryConsumeDeclarationSpecifier())) |
556 | return State.result(); |
557 | assert(Tok.is(tok::l_paren) && "Expected '('" ); |
558 | |
559 | while (true) { |
560 | // Consume a declarator. |
561 | if (State.update(IsDecl: TryParseDeclarator( |
562 | /*mayBeAbstract=*/false, |
563 | /*mayHaveIdentifier=*/true, |
564 | /*mayHaveDirectInit=*/false, |
565 | /*mayHaveTrailingReturnType=*/MayHaveTrailingReturnType))) |
566 | return State.result(); |
567 | |
568 | // Attributes, asm label, or an initializer imply this is not an expression. |
569 | // FIXME: Disambiguate properly after an = instead of assuming that it's a |
570 | // valid declaration. |
571 | if (Tok.isOneOf(K1: tok::equal, Ks: tok::kw_asm, Ks: tok::kw___attribute) || |
572 | (getLangOpts().CPlusPlus11 && Tok.is(K: tok::l_brace))) { |
573 | State.markNotExpression(); |
574 | return State.result(); |
575 | } |
576 | |
577 | // A colon here identifies a for-range declaration. |
578 | if (State.CanBeForRangeDecl && Tok.is(K: tok::colon)) |
579 | return ConditionOrInitStatement::ForRangeDecl; |
580 | |
581 | // At this point, it can't be a condition any more, because a condition |
582 | // must have a brace-or-equal-initializer. |
583 | if (State.markNotCondition()) |
584 | return State.result(); |
585 | |
586 | // Likewise, it can't be a for-range declaration any more. |
587 | if (State.markNotForRangeDecl()) |
588 | return State.result(); |
589 | |
590 | // A parenthesized initializer could be part of an expression or a |
591 | // simple-declaration. |
592 | if (Tok.is(K: tok::l_paren)) { |
593 | ConsumeParen(); |
594 | SkipUntil(T: tok::r_paren, Flags: StopAtSemi); |
595 | } |
596 | |
597 | if (!TryConsumeToken(Expected: tok::comma)) |
598 | break; |
599 | } |
600 | |
601 | // We reached the end. If it can now be some kind of decl, then it is. |
602 | if (State.CanBeCondition && Tok.is(K: tok::r_paren)) |
603 | return ConditionOrInitStatement::ConditionDecl; |
604 | else if (State.CanBeInitStatement && Tok.is(K: tok::semi)) |
605 | return ConditionOrInitStatement::InitStmtDecl; |
606 | else |
607 | return ConditionOrInitStatement::Expression; |
608 | } |
609 | |
610 | /// Determine whether the next set of tokens contains a type-id. |
611 | /// |
612 | /// The context parameter states what context we're parsing right |
613 | /// now, which affects how this routine copes with the token |
614 | /// following the type-id. If the context is TypeIdInParens, we have |
615 | /// already parsed the '(' and we will cease lookahead when we hit |
616 | /// the corresponding ')'. If the context is |
617 | /// TypeIdAsTemplateArgument, we've already parsed the '<' or ',' |
618 | /// before this template argument, and will cease lookahead when we |
619 | /// hit a '>', '>>' (in C++0x), or ','; or, in C++0x, an ellipsis immediately |
620 | /// preceding such. Returns true for a type-id and false for an expression. |
621 | /// If during the disambiguation process a parsing error is encountered, |
622 | /// the function returns true to let the declaration parsing code handle it. |
623 | /// |
624 | /// type-id: |
625 | /// type-specifier-seq abstract-declarator[opt] |
626 | /// |
627 | bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) { |
628 | |
629 | isAmbiguous = false; |
630 | |
631 | // C++ 8.2p2: |
632 | // The ambiguity arising from the similarity between a function-style cast and |
633 | // a type-id can occur in different contexts. The ambiguity appears as a |
634 | // choice between a function-style cast expression and a declaration of a |
635 | // type. The resolution is that any construct that could possibly be a type-id |
636 | // in its syntactic context shall be considered a type-id. |
637 | |
638 | TPResult TPR = isCXXDeclarationSpecifier(AllowImplicitTypename: ImplicitTypenameContext::No); |
639 | if (TPR != TPResult::Ambiguous) |
640 | return TPR != TPResult::False; // Returns true for TPResult::True or |
641 | // TPResult::Error. |
642 | |
643 | // FIXME: Add statistics about the number of ambiguous statements encountered |
644 | // and how they were resolved (number of declarations+number of expressions). |
645 | |
646 | // Ok, we have a simple-type-specifier/typename-specifier followed by a '('. |
647 | // We need tentative parsing... |
648 | |
649 | RevertingTentativeParsingAction PA(*this); |
650 | bool MayHaveTrailingReturnType = Tok.is(K: tok::kw_auto); |
651 | |
652 | // type-specifier-seq |
653 | TryConsumeDeclarationSpecifier(); |
654 | assert(Tok.is(tok::l_paren) && "Expected '('" ); |
655 | |
656 | // declarator |
657 | TPR = TryParseDeclarator(mayBeAbstract: true /*mayBeAbstract*/, mayHaveIdentifier: false /*mayHaveIdentifier*/, |
658 | /*mayHaveDirectInit=*/false, |
659 | mayHaveTrailingReturnType: MayHaveTrailingReturnType); |
660 | |
661 | // In case of an error, let the declaration parsing code handle it. |
662 | if (TPR == TPResult::Error) |
663 | TPR = TPResult::True; |
664 | |
665 | if (TPR == TPResult::Ambiguous) { |
666 | // We are supposed to be inside parens, so if after the abstract declarator |
667 | // we encounter a ')' this is a type-id, otherwise it's an expression. |
668 | if (Context == TypeIdInParens && Tok.is(K: tok::r_paren)) { |
669 | TPR = TPResult::True; |
670 | isAmbiguous = true; |
671 | // We are supposed to be inside the first operand to a _Generic selection |
672 | // expression, so if we find a comma after the declarator, we've found a |
673 | // type and not an expression. |
674 | } else if (Context == TypeIdAsGenericSelectionArgument && Tok.is(K: tok::comma)) { |
675 | TPR = TPResult::True; |
676 | isAmbiguous = true; |
677 | // We are supposed to be inside a template argument, so if after |
678 | // the abstract declarator we encounter a '>', '>>' (in C++0x), or |
679 | // ','; or, in C++0x, an ellipsis immediately preceding such, this |
680 | // is a type-id. Otherwise, it's an expression. |
681 | } else if (Context == TypeIdAsTemplateArgument && |
682 | (Tok.isOneOf(K1: tok::greater, K2: tok::comma) || |
683 | (getLangOpts().CPlusPlus11 && |
684 | (Tok.isOneOf(K1: tok::greatergreater, |
685 | K2: tok::greatergreatergreater) || |
686 | (Tok.is(K: tok::ellipsis) && |
687 | NextToken().isOneOf(K1: tok::greater, Ks: tok::greatergreater, |
688 | Ks: tok::greatergreatergreater, |
689 | Ks: tok::comma)))))) { |
690 | TPR = TPResult::True; |
691 | isAmbiguous = true; |
692 | |
693 | } else if (Context == TypeIdInTrailingReturnType) { |
694 | TPR = TPResult::True; |
695 | isAmbiguous = true; |
696 | } else |
697 | TPR = TPResult::False; |
698 | } |
699 | |
700 | assert(TPR == TPResult::True || TPR == TPResult::False); |
701 | return TPR == TPResult::True; |
702 | } |
703 | |
704 | /// Returns true if this is a C++11 attribute-specifier. Per |
705 | /// C++11 [dcl.attr.grammar]p6, two consecutive left square bracket tokens |
706 | /// always introduce an attribute. In Objective-C++11, this rule does not |
707 | /// apply if either '[' begins a message-send. |
708 | /// |
709 | /// If Disambiguate is true, we try harder to determine whether a '[[' starts |
710 | /// an attribute-specifier, and return CAK_InvalidAttributeSpecifier if not. |
711 | /// |
712 | /// If OuterMightBeMessageSend is true, we assume the outer '[' is either an |
713 | /// Obj-C message send or the start of an attribute. Otherwise, we assume it |
714 | /// is not an Obj-C message send. |
715 | /// |
716 | /// C++11 [dcl.attr.grammar]: |
717 | /// |
718 | /// attribute-specifier: |
719 | /// '[' '[' attribute-list ']' ']' |
720 | /// alignment-specifier |
721 | /// |
722 | /// attribute-list: |
723 | /// attribute[opt] |
724 | /// attribute-list ',' attribute[opt] |
725 | /// attribute '...' |
726 | /// attribute-list ',' attribute '...' |
727 | /// |
728 | /// attribute: |
729 | /// attribute-token attribute-argument-clause[opt] |
730 | /// |
731 | /// attribute-token: |
732 | /// identifier |
733 | /// identifier '::' identifier |
734 | /// |
735 | /// attribute-argument-clause: |
736 | /// '(' balanced-token-seq ')' |
737 | Parser::CXX11AttributeKind |
738 | Parser::isCXX11AttributeSpecifier(bool Disambiguate, |
739 | bool OuterMightBeMessageSend) { |
740 | if (Tok.is(K: tok::kw_alignas)) |
741 | return CAK_AttributeSpecifier; |
742 | |
743 | if (Tok.isRegularKeywordAttribute()) |
744 | return CAK_AttributeSpecifier; |
745 | |
746 | if (Tok.isNot(K: tok::l_square) || NextToken().isNot(K: tok::l_square)) |
747 | return CAK_NotAttributeSpecifier; |
748 | |
749 | // No tentative parsing if we don't need to look for ']]' or a lambda. |
750 | if (!Disambiguate && !getLangOpts().ObjC) |
751 | return CAK_AttributeSpecifier; |
752 | |
753 | // '[[using ns: ...]]' is an attribute. |
754 | if (GetLookAheadToken(N: 2).is(K: tok::kw_using)) |
755 | return CAK_AttributeSpecifier; |
756 | |
757 | RevertingTentativeParsingAction PA(*this); |
758 | |
759 | // Opening brackets were checked for above. |
760 | ConsumeBracket(); |
761 | |
762 | if (!getLangOpts().ObjC) { |
763 | ConsumeBracket(); |
764 | |
765 | bool IsAttribute = SkipUntil(T: tok::r_square); |
766 | IsAttribute &= Tok.is(K: tok::r_square); |
767 | |
768 | return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier; |
769 | } |
770 | |
771 | // In Obj-C++11, we need to distinguish four situations: |
772 | // 1a) int x[[attr]]; C++11 attribute. |
773 | // 1b) [[attr]]; C++11 statement attribute. |
774 | // 2) int x[[obj](){ return 1; }()]; Lambda in array size/index. |
775 | // 3a) int x[[obj get]]; Message send in array size/index. |
776 | // 3b) [[Class alloc] init]; Message send in message send. |
777 | // 4) [[obj]{ return self; }() doStuff]; Lambda in message send. |
778 | // (1) is an attribute, (2) is ill-formed, and (3) and (4) are accepted. |
779 | |
780 | // Check to see if this is a lambda-expression. |
781 | // FIXME: If this disambiguation is too slow, fold the tentative lambda parse |
782 | // into the tentative attribute parse below. |
783 | { |
784 | RevertingTentativeParsingAction LambdaTPA(*this); |
785 | LambdaIntroducer Intro; |
786 | LambdaIntroducerTentativeParse Tentative; |
787 | if (ParseLambdaIntroducer(Intro, Tentative: &Tentative)) { |
788 | // We hit a hard error after deciding this was not an attribute. |
789 | // FIXME: Don't parse and annotate expressions when disambiguating |
790 | // against an attribute. |
791 | return CAK_NotAttributeSpecifier; |
792 | } |
793 | |
794 | switch (Tentative) { |
795 | case LambdaIntroducerTentativeParse::MessageSend: |
796 | // Case 3: The inner construct is definitely a message send, so the |
797 | // outer construct is definitely not an attribute. |
798 | return CAK_NotAttributeSpecifier; |
799 | |
800 | case LambdaIntroducerTentativeParse::Success: |
801 | case LambdaIntroducerTentativeParse::Incomplete: |
802 | // This is a lambda-introducer or attribute-specifier. |
803 | if (Tok.is(K: tok::r_square)) |
804 | // Case 1: C++11 attribute. |
805 | return CAK_AttributeSpecifier; |
806 | |
807 | if (OuterMightBeMessageSend) |
808 | // Case 4: Lambda in message send. |
809 | return CAK_NotAttributeSpecifier; |
810 | |
811 | // Case 2: Lambda in array size / index. |
812 | return CAK_InvalidAttributeSpecifier; |
813 | |
814 | case LambdaIntroducerTentativeParse::Invalid: |
815 | // No idea what this is; we couldn't parse it as a lambda-introducer. |
816 | // Might still be an attribute-specifier or a message send. |
817 | break; |
818 | } |
819 | } |
820 | |
821 | ConsumeBracket(); |
822 | |
823 | // If we don't have a lambda-introducer, then we have an attribute or a |
824 | // message-send. |
825 | bool IsAttribute = true; |
826 | while (Tok.isNot(K: tok::r_square)) { |
827 | if (Tok.is(K: tok::comma)) { |
828 | // Case 1: Stray commas can only occur in attributes. |
829 | return CAK_AttributeSpecifier; |
830 | } |
831 | |
832 | // Parse the attribute-token, if present. |
833 | // C++11 [dcl.attr.grammar]: |
834 | // If a keyword or an alternative token that satisfies the syntactic |
835 | // requirements of an identifier is contained in an attribute-token, |
836 | // it is considered an identifier. |
837 | SourceLocation Loc; |
838 | if (!TryParseCXX11AttributeIdentifier(Loc)) { |
839 | IsAttribute = false; |
840 | break; |
841 | } |
842 | if (Tok.is(K: tok::coloncolon)) { |
843 | ConsumeToken(); |
844 | if (!TryParseCXX11AttributeIdentifier(Loc)) { |
845 | IsAttribute = false; |
846 | break; |
847 | } |
848 | } |
849 | |
850 | // Parse the attribute-argument-clause, if present. |
851 | if (Tok.is(K: tok::l_paren)) { |
852 | ConsumeParen(); |
853 | if (!SkipUntil(T: tok::r_paren)) { |
854 | IsAttribute = false; |
855 | break; |
856 | } |
857 | } |
858 | |
859 | TryConsumeToken(Expected: tok::ellipsis); |
860 | |
861 | if (!TryConsumeToken(Expected: tok::comma)) |
862 | break; |
863 | } |
864 | |
865 | // An attribute must end ']]'. |
866 | if (IsAttribute) { |
867 | if (Tok.is(K: tok::r_square)) { |
868 | ConsumeBracket(); |
869 | IsAttribute = Tok.is(K: tok::r_square); |
870 | } else { |
871 | IsAttribute = false; |
872 | } |
873 | } |
874 | |
875 | if (IsAttribute) |
876 | // Case 1: C++11 statement attribute. |
877 | return CAK_AttributeSpecifier; |
878 | |
879 | // Case 3: Message send. |
880 | return CAK_NotAttributeSpecifier; |
881 | } |
882 | |
883 | bool Parser::TrySkipAttributes() { |
884 | while (Tok.isOneOf(K1: tok::l_square, Ks: tok::kw___attribute, Ks: tok::kw___declspec, |
885 | Ks: tok::kw_alignas) || |
886 | Tok.isRegularKeywordAttribute()) { |
887 | if (Tok.is(K: tok::l_square)) { |
888 | ConsumeBracket(); |
889 | if (Tok.isNot(K: tok::l_square)) |
890 | return false; |
891 | ConsumeBracket(); |
892 | if (!SkipUntil(T: tok::r_square) || Tok.isNot(K: tok::r_square)) |
893 | return false; |
894 | // Note that explicitly checking for `[[` and `]]` allows to fail as |
895 | // expected in the case of the Objective-C message send syntax. |
896 | ConsumeBracket(); |
897 | } else if (Tok.isRegularKeywordAttribute() && |
898 | !doesKeywordAttributeTakeArgs(Kind: Tok.getKind())) { |
899 | ConsumeToken(); |
900 | } else { |
901 | ConsumeToken(); |
902 | if (Tok.isNot(K: tok::l_paren)) |
903 | return false; |
904 | ConsumeParen(); |
905 | if (!SkipUntil(T: tok::r_paren)) |
906 | return false; |
907 | } |
908 | } |
909 | |
910 | return true; |
911 | } |
912 | |
913 | Parser::TPResult Parser::TryParsePtrOperatorSeq() { |
914 | while (true) { |
915 | if (TryAnnotateOptionalCXXScopeToken(EnteringContext: true)) |
916 | return TPResult::Error; |
917 | |
918 | if (Tok.isOneOf(K1: tok::star, Ks: tok::amp, Ks: tok::caret, Ks: tok::ampamp) || |
919 | (Tok.is(K: tok::annot_cxxscope) && NextToken().is(K: tok::star))) { |
920 | // ptr-operator |
921 | ConsumeAnyToken(); |
922 | |
923 | // Skip attributes. |
924 | if (!TrySkipAttributes()) |
925 | return TPResult::Error; |
926 | |
927 | while (Tok.isOneOf(K1: tok::kw_const, Ks: tok::kw_volatile, Ks: tok::kw_restrict, |
928 | Ks: tok::kw__Nonnull, Ks: tok::kw__Nullable, |
929 | Ks: tok::kw__Nullable_result, Ks: tok::kw__Null_unspecified, |
930 | Ks: tok::kw__Atomic)) |
931 | ConsumeToken(); |
932 | } else { |
933 | return TPResult::True; |
934 | } |
935 | } |
936 | } |
937 | |
938 | /// operator-function-id: |
939 | /// 'operator' operator |
940 | /// |
941 | /// operator: one of |
942 | /// new delete new[] delete[] + - * / % ^ [...] |
943 | /// |
944 | /// conversion-function-id: |
945 | /// 'operator' conversion-type-id |
946 | /// |
947 | /// conversion-type-id: |
948 | /// type-specifier-seq conversion-declarator[opt] |
949 | /// |
950 | /// conversion-declarator: |
951 | /// ptr-operator conversion-declarator[opt] |
952 | /// |
953 | /// literal-operator-id: |
954 | /// 'operator' string-literal identifier |
955 | /// 'operator' user-defined-string-literal |
956 | Parser::TPResult Parser::TryParseOperatorId() { |
957 | assert(Tok.is(tok::kw_operator)); |
958 | ConsumeToken(); |
959 | |
960 | // Maybe this is an operator-function-id. |
961 | switch (Tok.getKind()) { |
962 | case tok::kw_new: case tok::kw_delete: |
963 | ConsumeToken(); |
964 | if (Tok.is(K: tok::l_square) && NextToken().is(K: tok::r_square)) { |
965 | ConsumeBracket(); |
966 | ConsumeBracket(); |
967 | } |
968 | return TPResult::True; |
969 | |
970 | #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \ |
971 | case tok::Token: |
972 | #define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly) |
973 | #include "clang/Basic/OperatorKinds.def" |
974 | ConsumeToken(); |
975 | return TPResult::True; |
976 | |
977 | case tok::l_square: |
978 | if (NextToken().is(K: tok::r_square)) { |
979 | ConsumeBracket(); |
980 | ConsumeBracket(); |
981 | return TPResult::True; |
982 | } |
983 | break; |
984 | |
985 | case tok::l_paren: |
986 | if (NextToken().is(K: tok::r_paren)) { |
987 | ConsumeParen(); |
988 | ConsumeParen(); |
989 | return TPResult::True; |
990 | } |
991 | break; |
992 | |
993 | default: |
994 | break; |
995 | } |
996 | |
997 | // Maybe this is a literal-operator-id. |
998 | if (getLangOpts().CPlusPlus11 && isTokenStringLiteral()) { |
999 | bool FoundUDSuffix = false; |
1000 | do { |
1001 | FoundUDSuffix |= Tok.hasUDSuffix(); |
1002 | ConsumeStringToken(); |
1003 | } while (isTokenStringLiteral()); |
1004 | |
1005 | if (!FoundUDSuffix) { |
1006 | if (Tok.is(K: tok::identifier)) |
1007 | ConsumeToken(); |
1008 | else |
1009 | return TPResult::Error; |
1010 | } |
1011 | return TPResult::True; |
1012 | } |
1013 | |
1014 | // Maybe this is a conversion-function-id. |
1015 | bool AnyDeclSpecifiers = false; |
1016 | while (true) { |
1017 | TPResult TPR = isCXXDeclarationSpecifier(AllowImplicitTypename: ImplicitTypenameContext::No); |
1018 | if (TPR == TPResult::Error) |
1019 | return TPR; |
1020 | if (TPR == TPResult::False) { |
1021 | if (!AnyDeclSpecifiers) |
1022 | return TPResult::Error; |
1023 | break; |
1024 | } |
1025 | if (TryConsumeDeclarationSpecifier() == TPResult::Error) |
1026 | return TPResult::Error; |
1027 | AnyDeclSpecifiers = true; |
1028 | } |
1029 | return TryParsePtrOperatorSeq(); |
1030 | } |
1031 | |
1032 | /// declarator: |
1033 | /// direct-declarator |
1034 | /// ptr-operator declarator |
1035 | /// |
1036 | /// direct-declarator: |
1037 | /// declarator-id |
1038 | /// direct-declarator '(' parameter-declaration-clause ')' |
1039 | /// cv-qualifier-seq[opt] exception-specification[opt] |
1040 | /// direct-declarator '[' constant-expression[opt] ']' |
1041 | /// '(' declarator ')' |
1042 | /// [GNU] '(' attributes declarator ')' |
1043 | /// |
1044 | /// abstract-declarator: |
1045 | /// ptr-operator abstract-declarator[opt] |
1046 | /// direct-abstract-declarator |
1047 | /// |
1048 | /// direct-abstract-declarator: |
1049 | /// direct-abstract-declarator[opt] |
1050 | /// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] |
1051 | /// exception-specification[opt] |
1052 | /// direct-abstract-declarator[opt] '[' constant-expression[opt] ']' |
1053 | /// '(' abstract-declarator ')' |
1054 | /// [C++0x] ... |
1055 | /// |
1056 | /// ptr-operator: |
1057 | /// '*' cv-qualifier-seq[opt] |
1058 | /// '&' |
1059 | /// [C++0x] '&&' [TODO] |
1060 | /// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] |
1061 | /// |
1062 | /// cv-qualifier-seq: |
1063 | /// cv-qualifier cv-qualifier-seq[opt] |
1064 | /// |
1065 | /// cv-qualifier: |
1066 | /// 'const' |
1067 | /// 'volatile' |
1068 | /// |
1069 | /// declarator-id: |
1070 | /// '...'[opt] id-expression |
1071 | /// |
1072 | /// id-expression: |
1073 | /// unqualified-id |
1074 | /// qualified-id [TODO] |
1075 | /// |
1076 | /// unqualified-id: |
1077 | /// identifier |
1078 | /// operator-function-id |
1079 | /// conversion-function-id |
1080 | /// literal-operator-id |
1081 | /// '~' class-name [TODO] |
1082 | /// '~' decltype-specifier [TODO] |
1083 | /// template-id [TODO] |
1084 | /// |
1085 | Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, |
1086 | bool mayHaveIdentifier, |
1087 | bool mayHaveDirectInit, |
1088 | bool mayHaveTrailingReturnType) { |
1089 | // declarator: |
1090 | // direct-declarator |
1091 | // ptr-operator declarator |
1092 | if (TryParsePtrOperatorSeq() == TPResult::Error) |
1093 | return TPResult::Error; |
1094 | |
1095 | // direct-declarator: |
1096 | // direct-abstract-declarator: |
1097 | if (Tok.is(K: tok::ellipsis)) |
1098 | ConsumeToken(); |
1099 | |
1100 | if ((Tok.isOneOf(K1: tok::identifier, K2: tok::kw_operator) || |
1101 | (Tok.is(K: tok::annot_cxxscope) && (NextToken().is(K: tok::identifier) || |
1102 | NextToken().is(K: tok::kw_operator)))) && |
1103 | mayHaveIdentifier) { |
1104 | // declarator-id |
1105 | if (Tok.is(K: tok::annot_cxxscope)) { |
1106 | CXXScopeSpec SS; |
1107 | Actions.RestoreNestedNameSpecifierAnnotation( |
1108 | Annotation: Tok.getAnnotationValue(), AnnotationRange: Tok.getAnnotationRange(), SS); |
1109 | if (SS.isInvalid()) |
1110 | return TPResult::Error; |
1111 | ConsumeAnnotationToken(); |
1112 | } else if (Tok.is(K: tok::identifier)) { |
1113 | TentativelyDeclaredIdentifiers.push_back(Elt: Tok.getIdentifierInfo()); |
1114 | } |
1115 | if (Tok.is(K: tok::kw_operator)) { |
1116 | if (TryParseOperatorId() == TPResult::Error) |
1117 | return TPResult::Error; |
1118 | } else |
1119 | ConsumeToken(); |
1120 | } else if (Tok.is(K: tok::l_paren)) { |
1121 | ConsumeParen(); |
1122 | if (mayBeAbstract && |
1123 | (Tok.is(K: tok::r_paren) || // 'int()' is a function. |
1124 | // 'int(...)' is a function. |
1125 | (Tok.is(K: tok::ellipsis) && NextToken().is(K: tok::r_paren)) || |
1126 | isDeclarationSpecifier( |
1127 | AllowImplicitTypename: ImplicitTypenameContext::No))) { // 'int(int)' is a function. |
1128 | // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] |
1129 | // exception-specification[opt] |
1130 | TPResult TPR = TryParseFunctionDeclarator(MayHaveTrailingReturnType: mayHaveTrailingReturnType); |
1131 | if (TPR != TPResult::Ambiguous) |
1132 | return TPR; |
1133 | } else { |
1134 | // '(' declarator ')' |
1135 | // '(' attributes declarator ')' |
1136 | // '(' abstract-declarator ')' |
1137 | if (Tok.isOneOf(K1: tok::kw___attribute, Ks: tok::kw___declspec, Ks: tok::kw___cdecl, |
1138 | Ks: tok::kw___stdcall, Ks: tok::kw___fastcall, Ks: tok::kw___thiscall, |
1139 | Ks: tok::kw___regcall, Ks: tok::kw___vectorcall)) |
1140 | return TPResult::True; // attributes indicate declaration |
1141 | TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier); |
1142 | if (TPR != TPResult::Ambiguous) |
1143 | return TPR; |
1144 | if (Tok.isNot(K: tok::r_paren)) |
1145 | return TPResult::False; |
1146 | ConsumeParen(); |
1147 | } |
1148 | } else if (!mayBeAbstract) { |
1149 | return TPResult::False; |
1150 | } |
1151 | |
1152 | if (mayHaveDirectInit) |
1153 | return TPResult::Ambiguous; |
1154 | |
1155 | while (true) { |
1156 | TPResult TPR(TPResult::Ambiguous); |
1157 | |
1158 | if (Tok.is(K: tok::l_paren)) { |
1159 | // Check whether we have a function declarator or a possible ctor-style |
1160 | // initializer that follows the declarator. Note that ctor-style |
1161 | // initializers are not possible in contexts where abstract declarators |
1162 | // are allowed. |
1163 | if (!mayBeAbstract && !isCXXFunctionDeclarator()) |
1164 | break; |
1165 | |
1166 | // direct-declarator '(' parameter-declaration-clause ')' |
1167 | // cv-qualifier-seq[opt] exception-specification[opt] |
1168 | ConsumeParen(); |
1169 | TPR = TryParseFunctionDeclarator(MayHaveTrailingReturnType: mayHaveTrailingReturnType); |
1170 | } else if (Tok.is(K: tok::l_square)) { |
1171 | // direct-declarator '[' constant-expression[opt] ']' |
1172 | // direct-abstract-declarator[opt] '[' constant-expression[opt] ']' |
1173 | TPR = TryParseBracketDeclarator(); |
1174 | } else if (Tok.is(K: tok::kw_requires)) { |
1175 | // declarator requires-clause |
1176 | // A requires clause indicates a function declaration. |
1177 | TPR = TPResult::True; |
1178 | } else { |
1179 | break; |
1180 | } |
1181 | |
1182 | if (TPR != TPResult::Ambiguous) |
1183 | return TPR; |
1184 | } |
1185 | |
1186 | return TPResult::Ambiguous; |
1187 | } |
1188 | |
1189 | bool Parser::isTentativelyDeclared(IdentifierInfo *II) { |
1190 | return llvm::is_contained(Range&: TentativelyDeclaredIdentifiers, Element: II); |
1191 | } |
1192 | |
1193 | namespace { |
1194 | class TentativeParseCCC final : public CorrectionCandidateCallback { |
1195 | public: |
1196 | TentativeParseCCC(const Token &Next) { |
1197 | WantRemainingKeywords = false; |
1198 | WantTypeSpecifiers = |
1199 | Next.isOneOf(K1: tok::l_paren, Ks: tok::r_paren, Ks: tok::greater, Ks: tok::l_brace, |
1200 | Ks: tok::identifier, Ks: tok::comma); |
1201 | } |
1202 | |
1203 | bool ValidateCandidate(const TypoCorrection &Candidate) override { |
1204 | // Reject any candidate that only resolves to instance members since they |
1205 | // aren't viable as standalone identifiers instead of member references. |
1206 | if (Candidate.isResolved() && !Candidate.isKeyword() && |
1207 | llvm::all_of(Range: Candidate, |
1208 | P: [](NamedDecl *ND) { return ND->isCXXInstanceMember(); })) |
1209 | return false; |
1210 | |
1211 | return CorrectionCandidateCallback::ValidateCandidate(candidate: Candidate); |
1212 | } |
1213 | |
1214 | std::unique_ptr<CorrectionCandidateCallback> clone() override { |
1215 | return std::make_unique<TentativeParseCCC>(args&: *this); |
1216 | } |
1217 | }; |
1218 | } |
1219 | /// isCXXDeclarationSpecifier - Returns TPResult::True if it is a declaration |
1220 | /// specifier, TPResult::False if it is not, TPResult::Ambiguous if it could |
1221 | /// be either a decl-specifier or a function-style cast, and TPResult::Error |
1222 | /// if a parsing error was found and reported. |
1223 | /// |
1224 | /// If InvalidAsDeclSpec is not null, some cases that would be ill-formed as |
1225 | /// declaration specifiers but possibly valid as some other kind of construct |
1226 | /// return TPResult::Ambiguous instead of TPResult::False. When this happens, |
1227 | /// the intent is to keep trying to disambiguate, on the basis that we might |
1228 | /// find a better reason to treat this construct as a declaration later on. |
1229 | /// When this happens and the name could possibly be valid in some other |
1230 | /// syntactic context, *InvalidAsDeclSpec is set to 'true'. The current cases |
1231 | /// that trigger this are: |
1232 | /// |
1233 | /// * When parsing X::Y (with no 'typename') where X is dependent |
1234 | /// * When parsing X<Y> where X is undeclared |
1235 | /// |
1236 | /// decl-specifier: |
1237 | /// storage-class-specifier |
1238 | /// type-specifier |
1239 | /// function-specifier |
1240 | /// 'friend' |
1241 | /// 'typedef' |
1242 | /// [C++11] 'constexpr' |
1243 | /// [C++20] 'consteval' |
1244 | /// [GNU] attributes declaration-specifiers[opt] |
1245 | /// |
1246 | /// storage-class-specifier: |
1247 | /// 'register' |
1248 | /// 'static' |
1249 | /// 'extern' |
1250 | /// 'mutable' |
1251 | /// 'auto' |
1252 | /// [GNU] '__thread' |
1253 | /// [C++11] 'thread_local' |
1254 | /// [C11] '_Thread_local' |
1255 | /// |
1256 | /// function-specifier: |
1257 | /// 'inline' |
1258 | /// 'virtual' |
1259 | /// 'explicit' |
1260 | /// |
1261 | /// typedef-name: |
1262 | /// identifier |
1263 | /// |
1264 | /// type-specifier: |
1265 | /// simple-type-specifier |
1266 | /// class-specifier |
1267 | /// enum-specifier |
1268 | /// elaborated-type-specifier |
1269 | /// typename-specifier |
1270 | /// cv-qualifier |
1271 | /// |
1272 | /// simple-type-specifier: |
1273 | /// '::'[opt] nested-name-specifier[opt] type-name |
1274 | /// '::'[opt] nested-name-specifier 'template' |
1275 | /// simple-template-id [TODO] |
1276 | /// 'char' |
1277 | /// 'wchar_t' |
1278 | /// 'bool' |
1279 | /// 'short' |
1280 | /// 'int' |
1281 | /// 'long' |
1282 | /// 'signed' |
1283 | /// 'unsigned' |
1284 | /// 'float' |
1285 | /// 'double' |
1286 | /// 'void' |
1287 | /// [GNU] typeof-specifier |
1288 | /// [GNU] '_Complex' |
1289 | /// [C++11] 'auto' |
1290 | /// [GNU] '__auto_type' |
1291 | /// [C++11] 'decltype' ( expression ) |
1292 | /// [C++1y] 'decltype' ( 'auto' ) |
1293 | /// |
1294 | /// type-name: |
1295 | /// class-name |
1296 | /// enum-name |
1297 | /// typedef-name |
1298 | /// |
1299 | /// elaborated-type-specifier: |
1300 | /// class-key '::'[opt] nested-name-specifier[opt] identifier |
1301 | /// class-key '::'[opt] nested-name-specifier[opt] 'template'[opt] |
1302 | /// simple-template-id |
1303 | /// 'enum' '::'[opt] nested-name-specifier[opt] identifier |
1304 | /// |
1305 | /// enum-name: |
1306 | /// identifier |
1307 | /// |
1308 | /// enum-specifier: |
1309 | /// 'enum' identifier[opt] '{' enumerator-list[opt] '}' |
1310 | /// 'enum' identifier[opt] '{' enumerator-list ',' '}' |
1311 | /// |
1312 | /// class-specifier: |
1313 | /// class-head '{' member-specification[opt] '}' |
1314 | /// |
1315 | /// class-head: |
1316 | /// class-key identifier[opt] base-clause[opt] |
1317 | /// class-key nested-name-specifier identifier base-clause[opt] |
1318 | /// class-key nested-name-specifier[opt] simple-template-id |
1319 | /// base-clause[opt] |
1320 | /// |
1321 | /// class-key: |
1322 | /// 'class' |
1323 | /// 'struct' |
1324 | /// 'union' |
1325 | /// |
1326 | /// cv-qualifier: |
1327 | /// 'const' |
1328 | /// 'volatile' |
1329 | /// [GNU] restrict |
1330 | /// |
1331 | Parser::TPResult |
1332 | Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename, |
1333 | Parser::TPResult BracedCastResult, |
1334 | bool *InvalidAsDeclSpec) { |
1335 | auto IsPlaceholderSpecifier = [&](TemplateIdAnnotation *TemplateId, |
1336 | int Lookahead) { |
1337 | // We have a placeholder-constraint (we check for 'auto' or 'decltype' to |
1338 | // distinguish 'C<int>;' from 'C<int> auto c = 1;') |
1339 | return TemplateId->Kind == TNK_Concept_template && |
1340 | (GetLookAheadToken(N: Lookahead + 1) |
1341 | .isOneOf(K1: tok::kw_auto, Ks: tok::kw_decltype, |
1342 | // If we have an identifier here, the user probably |
1343 | // forgot the 'auto' in the placeholder constraint, |
1344 | // e.g. 'C<int> x = 2;' This will be diagnosed nicely |
1345 | // later, so disambiguate as a declaration. |
1346 | Ks: tok::identifier, |
1347 | // CVR qualifierslikely the same situation for the |
1348 | // user, so let this be diagnosed nicely later. We |
1349 | // cannot handle references here, as `C<int> & Other` |
1350 | // and `C<int> && Other` are both legal. |
1351 | Ks: tok::kw_const, Ks: tok::kw_volatile, Ks: tok::kw_restrict) || |
1352 | // While `C<int> && Other` is legal, doing so while not specifying a |
1353 | // template argument is NOT, so see if we can fix up in that case at |
1354 | // minimum. Concepts require at least 1 template parameter, so we |
1355 | // can count on the argument count. |
1356 | // FIXME: In the future, we migth be able to have SEMA look up the |
1357 | // declaration for this concept, and see how many template |
1358 | // parameters it has. If the concept isn't fully specified, it is |
1359 | // possibly a situation where we want deduction, such as: |
1360 | // `BinaryConcept<int> auto f = bar();` |
1361 | (TemplateId->NumArgs == 0 && |
1362 | GetLookAheadToken(N: Lookahead + 1).isOneOf(K1: tok::amp, K2: tok::ampamp))); |
1363 | }; |
1364 | switch (Tok.getKind()) { |
1365 | case tok::identifier: { |
1366 | if (GetLookAheadToken(N: 1).is(K: tok::ellipsis) && |
1367 | GetLookAheadToken(N: 2).is(K: tok::l_square)) { |
1368 | |
1369 | if (TryAnnotateTypeOrScopeToken()) |
1370 | return TPResult::Error; |
1371 | if (Tok.is(K: tok::identifier)) |
1372 | return TPResult::False; |
1373 | return isCXXDeclarationSpecifier(AllowImplicitTypename: ImplicitTypenameContext::No, |
1374 | BracedCastResult, InvalidAsDeclSpec); |
1375 | } |
1376 | |
1377 | // Check for need to substitute AltiVec __vector keyword |
1378 | // for "vector" identifier. |
1379 | if (TryAltiVecVectorToken()) |
1380 | return TPResult::True; |
1381 | |
1382 | const Token &Next = NextToken(); |
1383 | // In 'foo bar', 'foo' is always a type name outside of Objective-C. |
1384 | if (!getLangOpts().ObjC && Next.is(K: tok::identifier)) |
1385 | return TPResult::True; |
1386 | |
1387 | if (Next.isNot(K: tok::coloncolon) && Next.isNot(K: tok::less)) { |
1388 | // Determine whether this is a valid expression. If not, we will hit |
1389 | // a parse error one way or another. In that case, tell the caller that |
1390 | // this is ambiguous. Typo-correct to type and expression keywords and |
1391 | // to types and identifiers, in order to try to recover from errors. |
1392 | TentativeParseCCC CCC(Next); |
1393 | switch (TryAnnotateName(CCC: &CCC)) { |
1394 | case ANK_Error: |
1395 | return TPResult::Error; |
1396 | case ANK_TentativeDecl: |
1397 | return TPResult::False; |
1398 | case ANK_TemplateName: |
1399 | // In C++17, this could be a type template for class template argument |
1400 | // deduction. Try to form a type annotation for it. If we're in a |
1401 | // template template argument, we'll undo this when checking the |
1402 | // validity of the argument. |
1403 | if (getLangOpts().CPlusPlus17) { |
1404 | if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename)) |
1405 | return TPResult::Error; |
1406 | if (Tok.isNot(K: tok::identifier)) |
1407 | break; |
1408 | } |
1409 | |
1410 | // A bare type template-name which can't be a template template |
1411 | // argument is an error, and was probably intended to be a type. |
1412 | return GreaterThanIsOperator ? TPResult::True : TPResult::False; |
1413 | case ANK_Unresolved: |
1414 | return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False; |
1415 | case ANK_Success: |
1416 | break; |
1417 | } |
1418 | assert(Tok.isNot(tok::identifier) && |
1419 | "TryAnnotateName succeeded without producing an annotation" ); |
1420 | } else { |
1421 | // This might possibly be a type with a dependent scope specifier and |
1422 | // a missing 'typename' keyword. Don't use TryAnnotateName in this case, |
1423 | // since it will annotate as a primary expression, and we want to use the |
1424 | // "missing 'typename'" logic. |
1425 | if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename)) |
1426 | return TPResult::Error; |
1427 | // If annotation failed, assume it's a non-type. |
1428 | // FIXME: If this happens due to an undeclared identifier, treat it as |
1429 | // ambiguous. |
1430 | if (Tok.is(K: tok::identifier)) |
1431 | return TPResult::False; |
1432 | } |
1433 | |
1434 | // We annotated this token as something. Recurse to handle whatever we got. |
1435 | return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult, |
1436 | InvalidAsDeclSpec); |
1437 | } |
1438 | |
1439 | case tok::kw_typename: // typename T::type |
1440 | // Annotate typenames and C++ scope specifiers. If we get one, just |
1441 | // recurse to handle whatever we get. |
1442 | if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename: ImplicitTypenameContext::Yes)) |
1443 | return TPResult::Error; |
1444 | return isCXXDeclarationSpecifier(AllowImplicitTypename: ImplicitTypenameContext::Yes, |
1445 | BracedCastResult, InvalidAsDeclSpec); |
1446 | |
1447 | case tok::kw_auto: { |
1448 | if (!getLangOpts().CPlusPlus23) |
1449 | return TPResult::True; |
1450 | if (NextToken().is(K: tok::l_brace)) |
1451 | return TPResult::False; |
1452 | if (NextToken().is(K: tok::l_paren)) |
1453 | return TPResult::Ambiguous; |
1454 | return TPResult::True; |
1455 | } |
1456 | |
1457 | case tok::coloncolon: { // ::foo::bar |
1458 | const Token &Next = NextToken(); |
1459 | if (Next.isOneOf(K1: tok::kw_new, // ::new |
1460 | K2: tok::kw_delete)) // ::delete |
1461 | return TPResult::False; |
1462 | [[fallthrough]]; |
1463 | } |
1464 | case tok::kw___super: |
1465 | case tok::kw_decltype: |
1466 | // Annotate typenames and C++ scope specifiers. If we get one, just |
1467 | // recurse to handle whatever we get. |
1468 | if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename)) |
1469 | return TPResult::Error; |
1470 | return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult, |
1471 | InvalidAsDeclSpec); |
1472 | |
1473 | // decl-specifier: |
1474 | // storage-class-specifier |
1475 | // type-specifier |
1476 | // function-specifier |
1477 | // 'friend' |
1478 | // 'typedef' |
1479 | // 'constexpr' |
1480 | case tok::kw_friend: |
1481 | case tok::kw_typedef: |
1482 | case tok::kw_constexpr: |
1483 | case tok::kw_consteval: |
1484 | case tok::kw_constinit: |
1485 | // storage-class-specifier |
1486 | case tok::kw_register: |
1487 | case tok::kw_static: |
1488 | case tok::kw_extern: |
1489 | case tok::kw_mutable: |
1490 | case tok::kw___thread: |
1491 | case tok::kw_thread_local: |
1492 | case tok::kw__Thread_local: |
1493 | // function-specifier |
1494 | case tok::kw_inline: |
1495 | case tok::kw_virtual: |
1496 | case tok::kw_explicit: |
1497 | |
1498 | // Modules |
1499 | case tok::kw___module_private__: |
1500 | |
1501 | // Debugger support |
1502 | case tok::kw___unknown_anytype: |
1503 | |
1504 | // type-specifier: |
1505 | // simple-type-specifier |
1506 | // class-specifier |
1507 | // enum-specifier |
1508 | // elaborated-type-specifier |
1509 | // typename-specifier |
1510 | // cv-qualifier |
1511 | |
1512 | // class-specifier |
1513 | // elaborated-type-specifier |
1514 | case tok::kw_class: |
1515 | case tok::kw_struct: |
1516 | case tok::kw_union: |
1517 | case tok::kw___interface: |
1518 | // enum-specifier |
1519 | case tok::kw_enum: |
1520 | // cv-qualifier |
1521 | case tok::kw_const: |
1522 | case tok::kw_volatile: |
1523 | return TPResult::True; |
1524 | |
1525 | // OpenCL address space qualifiers |
1526 | case tok::kw_private: |
1527 | if (!getLangOpts().OpenCL) |
1528 | return TPResult::False; |
1529 | [[fallthrough]]; |
1530 | case tok::kw___private: |
1531 | case tok::kw___local: |
1532 | case tok::kw___global: |
1533 | case tok::kw___constant: |
1534 | case tok::kw___generic: |
1535 | // OpenCL access qualifiers |
1536 | case tok::kw___read_only: |
1537 | case tok::kw___write_only: |
1538 | case tok::kw___read_write: |
1539 | // OpenCL pipe |
1540 | case tok::kw_pipe: |
1541 | |
1542 | // HLSL address space qualifiers |
1543 | case tok::kw_groupshared: |
1544 | case tok::kw_in: |
1545 | case tok::kw_inout: |
1546 | case tok::kw_out: |
1547 | |
1548 | // GNU |
1549 | case tok::kw_restrict: |
1550 | case tok::kw__Complex: |
1551 | case tok::kw___attribute: |
1552 | case tok::kw___auto_type: |
1553 | return TPResult::True; |
1554 | |
1555 | // Microsoft |
1556 | case tok::kw___declspec: |
1557 | case tok::kw___cdecl: |
1558 | case tok::kw___stdcall: |
1559 | case tok::kw___fastcall: |
1560 | case tok::kw___thiscall: |
1561 | case tok::kw___regcall: |
1562 | case tok::kw___vectorcall: |
1563 | case tok::kw___w64: |
1564 | case tok::kw___sptr: |
1565 | case tok::kw___uptr: |
1566 | case tok::kw___ptr64: |
1567 | case tok::kw___ptr32: |
1568 | case tok::kw___forceinline: |
1569 | case tok::kw___unaligned: |
1570 | case tok::kw__Nonnull: |
1571 | case tok::kw__Nullable: |
1572 | case tok::kw__Nullable_result: |
1573 | case tok::kw__Null_unspecified: |
1574 | case tok::kw___kindof: |
1575 | return TPResult::True; |
1576 | |
1577 | // WebAssemblyFuncref |
1578 | case tok::kw___funcref: |
1579 | return TPResult::True; |
1580 | |
1581 | // Borland |
1582 | case tok::kw___pascal: |
1583 | return TPResult::True; |
1584 | |
1585 | // AltiVec |
1586 | case tok::kw___vector: |
1587 | return TPResult::True; |
1588 | |
1589 | case tok::kw_this: { |
1590 | // Try to parse a C++23 Explicit Object Parameter |
1591 | // We do that in all language modes to produce a better diagnostic. |
1592 | if (getLangOpts().CPlusPlus) { |
1593 | RevertingTentativeParsingAction PA(*this); |
1594 | ConsumeToken(); |
1595 | return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult, |
1596 | InvalidAsDeclSpec); |
1597 | } |
1598 | return TPResult::False; |
1599 | } |
1600 | case tok::annot_template_id: { |
1601 | TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(tok: Tok); |
1602 | // If lookup for the template-name found nothing, don't assume we have a |
1603 | // definitive disambiguation result yet. |
1604 | if ((TemplateId->hasInvalidName() || |
1605 | TemplateId->Kind == TNK_Undeclared_template) && |
1606 | InvalidAsDeclSpec) { |
1607 | // 'template-id(' can be a valid expression but not a valid decl spec if |
1608 | // the template-name is not declared, but we don't consider this to be a |
1609 | // definitive disambiguation. In any other context, it's an error either |
1610 | // way. |
1611 | *InvalidAsDeclSpec = NextToken().is(K: tok::l_paren); |
1612 | return TPResult::Ambiguous; |
1613 | } |
1614 | if (TemplateId->hasInvalidName()) |
1615 | return TPResult::Error; |
1616 | if (IsPlaceholderSpecifier(TemplateId, /*Lookahead=*/0)) |
1617 | return TPResult::True; |
1618 | if (TemplateId->Kind != TNK_Type_template) |
1619 | return TPResult::False; |
1620 | CXXScopeSpec SS; |
1621 | AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename); |
1622 | assert(Tok.is(tok::annot_typename)); |
1623 | goto case_typename; |
1624 | } |
1625 | |
1626 | case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed |
1627 | // We've already annotated a scope; try to annotate a type. |
1628 | if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename)) |
1629 | return TPResult::Error; |
1630 | if (!Tok.is(K: tok::annot_typename)) { |
1631 | if (Tok.is(K: tok::annot_cxxscope) && |
1632 | NextToken().is(K: tok::annot_template_id)) { |
1633 | TemplateIdAnnotation *TemplateId = |
1634 | takeTemplateIdAnnotation(tok: NextToken()); |
1635 | if (TemplateId->hasInvalidName()) { |
1636 | if (InvalidAsDeclSpec) { |
1637 | *InvalidAsDeclSpec = NextToken().is(K: tok::l_paren); |
1638 | return TPResult::Ambiguous; |
1639 | } |
1640 | return TPResult::Error; |
1641 | } |
1642 | if (IsPlaceholderSpecifier(TemplateId, /*Lookahead=*/1)) |
1643 | return TPResult::True; |
1644 | } |
1645 | // If the next token is an identifier or a type qualifier, then this |
1646 | // can't possibly be a valid expression either. |
1647 | if (Tok.is(K: tok::annot_cxxscope) && NextToken().is(K: tok::identifier)) { |
1648 | CXXScopeSpec SS; |
1649 | Actions.RestoreNestedNameSpecifierAnnotation(Annotation: Tok.getAnnotationValue(), |
1650 | AnnotationRange: Tok.getAnnotationRange(), |
1651 | SS); |
1652 | if (SS.getScopeRep() && SS.getScopeRep()->isDependent()) { |
1653 | RevertingTentativeParsingAction PA(*this); |
1654 | ConsumeAnnotationToken(); |
1655 | ConsumeToken(); |
1656 | bool isIdentifier = Tok.is(K: tok::identifier); |
1657 | TPResult TPR = TPResult::False; |
1658 | if (!isIdentifier) |
1659 | TPR = isCXXDeclarationSpecifier( |
1660 | AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec); |
1661 | |
1662 | if (isIdentifier || |
1663 | TPR == TPResult::True || TPR == TPResult::Error) |
1664 | return TPResult::Error; |
1665 | |
1666 | if (InvalidAsDeclSpec) { |
1667 | // We can't tell whether this is a missing 'typename' or a valid |
1668 | // expression. |
1669 | *InvalidAsDeclSpec = true; |
1670 | return TPResult::Ambiguous; |
1671 | } else { |
1672 | // In MS mode, if InvalidAsDeclSpec is not provided, and the tokens |
1673 | // are or the form *) or &) *> or &> &&>, this can't be an expression. |
1674 | // The typename must be missing. |
1675 | if (getLangOpts().MSVCCompat) { |
1676 | if (((Tok.is(K: tok::amp) || Tok.is(K: tok::star)) && |
1677 | (NextToken().is(K: tok::r_paren) || |
1678 | NextToken().is(K: tok::greater))) || |
1679 | (Tok.is(K: tok::ampamp) && NextToken().is(K: tok::greater))) |
1680 | return TPResult::True; |
1681 | } |
1682 | } |
1683 | } else { |
1684 | // Try to resolve the name. If it doesn't exist, assume it was |
1685 | // intended to name a type and keep disambiguating. |
1686 | switch (TryAnnotateName(/*CCC=*/nullptr, AllowImplicitTypename)) { |
1687 | case ANK_Error: |
1688 | return TPResult::Error; |
1689 | case ANK_TentativeDecl: |
1690 | return TPResult::False; |
1691 | case ANK_TemplateName: |
1692 | // In C++17, this could be a type template for class template |
1693 | // argument deduction. |
1694 | if (getLangOpts().CPlusPlus17) { |
1695 | if (TryAnnotateTypeOrScopeToken()) |
1696 | return TPResult::Error; |
1697 | // If we annotated then the current token should not still be :: |
1698 | // FIXME we may want to also check for tok::annot_typename but |
1699 | // currently don't have a test case. |
1700 | if (Tok.isNot(K: tok::annot_cxxscope)) |
1701 | break; |
1702 | } |
1703 | |
1704 | // A bare type template-name which can't be a template template |
1705 | // argument is an error, and was probably intended to be a type. |
1706 | // In C++17, this could be class template argument deduction. |
1707 | return (getLangOpts().CPlusPlus17 || GreaterThanIsOperator) |
1708 | ? TPResult::True |
1709 | : TPResult::False; |
1710 | case ANK_Unresolved: |
1711 | return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False; |
1712 | case ANK_Success: |
1713 | break; |
1714 | } |
1715 | |
1716 | // Annotated it, check again. |
1717 | assert(Tok.isNot(tok::annot_cxxscope) || |
1718 | NextToken().isNot(tok::identifier)); |
1719 | return isCXXDeclarationSpecifier(AllowImplicitTypename, |
1720 | BracedCastResult, InvalidAsDeclSpec); |
1721 | } |
1722 | } |
1723 | return TPResult::False; |
1724 | } |
1725 | // If that succeeded, fallthrough into the generic simple-type-id case. |
1726 | [[fallthrough]]; |
1727 | |
1728 | // The ambiguity resides in a simple-type-specifier/typename-specifier |
1729 | // followed by a '('. The '(' could either be the start of: |
1730 | // |
1731 | // direct-declarator: |
1732 | // '(' declarator ')' |
1733 | // |
1734 | // direct-abstract-declarator: |
1735 | // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] |
1736 | // exception-specification[opt] |
1737 | // '(' abstract-declarator ')' |
1738 | // |
1739 | // or part of a function-style cast expression: |
1740 | // |
1741 | // simple-type-specifier '(' expression-list[opt] ')' |
1742 | // |
1743 | |
1744 | // simple-type-specifier: |
1745 | |
1746 | case tok::annot_typename: |
1747 | case_typename: |
1748 | // In Objective-C, we might have a protocol-qualified type. |
1749 | if (getLangOpts().ObjC && NextToken().is(K: tok::less)) { |
1750 | // Tentatively parse the protocol qualifiers. |
1751 | RevertingTentativeParsingAction PA(*this); |
1752 | ConsumeAnyToken(); // The type token |
1753 | |
1754 | TPResult TPR = TryParseProtocolQualifiers(); |
1755 | bool isFollowedByParen = Tok.is(K: tok::l_paren); |
1756 | bool isFollowedByBrace = Tok.is(K: tok::l_brace); |
1757 | |
1758 | if (TPR == TPResult::Error) |
1759 | return TPResult::Error; |
1760 | |
1761 | if (isFollowedByParen) |
1762 | return TPResult::Ambiguous; |
1763 | |
1764 | if (getLangOpts().CPlusPlus11 && isFollowedByBrace) |
1765 | return BracedCastResult; |
1766 | |
1767 | return TPResult::True; |
1768 | } |
1769 | |
1770 | [[fallthrough]]; |
1771 | |
1772 | case tok::kw_char: |
1773 | case tok::kw_wchar_t: |
1774 | case tok::kw_char8_t: |
1775 | case tok::kw_char16_t: |
1776 | case tok::kw_char32_t: |
1777 | case tok::kw_bool: |
1778 | case tok::kw_short: |
1779 | case tok::kw_int: |
1780 | case tok::kw_long: |
1781 | case tok::kw___int64: |
1782 | case tok::kw___int128: |
1783 | case tok::kw_signed: |
1784 | case tok::kw_unsigned: |
1785 | case tok::kw_half: |
1786 | case tok::kw_float: |
1787 | case tok::kw_double: |
1788 | case tok::kw___bf16: |
1789 | case tok::kw__Float16: |
1790 | case tok::kw___float128: |
1791 | case tok::kw___ibm128: |
1792 | case tok::kw_void: |
1793 | case tok::annot_decltype: |
1794 | case tok::kw__Accum: |
1795 | case tok::kw__Fract: |
1796 | case tok::kw__Sat: |
1797 | case tok::annot_pack_indexing_type: |
1798 | #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: |
1799 | #include "clang/Basic/OpenCLImageTypes.def" |
1800 | if (NextToken().is(K: tok::l_paren)) |
1801 | return TPResult::Ambiguous; |
1802 | |
1803 | // This is a function-style cast in all cases we disambiguate other than |
1804 | // one: |
1805 | // struct S { |
1806 | // enum E : int { a = 4 }; // enum |
1807 | // enum E : int { 4 }; // bit-field |
1808 | // }; |
1809 | if (getLangOpts().CPlusPlus11 && NextToken().is(K: tok::l_brace)) |
1810 | return BracedCastResult; |
1811 | |
1812 | if (isStartOfObjCClassMessageMissingOpenBracket()) |
1813 | return TPResult::False; |
1814 | |
1815 | return TPResult::True; |
1816 | |
1817 | // GNU typeof support. |
1818 | case tok::kw_typeof: { |
1819 | if (NextToken().isNot(K: tok::l_paren)) |
1820 | return TPResult::True; |
1821 | |
1822 | RevertingTentativeParsingAction PA(*this); |
1823 | |
1824 | TPResult TPR = TryParseTypeofSpecifier(); |
1825 | bool isFollowedByParen = Tok.is(K: tok::l_paren); |
1826 | bool isFollowedByBrace = Tok.is(K: tok::l_brace); |
1827 | |
1828 | if (TPR == TPResult::Error) |
1829 | return TPResult::Error; |
1830 | |
1831 | if (isFollowedByParen) |
1832 | return TPResult::Ambiguous; |
1833 | |
1834 | if (getLangOpts().CPlusPlus11 && isFollowedByBrace) |
1835 | return BracedCastResult; |
1836 | |
1837 | return TPResult::True; |
1838 | } |
1839 | |
1840 | #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: |
1841 | #include "clang/Basic/TransformTypeTraits.def" |
1842 | return TPResult::True; |
1843 | |
1844 | // C11 _Atomic |
1845 | case tok::kw__Atomic: |
1846 | return TPResult::True; |
1847 | |
1848 | case tok::kw__BitInt: |
1849 | case tok::kw__ExtInt: { |
1850 | if (NextToken().isNot(K: tok::l_paren)) |
1851 | return TPResult::Error; |
1852 | RevertingTentativeParsingAction PA(*this); |
1853 | ConsumeToken(); |
1854 | ConsumeParen(); |
1855 | |
1856 | if (!SkipUntil(T: tok::r_paren, Flags: StopAtSemi)) |
1857 | return TPResult::Error; |
1858 | |
1859 | if (Tok.is(K: tok::l_paren)) |
1860 | return TPResult::Ambiguous; |
1861 | |
1862 | if (getLangOpts().CPlusPlus11 && Tok.is(K: tok::l_brace)) |
1863 | return BracedCastResult; |
1864 | |
1865 | return TPResult::True; |
1866 | } |
1867 | default: |
1868 | return TPResult::False; |
1869 | } |
1870 | } |
1871 | |
1872 | bool Parser::isCXXDeclarationSpecifierAType() { |
1873 | switch (Tok.getKind()) { |
1874 | // typename-specifier |
1875 | case tok::annot_decltype: |
1876 | case tok::annot_pack_indexing_type: |
1877 | case tok::annot_template_id: |
1878 | case tok::annot_typename: |
1879 | case tok::kw_typeof: |
1880 | #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: |
1881 | #include "clang/Basic/TransformTypeTraits.def" |
1882 | return true; |
1883 | |
1884 | // elaborated-type-specifier |
1885 | case tok::kw_class: |
1886 | case tok::kw_struct: |
1887 | case tok::kw_union: |
1888 | case tok::kw___interface: |
1889 | case tok::kw_enum: |
1890 | return true; |
1891 | |
1892 | // simple-type-specifier |
1893 | case tok::kw_char: |
1894 | case tok::kw_wchar_t: |
1895 | case tok::kw_char8_t: |
1896 | case tok::kw_char16_t: |
1897 | case tok::kw_char32_t: |
1898 | case tok::kw_bool: |
1899 | case tok::kw_short: |
1900 | case tok::kw_int: |
1901 | case tok::kw__ExtInt: |
1902 | case tok::kw__BitInt: |
1903 | case tok::kw_long: |
1904 | case tok::kw___int64: |
1905 | case tok::kw___int128: |
1906 | case tok::kw_signed: |
1907 | case tok::kw_unsigned: |
1908 | case tok::kw_half: |
1909 | case tok::kw_float: |
1910 | case tok::kw_double: |
1911 | case tok::kw___bf16: |
1912 | case tok::kw__Float16: |
1913 | case tok::kw___float128: |
1914 | case tok::kw___ibm128: |
1915 | case tok::kw_void: |
1916 | case tok::kw___unknown_anytype: |
1917 | case tok::kw___auto_type: |
1918 | case tok::kw__Accum: |
1919 | case tok::kw__Fract: |
1920 | case tok::kw__Sat: |
1921 | #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: |
1922 | #include "clang/Basic/OpenCLImageTypes.def" |
1923 | return true; |
1924 | |
1925 | case tok::kw_auto: |
1926 | return getLangOpts().CPlusPlus11; |
1927 | |
1928 | case tok::kw__Atomic: |
1929 | // "_Atomic foo" |
1930 | return NextToken().is(K: tok::l_paren); |
1931 | |
1932 | default: |
1933 | return false; |
1934 | } |
1935 | } |
1936 | |
1937 | /// [GNU] typeof-specifier: |
1938 | /// 'typeof' '(' expressions ')' |
1939 | /// 'typeof' '(' type-name ')' |
1940 | /// |
1941 | Parser::TPResult Parser::TryParseTypeofSpecifier() { |
1942 | assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!" ); |
1943 | ConsumeToken(); |
1944 | |
1945 | assert(Tok.is(tok::l_paren) && "Expected '('" ); |
1946 | // Parse through the parens after 'typeof'. |
1947 | ConsumeParen(); |
1948 | if (!SkipUntil(T: tok::r_paren, Flags: StopAtSemi)) |
1949 | return TPResult::Error; |
1950 | |
1951 | return TPResult::Ambiguous; |
1952 | } |
1953 | |
1954 | /// [ObjC] protocol-qualifiers: |
1955 | //// '<' identifier-list '>' |
1956 | Parser::TPResult Parser::TryParseProtocolQualifiers() { |
1957 | assert(Tok.is(tok::less) && "Expected '<' for qualifier list" ); |
1958 | ConsumeToken(); |
1959 | do { |
1960 | if (Tok.isNot(K: tok::identifier)) |
1961 | return TPResult::Error; |
1962 | ConsumeToken(); |
1963 | |
1964 | if (Tok.is(K: tok::comma)) { |
1965 | ConsumeToken(); |
1966 | continue; |
1967 | } |
1968 | |
1969 | if (Tok.is(K: tok::greater)) { |
1970 | ConsumeToken(); |
1971 | return TPResult::Ambiguous; |
1972 | } |
1973 | } while (false); |
1974 | |
1975 | return TPResult::Error; |
1976 | } |
1977 | |
1978 | /// isCXXFunctionDeclarator - Disambiguates between a function declarator or |
1979 | /// a constructor-style initializer, when parsing declaration statements. |
1980 | /// Returns true for function declarator and false for constructor-style |
1981 | /// initializer. |
1982 | /// If during the disambiguation process a parsing error is encountered, |
1983 | /// the function returns true to let the declaration parsing code handle it. |
1984 | /// |
1985 | /// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] |
1986 | /// exception-specification[opt] |
1987 | /// |
1988 | bool Parser::isCXXFunctionDeclarator( |
1989 | bool *IsAmbiguous, ImplicitTypenameContext AllowImplicitTypename) { |
1990 | |
1991 | // C++ 8.2p1: |
1992 | // The ambiguity arising from the similarity between a function-style cast and |
1993 | // a declaration mentioned in 6.8 can also occur in the context of a |
1994 | // declaration. In that context, the choice is between a function declaration |
1995 | // with a redundant set of parentheses around a parameter name and an object |
1996 | // declaration with a function-style cast as the initializer. Just as for the |
1997 | // ambiguities mentioned in 6.8, the resolution is to consider any construct |
1998 | // that could possibly be a declaration a declaration. |
1999 | |
2000 | RevertingTentativeParsingAction PA(*this); |
2001 | |
2002 | ConsumeParen(); |
2003 | bool InvalidAsDeclaration = false; |
2004 | TPResult TPR = TryParseParameterDeclarationClause( |
2005 | InvalidAsDeclaration: &InvalidAsDeclaration, /*VersusTemplateArgument=*/VersusTemplateArg: false, |
2006 | AllowImplicitTypename); |
2007 | if (TPR == TPResult::Ambiguous) { |
2008 | if (Tok.isNot(K: tok::r_paren)) |
2009 | TPR = TPResult::False; |
2010 | else { |
2011 | const Token &Next = NextToken(); |
2012 | if (Next.isOneOf(K1: tok::amp, Ks: tok::ampamp, Ks: tok::kw_const, Ks: tok::kw_volatile, |
2013 | Ks: tok::kw_throw, Ks: tok::kw_noexcept, Ks: tok::l_square, |
2014 | Ks: tok::l_brace, Ks: tok::kw_try, Ks: tok::equal, Ks: tok::arrow) || |
2015 | isCXX11VirtSpecifier(Tok: Next)) |
2016 | // The next token cannot appear after a constructor-style initializer, |
2017 | // and can appear next in a function definition. This must be a function |
2018 | // declarator. |
2019 | TPR = TPResult::True; |
2020 | else if (InvalidAsDeclaration) |
2021 | // Use the absence of 'typename' as a tie-breaker. |
2022 | TPR = TPResult::False; |
2023 | } |
2024 | } |
2025 | |
2026 | if (IsAmbiguous && TPR == TPResult::Ambiguous) |
2027 | *IsAmbiguous = true; |
2028 | |
2029 | // In case of an error, let the declaration parsing code handle it. |
2030 | return TPR != TPResult::False; |
2031 | } |
2032 | |
2033 | /// parameter-declaration-clause: |
2034 | /// parameter-declaration-list[opt] '...'[opt] |
2035 | /// parameter-declaration-list ',' '...' |
2036 | /// |
2037 | /// parameter-declaration-list: |
2038 | /// parameter-declaration |
2039 | /// parameter-declaration-list ',' parameter-declaration |
2040 | /// |
2041 | /// parameter-declaration: |
2042 | /// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt] |
2043 | /// attribute-specifier-seq[opt] decl-specifier-seq declarator attributes[opt] |
2044 | /// '=' assignment-expression |
2045 | /// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt] |
2046 | /// attributes[opt] |
2047 | /// attribute-specifier-seq[opt] decl-specifier-seq abstract-declarator[opt] |
2048 | /// attributes[opt] '=' assignment-expression |
2049 | /// |
2050 | Parser::TPResult Parser::TryParseParameterDeclarationClause( |
2051 | bool *InvalidAsDeclaration, bool VersusTemplateArgument, |
2052 | ImplicitTypenameContext AllowImplicitTypename) { |
2053 | |
2054 | if (Tok.is(K: tok::r_paren)) |
2055 | return TPResult::Ambiguous; |
2056 | |
2057 | // parameter-declaration-list[opt] '...'[opt] |
2058 | // parameter-declaration-list ',' '...' |
2059 | // |
2060 | // parameter-declaration-list: |
2061 | // parameter-declaration |
2062 | // parameter-declaration-list ',' parameter-declaration |
2063 | // |
2064 | while (true) { |
2065 | // '...'[opt] |
2066 | if (Tok.is(K: tok::ellipsis)) { |
2067 | ConsumeToken(); |
2068 | if (Tok.is(K: tok::r_paren)) |
2069 | return TPResult::True; // '...)' is a sign of a function declarator. |
2070 | else |
2071 | return TPResult::False; |
2072 | } |
2073 | |
2074 | // An attribute-specifier-seq here is a sign of a function declarator. |
2075 | if (isCXX11AttributeSpecifier(/*Disambiguate*/false, |
2076 | /*OuterMightBeMessageSend*/true)) |
2077 | return TPResult::True; |
2078 | |
2079 | ParsedAttributes attrs(AttrFactory); |
2080 | MaybeParseMicrosoftAttributes(Attrs&: attrs); |
2081 | |
2082 | // decl-specifier-seq |
2083 | // A parameter-declaration's initializer must be preceded by an '=', so |
2084 | // decl-specifier-seq '{' is not a parameter in C++11. |
2085 | TPResult TPR = isCXXDeclarationSpecifier( |
2086 | AllowImplicitTypename, BracedCastResult: TPResult::False, InvalidAsDeclSpec: InvalidAsDeclaration); |
2087 | // A declaration-specifier (not followed by '(' or '{') means this can't be |
2088 | // an expression, but it could still be a template argument. |
2089 | if (TPR != TPResult::Ambiguous && |
2090 | !(VersusTemplateArgument && TPR == TPResult::True)) |
2091 | return TPR; |
2092 | |
2093 | bool SeenType = false; |
2094 | bool DeclarationSpecifierIsAuto = Tok.is(K: tok::kw_auto); |
2095 | do { |
2096 | SeenType |= isCXXDeclarationSpecifierAType(); |
2097 | if (TryConsumeDeclarationSpecifier() == TPResult::Error) |
2098 | return TPResult::Error; |
2099 | |
2100 | // If we see a parameter name, this can't be a template argument. |
2101 | if (SeenType && Tok.is(K: tok::identifier)) |
2102 | return TPResult::True; |
2103 | |
2104 | TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult: TPResult::False, |
2105 | InvalidAsDeclSpec: InvalidAsDeclaration); |
2106 | if (TPR == TPResult::Error) |
2107 | return TPR; |
2108 | |
2109 | // Two declaration-specifiers means this can't be an expression. |
2110 | if (TPR == TPResult::True && !VersusTemplateArgument) |
2111 | return TPR; |
2112 | } while (TPR != TPResult::False); |
2113 | |
2114 | // declarator |
2115 | // abstract-declarator[opt] |
2116 | TPR = TryParseDeclarator( |
2117 | /*mayBeAbstract=*/true, |
2118 | /*mayHaveIdentifier=*/true, |
2119 | /*mayHaveDirectInit=*/false, |
2120 | /*mayHaveTrailingReturnType=*/DeclarationSpecifierIsAuto); |
2121 | if (TPR != TPResult::Ambiguous) |
2122 | return TPR; |
2123 | |
2124 | // [GNU] attributes[opt] |
2125 | if (Tok.is(K: tok::kw___attribute)) |
2126 | return TPResult::True; |
2127 | |
2128 | // If we're disambiguating a template argument in a default argument in |
2129 | // a class definition versus a parameter declaration, an '=' here |
2130 | // disambiguates the parse one way or the other. |
2131 | // If this is a parameter, it must have a default argument because |
2132 | // (a) the previous parameter did, and |
2133 | // (b) this must be the first declaration of the function, so we can't |
2134 | // inherit any default arguments from elsewhere. |
2135 | // FIXME: If we reach a ')' without consuming any '>'s, then this must |
2136 | // also be a function parameter (that's missing its default argument). |
2137 | if (VersusTemplateArgument) |
2138 | return Tok.is(K: tok::equal) ? TPResult::True : TPResult::False; |
2139 | |
2140 | if (Tok.is(K: tok::equal)) { |
2141 | // '=' assignment-expression |
2142 | // Parse through assignment-expression. |
2143 | if (!SkipUntil(T1: tok::comma, T2: tok::r_paren, Flags: StopAtSemi | StopBeforeMatch)) |
2144 | return TPResult::Error; |
2145 | } |
2146 | |
2147 | if (Tok.is(K: tok::ellipsis)) { |
2148 | ConsumeToken(); |
2149 | if (Tok.is(K: tok::r_paren)) |
2150 | return TPResult::True; // '...)' is a sign of a function declarator. |
2151 | else |
2152 | return TPResult::False; |
2153 | } |
2154 | |
2155 | if (!TryConsumeToken(Expected: tok::comma)) |
2156 | break; |
2157 | } |
2158 | |
2159 | return TPResult::Ambiguous; |
2160 | } |
2161 | |
2162 | /// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue |
2163 | /// parsing as a function declarator. |
2164 | /// If TryParseFunctionDeclarator fully parsed the function declarator, it will |
2165 | /// return TPResult::Ambiguous, otherwise it will return either False() or |
2166 | /// Error(). |
2167 | /// |
2168 | /// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt] |
2169 | /// exception-specification[opt] |
2170 | /// |
2171 | /// exception-specification: |
2172 | /// 'throw' '(' type-id-list[opt] ')' |
2173 | /// |
2174 | Parser::TPResult |
2175 | Parser::TryParseFunctionDeclarator(bool MayHaveTrailingReturnType) { |
2176 | // The '(' is already parsed. |
2177 | |
2178 | TPResult TPR = TryParseParameterDeclarationClause(); |
2179 | if (TPR == TPResult::Ambiguous && Tok.isNot(K: tok::r_paren)) |
2180 | TPR = TPResult::False; |
2181 | |
2182 | if (TPR == TPResult::False || TPR == TPResult::Error) |
2183 | return TPR; |
2184 | |
2185 | // Parse through the parens. |
2186 | if (!SkipUntil(T: tok::r_paren, Flags: StopAtSemi)) |
2187 | return TPResult::Error; |
2188 | |
2189 | // cv-qualifier-seq |
2190 | while (Tok.isOneOf(K1: tok::kw_const, Ks: tok::kw_volatile, Ks: tok::kw___unaligned, |
2191 | Ks: tok::kw_restrict)) |
2192 | ConsumeToken(); |
2193 | |
2194 | // ref-qualifier[opt] |
2195 | if (Tok.isOneOf(K1: tok::amp, K2: tok::ampamp)) |
2196 | ConsumeToken(); |
2197 | |
2198 | // exception-specification |
2199 | if (Tok.is(K: tok::kw_throw)) { |
2200 | ConsumeToken(); |
2201 | if (Tok.isNot(K: tok::l_paren)) |
2202 | return TPResult::Error; |
2203 | |
2204 | // Parse through the parens after 'throw'. |
2205 | ConsumeParen(); |
2206 | if (!SkipUntil(T: tok::r_paren, Flags: StopAtSemi)) |
2207 | return TPResult::Error; |
2208 | } |
2209 | if (Tok.is(K: tok::kw_noexcept)) { |
2210 | ConsumeToken(); |
2211 | // Possibly an expression as well. |
2212 | if (Tok.is(K: tok::l_paren)) { |
2213 | // Find the matching rparen. |
2214 | ConsumeParen(); |
2215 | if (!SkipUntil(T: tok::r_paren, Flags: StopAtSemi)) |
2216 | return TPResult::Error; |
2217 | } |
2218 | } |
2219 | |
2220 | // attribute-specifier-seq |
2221 | if (!TrySkipAttributes()) |
2222 | return TPResult::Ambiguous; |
2223 | |
2224 | // trailing-return-type |
2225 | if (Tok.is(K: tok::arrow) && MayHaveTrailingReturnType) { |
2226 | if (TPR == TPResult::True) |
2227 | return TPR; |
2228 | ConsumeToken(); |
2229 | if (Tok.is(K: tok::identifier) && NameAfterArrowIsNonType()) { |
2230 | return TPResult::False; |
2231 | } |
2232 | if (isCXXTypeId(Context: TentativeCXXTypeIdContext::TypeIdInTrailingReturnType)) |
2233 | return TPResult::True; |
2234 | } |
2235 | |
2236 | return TPResult::Ambiguous; |
2237 | } |
2238 | |
2239 | // When parsing an identifier after an arrow it may be a member expression, |
2240 | // in which case we should not annotate it as an independant expression |
2241 | // so we just lookup that name, if it's not a type the construct is not |
2242 | // a function declaration. |
2243 | bool Parser::NameAfterArrowIsNonType() { |
2244 | assert(Tok.is(tok::identifier)); |
2245 | Token Next = NextToken(); |
2246 | if (Next.is(K: tok::coloncolon)) |
2247 | return false; |
2248 | IdentifierInfo *Name = Tok.getIdentifierInfo(); |
2249 | SourceLocation NameLoc = Tok.getLocation(); |
2250 | CXXScopeSpec SS; |
2251 | TentativeParseCCC CCC(Next); |
2252 | Sema::NameClassification Classification = |
2253 | Actions.ClassifyName(S: getCurScope(), SS, Name, NameLoc, NextToken: Next, CCC: &CCC); |
2254 | switch (Classification.getKind()) { |
2255 | case Sema::NC_OverloadSet: |
2256 | case Sema::NC_NonType: |
2257 | case Sema::NC_VarTemplate: |
2258 | case Sema::NC_FunctionTemplate: |
2259 | return true; |
2260 | default: |
2261 | break; |
2262 | } |
2263 | return false; |
2264 | } |
2265 | |
2266 | /// '[' constant-expression[opt] ']' |
2267 | /// |
2268 | Parser::TPResult Parser::TryParseBracketDeclarator() { |
2269 | ConsumeBracket(); |
2270 | |
2271 | // A constant-expression cannot begin with a '{', but the |
2272 | // expr-or-braced-init-list of a postfix-expression can. |
2273 | if (Tok.is(K: tok::l_brace)) |
2274 | return TPResult::False; |
2275 | |
2276 | if (!SkipUntil(T1: tok::r_square, T2: tok::comma, Flags: StopAtSemi | StopBeforeMatch)) |
2277 | return TPResult::Error; |
2278 | |
2279 | // If we hit a comma before the ']', this is not a constant-expression, |
2280 | // but might still be the expr-or-braced-init-list of a postfix-expression. |
2281 | if (Tok.isNot(K: tok::r_square)) |
2282 | return TPResult::False; |
2283 | |
2284 | ConsumeBracket(); |
2285 | return TPResult::Ambiguous; |
2286 | } |
2287 | |
2288 | /// Determine whether we might be looking at the '<' template-argument-list '>' |
2289 | /// of a template-id or simple-template-id, rather than a less-than comparison. |
2290 | /// This will often fail and produce an ambiguity, but should never be wrong |
2291 | /// if it returns True or False. |
2292 | Parser::TPResult Parser::isTemplateArgumentList(unsigned TokensToSkip) { |
2293 | if (!TokensToSkip) { |
2294 | if (Tok.isNot(K: tok::less)) |
2295 | return TPResult::False; |
2296 | if (NextToken().is(K: tok::greater)) |
2297 | return TPResult::True; |
2298 | } |
2299 | |
2300 | RevertingTentativeParsingAction PA(*this); |
2301 | |
2302 | while (TokensToSkip) { |
2303 | ConsumeAnyToken(); |
2304 | --TokensToSkip; |
2305 | } |
2306 | |
2307 | if (!TryConsumeToken(Expected: tok::less)) |
2308 | return TPResult::False; |
2309 | |
2310 | // We can't do much to tell an expression apart from a template-argument, |
2311 | // but one good distinguishing factor is that a "decl-specifier" not |
2312 | // followed by '(' or '{' can't appear in an expression. |
2313 | bool InvalidAsTemplateArgumentList = false; |
2314 | if (isCXXDeclarationSpecifier(AllowImplicitTypename: ImplicitTypenameContext::No, BracedCastResult: TPResult::False, |
2315 | InvalidAsDeclSpec: &InvalidAsTemplateArgumentList) == |
2316 | TPResult::True) |
2317 | return TPResult::True; |
2318 | if (InvalidAsTemplateArgumentList) |
2319 | return TPResult::False; |
2320 | |
2321 | // FIXME: In many contexts, X<thing1, Type> can only be a |
2322 | // template-argument-list. But that's not true in general: |
2323 | // |
2324 | // using b = int; |
2325 | // void f() { |
2326 | // int a = A<B, b, c = C>D; // OK, declares b, not a template-id. |
2327 | // |
2328 | // X<Y<0, int> // ', int>' might be end of X's template argument list |
2329 | // |
2330 | // We might be able to disambiguate a few more cases if we're careful. |
2331 | |
2332 | // A template-argument-list must be terminated by a '>'. |
2333 | if (SkipUntil(Toks: {tok::greater, tok::greatergreater, tok::greatergreatergreater}, |
2334 | Flags: StopAtSemi | StopBeforeMatch)) |
2335 | return TPResult::Ambiguous; |
2336 | return TPResult::False; |
2337 | } |
2338 | |
2339 | /// Determine whether we might be looking at the '(' of a C++20 explicit(bool) |
2340 | /// in an earlier language mode. |
2341 | Parser::TPResult Parser::isExplicitBool() { |
2342 | assert(Tok.is(tok::l_paren) && "expected to be looking at a '(' token" ); |
2343 | |
2344 | RevertingTentativeParsingAction PA(*this); |
2345 | ConsumeParen(); |
2346 | |
2347 | // We can only have 'explicit' on a constructor, conversion function, or |
2348 | // deduction guide. The declarator of a deduction guide cannot be |
2349 | // parenthesized, so we know this isn't a deduction guide. So the only |
2350 | // thing we need to check for is some number of parens followed by either |
2351 | // the current class name or 'operator'. |
2352 | while (Tok.is(K: tok::l_paren)) |
2353 | ConsumeParen(); |
2354 | |
2355 | if (TryAnnotateOptionalCXXScopeToken()) |
2356 | return TPResult::Error; |
2357 | |
2358 | // Class-scope constructor and conversion function names can't really be |
2359 | // qualified, but we get better diagnostics if we assume they can be. |
2360 | CXXScopeSpec SS; |
2361 | if (Tok.is(K: tok::annot_cxxscope)) { |
2362 | Actions.RestoreNestedNameSpecifierAnnotation(Annotation: Tok.getAnnotationValue(), |
2363 | AnnotationRange: Tok.getAnnotationRange(), |
2364 | SS); |
2365 | ConsumeAnnotationToken(); |
2366 | } |
2367 | |
2368 | // 'explicit(operator' might be explicit(bool) or the declaration of a |
2369 | // conversion function, but it's probably a conversion function. |
2370 | if (Tok.is(K: tok::kw_operator)) |
2371 | return TPResult::Ambiguous; |
2372 | |
2373 | // If this can't be a constructor name, it can only be explicit(bool). |
2374 | if (Tok.isNot(K: tok::identifier) && Tok.isNot(K: tok::annot_template_id)) |
2375 | return TPResult::True; |
2376 | if (!Actions.isCurrentClassName(II: Tok.is(K: tok::identifier) |
2377 | ? *Tok.getIdentifierInfo() |
2378 | : *takeTemplateIdAnnotation(tok: Tok)->Name, |
2379 | S: getCurScope(), SS: &SS)) |
2380 | return TPResult::True; |
2381 | // Formally, we must have a right-paren after the constructor name to match |
2382 | // the grammar for a constructor. But clang permits a parenthesized |
2383 | // constructor declarator, so also allow a constructor declarator to follow |
2384 | // with no ')' token after the constructor name. |
2385 | if (!NextToken().is(K: tok::r_paren) && |
2386 | !isConstructorDeclarator(/*Unqualified=*/SS.isEmpty(), |
2387 | /*DeductionGuide=*/false)) |
2388 | return TPResult::True; |
2389 | |
2390 | // Might be explicit(bool) or a parenthesized constructor name. |
2391 | return TPResult::Ambiguous; |
2392 | } |
2393 | |