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

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of clang/lib/Parse/ParseCXXInlineMethods.cpp