1375 lines · cpp
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-exception6//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(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().CPlusPlus2636 ? diag::warn_cxx23_delete_with_message37 : 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(tok::r_paren, StopAtSemi | StopBeforeMatch);44 }45 46 BT.consumeClose();47 return Message;48}49 50void Parser::SkipDeletedFunctionBody() {51 if (!Tok.is(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(tok::r_paren, tok::comma, StopAtSemi | StopBeforeMatch);59 if (Tok.is(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(getCurScope(), D,79 TemplateParams);80 else {81 FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D,82 TemplateParams, nullptr,83 VS, 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(tok::equal)) {97 if (!FnD) {98 SkipUntil(tok::semi);99 return nullptr;100 }101 102 bool Delete = false;103 SourceLocation KWLoc;104 SourceLocation KWEndLoc = Tok.getEndLoc().getLocWithOffset(-1);105 if (TryConsumeToken(tok::kw_delete, KWLoc)) {106 Diag(KWLoc, getLangOpts().CPlusPlus11107 ? diag::warn_cxx98_compat_defaulted_deleted_function108 : 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>(FnD)) {114 DeclAsFunction->setRangeEnd(KWEndLoc);115 }116 } else if (TryConsumeToken(tok::kw_default, KWLoc)) {117 Diag(KWLoc, getLangOpts().CPlusPlus11118 ? diag::warn_cxx98_compat_defaulted_deleted_function119 : diag::ext_defaulted_deleted_function)120 << 0 /* defaulted */;121 Actions.SetDeclDefaulted(FnD, KWLoc);122 if (auto *DeclAsFunction = dyn_cast<FunctionDecl>(FnD)) {123 DeclAsFunction->setRangeEnd(KWEndLoc);124 }125 } else {126 llvm_unreachable("function definition after = not 'delete' or 'default'");127 }128 129 if (Tok.is(tok::comma)) {130 Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)131 << Delete;132 SkipUntil(tok::semi);133 } else if (ExpectAndConsume(tok::semi, diag::err_expected_after,134 Delete ? "delete" : "default")) {135 SkipUntil(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 template148 // or if we are about to parse function member template then consume149 // 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(LM);176 CachedTokens &Toks = LM->Toks;177 178 tok::TokenKind kind = Tok.getKind();179 // Consume everything up to (and including) the left brace of the180 // function body.181 if (ConsumeAndStoreFunctionPrologue(Toks)) {182 // We didn't find the left-brace we expected after the183 // constructor initializer.184 185 // If we're code-completing and the completion point was in the broken186 // initializer, we want to parse it even though that will fail.187 if (PP.isCodeCompletionEnabled() &&188 llvm::any_of(Toks, [](const Token &Tok) {189 return Tok.is(tok::code_completion);190 })) {191 // If we gave up at the completion point, the initializer list was192 // likely truncated, so don't eat more tokens. We'll hit some extra193 // 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 looks200 // 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(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(tok::kw_catch)) {213 ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false);214 ConsumeAndStoreUntil(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 needs221 // 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(MI);241 CachedTokens &Toks = MI->Toks;242 243 tok::TokenKind kind = Tok.getKind();244 if (kind == tok::equal) {245 Toks.push_back(Tok);246 ConsumeToken();247 }248 249 if (kind == tok::l_brace) {250 // Begin by storing the '{' token.251 Toks.push_back(Tok);252 ConsumeBrace();253 254 // Consume everything up to (and including) the matching right brace.255 ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/true);256 } else {257 // Consume everything up to (but excluding) the comma or semicolon.258 ConsumeAndStoreInitializer(Toks, CachedInitKind::DefaultInitializer);259 }260 261 // Store an artificial EOF token to ensure that we don't run off the end of262 // 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(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);287}288 289void Parser::LateParsedClass::ParseLexedMemberInitializers() {290 Self->ParseLexedMemberInitializers(*Class);291}292 293void Parser::LateParsedClass::ParseLexedMethodDefs() {294 Self->ParseLexedMethodDefs(*Class);295}296 297void Parser::LateParsedClass::ParseLexedAttributes() {298 Self->ParseLexedAttributes(*Class);299}300 301void Parser::LateParsedClass::ParseLexedPragmas() {302 Self->ParseLexedPragmas(*Class);303}304 305void Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() {306 Self->ParseLexedMethodDeclaration(*this);307}308 309void Parser::LexedMethod::ParseLexedMethodDefs() {310 Self->ParseLexedMethodDef(*this);311}312 313void Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() {314 Self->ParseLexedMemberInitializer(*this);315}316 317void Parser::LateParsedAttribute::ParseLexedAttributes() {318 Self->ParseLexedAttribute(*this, true, false);319}320 321void Parser::LateParsedPragma::ParseLexedPragmas() {322 Self->ParseLexedPragma(*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 P.ReenterTemplateScopes(Scopes, 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(Scope::ClassScope|Scope::DeclScope);352 P.Actions.ActOnStartDelayedMemberDeclarations(P.getCurScope(),353 Class.TagOrTemplate);354 }355 ~ReenterClassScopeRAII() {356 if (Class.TopLevelClass)357 return;358 359 P.Actions.ActOnFinishDelayedMemberDeclarations(P.getCurScope(),360 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 declaration376 Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method);377 378 // Introduce the parameters into scope and parse their default379 // arguments.380 InFunctionTemplateScope.Scopes.Enter(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>(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 when393 // 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(DefArgEnd);401 402 // Parse the default argument from its saved token stream.403 Toks->push_back(Tok); // So that the current token doesn't get lost404 PP.EnterTokenStream(*Toks, 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 is414 // used.415 EnterExpressionEvaluationContext Eval(416 Actions,417 Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed, Param);418 419 ExprResult DefArgResult;420 if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {421 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);422 DefArgResult = ParseBraceInitializer();423 } else424 DefArgResult = ParseAssignmentExpression();425 if (DefArgResult.isInvalid()) {426 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,427 /*DefaultArg=*/nullptr);428 } else {429 if (Tok.isNot(tok::eof) || Tok.getEofData() != Param) {430 // The last two tokens are the terminator and the saved value of431 // Tok; the last token in the default argument is the one before432 // those.433 assert(Toks->size() >= 3 && "expected a token in default arg");434 Diag(Tok.getLocation(), diag::err_default_arg_unparsed)435 << SourceRange(Tok.getLocation(),436 (*Toks)[Toks->size() - 3].getLocation());437 }438 Actions.ActOnParamDefaultArgument(Param, EqualLoc,439 DefArgResult.get());440 }441 442 // There could be leftover tokens (e.g. because of an error).443 // Skip through until we reach the 'end of default argument' token.444 while (Tok.isNot(tok::eof))445 ConsumeAnyToken();446 447 if (Tok.is(tok::eof) && Tok.getEofData() == Param)448 ConsumeAnyToken();449 } else if (HasUnparsed) {450 assert(Param->hasInheritedDefaultArg());451 FunctionDecl *Old;452 if (const auto *FunTmpl = dyn_cast<FunctionTemplateDecl>(LM.Method))453 Old =454 cast<FunctionDecl>(FunTmpl->getTemplatedDecl())->getPreviousDecl();455 else456 Old = cast<FunctionDecl>(LM.Method)->getPreviousDecl();457 if (Old) {458 ParmVarDecl *OldParam = Old->getParamDecl(I);459 assert(!OldParam->hasUnparsedDefaultArg());460 if (OldParam->hasUninstantiatedDefaultArg())461 Param->setUninstantiatedDefaultArg(462 OldParam->getUninstantiatedDefaultArg());463 else464 Param->setDefaultArg(OldParam->getInit());465 }466 }467 }468 469 // Parse a delayed exception-specification, if there is one.470 if (CachedTokens *Toks = LM.ExceptionSpecTokens) {471 ParenBraceBracketBalancer BalancerRAIIObj(*this);472 473 // Add the 'stop' token.474 Token LastExceptionSpecToken = Toks->back();475 Token ExceptionSpecEnd;476 ExceptionSpecEnd.startToken();477 ExceptionSpecEnd.setKind(tok::eof);478 ExceptionSpecEnd.setLocation(LastExceptionSpecToken.getEndLoc());479 ExceptionSpecEnd.setEofData(LM.Method);480 Toks->push_back(ExceptionSpecEnd);481 482 // Parse the default argument from its saved token stream.483 Toks->push_back(Tok); // So that the current token doesn't get lost484 PP.EnterTokenStream(*Toks, true, /*IsReinject*/true);485 486 // Consume the previously-pushed token.487 ConsumeAnyToken();488 489 // C++11 [expr.prim.general]p3:490 // If a declaration declares a member function or member function491 // template of a class X, the expression this is a prvalue of type492 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq493 // and the end of the function-definition, member-declarator, or494 // declarator.495 CXXMethodDecl *Method;496 FunctionDecl *FunctionToPush;497 if (FunctionTemplateDecl *FunTmpl498 = dyn_cast<FunctionTemplateDecl>(LM.Method))499 FunctionToPush = FunTmpl->getTemplatedDecl();500 else501 FunctionToPush = cast<FunctionDecl>(LM.Method);502 Method = dyn_cast<CXXMethodDecl>(FunctionToPush);503 504 // Push a function scope so that tryCaptureVariable() can properly visit505 // function scopes involving function parameters that are referenced inside506 // the noexcept specifier e.g. through a lambda expression.507 // Example:508 // struct X {509 // void ICE(int val) noexcept(noexcept([val]{}));510 // };511 // Setup the CurScope to match the function DeclContext - we have such512 // assumption in IsInFnTryBlockHandler().513 ParseScope FnScope(this, Scope::FnScope);514 Sema::ContextRAII FnContext(Actions, FunctionToPush,515 /*NewThisContext=*/false);516 Sema::FunctionScopeRAII PopFnContext(Actions);517 Actions.PushFunctionScope();518 519 Sema::CXXThisScopeRAII ThisScope(520 Actions, Method ? Method->getParent() : nullptr,521 Method ? Method->getMethodQualifiers() : Qualifiers{},522 Method && getLangOpts().CPlusPlus11);523 524 // Parse the exception-specification.525 SourceRange SpecificationRange;526 SmallVector<ParsedType, 4> DynamicExceptions;527 SmallVector<SourceRange, 4> DynamicExceptionRanges;528 ExprResult NoexceptExpr;529 CachedTokens *ExceptionSpecTokens;530 531 ExceptionSpecificationType EST532 = tryParseExceptionSpecification(/*Delayed=*/false, SpecificationRange,533 DynamicExceptions,534 DynamicExceptionRanges, NoexceptExpr,535 ExceptionSpecTokens);536 537 if (Tok.isNot(tok::eof) || Tok.getEofData() != LM.Method)538 Diag(Tok.getLocation(), diag::err_except_spec_unparsed);539 540 // Attach the exception-specification to the method.541 Actions.actOnDelayedExceptionSpecification(LM.Method, EST,542 SpecificationRange,543 DynamicExceptions,544 DynamicExceptionRanges,545 NoexceptExpr.isUsable()?546 NoexceptExpr.get() : nullptr);547 548 // There could be leftover tokens (e.g. because of an error).549 // Skip through until we reach the original token position.550 while (Tok.isNot(tok::eof))551 ConsumeAnyToken();552 553 // Clean up the remaining EOF token.554 if (Tok.is(tok::eof) && Tok.getEofData() == LM.Method)555 ConsumeAnyToken();556 557 delete Toks;558 LM.ExceptionSpecTokens = nullptr;559 }560 561 InFunctionTemplateScope.Scopes.Exit();562 563 // Finish the delayed C++ method declaration.564 Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method);565}566 567void Parser::ParseLexedMethodDefs(ParsingClass &Class) {568 ReenterClassScopeRAII InClassScope(*this, Class);569 570 for (LateParsedDeclaration *D : Class.LateParsedDeclarations)571 D->ParseLexedMethodDefs();572}573 574void Parser::ParseLexedMethodDef(LexedMethod &LM) {575 // If this is a member template, introduce the template parameter scope.576 ReenterTemplateScopeRAII InFunctionTemplateScope(*this, LM.D);577 578 ParenBraceBracketBalancer BalancerRAIIObj(*this);579 580 assert(!LM.Toks.empty() && "Empty body!");581 Token LastBodyToken = LM.Toks.back();582 Token BodyEnd;583 BodyEnd.startToken();584 BodyEnd.setKind(tok::eof);585 BodyEnd.setLocation(LastBodyToken.getEndLoc());586 BodyEnd.setEofData(LM.D);587 LM.Toks.push_back(BodyEnd);588 // Append the current token at the end of the new token stream so that it589 // doesn't get lost.590 LM.Toks.push_back(Tok);591 PP.EnterTokenStream(LM.Toks, true, /*IsReinject*/true);592 593 // Consume the previously pushed token.594 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);595 assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try)596 && "Inline method not starting with '{', ':' or 'try'");597 598 // Parse the method body. Function body parsing code is similar enough599 // to be re-used for method bodies as well.600 ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope |601 Scope::CompoundStmtScope);602 Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);603 604 Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D);605 606 auto _ = llvm::make_scope_exit([&]() {607 while (Tok.isNot(tok::eof))608 ConsumeAnyToken();609 610 if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)611 ConsumeAnyToken();612 613 if (auto *FD = dyn_cast_or_null<FunctionDecl>(LM.D))614 if (isa<CXXMethodDecl>(FD) ||615 FD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend))616 Actions.ActOnFinishInlineFunctionDef(FD);617 });618 619 if (Tok.is(tok::kw_try)) {620 ParseFunctionTryBlock(LM.D, FnScope);621 return;622 }623 if (Tok.is(tok::colon)) {624 ParseConstructorInitializer(LM.D);625 626 // Error recovery.627 if (!Tok.is(tok::l_brace)) {628 FnScope.Exit();629 Actions.ActOnFinishFunctionBody(LM.D, nullptr);630 return;631 }632 } else633 Actions.ActOnDefaultCtorInitializers(LM.D);634 635 assert((Actions.getDiagnostics().hasErrorOccurred() ||636 !isa<FunctionTemplateDecl>(LM.D) ||637 cast<FunctionTemplateDecl>(LM.D)->getTemplateParameters()->getDepth()638 < TemplateParameterDepth) &&639 "TemplateParameterDepth should be greater than the depth of "640 "current template being instantiated!");641 642 ParseFunctionStatementBody(LM.D, FnScope);643}644 645void Parser::ParseLexedMemberInitializers(ParsingClass &Class) {646 ReenterClassScopeRAII InClassScope(*this, Class);647 648 if (!Class.LateParsedDeclarations.empty()) {649 // C++11 [expr.prim.general]p4:650 // Otherwise, if a member-declarator declares a non-static data member651 // (9.2) of a class X, the expression this is a prvalue of type "pointer652 // to X" within the optional brace-or-equal-initializer. It shall not653 // appear elsewhere in the member-declarator.654 // FIXME: This should be done in ParseLexedMemberInitializer, not here.655 Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate,656 Qualifiers());657 658 for (LateParsedDeclaration *D : Class.LateParsedDeclarations)659 D->ParseLexedMemberInitializers();660 }661 662 Actions.ActOnFinishDelayedMemberInitializers(Class.TagOrTemplate);663}664 665void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {666 if (!MI.Field || MI.Field->isInvalidDecl())667 return;668 669 ParenBraceBracketBalancer BalancerRAIIObj(*this);670 671 // Append the current token at the end of the new token stream so that it672 // doesn't get lost.673 MI.Toks.push_back(Tok);674 PP.EnterTokenStream(MI.Toks, true, /*IsReinject*/true);675 676 // Consume the previously pushed token.677 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);678 679 SourceLocation EqualLoc;680 681 Actions.ActOnStartCXXInClassMemberInitializer();682 683 // The initializer isn't actually potentially evaluated unless it is684 // used.685 EnterExpressionEvaluationContext Eval(686 Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed);687 688 ExprResult Init = ParseCXXMemberInitializer(MI.Field, /*IsFunction=*/false,689 EqualLoc);690 691 Actions.ActOnFinishCXXInClassMemberInitializer(MI.Field, EqualLoc, Init);692 693 // The next token should be our artificial terminating EOF token.694 if (Tok.isNot(tok::eof)) {695 if (!Init.isInvalid()) {696 SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);697 if (!EndLoc.isValid())698 EndLoc = Tok.getLocation();699 // No fixit; we can't recover as if there were a semicolon here.700 Diag(EndLoc, diag::err_expected_semi_decl_list);701 }702 703 // Consume tokens until we hit the artificial EOF.704 while (Tok.isNot(tok::eof))705 ConsumeAnyToken();706 }707 // Make sure this is *our* artificial EOF token.708 if (Tok.getEofData() == MI.Field)709 ConsumeAnyToken();710}711 712void Parser::ParseLexedAttributes(ParsingClass &Class) {713 ReenterClassScopeRAII InClassScope(*this, Class);714 715 for (LateParsedDeclaration *LateD : Class.LateParsedDeclarations)716 LateD->ParseLexedAttributes();717}718 719void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,720 bool EnterScope, bool OnDefinition) {721 assert(LAs.parseSoon() &&722 "Attribute list should be marked for immediate parsing.");723 for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {724 if (D)725 LAs[i]->addDecl(D);726 ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);727 delete LAs[i];728 }729 LAs.clear();730}731 732void Parser::ParseLexedAttribute(LateParsedAttribute &LA,733 bool EnterScope, bool OnDefinition) {734 // Create a fake EOF so that attribute parsing won't go off the end of the735 // attribute.736 Token AttrEnd;737 AttrEnd.startToken();738 AttrEnd.setKind(tok::eof);739 AttrEnd.setLocation(Tok.getLocation());740 AttrEnd.setEofData(LA.Toks.data());741 LA.Toks.push_back(AttrEnd);742 743 // Append the current token at the end of the new token stream so that it744 // doesn't get lost.745 LA.Toks.push_back(Tok);746 PP.EnterTokenStream(LA.Toks, true, /*IsReinject=*/true);747 // Consume the previously pushed token.748 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);749 750 ParsedAttributes Attrs(AttrFactory);751 752 if (LA.Decls.size() > 0) {753 Decl *D = LA.Decls[0];754 NamedDecl *ND = dyn_cast<NamedDecl>(D);755 RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());756 757 // Allow 'this' within late-parsed attributes.758 Sema::CXXThisScopeRAII ThisScope(Actions, RD, Qualifiers(),759 ND && ND->isCXXInstanceMember());760 761 if (LA.Decls.size() == 1) {762 // If the Decl is templatized, add template parameters to scope.763 ReenterTemplateScopeRAII InDeclScope(*this, D, EnterScope);764 765 // If the Decl is on a function, add function parameters to the scope.766 bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate();767 if (HasFunScope) {768 InDeclScope.Scopes.Enter(Scope::FnScope | Scope::DeclScope |769 Scope::CompoundStmtScope);770 Actions.ActOnReenterFunctionContext(Actions.CurScope, D);771 }772 773 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr,774 nullptr, SourceLocation(), ParsedAttr::Form::GNU(),775 nullptr);776 777 if (HasFunScope)778 Actions.ActOnExitFunctionContext();779 } else {780 // If there are multiple decls, then the decl cannot be within the781 // function scope.782 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr,783 nullptr, SourceLocation(), ParsedAttr::Form::GNU(),784 nullptr);785 }786 } else {787 Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();788 }789 790 if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() &&791 Attrs.begin()->isKnownToGCC())792 Diag(Tok, diag::warn_attribute_on_function_definition)793 << &LA.AttrName;794 795 for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i)796 Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs);797 798 // Due to a parsing error, we either went over the cached tokens or799 // there are still cached tokens left, so we skip the leftover tokens.800 while (Tok.isNot(tok::eof))801 ConsumeAnyToken();802 803 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())804 ConsumeAnyToken();805}806 807void Parser::ParseLexedPragmas(ParsingClass &Class) {808 ReenterClassScopeRAII InClassScope(*this, Class);809 810 for (LateParsedDeclaration *D : Class.LateParsedDeclarations)811 D->ParseLexedPragmas();812}813 814void Parser::ParseLexedPragma(LateParsedPragma &LP) {815 PP.EnterToken(Tok, /*IsReinject=*/true);816 PP.EnterTokenStream(LP.toks(), /*DisableMacroExpansion=*/true,817 /*IsReinject=*/true);818 819 // Consume the previously pushed token.820 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);821 assert(Tok.isAnnotation() && "Expected annotation token.");822 switch (Tok.getKind()) {823 case tok::annot_attr_openmp:824 case tok::annot_pragma_openmp: {825 AccessSpecifier AS = LP.getAccessSpecifier();826 ParsedAttributes Attrs(AttrFactory);827 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);828 break;829 }830 default:831 llvm_unreachable("Unexpected token.");832 }833}834 835bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,836 CachedTokens &Toks,837 bool StopAtSemi, bool ConsumeFinalToken) {838 // We always want this function to consume at least one token if the first839 // token isn't T and if not at EOF.840 bool isFirstTokenConsumed = true;841 while (true) {842 // If we found one of the tokens, stop and return true.843 if (Tok.is(T1) || Tok.is(T2)) {844 if (ConsumeFinalToken) {845 Toks.push_back(Tok);846 ConsumeAnyToken();847 }848 return true;849 }850 851 switch (Tok.getKind()) {852 case tok::eof:853 case tok::annot_module_begin:854 case tok::annot_module_end:855 case tok::annot_module_include:856 case tok::annot_repl_input_end:857 // Ran out of tokens.858 return false;859 860 case tok::l_paren:861 // Recursively consume properly-nested parens.862 Toks.push_back(Tok);863 ConsumeParen();864 ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);865 break;866 case tok::l_square:867 // Recursively consume properly-nested square brackets.868 Toks.push_back(Tok);869 ConsumeBracket();870 ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/false);871 break;872 case tok::l_brace:873 // Recursively consume properly-nested braces.874 Toks.push_back(Tok);875 ConsumeBrace();876 ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);877 break;878 879 // Okay, we found a ']' or '}' or ')', which we think should be balanced.880 // Since the user wasn't looking for this token (if they were, it would881 // already be handled), this isn't balanced. If there is a LHS token at a882 // higher level, we will assume that this matches the unbalanced token883 // and return it. Otherwise, this is a spurious RHS token, which we skip.884 case tok::r_paren:885 if (ParenCount && !isFirstTokenConsumed)886 return false; // Matches something.887 Toks.push_back(Tok);888 ConsumeParen();889 break;890 case tok::r_square:891 if (BracketCount && !isFirstTokenConsumed)892 return false; // Matches something.893 Toks.push_back(Tok);894 ConsumeBracket();895 break;896 case tok::r_brace:897 if (BraceCount && !isFirstTokenConsumed)898 return false; // Matches something.899 Toks.push_back(Tok);900 ConsumeBrace();901 break;902 903 case tok::semi:904 if (StopAtSemi)905 return false;906 [[fallthrough]];907 default:908 // consume this token.909 Toks.push_back(Tok);910 ConsumeAnyToken(/*ConsumeCodeCompletionTok*/true);911 break;912 }913 isFirstTokenConsumed = false;914 }915}916 917bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) {918 if (Tok.is(tok::kw_try)) {919 Toks.push_back(Tok);920 ConsumeToken();921 }922 923 if (Tok.isNot(tok::colon)) {924 // Easy case, just a function body.925 926 // Grab any remaining garbage to be diagnosed later. We stop when we reach a927 // brace: an opening one is the function body, while a closing one probably928 // means we've reached the end of the class.929 ConsumeAndStoreUntil(tok::l_brace, tok::r_brace, Toks,930 /*StopAtSemi=*/true,931 /*ConsumeFinalToken=*/false);932 if (Tok.isNot(tok::l_brace))933 return Diag(Tok.getLocation(), diag::err_expected) << tok::l_brace;934 935 Toks.push_back(Tok);936 ConsumeBrace();937 return false;938 }939 940 Toks.push_back(Tok);941 ConsumeToken();942 943 // We can't reliably skip over a mem-initializer-id, because it could be944 // a template-id involving not-yet-declared names. Given:945 //946 // S ( ) : a < b < c > ( e )947 //948 // 'e' might be an initializer or part of a template argument, depending949 // on whether 'b' is a template.950 951 // Track whether we might be inside a template argument. We can give952 // significantly better diagnostics if we know that we're not.953 bool MightBeTemplateArgument = false;954 955 while (true) {956 // Skip over the mem-initializer-id, if possible.957 if (Tok.is(tok::kw_decltype)) {958 Toks.push_back(Tok);959 SourceLocation OpenLoc = ConsumeToken();960 if (Tok.isNot(tok::l_paren))961 return Diag(Tok.getLocation(), diag::err_expected_lparen_after)962 << "decltype";963 Toks.push_back(Tok);964 ConsumeParen();965 if (!ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/true)) {966 Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;967 Diag(OpenLoc, diag::note_matching) << tok::l_paren;968 return true;969 }970 }971 do {972 // Walk over a component of a nested-name-specifier.973 if (Tok.is(tok::coloncolon)) {974 Toks.push_back(Tok);975 ConsumeToken();976 977 if (Tok.is(tok::kw_template)) {978 Toks.push_back(Tok);979 ConsumeToken();980 }981 }982 983 if (Tok.is(tok::identifier)) {984 Toks.push_back(Tok);985 ConsumeToken();986 } else {987 break;988 }989 // Pack indexing990 if (Tok.is(tok::ellipsis) && NextToken().is(tok::l_square)) {991 Toks.push_back(Tok);992 SourceLocation OpenLoc = ConsumeToken();993 Toks.push_back(Tok);994 ConsumeBracket();995 if (!ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/true)) {996 Diag(Tok.getLocation(), diag::err_expected) << tok::r_square;997 Diag(OpenLoc, diag::note_matching) << tok::l_square;998 return true;999 }1000 }1001 1002 } while (Tok.is(tok::coloncolon));1003 1004 if (Tok.is(tok::code_completion)) {1005 Toks.push_back(Tok);1006 ConsumeCodeCompletionToken();1007 if (Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype)) {1008 // Could be the start of another member initializer (the ',' has not1009 // been written yet)1010 continue;1011 }1012 }1013 1014 if (Tok.is(tok::comma)) {1015 // The initialization is missing, we'll diagnose it later.1016 Toks.push_back(Tok);1017 ConsumeToken();1018 continue;1019 }1020 if (Tok.is(tok::less))1021 MightBeTemplateArgument = true;1022 1023 if (MightBeTemplateArgument) {1024 // We may be inside a template argument list. Grab up to the start of the1025 // next parenthesized initializer or braced-init-list. This *might* be the1026 // initializer, or it might be a subexpression in the template argument1027 // list.1028 // FIXME: Count angle brackets, and clear MightBeTemplateArgument1029 // if all angles are closed.1030 if (!ConsumeAndStoreUntil(tok::l_paren, tok::l_brace, Toks,1031 /*StopAtSemi=*/true,1032 /*ConsumeFinalToken=*/false)) {1033 // We're not just missing the initializer, we're also missing the1034 // function body!1035 return Diag(Tok.getLocation(), diag::err_expected) << tok::l_brace;1036 }1037 } else if (Tok.isNot(tok::l_paren) && Tok.isNot(tok::l_brace)) {1038 // We found something weird in a mem-initializer-id.1039 if (getLangOpts().CPlusPlus11)1040 return Diag(Tok.getLocation(), diag::err_expected_either)1041 << tok::l_paren << tok::l_brace;1042 else1043 return Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;1044 }1045 1046 tok::TokenKind kind = Tok.getKind();1047 Toks.push_back(Tok);1048 bool IsLParen = (kind == tok::l_paren);1049 SourceLocation OpenLoc = Tok.getLocation();1050 1051 if (IsLParen) {1052 ConsumeParen();1053 } else {1054 assert(kind == tok::l_brace && "Must be left paren or brace here.");1055 ConsumeBrace();1056 // In C++03, this has to be the start of the function body, which1057 // means the initializer is malformed; we'll diagnose it later.1058 if (!getLangOpts().CPlusPlus11)1059 return false;1060 1061 const Token &PreviousToken = Toks[Toks.size() - 2];1062 if (!MightBeTemplateArgument &&1063 !PreviousToken.isOneOf(tok::identifier, tok::greater,1064 tok::greatergreater)) {1065 // If the opening brace is not preceded by one of these tokens, we are1066 // missing the mem-initializer-id. In order to recover better, we need1067 // to use heuristics to determine if this '{' is most likely the1068 // beginning of a brace-init-list or the function body.1069 // Check the token after the corresponding '}'.1070 TentativeParsingAction PA(*this);1071 if (SkipUntil(tok::r_brace) &&1072 !Tok.isOneOf(tok::comma, tok::ellipsis, tok::l_brace)) {1073 // Consider there was a malformed initializer and this is the start1074 // of the function body. We'll diagnose it later.1075 PA.Revert();1076 return false;1077 }1078 PA.Revert();1079 }1080 }1081 1082 // Grab the initializer (or the subexpression of the template argument).1083 // FIXME: If we support lambdas here, we'll need to set StopAtSemi to false1084 // if we might be inside the braces of a lambda-expression.1085 tok::TokenKind CloseKind = IsLParen ? tok::r_paren : tok::r_brace;1086 if (!ConsumeAndStoreUntil(CloseKind, Toks, /*StopAtSemi=*/true)) {1087 Diag(Tok, diag::err_expected) << CloseKind;1088 Diag(OpenLoc, diag::note_matching) << kind;1089 return true;1090 }1091 1092 // Grab pack ellipsis, if present.1093 if (Tok.is(tok::ellipsis)) {1094 Toks.push_back(Tok);1095 ConsumeToken();1096 }1097 1098 // If we know we just consumed a mem-initializer, we must have ',' or '{'1099 // next.1100 if (Tok.is(tok::comma)) {1101 Toks.push_back(Tok);1102 ConsumeToken();1103 } else if (Tok.is(tok::l_brace)) {1104 // This is the function body if the ')' or '}' is immediately followed by1105 // a '{'. That cannot happen within a template argument, apart from the1106 // case where a template argument contains a compound literal:1107 //1108 // S ( ) : a < b < c > ( d ) { }1109 // // End of declaration, or still inside the template argument?1110 //1111 // ... and the case where the template argument contains a lambda:1112 //1113 // S ( ) : a < 0 && b < c > ( d ) + [ ] ( ) { return 0; }1114 // ( ) > ( ) { }1115 //1116 // FIXME: Disambiguate these cases. Note that the latter case is probably1117 // going to be made ill-formed by core issue 1607.1118 Toks.push_back(Tok);1119 ConsumeBrace();1120 return false;1121 } else if (!MightBeTemplateArgument) {1122 return Diag(Tok.getLocation(), diag::err_expected_either) << tok::l_brace1123 << tok::comma;1124 }1125 }1126}1127 1128bool Parser::ConsumeAndStoreConditional(CachedTokens &Toks) {1129 // Consume '?'.1130 assert(Tok.is(tok::question));1131 Toks.push_back(Tok);1132 ConsumeToken();1133 1134 while (Tok.isNot(tok::colon)) {1135 if (!ConsumeAndStoreUntil(tok::question, tok::colon, Toks,1136 /*StopAtSemi=*/true,1137 /*ConsumeFinalToken=*/false))1138 return false;1139 1140 // If we found a nested conditional, consume it.1141 if (Tok.is(tok::question) && !ConsumeAndStoreConditional(Toks))1142 return false;1143 }1144 1145 // Consume ':'.1146 Toks.push_back(Tok);1147 ConsumeToken();1148 return true;1149}1150 1151bool Parser::ConsumeAndStoreInitializer(CachedTokens &Toks,1152 CachedInitKind CIK) {1153 // We always want this function to consume at least one token if not at EOF.1154 bool IsFirstToken = true;1155 1156 // Number of possible unclosed <s we've seen so far. These might be templates,1157 // and might not, but if there were none of them (or we know for sure that1158 // we're within a template), we can avoid a tentative parse.1159 unsigned AngleCount = 0;1160 unsigned KnownTemplateCount = 0;1161 1162 while (true) {1163 switch (Tok.getKind()) {1164 case tok::ellipsis:1165 // We found an elipsis at the end of the parameter list;1166 // it is not part of a parameter declaration.1167 if (ParenCount == 1 && NextToken().is(tok::r_paren))1168 return true;1169 goto consume_token;1170 case tok::comma:1171 // If we might be in a template, perform a tentative parse to check.1172 if (!AngleCount)1173 // Not a template argument: this is the end of the initializer.1174 return true;1175 if (KnownTemplateCount)1176 goto consume_token;1177 1178 // We hit a comma inside angle brackets. This is the hard case. The1179 // rule we follow is:1180 // * For a default argument, if the tokens after the comma form a1181 // syntactically-valid parameter-declaration-clause, in which each1182 // parameter has an initializer, then this comma ends the default1183 // argument.1184 // * For a default initializer, if the tokens after the comma form a1185 // syntactically-valid init-declarator-list, then this comma ends1186 // the default initializer.1187 {1188 TentativeParsingAction TPA(*this, /*Unannotated=*/true);1189 Sema::TentativeAnalysisScope Scope(Actions);1190 1191 TPResult Result = TPResult::Error;1192 ConsumeToken();1193 switch (CIK) {1194 case CachedInitKind::DefaultInitializer:1195 Result = TryParseInitDeclaratorList();1196 // If we parsed a complete, ambiguous init-declarator-list, this1197 // is only syntactically-valid if it's followed by a semicolon.1198 if (Result == TPResult::Ambiguous && Tok.isNot(tok::semi))1199 Result = TPResult::False;1200 break;1201 1202 case CachedInitKind::DefaultArgument:1203 bool InvalidAsDeclaration = false;1204 Result = TryParseParameterDeclarationClause(1205 &InvalidAsDeclaration, /*VersusTemplateArg=*/true);1206 // If this is an expression or a declaration with a missing1207 // 'typename', assume it's not a declaration.1208 if (Result == TPResult::Ambiguous && InvalidAsDeclaration)1209 Result = TPResult::False;1210 break;1211 }1212 1213 // Put the token stream back and undo any annotations we performed1214 // after the comma. They may reflect a different parse than the one1215 // we will actually perform at the end of the class.1216 TPA.Revert();1217 1218 // If what follows could be a declaration, it is a declaration.1219 if (Result != TPResult::False && Result != TPResult::Error)1220 return true;1221 }1222 1223 // Keep going. We know we're inside a template argument list now.1224 ++KnownTemplateCount;1225 goto consume_token;1226 1227 case tok::eof:1228 // Ran out of tokens.1229 return false;1230 1231 case tok::less:1232 // FIXME: A '<' can only start a template-id if it's preceded by an1233 // identifier, an operator-function-id, or a literal-operator-id.1234 ++AngleCount;1235 goto consume_token;1236 1237 case tok::question:1238 // In 'a ? b : c', 'b' can contain an unparenthesized comma. If it does,1239 // that is *never* the end of the initializer. Skip to the ':'.1240 if (!ConsumeAndStoreConditional(Toks))1241 return false;1242 break;1243 1244 case tok::greatergreatergreater:1245 if (!getLangOpts().CPlusPlus11)1246 goto consume_token;1247 if (AngleCount) --AngleCount;1248 if (KnownTemplateCount) --KnownTemplateCount;1249 [[fallthrough]];1250 case tok::greatergreater:1251 if (!getLangOpts().CPlusPlus11)1252 goto consume_token;1253 if (AngleCount) --AngleCount;1254 if (KnownTemplateCount) --KnownTemplateCount;1255 [[fallthrough]];1256 case tok::greater:1257 if (AngleCount) --AngleCount;1258 if (KnownTemplateCount) --KnownTemplateCount;1259 goto consume_token;1260 1261 case tok::kw_template:1262 // 'template' identifier '<' is known to start a template argument list,1263 // and can be used to disambiguate the parse.1264 // FIXME: Support all forms of 'template' unqualified-id '<'.1265 Toks.push_back(Tok);1266 ConsumeToken();1267 if (Tok.is(tok::identifier)) {1268 Toks.push_back(Tok);1269 ConsumeToken();1270 if (Tok.is(tok::less)) {1271 ++AngleCount;1272 ++KnownTemplateCount;1273 Toks.push_back(Tok);1274 ConsumeToken();1275 }1276 }1277 break;1278 1279 case tok::kw_operator:1280 // If 'operator' precedes other punctuation, that punctuation loses1281 // its special behavior.1282 Toks.push_back(Tok);1283 ConsumeToken();1284 switch (Tok.getKind()) {1285 case tok::comma:1286 case tok::greatergreatergreater:1287 case tok::greatergreater:1288 case tok::greater:1289 case tok::less:1290 Toks.push_back(Tok);1291 ConsumeToken();1292 break;1293 default:1294 break;1295 }1296 break;1297 1298 case tok::l_paren:1299 // Recursively consume properly-nested parens.1300 Toks.push_back(Tok);1301 ConsumeParen();1302 ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);1303 break;1304 case tok::l_square:1305 // Recursively consume properly-nested square brackets.1306 Toks.push_back(Tok);1307 ConsumeBracket();1308 ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/false);1309 break;1310 case tok::l_brace:1311 // Recursively consume properly-nested braces.1312 Toks.push_back(Tok);1313 ConsumeBrace();1314 ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);1315 break;1316 1317 // Okay, we found a ']' or '}' or ')', which we think should be balanced.1318 // Since the user wasn't looking for this token (if they were, it would1319 // already be handled), this isn't balanced. If there is a LHS token at a1320 // higher level, we will assume that this matches the unbalanced token1321 // and return it. Otherwise, this is a spurious RHS token, which we1322 // consume and pass on to downstream code to diagnose.1323 case tok::r_paren:1324 if (CIK == CachedInitKind::DefaultArgument)1325 return true; // End of the default argument.1326 if (ParenCount && !IsFirstToken)1327 return false;1328 Toks.push_back(Tok);1329 ConsumeParen();1330 continue;1331 case tok::r_square:1332 if (BracketCount && !IsFirstToken)1333 return false;1334 Toks.push_back(Tok);1335 ConsumeBracket();1336 continue;1337 case tok::r_brace:1338 if (BraceCount && !IsFirstToken)1339 return false;1340 Toks.push_back(Tok);1341 ConsumeBrace();1342 continue;1343 1344 case tok::code_completion:1345 Toks.push_back(Tok);1346 ConsumeCodeCompletionToken();1347 break;1348 1349 case tok::string_literal:1350 case tok::wide_string_literal:1351 case tok::utf8_string_literal:1352 case tok::utf16_string_literal:1353 case tok::utf32_string_literal:1354 Toks.push_back(Tok);1355 ConsumeStringToken();1356 break;1357 case tok::semi:1358 if (CIK == CachedInitKind::DefaultInitializer)1359 return true; // End of the default initializer.1360 [[fallthrough]];1361 default:1362 consume_token:1363 // If it's an annotation token, then we've run out of tokens and should1364 // bail out. Otherwise, cache the token and consume it.1365 if (Tok.isAnnotation())1366 return false;1367 1368 Toks.push_back(Tok);1369 ConsumeToken();1370 break;1371 }1372 IsFirstToken = false;1373 }1374}1375