Path: blob/main/contrib/llvm-project/clang/lib/Parse/ParseCXXInlineMethods.cpp
35233 views
//===--- ParseCXXInlineMethods.cpp - C++ class inline methods parsing------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements parsing for C++ class inline methods.9//10//===----------------------------------------------------------------------===//1112#include "clang/AST/DeclTemplate.h"13#include "clang/Parse/ParseDiagnostic.h"14#include "clang/Parse/Parser.h"15#include "clang/Parse/RAIIObjectsForParser.h"16#include "clang/Sema/DeclSpec.h"17#include "clang/Sema/EnterExpressionEvaluationContext.h"18#include "clang/Sema/Scope.h"1920using namespace clang;2122/// Parse the optional ("message") part of a deleted-function-body.23StringLiteral *Parser::ParseCXXDeletedFunctionMessage() {24if (!Tok.is(tok::l_paren))25return nullptr;26StringLiteral *Message = nullptr;27BalancedDelimiterTracker BT{*this, tok::l_paren};28BT.consumeOpen();2930if (isTokenStringLiteral()) {31ExprResult Res = ParseUnevaluatedStringLiteralExpression();32if (Res.isUsable()) {33Message = Res.getAs<StringLiteral>();34Diag(Message->getBeginLoc(), getLangOpts().CPlusPlus2635? diag::warn_cxx23_delete_with_message36: diag::ext_delete_with_message)37<< Message->getSourceRange();38}39} else {40Diag(Tok.getLocation(), diag::err_expected_string_literal)41<< /*Source='in'*/ 0 << "'delete'";42SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);43}4445BT.consumeClose();46return Message;47}4849/// If we've encountered '= delete' in a context where it is ill-formed, such50/// as in the declaration of a non-function, also skip the ("message") part if51/// it is present to avoid issuing further diagnostics.52void Parser::SkipDeletedFunctionBody() {53if (!Tok.is(tok::l_paren))54return;5556BalancedDelimiterTracker BT{*this, tok::l_paren};57BT.consumeOpen();5859// Just skip to the end of the current declaration.60SkipUntil(tok::r_paren, tok::comma, StopAtSemi | StopBeforeMatch);61if (Tok.is(tok::r_paren))62BT.consumeClose();63}6465/// ParseCXXInlineMethodDef - We parsed and verified that the specified66/// Declarator is a well formed C++ inline method definition. Now lex its body67/// and store its tokens for parsing after the C++ class is complete.68NamedDecl *Parser::ParseCXXInlineMethodDef(69AccessSpecifier AS, const ParsedAttributesView &AccessAttrs,70ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo,71const VirtSpecifiers &VS, SourceLocation PureSpecLoc) {72assert(D.isFunctionDeclarator() && "This isn't a function declarator!");73assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try, tok::equal) &&74"Current token not a '{', ':', '=', or 'try'!");7576MultiTemplateParamsArg TemplateParams(77TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data()78: nullptr,79TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);8081NamedDecl *FnD;82if (D.getDeclSpec().isFriendSpecified())83FnD = Actions.ActOnFriendFunctionDecl(getCurScope(), D,84TemplateParams);85else {86FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D,87TemplateParams, nullptr,88VS, ICIS_NoInit);89if (FnD) {90Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs);91if (PureSpecLoc.isValid())92Actions.ActOnPureSpecifier(FnD, PureSpecLoc);93}94}9596if (FnD)97HandleMemberFunctionDeclDelays(D, FnD);9899D.complete(FnD);100101if (TryConsumeToken(tok::equal)) {102if (!FnD) {103SkipUntil(tok::semi);104return nullptr;105}106107bool Delete = false;108SourceLocation KWLoc;109SourceLocation KWEndLoc = Tok.getEndLoc().getLocWithOffset(-1);110if (TryConsumeToken(tok::kw_delete, KWLoc)) {111Diag(KWLoc, getLangOpts().CPlusPlus11112? diag::warn_cxx98_compat_defaulted_deleted_function113: diag::ext_defaulted_deleted_function)114<< 1 /* deleted */;115StringLiteral *Message = ParseCXXDeletedFunctionMessage();116Actions.SetDeclDeleted(FnD, KWLoc, Message);117Delete = true;118if (auto *DeclAsFunction = dyn_cast<FunctionDecl>(FnD)) {119DeclAsFunction->setRangeEnd(KWEndLoc);120}121} else if (TryConsumeToken(tok::kw_default, KWLoc)) {122Diag(KWLoc, getLangOpts().CPlusPlus11123? diag::warn_cxx98_compat_defaulted_deleted_function124: diag::ext_defaulted_deleted_function)125<< 0 /* defaulted */;126Actions.SetDeclDefaulted(FnD, KWLoc);127if (auto *DeclAsFunction = dyn_cast<FunctionDecl>(FnD)) {128DeclAsFunction->setRangeEnd(KWEndLoc);129}130} else {131llvm_unreachable("function definition after = not 'delete' or 'default'");132}133134if (Tok.is(tok::comma)) {135Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)136<< Delete;137SkipUntil(tok::semi);138} else if (ExpectAndConsume(tok::semi, diag::err_expected_after,139Delete ? "delete" : "default")) {140SkipUntil(tok::semi);141}142143return FnD;144}145146if (SkipFunctionBodies && (!FnD || Actions.canSkipFunctionBody(FnD)) &&147trySkippingFunctionBody()) {148Actions.ActOnSkippedFunctionBody(FnD);149return FnD;150}151152// In delayed template parsing mode, if we are within a class template153// or if we are about to parse function member template then consume154// the tokens and store them for parsing at the end of the translation unit.155if (getLangOpts().DelayedTemplateParsing &&156D.getFunctionDefinitionKind() == FunctionDefinitionKind::Definition &&157!D.getDeclSpec().hasConstexprSpecifier() &&158!(FnD && FnD->getAsFunction() &&159FnD->getAsFunction()->getReturnType()->getContainedAutoType()) &&160((Actions.CurContext->isDependentContext() ||161(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&162TemplateInfo.Kind != ParsedTemplateInfo::ExplicitSpecialization)) &&163!Actions.IsInsideALocalClassWithinATemplateFunction())) {164165CachedTokens Toks;166LexTemplateFunctionForLateParsing(Toks);167168if (FnD) {169FunctionDecl *FD = FnD->getAsFunction();170Actions.CheckForFunctionRedefinition(FD);171Actions.MarkAsLateParsedTemplate(FD, FnD, Toks);172}173174return FnD;175}176177// Consume the tokens and store them for later parsing.178179LexedMethod* LM = new LexedMethod(this, FnD);180getCurrentClass().LateParsedDeclarations.push_back(LM);181CachedTokens &Toks = LM->Toks;182183tok::TokenKind kind = Tok.getKind();184// Consume everything up to (and including) the left brace of the185// function body.186if (ConsumeAndStoreFunctionPrologue(Toks)) {187// We didn't find the left-brace we expected after the188// constructor initializer.189190// If we're code-completing and the completion point was in the broken191// initializer, we want to parse it even though that will fail.192if (PP.isCodeCompletionEnabled() &&193llvm::any_of(Toks, [](const Token &Tok) {194return Tok.is(tok::code_completion);195})) {196// If we gave up at the completion point, the initializer list was197// likely truncated, so don't eat more tokens. We'll hit some extra198// errors, but they should be ignored in code completion.199return FnD;200}201202// We already printed an error, and it's likely impossible to recover,203// so don't try to parse this method later.204// Skip over the rest of the decl and back to somewhere that looks205// reasonable.206SkipMalformedDecl();207delete getCurrentClass().LateParsedDeclarations.back();208getCurrentClass().LateParsedDeclarations.pop_back();209return FnD;210} else {211// Consume everything up to (and including) the matching right brace.212ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);213}214215// If we're in a function-try-block, we need to store all the catch blocks.216if (kind == tok::kw_try) {217while (Tok.is(tok::kw_catch)) {218ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false);219ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);220}221}222223if (FnD) {224FunctionDecl *FD = FnD->getAsFunction();225// Track that this function will eventually have a body; Sema needs226// to know this.227Actions.CheckForFunctionRedefinition(FD);228FD->setWillHaveBody(true);229} else {230// If semantic analysis could not build a function declaration,231// just throw away the late-parsed declaration.232delete getCurrentClass().LateParsedDeclarations.back();233getCurrentClass().LateParsedDeclarations.pop_back();234}235236return FnD;237}238239/// ParseCXXNonStaticMemberInitializer - We parsed and verified that the240/// specified Declarator is a well formed C++ non-static data member241/// declaration. Now lex its initializer and store its tokens for parsing242/// after the class is complete.243void Parser::ParseCXXNonStaticMemberInitializer(Decl *VarD) {244assert(Tok.isOneOf(tok::l_brace, tok::equal) &&245"Current token not a '{' or '='!");246247LateParsedMemberInitializer *MI =248new LateParsedMemberInitializer(this, VarD);249getCurrentClass().LateParsedDeclarations.push_back(MI);250CachedTokens &Toks = MI->Toks;251252tok::TokenKind kind = Tok.getKind();253if (kind == tok::equal) {254Toks.push_back(Tok);255ConsumeToken();256}257258if (kind == tok::l_brace) {259// Begin by storing the '{' token.260Toks.push_back(Tok);261ConsumeBrace();262263// Consume everything up to (and including) the matching right brace.264ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/true);265} else {266// Consume everything up to (but excluding) the comma or semicolon.267ConsumeAndStoreInitializer(Toks, CIK_DefaultInitializer);268}269270// Store an artificial EOF token to ensure that we don't run off the end of271// the initializer when we come to parse it.272Token Eof;273Eof.startToken();274Eof.setKind(tok::eof);275Eof.setLocation(Tok.getLocation());276Eof.setEofData(VarD);277Toks.push_back(Eof);278}279280Parser::LateParsedDeclaration::~LateParsedDeclaration() {}281void Parser::LateParsedDeclaration::ParseLexedMethodDeclarations() {}282void Parser::LateParsedDeclaration::ParseLexedMemberInitializers() {}283void Parser::LateParsedDeclaration::ParseLexedMethodDefs() {}284void Parser::LateParsedDeclaration::ParseLexedAttributes() {}285void Parser::LateParsedDeclaration::ParseLexedPragmas() {}286287Parser::LateParsedClass::LateParsedClass(Parser *P, ParsingClass *C)288: Self(P), Class(C) {}289290Parser::LateParsedClass::~LateParsedClass() {291Self->DeallocateParsedClasses(Class);292}293294void Parser::LateParsedClass::ParseLexedMethodDeclarations() {295Self->ParseLexedMethodDeclarations(*Class);296}297298void Parser::LateParsedClass::ParseLexedMemberInitializers() {299Self->ParseLexedMemberInitializers(*Class);300}301302void Parser::LateParsedClass::ParseLexedMethodDefs() {303Self->ParseLexedMethodDefs(*Class);304}305306void Parser::LateParsedClass::ParseLexedAttributes() {307Self->ParseLexedAttributes(*Class);308}309310void Parser::LateParsedClass::ParseLexedPragmas() {311Self->ParseLexedPragmas(*Class);312}313314void Parser::LateParsedMethodDeclaration::ParseLexedMethodDeclarations() {315Self->ParseLexedMethodDeclaration(*this);316}317318void Parser::LexedMethod::ParseLexedMethodDefs() {319Self->ParseLexedMethodDef(*this);320}321322void Parser::LateParsedMemberInitializer::ParseLexedMemberInitializers() {323Self->ParseLexedMemberInitializer(*this);324}325326void Parser::LateParsedAttribute::ParseLexedAttributes() {327Self->ParseLexedAttribute(*this, true, false);328}329330void Parser::LateParsedPragma::ParseLexedPragmas() {331Self->ParseLexedPragma(*this);332}333334/// Utility to re-enter a possibly-templated scope while parsing its335/// late-parsed components.336struct Parser::ReenterTemplateScopeRAII {337Parser &P;338MultiParseScope Scopes;339TemplateParameterDepthRAII CurTemplateDepthTracker;340341ReenterTemplateScopeRAII(Parser &P, Decl *MaybeTemplated, bool Enter = true)342: P(P), Scopes(P), CurTemplateDepthTracker(P.TemplateParameterDepth) {343if (Enter) {344CurTemplateDepthTracker.addDepth(345P.ReenterTemplateScopes(Scopes, MaybeTemplated));346}347}348};349350/// Utility to re-enter a class scope while parsing its late-parsed components.351struct Parser::ReenterClassScopeRAII : ReenterTemplateScopeRAII {352ParsingClass &Class;353354ReenterClassScopeRAII(Parser &P, ParsingClass &Class)355: ReenterTemplateScopeRAII(P, Class.TagOrTemplate,356/*Enter=*/!Class.TopLevelClass),357Class(Class) {358// If this is the top-level class, we're still within its scope.359if (Class.TopLevelClass)360return;361362// Re-enter the class scope itself.363Scopes.Enter(Scope::ClassScope|Scope::DeclScope);364P.Actions.ActOnStartDelayedMemberDeclarations(P.getCurScope(),365Class.TagOrTemplate);366}367~ReenterClassScopeRAII() {368if (Class.TopLevelClass)369return;370371P.Actions.ActOnFinishDelayedMemberDeclarations(P.getCurScope(),372Class.TagOrTemplate);373}374};375376/// ParseLexedMethodDeclarations - We finished parsing the member377/// specification of a top (non-nested) C++ class. Now go over the378/// stack of method declarations with some parts for which parsing was379/// delayed (such as default arguments) and parse them.380void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) {381ReenterClassScopeRAII InClassScope(*this, Class);382383for (LateParsedDeclaration *LateD : Class.LateParsedDeclarations)384LateD->ParseLexedMethodDeclarations();385}386387void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {388// If this is a member template, introduce the template parameter scope.389ReenterTemplateScopeRAII InFunctionTemplateScope(*this, LM.Method);390391// Start the delayed C++ method declaration392Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method);393394// Introduce the parameters into scope and parse their default395// arguments.396InFunctionTemplateScope.Scopes.Enter(Scope::FunctionPrototypeScope |397Scope::FunctionDeclarationScope |398Scope::DeclScope);399for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) {400auto Param = cast<ParmVarDecl>(LM.DefaultArgs[I].Param);401// Introduce the parameter into scope.402bool HasUnparsed = Param->hasUnparsedDefaultArg();403Actions.ActOnDelayedCXXMethodParameter(getCurScope(), Param);404std::unique_ptr<CachedTokens> Toks = std::move(LM.DefaultArgs[I].Toks);405if (Toks) {406ParenBraceBracketBalancer BalancerRAIIObj(*this);407408// Mark the end of the default argument so that we know when to stop when409// we parse it later on.410Token LastDefaultArgToken = Toks->back();411Token DefArgEnd;412DefArgEnd.startToken();413DefArgEnd.setKind(tok::eof);414DefArgEnd.setLocation(LastDefaultArgToken.getEndLoc());415DefArgEnd.setEofData(Param);416Toks->push_back(DefArgEnd);417418// Parse the default argument from its saved token stream.419Toks->push_back(Tok); // So that the current token doesn't get lost420PP.EnterTokenStream(*Toks, true, /*IsReinject*/ true);421422// Consume the previously-pushed token.423ConsumeAnyToken();424425// Consume the '='.426assert(Tok.is(tok::equal) && "Default argument not starting with '='");427SourceLocation EqualLoc = ConsumeToken();428429// The argument isn't actually potentially evaluated unless it is430// used.431EnterExpressionEvaluationContext Eval(432Actions,433Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed, Param);434435ExprResult DefArgResult;436if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {437Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);438DefArgResult = ParseBraceInitializer();439} else440DefArgResult = ParseAssignmentExpression();441DefArgResult = Actions.CorrectDelayedTyposInExpr(DefArgResult, Param);442if (DefArgResult.isInvalid()) {443Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,444/*DefaultArg=*/nullptr);445} else {446if (Tok.isNot(tok::eof) || Tok.getEofData() != Param) {447// The last two tokens are the terminator and the saved value of448// Tok; the last token in the default argument is the one before449// those.450assert(Toks->size() >= 3 && "expected a token in default arg");451Diag(Tok.getLocation(), diag::err_default_arg_unparsed)452<< SourceRange(Tok.getLocation(),453(*Toks)[Toks->size() - 3].getLocation());454}455Actions.ActOnParamDefaultArgument(Param, EqualLoc,456DefArgResult.get());457}458459// There could be leftover tokens (e.g. because of an error).460// Skip through until we reach the 'end of default argument' token.461while (Tok.isNot(tok::eof))462ConsumeAnyToken();463464if (Tok.is(tok::eof) && Tok.getEofData() == Param)465ConsumeAnyToken();466} else if (HasUnparsed) {467assert(Param->hasInheritedDefaultArg());468FunctionDecl *Old;469if (const auto *FunTmpl = dyn_cast<FunctionTemplateDecl>(LM.Method))470Old =471cast<FunctionDecl>(FunTmpl->getTemplatedDecl())->getPreviousDecl();472else473Old = cast<FunctionDecl>(LM.Method)->getPreviousDecl();474if (Old) {475ParmVarDecl *OldParam = Old->getParamDecl(I);476assert(!OldParam->hasUnparsedDefaultArg());477if (OldParam->hasUninstantiatedDefaultArg())478Param->setUninstantiatedDefaultArg(479OldParam->getUninstantiatedDefaultArg());480else481Param->setDefaultArg(OldParam->getInit());482}483}484}485486// Parse a delayed exception-specification, if there is one.487if (CachedTokens *Toks = LM.ExceptionSpecTokens) {488ParenBraceBracketBalancer BalancerRAIIObj(*this);489490// Add the 'stop' token.491Token LastExceptionSpecToken = Toks->back();492Token ExceptionSpecEnd;493ExceptionSpecEnd.startToken();494ExceptionSpecEnd.setKind(tok::eof);495ExceptionSpecEnd.setLocation(LastExceptionSpecToken.getEndLoc());496ExceptionSpecEnd.setEofData(LM.Method);497Toks->push_back(ExceptionSpecEnd);498499// Parse the default argument from its saved token stream.500Toks->push_back(Tok); // So that the current token doesn't get lost501PP.EnterTokenStream(*Toks, true, /*IsReinject*/true);502503// Consume the previously-pushed token.504ConsumeAnyToken();505506// C++11 [expr.prim.general]p3:507// If a declaration declares a member function or member function508// template of a class X, the expression this is a prvalue of type509// "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq510// and the end of the function-definition, member-declarator, or511// declarator.512CXXMethodDecl *Method;513FunctionDecl *FunctionToPush;514if (FunctionTemplateDecl *FunTmpl515= dyn_cast<FunctionTemplateDecl>(LM.Method))516FunctionToPush = FunTmpl->getTemplatedDecl();517else518FunctionToPush = cast<FunctionDecl>(LM.Method);519Method = dyn_cast<CXXMethodDecl>(FunctionToPush);520521// Push a function scope so that tryCaptureVariable() can properly visit522// function scopes involving function parameters that are referenced inside523// the noexcept specifier e.g. through a lambda expression.524// Example:525// struct X {526// void ICE(int val) noexcept(noexcept([val]{}));527// };528// Setup the CurScope to match the function DeclContext - we have such529// assumption in IsInFnTryBlockHandler().530ParseScope FnScope(this, Scope::FnScope);531Sema::ContextRAII FnContext(Actions, FunctionToPush,532/*NewThisContext=*/false);533Sema::FunctionScopeRAII PopFnContext(Actions);534Actions.PushFunctionScope();535536Sema::CXXThisScopeRAII ThisScope(537Actions, Method ? Method->getParent() : nullptr,538Method ? Method->getMethodQualifiers() : Qualifiers{},539Method && getLangOpts().CPlusPlus11);540541// Parse the exception-specification.542SourceRange SpecificationRange;543SmallVector<ParsedType, 4> DynamicExceptions;544SmallVector<SourceRange, 4> DynamicExceptionRanges;545ExprResult NoexceptExpr;546CachedTokens *ExceptionSpecTokens;547548ExceptionSpecificationType EST549= tryParseExceptionSpecification(/*Delayed=*/false, SpecificationRange,550DynamicExceptions,551DynamicExceptionRanges, NoexceptExpr,552ExceptionSpecTokens);553554if (Tok.isNot(tok::eof) || Tok.getEofData() != LM.Method)555Diag(Tok.getLocation(), diag::err_except_spec_unparsed);556557// Attach the exception-specification to the method.558Actions.actOnDelayedExceptionSpecification(LM.Method, EST,559SpecificationRange,560DynamicExceptions,561DynamicExceptionRanges,562NoexceptExpr.isUsable()?563NoexceptExpr.get() : nullptr);564565// There could be leftover tokens (e.g. because of an error).566// Skip through until we reach the original token position.567while (Tok.isNot(tok::eof))568ConsumeAnyToken();569570// Clean up the remaining EOF token.571if (Tok.is(tok::eof) && Tok.getEofData() == LM.Method)572ConsumeAnyToken();573574delete Toks;575LM.ExceptionSpecTokens = nullptr;576}577578InFunctionTemplateScope.Scopes.Exit();579580// Finish the delayed C++ method declaration.581Actions.ActOnFinishDelayedCXXMethodDeclaration(getCurScope(), LM.Method);582}583584/// ParseLexedMethodDefs - We finished parsing the member specification of a top585/// (non-nested) C++ class. Now go over the stack of lexed methods that were586/// collected during its parsing and parse them all.587void Parser::ParseLexedMethodDefs(ParsingClass &Class) {588ReenterClassScopeRAII InClassScope(*this, Class);589590for (LateParsedDeclaration *D : Class.LateParsedDeclarations)591D->ParseLexedMethodDefs();592}593594void Parser::ParseLexedMethodDef(LexedMethod &LM) {595// If this is a member template, introduce the template parameter scope.596ReenterTemplateScopeRAII InFunctionTemplateScope(*this, LM.D);597598ParenBraceBracketBalancer BalancerRAIIObj(*this);599600assert(!LM.Toks.empty() && "Empty body!");601Token LastBodyToken = LM.Toks.back();602Token BodyEnd;603BodyEnd.startToken();604BodyEnd.setKind(tok::eof);605BodyEnd.setLocation(LastBodyToken.getEndLoc());606BodyEnd.setEofData(LM.D);607LM.Toks.push_back(BodyEnd);608// Append the current token at the end of the new token stream so that it609// doesn't get lost.610LM.Toks.push_back(Tok);611PP.EnterTokenStream(LM.Toks, true, /*IsReinject*/true);612613// Consume the previously pushed token.614ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);615assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try)616&& "Inline method not starting with '{', ':' or 'try'");617618// Parse the method body. Function body parsing code is similar enough619// to be re-used for method bodies as well.620ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope |621Scope::CompoundStmtScope);622Sema::FPFeaturesStateRAII SaveFPFeatures(Actions);623624Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D);625626if (Tok.is(tok::kw_try)) {627ParseFunctionTryBlock(LM.D, FnScope);628629while (Tok.isNot(tok::eof))630ConsumeAnyToken();631632if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)633ConsumeAnyToken();634return;635}636if (Tok.is(tok::colon)) {637ParseConstructorInitializer(LM.D);638639// Error recovery.640if (!Tok.is(tok::l_brace)) {641FnScope.Exit();642Actions.ActOnFinishFunctionBody(LM.D, nullptr);643644while (Tok.isNot(tok::eof))645ConsumeAnyToken();646647if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)648ConsumeAnyToken();649return;650}651} else652Actions.ActOnDefaultCtorInitializers(LM.D);653654assert((Actions.getDiagnostics().hasErrorOccurred() ||655!isa<FunctionTemplateDecl>(LM.D) ||656cast<FunctionTemplateDecl>(LM.D)->getTemplateParameters()->getDepth()657< TemplateParameterDepth) &&658"TemplateParameterDepth should be greater than the depth of "659"current template being instantiated!");660661ParseFunctionStatementBody(LM.D, FnScope);662663while (Tok.isNot(tok::eof))664ConsumeAnyToken();665666if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)667ConsumeAnyToken();668669if (auto *FD = dyn_cast_or_null<FunctionDecl>(LM.D))670if (isa<CXXMethodDecl>(FD) ||671FD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend))672Actions.ActOnFinishInlineFunctionDef(FD);673}674675/// ParseLexedMemberInitializers - We finished parsing the member specification676/// of a top (non-nested) C++ class. Now go over the stack of lexed data member677/// initializers that were collected during its parsing and parse them all.678void Parser::ParseLexedMemberInitializers(ParsingClass &Class) {679ReenterClassScopeRAII InClassScope(*this, Class);680681if (!Class.LateParsedDeclarations.empty()) {682// C++11 [expr.prim.general]p4:683// Otherwise, if a member-declarator declares a non-static data member684// (9.2) of a class X, the expression this is a prvalue of type "pointer685// to X" within the optional brace-or-equal-initializer. It shall not686// appear elsewhere in the member-declarator.687// FIXME: This should be done in ParseLexedMemberInitializer, not here.688Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate,689Qualifiers());690691for (LateParsedDeclaration *D : Class.LateParsedDeclarations)692D->ParseLexedMemberInitializers();693}694695Actions.ActOnFinishDelayedMemberInitializers(Class.TagOrTemplate);696}697698void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {699if (!MI.Field || MI.Field->isInvalidDecl())700return;701702ParenBraceBracketBalancer BalancerRAIIObj(*this);703704// Append the current token at the end of the new token stream so that it705// doesn't get lost.706MI.Toks.push_back(Tok);707PP.EnterTokenStream(MI.Toks, true, /*IsReinject*/true);708709// Consume the previously pushed token.710ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);711712SourceLocation EqualLoc;713714Actions.ActOnStartCXXInClassMemberInitializer();715716// The initializer isn't actually potentially evaluated unless it is717// used.718EnterExpressionEvaluationContext Eval(719Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed);720721ExprResult Init = ParseCXXMemberInitializer(MI.Field, /*IsFunction=*/false,722EqualLoc);723724Actions.ActOnFinishCXXInClassMemberInitializer(MI.Field, EqualLoc,725Init.get());726727// The next token should be our artificial terminating EOF token.728if (Tok.isNot(tok::eof)) {729if (!Init.isInvalid()) {730SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);731if (!EndLoc.isValid())732EndLoc = Tok.getLocation();733// No fixit; we can't recover as if there were a semicolon here.734Diag(EndLoc, diag::err_expected_semi_decl_list);735}736737// Consume tokens until we hit the artificial EOF.738while (Tok.isNot(tok::eof))739ConsumeAnyToken();740}741// Make sure this is *our* artificial EOF token.742if (Tok.getEofData() == MI.Field)743ConsumeAnyToken();744}745746/// Wrapper class which calls ParseLexedAttribute, after setting up the747/// scope appropriately.748void Parser::ParseLexedAttributes(ParsingClass &Class) {749ReenterClassScopeRAII InClassScope(*this, Class);750751for (LateParsedDeclaration *LateD : Class.LateParsedDeclarations)752LateD->ParseLexedAttributes();753}754755/// Parse all attributes in LAs, and attach them to Decl D.756void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,757bool EnterScope, bool OnDefinition) {758assert(LAs.parseSoon() &&759"Attribute list should be marked for immediate parsing.");760for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {761if (D)762LAs[i]->addDecl(D);763ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);764delete LAs[i];765}766LAs.clear();767}768769/// Finish parsing an attribute for which parsing was delayed.770/// This will be called at the end of parsing a class declaration771/// for each LateParsedAttribute. We consume the saved tokens and772/// create an attribute with the arguments filled in. We add this773/// to the Attribute list for the decl.774void Parser::ParseLexedAttribute(LateParsedAttribute &LA,775bool EnterScope, bool OnDefinition) {776// Create a fake EOF so that attribute parsing won't go off the end of the777// attribute.778Token AttrEnd;779AttrEnd.startToken();780AttrEnd.setKind(tok::eof);781AttrEnd.setLocation(Tok.getLocation());782AttrEnd.setEofData(LA.Toks.data());783LA.Toks.push_back(AttrEnd);784785// Append the current token at the end of the new token stream so that it786// doesn't get lost.787LA.Toks.push_back(Tok);788PP.EnterTokenStream(LA.Toks, true, /*IsReinject=*/true);789// Consume the previously pushed token.790ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);791792ParsedAttributes Attrs(AttrFactory);793794if (LA.Decls.size() > 0) {795Decl *D = LA.Decls[0];796NamedDecl *ND = dyn_cast<NamedDecl>(D);797RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());798799// Allow 'this' within late-parsed attributes.800Sema::CXXThisScopeRAII ThisScope(Actions, RD, Qualifiers(),801ND && ND->isCXXInstanceMember());802803if (LA.Decls.size() == 1) {804// If the Decl is templatized, add template parameters to scope.805ReenterTemplateScopeRAII InDeclScope(*this, D, EnterScope);806807// If the Decl is on a function, add function parameters to the scope.808bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate();809if (HasFunScope) {810InDeclScope.Scopes.Enter(Scope::FnScope | Scope::DeclScope |811Scope::CompoundStmtScope);812Actions.ActOnReenterFunctionContext(Actions.CurScope, D);813}814815ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr,816nullptr, SourceLocation(), ParsedAttr::Form::GNU(),817nullptr);818819if (HasFunScope)820Actions.ActOnExitFunctionContext();821} else {822// If there are multiple decls, then the decl cannot be within the823// function scope.824ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr,825nullptr, SourceLocation(), ParsedAttr::Form::GNU(),826nullptr);827}828} else {829Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();830}831832if (OnDefinition && !Attrs.empty() && !Attrs.begin()->isCXX11Attribute() &&833Attrs.begin()->isKnownToGCC())834Diag(Tok, diag::warn_attribute_on_function_definition)835<< &LA.AttrName;836837for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i)838Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs);839840// Due to a parsing error, we either went over the cached tokens or841// there are still cached tokens left, so we skip the leftover tokens.842while (Tok.isNot(tok::eof))843ConsumeAnyToken();844845if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())846ConsumeAnyToken();847}848849void Parser::ParseLexedPragmas(ParsingClass &Class) {850ReenterClassScopeRAII InClassScope(*this, Class);851852for (LateParsedDeclaration *D : Class.LateParsedDeclarations)853D->ParseLexedPragmas();854}855856void Parser::ParseLexedPragma(LateParsedPragma &LP) {857PP.EnterToken(Tok, /*IsReinject=*/true);858PP.EnterTokenStream(LP.toks(), /*DisableMacroExpansion=*/true,859/*IsReinject=*/true);860861// Consume the previously pushed token.862ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);863assert(Tok.isAnnotation() && "Expected annotation token.");864switch (Tok.getKind()) {865case tok::annot_attr_openmp:866case tok::annot_pragma_openmp: {867AccessSpecifier AS = LP.getAccessSpecifier();868ParsedAttributes Attrs(AttrFactory);869(void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);870break;871}872default:873llvm_unreachable("Unexpected token.");874}875}876877/// ConsumeAndStoreUntil - Consume and store the token at the passed token878/// container until the token 'T' is reached (which gets879/// consumed/stored too, if ConsumeFinalToken).880/// If StopAtSemi is true, then we will stop early at a ';' character.881/// Returns true if token 'T1' or 'T2' was found.882/// NOTE: This is a specialized version of Parser::SkipUntil.883bool Parser::ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,884CachedTokens &Toks,885bool StopAtSemi, bool ConsumeFinalToken) {886// We always want this function to consume at least one token if the first887// token isn't T and if not at EOF.888bool isFirstTokenConsumed = true;889while (true) {890// If we found one of the tokens, stop and return true.891if (Tok.is(T1) || Tok.is(T2)) {892if (ConsumeFinalToken) {893Toks.push_back(Tok);894ConsumeAnyToken();895}896return true;897}898899switch (Tok.getKind()) {900case tok::eof:901case tok::annot_module_begin:902case tok::annot_module_end:903case tok::annot_module_include:904case tok::annot_repl_input_end:905// Ran out of tokens.906return false;907908case tok::l_paren:909// Recursively consume properly-nested parens.910Toks.push_back(Tok);911ConsumeParen();912ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);913break;914case tok::l_square:915// Recursively consume properly-nested square brackets.916Toks.push_back(Tok);917ConsumeBracket();918ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/false);919break;920case tok::l_brace:921// Recursively consume properly-nested braces.922Toks.push_back(Tok);923ConsumeBrace();924ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);925break;926927// Okay, we found a ']' or '}' or ')', which we think should be balanced.928// Since the user wasn't looking for this token (if they were, it would929// already be handled), this isn't balanced. If there is a LHS token at a930// higher level, we will assume that this matches the unbalanced token931// and return it. Otherwise, this is a spurious RHS token, which we skip.932case tok::r_paren:933if (ParenCount && !isFirstTokenConsumed)934return false; // Matches something.935Toks.push_back(Tok);936ConsumeParen();937break;938case tok::r_square:939if (BracketCount && !isFirstTokenConsumed)940return false; // Matches something.941Toks.push_back(Tok);942ConsumeBracket();943break;944case tok::r_brace:945if (BraceCount && !isFirstTokenConsumed)946return false; // Matches something.947Toks.push_back(Tok);948ConsumeBrace();949break;950951case tok::semi:952if (StopAtSemi)953return false;954[[fallthrough]];955default:956// consume this token.957Toks.push_back(Tok);958ConsumeAnyToken(/*ConsumeCodeCompletionTok*/true);959break;960}961isFirstTokenConsumed = false;962}963}964965/// Consume tokens and store them in the passed token container until966/// we've passed the try keyword and constructor initializers and have consumed967/// the opening brace of the function body. The opening brace will be consumed968/// if and only if there was no error.969///970/// \return True on error.971bool Parser::ConsumeAndStoreFunctionPrologue(CachedTokens &Toks) {972if (Tok.is(tok::kw_try)) {973Toks.push_back(Tok);974ConsumeToken();975}976977if (Tok.isNot(tok::colon)) {978// Easy case, just a function body.979980// Grab any remaining garbage to be diagnosed later. We stop when we reach a981// brace: an opening one is the function body, while a closing one probably982// means we've reached the end of the class.983ConsumeAndStoreUntil(tok::l_brace, tok::r_brace, Toks,984/*StopAtSemi=*/true,985/*ConsumeFinalToken=*/false);986if (Tok.isNot(tok::l_brace))987return Diag(Tok.getLocation(), diag::err_expected) << tok::l_brace;988989Toks.push_back(Tok);990ConsumeBrace();991return false;992}993994Toks.push_back(Tok);995ConsumeToken();996997// We can't reliably skip over a mem-initializer-id, because it could be998// a template-id involving not-yet-declared names. Given:999//1000// S ( ) : a < b < c > ( e )1001//1002// 'e' might be an initializer or part of a template argument, depending1003// on whether 'b' is a template.10041005// Track whether we might be inside a template argument. We can give1006// significantly better diagnostics if we know that we're not.1007bool MightBeTemplateArgument = false;10081009while (true) {1010// Skip over the mem-initializer-id, if possible.1011if (Tok.is(tok::kw_decltype)) {1012Toks.push_back(Tok);1013SourceLocation OpenLoc = ConsumeToken();1014if (Tok.isNot(tok::l_paren))1015return Diag(Tok.getLocation(), diag::err_expected_lparen_after)1016<< "decltype";1017Toks.push_back(Tok);1018ConsumeParen();1019if (!ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/true)) {1020Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;1021Diag(OpenLoc, diag::note_matching) << tok::l_paren;1022return true;1023}1024}1025do {1026// Walk over a component of a nested-name-specifier.1027if (Tok.is(tok::coloncolon)) {1028Toks.push_back(Tok);1029ConsumeToken();10301031if (Tok.is(tok::kw_template)) {1032Toks.push_back(Tok);1033ConsumeToken();1034}1035}10361037if (Tok.is(tok::identifier)) {1038Toks.push_back(Tok);1039ConsumeToken();1040} else {1041break;1042}1043// Pack indexing1044if (Tok.is(tok::ellipsis) && NextToken().is(tok::l_square)) {1045Toks.push_back(Tok);1046SourceLocation OpenLoc = ConsumeToken();1047Toks.push_back(Tok);1048ConsumeBracket();1049if (!ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/true)) {1050Diag(Tok.getLocation(), diag::err_expected) << tok::r_square;1051Diag(OpenLoc, diag::note_matching) << tok::l_square;1052return true;1053}1054}10551056} while (Tok.is(tok::coloncolon));10571058if (Tok.is(tok::code_completion)) {1059Toks.push_back(Tok);1060ConsumeCodeCompletionToken();1061if (Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype)) {1062// Could be the start of another member initializer (the ',' has not1063// been written yet)1064continue;1065}1066}10671068if (Tok.is(tok::comma)) {1069// The initialization is missing, we'll diagnose it later.1070Toks.push_back(Tok);1071ConsumeToken();1072continue;1073}1074if (Tok.is(tok::less))1075MightBeTemplateArgument = true;10761077if (MightBeTemplateArgument) {1078// We may be inside a template argument list. Grab up to the start of the1079// next parenthesized initializer or braced-init-list. This *might* be the1080// initializer, or it might be a subexpression in the template argument1081// list.1082// FIXME: Count angle brackets, and clear MightBeTemplateArgument1083// if all angles are closed.1084if (!ConsumeAndStoreUntil(tok::l_paren, tok::l_brace, Toks,1085/*StopAtSemi=*/true,1086/*ConsumeFinalToken=*/false)) {1087// We're not just missing the initializer, we're also missing the1088// function body!1089return Diag(Tok.getLocation(), diag::err_expected) << tok::l_brace;1090}1091} else if (Tok.isNot(tok::l_paren) && Tok.isNot(tok::l_brace)) {1092// We found something weird in a mem-initializer-id.1093if (getLangOpts().CPlusPlus11)1094return Diag(Tok.getLocation(), diag::err_expected_either)1095<< tok::l_paren << tok::l_brace;1096else1097return Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;1098}10991100tok::TokenKind kind = Tok.getKind();1101Toks.push_back(Tok);1102bool IsLParen = (kind == tok::l_paren);1103SourceLocation OpenLoc = Tok.getLocation();11041105if (IsLParen) {1106ConsumeParen();1107} else {1108assert(kind == tok::l_brace && "Must be left paren or brace here.");1109ConsumeBrace();1110// In C++03, this has to be the start of the function body, which1111// means the initializer is malformed; we'll diagnose it later.1112if (!getLangOpts().CPlusPlus11)1113return false;11141115const Token &PreviousToken = Toks[Toks.size() - 2];1116if (!MightBeTemplateArgument &&1117!PreviousToken.isOneOf(tok::identifier, tok::greater,1118tok::greatergreater)) {1119// If the opening brace is not preceded by one of these tokens, we are1120// missing the mem-initializer-id. In order to recover better, we need1121// to use heuristics to determine if this '{' is most likely the1122// beginning of a brace-init-list or the function body.1123// Check the token after the corresponding '}'.1124TentativeParsingAction PA(*this);1125if (SkipUntil(tok::r_brace) &&1126!Tok.isOneOf(tok::comma, tok::ellipsis, tok::l_brace)) {1127// Consider there was a malformed initializer and this is the start1128// of the function body. We'll diagnose it later.1129PA.Revert();1130return false;1131}1132PA.Revert();1133}1134}11351136// Grab the initializer (or the subexpression of the template argument).1137// FIXME: If we support lambdas here, we'll need to set StopAtSemi to false1138// if we might be inside the braces of a lambda-expression.1139tok::TokenKind CloseKind = IsLParen ? tok::r_paren : tok::r_brace;1140if (!ConsumeAndStoreUntil(CloseKind, Toks, /*StopAtSemi=*/true)) {1141Diag(Tok, diag::err_expected) << CloseKind;1142Diag(OpenLoc, diag::note_matching) << kind;1143return true;1144}11451146// Grab pack ellipsis, if present.1147if (Tok.is(tok::ellipsis)) {1148Toks.push_back(Tok);1149ConsumeToken();1150}11511152// If we know we just consumed a mem-initializer, we must have ',' or '{'1153// next.1154if (Tok.is(tok::comma)) {1155Toks.push_back(Tok);1156ConsumeToken();1157} else if (Tok.is(tok::l_brace)) {1158// This is the function body if the ')' or '}' is immediately followed by1159// a '{'. That cannot happen within a template argument, apart from the1160// case where a template argument contains a compound literal:1161//1162// S ( ) : a < b < c > ( d ) { }1163// // End of declaration, or still inside the template argument?1164//1165// ... and the case where the template argument contains a lambda:1166//1167// S ( ) : a < 0 && b < c > ( d ) + [ ] ( ) { return 0; }1168// ( ) > ( ) { }1169//1170// FIXME: Disambiguate these cases. Note that the latter case is probably1171// going to be made ill-formed by core issue 1607.1172Toks.push_back(Tok);1173ConsumeBrace();1174return false;1175} else if (!MightBeTemplateArgument) {1176return Diag(Tok.getLocation(), diag::err_expected_either) << tok::l_brace1177<< tok::comma;1178}1179}1180}11811182/// Consume and store tokens from the '?' to the ':' in a conditional1183/// expression.1184bool Parser::ConsumeAndStoreConditional(CachedTokens &Toks) {1185// Consume '?'.1186assert(Tok.is(tok::question));1187Toks.push_back(Tok);1188ConsumeToken();11891190while (Tok.isNot(tok::colon)) {1191if (!ConsumeAndStoreUntil(tok::question, tok::colon, Toks,1192/*StopAtSemi=*/true,1193/*ConsumeFinalToken=*/false))1194return false;11951196// If we found a nested conditional, consume it.1197if (Tok.is(tok::question) && !ConsumeAndStoreConditional(Toks))1198return false;1199}12001201// Consume ':'.1202Toks.push_back(Tok);1203ConsumeToken();1204return true;1205}12061207/// A tentative parsing action that can also revert token annotations.1208class Parser::UnannotatedTentativeParsingAction : public TentativeParsingAction {1209public:1210explicit UnannotatedTentativeParsingAction(Parser &Self,1211tok::TokenKind EndKind)1212: TentativeParsingAction(Self), Self(Self), EndKind(EndKind) {1213// Stash away the old token stream, so we can restore it once the1214// tentative parse is complete.1215TentativeParsingAction Inner(Self);1216Self.ConsumeAndStoreUntil(EndKind, Toks, true, /*ConsumeFinalToken*/false);1217Inner.Revert();1218}12191220void RevertAnnotations() {1221Revert();12221223// Put back the original tokens.1224Self.SkipUntil(EndKind, StopAtSemi | StopBeforeMatch);1225if (Toks.size()) {1226auto Buffer = std::make_unique<Token[]>(Toks.size());1227std::copy(Toks.begin() + 1, Toks.end(), Buffer.get());1228Buffer[Toks.size() - 1] = Self.Tok;1229Self.PP.EnterTokenStream(std::move(Buffer), Toks.size(), true,1230/*IsReinject*/ true);12311232Self.Tok = Toks.front();1233}1234}12351236private:1237Parser &Self;1238CachedTokens Toks;1239tok::TokenKind EndKind;1240};12411242/// ConsumeAndStoreInitializer - Consume and store the token at the passed token1243/// container until the end of the current initializer expression (either a1244/// default argument or an in-class initializer for a non-static data member).1245///1246/// Returns \c true if we reached the end of something initializer-shaped,1247/// \c false if we bailed out.1248bool Parser::ConsumeAndStoreInitializer(CachedTokens &Toks,1249CachedInitKind CIK) {1250// We always want this function to consume at least one token if not at EOF.1251bool IsFirstToken = true;12521253// Number of possible unclosed <s we've seen so far. These might be templates,1254// and might not, but if there were none of them (or we know for sure that1255// we're within a template), we can avoid a tentative parse.1256unsigned AngleCount = 0;1257unsigned KnownTemplateCount = 0;12581259while (true) {1260switch (Tok.getKind()) {1261case tok::comma:1262// If we might be in a template, perform a tentative parse to check.1263if (!AngleCount)1264// Not a template argument: this is the end of the initializer.1265return true;1266if (KnownTemplateCount)1267goto consume_token;12681269// We hit a comma inside angle brackets. This is the hard case. The1270// rule we follow is:1271// * For a default argument, if the tokens after the comma form a1272// syntactically-valid parameter-declaration-clause, in which each1273// parameter has an initializer, then this comma ends the default1274// argument.1275// * For a default initializer, if the tokens after the comma form a1276// syntactically-valid init-declarator-list, then this comma ends1277// the default initializer.1278{1279UnannotatedTentativeParsingAction PA(*this,1280CIK == CIK_DefaultInitializer1281? tok::semi : tok::r_paren);1282Sema::TentativeAnalysisScope Scope(Actions);12831284TPResult Result = TPResult::Error;1285ConsumeToken();1286switch (CIK) {1287case CIK_DefaultInitializer:1288Result = TryParseInitDeclaratorList();1289// If we parsed a complete, ambiguous init-declarator-list, this1290// is only syntactically-valid if it's followed by a semicolon.1291if (Result == TPResult::Ambiguous && Tok.isNot(tok::semi))1292Result = TPResult::False;1293break;12941295case CIK_DefaultArgument:1296bool InvalidAsDeclaration = false;1297Result = TryParseParameterDeclarationClause(1298&InvalidAsDeclaration, /*VersusTemplateArg=*/true);1299// If this is an expression or a declaration with a missing1300// 'typename', assume it's not a declaration.1301if (Result == TPResult::Ambiguous && InvalidAsDeclaration)1302Result = TPResult::False;1303break;1304}13051306// Put the token stream back and undo any annotations we performed1307// after the comma. They may reflect a different parse than the one1308// we will actually perform at the end of the class.1309PA.RevertAnnotations();13101311// If what follows could be a declaration, it is a declaration.1312if (Result != TPResult::False && Result != TPResult::Error)1313return true;1314}13151316// Keep going. We know we're inside a template argument list now.1317++KnownTemplateCount;1318goto consume_token;13191320case tok::eof:1321case tok::annot_module_begin:1322case tok::annot_module_end:1323case tok::annot_module_include:1324case tok::annot_repl_input_end:1325// Ran out of tokens.1326return false;13271328case tok::less:1329// FIXME: A '<' can only start a template-id if it's preceded by an1330// identifier, an operator-function-id, or a literal-operator-id.1331++AngleCount;1332goto consume_token;13331334case tok::question:1335// In 'a ? b : c', 'b' can contain an unparenthesized comma. If it does,1336// that is *never* the end of the initializer. Skip to the ':'.1337if (!ConsumeAndStoreConditional(Toks))1338return false;1339break;13401341case tok::greatergreatergreater:1342if (!getLangOpts().CPlusPlus11)1343goto consume_token;1344if (AngleCount) --AngleCount;1345if (KnownTemplateCount) --KnownTemplateCount;1346[[fallthrough]];1347case tok::greatergreater:1348if (!getLangOpts().CPlusPlus11)1349goto consume_token;1350if (AngleCount) --AngleCount;1351if (KnownTemplateCount) --KnownTemplateCount;1352[[fallthrough]];1353case tok::greater:1354if (AngleCount) --AngleCount;1355if (KnownTemplateCount) --KnownTemplateCount;1356goto consume_token;13571358case tok::kw_template:1359// 'template' identifier '<' is known to start a template argument list,1360// and can be used to disambiguate the parse.1361// FIXME: Support all forms of 'template' unqualified-id '<'.1362Toks.push_back(Tok);1363ConsumeToken();1364if (Tok.is(tok::identifier)) {1365Toks.push_back(Tok);1366ConsumeToken();1367if (Tok.is(tok::less)) {1368++AngleCount;1369++KnownTemplateCount;1370Toks.push_back(Tok);1371ConsumeToken();1372}1373}1374break;13751376case tok::kw_operator:1377// If 'operator' precedes other punctuation, that punctuation loses1378// its special behavior.1379Toks.push_back(Tok);1380ConsumeToken();1381switch (Tok.getKind()) {1382case tok::comma:1383case tok::greatergreatergreater:1384case tok::greatergreater:1385case tok::greater:1386case tok::less:1387Toks.push_back(Tok);1388ConsumeToken();1389break;1390default:1391break;1392}1393break;13941395case tok::l_paren:1396// Recursively consume properly-nested parens.1397Toks.push_back(Tok);1398ConsumeParen();1399ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);1400break;1401case tok::l_square:1402// Recursively consume properly-nested square brackets.1403Toks.push_back(Tok);1404ConsumeBracket();1405ConsumeAndStoreUntil(tok::r_square, Toks, /*StopAtSemi=*/false);1406break;1407case tok::l_brace:1408// Recursively consume properly-nested braces.1409Toks.push_back(Tok);1410ConsumeBrace();1411ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);1412break;14131414// Okay, we found a ']' or '}' or ')', which we think should be balanced.1415// Since the user wasn't looking for this token (if they were, it would1416// already be handled), this isn't balanced. If there is a LHS token at a1417// higher level, we will assume that this matches the unbalanced token1418// and return it. Otherwise, this is a spurious RHS token, which we1419// consume and pass on to downstream code to diagnose.1420case tok::r_paren:1421if (CIK == CIK_DefaultArgument)1422return true; // End of the default argument.1423if (ParenCount && !IsFirstToken)1424return false;1425Toks.push_back(Tok);1426ConsumeParen();1427continue;1428case tok::r_square:1429if (BracketCount && !IsFirstToken)1430return false;1431Toks.push_back(Tok);1432ConsumeBracket();1433continue;1434case tok::r_brace:1435if (BraceCount && !IsFirstToken)1436return false;1437Toks.push_back(Tok);1438ConsumeBrace();1439continue;14401441case tok::code_completion:1442Toks.push_back(Tok);1443ConsumeCodeCompletionToken();1444break;14451446case tok::string_literal:1447case tok::wide_string_literal:1448case tok::utf8_string_literal:1449case tok::utf16_string_literal:1450case tok::utf32_string_literal:1451Toks.push_back(Tok);1452ConsumeStringToken();1453break;1454case tok::semi:1455if (CIK == CIK_DefaultInitializer)1456return true; // End of the default initializer.1457[[fallthrough]];1458default:1459consume_token:1460Toks.push_back(Tok);1461ConsumeToken();1462break;1463}1464IsFirstToken = false;1465}1466}146714681469