1//===--- ParseCXXInlineMethods.cpp - C++ class inline methods 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 parsing for C++ class inline methods.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/DeclTemplate.h"
14#include "clang/Basic/DiagnosticParse.h"
15#include "clang/Parse/Parser.h"
16#include "clang/Parse/RAIIObjectsForParser.h"
17#include "clang/Sema/DeclSpec.h"
18#include "clang/Sema/EnterExpressionEvaluationContext.h"
19#include "clang/Sema/Scope.h"
20#include "llvm/ADT/ScopeExit.h"
21
22using namespace clang;
23
24StringLiteral *Parser::ParseCXXDeletedFunctionMessage() {
25 if (!Tok.is(K: tok::l_paren))
26 return nullptr;
27 StringLiteral *Message = nullptr;
28 BalancedDelimiterTracker BT{*this, tok::l_paren};
29 BT.consumeOpen();
30
31 if (isTokenStringLiteral()) {
32 ExprResult Res = ParseUnevaluatedStringLiteralExpression();
33 if (Res.isUsable()) {
34 Message = Res.getAs<StringLiteral>();
35 DiagCompat(Loc: Message->getBeginLoc(), CompatDiagId: diag_compat::delete_with_message)
36 << Message->getSourceRange();
37 }
38 } else {
39 Diag(Loc: Tok.getLocation(), DiagID: diag::err_expected_string_literal)
40 << /*Source='in'*/ 0 << "'delete'";
41 SkipUntil(T: tok::r_paren, Flags: StopAtSemi | StopBeforeMatch);
42 }
43
44 BT.consumeClose();
45 return Message;
46}
47
48void Parser::SkipDeletedFunctionBody() {
49 if (!Tok.is(K: tok::l_paren))
50 return;
51
52 BalancedDelimiterTracker BT{*this, tok::l_paren};
53 BT.consumeOpen();
54
55 // Just skip to the end of the current declaration.
56 SkipUntil(T1: tok::r_paren, T2: tok::comma, Flags: StopAtSemi | StopBeforeMatch);
57 if (Tok.is(K: tok::r_paren))
58 BT.consumeClose();
59}
60
61NamedDecl *Parser::ParseCXXInlineMethodDef(
62 AccessSpecifier AS, const ParsedAttributesView &AccessAttrs,
63 ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo,
64 const VirtSpecifiers &VS, SourceLocation PureSpecLoc) {
65 assert(D.isFunctionDeclarator() && "This isn't a function declarator!");
66 assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try, tok::equal) &&
67 "Current token not a '{', ':', '=', or 'try'!");
68
69 MultiTemplateParamsArg TemplateParams(
70 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data()
71 : nullptr,
72 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
73
74 NamedDecl *FnD;
75 if (D.getDeclSpec().isFriendSpecified())
76 FnD = Actions.ActOnFriendFunctionDecl(S: getCurScope(), D,
77 TemplateParams);
78 else {
79 FnD = Actions.ActOnCXXMemberDeclarator(S: getCurScope(), AS, D,
80 TemplateParameterLists: TemplateParams, BitfieldWidth: nullptr,
81 VS, InitStyle: ICIS_NoInit);
82 if (FnD) {
83 Actions.ProcessDeclAttributeList(S: getCurScope(), D: FnD, AttrList: AccessAttrs);
84 if (PureSpecLoc.isValid())
85 Actions.ActOnPureSpecifier(D: FnD, PureSpecLoc);
86 }
87 }
88
89 if (FnD)
90 HandleMemberFunctionDeclDelays(DeclaratorInfo&: D, ThisDecl: FnD);
91
92 D.complete(D: FnD);
93
94 if (TryConsumeToken(Expected: tok::equal)) {
95 if (!FnD) {
96 SkipUntil(T: tok::semi);
97 return nullptr;
98 }
99
100 bool Delete = false;
101 SourceLocation KWLoc;
102 if (TryConsumeToken(Expected: tok::kw_delete, Loc&: KWLoc)) {
103 DiagCompat(Loc: KWLoc, CompatDiagId: diag_compat::defaulted_deleted_function)
104 << 1 /* deleted */;
105 StringLiteral *Message = ParseCXXDeletedFunctionMessage();
106 Actions.SetDeclDeleted(dcl: FnD, DelLoc: KWLoc, Message);
107 Delete = true;
108 if (auto *DeclAsFunction = dyn_cast<FunctionDecl>(Val: FnD)) {
109 DeclAsFunction->setRangeEnd(PrevTokLocation);
110 }
111 } else if (TryConsumeToken(Expected: tok::kw_default, Loc&: KWLoc)) {
112 DiagCompat(Loc: KWLoc, CompatDiagId: diag_compat::defaulted_deleted_function)
113 << 0 /* defaulted */;
114 Actions.SetDeclDefaulted(dcl: FnD, DefaultLoc: KWLoc);
115 if (auto *DeclAsFunction = dyn_cast<FunctionDecl>(Val: FnD)) {
116 DeclAsFunction->setRangeEnd(PrevTokLocation);
117 }
118 } else {
119 llvm_unreachable("function definition after = not 'delete' or 'default'");
120 }
121
122 if (Tok.is(K: tok::comma)) {
123 Diag(Loc: KWLoc, DiagID: diag::err_default_delete_in_multiple_declaration)
124 << Delete;
125 SkipUntil(T: tok::semi);
126 } else if (ExpectAndConsume(ExpectedTok: tok::semi, Diag: diag::err_expected_after,
127 DiagMsg: Delete ? "delete" : "default") &&
128 !isLikelyAtStartOfNewDeclaration()) {
129 SkipUntil(T: tok::semi);
130 }
131
132 return FnD;
133 }
134
135 if (SkipFunctionBodies && (!FnD || Actions.canSkipFunctionBody(D: FnD)) &&
136 trySkippingFunctionBody()) {
137 Actions.ActOnSkippedFunctionBody(Decl: FnD);
138 return FnD;
139 }
140
141 // In delayed template parsing mode, if we are within a class template
142 // or if we are about to parse function member template then consume
143 // the tokens and store them for parsing at the end of the translation unit.
144 if (getLangOpts().DelayedTemplateParsing &&
145 D.getFunctionDefinitionKind() == FunctionDefinitionKind::Definition &&
146 !D.getDeclSpec().hasConstexprSpecifier() &&
147 !(FnD && FnD->getAsFunction() &&
148 FnD->getAsFunction()->getReturnType()->getContainedAutoType()) &&
149 ((Actions.CurContext->isDependentContext() ||
150 (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate &&
151 TemplateInfo.Kind != ParsedTemplateKind::ExplicitSpecialization)) &&
152 !Actions.IsInsideALocalClassWithinATemplateFunction())) {
153
154 CachedTokens Toks;
155 LexTemplateFunctionForLateParsing(Toks);
156
157 if (FnD) {
158 FunctionDecl *FD = FnD->getAsFunction();
159 Actions.CheckForFunctionRedefinition(FD);
160 Actions.MarkAsLateParsedTemplate(FD, FnD, Toks);
161 }
162
163 return FnD;
164 }
165
166 // Consume the tokens and store them for later parsing.
167
168 LexedMethod* LM = new LexedMethod(this, FnD);
169 getCurrentClass().LateParsedDeclarations.push_back(Elt: LM);
170 CachedTokens &Toks = LM->Toks;
171
172 tok::TokenKind kind = Tok.getKind();
173 // Consume everything up to (and including) the left brace of the
174 // function body.
175 if (ConsumeAndStoreFunctionPrologue(Toks)) {
176 // We didn't find the left-brace we expected after the
177 // constructor initializer.
178
179 // If we're code-completing and the completion point was in the broken
180 // initializer, we want to parse it even though that will fail.
181 if (PP.isCodeCompletionEnabled() &&
182 llvm::any_of(Range&: Toks, P: [](const Token &Tok) {
183 return Tok.is(K: tok::code_completion);
184 })) {
185 // If we gave up at the completion point, the initializer list was
186 // likely truncated, so don't eat more tokens. We'll hit some extra
187 // errors, but they should be ignored in code completion.
188 return FnD;
189 }
190
191 // We already printed an error, and it's likely impossible to recover,
192 // so don't try to parse this method later.
193 // Skip over the rest of the decl and back to somewhere that looks
194 // reasonable.
195 SkipMalformedDecl();
196 delete getCurrentClass().LateParsedDeclarations.back();
197 getCurrentClass().LateParsedDeclarations.pop_back();
198 return FnD;
199 } else {
200 // Consume everything up to (and including) the matching right brace.
201 ConsumeAndStoreUntil(T1: tok::r_brace, Toks, /*StopAtSemi=*/false);
202 }
203
204 // If we're in a function-try-block, we need to store all the catch blocks.
205 if (kind == tok::kw_try) {
206 while (Tok.is(K: tok::kw_catch)) {
207 ConsumeAndStoreUntil(T1: tok::l_brace, Toks, /*StopAtSemi=*/false);
208 ConsumeAndStoreUntil(T1: tok::r_brace, Toks, /*StopAtSemi=*/false);
209 }
210 }
211
212 if (FnD) {
213 FunctionDecl *FD = FnD->getAsFunction();
214 // Track that this function will eventually have a body; Sema needs
215 // to know this.
216 Actions.CheckForFunctionRedefinition(FD);
217 FD->setWillHaveBody(true);
218 } else {
219 // If semantic analysis could not build a function declaration,
220 // just throw away the late-parsed declaration.
221 delete getCurrentClass().LateParsedDeclarations.back();
222 getCurrentClass().LateParsedDeclarations.pop_back();
223 }
224
225 return FnD;
226}
227
228void Parser::ParseCXXNonStaticMemberInitializer(Decl *VarD) {
229 assert(Tok.isOneOf(tok::l_brace, tok::equal) &&
230 "Current token not a '{' or '='!");
231
232 LateParsedMemberInitializer *MI =
233 new LateParsedMemberInitializer(this, VarD);
234 getCurrentClass().LateParsedDeclarations.push_back(Elt: MI);
235 CachedTokens &Toks = MI->Toks;
236
237 tok::TokenKind kind = Tok.getKind();
238 if (kind == tok::equal) {
239 Toks.push_back(Elt: Tok);
240 ConsumeToken();
241 }
242
243 if (kind == tok::l_brace) {
244 // Begin by storing the '{' token.
245 Toks.push_back(Elt: Tok);
246 ConsumeBrace();
247
248 // Consume everything up to (and including) the matching right brace.
249 ConsumeAndStoreUntil(T1: tok::r_brace, Toks, /*StopAtSemi=*/true);
250 } else {
251 // Consume everything up to (but excluding) the comma or semicolon.
252 ConsumeAndStoreInitializer(Toks, CIK: CachedInitKind::DefaultInitializer);
253 }
254
255 // Store an artificial EOF token to ensure that we don't run off the end of
256 // the initializer when we come to parse it.
257 Token Eof = Token::createEof(Loc: Tok.getLocation(), Data: VarD);
258 Toks.push_back(Elt: Eof);
259}
260
261LateParsedDeclaration::~LateParsedDeclaration() {}
262void LateParsedDeclaration::ParseLexedMethodDeclarations() {}
263void LateParsedDeclaration::ParseLexedMemberInitializers() {}
264void LateParsedDeclaration::ParseLexedMethodDefs() {}
265void LateParsedDeclaration::ParseLexedAttributes() {}
266void LateParsedDeclaration::ParseLexedPragmas() {}
267
268Parser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C)
269 : Self(P), Class(C) {}
270
271Parser::LateParsedClass::~LateParsedClass() {
272 Self->DeallocateParsedClasses(Class);
273}
274
275void Parser::LateParsedClass::ParseLexedMethodDeclarations() {
276 Self->ParseLexedMethodDeclarations(Class&: *Class);
277}
278
279void Parser::LateParsedClass::ParseLexedMemberInitializers() {
280 Self->ParseLexedMemberInitializers(Class&: *Class);
281}
282
283void Parser::LateParsedClass::ParseLexedMethodDefs() {
284 Self->ParseLexedMethodDefs(Class&: *Class);
285}
286
287void Parser::LateParsedClass::ParseLexedAttributes() {
288 Self->ParseLexedAttributes(Class&: *Class);
289}
290
291void Parser::LateParsedClass::ParseLexedPragmas() {
292 Self->ParseLexedPragmas(Class&: *Class);
293}
294
295void Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() {
296 Self->ParseLexedMethodDeclaration(LM&: *this);
297}
298
299void Parser::LexedMethod::ParseLexedMethodDefs() {
300 Self->ParseLexedMethodDef(LM&: *this);
301}
302
303void Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() {
304 Self->ParseLexedMemberInitializer(MI&: *this);
305}
306
307void LateParsedAttribute::ParseLexedAttributes() {
308 Self->ParseLexedAttribute(LPA&: *this, EnterScope: true, OnDefinition: false);
309}
310
311void LateParsedTypeAttribute::ParseLexedAttributes() {}
312
313void Parser::LateParsedPragma::ParseLexedPragmas() {
314 Self->ParseLexedPragma(LP&: *this);
315}
316
317struct Parser::ReenterTemplateScopeRAII {
318 Parser &P;
319 MultiParseScope Scopes;
320 TemplateParameterDepthRAII CurTemplateDepthTracker;
321
322 ReenterTemplateScopeRAII(Parser &P, Decl *MaybeTemplated, bool Enter = true)
323 : P(P), Scopes(P), CurTemplateDepthTracker(P.TemplateParameterDepth) {
324 if (Enter) {
325 CurTemplateDepthTracker.addDepth(
326 D: P.ReenterTemplateScopes(S&: Scopes, D: MaybeTemplated));
327 }
328 }
329};
330
331struct Parser::ReenterClassScopeRAII : ReenterTemplateScopeRAII {
332 ParsingClass &Class;
333
334 ReenterClassScopeRAII(Parser &P, ParsingClass &Class)
335 : ReenterTemplateScopeRAII(P, Class.TagOrTemplate,
336 /*Enter=*/!Class.TopLevelClass),
337 Class(Class) {
338 // If this is the top-level class, we're still within its scope.
339 if (Class.TopLevelClass)
340 return;
341
342 // Re-enter the class scope itself.
343 Scopes.Enter(ScopeFlags: Scope::ClassScope|Scope::DeclScope);
344 P.Actions.ActOnStartDelayedMemberDeclarations(S: P.getCurScope(),
345 Record: Class.TagOrTemplate);
346 }
347 ~ReenterClassScopeRAII() {
348 if (Class.TopLevelClass)
349 return;
350
351 P.Actions.ActOnFinishDelayedMemberDeclarations(S: P.getCurScope(),
352 Record: Class.TagOrTemplate);
353 }
354};
355
356void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) {
357 ReenterClassScopeRAII InClassScope(*this, Class);
358
359 for (LateParsedDeclaration *LateD : Class.LateParsedDeclarations)
360 LateD->ParseLexedMethodDeclarations();
361}
362
363void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
364 // If this is a member template, introduce the template parameter scope.
365 ReenterTemplateScopeRAII InFunctionTemplateScope(*this, LM.Method);
366
367 // Start the delayed C++ method declaration
368 Actions.ActOnStartDelayedCXXMethodDeclaration(S: getCurScope(), Method: LM.Method);
369
370 // Introduce the parameters into scope and parse their default
371 // arguments.
372 InFunctionTemplateScope.Scopes.Enter(ScopeFlags: Scope::FunctionPrototypeScope |
373 Scope::FunctionDeclarationScope |
374 Scope::DeclScope);
375
376 // Delayed default arguments or exception specifications may contain lambdas,
377 // struct S {
378 // void ICE(int x, int = sizeof([x] { return x; }()));
379 // }
380 //
381 // struct X {
382 // void ICE(int val) noexcept(noexcept([val]{}));
383 // };
384 // Lambda capture handling in tryCaptureVariable() expects an enclosing
385 // function scope in Sema's FunctionScopes stack.
386 Sema::FunctionScopeRAII PopFnContext(Actions);
387 Actions.PushFunctionScope();
388
389 for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) {
390 auto Param = cast<ParmVarDecl>(Val: LM.DefaultArgs[I].Param);
391 // Introduce the parameter into scope.
392 bool HasUnparsed = Param->hasUnparsedDefaultArg();
393 Actions.ActOnDelayedCXXMethodParameter(S: getCurScope(), Param);
394 std::unique_ptr<CachedTokens> Toks = std::move(LM.DefaultArgs[I].Toks);
395 if (Toks) {
396 ParenBraceBracketBalancer BalancerRAIIObj(*this);
397
398 // Mark the end of the default argument so that we know when to stop when
399 // we parse it later on.
400 Token LastDefaultArgToken = Toks->back();
401 Token DefArgEnd =
402 Token::createEof(Loc: LastDefaultArgToken.getEndLoc(), Data: Param);
403 Toks->push_back(Elt: DefArgEnd);
404
405 // Parse the default argument from its saved token stream.
406 Toks->push_back(Elt: Tok); // So that the current token doesn't get lost
407 PP.EnterTokenStream(Toks: *Toks, DisableMacroExpansion: true, /*IsReinject*/ true);
408
409 // Consume the previously-pushed token.
410 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
411
412 // Consume the '='.
413 assert(Tok.is(tok::equal) && "Default argument not starting with '='");
414 SourceLocation EqualLoc = ConsumeToken();
415
416 // The argument isn't actually potentially evaluated unless it is
417 // used.
418 EnterExpressionEvaluationContext Eval(
419 Actions,
420 Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed, Param);
421
422 ExprResult DefArgResult;
423 if (getLangOpts().CPlusPlus11 && Tok.is(K: tok::l_brace)) {
424 Diag(Tok, DiagID: diag::compat_cxx11_generalized_initializer_lists);
425 DefArgResult = ParseBraceInitializer();
426 } else
427 DefArgResult = ParseAssignmentExpression();
428 if (DefArgResult.isInvalid()) {
429 Actions.ActOnParamDefaultArgumentError(param: Param, EqualLoc,
430 /*DefaultArg=*/nullptr);
431 } else {
432 if (Tok.isNot(K: tok::eof) || Tok.getEofData() != Param) {
433 // The last two tokens are the terminator and the saved value of
434 // Tok; the last token in the default argument is the one before
435 // those.
436 assert(Toks->size() >= 3 && "expected a token in default arg");
437 Diag(Loc: Tok.getLocation(), DiagID: diag::err_default_arg_unparsed)
438 << SourceRange(Tok.getLocation(),
439 (*Toks)[Toks->size() - 3].getLocation());
440 }
441 Actions.ActOnParamDefaultArgument(param: Param, EqualLoc,
442 defarg: DefArgResult.get());
443 }
444
445 // There could be leftover tokens (e.g. because of an error).
446 // Skip through until we reach the 'end of default argument' token.
447 while (Tok.isNot(K: tok::eof))
448 ConsumeAnyToken();
449
450 if (Tok.is(K: tok::eof) && Tok.getEofData() == Param)
451 ConsumeAnyToken();
452 } else if (HasUnparsed) {
453 assert(Param->hasInheritedDefaultArg());
454 FunctionDecl *Old;
455 if (const auto *FunTmpl = dyn_cast<FunctionTemplateDecl>(Val: LM.Method))
456 Old =
457 cast<FunctionDecl>(Val: FunTmpl->getTemplatedDecl())->getPreviousDecl();
458 else
459 Old = cast<FunctionDecl>(Val: LM.Method)->getPreviousDecl();
460 if (Old) {
461 ParmVarDecl *OldParam = Old->getParamDecl(i: I);
462 assert(!OldParam->hasUnparsedDefaultArg());
463 if (OldParam->hasUninstantiatedDefaultArg())
464 Param->setUninstantiatedDefaultArg(
465 OldParam->getUninstantiatedDefaultArg());
466 else
467 Param->setDefaultArg(OldParam->getInit());
468 }
469 }
470 }
471
472 // Parse a delayed exception-specification, if there is one.
473 if (CachedTokens *Toks = LM.ExceptionSpecTokens) {
474 ParenBraceBracketBalancer BalancerRAIIObj(*this);
475
476 // Add the 'stop' token.
477 Token LastExceptionSpecToken = Toks->back();
478 Token ExceptionSpecEnd =
479 Token::createEof(Loc: LastExceptionSpecToken.getEndLoc(), Data: LM.Method);
480 Toks->push_back(Elt: ExceptionSpecEnd);
481
482 // Parse the default argument from its saved token stream.
483 Toks->push_back(Elt: Tok); // So that the current token doesn't get lost
484 PP.EnterTokenStream(Toks: *Toks, DisableMacroExpansion: true, /*IsReinject*/true);
485
486 // Consume the previously-pushed token.
487 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
488
489 // C++11 [expr.prim.general]p3:
490 // If a declaration declares a member function or member function
491 // template of a class X, the expression this is a prvalue of type
492 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
493 // and the end of the function-definition, member-declarator, or
494 // declarator.
495 CXXMethodDecl *Method;
496 FunctionDecl *FunctionToPush;
497 if (FunctionTemplateDecl *FunTmpl
498 = dyn_cast<FunctionTemplateDecl>(Val: LM.Method))
499 FunctionToPush = FunTmpl->getTemplatedDecl();
500 else
501 FunctionToPush = cast<FunctionDecl>(Val: LM.Method);
502 Method = dyn_cast<CXXMethodDecl>(Val: FunctionToPush);
503
504 // Setup the CurScope to match the function DeclContext - we have such
505 // assumption in IsInFnTryBlockHandler().
506 ParseScope FnScope(this, Scope::FnScope);
507 Sema::ContextRAII FnContext(Actions, FunctionToPush,
508 /*NewThisContext=*/false);
509
510 Sema::CXXThisScopeRAII ThisScope(
511 Actions, Method ? Method->getParent() : nullptr,
512 Method ? Method->getMethodQualifiers() : Qualifiers{},
513 Method && getLangOpts().CPlusPlus11);
514
515 // Parse the exception-specification.
516 SourceRange SpecificationRange;
517 SmallVector<ParsedType, 4> DynamicExceptions;
518 SmallVector<SourceRange, 4> DynamicExceptionRanges;
519 ExprResult NoexceptExpr;
520 CachedTokens *ExceptionSpecTokens;
521
522 ExceptionSpecificationType EST
523 = tryParseExceptionSpecification(/*Delayed=*/false, SpecificationRange,
524 DynamicExceptions,
525 DynamicExceptionRanges, NoexceptExpr,
526 ExceptionSpecTokens);
527
528 if (Tok.isNot(K: tok::eof) || Tok.getEofData() != LM.Method)
529 Diag(Loc: Tok.getLocation(), DiagID: diag::err_except_spec_unparsed);
530
531 // Attach the exception-specification to the method.
532 Actions.actOnDelayedExceptionSpecification(D: LM.Method, EST,
533 SpecificationRange,
534 DynamicExceptions,
535 DynamicExceptionRanges,
536 NoexceptExpr: NoexceptExpr.isUsable()?
537 NoexceptExpr.get() : nullptr);
538
539 // There could be leftover tokens (e.g. because of an error).
540 // Skip through until we reach the original token position.
541 while (Tok.isNot(K: tok::eof))
542 ConsumeAnyToken();
543
544 // Clean up the remaining EOF token.
545 if (Tok.is(K: tok::eof) && Tok.getEofData() == LM.Method)
546 ConsumeAnyToken();
547
548 delete Toks;
549 LM.ExceptionSpecTokens = nullptr;
550 }
551
552 InFunctionTemplateScope.Scopes.Exit();
553
554 // Finish the delayed C++ method declaration.
555 Actions.ActOnFinishDelayedCXXMethodDeclaration(S: getCurScope(), Method: LM.Method);
556}
557
558void Parser::ParseLexedMethodDefs(ParsingClass &Class) {
559 ReenterClassScopeRAII InClassScope(*this, Class);
560
561 for (LateParsedDeclaration *D : Class.LateParsedDeclarations)
562 D->ParseLexedMethodDefs();
563}
564
565void Parser::ParseLexedMethodDef(LexedMethod &LM) {
566 // If this is a member template, introduce the template parameter scope.
567 ReenterTemplateScopeRAII InFunctionTemplateScope(*this, LM.D);
568
569 ParenBraceBracketBalancer BalancerRAIIObj(*this);
570
571 assert(!LM.Toks.empty() && "Empty body!");
572 Token LastBodyToken = LM.Toks.back();
573 Token BodyEnd = Token::createEof(Loc: LastBodyToken.getEndLoc(), Data: LM.D);
574 LM.Toks.push_back(Elt: BodyEnd);
575 // Append the current token at the end of the new token stream so that it
576 // doesn't get lost.
577 LM.Toks.push_back(Elt: Tok);
578 PP.EnterTokenStream(Toks: LM.Toks, DisableMacroExpansion: true, /*IsReinject*/true);
579
580 // Consume the previously pushed token.
581 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
582 assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try)
583 && "Inline method not starting with '{', ':' or 'try'");
584
585 // Parse the method body. Function body parsing code is similar enough
586 // to be re-used for method bodies as well.
587 ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope |
588 Scope::CompoundStmtScope);
589 Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);
590
591 Actions.ActOnStartOfFunctionDef(S: getCurScope(), D: LM.D);
592
593 llvm::scope_exit _([&]() {
594 while (Tok.isNot(K: tok::eof))
595 ConsumeAnyToken();
596
597 if (Tok.is(K: tok::eof) && Tok.getEofData() == LM.D)
598 ConsumeAnyToken();
599
600 if (auto *FD = dyn_cast_or_null<FunctionDecl>(Val: LM.D))
601 if (isa<CXXMethodDecl>(Val: FD) ||
602 FD->isInIdentifierNamespace(NS: Decl::IDNS_OrdinaryFriend))
603 Actions.ActOnFinishInlineFunctionDef(D: FD);
604 });
605
606 assert((Actions.getDiagnostics().hasErrorOccurred() ||
607 !isa<FunctionTemplateDecl>(LM.D) ||
608 cast<FunctionTemplateDecl>(LM.D)->getTemplateParameters()->getDepth()
609 < TemplateParameterDepth) &&
610 "TemplateParameterDepth should be greater than the depth of "
611 "current template being instantiated!");
612
613 ParseFunctionBody(D: LM.D, BodyScope&: FnScope);
614}
615
616void Parser::ParseLexedMemberInitializers(ParsingClass &Class) {
617 ReenterClassScopeRAII InClassScope(*this, Class);
618
619 if (!Class.LateParsedDeclarations.empty()) {
620 // C++11 [expr.prim.general]p4:
621 // Otherwise, if a member-declarator declares a non-static data member
622 // (9.2) of a class X, the expression this is a prvalue of type "pointer
623 // to X" within the optional brace-or-equal-initializer. It shall not
624 // appear elsewhere in the member-declarator.
625 // FIXME: This should be done in ParseLexedMemberInitializer, not here.
626 Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate,
627 Qualifiers());
628
629 for (LateParsedDeclaration *D : Class.LateParsedDeclarations)
630 D->ParseLexedMemberInitializers();
631 }
632
633 Actions.ActOnFinishDelayedMemberInitializers(Record: Class.TagOrTemplate);
634}
635
636void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
637 if (!MI.Field || MI.Field->isInvalidDecl())
638 return;
639
640 ParenBraceBracketBalancer BalancerRAIIObj(*this);
641
642 // Append the current token at the end of the new token stream so that it
643 // doesn't get lost.
644 MI.Toks.push_back(Elt: Tok);
645 PP.EnterTokenStream(Toks: MI.Toks, DisableMacroExpansion: true, /*IsReinject*/true);
646
647 // Consume the previously pushed token.
648 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
649
650 SourceLocation EqualLoc;
651
652 Actions.ActOnStartCXXInClassMemberInitializer();
653
654 // The initializer isn't actually potentially evaluated unless it is
655 // used.
656 EnterExpressionEvaluationContext Eval(
657 Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed);
658
659 ExprResult Init = ParseCXXMemberInitializer(D: MI.Field, /*IsFunction=*/false,
660 EqualLoc);
661
662 Actions.ActOnFinishCXXInClassMemberInitializer(VarDecl: MI.Field, EqualLoc, Init);
663
664 // The next token should be our artificial terminating EOF token.
665 if (Tok.isNot(K: tok::eof)) {
666 if (!Init.isInvalid()) {
667 SourceLocation EndLoc = PP.getLocForEndOfToken(Loc: PrevTokLocation);
668 if (!EndLoc.isValid())
669 EndLoc = Tok.getLocation();
670 // No fixit; we can't recover as if there were a semicolon here.
671 Diag(Loc: EndLoc, DiagID: diag::err_expected_semi_decl_list);
672 }
673
674 // Consume tokens until we hit the artificial EOF.
675 while (Tok.isNot(K: tok::eof))
676 ConsumeAnyToken();
677 }
678 // Make sure this is *our* artificial EOF token.
679 if (Tok.getEofData() == MI.Field)
680 ConsumeAnyToken();
681}
682
683void Parser::ParseLexedAttributes(ParsingClass &Class) {
684 ReenterClassScopeRAII InClassScope(*this, Class);
685
686 for (LateParsedDeclaration *LateD : Class.LateParsedDeclarations)
687 LateD->ParseLexedAttributes();
688}
689
690void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
691 bool EnterScope, bool OnDefinition,
692 ParsedAttributes *OutAttrs) {
693 assert(LAs.parseSoon() &&
694 "Attribute list should be marked for immediate parsing.");
695 for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
696 if (D)
697 LAs[i]->addDecl(D);
698 ParseLexedAttribute(LPA&: *LAs[i], EnterScope, OnDefinition, OutAttrs);
699 delete LAs[i];
700 }
701 LAs.clear();
702}
703
704void Parser::ParseLexedAttribute(LateParsedAttribute &LPA, bool EnterScope,
705 bool OnDefinition,
706 ParsedAttributes *OutAttrs) {
707 ParsedAttributes Attrs(AttrFactory);
708
709 if (LPA.Decls.size() > 0) {
710 Decl *D = LPA.Decls[0];
711 bool HasFuncScope = EnterScope && LPA.Decls.size() == 1 &&
712 D->isFunctionOrFunctionTemplate();
713 bool IsCPlusPlus = getLangOpts().CPlusPlus;
714
715 NamedDecl *ND = dyn_cast<NamedDecl>(Val: D);
716 RecordDecl *RD = dyn_cast_or_null<RecordDecl>(Val: D->getDeclContext());
717
718 // Allow 'this' within late-parsed attributes.
719 Sema::CXXThisScopeRAII ThisScope(Actions, RD, Qualifiers(),
720 IsCPlusPlus && ND &&
721 ND->isCXXInstanceMember());
722
723 // If the Decl is templatized, add template parameters to the scope.
724 ReenterTemplateScopeRAII InDeclScope(*this, D, IsCPlusPlus && EnterScope);
725
726 // If the Decl is on a function, add function parameters to the scope.
727 if (HasFuncScope) {
728 InDeclScope.Scopes.Enter(ScopeFlags: Scope::FnScope | Scope::DeclScope |
729 Scope::CompoundStmtScope);
730 Actions.ActOnReenterFunctionContext(S: Actions.CurScope, D);
731 }
732
733 ParsedAttributes Parsed = ParseLexedAttributeTokens(LPA);
734 Attrs.takeAllAppendingFrom(Other&: Parsed);
735
736 if (HasFuncScope)
737 Actions.ActOnExitFunctionContext();
738 } else {
739 Diag(Loc: LPA.AttrNameLoc, DiagID: diag::warn_attribute_no_decl)
740 << LPA.AttrName.getName();
741 }
742
743 if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() &&
744 Attrs.begin()->isKnownToGCC())
745 Diag(Tok, DiagID: diag::warn_attribute_on_function_definition) << &LPA.AttrName;
746
747 for (auto *D : LPA.Decls)
748 Actions.ActOnFinishDelayedAttribute(S: getCurScope(), D, Attrs);
749
750 if (OutAttrs)
751 OutAttrs->takeAllAppendingFrom(Other&: Attrs);
752}
753
754void Parser::ParseLexedPragmas(ParsingClass &Class) {
755 ReenterClassScopeRAII InClassScope(*this, Class);
756
757 for (LateParsedDeclaration *D : Class.LateParsedDeclarations)
758 D->ParseLexedPragmas();
759}
760
761void Parser::ParseLexedPragma(LateParsedPragma &LP) {
762 PP.EnterToken(Tok, /*IsReinject=*/true);
763 PP.EnterTokenStream(Toks: LP.toks(), /*DisableMacroExpansion=*/true,
764 /*IsReinject=*/true);
765
766 // Consume the previously pushed token.
767 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
768 assert(Tok.isAnnotation() && "Expected annotation token.");
769 switch (Tok.getKind()) {
770 case tok::annot_attr_openmp:
771 case tok::annot_pragma_openmp: {
772 AccessSpecifier AS = LP.getAccessSpecifier();
773 ParsedAttributes Attrs(AttrFactory);
774 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
775 break;
776 }
777 default:
778 llvm_unreachable("Unexpected token.");
779 }
780}
781
782bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
783 CachedTokens &Toks,
784 bool StopAtSemi, bool ConsumeFinalToken) {
785 // We always want this function to consume at least one token if the first
786 // token isn't T and if not at EOF.
787 bool isFirstTokenConsumed = true;
788 while (true) {
789 // If we found one of the tokens, stop and return true.
790 if (Tok.is(K: T1) || Tok.is(K: T2)) {
791 if (ConsumeFinalToken) {
792 Toks.push_back(Elt: Tok);
793 ConsumeAnyToken();
794 }
795 return true;
796 }
797
798 switch (Tok.getKind()) {
799 case tok::eof:
800 case tok::annot_module_begin:
801 case tok::annot_module_end:
802 case tok::annot_module_include:
803 case tok::annot_repl_input_end:
804 // Ran out of tokens.
805 return false;
806
807 case tok::annot_pragma_openacc:
808 case tok::annot_pragma_openmp:
809 case tok::annot_attr_openmp: {
810 // Ignore any tokens inside of a OMP/OpenACC pragma, as these should just
811 // be taken as 1.
812 tok::TokenKind EndKind = Tok.is(K: tok::annot_pragma_openacc)
813 ? tok::annot_pragma_openacc_end
814 : tok::annot_pragma_openmp_end;
815 Toks.push_back(Elt: Tok);
816 ConsumeAnnotationToken();
817 while (Tok.isNot(K: EndKind) && Tok.isNot(K: tok::eof)) {
818 Toks.push_back(Elt: Tok);
819 ConsumeAnyToken();
820 }
821 if (Tok.is(K: EndKind)) {
822 Toks.push_back(Elt: Tok);
823 ConsumeAnnotationToken();
824 }
825 break;
826 }
827
828 case tok::l_paren:
829 // Recursively consume properly-nested parens.
830 Toks.push_back(Elt: Tok);
831 ConsumeParen();
832 ConsumeAndStoreUntil(T1: tok::r_paren, Toks, /*StopAtSemi=*/false);
833 break;
834 case tok::l_square:
835 // Recursively consume properly-nested square brackets.
836 Toks.push_back(Elt: Tok);
837 ConsumeBracket();
838 ConsumeAndStoreUntil(T1: tok::r_square, Toks, /*StopAtSemi=*/false);
839 break;
840 case tok::l_brace:
841 // Recursively consume properly-nested braces.
842 Toks.push_back(Elt: Tok);
843 ConsumeBrace();
844 ConsumeAndStoreUntil(T1: tok::r_brace, Toks, /*StopAtSemi=*/false);
845 break;
846
847 // Okay, we found a ']' or '}' or ')', which we think should be balanced.
848 // Since the user wasn't looking for this token (if they were, it would
849 // already be handled), this isn't balanced. If there is a LHS token at a
850 // higher level, we will assume that this matches the unbalanced token
851 // and return it. Otherwise, this is a spurious RHS token, which we skip.
852 case tok::r_paren:
853 if (ParenCount && !isFirstTokenConsumed)
854 return false; // Matches something.
855 Toks.push_back(Elt: Tok);
856 ConsumeParen();
857 break;
858 case tok::r_square:
859 if (BracketCount && !isFirstTokenConsumed)
860 return false; // Matches something.
861 Toks.push_back(Elt: Tok);
862 ConsumeBracket();
863 break;
864 case tok::r_brace:
865 if (BraceCount && !isFirstTokenConsumed)
866 return false; // Matches something.
867 Toks.push_back(Elt: Tok);
868 ConsumeBrace();
869 break;
870
871 case tok::semi:
872 if (StopAtSemi)
873 return false;
874 [[fallthrough]];
875 default:
876 // consume this token.
877 Toks.push_back(Elt: Tok);
878 ConsumeAnyToken(/*ConsumeCodeCompletionTok*/true);
879 break;
880 }
881 isFirstTokenConsumed = false;
882 }
883}
884
885bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) {
886 if (Tok.is(K: tok::kw_try)) {
887 Toks.push_back(Elt: Tok);
888 ConsumeToken();
889 }
890
891 if (Tok.isNot(K: tok::colon)) {
892 // Easy case, just a function body.
893
894 // Grab any remaining garbage to be diagnosed later. We stop when we reach a
895 // brace: an opening one is the function body, while a closing one probably
896 // means we've reached the end of the class.
897 ConsumeAndStoreUntil(T1: tok::l_brace, T2: tok::r_brace, Toks,
898 /*StopAtSemi=*/true,
899 /*ConsumeFinalToken=*/false);
900 if (Tok.isNot(K: tok::l_brace))
901 return Diag(Loc: Tok.getLocation(), DiagID: diag::err_expected) << tok::l_brace;
902
903 Toks.push_back(Elt: Tok);
904 ConsumeBrace();
905 return false;
906 }
907
908 Toks.push_back(Elt: Tok);
909 ConsumeToken();
910
911 // We can't reliably skip over a mem-initializer-id, because it could be
912 // a template-id involving not-yet-declared names. Given:
913 //
914 // S ( ) : a < b < c > ( e )
915 //
916 // 'e' might be an initializer or part of a template argument, depending
917 // on whether 'b' is a template.
918
919 // Track whether we might be inside a template argument. We can give
920 // significantly better diagnostics if we know that we're not.
921 bool MightBeTemplateArgument = false;
922
923 while (true) {
924 // Skip over the mem-initializer-id, if possible.
925 if (Tok.is(K: tok::kw_decltype)) {
926 Toks.push_back(Elt: Tok);
927 SourceLocation OpenLoc = ConsumeToken();
928 if (Tok.isNot(K: tok::l_paren))
929 return Diag(Loc: Tok.getLocation(), DiagID: diag::err_expected_lparen_after)
930 << "decltype";
931 Toks.push_back(Elt: Tok);
932 ConsumeParen();
933 if (!ConsumeAndStoreUntil(T1: tok::r_paren, Toks, /*StopAtSemi=*/true)) {
934 Diag(Loc: Tok.getLocation(), DiagID: diag::err_expected) << tok::r_paren;
935 Diag(Loc: OpenLoc, DiagID: diag::note_matching) << tok::l_paren;
936 return true;
937 }
938 }
939 do {
940 // Walk over a component of a nested-name-specifier.
941 if (Tok.is(K: tok::coloncolon)) {
942 Toks.push_back(Elt: Tok);
943 ConsumeToken();
944
945 if (Tok.is(K: tok::kw_template)) {
946 Toks.push_back(Elt: Tok);
947 ConsumeToken();
948 }
949 }
950
951 if (Tok.is(K: tok::identifier)) {
952 Toks.push_back(Elt: Tok);
953 ConsumeToken();
954 } else {
955 break;
956 }
957 // Pack indexing
958 if (Tok.is(K: tok::ellipsis) && NextToken().is(K: tok::l_square)) {
959 Toks.push_back(Elt: Tok);
960 SourceLocation OpenLoc = ConsumeToken();
961 Toks.push_back(Elt: Tok);
962 ConsumeBracket();
963 if (!ConsumeAndStoreUntil(T1: tok::r_square, Toks, /*StopAtSemi=*/true)) {
964 Diag(Loc: Tok.getLocation(), DiagID: diag::err_expected) << tok::r_square;
965 Diag(Loc: OpenLoc, DiagID: diag::note_matching) << tok::l_square;
966 return true;
967 }
968 }
969
970 } while (Tok.is(K: tok::coloncolon));
971
972 if (Tok.is(K: tok::code_completion)) {
973 Toks.push_back(Elt: Tok);
974 ConsumeCodeCompletionToken();
975 if (Tok.isOneOf(Ks: tok::identifier, Ks: tok::coloncolon, Ks: tok::kw_decltype)) {
976 // Could be the start of another member initializer (the ',' has not
977 // been written yet)
978 continue;
979 }
980 }
981
982 if (Tok.is(K: tok::comma)) {
983 // The initialization is missing, we'll diagnose it later.
984 Toks.push_back(Elt: Tok);
985 ConsumeToken();
986 continue;
987 }
988 if (Tok.is(K: tok::less))
989 MightBeTemplateArgument = true;
990
991 if (MightBeTemplateArgument) {
992 // We may be inside a template argument list. Grab up to the start of the
993 // next parenthesized initializer or braced-init-list. This *might* be the
994 // initializer, or it might be a subexpression in the template argument
995 // list.
996 // FIXME: Count angle brackets, and clear MightBeTemplateArgument
997 // if all angles are closed.
998 if (!ConsumeAndStoreUntil(T1: tok::l_paren, T2: tok::l_brace, Toks,
999 /*StopAtSemi=*/true,
1000 /*ConsumeFinalToken=*/false)) {
1001 // We're not just missing the initializer, we're also missing the
1002 // function body!
1003 return Diag(Loc: Tok.getLocation(), DiagID: diag::err_expected) << tok::l_brace;
1004 }
1005 } else if (Tok.isNot(K: tok::l_paren) && Tok.isNot(K: tok::l_brace)) {
1006 // We found something weird in a mem-initializer-id.
1007 if (getLangOpts().CPlusPlus11)
1008 return Diag(Loc: Tok.getLocation(), DiagID: diag::err_expected_either)
1009 << tok::l_paren << tok::l_brace;
1010 else
1011 return Diag(Loc: Tok.getLocation(), DiagID: diag::err_expected) << tok::l_paren;
1012 }
1013
1014 tok::TokenKind kind = Tok.getKind();
1015 Toks.push_back(Elt: Tok);
1016 bool IsLParen = (kind == tok::l_paren);
1017 SourceLocation OpenLoc = Tok.getLocation();
1018
1019 if (IsLParen) {
1020 ConsumeParen();
1021 } else {
1022 assert(kind == tok::l_brace && "Must be left paren or brace here.");
1023 ConsumeBrace();
1024 // In C++03, this has to be the start of the function body, which
1025 // means the initializer is malformed; we'll diagnose it later.
1026 if (!getLangOpts().CPlusPlus11)
1027 return false;
1028
1029 const Token &PreviousToken = Toks[Toks.size() - 2];
1030 if (!MightBeTemplateArgument &&
1031 !PreviousToken.isOneOf(Ks: tok::identifier, Ks: tok::greater,
1032 Ks: tok::greatergreater)) {
1033 // If the opening brace is not preceded by one of these tokens, we are
1034 // missing the mem-initializer-id. In order to recover better, we need
1035 // to use heuristics to determine if this '{' is most likely the
1036 // beginning of a brace-init-list or the function body.
1037 // Check the token after the corresponding '}'.
1038 TentativeParsingAction PA(*this);
1039 if (SkipUntil(T: tok::r_brace) &&
1040 !Tok.isOneOf(Ks: tok::comma, Ks: tok::ellipsis, Ks: tok::l_brace)) {
1041 // Consider there was a malformed initializer and this is the start
1042 // of the function body. We'll diagnose it later.
1043 PA.Revert();
1044 return false;
1045 }
1046 PA.Revert();
1047 }
1048 }
1049
1050 // Grab the initializer (or the subexpression of the template argument).
1051 // FIXME: If we support lambdas here, we'll need to set StopAtSemi to false
1052 // if we might be inside the braces of a lambda-expression.
1053 tok::TokenKind CloseKind = IsLParen ? tok::r_paren : tok::r_brace;
1054 if (!ConsumeAndStoreUntil(T1: CloseKind, Toks, /*StopAtSemi=*/true)) {
1055 Diag(Tok, DiagID: diag::err_expected) << CloseKind;
1056 Diag(Loc: OpenLoc, DiagID: diag::note_matching) << kind;
1057 return true;
1058 }
1059
1060 // Grab pack ellipsis, if present.
1061 if (Tok.is(K: tok::ellipsis)) {
1062 Toks.push_back(Elt: Tok);
1063 ConsumeToken();
1064 }
1065
1066 // If we know we just consumed a mem-initializer, we must have ',' or '{'
1067 // next.
1068 if (Tok.is(K: tok::comma)) {
1069 Toks.push_back(Elt: Tok);
1070 ConsumeToken();
1071 } else if (Tok.is(K: tok::l_brace)) {
1072 // This is the function body if the ')' or '}' is immediately followed by
1073 // a '{'. That cannot happen within a template argument, apart from the
1074 // case where a template argument contains a compound literal:
1075 //
1076 // S ( ) : a < b < c > ( d ) { }
1077 // // End of declaration, or still inside the template argument?
1078 //
1079 // ... and the case where the template argument contains a lambda:
1080 //
1081 // S ( ) : a < 0 && b < c > ( d ) + [ ] ( ) { return 0; }
1082 // ( ) > ( ) { }
1083 //
1084 // FIXME: Disambiguate these cases. Note that the latter case is probably
1085 // going to be made ill-formed by core issue 1607.
1086 Toks.push_back(Elt: Tok);
1087 ConsumeBrace();
1088 return false;
1089 } else if (!MightBeTemplateArgument) {
1090 return Diag(Loc: Tok.getLocation(), DiagID: diag::err_expected_either) << tok::l_brace
1091 << tok::comma;
1092 }
1093 }
1094}
1095
1096bool Parser::ConsumeAndStoreConditional(CachedTokens &Toks) {
1097 // Consume '?'.
1098 assert(Tok.is(tok::question));
1099 Toks.push_back(Elt: Tok);
1100 ConsumeToken();
1101
1102 while (Tok.isNot(K: tok::colon)) {
1103 if (!ConsumeAndStoreUntil(T1: tok::question, T2: tok::colon, Toks,
1104 /*StopAtSemi=*/true,
1105 /*ConsumeFinalToken=*/false))
1106 return false;
1107
1108 // If we found a nested conditional, consume it.
1109 if (Tok.is(K: tok::question) && !ConsumeAndStoreConditional(Toks))
1110 return false;
1111 }
1112
1113 // Consume ':'.
1114 Toks.push_back(Elt: Tok);
1115 ConsumeToken();
1116 return true;
1117}
1118
1119bool Parser::ConsumeAndStoreInitializer(CachedTokens &Toks,
1120 CachedInitKind CIK) {
1121 // We always want this function to consume at least one token if not at EOF.
1122 bool IsFirstToken = true;
1123
1124 // Number of possible unclosed <s we've seen so far. These might be templates,
1125 // and might not, but if there were none of them (or we know for sure that
1126 // we're within a template), we can avoid a tentative parse.
1127 unsigned AngleCount = 0;
1128 unsigned KnownTemplateCount = 0;
1129
1130 while (true) {
1131 switch (Tok.getKind()) {
1132 case tok::ellipsis:
1133 // We found an elipsis at the end of the parameter list;
1134 // it is not part of a parameter declaration.
1135 if (ParenCount == 1 && NextToken().is(K: tok::r_paren))
1136 return true;
1137 goto consume_token;
1138 case tok::comma:
1139 // If we might be in a template, perform a tentative parse to check.
1140 if (!AngleCount)
1141 // Not a template argument: this is the end of the initializer.
1142 return true;
1143 if (KnownTemplateCount)
1144 goto consume_token;
1145
1146 // We hit a comma inside angle brackets. This is the hard case. The
1147 // rule we follow is:
1148 // * For a default argument, if the tokens after the comma form a
1149 // syntactically-valid parameter-declaration-clause, in which each
1150 // parameter has an initializer, then this comma ends the default
1151 // argument.
1152 // * For a default initializer, if the tokens after the comma form a
1153 // syntactically-valid init-declarator-list, then this comma ends
1154 // the default initializer.
1155 {
1156 TentativeParsingAction TPA(*this, /*Unannotated=*/true);
1157 Sema::TentativeAnalysisScope Scope(Actions);
1158
1159 TPResult Result = TPResult::Error;
1160 ConsumeToken();
1161 switch (CIK) {
1162 case CachedInitKind::DefaultInitializer:
1163 Result = TryParseInitDeclaratorList();
1164 // If we parsed a complete, ambiguous init-declarator-list, this
1165 // is only syntactically-valid if it's followed by a semicolon.
1166 if (Result == TPResult::Ambiguous && Tok.isNot(K: tok::semi))
1167 Result = TPResult::False;
1168 break;
1169
1170 case CachedInitKind::DefaultArgument:
1171 bool InvalidAsDeclaration = false;
1172 Result = TryParseParameterDeclarationClause(
1173 InvalidAsDeclaration: &InvalidAsDeclaration, /*VersusTemplateArg=*/true);
1174 // If this is an expression or a declaration with a missing
1175 // 'typename', assume it's not a declaration.
1176 if (Result == TPResult::Ambiguous && InvalidAsDeclaration)
1177 Result = TPResult::False;
1178 break;
1179 }
1180
1181 // Put the token stream back and undo any annotations we performed
1182 // after the comma. They may reflect a different parse than the one
1183 // we will actually perform at the end of the class.
1184 TPA.Revert();
1185
1186 // If what follows could be a declaration, it is a declaration.
1187 if (Result != TPResult::False && Result != TPResult::Error)
1188 return true;
1189 }
1190
1191 // Keep going. We know we're inside a template argument list now.
1192 ++KnownTemplateCount;
1193 goto consume_token;
1194
1195 case tok::eof:
1196 // Ran out of tokens.
1197 return false;
1198
1199 case tok::less:
1200 // FIXME: A '<' can only start a template-id if it's preceded by an
1201 // identifier, an operator-function-id, or a literal-operator-id.
1202 ++AngleCount;
1203 goto consume_token;
1204
1205 case tok::question:
1206 // In 'a ? b : c', 'b' can contain an unparenthesized comma. If it does,
1207 // that is *never* the end of the initializer. Skip to the ':'.
1208 if (!ConsumeAndStoreConditional(Toks))
1209 return false;
1210 break;
1211
1212 case tok::greatergreatergreater:
1213 if (!getLangOpts().CPlusPlus11)
1214 goto consume_token;
1215 if (AngleCount) --AngleCount;
1216 if (KnownTemplateCount) --KnownTemplateCount;
1217 [[fallthrough]];
1218 case tok::greatergreater:
1219 if (!getLangOpts().CPlusPlus11)
1220 goto consume_token;
1221 if (AngleCount) --AngleCount;
1222 if (KnownTemplateCount) --KnownTemplateCount;
1223 [[fallthrough]];
1224 case tok::greater:
1225 if (AngleCount) --AngleCount;
1226 if (KnownTemplateCount) --KnownTemplateCount;
1227 goto consume_token;
1228
1229 case tok::kw_template:
1230 // 'template' identifier '<' is known to start a template argument list,
1231 // and can be used to disambiguate the parse.
1232 // FIXME: Support all forms of 'template' unqualified-id '<'.
1233 Toks.push_back(Elt: Tok);
1234 ConsumeToken();
1235 if (Tok.is(K: tok::identifier)) {
1236 Toks.push_back(Elt: Tok);
1237 ConsumeToken();
1238 if (Tok.is(K: tok::less)) {
1239 ++AngleCount;
1240 ++KnownTemplateCount;
1241 Toks.push_back(Elt: Tok);
1242 ConsumeToken();
1243 }
1244 }
1245 break;
1246
1247 case tok::kw_operator:
1248 // If 'operator' precedes other punctuation, that punctuation loses
1249 // its special behavior.
1250 Toks.push_back(Elt: Tok);
1251 ConsumeToken();
1252 switch (Tok.getKind()) {
1253 case tok::comma:
1254 case tok::greatergreatergreater:
1255 case tok::greatergreater:
1256 case tok::greater:
1257 case tok::less:
1258 Toks.push_back(Elt: Tok);
1259 ConsumeToken();
1260 break;
1261 default:
1262 break;
1263 }
1264 break;
1265
1266 case tok::l_paren:
1267 // Recursively consume properly-nested parens.
1268 Toks.push_back(Elt: Tok);
1269 ConsumeParen();
1270 ConsumeAndStoreUntil(T1: tok::r_paren, Toks, /*StopAtSemi=*/false);
1271 break;
1272 case tok::l_square:
1273 // Recursively consume properly-nested square brackets.
1274 Toks.push_back(Elt: Tok);
1275 ConsumeBracket();
1276 ConsumeAndStoreUntil(T1: tok::r_square, Toks, /*StopAtSemi=*/false);
1277 break;
1278 case tok::l_brace:
1279 // Recursively consume properly-nested braces.
1280 Toks.push_back(Elt: Tok);
1281 ConsumeBrace();
1282 ConsumeAndStoreUntil(T1: tok::r_brace, Toks, /*StopAtSemi=*/false);
1283 break;
1284
1285 // Okay, we found a ']' or '}' or ')', which we think should be balanced.
1286 // Since the user wasn't looking for this token (if they were, it would
1287 // already be handled), this isn't balanced. If there is a LHS token at a
1288 // higher level, we will assume that this matches the unbalanced token
1289 // and return it. Otherwise, this is a spurious RHS token, which we
1290 // consume and pass on to downstream code to diagnose.
1291 case tok::r_paren:
1292 if (CIK == CachedInitKind::DefaultArgument)
1293 return true; // End of the default argument.
1294 if (ParenCount && !IsFirstToken)
1295 return false;
1296 Toks.push_back(Elt: Tok);
1297 ConsumeParen();
1298 continue;
1299 case tok::r_square:
1300 if (BracketCount && !IsFirstToken)
1301 return false;
1302 Toks.push_back(Elt: Tok);
1303 ConsumeBracket();
1304 continue;
1305 case tok::r_brace:
1306 if (BraceCount && !IsFirstToken)
1307 return false;
1308 Toks.push_back(Elt: Tok);
1309 ConsumeBrace();
1310 continue;
1311
1312 case tok::code_completion:
1313 Toks.push_back(Elt: Tok);
1314 ConsumeCodeCompletionToken();
1315 break;
1316
1317 case tok::string_literal:
1318 case tok::wide_string_literal:
1319 case tok::utf8_string_literal:
1320 case tok::utf16_string_literal:
1321 case tok::utf32_string_literal:
1322 Toks.push_back(Elt: Tok);
1323 ConsumeStringToken();
1324 break;
1325 case tok::semi:
1326 if (CIK == CachedInitKind::DefaultInitializer)
1327 return true; // End of the default initializer.
1328 [[fallthrough]];
1329 default:
1330 consume_token:
1331 // If it's an annotation token, then we've run out of tokens and should
1332 // bail out. Otherwise, cache the token and consume it.
1333 if (Tok.isAnnotation())
1334 return false;
1335
1336 Toks.push_back(Elt: Tok);
1337 ConsumeToken();
1338 break;
1339 }
1340 IsFirstToken = false;
1341 }
1342}
1343