Path: blob/main/contrib/llvm-project/clang/lib/Parse/ParseExprCXX.cpp
35233 views
//===--- ParseExprCXX.cpp - C++ Expression 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 the Expression parsing implementation for C++.9//10//===----------------------------------------------------------------------===//11#include "clang/AST/ASTContext.h"12#include "clang/AST/Decl.h"13#include "clang/AST/DeclTemplate.h"14#include "clang/AST/ExprCXX.h"15#include "clang/Basic/PrettyStackTrace.h"16#include "clang/Basic/TemplateKinds.h"17#include "clang/Basic/TokenKinds.h"18#include "clang/Lex/LiteralSupport.h"19#include "clang/Parse/ParseDiagnostic.h"20#include "clang/Parse/Parser.h"21#include "clang/Parse/RAIIObjectsForParser.h"22#include "clang/Sema/DeclSpec.h"23#include "clang/Sema/EnterExpressionEvaluationContext.h"24#include "clang/Sema/ParsedTemplate.h"25#include "clang/Sema/Scope.h"26#include "clang/Sema/SemaCodeCompletion.h"27#include "llvm/Support/Compiler.h"28#include "llvm/Support/ErrorHandling.h"29#include <numeric>3031using namespace clang;3233static int SelectDigraphErrorMessage(tok::TokenKind Kind) {34switch (Kind) {35// template name36case tok::unknown: return 0;37// casts38case tok::kw_addrspace_cast: return 1;39case tok::kw_const_cast: return 2;40case tok::kw_dynamic_cast: return 3;41case tok::kw_reinterpret_cast: return 4;42case tok::kw_static_cast: return 5;43default:44llvm_unreachable("Unknown type for digraph error message.");45}46}4748// Are the two tokens adjacent in the same source file?49bool Parser::areTokensAdjacent(const Token &First, const Token &Second) {50SourceManager &SM = PP.getSourceManager();51SourceLocation FirstLoc = SM.getSpellingLoc(First.getLocation());52SourceLocation FirstEnd = FirstLoc.getLocWithOffset(First.getLength());53return FirstEnd == SM.getSpellingLoc(Second.getLocation());54}5556// Suggest fixit for "<::" after a cast.57static void FixDigraph(Parser &P, Preprocessor &PP, Token &DigraphToken,58Token &ColonToken, tok::TokenKind Kind, bool AtDigraph) {59// Pull '<:' and ':' off token stream.60if (!AtDigraph)61PP.Lex(DigraphToken);62PP.Lex(ColonToken);6364SourceRange Range;65Range.setBegin(DigraphToken.getLocation());66Range.setEnd(ColonToken.getLocation());67P.Diag(DigraphToken.getLocation(), diag::err_missing_whitespace_digraph)68<< SelectDigraphErrorMessage(Kind)69<< FixItHint::CreateReplacement(Range, "< ::");7071// Update token information to reflect their change in token type.72ColonToken.setKind(tok::coloncolon);73ColonToken.setLocation(ColonToken.getLocation().getLocWithOffset(-1));74ColonToken.setLength(2);75DigraphToken.setKind(tok::less);76DigraphToken.setLength(1);7778// Push new tokens back to token stream.79PP.EnterToken(ColonToken, /*IsReinject*/ true);80if (!AtDigraph)81PP.EnterToken(DigraphToken, /*IsReinject*/ true);82}8384// Check for '<::' which should be '< ::' instead of '[:' when following85// a template name.86void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType,87bool EnteringContext,88IdentifierInfo &II, CXXScopeSpec &SS) {89if (!Next.is(tok::l_square) || Next.getLength() != 2)90return;9192Token SecondToken = GetLookAheadToken(2);93if (!SecondToken.is(tok::colon) || !areTokensAdjacent(Next, SecondToken))94return;9596TemplateTy Template;97UnqualifiedId TemplateName;98TemplateName.setIdentifier(&II, Tok.getLocation());99bool MemberOfUnknownSpecialization;100if (!Actions.isTemplateName(getCurScope(), SS, /*hasTemplateKeyword=*/false,101TemplateName, ObjectType, EnteringContext,102Template, MemberOfUnknownSpecialization))103return;104105FixDigraph(*this, PP, Next, SecondToken, tok::unknown,106/*AtDigraph*/false);107}108109/// Parse global scope or nested-name-specifier if present.110///111/// Parses a C++ global scope specifier ('::') or nested-name-specifier (which112/// may be preceded by '::'). Note that this routine will not parse ::new or113/// ::delete; it will just leave them in the token stream.114///115/// '::'[opt] nested-name-specifier116/// '::'117///118/// nested-name-specifier:119/// type-name '::'120/// namespace-name '::'121/// nested-name-specifier identifier '::'122/// nested-name-specifier 'template'[opt] simple-template-id '::'123///124///125/// \param SS the scope specifier that will be set to the parsed126/// nested-name-specifier (or empty)127///128/// \param ObjectType if this nested-name-specifier is being parsed following129/// the "." or "->" of a member access expression, this parameter provides the130/// type of the object whose members are being accessed.131///132/// \param ObjectHadErrors if this unqualified-id occurs within a member access133/// expression, indicates whether the original subexpressions had any errors.134/// When true, diagnostics for missing 'template' keyword will be supressed.135///136/// \param EnteringContext whether we will be entering into the context of137/// the nested-name-specifier after parsing it.138///139/// \param MayBePseudoDestructor When non-NULL, points to a flag that140/// indicates whether this nested-name-specifier may be part of a141/// pseudo-destructor name. In this case, the flag will be set false142/// if we don't actually end up parsing a destructor name. Moreover,143/// if we do end up determining that we are parsing a destructor name,144/// the last component of the nested-name-specifier is not parsed as145/// part of the scope specifier.146///147/// \param IsTypename If \c true, this nested-name-specifier is known to be148/// part of a type name. This is used to improve error recovery.149///150/// \param LastII When non-NULL, points to an IdentifierInfo* that will be151/// filled in with the leading identifier in the last component of the152/// nested-name-specifier, if any.153///154/// \param OnlyNamespace If true, only considers namespaces in lookup.155///156///157/// \returns true if there was an error parsing a scope specifier158bool Parser::ParseOptionalCXXScopeSpecifier(159CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors,160bool EnteringContext, bool *MayBePseudoDestructor, bool IsTypename,161const IdentifierInfo **LastII, bool OnlyNamespace,162bool InUsingDeclaration) {163assert(getLangOpts().CPlusPlus &&164"Call sites of this function should be guarded by checking for C++");165166if (Tok.is(tok::annot_cxxscope)) {167assert(!LastII && "want last identifier but have already annotated scope");168assert(!MayBePseudoDestructor && "unexpected annot_cxxscope");169Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),170Tok.getAnnotationRange(),171SS);172ConsumeAnnotationToken();173return false;174}175176// Has to happen before any "return false"s in this function.177bool CheckForDestructor = false;178if (MayBePseudoDestructor && *MayBePseudoDestructor) {179CheckForDestructor = true;180*MayBePseudoDestructor = false;181}182183if (LastII)184*LastII = nullptr;185186bool HasScopeSpecifier = false;187188if (Tok.is(tok::coloncolon)) {189// ::new and ::delete aren't nested-name-specifiers.190tok::TokenKind NextKind = NextToken().getKind();191if (NextKind == tok::kw_new || NextKind == tok::kw_delete)192return false;193194if (NextKind == tok::l_brace) {195// It is invalid to have :: {, consume the scope qualifier and pretend196// like we never saw it.197Diag(ConsumeToken(), diag::err_expected) << tok::identifier;198} else {199// '::' - Global scope qualifier.200if (Actions.ActOnCXXGlobalScopeSpecifier(ConsumeToken(), SS))201return true;202203HasScopeSpecifier = true;204}205}206207if (Tok.is(tok::kw___super)) {208SourceLocation SuperLoc = ConsumeToken();209if (!Tok.is(tok::coloncolon)) {210Diag(Tok.getLocation(), diag::err_expected_coloncolon_after_super);211return true;212}213214return Actions.ActOnSuperScopeSpecifier(SuperLoc, ConsumeToken(), SS);215}216217if (!HasScopeSpecifier &&218Tok.isOneOf(tok::kw_decltype, tok::annot_decltype)) {219DeclSpec DS(AttrFactory);220SourceLocation DeclLoc = Tok.getLocation();221SourceLocation EndLoc = ParseDecltypeSpecifier(DS);222223SourceLocation CCLoc;224// Work around a standard defect: 'decltype(auto)::' is not a225// nested-name-specifier.226if (DS.getTypeSpecType() == DeclSpec::TST_decltype_auto ||227!TryConsumeToken(tok::coloncolon, CCLoc)) {228AnnotateExistingDecltypeSpecifier(DS, DeclLoc, EndLoc);229return false;230}231232if (Actions.ActOnCXXNestedNameSpecifierDecltype(SS, DS, CCLoc))233SS.SetInvalid(SourceRange(DeclLoc, CCLoc));234235HasScopeSpecifier = true;236}237238else if (!HasScopeSpecifier && Tok.is(tok::identifier) &&239GetLookAheadToken(1).is(tok::ellipsis) &&240GetLookAheadToken(2).is(tok::l_square)) {241SourceLocation Start = Tok.getLocation();242DeclSpec DS(AttrFactory);243SourceLocation CCLoc;244SourceLocation EndLoc = ParsePackIndexingType(DS);245if (DS.getTypeSpecType() == DeclSpec::TST_error)246return false;247248QualType Type = Actions.ActOnPackIndexingType(249DS.getRepAsType().get(), DS.getPackIndexingExpr(), DS.getBeginLoc(),250DS.getEllipsisLoc());251252if (Type.isNull())253return false;254255if (!TryConsumeToken(tok::coloncolon, CCLoc)) {256AnnotateExistingIndexedTypeNamePack(ParsedType::make(Type), Start,257EndLoc);258return false;259}260if (Actions.ActOnCXXNestedNameSpecifierIndexedPack(SS, DS, CCLoc,261std::move(Type)))262SS.SetInvalid(SourceRange(Start, CCLoc));263HasScopeSpecifier = true;264}265266// Preferred type might change when parsing qualifiers, we need the original.267auto SavedType = PreferredType;268while (true) {269if (HasScopeSpecifier) {270if (Tok.is(tok::code_completion)) {271cutOffParsing();272// Code completion for a nested-name-specifier, where the code273// completion token follows the '::'.274Actions.CodeCompletion().CodeCompleteQualifiedId(275getCurScope(), SS, EnteringContext, InUsingDeclaration,276ObjectType.get(), SavedType.get(SS.getBeginLoc()));277// Include code completion token into the range of the scope otherwise278// when we try to annotate the scope tokens the dangling code completion279// token will cause assertion in280// Preprocessor::AnnotatePreviousCachedTokens.281SS.setEndLoc(Tok.getLocation());282return true;283}284285// C++ [basic.lookup.classref]p5:286// If the qualified-id has the form287//288// ::class-name-or-namespace-name::...289//290// the class-name-or-namespace-name is looked up in global scope as a291// class-name or namespace-name.292//293// To implement this, we clear out the object type as soon as we've294// seen a leading '::' or part of a nested-name-specifier.295ObjectType = nullptr;296}297298// nested-name-specifier:299// nested-name-specifier 'template'[opt] simple-template-id '::'300301// Parse the optional 'template' keyword, then make sure we have302// 'identifier <' after it.303if (Tok.is(tok::kw_template)) {304// If we don't have a scope specifier or an object type, this isn't a305// nested-name-specifier, since they aren't allowed to start with306// 'template'.307if (!HasScopeSpecifier && !ObjectType)308break;309310TentativeParsingAction TPA(*this);311SourceLocation TemplateKWLoc = ConsumeToken();312313UnqualifiedId TemplateName;314if (Tok.is(tok::identifier)) {315// Consume the identifier.316TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());317ConsumeToken();318} else if (Tok.is(tok::kw_operator)) {319// We don't need to actually parse the unqualified-id in this case,320// because a simple-template-id cannot start with 'operator', but321// go ahead and parse it anyway for consistency with the case where322// we already annotated the template-id.323if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType,324TemplateName)) {325TPA.Commit();326break;327}328329if (TemplateName.getKind() != UnqualifiedIdKind::IK_OperatorFunctionId &&330TemplateName.getKind() != UnqualifiedIdKind::IK_LiteralOperatorId) {331Diag(TemplateName.getSourceRange().getBegin(),332diag::err_id_after_template_in_nested_name_spec)333<< TemplateName.getSourceRange();334TPA.Commit();335break;336}337} else {338TPA.Revert();339break;340}341342// If the next token is not '<', we have a qualified-id that refers343// to a template name, such as T::template apply, but is not a344// template-id.345if (Tok.isNot(tok::less)) {346TPA.Revert();347break;348}349350// Commit to parsing the template-id.351TPA.Commit();352TemplateTy Template;353TemplateNameKind TNK = Actions.ActOnTemplateName(354getCurScope(), SS, TemplateKWLoc, TemplateName, ObjectType,355EnteringContext, Template, /*AllowInjectedClassName*/ true);356if (AnnotateTemplateIdToken(Template, TNK, SS, TemplateKWLoc,357TemplateName, false))358return true;359360continue;361}362363if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) {364// We have365//366// template-id '::'367//368// So we need to check whether the template-id is a simple-template-id of369// the right kind (it should name a type or be dependent), and then370// convert it into a type within the nested-name-specifier.371TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);372if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) {373*MayBePseudoDestructor = true;374return false;375}376377if (LastII)378*LastII = TemplateId->Name;379380// Consume the template-id token.381ConsumeAnnotationToken();382383assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");384SourceLocation CCLoc = ConsumeToken();385386HasScopeSpecifier = true;387388ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),389TemplateId->NumArgs);390391if (TemplateId->isInvalid() ||392Actions.ActOnCXXNestedNameSpecifier(getCurScope(),393SS,394TemplateId->TemplateKWLoc,395TemplateId->Template,396TemplateId->TemplateNameLoc,397TemplateId->LAngleLoc,398TemplateArgsPtr,399TemplateId->RAngleLoc,400CCLoc,401EnteringContext)) {402SourceLocation StartLoc403= SS.getBeginLoc().isValid()? SS.getBeginLoc()404: TemplateId->TemplateNameLoc;405SS.SetInvalid(SourceRange(StartLoc, CCLoc));406}407408continue;409}410411switch (Tok.getKind()) {412#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:413#include "clang/Basic/TransformTypeTraits.def"414if (!NextToken().is(tok::l_paren)) {415Tok.setKind(tok::identifier);416Diag(Tok, diag::ext_keyword_as_ident)417<< Tok.getIdentifierInfo()->getName() << 0;418continue;419}420[[fallthrough]];421default:422break;423}424425// The rest of the nested-name-specifier possibilities start with426// tok::identifier.427if (Tok.isNot(tok::identifier))428break;429430IdentifierInfo &II = *Tok.getIdentifierInfo();431432// nested-name-specifier:433// type-name '::'434// namespace-name '::'435// nested-name-specifier identifier '::'436Token Next = NextToken();437Sema::NestedNameSpecInfo IdInfo(&II, Tok.getLocation(), Next.getLocation(),438ObjectType);439440// If we get foo:bar, this is almost certainly a typo for foo::bar. Recover441// and emit a fixit hint for it.442if (Next.is(tok::colon) && !ColonIsSacred) {443if (Actions.IsInvalidUnlessNestedName(getCurScope(), SS, IdInfo,444EnteringContext) &&445// If the token after the colon isn't an identifier, it's still an446// error, but they probably meant something else strange so don't447// recover like this.448PP.LookAhead(1).is(tok::identifier)) {449Diag(Next, diag::err_unexpected_colon_in_nested_name_spec)450<< FixItHint::CreateReplacement(Next.getLocation(), "::");451// Recover as if the user wrote '::'.452Next.setKind(tok::coloncolon);453}454}455456if (Next.is(tok::coloncolon) && GetLookAheadToken(2).is(tok::l_brace)) {457// It is invalid to have :: {, consume the scope qualifier and pretend458// like we never saw it.459Token Identifier = Tok; // Stash away the identifier.460ConsumeToken(); // Eat the identifier, current token is now '::'.461Diag(PP.getLocForEndOfToken(ConsumeToken()), diag::err_expected)462<< tok::identifier;463UnconsumeToken(Identifier); // Stick the identifier back.464Next = NextToken(); // Point Next at the '{' token.465}466467if (Next.is(tok::coloncolon)) {468if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) {469*MayBePseudoDestructor = true;470return false;471}472473if (ColonIsSacred) {474const Token &Next2 = GetLookAheadToken(2);475if (Next2.is(tok::kw_private) || Next2.is(tok::kw_protected) ||476Next2.is(tok::kw_public) || Next2.is(tok::kw_virtual)) {477Diag(Next2, diag::err_unexpected_token_in_nested_name_spec)478<< Next2.getName()479<< FixItHint::CreateReplacement(Next.getLocation(), ":");480Token ColonColon;481PP.Lex(ColonColon);482ColonColon.setKind(tok::colon);483PP.EnterToken(ColonColon, /*IsReinject*/ true);484break;485}486}487488if (LastII)489*LastII = &II;490491// We have an identifier followed by a '::'. Lookup this name492// as the name in a nested-name-specifier.493Token Identifier = Tok;494SourceLocation IdLoc = ConsumeToken();495assert(Tok.isOneOf(tok::coloncolon, tok::colon) &&496"NextToken() not working properly!");497Token ColonColon = Tok;498SourceLocation CCLoc = ConsumeToken();499500bool IsCorrectedToColon = false;501bool *CorrectionFlagPtr = ColonIsSacred ? &IsCorrectedToColon : nullptr;502if (Actions.ActOnCXXNestedNameSpecifier(503getCurScope(), IdInfo, EnteringContext, SS, CorrectionFlagPtr,504OnlyNamespace)) {505// Identifier is not recognized as a nested name, but we can have506// mistyped '::' instead of ':'.507if (CorrectionFlagPtr && IsCorrectedToColon) {508ColonColon.setKind(tok::colon);509PP.EnterToken(Tok, /*IsReinject*/ true);510PP.EnterToken(ColonColon, /*IsReinject*/ true);511Tok = Identifier;512break;513}514SS.SetInvalid(SourceRange(IdLoc, CCLoc));515}516HasScopeSpecifier = true;517continue;518}519520CheckForTemplateAndDigraph(Next, ObjectType, EnteringContext, II, SS);521522// nested-name-specifier:523// type-name '<'524if (Next.is(tok::less)) {525526TemplateTy Template;527UnqualifiedId TemplateName;528TemplateName.setIdentifier(&II, Tok.getLocation());529bool MemberOfUnknownSpecialization;530if (TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS,531/*hasTemplateKeyword=*/false,532TemplateName,533ObjectType,534EnteringContext,535Template,536MemberOfUnknownSpecialization)) {537// If lookup didn't find anything, we treat the name as a template-name538// anyway. C++20 requires this, and in prior language modes it improves539// error recovery. But before we commit to this, check that we actually540// have something that looks like a template-argument-list next.541if (!IsTypename && TNK == TNK_Undeclared_template &&542isTemplateArgumentList(1) == TPResult::False)543break;544545// We have found a template name, so annotate this token546// with a template-id annotation. We do not permit the547// template-id to be translated into a type annotation,548// because some clients (e.g., the parsing of class template549// specializations) still want to see the original template-id550// token, and it might not be a type at all (e.g. a concept name in a551// type-constraint).552ConsumeToken();553if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),554TemplateName, false))555return true;556continue;557}558559if (MemberOfUnknownSpecialization && (ObjectType || SS.isSet()) &&560(IsTypename || isTemplateArgumentList(1) == TPResult::True)) {561// If we had errors before, ObjectType can be dependent even without any562// templates. Do not report missing template keyword in that case.563if (!ObjectHadErrors) {564// We have something like t::getAs<T>, where getAs is a565// member of an unknown specialization. However, this will only566// parse correctly as a template, so suggest the keyword 'template'567// before 'getAs' and treat this as a dependent template name.568unsigned DiagID = diag::err_missing_dependent_template_keyword;569if (getLangOpts().MicrosoftExt)570DiagID = diag::warn_missing_dependent_template_keyword;571572Diag(Tok.getLocation(), DiagID)573<< II.getName()574<< FixItHint::CreateInsertion(Tok.getLocation(), "template ");575}576577SourceLocation TemplateNameLoc = ConsumeToken();578579TemplateNameKind TNK = Actions.ActOnTemplateName(580getCurScope(), SS, TemplateNameLoc, TemplateName, ObjectType,581EnteringContext, Template, /*AllowInjectedClassName*/ true);582if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),583TemplateName, false))584return true;585586continue;587}588}589590// We don't have any tokens that form the beginning of a591// nested-name-specifier, so we're done.592break;593}594595// Even if we didn't see any pieces of a nested-name-specifier, we596// still check whether there is a tilde in this position, which597// indicates a potential pseudo-destructor.598if (CheckForDestructor && !HasScopeSpecifier && Tok.is(tok::tilde))599*MayBePseudoDestructor = true;600601return false;602}603604ExprResult Parser::tryParseCXXIdExpression(CXXScopeSpec &SS,605bool isAddressOfOperand,606Token &Replacement) {607ExprResult E;608609// We may have already annotated this id-expression.610switch (Tok.getKind()) {611case tok::annot_non_type: {612NamedDecl *ND = getNonTypeAnnotation(Tok);613SourceLocation Loc = ConsumeAnnotationToken();614E = Actions.ActOnNameClassifiedAsNonType(getCurScope(), SS, ND, Loc, Tok);615break;616}617618case tok::annot_non_type_dependent: {619IdentifierInfo *II = getIdentifierAnnotation(Tok);620SourceLocation Loc = ConsumeAnnotationToken();621622// This is only the direct operand of an & operator if it is not623// followed by a postfix-expression suffix.624if (isAddressOfOperand && isPostfixExpressionSuffixStart())625isAddressOfOperand = false;626627E = Actions.ActOnNameClassifiedAsDependentNonType(SS, II, Loc,628isAddressOfOperand);629break;630}631632case tok::annot_non_type_undeclared: {633assert(SS.isEmpty() &&634"undeclared non-type annotation should be unqualified");635IdentifierInfo *II = getIdentifierAnnotation(Tok);636SourceLocation Loc = ConsumeAnnotationToken();637E = Actions.ActOnNameClassifiedAsUndeclaredNonType(II, Loc);638break;639}640641default:642SourceLocation TemplateKWLoc;643UnqualifiedId Name;644if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr,645/*ObjectHadErrors=*/false,646/*EnteringContext=*/false,647/*AllowDestructorName=*/false,648/*AllowConstructorName=*/false,649/*AllowDeductionGuide=*/false, &TemplateKWLoc, Name))650return ExprError();651652// This is only the direct operand of an & operator if it is not653// followed by a postfix-expression suffix.654if (isAddressOfOperand && isPostfixExpressionSuffixStart())655isAddressOfOperand = false;656657E = Actions.ActOnIdExpression(658getCurScope(), SS, TemplateKWLoc, Name, Tok.is(tok::l_paren),659isAddressOfOperand, /*CCC=*/nullptr, /*IsInlineAsmIdentifier=*/false,660&Replacement);661break;662}663664// Might be a pack index expression!665E = tryParseCXXPackIndexingExpression(E);666667if (!E.isInvalid() && !E.isUnset() && Tok.is(tok::less))668checkPotentialAngleBracket(E);669return E;670}671672ExprResult Parser::ParseCXXPackIndexingExpression(ExprResult PackIdExpression) {673assert(Tok.is(tok::ellipsis) && NextToken().is(tok::l_square) &&674"expected ...[");675SourceLocation EllipsisLoc = ConsumeToken();676BalancedDelimiterTracker T(*this, tok::l_square);677T.consumeOpen();678ExprResult IndexExpr = ParseConstantExpression();679if (T.consumeClose() || IndexExpr.isInvalid())680return ExprError();681return Actions.ActOnPackIndexingExpr(getCurScope(), PackIdExpression.get(),682EllipsisLoc, T.getOpenLocation(),683IndexExpr.get(), T.getCloseLocation());684}685686ExprResult687Parser::tryParseCXXPackIndexingExpression(ExprResult PackIdExpression) {688ExprResult E = PackIdExpression;689if (!PackIdExpression.isInvalid() && !PackIdExpression.isUnset() &&690Tok.is(tok::ellipsis) && NextToken().is(tok::l_square)) {691E = ParseCXXPackIndexingExpression(E);692}693return E;694}695696/// ParseCXXIdExpression - Handle id-expression.697///698/// id-expression:699/// unqualified-id700/// qualified-id701///702/// qualified-id:703/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id704/// '::' identifier705/// '::' operator-function-id706/// '::' template-id707///708/// NOTE: The standard specifies that, for qualified-id, the parser does not709/// expect:710///711/// '::' conversion-function-id712/// '::' '~' class-name713///714/// This may cause a slight inconsistency on diagnostics:715///716/// class C {};717/// namespace A {}718/// void f() {719/// :: A :: ~ C(); // Some Sema error about using destructor with a720/// // namespace.721/// :: ~ C(); // Some Parser error like 'unexpected ~'.722/// }723///724/// We simplify the parser a bit and make it work like:725///726/// qualified-id:727/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id728/// '::' unqualified-id729///730/// That way Sema can handle and report similar errors for namespaces and the731/// global scope.732///733/// The isAddressOfOperand parameter indicates that this id-expression is a734/// direct operand of the address-of operator. This is, besides member contexts,735/// the only place where a qualified-id naming a non-static class member may736/// appear.737///738ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {739// qualified-id:740// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id741// '::' unqualified-id742//743CXXScopeSpec SS;744ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,745/*ObjectHasErrors=*/false,746/*EnteringContext=*/false);747748Token Replacement;749ExprResult Result =750tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement);751if (Result.isUnset()) {752// If the ExprResult is valid but null, then typo correction suggested a753// keyword replacement that needs to be reparsed.754UnconsumeToken(Replacement);755Result = tryParseCXXIdExpression(SS, isAddressOfOperand, Replacement);756}757assert(!Result.isUnset() && "Typo correction suggested a keyword replacement "758"for a previous keyword suggestion");759return Result;760}761762/// ParseLambdaExpression - Parse a C++11 lambda expression.763///764/// lambda-expression:765/// lambda-introducer lambda-declarator compound-statement766/// lambda-introducer '<' template-parameter-list '>'767/// requires-clause[opt] lambda-declarator compound-statement768///769/// lambda-introducer:770/// '[' lambda-capture[opt] ']'771///772/// lambda-capture:773/// capture-default774/// capture-list775/// capture-default ',' capture-list776///777/// capture-default:778/// '&'779/// '='780///781/// capture-list:782/// capture783/// capture-list ',' capture784///785/// capture:786/// simple-capture787/// init-capture [C++1y]788///789/// simple-capture:790/// identifier791/// '&' identifier792/// 'this'793///794/// init-capture: [C++1y]795/// identifier initializer796/// '&' identifier initializer797///798/// lambda-declarator:799/// lambda-specifiers [C++23]800/// '(' parameter-declaration-clause ')' lambda-specifiers801/// requires-clause[opt]802///803/// lambda-specifiers:804/// decl-specifier-seq[opt] noexcept-specifier[opt]805/// attribute-specifier-seq[opt] trailing-return-type[opt]806///807ExprResult Parser::ParseLambdaExpression() {808// Parse lambda-introducer.809LambdaIntroducer Intro;810if (ParseLambdaIntroducer(Intro)) {811SkipUntil(tok::r_square, StopAtSemi);812SkipUntil(tok::l_brace, StopAtSemi);813SkipUntil(tok::r_brace, StopAtSemi);814return ExprError();815}816817return ParseLambdaExpressionAfterIntroducer(Intro);818}819820/// Use lookahead and potentially tentative parsing to determine if we are821/// looking at a C++11 lambda expression, and parse it if we are.822///823/// If we are not looking at a lambda expression, returns ExprError().824ExprResult Parser::TryParseLambdaExpression() {825assert(getLangOpts().CPlusPlus && Tok.is(tok::l_square) &&826"Not at the start of a possible lambda expression.");827828const Token Next = NextToken();829if (Next.is(tok::eof)) // Nothing else to lookup here...830return ExprEmpty();831832const Token After = GetLookAheadToken(2);833// If lookahead indicates this is a lambda...834if (Next.is(tok::r_square) || // []835Next.is(tok::equal) || // [=836(Next.is(tok::amp) && // [&] or [&,837After.isOneOf(tok::r_square, tok::comma)) ||838(Next.is(tok::identifier) && // [identifier]839After.is(tok::r_square)) ||840Next.is(tok::ellipsis)) { // [...841return ParseLambdaExpression();842}843844// If lookahead indicates an ObjC message send...845// [identifier identifier846if (Next.is(tok::identifier) && After.is(tok::identifier))847return ExprEmpty();848849// Here, we're stuck: lambda introducers and Objective-C message sends are850// unambiguous, but it requires arbitrary lookhead. [a,b,c,d,e,f,g] is a851// lambda, and [a,b,c,d,e,f,g h] is a Objective-C message send. Instead of852// writing two routines to parse a lambda introducer, just try to parse853// a lambda introducer first, and fall back if that fails.854LambdaIntroducer Intro;855{856TentativeParsingAction TPA(*this);857LambdaIntroducerTentativeParse Tentative;858if (ParseLambdaIntroducer(Intro, &Tentative)) {859TPA.Commit();860return ExprError();861}862863switch (Tentative) {864case LambdaIntroducerTentativeParse::Success:865TPA.Commit();866break;867868case LambdaIntroducerTentativeParse::Incomplete:869// Didn't fully parse the lambda-introducer, try again with a870// non-tentative parse.871TPA.Revert();872Intro = LambdaIntroducer();873if (ParseLambdaIntroducer(Intro))874return ExprError();875break;876877case LambdaIntroducerTentativeParse::MessageSend:878case LambdaIntroducerTentativeParse::Invalid:879// Not a lambda-introducer, might be a message send.880TPA.Revert();881return ExprEmpty();882}883}884885return ParseLambdaExpressionAfterIntroducer(Intro);886}887888/// Parse a lambda introducer.889/// \param Intro A LambdaIntroducer filled in with information about the890/// contents of the lambda-introducer.891/// \param Tentative If non-null, we are disambiguating between a892/// lambda-introducer and some other construct. In this mode, we do not893/// produce any diagnostics or take any other irreversible action unless894/// we're sure that this is a lambda-expression.895/// \return \c true if parsing (or disambiguation) failed with a diagnostic and896/// the caller should bail out / recover.897bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,898LambdaIntroducerTentativeParse *Tentative) {899if (Tentative)900*Tentative = LambdaIntroducerTentativeParse::Success;901902assert(Tok.is(tok::l_square) && "Lambda expressions begin with '['.");903BalancedDelimiterTracker T(*this, tok::l_square);904T.consumeOpen();905906Intro.Range.setBegin(T.getOpenLocation());907908bool First = true;909910// Produce a diagnostic if we're not tentatively parsing; otherwise track911// that our parse has failed.912auto Invalid = [&](llvm::function_ref<void()> Action) {913if (Tentative) {914*Tentative = LambdaIntroducerTentativeParse::Invalid;915return false;916}917Action();918return true;919};920921// Perform some irreversible action if this is a non-tentative parse;922// otherwise note that our actions were incomplete.923auto NonTentativeAction = [&](llvm::function_ref<void()> Action) {924if (Tentative)925*Tentative = LambdaIntroducerTentativeParse::Incomplete;926else927Action();928};929930// Parse capture-default.931if (Tok.is(tok::amp) &&932(NextToken().is(tok::comma) || NextToken().is(tok::r_square))) {933Intro.Default = LCD_ByRef;934Intro.DefaultLoc = ConsumeToken();935First = false;936if (!Tok.getIdentifierInfo()) {937// This can only be a lambda; no need for tentative parsing any more.938// '[[and]]' can still be an attribute, though.939Tentative = nullptr;940}941} else if (Tok.is(tok::equal)) {942Intro.Default = LCD_ByCopy;943Intro.DefaultLoc = ConsumeToken();944First = false;945Tentative = nullptr;946}947948while (Tok.isNot(tok::r_square)) {949if (!First) {950if (Tok.isNot(tok::comma)) {951// Provide a completion for a lambda introducer here. Except952// in Objective-C, where this is Almost Surely meant to be a message953// send. In that case, fail here and let the ObjC message954// expression parser perform the completion.955if (Tok.is(tok::code_completion) &&956!(getLangOpts().ObjC && Tentative)) {957cutOffParsing();958Actions.CodeCompletion().CodeCompleteLambdaIntroducer(959getCurScope(), Intro,960/*AfterAmpersand=*/false);961break;962}963964return Invalid([&] {965Diag(Tok.getLocation(), diag::err_expected_comma_or_rsquare);966});967}968ConsumeToken();969}970971if (Tok.is(tok::code_completion)) {972cutOffParsing();973// If we're in Objective-C++ and we have a bare '[', then this is more974// likely to be a message receiver.975if (getLangOpts().ObjC && Tentative && First)976Actions.CodeCompletion().CodeCompleteObjCMessageReceiver(getCurScope());977else978Actions.CodeCompletion().CodeCompleteLambdaIntroducer(979getCurScope(), Intro,980/*AfterAmpersand=*/false);981break;982}983984First = false;985986// Parse capture.987LambdaCaptureKind Kind = LCK_ByCopy;988LambdaCaptureInitKind InitKind = LambdaCaptureInitKind::NoInit;989SourceLocation Loc;990IdentifierInfo *Id = nullptr;991SourceLocation EllipsisLocs[4];992ExprResult Init;993SourceLocation LocStart = Tok.getLocation();994995if (Tok.is(tok::star)) {996Loc = ConsumeToken();997if (Tok.is(tok::kw_this)) {998ConsumeToken();999Kind = LCK_StarThis;1000} else {1001return Invalid([&] {1002Diag(Tok.getLocation(), diag::err_expected_star_this_capture);1003});1004}1005} else if (Tok.is(tok::kw_this)) {1006Kind = LCK_This;1007Loc = ConsumeToken();1008} else if (Tok.isOneOf(tok::amp, tok::equal) &&1009NextToken().isOneOf(tok::comma, tok::r_square) &&1010Intro.Default == LCD_None) {1011// We have a lone "&" or "=" which is either a misplaced capture-default1012// or the start of a capture (in the "&" case) with the rest of the1013// capture missing. Both are an error but a misplaced capture-default1014// is more likely if we don't already have a capture default.1015return Invalid(1016[&] { Diag(Tok.getLocation(), diag::err_capture_default_first); });1017} else {1018TryConsumeToken(tok::ellipsis, EllipsisLocs[0]);10191020if (Tok.is(tok::amp)) {1021Kind = LCK_ByRef;1022ConsumeToken();10231024if (Tok.is(tok::code_completion)) {1025cutOffParsing();1026Actions.CodeCompletion().CodeCompleteLambdaIntroducer(1027getCurScope(), Intro,1028/*AfterAmpersand=*/true);1029break;1030}1031}10321033TryConsumeToken(tok::ellipsis, EllipsisLocs[1]);10341035if (Tok.is(tok::identifier)) {1036Id = Tok.getIdentifierInfo();1037Loc = ConsumeToken();1038} else if (Tok.is(tok::kw_this)) {1039return Invalid([&] {1040// FIXME: Suggest a fixit here.1041Diag(Tok.getLocation(), diag::err_this_captured_by_reference);1042});1043} else {1044return Invalid([&] {1045Diag(Tok.getLocation(), diag::err_expected_capture);1046});1047}10481049TryConsumeToken(tok::ellipsis, EllipsisLocs[2]);10501051if (Tok.is(tok::l_paren)) {1052BalancedDelimiterTracker Parens(*this, tok::l_paren);1053Parens.consumeOpen();10541055InitKind = LambdaCaptureInitKind::DirectInit;10561057ExprVector Exprs;1058if (Tentative) {1059Parens.skipToEnd();1060*Tentative = LambdaIntroducerTentativeParse::Incomplete;1061} else if (ParseExpressionList(Exprs)) {1062Parens.skipToEnd();1063Init = ExprError();1064} else {1065Parens.consumeClose();1066Init = Actions.ActOnParenListExpr(Parens.getOpenLocation(),1067Parens.getCloseLocation(),1068Exprs);1069}1070} else if (Tok.isOneOf(tok::l_brace, tok::equal)) {1071// Each lambda init-capture forms its own full expression, which clears1072// Actions.MaybeODRUseExprs. So create an expression evaluation context1073// to save the necessary state, and restore it later.1074EnterExpressionEvaluationContext EC(1075Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);10761077if (TryConsumeToken(tok::equal))1078InitKind = LambdaCaptureInitKind::CopyInit;1079else1080InitKind = LambdaCaptureInitKind::ListInit;10811082if (!Tentative) {1083Init = ParseInitializer();1084} else if (Tok.is(tok::l_brace)) {1085BalancedDelimiterTracker Braces(*this, tok::l_brace);1086Braces.consumeOpen();1087Braces.skipToEnd();1088*Tentative = LambdaIntroducerTentativeParse::Incomplete;1089} else {1090// We're disambiguating this:1091//1092// [..., x = expr1093//1094// We need to find the end of the following expression in order to1095// determine whether this is an Obj-C message send's receiver, a1096// C99 designator, or a lambda init-capture.1097//1098// Parse the expression to find where it ends, and annotate it back1099// onto the tokens. We would have parsed this expression the same way1100// in either case: both the RHS of an init-capture and the RHS of an1101// assignment expression are parsed as an initializer-clause, and in1102// neither case can anything be added to the scope between the '[' and1103// here.1104//1105// FIXME: This is horrible. Adding a mechanism to skip an expression1106// would be much cleaner.1107// FIXME: If there is a ',' before the next ']' or ':', we can skip to1108// that instead. (And if we see a ':' with no matching '?', we can1109// classify this as an Obj-C message send.)1110SourceLocation StartLoc = Tok.getLocation();1111InMessageExpressionRAIIObject MaybeInMessageExpression(*this, true);1112Init = ParseInitializer();1113if (!Init.isInvalid())1114Init = Actions.CorrectDelayedTyposInExpr(Init.get());11151116if (Tok.getLocation() != StartLoc) {1117// Back out the lexing of the token after the initializer.1118PP.RevertCachedTokens(1);11191120// Replace the consumed tokens with an appropriate annotation.1121Tok.setLocation(StartLoc);1122Tok.setKind(tok::annot_primary_expr);1123setExprAnnotation(Tok, Init);1124Tok.setAnnotationEndLoc(PP.getLastCachedTokenLocation());1125PP.AnnotateCachedTokens(Tok);11261127// Consume the annotated initializer.1128ConsumeAnnotationToken();1129}1130}1131}11321133TryConsumeToken(tok::ellipsis, EllipsisLocs[3]);1134}11351136// Check if this is a message send before we act on a possible init-capture.1137if (Tentative && Tok.is(tok::identifier) &&1138NextToken().isOneOf(tok::colon, tok::r_square)) {1139// This can only be a message send. We're done with disambiguation.1140*Tentative = LambdaIntroducerTentativeParse::MessageSend;1141return false;1142}11431144// Ensure that any ellipsis was in the right place.1145SourceLocation EllipsisLoc;1146if (llvm::any_of(EllipsisLocs,1147[](SourceLocation Loc) { return Loc.isValid(); })) {1148// The '...' should appear before the identifier in an init-capture, and1149// after the identifier otherwise.1150bool InitCapture = InitKind != LambdaCaptureInitKind::NoInit;1151SourceLocation *ExpectedEllipsisLoc =1152!InitCapture ? &EllipsisLocs[2] :1153Kind == LCK_ByRef ? &EllipsisLocs[1] :1154&EllipsisLocs[0];1155EllipsisLoc = *ExpectedEllipsisLoc;11561157unsigned DiagID = 0;1158if (EllipsisLoc.isInvalid()) {1159DiagID = diag::err_lambda_capture_misplaced_ellipsis;1160for (SourceLocation Loc : EllipsisLocs) {1161if (Loc.isValid())1162EllipsisLoc = Loc;1163}1164} else {1165unsigned NumEllipses = std::accumulate(1166std::begin(EllipsisLocs), std::end(EllipsisLocs), 0,1167[](int N, SourceLocation Loc) { return N + Loc.isValid(); });1168if (NumEllipses > 1)1169DiagID = diag::err_lambda_capture_multiple_ellipses;1170}1171if (DiagID) {1172NonTentativeAction([&] {1173// Point the diagnostic at the first misplaced ellipsis.1174SourceLocation DiagLoc;1175for (SourceLocation &Loc : EllipsisLocs) {1176if (&Loc != ExpectedEllipsisLoc && Loc.isValid()) {1177DiagLoc = Loc;1178break;1179}1180}1181assert(DiagLoc.isValid() && "no location for diagnostic");11821183// Issue the diagnostic and produce fixits showing where the ellipsis1184// should have been written.1185auto &&D = Diag(DiagLoc, DiagID);1186if (DiagID == diag::err_lambda_capture_misplaced_ellipsis) {1187SourceLocation ExpectedLoc =1188InitCapture ? Loc1189: Lexer::getLocForEndOfToken(1190Loc, 0, PP.getSourceManager(), getLangOpts());1191D << InitCapture << FixItHint::CreateInsertion(ExpectedLoc, "...");1192}1193for (SourceLocation &Loc : EllipsisLocs) {1194if (&Loc != ExpectedEllipsisLoc && Loc.isValid())1195D << FixItHint::CreateRemoval(Loc);1196}1197});1198}1199}12001201// Process the init-capture initializers now rather than delaying until we1202// form the lambda-expression so that they can be handled in the context1203// enclosing the lambda-expression, rather than in the context of the1204// lambda-expression itself.1205ParsedType InitCaptureType;1206if (Init.isUsable())1207Init = Actions.CorrectDelayedTyposInExpr(Init.get());1208if (Init.isUsable()) {1209NonTentativeAction([&] {1210// Get the pointer and store it in an lvalue, so we can use it as an1211// out argument.1212Expr *InitExpr = Init.get();1213// This performs any lvalue-to-rvalue conversions if necessary, which1214// can affect what gets captured in the containing decl-context.1215InitCaptureType = Actions.actOnLambdaInitCaptureInitialization(1216Loc, Kind == LCK_ByRef, EllipsisLoc, Id, InitKind, InitExpr);1217Init = InitExpr;1218});1219}12201221SourceLocation LocEnd = PrevTokLocation;12221223Intro.addCapture(Kind, Loc, Id, EllipsisLoc, InitKind, Init,1224InitCaptureType, SourceRange(LocStart, LocEnd));1225}12261227T.consumeClose();1228Intro.Range.setEnd(T.getCloseLocation());1229return false;1230}12311232static void tryConsumeLambdaSpecifierToken(Parser &P,1233SourceLocation &MutableLoc,1234SourceLocation &StaticLoc,1235SourceLocation &ConstexprLoc,1236SourceLocation &ConstevalLoc,1237SourceLocation &DeclEndLoc) {1238assert(MutableLoc.isInvalid());1239assert(StaticLoc.isInvalid());1240assert(ConstexprLoc.isInvalid());1241assert(ConstevalLoc.isInvalid());1242// Consume constexpr-opt mutable-opt in any sequence, and set the DeclEndLoc1243// to the final of those locations. Emit an error if we have multiple1244// copies of those keywords and recover.12451246auto ConsumeLocation = [&P, &DeclEndLoc](SourceLocation &SpecifierLoc,1247int DiagIndex) {1248if (SpecifierLoc.isValid()) {1249P.Diag(P.getCurToken().getLocation(),1250diag::err_lambda_decl_specifier_repeated)1251<< DiagIndex1252<< FixItHint::CreateRemoval(P.getCurToken().getLocation());1253}1254SpecifierLoc = P.ConsumeToken();1255DeclEndLoc = SpecifierLoc;1256};12571258while (true) {1259switch (P.getCurToken().getKind()) {1260case tok::kw_mutable:1261ConsumeLocation(MutableLoc, 0);1262break;1263case tok::kw_static:1264ConsumeLocation(StaticLoc, 1);1265break;1266case tok::kw_constexpr:1267ConsumeLocation(ConstexprLoc, 2);1268break;1269case tok::kw_consteval:1270ConsumeLocation(ConstevalLoc, 3);1271break;1272default:1273return;1274}1275}1276}12771278static void addStaticToLambdaDeclSpecifier(Parser &P, SourceLocation StaticLoc,1279DeclSpec &DS) {1280if (StaticLoc.isValid()) {1281P.Diag(StaticLoc, !P.getLangOpts().CPlusPlus231282? diag::err_static_lambda1283: diag::warn_cxx20_compat_static_lambda);1284const char *PrevSpec = nullptr;1285unsigned DiagID = 0;1286DS.SetStorageClassSpec(P.getActions(), DeclSpec::SCS_static, StaticLoc,1287PrevSpec, DiagID,1288P.getActions().getASTContext().getPrintingPolicy());1289assert(PrevSpec == nullptr && DiagID == 0 &&1290"Static cannot have been set previously!");1291}1292}12931294static void1295addConstexprToLambdaDeclSpecifier(Parser &P, SourceLocation ConstexprLoc,1296DeclSpec &DS) {1297if (ConstexprLoc.isValid()) {1298P.Diag(ConstexprLoc, !P.getLangOpts().CPlusPlus171299? diag::ext_constexpr_on_lambda_cxx171300: diag::warn_cxx14_compat_constexpr_on_lambda);1301const char *PrevSpec = nullptr;1302unsigned DiagID = 0;1303DS.SetConstexprSpec(ConstexprSpecKind::Constexpr, ConstexprLoc, PrevSpec,1304DiagID);1305assert(PrevSpec == nullptr && DiagID == 0 &&1306"Constexpr cannot have been set previously!");1307}1308}13091310static void addConstevalToLambdaDeclSpecifier(Parser &P,1311SourceLocation ConstevalLoc,1312DeclSpec &DS) {1313if (ConstevalLoc.isValid()) {1314P.Diag(ConstevalLoc, diag::warn_cxx20_compat_consteval);1315const char *PrevSpec = nullptr;1316unsigned DiagID = 0;1317DS.SetConstexprSpec(ConstexprSpecKind::Consteval, ConstevalLoc, PrevSpec,1318DiagID);1319if (DiagID != 0)1320P.Diag(ConstevalLoc, DiagID) << PrevSpec;1321}1322}13231324static void DiagnoseStaticSpecifierRestrictions(Parser &P,1325SourceLocation StaticLoc,1326SourceLocation MutableLoc,1327const LambdaIntroducer &Intro) {1328if (StaticLoc.isInvalid())1329return;13301331// [expr.prim.lambda.general] p41332// The lambda-specifier-seq shall not contain both mutable and static.1333// If the lambda-specifier-seq contains static, there shall be no1334// lambda-capture.1335if (MutableLoc.isValid())1336P.Diag(StaticLoc, diag::err_static_mutable_lambda);1337if (Intro.hasLambdaCapture()) {1338P.Diag(StaticLoc, diag::err_static_lambda_captures);1339}1340}13411342/// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda1343/// expression.1344ExprResult Parser::ParseLambdaExpressionAfterIntroducer(1345LambdaIntroducer &Intro) {1346SourceLocation LambdaBeginLoc = Intro.Range.getBegin();1347Diag(LambdaBeginLoc, getLangOpts().CPlusPlus111348? diag::warn_cxx98_compat_lambda1349: diag::ext_lambda);13501351PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc,1352"lambda expression parsing");13531354// Parse lambda-declarator[opt].1355DeclSpec DS(AttrFactory);1356Declarator D(DS, ParsedAttributesView::none(), DeclaratorContext::LambdaExpr);1357TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);13581359ParseScope LambdaScope(this, Scope::LambdaScope | Scope::DeclScope |1360Scope::FunctionDeclarationScope |1361Scope::FunctionPrototypeScope);13621363Actions.PushLambdaScope();1364Actions.ActOnLambdaExpressionAfterIntroducer(Intro, getCurScope());13651366ParsedAttributes Attributes(AttrFactory);1367if (getLangOpts().CUDA) {1368// In CUDA code, GNU attributes are allowed to appear immediately after the1369// "[...]", even if there is no "(...)" before the lambda body.1370//1371// Note that we support __noinline__ as a keyword in this mode and thus1372// it has to be separately handled.1373while (true) {1374if (Tok.is(tok::kw___noinline__)) {1375IdentifierInfo *AttrName = Tok.getIdentifierInfo();1376SourceLocation AttrNameLoc = ConsumeToken();1377Attributes.addNew(AttrName, AttrNameLoc, /*ScopeName=*/nullptr,1378AttrNameLoc, /*ArgsUnion=*/nullptr,1379/*numArgs=*/0, tok::kw___noinline__);1380} else if (Tok.is(tok::kw___attribute))1381ParseGNUAttributes(Attributes, /*LatePArsedAttrList=*/nullptr, &D);1382else1383break;1384}13851386D.takeAttributes(Attributes);1387}13881389MultiParseScope TemplateParamScope(*this);1390if (Tok.is(tok::less)) {1391Diag(Tok, getLangOpts().CPlusPlus201392? diag::warn_cxx17_compat_lambda_template_parameter_list1393: diag::ext_lambda_template_parameter_list);13941395SmallVector<NamedDecl*, 4> TemplateParams;1396SourceLocation LAngleLoc, RAngleLoc;1397if (ParseTemplateParameters(TemplateParamScope,1398CurTemplateDepthTracker.getDepth(),1399TemplateParams, LAngleLoc, RAngleLoc)) {1400Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());1401return ExprError();1402}14031404if (TemplateParams.empty()) {1405Diag(RAngleLoc,1406diag::err_lambda_template_parameter_list_empty);1407} else {1408// We increase the template depth before recursing into a requires-clause.1409//1410// This depth is used for setting up a LambdaScopeInfo (in1411// Sema::RecordParsingTemplateParameterDepth), which is used later when1412// inventing template parameters in InventTemplateParameter.1413//1414// This way, abbreviated generic lambdas could have different template1415// depths, avoiding substitution into the wrong template parameters during1416// constraint satisfaction check.1417++CurTemplateDepthTracker;1418ExprResult RequiresClause;1419if (TryConsumeToken(tok::kw_requires)) {1420RequiresClause =1421Actions.ActOnRequiresClause(ParseConstraintLogicalOrExpression(1422/*IsTrailingRequiresClause=*/false));1423if (RequiresClause.isInvalid())1424SkipUntil({tok::l_brace, tok::l_paren}, StopAtSemi | StopBeforeMatch);1425}14261427Actions.ActOnLambdaExplicitTemplateParameterList(1428Intro, LAngleLoc, TemplateParams, RAngleLoc, RequiresClause);1429}1430}14311432// Implement WG21 P2173, which allows attributes immediately before the1433// lambda declarator and applies them to the corresponding function operator1434// or operator template declaration. We accept this as a conforming extension1435// in all language modes that support lambdas.1436if (isCXX11AttributeSpecifier()) {1437Diag(Tok, getLangOpts().CPlusPlus231438? diag::warn_cxx20_compat_decl_attrs_on_lambda1439: diag::ext_decl_attrs_on_lambda)1440<< Tok.getIdentifierInfo() << Tok.isRegularKeywordAttribute();1441MaybeParseCXX11Attributes(D);1442}14431444TypeResult TrailingReturnType;1445SourceLocation TrailingReturnTypeLoc;1446SourceLocation LParenLoc, RParenLoc;1447SourceLocation DeclEndLoc;1448bool HasParentheses = false;1449bool HasSpecifiers = false;1450SourceLocation MutableLoc;14511452ParseScope Prototype(this, Scope::FunctionPrototypeScope |1453Scope::FunctionDeclarationScope |1454Scope::DeclScope);14551456// Parse parameter-declaration-clause.1457SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;1458SourceLocation EllipsisLoc;14591460if (Tok.is(tok::l_paren)) {1461BalancedDelimiterTracker T(*this, tok::l_paren);1462T.consumeOpen();1463LParenLoc = T.getOpenLocation();14641465if (Tok.isNot(tok::r_paren)) {1466Actions.RecordParsingTemplateParameterDepth(1467CurTemplateDepthTracker.getOriginalDepth());14681469ParseParameterDeclarationClause(D, Attributes, ParamInfo, EllipsisLoc);1470// For a generic lambda, each 'auto' within the parameter declaration1471// clause creates a template type parameter, so increment the depth.1472// If we've parsed any explicit template parameters, then the depth will1473// have already been incremented. So we make sure that at most a single1474// depth level is added.1475if (Actions.getCurGenericLambda())1476CurTemplateDepthTracker.setAddedDepth(1);1477}14781479T.consumeClose();1480DeclEndLoc = RParenLoc = T.getCloseLocation();1481HasParentheses = true;1482}14831484HasSpecifiers =1485Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute,1486tok::kw_constexpr, tok::kw_consteval, tok::kw_static,1487tok::kw___private, tok::kw___global, tok::kw___local,1488tok::kw___constant, tok::kw___generic, tok::kw_groupshared,1489tok::kw_requires, tok::kw_noexcept) ||1490Tok.isRegularKeywordAttribute() ||1491(Tok.is(tok::l_square) && NextToken().is(tok::l_square));14921493if (HasSpecifiers && !HasParentheses && !getLangOpts().CPlusPlus23) {1494// It's common to forget that one needs '()' before 'mutable', an1495// attribute specifier, the result type, or the requires clause. Deal with1496// this.1497Diag(Tok, diag::ext_lambda_missing_parens)1498<< FixItHint::CreateInsertion(Tok.getLocation(), "() ");1499}15001501if (HasParentheses || HasSpecifiers) {1502// GNU-style attributes must be parsed before the mutable specifier to1503// be compatible with GCC. MSVC-style attributes must be parsed before1504// the mutable specifier to be compatible with MSVC.1505MaybeParseAttributes(PAKM_GNU | PAKM_Declspec, Attributes);1506// Parse mutable-opt and/or constexpr-opt or consteval-opt, and update1507// the DeclEndLoc.1508SourceLocation ConstexprLoc;1509SourceLocation ConstevalLoc;1510SourceLocation StaticLoc;15111512tryConsumeLambdaSpecifierToken(*this, MutableLoc, StaticLoc, ConstexprLoc,1513ConstevalLoc, DeclEndLoc);15141515DiagnoseStaticSpecifierRestrictions(*this, StaticLoc, MutableLoc, Intro);15161517addStaticToLambdaDeclSpecifier(*this, StaticLoc, DS);1518addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS);1519addConstevalToLambdaDeclSpecifier(*this, ConstevalLoc, DS);1520}15211522Actions.ActOnLambdaClosureParameters(getCurScope(), ParamInfo);15231524if (!HasParentheses)1525Actions.ActOnLambdaClosureQualifiers(Intro, MutableLoc);15261527if (HasSpecifiers || HasParentheses) {1528// Parse exception-specification[opt].1529ExceptionSpecificationType ESpecType = EST_None;1530SourceRange ESpecRange;1531SmallVector<ParsedType, 2> DynamicExceptions;1532SmallVector<SourceRange, 2> DynamicExceptionRanges;1533ExprResult NoexceptExpr;1534CachedTokens *ExceptionSpecTokens;15351536ESpecType = tryParseExceptionSpecification(1537/*Delayed=*/false, ESpecRange, DynamicExceptions,1538DynamicExceptionRanges, NoexceptExpr, ExceptionSpecTokens);15391540if (ESpecType != EST_None)1541DeclEndLoc = ESpecRange.getEnd();15421543// Parse attribute-specifier[opt].1544if (MaybeParseCXX11Attributes(Attributes))1545DeclEndLoc = Attributes.Range.getEnd();15461547// Parse OpenCL addr space attribute.1548if (Tok.isOneOf(tok::kw___private, tok::kw___global, tok::kw___local,1549tok::kw___constant, tok::kw___generic)) {1550ParseOpenCLQualifiers(DS.getAttributes());1551ConsumeToken();1552}15531554SourceLocation FunLocalRangeEnd = DeclEndLoc;15551556// Parse trailing-return-type[opt].1557if (Tok.is(tok::arrow)) {1558FunLocalRangeEnd = Tok.getLocation();1559SourceRange Range;1560TrailingReturnType =1561ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit=*/false);1562TrailingReturnTypeLoc = Range.getBegin();1563if (Range.getEnd().isValid())1564DeclEndLoc = Range.getEnd();1565}15661567SourceLocation NoLoc;1568D.AddTypeInfo(DeclaratorChunk::getFunction(1569/*HasProto=*/true,1570/*IsAmbiguous=*/false, LParenLoc, ParamInfo.data(),1571ParamInfo.size(), EllipsisLoc, RParenLoc,1572/*RefQualifierIsLvalueRef=*/true,1573/*RefQualifierLoc=*/NoLoc, MutableLoc, ESpecType,1574ESpecRange, DynamicExceptions.data(),1575DynamicExceptionRanges.data(), DynamicExceptions.size(),1576NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr,1577/*ExceptionSpecTokens*/ nullptr,1578/*DeclsInPrototype=*/std::nullopt, LParenLoc,1579FunLocalRangeEnd, D, TrailingReturnType,1580TrailingReturnTypeLoc, &DS),1581std::move(Attributes), DeclEndLoc);15821583// We have called ActOnLambdaClosureQualifiers for parentheses-less cases1584// above.1585if (HasParentheses)1586Actions.ActOnLambdaClosureQualifiers(Intro, MutableLoc);15871588if (HasParentheses && Tok.is(tok::kw_requires))1589ParseTrailingRequiresClause(D);1590}15911592// Emit a warning if we see a CUDA host/device/global attribute1593// after '(...)'. nvcc doesn't accept this.1594if (getLangOpts().CUDA) {1595for (const ParsedAttr &A : Attributes)1596if (A.getKind() == ParsedAttr::AT_CUDADevice ||1597A.getKind() == ParsedAttr::AT_CUDAHost ||1598A.getKind() == ParsedAttr::AT_CUDAGlobal)1599Diag(A.getLoc(), diag::warn_cuda_attr_lambda_position)1600<< A.getAttrName()->getName();1601}16021603Prototype.Exit();16041605// FIXME: Rename BlockScope -> ClosureScope if we decide to continue using1606// it.1607unsigned ScopeFlags = Scope::BlockScope | Scope::FnScope | Scope::DeclScope |1608Scope::CompoundStmtScope;1609ParseScope BodyScope(this, ScopeFlags);16101611Actions.ActOnStartOfLambdaDefinition(Intro, D, DS);16121613// Parse compound-statement.1614if (!Tok.is(tok::l_brace)) {1615Diag(Tok, diag::err_expected_lambda_body);1616Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());1617return ExprError();1618}16191620StmtResult Stmt(ParseCompoundStatementBody());1621BodyScope.Exit();1622TemplateParamScope.Exit();1623LambdaScope.Exit();16241625if (!Stmt.isInvalid() && !TrailingReturnType.isInvalid() &&1626!D.isInvalidType())1627return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.get());16281629Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());1630return ExprError();1631}16321633/// ParseCXXCasts - This handles the various ways to cast expressions to another1634/// type.1635///1636/// postfix-expression: [C++ 5.2p1]1637/// 'dynamic_cast' '<' type-name '>' '(' expression ')'1638/// 'static_cast' '<' type-name '>' '(' expression ')'1639/// 'reinterpret_cast' '<' type-name '>' '(' expression ')'1640/// 'const_cast' '<' type-name '>' '(' expression ')'1641///1642/// C++ for OpenCL s2.3.1 adds:1643/// 'addrspace_cast' '<' type-name '>' '(' expression ')'1644ExprResult Parser::ParseCXXCasts() {1645tok::TokenKind Kind = Tok.getKind();1646const char *CastName = nullptr; // For error messages16471648switch (Kind) {1649default: llvm_unreachable("Unknown C++ cast!");1650case tok::kw_addrspace_cast: CastName = "addrspace_cast"; break;1651case tok::kw_const_cast: CastName = "const_cast"; break;1652case tok::kw_dynamic_cast: CastName = "dynamic_cast"; break;1653case tok::kw_reinterpret_cast: CastName = "reinterpret_cast"; break;1654case tok::kw_static_cast: CastName = "static_cast"; break;1655}16561657SourceLocation OpLoc = ConsumeToken();1658SourceLocation LAngleBracketLoc = Tok.getLocation();16591660// Check for "<::" which is parsed as "[:". If found, fix token stream,1661// diagnose error, suggest fix, and recover parsing.1662if (Tok.is(tok::l_square) && Tok.getLength() == 2) {1663Token Next = NextToken();1664if (Next.is(tok::colon) && areTokensAdjacent(Tok, Next))1665FixDigraph(*this, PP, Tok, Next, Kind, /*AtDigraph*/true);1666}16671668if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))1669return ExprError();16701671// Parse the common declaration-specifiers piece.1672DeclSpec DS(AttrFactory);1673ParseSpecifierQualifierList(DS, /*AccessSpecifier=*/AS_none,1674DeclSpecContext::DSC_type_specifier);16751676// Parse the abstract-declarator, if present.1677Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),1678DeclaratorContext::TypeName);1679ParseDeclarator(DeclaratorInfo);16801681SourceLocation RAngleBracketLoc = Tok.getLocation();16821683if (ExpectAndConsume(tok::greater))1684return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << tok::less);16851686BalancedDelimiterTracker T(*this, tok::l_paren);16871688if (T.expectAndConsume(diag::err_expected_lparen_after, CastName))1689return ExprError();16901691ExprResult Result = ParseExpression();16921693// Match the ')'.1694T.consumeClose();16951696if (!Result.isInvalid() && !DeclaratorInfo.isInvalidType())1697Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,1698LAngleBracketLoc, DeclaratorInfo,1699RAngleBracketLoc,1700T.getOpenLocation(), Result.get(),1701T.getCloseLocation());17021703return Result;1704}17051706/// ParseCXXTypeid - This handles the C++ typeid expression.1707///1708/// postfix-expression: [C++ 5.2p1]1709/// 'typeid' '(' expression ')'1710/// 'typeid' '(' type-id ')'1711///1712ExprResult Parser::ParseCXXTypeid() {1713assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");17141715SourceLocation OpLoc = ConsumeToken();1716SourceLocation LParenLoc, RParenLoc;1717BalancedDelimiterTracker T(*this, tok::l_paren);17181719// typeid expressions are always parenthesized.1720if (T.expectAndConsume(diag::err_expected_lparen_after, "typeid"))1721return ExprError();1722LParenLoc = T.getOpenLocation();17231724ExprResult Result;17251726// C++0x [expr.typeid]p3:1727// When typeid is applied to an expression other than an lvalue of a1728// polymorphic class type [...] The expression is an unevaluated1729// operand (Clause 5).1730//1731// Note that we can't tell whether the expression is an lvalue of a1732// polymorphic class type until after we've parsed the expression; we1733// speculatively assume the subexpression is unevaluated, and fix it up1734// later.1735//1736// We enter the unevaluated context before trying to determine whether we1737// have a type-id, because the tentative parse logic will try to resolve1738// names, and must treat them as unevaluated.1739EnterExpressionEvaluationContext Unevaluated(1740Actions, Sema::ExpressionEvaluationContext::Unevaluated,1741Sema::ReuseLambdaContextDecl);17421743if (isTypeIdInParens()) {1744TypeResult Ty = ParseTypeName();17451746// Match the ')'.1747T.consumeClose();1748RParenLoc = T.getCloseLocation();1749if (Ty.isInvalid() || RParenLoc.isInvalid())1750return ExprError();17511752Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,1753Ty.get().getAsOpaquePtr(), RParenLoc);1754} else {1755Result = ParseExpression();17561757// Match the ')'.1758if (Result.isInvalid())1759SkipUntil(tok::r_paren, StopAtSemi);1760else {1761T.consumeClose();1762RParenLoc = T.getCloseLocation();1763if (RParenLoc.isInvalid())1764return ExprError();17651766Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,1767Result.get(), RParenLoc);1768}1769}17701771return Result;1772}17731774/// ParseCXXUuidof - This handles the Microsoft C++ __uuidof expression.1775///1776/// '__uuidof' '(' expression ')'1777/// '__uuidof' '(' type-id ')'1778///1779ExprResult Parser::ParseCXXUuidof() {1780assert(Tok.is(tok::kw___uuidof) && "Not '__uuidof'!");17811782SourceLocation OpLoc = ConsumeToken();1783BalancedDelimiterTracker T(*this, tok::l_paren);17841785// __uuidof expressions are always parenthesized.1786if (T.expectAndConsume(diag::err_expected_lparen_after, "__uuidof"))1787return ExprError();17881789ExprResult Result;17901791if (isTypeIdInParens()) {1792TypeResult Ty = ParseTypeName();17931794// Match the ')'.1795T.consumeClose();17961797if (Ty.isInvalid())1798return ExprError();17991800Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(), /*isType=*/true,1801Ty.get().getAsOpaquePtr(),1802T.getCloseLocation());1803} else {1804EnterExpressionEvaluationContext Unevaluated(1805Actions, Sema::ExpressionEvaluationContext::Unevaluated);1806Result = ParseExpression();18071808// Match the ')'.1809if (Result.isInvalid())1810SkipUntil(tok::r_paren, StopAtSemi);1811else {1812T.consumeClose();18131814Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(),1815/*isType=*/false,1816Result.get(), T.getCloseLocation());1817}1818}18191820return Result;1821}18221823/// Parse a C++ pseudo-destructor expression after the base,1824/// . or -> operator, and nested-name-specifier have already been1825/// parsed. We're handling this fragment of the grammar:1826///1827/// postfix-expression: [C++2a expr.post]1828/// postfix-expression . template[opt] id-expression1829/// postfix-expression -> template[opt] id-expression1830///1831/// id-expression:1832/// qualified-id1833/// unqualified-id1834///1835/// qualified-id:1836/// nested-name-specifier template[opt] unqualified-id1837///1838/// nested-name-specifier:1839/// type-name ::1840/// decltype-specifier :: FIXME: not implemented, but probably only1841/// allowed in C++ grammar by accident1842/// nested-name-specifier identifier ::1843/// nested-name-specifier template[opt] simple-template-id ::1844/// [...]1845///1846/// unqualified-id:1847/// ~ type-name1848/// ~ decltype-specifier1849/// [...]1850///1851/// ... where the all but the last component of the nested-name-specifier1852/// has already been parsed, and the base expression is not of a non-dependent1853/// class type.1854ExprResult1855Parser::ParseCXXPseudoDestructor(Expr *Base, SourceLocation OpLoc,1856tok::TokenKind OpKind,1857CXXScopeSpec &SS,1858ParsedType ObjectType) {1859// If the last component of the (optional) nested-name-specifier is1860// template[opt] simple-template-id, it has already been annotated.1861UnqualifiedId FirstTypeName;1862SourceLocation CCLoc;1863if (Tok.is(tok::identifier)) {1864FirstTypeName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());1865ConsumeToken();1866assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");1867CCLoc = ConsumeToken();1868} else if (Tok.is(tok::annot_template_id)) {1869TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);1870// FIXME: Carry on and build an AST representation for tooling.1871if (TemplateId->isInvalid())1872return ExprError();1873FirstTypeName.setTemplateId(TemplateId);1874ConsumeAnnotationToken();1875assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");1876CCLoc = ConsumeToken();1877} else {1878assert(SS.isEmpty() && "missing last component of nested name specifier");1879FirstTypeName.setIdentifier(nullptr, SourceLocation());1880}18811882// Parse the tilde.1883assert(Tok.is(tok::tilde) && "ParseOptionalCXXScopeSpecifier fail");1884SourceLocation TildeLoc = ConsumeToken();18851886if (Tok.is(tok::kw_decltype) && !FirstTypeName.isValid()) {1887DeclSpec DS(AttrFactory);1888ParseDecltypeSpecifier(DS);1889if (DS.getTypeSpecType() == TST_error)1890return ExprError();1891return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc, OpKind,1892TildeLoc, DS);1893}18941895if (!Tok.is(tok::identifier)) {1896Diag(Tok, diag::err_destructor_tilde_identifier);1897return ExprError();1898}18991900// pack-index-specifier1901if (GetLookAheadToken(1).is(tok::ellipsis) &&1902GetLookAheadToken(2).is(tok::l_square)) {1903DeclSpec DS(AttrFactory);1904ParsePackIndexingType(DS);1905return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc, OpKind,1906TildeLoc, DS);1907}19081909// Parse the second type.1910UnqualifiedId SecondTypeName;1911IdentifierInfo *Name = Tok.getIdentifierInfo();1912SourceLocation NameLoc = ConsumeToken();1913SecondTypeName.setIdentifier(Name, NameLoc);19141915// If there is a '<', the second type name is a template-id. Parse1916// it as such.1917//1918// FIXME: This is not a context in which a '<' is assumed to start a template1919// argument list. This affects examples such as1920// void f(auto *p) { p->~X<int>(); }1921// ... but there's no ambiguity, and nowhere to write 'template' in such an1922// example, so we accept it anyway.1923if (Tok.is(tok::less) &&1924ParseUnqualifiedIdTemplateId(1925SS, ObjectType, Base && Base->containsErrors(), SourceLocation(),1926Name, NameLoc, false, SecondTypeName,1927/*AssumeTemplateId=*/true))1928return ExprError();19291930return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc, OpKind,1931SS, FirstTypeName, CCLoc, TildeLoc,1932SecondTypeName);1933}19341935/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.1936///1937/// boolean-literal: [C++ 2.13.5]1938/// 'true'1939/// 'false'1940ExprResult Parser::ParseCXXBoolLiteral() {1941tok::TokenKind Kind = Tok.getKind();1942return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind);1943}19441945/// ParseThrowExpression - This handles the C++ throw expression.1946///1947/// throw-expression: [C++ 15]1948/// 'throw' assignment-expression[opt]1949ExprResult Parser::ParseThrowExpression() {1950assert(Tok.is(tok::kw_throw) && "Not throw!");1951SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token.19521953// If the current token isn't the start of an assignment-expression,1954// then the expression is not present. This handles things like:1955// "C ? throw : (void)42", which is crazy but legal.1956switch (Tok.getKind()) { // FIXME: move this predicate somewhere common.1957case tok::semi:1958case tok::r_paren:1959case tok::r_square:1960case tok::r_brace:1961case tok::colon:1962case tok::comma:1963return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, nullptr);19641965default:1966ExprResult Expr(ParseAssignmentExpression());1967if (Expr.isInvalid()) return Expr;1968return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, Expr.get());1969}1970}19711972/// Parse the C++ Coroutines co_yield expression.1973///1974/// co_yield-expression:1975/// 'co_yield' assignment-expression[opt]1976ExprResult Parser::ParseCoyieldExpression() {1977assert(Tok.is(tok::kw_co_yield) && "Not co_yield!");19781979SourceLocation Loc = ConsumeToken();1980ExprResult Expr = Tok.is(tok::l_brace) ? ParseBraceInitializer()1981: ParseAssignmentExpression();1982if (!Expr.isInvalid())1983Expr = Actions.ActOnCoyieldExpr(getCurScope(), Loc, Expr.get());1984return Expr;1985}19861987/// ParseCXXThis - This handles the C++ 'this' pointer.1988///1989/// C++ 9.3.2: In the body of a non-static member function, the keyword this is1990/// a non-lvalue expression whose value is the address of the object for which1991/// the function is called.1992ExprResult Parser::ParseCXXThis() {1993assert(Tok.is(tok::kw_this) && "Not 'this'!");1994SourceLocation ThisLoc = ConsumeToken();1995return Actions.ActOnCXXThis(ThisLoc);1996}19971998/// ParseCXXTypeConstructExpression - Parse construction of a specified type.1999/// Can be interpreted either as function-style casting ("int(x)")2000/// or class type construction ("ClassType(x,y,z)")2001/// or creation of a value-initialized type ("int()").2002/// See [C++ 5.2.3].2003///2004/// postfix-expression: [C++ 5.2p1]2005/// simple-type-specifier '(' expression-list[opt] ')'2006/// [C++0x] simple-type-specifier braced-init-list2007/// typename-specifier '(' expression-list[opt] ')'2008/// [C++0x] typename-specifier braced-init-list2009///2010/// In C++1z onwards, the type specifier can also be a template-name.2011ExprResult2012Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {2013Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),2014DeclaratorContext::FunctionalCast);2015ParsedType TypeRep = Actions.ActOnTypeName(DeclaratorInfo).get();20162017assert((Tok.is(tok::l_paren) ||2018(getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)))2019&& "Expected '(' or '{'!");20202021if (Tok.is(tok::l_brace)) {2022PreferredType.enterTypeCast(Tok.getLocation(), TypeRep.get());2023ExprResult Init = ParseBraceInitializer();2024if (Init.isInvalid())2025return Init;2026Expr *InitList = Init.get();2027return Actions.ActOnCXXTypeConstructExpr(2028TypeRep, InitList->getBeginLoc(), MultiExprArg(&InitList, 1),2029InitList->getEndLoc(), /*ListInitialization=*/true);2030} else {2031BalancedDelimiterTracker T(*this, tok::l_paren);2032T.consumeOpen();20332034PreferredType.enterTypeCast(Tok.getLocation(), TypeRep.get());20352036ExprVector Exprs;20372038auto RunSignatureHelp = [&]() {2039QualType PreferredType;2040if (TypeRep)2041PreferredType =2042Actions.CodeCompletion().ProduceConstructorSignatureHelp(2043TypeRep.get()->getCanonicalTypeInternal(), DS.getEndLoc(),2044Exprs, T.getOpenLocation(), /*Braced=*/false);2045CalledSignatureHelp = true;2046return PreferredType;2047};20482049if (Tok.isNot(tok::r_paren)) {2050if (ParseExpressionList(Exprs, [&] {2051PreferredType.enterFunctionArgument(Tok.getLocation(),2052RunSignatureHelp);2053})) {2054if (PP.isCodeCompletionReached() && !CalledSignatureHelp)2055RunSignatureHelp();2056SkipUntil(tok::r_paren, StopAtSemi);2057return ExprError();2058}2059}20602061// Match the ')'.2062T.consumeClose();20632064// TypeRep could be null, if it references an invalid typedef.2065if (!TypeRep)2066return ExprError();20672068return Actions.ActOnCXXTypeConstructExpr(TypeRep, T.getOpenLocation(),2069Exprs, T.getCloseLocation(),2070/*ListInitialization=*/false);2071}2072}20732074Parser::DeclGroupPtrTy2075Parser::ParseAliasDeclarationInInitStatement(DeclaratorContext Context,2076ParsedAttributes &Attrs) {2077assert(Tok.is(tok::kw_using) && "Expected using");2078assert((Context == DeclaratorContext::ForInit ||2079Context == DeclaratorContext::SelectionInit) &&2080"Unexpected Declarator Context");2081DeclGroupPtrTy DG;2082SourceLocation DeclStart = ConsumeToken(), DeclEnd;20832084DG = ParseUsingDeclaration(Context, {}, DeclStart, DeclEnd, Attrs, AS_none);2085if (!DG)2086return DG;20872088Diag(DeclStart, !getLangOpts().CPlusPlus232089? diag::ext_alias_in_init_statement2090: diag::warn_cxx20_alias_in_init_statement)2091<< SourceRange(DeclStart, DeclEnd);20922093return DG;2094}20952096/// ParseCXXCondition - if/switch/while condition expression.2097///2098/// condition:2099/// expression2100/// type-specifier-seq declarator '=' assignment-expression2101/// [C++11] type-specifier-seq declarator '=' initializer-clause2102/// [C++11] type-specifier-seq declarator braced-init-list2103/// [Clang] type-specifier-seq ref-qualifier[opt] '[' identifier-list ']'2104/// brace-or-equal-initializer2105/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]2106/// '=' assignment-expression2107///2108/// In C++1z, a condition may in some contexts be preceded by an2109/// optional init-statement. This function will parse that too.2110///2111/// \param InitStmt If non-null, an init-statement is permitted, and if present2112/// will be parsed and stored here.2113///2114/// \param Loc The location of the start of the statement that requires this2115/// condition, e.g., the "for" in a for loop.2116///2117/// \param MissingOK Whether an empty condition is acceptable here. Otherwise2118/// it is considered an error to be recovered from.2119///2120/// \param FRI If non-null, a for range declaration is permitted, and if2121/// present will be parsed and stored here, and a null result will be returned.2122///2123/// \param EnterForConditionScope If true, enter a continue/break scope at the2124/// appropriate moment for a 'for' loop.2125///2126/// \returns The parsed condition.2127Sema::ConditionResult2128Parser::ParseCXXCondition(StmtResult *InitStmt, SourceLocation Loc,2129Sema::ConditionKind CK, bool MissingOK,2130ForRangeInfo *FRI, bool EnterForConditionScope) {2131// Helper to ensure we always enter a continue/break scope if requested.2132struct ForConditionScopeRAII {2133Scope *S;2134void enter(bool IsConditionVariable) {2135if (S) {2136S->AddFlags(Scope::BreakScope | Scope::ContinueScope);2137S->setIsConditionVarScope(IsConditionVariable);2138}2139}2140~ForConditionScopeRAII() {2141if (S)2142S->setIsConditionVarScope(false);2143}2144} ForConditionScope{EnterForConditionScope ? getCurScope() : nullptr};21452146ParenBraceBracketBalancer BalancerRAIIObj(*this);2147PreferredType.enterCondition(Actions, Tok.getLocation());21482149if (Tok.is(tok::code_completion)) {2150cutOffParsing();2151Actions.CodeCompletion().CodeCompleteOrdinaryName(2152getCurScope(), SemaCodeCompletion::PCC_Condition);2153return Sema::ConditionError();2154}21552156ParsedAttributes attrs(AttrFactory);2157MaybeParseCXX11Attributes(attrs);21582159const auto WarnOnInit = [this, &CK] {2160Diag(Tok.getLocation(), getLangOpts().CPlusPlus172161? diag::warn_cxx14_compat_init_statement2162: diag::ext_init_statement)2163<< (CK == Sema::ConditionKind::Switch);2164};21652166// Determine what kind of thing we have.2167switch (isCXXConditionDeclarationOrInitStatement(InitStmt, FRI)) {2168case ConditionOrInitStatement::Expression: {2169// If this is a for loop, we're entering its condition.2170ForConditionScope.enter(/*IsConditionVariable=*/false);21712172ProhibitAttributes(attrs);21732174// We can have an empty expression here.2175// if (; true);2176if (InitStmt && Tok.is(tok::semi)) {2177WarnOnInit();2178SourceLocation SemiLoc = Tok.getLocation();2179if (!Tok.hasLeadingEmptyMacro() && !SemiLoc.isMacroID()) {2180Diag(SemiLoc, diag::warn_empty_init_statement)2181<< (CK == Sema::ConditionKind::Switch)2182<< FixItHint::CreateRemoval(SemiLoc);2183}2184ConsumeToken();2185*InitStmt = Actions.ActOnNullStmt(SemiLoc);2186return ParseCXXCondition(nullptr, Loc, CK, MissingOK);2187}21882189// Parse the expression.2190ExprResult Expr = ParseExpression(); // expression2191if (Expr.isInvalid())2192return Sema::ConditionError();21932194if (InitStmt && Tok.is(tok::semi)) {2195WarnOnInit();2196*InitStmt = Actions.ActOnExprStmt(Expr.get());2197ConsumeToken();2198return ParseCXXCondition(nullptr, Loc, CK, MissingOK);2199}22002201return Actions.ActOnCondition(getCurScope(), Loc, Expr.get(), CK,2202MissingOK);2203}22042205case ConditionOrInitStatement::InitStmtDecl: {2206WarnOnInit();2207DeclGroupPtrTy DG;2208SourceLocation DeclStart = Tok.getLocation(), DeclEnd;2209if (Tok.is(tok::kw_using))2210DG = ParseAliasDeclarationInInitStatement(2211DeclaratorContext::SelectionInit, attrs);2212else {2213ParsedAttributes DeclSpecAttrs(AttrFactory);2214DG = ParseSimpleDeclaration(DeclaratorContext::SelectionInit, DeclEnd,2215attrs, DeclSpecAttrs, /*RequireSemi=*/true);2216}2217*InitStmt = Actions.ActOnDeclStmt(DG, DeclStart, DeclEnd);2218return ParseCXXCondition(nullptr, Loc, CK, MissingOK);2219}22202221case ConditionOrInitStatement::ForRangeDecl: {2222// This is 'for (init-stmt; for-range-decl : range-expr)'.2223// We're not actually in a for loop yet, so 'break' and 'continue' aren't2224// permitted here.2225assert(FRI && "should not parse a for range declaration here");2226SourceLocation DeclStart = Tok.getLocation(), DeclEnd;2227ParsedAttributes DeclSpecAttrs(AttrFactory);2228DeclGroupPtrTy DG = ParseSimpleDeclaration(2229DeclaratorContext::ForInit, DeclEnd, attrs, DeclSpecAttrs, false, FRI);2230FRI->LoopVar = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());2231return Sema::ConditionResult();2232}22332234case ConditionOrInitStatement::ConditionDecl:2235case ConditionOrInitStatement::Error:2236break;2237}22382239// If this is a for loop, we're entering its condition.2240ForConditionScope.enter(/*IsConditionVariable=*/true);22412242// type-specifier-seq2243DeclSpec DS(AttrFactory);2244ParseSpecifierQualifierList(DS, AS_none, DeclSpecContext::DSC_condition);22452246// declarator2247Declarator DeclaratorInfo(DS, attrs, DeclaratorContext::Condition);2248ParseDeclarator(DeclaratorInfo);22492250// simple-asm-expr[opt]2251if (Tok.is(tok::kw_asm)) {2252SourceLocation Loc;2253ExprResult AsmLabel(ParseSimpleAsm(/*ForAsmLabel*/ true, &Loc));2254if (AsmLabel.isInvalid()) {2255SkipUntil(tok::semi, StopAtSemi);2256return Sema::ConditionError();2257}2258DeclaratorInfo.setAsmLabel(AsmLabel.get());2259DeclaratorInfo.SetRangeEnd(Loc);2260}22612262// If attributes are present, parse them.2263MaybeParseGNUAttributes(DeclaratorInfo);22642265// Type-check the declaration itself.2266DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(),2267DeclaratorInfo);2268if (Dcl.isInvalid())2269return Sema::ConditionError();2270Decl *DeclOut = Dcl.get();22712272// '=' assignment-expression2273// If a '==' or '+=' is found, suggest a fixit to '='.2274bool CopyInitialization = isTokenEqualOrEqualTypo();2275if (CopyInitialization)2276ConsumeToken();22772278ExprResult InitExpr = ExprError();2279if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {2280Diag(Tok.getLocation(),2281diag::warn_cxx98_compat_generalized_initializer_lists);2282InitExpr = ParseBraceInitializer();2283} else if (CopyInitialization) {2284PreferredType.enterVariableInit(Tok.getLocation(), DeclOut);2285InitExpr = ParseAssignmentExpression();2286} else if (Tok.is(tok::l_paren)) {2287// This was probably an attempt to initialize the variable.2288SourceLocation LParen = ConsumeParen(), RParen = LParen;2289if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch))2290RParen = ConsumeParen();2291Diag(DeclOut->getLocation(),2292diag::err_expected_init_in_condition_lparen)2293<< SourceRange(LParen, RParen);2294} else {2295Diag(DeclOut->getLocation(), diag::err_expected_init_in_condition);2296}22972298if (!InitExpr.isInvalid())2299Actions.AddInitializerToDecl(DeclOut, InitExpr.get(), !CopyInitialization);2300else2301Actions.ActOnInitializerError(DeclOut);23022303Actions.FinalizeDeclaration(DeclOut);2304return Actions.ActOnConditionVariable(DeclOut, Loc, CK);2305}23062307/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.2308/// This should only be called when the current token is known to be part of2309/// simple-type-specifier.2310///2311/// simple-type-specifier:2312/// '::'[opt] nested-name-specifier[opt] type-name2313/// '::'[opt] nested-name-specifier 'template' simple-template-id [TODO]2314/// char2315/// wchar_t2316/// bool2317/// short2318/// int2319/// long2320/// signed2321/// unsigned2322/// float2323/// double2324/// void2325/// [GNU] typeof-specifier2326/// [C++0x] auto [TODO]2327///2328/// type-name:2329/// class-name2330/// enum-name2331/// typedef-name2332///2333void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {2334DS.SetRangeStart(Tok.getLocation());2335const char *PrevSpec;2336unsigned DiagID;2337SourceLocation Loc = Tok.getLocation();2338const clang::PrintingPolicy &Policy =2339Actions.getASTContext().getPrintingPolicy();23402341switch (Tok.getKind()) {2342case tok::identifier: // foo::bar2343case tok::coloncolon: // ::foo::bar2344llvm_unreachable("Annotation token should already be formed!");2345default:2346llvm_unreachable("Not a simple-type-specifier token!");23472348// type-name2349case tok::annot_typename: {2350DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID,2351getTypeAnnotation(Tok), Policy);2352DS.SetRangeEnd(Tok.getAnnotationEndLoc());2353ConsumeAnnotationToken();2354DS.Finish(Actions, Policy);2355return;2356}23572358case tok::kw__ExtInt:2359case tok::kw__BitInt: {2360DiagnoseBitIntUse(Tok);2361ExprResult ER = ParseExtIntegerArgument();2362if (ER.isInvalid())2363DS.SetTypeSpecError();2364else2365DS.SetBitIntType(Loc, ER.get(), PrevSpec, DiagID, Policy);23662367// Do this here because we have already consumed the close paren.2368DS.SetRangeEnd(PrevTokLocation);2369DS.Finish(Actions, Policy);2370return;2371}23722373// builtin types2374case tok::kw_short:2375DS.SetTypeSpecWidth(TypeSpecifierWidth::Short, Loc, PrevSpec, DiagID,2376Policy);2377break;2378case tok::kw_long:2379DS.SetTypeSpecWidth(TypeSpecifierWidth::Long, Loc, PrevSpec, DiagID,2380Policy);2381break;2382case tok::kw___int64:2383DS.SetTypeSpecWidth(TypeSpecifierWidth::LongLong, Loc, PrevSpec, DiagID,2384Policy);2385break;2386case tok::kw_signed:2387DS.SetTypeSpecSign(TypeSpecifierSign::Signed, Loc, PrevSpec, DiagID);2388break;2389case tok::kw_unsigned:2390DS.SetTypeSpecSign(TypeSpecifierSign::Unsigned, Loc, PrevSpec, DiagID);2391break;2392case tok::kw_void:2393DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID, Policy);2394break;2395case tok::kw_auto:2396DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec, DiagID, Policy);2397break;2398case tok::kw_char:2399DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID, Policy);2400break;2401case tok::kw_int:2402DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID, Policy);2403break;2404case tok::kw___int128:2405DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, DiagID, Policy);2406break;2407case tok::kw___bf16:2408DS.SetTypeSpecType(DeclSpec::TST_BFloat16, Loc, PrevSpec, DiagID, Policy);2409break;2410case tok::kw_half:2411DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, DiagID, Policy);2412break;2413case tok::kw_float:2414DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID, Policy);2415break;2416case tok::kw_double:2417DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID, Policy);2418break;2419case tok::kw__Float16:2420DS.SetTypeSpecType(DeclSpec::TST_float16, Loc, PrevSpec, DiagID, Policy);2421break;2422case tok::kw___float128:2423DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec, DiagID, Policy);2424break;2425case tok::kw___ibm128:2426DS.SetTypeSpecType(DeclSpec::TST_ibm128, Loc, PrevSpec, DiagID, Policy);2427break;2428case tok::kw_wchar_t:2429DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID, Policy);2430break;2431case tok::kw_char8_t:2432DS.SetTypeSpecType(DeclSpec::TST_char8, Loc, PrevSpec, DiagID, Policy);2433break;2434case tok::kw_char16_t:2435DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID, Policy);2436break;2437case tok::kw_char32_t:2438DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID, Policy);2439break;2440case tok::kw_bool:2441DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID, Policy);2442break;2443case tok::kw__Accum:2444DS.SetTypeSpecType(DeclSpec::TST_accum, Loc, PrevSpec, DiagID, Policy);2445break;2446case tok::kw__Fract:2447DS.SetTypeSpecType(DeclSpec::TST_fract, Loc, PrevSpec, DiagID, Policy);2448break;2449case tok::kw__Sat:2450DS.SetTypeSpecSat(Loc, PrevSpec, DiagID);2451break;2452#define GENERIC_IMAGE_TYPE(ImgType, Id) \2453case tok::kw_##ImgType##_t: \2454DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, DiagID, \2455Policy); \2456break;2457#include "clang/Basic/OpenCLImageTypes.def"24582459case tok::annot_decltype:2460case tok::kw_decltype:2461DS.SetRangeEnd(ParseDecltypeSpecifier(DS));2462return DS.Finish(Actions, Policy);24632464case tok::annot_pack_indexing_type:2465DS.SetRangeEnd(ParsePackIndexingType(DS));2466return DS.Finish(Actions, Policy);24672468// GNU typeof support.2469case tok::kw_typeof:2470ParseTypeofSpecifier(DS);2471DS.Finish(Actions, Policy);2472return;2473}2474ConsumeAnyToken();2475DS.SetRangeEnd(PrevTokLocation);2476DS.Finish(Actions, Policy);2477}24782479/// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++2480/// [dcl.name]), which is a non-empty sequence of type-specifiers,2481/// e.g., "const short int". Note that the DeclSpec is *not* finished2482/// by parsing the type-specifier-seq, because these sequences are2483/// typically followed by some form of declarator. Returns true and2484/// emits diagnostics if this is not a type-specifier-seq, false2485/// otherwise.2486///2487/// type-specifier-seq: [C++ 8.1]2488/// type-specifier type-specifier-seq[opt]2489///2490bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS, DeclaratorContext Context) {2491ParseSpecifierQualifierList(DS, AS_none,2492getDeclSpecContextFromDeclaratorContext(Context));2493DS.Finish(Actions, Actions.getASTContext().getPrintingPolicy());2494return false;2495}24962497/// Finish parsing a C++ unqualified-id that is a template-id of2498/// some form.2499///2500/// This routine is invoked when a '<' is encountered after an identifier or2501/// operator-function-id is parsed by \c ParseUnqualifiedId() to determine2502/// whether the unqualified-id is actually a template-id. This routine will2503/// then parse the template arguments and form the appropriate template-id to2504/// return to the caller.2505///2506/// \param SS the nested-name-specifier that precedes this template-id, if2507/// we're actually parsing a qualified-id.2508///2509/// \param ObjectType if this unqualified-id occurs within a member access2510/// expression, the type of the base object whose member is being accessed.2511///2512/// \param ObjectHadErrors this unqualified-id occurs within a member access2513/// expression, indicates whether the original subexpressions had any errors.2514///2515/// \param Name for constructor and destructor names, this is the actual2516/// identifier that may be a template-name.2517///2518/// \param NameLoc the location of the class-name in a constructor or2519/// destructor.2520///2521/// \param EnteringContext whether we're entering the scope of the2522/// nested-name-specifier.2523///2524/// \param Id as input, describes the template-name or operator-function-id2525/// that precedes the '<'. If template arguments were parsed successfully,2526/// will be updated with the template-id.2527///2528/// \param AssumeTemplateId When true, this routine will assume that the name2529/// refers to a template without performing name lookup to verify.2530///2531/// \returns true if a parse error occurred, false otherwise.2532bool Parser::ParseUnqualifiedIdTemplateId(2533CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors,2534SourceLocation TemplateKWLoc, IdentifierInfo *Name, SourceLocation NameLoc,2535bool EnteringContext, UnqualifiedId &Id, bool AssumeTemplateId) {2536assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id");25372538TemplateTy Template;2539TemplateNameKind TNK = TNK_Non_template;2540switch (Id.getKind()) {2541case UnqualifiedIdKind::IK_Identifier:2542case UnqualifiedIdKind::IK_OperatorFunctionId:2543case UnqualifiedIdKind::IK_LiteralOperatorId:2544if (AssumeTemplateId) {2545// We defer the injected-class-name checks until we've found whether2546// this template-id is used to form a nested-name-specifier or not.2547TNK = Actions.ActOnTemplateName(getCurScope(), SS, TemplateKWLoc, Id,2548ObjectType, EnteringContext, Template,2549/*AllowInjectedClassName*/ true);2550} else {2551bool MemberOfUnknownSpecialization;2552TNK = Actions.isTemplateName(getCurScope(), SS,2553TemplateKWLoc.isValid(), Id,2554ObjectType, EnteringContext, Template,2555MemberOfUnknownSpecialization);2556// If lookup found nothing but we're assuming that this is a template2557// name, double-check that makes sense syntactically before committing2558// to it.2559if (TNK == TNK_Undeclared_template &&2560isTemplateArgumentList(0) == TPResult::False)2561return false;25622563if (TNK == TNK_Non_template && MemberOfUnknownSpecialization &&2564ObjectType && isTemplateArgumentList(0) == TPResult::True) {2565// If we had errors before, ObjectType can be dependent even without any2566// templates, do not report missing template keyword in that case.2567if (!ObjectHadErrors) {2568// We have something like t->getAs<T>(), where getAs is a2569// member of an unknown specialization. However, this will only2570// parse correctly as a template, so suggest the keyword 'template'2571// before 'getAs' and treat this as a dependent template name.2572std::string Name;2573if (Id.getKind() == UnqualifiedIdKind::IK_Identifier)2574Name = std::string(Id.Identifier->getName());2575else {2576Name = "operator ";2577if (Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId)2578Name += getOperatorSpelling(Id.OperatorFunctionId.Operator);2579else2580Name += Id.Identifier->getName();2581}2582Diag(Id.StartLocation, diag::err_missing_dependent_template_keyword)2583<< Name2584<< FixItHint::CreateInsertion(Id.StartLocation, "template ");2585}2586TNK = Actions.ActOnTemplateName(2587getCurScope(), SS, TemplateKWLoc, Id, ObjectType, EnteringContext,2588Template, /*AllowInjectedClassName*/ true);2589} else if (TNK == TNK_Non_template) {2590return false;2591}2592}2593break;25942595case UnqualifiedIdKind::IK_ConstructorName: {2596UnqualifiedId TemplateName;2597bool MemberOfUnknownSpecialization;2598TemplateName.setIdentifier(Name, NameLoc);2599TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(),2600TemplateName, ObjectType,2601EnteringContext, Template,2602MemberOfUnknownSpecialization);2603if (TNK == TNK_Non_template)2604return false;2605break;2606}26072608case UnqualifiedIdKind::IK_DestructorName: {2609UnqualifiedId TemplateName;2610bool MemberOfUnknownSpecialization;2611TemplateName.setIdentifier(Name, NameLoc);2612if (ObjectType) {2613TNK = Actions.ActOnTemplateName(2614getCurScope(), SS, TemplateKWLoc, TemplateName, ObjectType,2615EnteringContext, Template, /*AllowInjectedClassName*/ true);2616} else {2617TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(),2618TemplateName, ObjectType,2619EnteringContext, Template,2620MemberOfUnknownSpecialization);26212622if (TNK == TNK_Non_template && !Id.DestructorName.get()) {2623Diag(NameLoc, diag::err_destructor_template_id)2624<< Name << SS.getRange();2625// Carry on to parse the template arguments before bailing out.2626}2627}2628break;2629}26302631default:2632return false;2633}26342635// Parse the enclosed template argument list.2636SourceLocation LAngleLoc, RAngleLoc;2637TemplateArgList TemplateArgs;2638if (ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs, RAngleLoc,2639Template))2640return true;26412642// If this is a non-template, we already issued a diagnostic.2643if (TNK == TNK_Non_template)2644return true;26452646if (Id.getKind() == UnqualifiedIdKind::IK_Identifier ||2647Id.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId ||2648Id.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId) {2649// Form a parsed representation of the template-id to be stored in the2650// UnqualifiedId.26512652// FIXME: Store name for literal operator too.2653const IdentifierInfo *TemplateII =2654Id.getKind() == UnqualifiedIdKind::IK_Identifier ? Id.Identifier2655: nullptr;2656OverloadedOperatorKind OpKind =2657Id.getKind() == UnqualifiedIdKind::IK_Identifier2658? OO_None2659: Id.OperatorFunctionId.Operator;26602661TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(2662TemplateKWLoc, Id.StartLocation, TemplateII, OpKind, Template, TNK,2663LAngleLoc, RAngleLoc, TemplateArgs, /*ArgsInvalid*/false, TemplateIds);26642665Id.setTemplateId(TemplateId);2666return false;2667}26682669// Bundle the template arguments together.2670ASTTemplateArgsPtr TemplateArgsPtr(TemplateArgs);26712672// Constructor and destructor names.2673TypeResult Type = Actions.ActOnTemplateIdType(2674getCurScope(), SS, TemplateKWLoc, Template, Name, NameLoc, LAngleLoc,2675TemplateArgsPtr, RAngleLoc, /*IsCtorOrDtorName=*/true);2676if (Type.isInvalid())2677return true;26782679if (Id.getKind() == UnqualifiedIdKind::IK_ConstructorName)2680Id.setConstructorName(Type.get(), NameLoc, RAngleLoc);2681else2682Id.setDestructorName(Id.StartLocation, Type.get(), RAngleLoc);26832684return false;2685}26862687/// Parse an operator-function-id or conversion-function-id as part2688/// of a C++ unqualified-id.2689///2690/// This routine is responsible only for parsing the operator-function-id or2691/// conversion-function-id; it does not handle template arguments in any way.2692///2693/// \code2694/// operator-function-id: [C++ 13.5]2695/// 'operator' operator2696///2697/// operator: one of2698/// new delete new[] delete[]2699/// + - * / % ^ & | ~2700/// ! = < > += -= *= /= %=2701/// ^= &= |= << >> >>= <<= == !=2702/// <= >= && || ++ -- , ->* ->2703/// () [] <=>2704///2705/// conversion-function-id: [C++ 12.3.2]2706/// operator conversion-type-id2707///2708/// conversion-type-id:2709/// type-specifier-seq conversion-declarator[opt]2710///2711/// conversion-declarator:2712/// ptr-operator conversion-declarator[opt]2713/// \endcode2714///2715/// \param SS The nested-name-specifier that preceded this unqualified-id. If2716/// non-empty, then we are parsing the unqualified-id of a qualified-id.2717///2718/// \param EnteringContext whether we are entering the scope of the2719/// nested-name-specifier.2720///2721/// \param ObjectType if this unqualified-id occurs within a member access2722/// expression, the type of the base object whose member is being accessed.2723///2724/// \param Result on a successful parse, contains the parsed unqualified-id.2725///2726/// \returns true if parsing fails, false otherwise.2727bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,2728ParsedType ObjectType,2729UnqualifiedId &Result) {2730assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");27312732// Consume the 'operator' keyword.2733SourceLocation KeywordLoc = ConsumeToken();27342735// Determine what kind of operator name we have.2736unsigned SymbolIdx = 0;2737SourceLocation SymbolLocations[3];2738OverloadedOperatorKind Op = OO_None;2739switch (Tok.getKind()) {2740case tok::kw_new:2741case tok::kw_delete: {2742bool isNew = Tok.getKind() == tok::kw_new;2743// Consume the 'new' or 'delete'.2744SymbolLocations[SymbolIdx++] = ConsumeToken();2745// Check for array new/delete.2746if (Tok.is(tok::l_square) &&2747(!getLangOpts().CPlusPlus11 || NextToken().isNot(tok::l_square))) {2748// Consume the '[' and ']'.2749BalancedDelimiterTracker T(*this, tok::l_square);2750T.consumeOpen();2751T.consumeClose();2752if (T.getCloseLocation().isInvalid())2753return true;27542755SymbolLocations[SymbolIdx++] = T.getOpenLocation();2756SymbolLocations[SymbolIdx++] = T.getCloseLocation();2757Op = isNew? OO_Array_New : OO_Array_Delete;2758} else {2759Op = isNew? OO_New : OO_Delete;2760}2761break;2762}27632764#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \2765case tok::Token: \2766SymbolLocations[SymbolIdx++] = ConsumeToken(); \2767Op = OO_##Name; \2768break;2769#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)2770#include "clang/Basic/OperatorKinds.def"27712772case tok::l_paren: {2773// Consume the '(' and ')'.2774BalancedDelimiterTracker T(*this, tok::l_paren);2775T.consumeOpen();2776T.consumeClose();2777if (T.getCloseLocation().isInvalid())2778return true;27792780SymbolLocations[SymbolIdx++] = T.getOpenLocation();2781SymbolLocations[SymbolIdx++] = T.getCloseLocation();2782Op = OO_Call;2783break;2784}27852786case tok::l_square: {2787// Consume the '[' and ']'.2788BalancedDelimiterTracker T(*this, tok::l_square);2789T.consumeOpen();2790T.consumeClose();2791if (T.getCloseLocation().isInvalid())2792return true;27932794SymbolLocations[SymbolIdx++] = T.getOpenLocation();2795SymbolLocations[SymbolIdx++] = T.getCloseLocation();2796Op = OO_Subscript;2797break;2798}27992800case tok::code_completion: {2801// Don't try to parse any further.2802cutOffParsing();2803// Code completion for the operator name.2804Actions.CodeCompletion().CodeCompleteOperatorName(getCurScope());2805return true;2806}28072808default:2809break;2810}28112812if (Op != OO_None) {2813// We have parsed an operator-function-id.2814Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations);2815return false;2816}28172818// Parse a literal-operator-id.2819//2820// literal-operator-id: C++11 [over.literal]2821// operator string-literal identifier2822// operator user-defined-string-literal28232824if (getLangOpts().CPlusPlus11 && isTokenStringLiteral()) {2825Diag(Tok.getLocation(), diag::warn_cxx98_compat_literal_operator);28262827SourceLocation DiagLoc;2828unsigned DiagId = 0;28292830// We're past translation phase 6, so perform string literal concatenation2831// before checking for "".2832SmallVector<Token, 4> Toks;2833SmallVector<SourceLocation, 4> TokLocs;2834while (isTokenStringLiteral()) {2835if (!Tok.is(tok::string_literal) && !DiagId) {2836// C++11 [over.literal]p1:2837// The string-literal or user-defined-string-literal in a2838// literal-operator-id shall have no encoding-prefix [...].2839DiagLoc = Tok.getLocation();2840DiagId = diag::err_literal_operator_string_prefix;2841}2842Toks.push_back(Tok);2843TokLocs.push_back(ConsumeStringToken());2844}28452846StringLiteralParser Literal(Toks, PP);2847if (Literal.hadError)2848return true;28492850// Grab the literal operator's suffix, which will be either the next token2851// or a ud-suffix from the string literal.2852bool IsUDSuffix = !Literal.getUDSuffix().empty();2853IdentifierInfo *II = nullptr;2854SourceLocation SuffixLoc;2855if (IsUDSuffix) {2856II = &PP.getIdentifierTable().get(Literal.getUDSuffix());2857SuffixLoc =2858Lexer::AdvanceToTokenCharacter(TokLocs[Literal.getUDSuffixToken()],2859Literal.getUDSuffixOffset(),2860PP.getSourceManager(), getLangOpts());2861} else if (Tok.is(tok::identifier)) {2862II = Tok.getIdentifierInfo();2863SuffixLoc = ConsumeToken();2864TokLocs.push_back(SuffixLoc);2865} else {2866Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;2867return true;2868}28692870// The string literal must be empty.2871if (!Literal.GetString().empty() || Literal.Pascal) {2872// C++11 [over.literal]p1:2873// The string-literal or user-defined-string-literal in a2874// literal-operator-id shall [...] contain no characters2875// other than the implicit terminating '\0'.2876DiagLoc = TokLocs.front();2877DiagId = diag::err_literal_operator_string_not_empty;2878}28792880if (DiagId) {2881// This isn't a valid literal-operator-id, but we think we know2882// what the user meant. Tell them what they should have written.2883SmallString<32> Str;2884Str += "\"\"";2885Str += II->getName();2886Diag(DiagLoc, DiagId) << FixItHint::CreateReplacement(2887SourceRange(TokLocs.front(), TokLocs.back()), Str);2888}28892890Result.setLiteralOperatorId(II, KeywordLoc, SuffixLoc);28912892return Actions.checkLiteralOperatorId(SS, Result, IsUDSuffix);2893}28942895// Parse a conversion-function-id.2896//2897// conversion-function-id: [C++ 12.3.2]2898// operator conversion-type-id2899//2900// conversion-type-id:2901// type-specifier-seq conversion-declarator[opt]2902//2903// conversion-declarator:2904// ptr-operator conversion-declarator[opt]29052906// Parse the type-specifier-seq.2907DeclSpec DS(AttrFactory);2908if (ParseCXXTypeSpecifierSeq(2909DS, DeclaratorContext::ConversionId)) // FIXME: ObjectType?2910return true;29112912// Parse the conversion-declarator, which is merely a sequence of2913// ptr-operators.2914Declarator D(DS, ParsedAttributesView::none(),2915DeclaratorContext::ConversionId);2916ParseDeclaratorInternal(D, /*DirectDeclParser=*/nullptr);29172918// Finish up the type.2919TypeResult Ty = Actions.ActOnTypeName(D);2920if (Ty.isInvalid())2921return true;29222923// Note that this is a conversion-function-id.2924Result.setConversionFunctionId(KeywordLoc, Ty.get(),2925D.getSourceRange().getEnd());2926return false;2927}29282929/// Parse a C++ unqualified-id (or a C identifier), which describes the2930/// name of an entity.2931///2932/// \code2933/// unqualified-id: [C++ expr.prim.general]2934/// identifier2935/// operator-function-id2936/// conversion-function-id2937/// [C++0x] literal-operator-id [TODO]2938/// ~ class-name2939/// template-id2940///2941/// \endcode2942///2943/// \param SS The nested-name-specifier that preceded this unqualified-id. If2944/// non-empty, then we are parsing the unqualified-id of a qualified-id.2945///2946/// \param ObjectType if this unqualified-id occurs within a member access2947/// expression, the type of the base object whose member is being accessed.2948///2949/// \param ObjectHadErrors if this unqualified-id occurs within a member access2950/// expression, indicates whether the original subexpressions had any errors.2951/// When true, diagnostics for missing 'template' keyword will be supressed.2952///2953/// \param EnteringContext whether we are entering the scope of the2954/// nested-name-specifier.2955///2956/// \param AllowDestructorName whether we allow parsing of a destructor name.2957///2958/// \param AllowConstructorName whether we allow parsing a constructor name.2959///2960/// \param AllowDeductionGuide whether we allow parsing a deduction guide name.2961///2962/// \param Result on a successful parse, contains the parsed unqualified-id.2963///2964/// \returns true if parsing fails, false otherwise.2965bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType,2966bool ObjectHadErrors, bool EnteringContext,2967bool AllowDestructorName,2968bool AllowConstructorName,2969bool AllowDeductionGuide,2970SourceLocation *TemplateKWLoc,2971UnqualifiedId &Result) {2972if (TemplateKWLoc)2973*TemplateKWLoc = SourceLocation();29742975// Handle 'A::template B'. This is for template-ids which have not2976// already been annotated by ParseOptionalCXXScopeSpecifier().2977bool TemplateSpecified = false;2978if (Tok.is(tok::kw_template)) {2979if (TemplateKWLoc && (ObjectType || SS.isSet())) {2980TemplateSpecified = true;2981*TemplateKWLoc = ConsumeToken();2982} else {2983SourceLocation TemplateLoc = ConsumeToken();2984Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id)2985<< FixItHint::CreateRemoval(TemplateLoc);2986}2987}29882989// unqualified-id:2990// identifier2991// template-id (when it hasn't already been annotated)2992if (Tok.is(tok::identifier)) {2993ParseIdentifier:2994// Consume the identifier.2995IdentifierInfo *Id = Tok.getIdentifierInfo();2996SourceLocation IdLoc = ConsumeToken();29972998if (!getLangOpts().CPlusPlus) {2999// If we're not in C++, only identifiers matter. Record the3000// identifier and return.3001Result.setIdentifier(Id, IdLoc);3002return false;3003}30043005ParsedTemplateTy TemplateName;3006if (AllowConstructorName &&3007Actions.isCurrentClassName(*Id, getCurScope(), &SS)) {3008// We have parsed a constructor name.3009ParsedType Ty = Actions.getConstructorName(*Id, IdLoc, getCurScope(), SS,3010EnteringContext);3011if (!Ty)3012return true;3013Result.setConstructorName(Ty, IdLoc, IdLoc);3014} else if (getLangOpts().CPlusPlus17 && AllowDeductionGuide &&3015SS.isEmpty() &&3016Actions.isDeductionGuideName(getCurScope(), *Id, IdLoc, SS,3017&TemplateName)) {3018// We have parsed a template-name naming a deduction guide.3019Result.setDeductionGuideName(TemplateName, IdLoc);3020} else {3021// We have parsed an identifier.3022Result.setIdentifier(Id, IdLoc);3023}30243025// If the next token is a '<', we may have a template.3026TemplateTy Template;3027if (Tok.is(tok::less))3028return ParseUnqualifiedIdTemplateId(3029SS, ObjectType, ObjectHadErrors,3030TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), Id, IdLoc,3031EnteringContext, Result, TemplateSpecified);30323033if (TemplateSpecified) {3034TemplateNameKind TNK =3035Actions.ActOnTemplateName(getCurScope(), SS, *TemplateKWLoc, Result,3036ObjectType, EnteringContext, Template,3037/*AllowInjectedClassName=*/true);3038if (TNK == TNK_Non_template)3039return true;30403041// C++2c [tem.names]p63042// A name prefixed by the keyword template shall be followed by a template3043// argument list or refer to a class template or an alias template.3044if ((TNK == TNK_Function_template || TNK == TNK_Dependent_template_name ||3045TNK == TNK_Var_template) &&3046!Tok.is(tok::less))3047Diag(IdLoc, diag::missing_template_arg_list_after_template_kw);3048}3049return false;3050}30513052// unqualified-id:3053// template-id (already parsed and annotated)3054if (Tok.is(tok::annot_template_id)) {3055TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);30563057// FIXME: Consider passing invalid template-ids on to callers; they may3058// be able to recover better than we can.3059if (TemplateId->isInvalid()) {3060ConsumeAnnotationToken();3061return true;3062}30633064// If the template-name names the current class, then this is a constructor3065if (AllowConstructorName && TemplateId->Name &&3066Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {3067if (SS.isSet()) {3068// C++ [class.qual]p2 specifies that a qualified template-name3069// is taken as the constructor name where a constructor can be3070// declared. Thus, the template arguments are extraneous, so3071// complain about them and remove them entirely.3072Diag(TemplateId->TemplateNameLoc,3073diag::err_out_of_line_constructor_template_id)3074<< TemplateId->Name3075<< FixItHint::CreateRemoval(3076SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc));3077ParsedType Ty = Actions.getConstructorName(3078*TemplateId->Name, TemplateId->TemplateNameLoc, getCurScope(), SS,3079EnteringContext);3080if (!Ty)3081return true;3082Result.setConstructorName(Ty, TemplateId->TemplateNameLoc,3083TemplateId->RAngleLoc);3084ConsumeAnnotationToken();3085return false;3086}30873088Result.setConstructorTemplateId(TemplateId);3089ConsumeAnnotationToken();3090return false;3091}30923093// We have already parsed a template-id; consume the annotation token as3094// our unqualified-id.3095Result.setTemplateId(TemplateId);3096SourceLocation TemplateLoc = TemplateId->TemplateKWLoc;3097if (TemplateLoc.isValid()) {3098if (TemplateKWLoc && (ObjectType || SS.isSet()))3099*TemplateKWLoc = TemplateLoc;3100else3101Diag(TemplateLoc, diag::err_unexpected_template_in_unqualified_id)3102<< FixItHint::CreateRemoval(TemplateLoc);3103}3104ConsumeAnnotationToken();3105return false;3106}31073108// unqualified-id:3109// operator-function-id3110// conversion-function-id3111if (Tok.is(tok::kw_operator)) {3112if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, Result))3113return true;31143115// If we have an operator-function-id or a literal-operator-id and the next3116// token is a '<', we may have a3117//3118// template-id:3119// operator-function-id < template-argument-list[opt] >3120TemplateTy Template;3121if ((Result.getKind() == UnqualifiedIdKind::IK_OperatorFunctionId ||3122Result.getKind() == UnqualifiedIdKind::IK_LiteralOperatorId) &&3123Tok.is(tok::less))3124return ParseUnqualifiedIdTemplateId(3125SS, ObjectType, ObjectHadErrors,3126TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), nullptr,3127SourceLocation(), EnteringContext, Result, TemplateSpecified);3128else if (TemplateSpecified &&3129Actions.ActOnTemplateName(3130getCurScope(), SS, *TemplateKWLoc, Result, ObjectType,3131EnteringContext, Template,3132/*AllowInjectedClassName*/ true) == TNK_Non_template)3133return true;31343135return false;3136}31373138if (getLangOpts().CPlusPlus &&3139(AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) {3140// C++ [expr.unary.op]p10:3141// There is an ambiguity in the unary-expression ~X(), where X is a3142// class-name. The ambiguity is resolved in favor of treating ~ as a3143// unary complement rather than treating ~X as referring to a destructor.31443145// Parse the '~'.3146SourceLocation TildeLoc = ConsumeToken();31473148if (TemplateSpecified) {3149// C++ [temp.names]p3:3150// A name prefixed by the keyword template shall be a template-id [...]3151//3152// A template-id cannot begin with a '~' token. This would never work3153// anyway: x.~A<int>() would specify that the destructor is a template,3154// not that 'A' is a template.3155//3156// FIXME: Suggest replacing the attempted destructor name with a correct3157// destructor name and recover. (This is not trivial if this would become3158// a pseudo-destructor name).3159Diag(*TemplateKWLoc, diag::err_unexpected_template_in_destructor_name)3160<< Tok.getLocation();3161return true;3162}31633164if (SS.isEmpty() && Tok.is(tok::kw_decltype)) {3165DeclSpec DS(AttrFactory);3166SourceLocation EndLoc = ParseDecltypeSpecifier(DS);3167if (ParsedType Type =3168Actions.getDestructorTypeForDecltype(DS, ObjectType)) {3169Result.setDestructorName(TildeLoc, Type, EndLoc);3170return false;3171}3172return true;3173}31743175// Parse the class-name.3176if (Tok.isNot(tok::identifier)) {3177Diag(Tok, diag::err_destructor_tilde_identifier);3178return true;3179}31803181// If the user wrote ~T::T, correct it to T::~T.3182DeclaratorScopeObj DeclScopeObj(*this, SS);3183if (NextToken().is(tok::coloncolon)) {3184// Don't let ParseOptionalCXXScopeSpecifier() "correct"3185// `int A; struct { ~A::A(); };` to `int A; struct { ~A:A(); };`,3186// it will confuse this recovery logic.3187ColonProtectionRAIIObject ColonRAII(*this, false);31883189if (SS.isSet()) {3190AnnotateScopeToken(SS, /*NewAnnotation*/true);3191SS.clear();3192}3193if (ParseOptionalCXXScopeSpecifier(SS, ObjectType, ObjectHadErrors,3194EnteringContext))3195return true;3196if (SS.isNotEmpty())3197ObjectType = nullptr;3198if (Tok.isNot(tok::identifier) || NextToken().is(tok::coloncolon) ||3199!SS.isSet()) {3200Diag(TildeLoc, diag::err_destructor_tilde_scope);3201return true;3202}32033204// Recover as if the tilde had been written before the identifier.3205Diag(TildeLoc, diag::err_destructor_tilde_scope)3206<< FixItHint::CreateRemoval(TildeLoc)3207<< FixItHint::CreateInsertion(Tok.getLocation(), "~");32083209// Temporarily enter the scope for the rest of this function.3210if (Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))3211DeclScopeObj.EnterDeclaratorScope();3212}32133214// Parse the class-name (or template-name in a simple-template-id).3215IdentifierInfo *ClassName = Tok.getIdentifierInfo();3216SourceLocation ClassNameLoc = ConsumeToken();32173218if (Tok.is(tok::less)) {3219Result.setDestructorName(TildeLoc, nullptr, ClassNameLoc);3220return ParseUnqualifiedIdTemplateId(3221SS, ObjectType, ObjectHadErrors,3222TemplateKWLoc ? *TemplateKWLoc : SourceLocation(), ClassName,3223ClassNameLoc, EnteringContext, Result, TemplateSpecified);3224}32253226// Note that this is a destructor name.3227ParsedType Ty =3228Actions.getDestructorName(*ClassName, ClassNameLoc, getCurScope(), SS,3229ObjectType, EnteringContext);3230if (!Ty)3231return true;32323233Result.setDestructorName(TildeLoc, Ty, ClassNameLoc);3234return false;3235}32363237switch (Tok.getKind()) {3238#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:3239#include "clang/Basic/TransformTypeTraits.def"3240if (!NextToken().is(tok::l_paren)) {3241Tok.setKind(tok::identifier);3242Diag(Tok, diag::ext_keyword_as_ident)3243<< Tok.getIdentifierInfo()->getName() << 0;3244goto ParseIdentifier;3245}3246[[fallthrough]];3247default:3248Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus;3249return true;3250}3251}32523253/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate3254/// memory in a typesafe manner and call constructors.3255///3256/// This method is called to parse the new expression after the optional :: has3257/// been already parsed. If the :: was present, "UseGlobal" is true and "Start"3258/// is its location. Otherwise, "Start" is the location of the 'new' token.3259///3260/// new-expression:3261/// '::'[opt] 'new' new-placement[opt] new-type-id3262/// new-initializer[opt]3263/// '::'[opt] 'new' new-placement[opt] '(' type-id ')'3264/// new-initializer[opt]3265///3266/// new-placement:3267/// '(' expression-list ')'3268///3269/// new-type-id:3270/// type-specifier-seq new-declarator[opt]3271/// [GNU] attributes type-specifier-seq new-declarator[opt]3272///3273/// new-declarator:3274/// ptr-operator new-declarator[opt]3275/// direct-new-declarator3276///3277/// new-initializer:3278/// '(' expression-list[opt] ')'3279/// [C++0x] braced-init-list3280///3281ExprResult3282Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {3283assert(Tok.is(tok::kw_new) && "expected 'new' token");3284ConsumeToken(); // Consume 'new'32853286// A '(' now can be a new-placement or the '(' wrapping the type-id in the3287// second form of new-expression. It can't be a new-type-id.32883289ExprVector PlacementArgs;3290SourceLocation PlacementLParen, PlacementRParen;32913292SourceRange TypeIdParens;3293DeclSpec DS(AttrFactory);3294Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),3295DeclaratorContext::CXXNew);3296if (Tok.is(tok::l_paren)) {3297// If it turns out to be a placement, we change the type location.3298BalancedDelimiterTracker T(*this, tok::l_paren);3299T.consumeOpen();3300PlacementLParen = T.getOpenLocation();3301if (ParseExpressionListOrTypeId(PlacementArgs, DeclaratorInfo)) {3302SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);3303return ExprError();3304}33053306T.consumeClose();3307PlacementRParen = T.getCloseLocation();3308if (PlacementRParen.isInvalid()) {3309SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);3310return ExprError();3311}33123313if (PlacementArgs.empty()) {3314// Reset the placement locations. There was no placement.3315TypeIdParens = T.getRange();3316PlacementLParen = PlacementRParen = SourceLocation();3317} else {3318// We still need the type.3319if (Tok.is(tok::l_paren)) {3320BalancedDelimiterTracker T(*this, tok::l_paren);3321T.consumeOpen();3322MaybeParseGNUAttributes(DeclaratorInfo);3323ParseSpecifierQualifierList(DS);3324DeclaratorInfo.SetSourceRange(DS.getSourceRange());3325ParseDeclarator(DeclaratorInfo);3326T.consumeClose();3327TypeIdParens = T.getRange();3328} else {3329MaybeParseGNUAttributes(DeclaratorInfo);3330if (ParseCXXTypeSpecifierSeq(DS))3331DeclaratorInfo.setInvalidType(true);3332else {3333DeclaratorInfo.SetSourceRange(DS.getSourceRange());3334ParseDeclaratorInternal(DeclaratorInfo,3335&Parser::ParseDirectNewDeclarator);3336}3337}3338}3339} else {3340// A new-type-id is a simplified type-id, where essentially the3341// direct-declarator is replaced by a direct-new-declarator.3342MaybeParseGNUAttributes(DeclaratorInfo);3343if (ParseCXXTypeSpecifierSeq(DS, DeclaratorContext::CXXNew))3344DeclaratorInfo.setInvalidType(true);3345else {3346DeclaratorInfo.SetSourceRange(DS.getSourceRange());3347ParseDeclaratorInternal(DeclaratorInfo,3348&Parser::ParseDirectNewDeclarator);3349}3350}3351if (DeclaratorInfo.isInvalidType()) {3352SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);3353return ExprError();3354}33553356ExprResult Initializer;33573358if (Tok.is(tok::l_paren)) {3359SourceLocation ConstructorLParen, ConstructorRParen;3360ExprVector ConstructorArgs;3361BalancedDelimiterTracker T(*this, tok::l_paren);3362T.consumeOpen();3363ConstructorLParen = T.getOpenLocation();3364if (Tok.isNot(tok::r_paren)) {3365auto RunSignatureHelp = [&]() {3366ParsedType TypeRep = Actions.ActOnTypeName(DeclaratorInfo).get();3367QualType PreferredType;3368// ActOnTypeName might adjust DeclaratorInfo and return a null type even3369// the passing DeclaratorInfo is valid, e.g. running SignatureHelp on3370// `new decltype(invalid) (^)`.3371if (TypeRep)3372PreferredType =3373Actions.CodeCompletion().ProduceConstructorSignatureHelp(3374TypeRep.get()->getCanonicalTypeInternal(),3375DeclaratorInfo.getEndLoc(), ConstructorArgs,3376ConstructorLParen,3377/*Braced=*/false);3378CalledSignatureHelp = true;3379return PreferredType;3380};3381if (ParseExpressionList(ConstructorArgs, [&] {3382PreferredType.enterFunctionArgument(Tok.getLocation(),3383RunSignatureHelp);3384})) {3385if (PP.isCodeCompletionReached() && !CalledSignatureHelp)3386RunSignatureHelp();3387SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);3388return ExprError();3389}3390}3391T.consumeClose();3392ConstructorRParen = T.getCloseLocation();3393if (ConstructorRParen.isInvalid()) {3394SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);3395return ExprError();3396}3397Initializer = Actions.ActOnParenListExpr(ConstructorLParen,3398ConstructorRParen,3399ConstructorArgs);3400} else if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus11) {3401Diag(Tok.getLocation(),3402diag::warn_cxx98_compat_generalized_initializer_lists);3403Initializer = ParseBraceInitializer();3404}3405if (Initializer.isInvalid())3406return Initializer;34073408return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,3409PlacementArgs, PlacementRParen,3410TypeIdParens, DeclaratorInfo, Initializer.get());3411}34123413/// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be3414/// passed to ParseDeclaratorInternal.3415///3416/// direct-new-declarator:3417/// '[' expression[opt] ']'3418/// direct-new-declarator '[' constant-expression ']'3419///3420void Parser::ParseDirectNewDeclarator(Declarator &D) {3421// Parse the array dimensions.3422bool First = true;3423while (Tok.is(tok::l_square)) {3424// An array-size expression can't start with a lambda.3425if (CheckProhibitedCXX11Attribute())3426continue;34273428BalancedDelimiterTracker T(*this, tok::l_square);3429T.consumeOpen();34303431ExprResult Size =3432First ? (Tok.is(tok::r_square) ? ExprResult() : ParseExpression())3433: ParseConstantExpression();3434if (Size.isInvalid()) {3435// Recover3436SkipUntil(tok::r_square, StopAtSemi);3437return;3438}3439First = false;34403441T.consumeClose();34423443// Attributes here appertain to the array type. C++11 [expr.new]p5.3444ParsedAttributes Attrs(AttrFactory);3445MaybeParseCXX11Attributes(Attrs);34463447D.AddTypeInfo(DeclaratorChunk::getArray(0,3448/*isStatic=*/false, /*isStar=*/false,3449Size.get(), T.getOpenLocation(),3450T.getCloseLocation()),3451std::move(Attrs), T.getCloseLocation());34523453if (T.getCloseLocation().isInvalid())3454return;3455}3456}34573458/// ParseExpressionListOrTypeId - Parse either an expression-list or a type-id.3459/// This ambiguity appears in the syntax of the C++ new operator.3460///3461/// new-expression:3462/// '::'[opt] 'new' new-placement[opt] '(' type-id ')'3463/// new-initializer[opt]3464///3465/// new-placement:3466/// '(' expression-list ')'3467///3468bool Parser::ParseExpressionListOrTypeId(3469SmallVectorImpl<Expr*> &PlacementArgs,3470Declarator &D) {3471// The '(' was already consumed.3472if (isTypeIdInParens()) {3473ParseSpecifierQualifierList(D.getMutableDeclSpec());3474D.SetSourceRange(D.getDeclSpec().getSourceRange());3475ParseDeclarator(D);3476return D.isInvalidType();3477}34783479// It's not a type, it has to be an expression list.3480return ParseExpressionList(PlacementArgs);3481}34823483/// ParseCXXDeleteExpression - Parse a C++ delete-expression. Delete is used3484/// to free memory allocated by new.3485///3486/// This method is called to parse the 'delete' expression after the optional3487/// '::' has been already parsed. If the '::' was present, "UseGlobal" is true3488/// and "Start" is its location. Otherwise, "Start" is the location of the3489/// 'delete' token.3490///3491/// delete-expression:3492/// '::'[opt] 'delete' cast-expression3493/// '::'[opt] 'delete' '[' ']' cast-expression3494ExprResult3495Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) {3496assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword");3497ConsumeToken(); // Consume 'delete'34983499// Array delete?3500bool ArrayDelete = false;3501if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) {3502// C++11 [expr.delete]p1:3503// Whenever the delete keyword is followed by empty square brackets, it3504// shall be interpreted as [array delete].3505// [Footnote: A lambda expression with a lambda-introducer that consists3506// of empty square brackets can follow the delete keyword if3507// the lambda expression is enclosed in parentheses.]35083509const Token Next = GetLookAheadToken(2);35103511// Basic lookahead to check if we have a lambda expression.3512if (Next.isOneOf(tok::l_brace, tok::less) ||3513(Next.is(tok::l_paren) &&3514(GetLookAheadToken(3).is(tok::r_paren) ||3515(GetLookAheadToken(3).is(tok::identifier) &&3516GetLookAheadToken(4).is(tok::identifier))))) {3517TentativeParsingAction TPA(*this);3518SourceLocation LSquareLoc = Tok.getLocation();3519SourceLocation RSquareLoc = NextToken().getLocation();35203521// SkipUntil can't skip pairs of </*...*/>; don't emit a FixIt in this3522// case.3523SkipUntil({tok::l_brace, tok::less}, StopBeforeMatch);3524SourceLocation RBraceLoc;3525bool EmitFixIt = false;3526if (Tok.is(tok::l_brace)) {3527ConsumeBrace();3528SkipUntil(tok::r_brace, StopBeforeMatch);3529RBraceLoc = Tok.getLocation();3530EmitFixIt = true;3531}35323533TPA.Revert();35343535if (EmitFixIt)3536Diag(Start, diag::err_lambda_after_delete)3537<< SourceRange(Start, RSquareLoc)3538<< FixItHint::CreateInsertion(LSquareLoc, "(")3539<< FixItHint::CreateInsertion(3540Lexer::getLocForEndOfToken(3541RBraceLoc, 0, Actions.getSourceManager(), getLangOpts()),3542")");3543else3544Diag(Start, diag::err_lambda_after_delete)3545<< SourceRange(Start, RSquareLoc);35463547// Warn that the non-capturing lambda isn't surrounded by parentheses3548// to disambiguate it from 'delete[]'.3549ExprResult Lambda = ParseLambdaExpression();3550if (Lambda.isInvalid())3551return ExprError();35523553// Evaluate any postfix expressions used on the lambda.3554Lambda = ParsePostfixExpressionSuffix(Lambda);3555if (Lambda.isInvalid())3556return ExprError();3557return Actions.ActOnCXXDelete(Start, UseGlobal, /*ArrayForm=*/false,3558Lambda.get());3559}35603561ArrayDelete = true;3562BalancedDelimiterTracker T(*this, tok::l_square);35633564T.consumeOpen();3565T.consumeClose();3566if (T.getCloseLocation().isInvalid())3567return ExprError();3568}35693570ExprResult Operand(ParseCastExpression(AnyCastExpr));3571if (Operand.isInvalid())3572return Operand;35733574return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.get());3575}35763577/// ParseRequiresExpression - Parse a C++2a requires-expression.3578/// C++2a [expr.prim.req]p13579/// A requires-expression provides a concise way to express requirements on3580/// template arguments. A requirement is one that can be checked by name3581/// lookup (6.4) or by checking properties of types and expressions.3582///3583/// requires-expression:3584/// 'requires' requirement-parameter-list[opt] requirement-body3585///3586/// requirement-parameter-list:3587/// '(' parameter-declaration-clause[opt] ')'3588///3589/// requirement-body:3590/// '{' requirement-seq '}'3591///3592/// requirement-seq:3593/// requirement3594/// requirement-seq requirement3595///3596/// requirement:3597/// simple-requirement3598/// type-requirement3599/// compound-requirement3600/// nested-requirement3601ExprResult Parser::ParseRequiresExpression() {3602assert(Tok.is(tok::kw_requires) && "Expected 'requires' keyword");3603SourceLocation RequiresKWLoc = ConsumeToken(); // Consume 'requires'36043605llvm::SmallVector<ParmVarDecl *, 2> LocalParameterDecls;3606BalancedDelimiterTracker Parens(*this, tok::l_paren);3607if (Tok.is(tok::l_paren)) {3608// requirement parameter list is present.3609ParseScope LocalParametersScope(this, Scope::FunctionPrototypeScope |3610Scope::DeclScope);3611Parens.consumeOpen();3612if (!Tok.is(tok::r_paren)) {3613ParsedAttributes FirstArgAttrs(getAttrFactory());3614SourceLocation EllipsisLoc;3615llvm::SmallVector<DeclaratorChunk::ParamInfo, 2> LocalParameters;3616ParseParameterDeclarationClause(DeclaratorContext::RequiresExpr,3617FirstArgAttrs, LocalParameters,3618EllipsisLoc);3619if (EllipsisLoc.isValid())3620Diag(EllipsisLoc, diag::err_requires_expr_parameter_list_ellipsis);3621for (auto &ParamInfo : LocalParameters)3622LocalParameterDecls.push_back(cast<ParmVarDecl>(ParamInfo.Param));3623}3624Parens.consumeClose();3625}36263627BalancedDelimiterTracker Braces(*this, tok::l_brace);3628if (Braces.expectAndConsume())3629return ExprError();36303631// Start of requirement list3632llvm::SmallVector<concepts::Requirement *, 2> Requirements;36333634// C++2a [expr.prim.req]p23635// Expressions appearing within a requirement-body are unevaluated operands.3636EnterExpressionEvaluationContext Ctx(3637Actions, Sema::ExpressionEvaluationContext::Unevaluated);36383639ParseScope BodyScope(this, Scope::DeclScope);3640// Create a separate diagnostic pool for RequiresExprBodyDecl.3641// Dependent diagnostics are attached to this Decl and non-depenedent3642// diagnostics are surfaced after this parse.3643ParsingDeclRAIIObject ParsingBodyDecl(*this, ParsingDeclRAIIObject::NoParent);3644RequiresExprBodyDecl *Body = Actions.ActOnStartRequiresExpr(3645RequiresKWLoc, LocalParameterDecls, getCurScope());36463647if (Tok.is(tok::r_brace)) {3648// Grammar does not allow an empty body.3649// requirement-body:3650// { requirement-seq }3651// requirement-seq:3652// requirement3653// requirement-seq requirement3654Diag(Tok, diag::err_empty_requires_expr);3655// Continue anyway and produce a requires expr with no requirements.3656} else {3657while (!Tok.is(tok::r_brace)) {3658switch (Tok.getKind()) {3659case tok::l_brace: {3660// Compound requirement3661// C++ [expr.prim.req.compound]3662// compound-requirement:3663// '{' expression '}' 'noexcept'[opt]3664// return-type-requirement[opt] ';'3665// return-type-requirement:3666// trailing-return-type3667// '->' cv-qualifier-seq[opt] constrained-parameter3668// cv-qualifier-seq[opt] abstract-declarator[opt]3669BalancedDelimiterTracker ExprBraces(*this, tok::l_brace);3670ExprBraces.consumeOpen();3671ExprResult Expression =3672Actions.CorrectDelayedTyposInExpr(ParseExpression());3673if (!Expression.isUsable()) {3674ExprBraces.skipToEnd();3675SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);3676break;3677}3678if (ExprBraces.consumeClose())3679ExprBraces.skipToEnd();36803681concepts::Requirement *Req = nullptr;3682SourceLocation NoexceptLoc;3683TryConsumeToken(tok::kw_noexcept, NoexceptLoc);3684if (Tok.is(tok::semi)) {3685Req = Actions.ActOnCompoundRequirement(Expression.get(), NoexceptLoc);3686if (Req)3687Requirements.push_back(Req);3688break;3689}3690if (!TryConsumeToken(tok::arrow))3691// User probably forgot the arrow, remind them and try to continue.3692Diag(Tok, diag::err_requires_expr_missing_arrow)3693<< FixItHint::CreateInsertion(Tok.getLocation(), "->");3694// Try to parse a 'type-constraint'3695if (TryAnnotateTypeConstraint()) {3696SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);3697break;3698}3699if (!isTypeConstraintAnnotation()) {3700Diag(Tok, diag::err_requires_expr_expected_type_constraint);3701SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);3702break;3703}3704CXXScopeSpec SS;3705if (Tok.is(tok::annot_cxxscope)) {3706Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),3707Tok.getAnnotationRange(),3708SS);3709ConsumeAnnotationToken();3710}37113712Req = Actions.ActOnCompoundRequirement(3713Expression.get(), NoexceptLoc, SS, takeTemplateIdAnnotation(Tok),3714TemplateParameterDepth);3715ConsumeAnnotationToken();3716if (Req)3717Requirements.push_back(Req);3718break;3719}3720default: {3721bool PossibleRequiresExprInSimpleRequirement = false;3722if (Tok.is(tok::kw_requires)) {3723auto IsNestedRequirement = [&] {3724RevertingTentativeParsingAction TPA(*this);3725ConsumeToken(); // 'requires'3726if (Tok.is(tok::l_brace))3727// This is a requires expression3728// requires (T t) {3729// requires { t++; };3730// ... ^3731// }3732return false;3733if (Tok.is(tok::l_paren)) {3734// This might be the parameter list of a requires expression3735ConsumeParen();3736auto Res = TryParseParameterDeclarationClause();3737if (Res != TPResult::False) {3738// Skip to the closing parenthesis3739unsigned Depth = 1;3740while (Depth != 0) {3741bool FoundParen = SkipUntil(tok::l_paren, tok::r_paren,3742SkipUntilFlags::StopBeforeMatch);3743if (!FoundParen)3744break;3745if (Tok.is(tok::l_paren))3746Depth++;3747else if (Tok.is(tok::r_paren))3748Depth--;3749ConsumeAnyToken();3750}3751// requires (T t) {3752// requires () ?3753// ... ^3754// - OR -3755// requires (int x) ?3756// ... ^3757// }3758if (Tok.is(tok::l_brace))3759// requires (...) {3760// ^ - a requires expression as a3761// simple-requirement.3762return false;3763}3764}3765return true;3766};3767if (IsNestedRequirement()) {3768ConsumeToken();3769// Nested requirement3770// C++ [expr.prim.req.nested]3771// nested-requirement:3772// 'requires' constraint-expression ';'3773ExprResult ConstraintExpr =3774Actions.CorrectDelayedTyposInExpr(ParseConstraintExpression());3775if (ConstraintExpr.isInvalid() || !ConstraintExpr.isUsable()) {3776SkipUntil(tok::semi, tok::r_brace,3777SkipUntilFlags::StopBeforeMatch);3778break;3779}3780if (auto *Req =3781Actions.ActOnNestedRequirement(ConstraintExpr.get()))3782Requirements.push_back(Req);3783else {3784SkipUntil(tok::semi, tok::r_brace,3785SkipUntilFlags::StopBeforeMatch);3786break;3787}3788break;3789} else3790PossibleRequiresExprInSimpleRequirement = true;3791} else if (Tok.is(tok::kw_typename)) {3792// This might be 'typename T::value_type;' (a type requirement) or3793// 'typename T::value_type{};' (a simple requirement).3794TentativeParsingAction TPA(*this);37953796// We need to consume the typename to allow 'requires { typename a; }'3797SourceLocation TypenameKWLoc = ConsumeToken();3798if (TryAnnotateOptionalCXXScopeToken()) {3799TPA.Commit();3800SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);3801break;3802}3803CXXScopeSpec SS;3804if (Tok.is(tok::annot_cxxscope)) {3805Actions.RestoreNestedNameSpecifierAnnotation(3806Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);3807ConsumeAnnotationToken();3808}38093810if (Tok.isOneOf(tok::identifier, tok::annot_template_id) &&3811!NextToken().isOneOf(tok::l_brace, tok::l_paren)) {3812TPA.Commit();3813SourceLocation NameLoc = Tok.getLocation();3814IdentifierInfo *II = nullptr;3815TemplateIdAnnotation *TemplateId = nullptr;3816if (Tok.is(tok::identifier)) {3817II = Tok.getIdentifierInfo();3818ConsumeToken();3819} else {3820TemplateId = takeTemplateIdAnnotation(Tok);3821ConsumeAnnotationToken();3822if (TemplateId->isInvalid())3823break;3824}38253826if (auto *Req = Actions.ActOnTypeRequirement(TypenameKWLoc, SS,3827NameLoc, II,3828TemplateId)) {3829Requirements.push_back(Req);3830}3831break;3832}3833TPA.Revert();3834}3835// Simple requirement3836// C++ [expr.prim.req.simple]3837// simple-requirement:3838// expression ';'3839SourceLocation StartLoc = Tok.getLocation();3840ExprResult Expression =3841Actions.CorrectDelayedTyposInExpr(ParseExpression());3842if (!Expression.isUsable()) {3843SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);3844break;3845}3846if (!Expression.isInvalid() && PossibleRequiresExprInSimpleRequirement)3847Diag(StartLoc, diag::err_requires_expr_in_simple_requirement)3848<< FixItHint::CreateInsertion(StartLoc, "requires");3849if (auto *Req = Actions.ActOnSimpleRequirement(Expression.get()))3850Requirements.push_back(Req);3851else {3852SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);3853break;3854}3855// User may have tried to put some compound requirement stuff here3856if (Tok.is(tok::kw_noexcept)) {3857Diag(Tok, diag::err_requires_expr_simple_requirement_noexcept)3858<< FixItHint::CreateInsertion(StartLoc, "{")3859<< FixItHint::CreateInsertion(Tok.getLocation(), "}");3860SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);3861break;3862}3863break;3864}3865}3866if (ExpectAndConsumeSemi(diag::err_expected_semi_requirement)) {3867SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);3868TryConsumeToken(tok::semi);3869break;3870}3871}3872if (Requirements.empty()) {3873// Don't emit an empty requires expr here to avoid confusing the user with3874// other diagnostics quoting an empty requires expression they never3875// wrote.3876Braces.consumeClose();3877Actions.ActOnFinishRequiresExpr();3878return ExprError();3879}3880}3881Braces.consumeClose();3882Actions.ActOnFinishRequiresExpr();3883ParsingBodyDecl.complete(Body);3884return Actions.ActOnRequiresExpr(3885RequiresKWLoc, Body, Parens.getOpenLocation(), LocalParameterDecls,3886Parens.getCloseLocation(), Requirements, Braces.getCloseLocation());3887}38883889static TypeTrait TypeTraitFromTokKind(tok::TokenKind kind) {3890switch (kind) {3891default: llvm_unreachable("Not a known type trait");3892#define TYPE_TRAIT_1(Spelling, Name, Key) \3893case tok::kw_ ## Spelling: return UTT_ ## Name;3894#define TYPE_TRAIT_2(Spelling, Name, Key) \3895case tok::kw_ ## Spelling: return BTT_ ## Name;3896#include "clang/Basic/TokenKinds.def"3897#define TYPE_TRAIT_N(Spelling, Name, Key) \3898case tok::kw_ ## Spelling: return TT_ ## Name;3899#include "clang/Basic/TokenKinds.def"3900}3901}39023903static ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind) {3904switch (kind) {3905default:3906llvm_unreachable("Not a known array type trait");3907#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) \3908case tok::kw_##Spelling: \3909return ATT_##Name;3910#include "clang/Basic/TokenKinds.def"3911}3912}39133914static ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind) {3915switch (kind) {3916default:3917llvm_unreachable("Not a known unary expression trait.");3918#define EXPRESSION_TRAIT(Spelling, Name, Key) \3919case tok::kw_##Spelling: \3920return ET_##Name;3921#include "clang/Basic/TokenKinds.def"3922}3923}39243925/// Parse the built-in type-trait pseudo-functions that allow3926/// implementation of the TR1/C++11 type traits templates.3927///3928/// primary-expression:3929/// unary-type-trait '(' type-id ')'3930/// binary-type-trait '(' type-id ',' type-id ')'3931/// type-trait '(' type-id-seq ')'3932///3933/// type-id-seq:3934/// type-id ...[opt] type-id-seq[opt]3935///3936ExprResult Parser::ParseTypeTrait() {3937tok::TokenKind Kind = Tok.getKind();39383939SourceLocation Loc = ConsumeToken();39403941BalancedDelimiterTracker Parens(*this, tok::l_paren);3942if (Parens.expectAndConsume())3943return ExprError();39443945SmallVector<ParsedType, 2> Args;3946do {3947// Parse the next type.3948TypeResult Ty = ParseTypeName(/*SourceRange=*/nullptr,3949getLangOpts().CPlusPlus3950? DeclaratorContext::TemplateTypeArg3951: DeclaratorContext::TypeName);3952if (Ty.isInvalid()) {3953Parens.skipToEnd();3954return ExprError();3955}39563957// Parse the ellipsis, if present.3958if (Tok.is(tok::ellipsis)) {3959Ty = Actions.ActOnPackExpansion(Ty.get(), ConsumeToken());3960if (Ty.isInvalid()) {3961Parens.skipToEnd();3962return ExprError();3963}3964}39653966// Add this type to the list of arguments.3967Args.push_back(Ty.get());3968} while (TryConsumeToken(tok::comma));39693970if (Parens.consumeClose())3971return ExprError();39723973SourceLocation EndLoc = Parens.getCloseLocation();39743975return Actions.ActOnTypeTrait(TypeTraitFromTokKind(Kind), Loc, Args, EndLoc);3976}39773978/// ParseArrayTypeTrait - Parse the built-in array type-trait3979/// pseudo-functions.3980///3981/// primary-expression:3982/// [Embarcadero] '__array_rank' '(' type-id ')'3983/// [Embarcadero] '__array_extent' '(' type-id ',' expression ')'3984///3985ExprResult Parser::ParseArrayTypeTrait() {3986ArrayTypeTrait ATT = ArrayTypeTraitFromTokKind(Tok.getKind());3987SourceLocation Loc = ConsumeToken();39883989BalancedDelimiterTracker T(*this, tok::l_paren);3990if (T.expectAndConsume())3991return ExprError();39923993TypeResult Ty = ParseTypeName(/*SourceRange=*/nullptr,3994DeclaratorContext::TemplateTypeArg);3995if (Ty.isInvalid()) {3996SkipUntil(tok::comma, StopAtSemi);3997SkipUntil(tok::r_paren, StopAtSemi);3998return ExprError();3999}40004001switch (ATT) {4002case ATT_ArrayRank: {4003T.consumeClose();4004return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), nullptr,4005T.getCloseLocation());4006}4007case ATT_ArrayExtent: {4008if (ExpectAndConsume(tok::comma)) {4009SkipUntil(tok::r_paren, StopAtSemi);4010return ExprError();4011}40124013ExprResult DimExpr = ParseExpression();4014T.consumeClose();40154016if (DimExpr.isInvalid())4017return ExprError();40184019return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), DimExpr.get(),4020T.getCloseLocation());4021}4022}4023llvm_unreachable("Invalid ArrayTypeTrait!");4024}40254026/// ParseExpressionTrait - Parse built-in expression-trait4027/// pseudo-functions like __is_lvalue_expr( xxx ).4028///4029/// primary-expression:4030/// [Embarcadero] expression-trait '(' expression ')'4031///4032ExprResult Parser::ParseExpressionTrait() {4033ExpressionTrait ET = ExpressionTraitFromTokKind(Tok.getKind());4034SourceLocation Loc = ConsumeToken();40354036BalancedDelimiterTracker T(*this, tok::l_paren);4037if (T.expectAndConsume())4038return ExprError();40394040ExprResult Expr = ParseExpression();40414042T.consumeClose();40434044return Actions.ActOnExpressionTrait(ET, Loc, Expr.get(),4045T.getCloseLocation());4046}404740484049/// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a4050/// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate4051/// based on the context past the parens.4052ExprResult4053Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,4054ParsedType &CastTy,4055BalancedDelimiterTracker &Tracker,4056ColonProtectionRAIIObject &ColonProt) {4057assert(getLangOpts().CPlusPlus && "Should only be called for C++!");4058assert(ExprType == CastExpr && "Compound literals are not ambiguous!");4059assert(isTypeIdInParens() && "Not a type-id!");40604061ExprResult Result(true);4062CastTy = nullptr;40634064// We need to disambiguate a very ugly part of the C++ syntax:4065//4066// (T())x; - type-id4067// (T())*x; - type-id4068// (T())/x; - expression4069// (T()); - expression4070//4071// The bad news is that we cannot use the specialized tentative parser, since4072// it can only verify that the thing inside the parens can be parsed as4073// type-id, it is not useful for determining the context past the parens.4074//4075// The good news is that the parser can disambiguate this part without4076// making any unnecessary Action calls.4077//4078// It uses a scheme similar to parsing inline methods. The parenthesized4079// tokens are cached, the context that follows is determined (possibly by4080// parsing a cast-expression), and then we re-introduce the cached tokens4081// into the token stream and parse them appropriately.40824083ParenParseOption ParseAs;4084CachedTokens Toks;40854086// Store the tokens of the parentheses. We will parse them after we determine4087// the context that follows them.4088if (!ConsumeAndStoreUntil(tok::r_paren, Toks)) {4089// We didn't find the ')' we expected.4090Tracker.consumeClose();4091return ExprError();4092}40934094if (Tok.is(tok::l_brace)) {4095ParseAs = CompoundLiteral;4096} else {4097bool NotCastExpr;4098if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) {4099NotCastExpr = true;4100} else {4101// Try parsing the cast-expression that may follow.4102// If it is not a cast-expression, NotCastExpr will be true and no token4103// will be consumed.4104ColonProt.restore();4105Result = ParseCastExpression(AnyCastExpr,4106false/*isAddressofOperand*/,4107NotCastExpr,4108// type-id has priority.4109IsTypeCast);4110}41114112// If we parsed a cast-expression, it's really a type-id, otherwise it's4113// an expression.4114ParseAs = NotCastExpr ? SimpleExpr : CastExpr;4115}41164117// Create a fake EOF to mark end of Toks buffer.4118Token AttrEnd;4119AttrEnd.startToken();4120AttrEnd.setKind(tok::eof);4121AttrEnd.setLocation(Tok.getLocation());4122AttrEnd.setEofData(Toks.data());4123Toks.push_back(AttrEnd);41244125// The current token should go after the cached tokens.4126Toks.push_back(Tok);4127// Re-enter the stored parenthesized tokens into the token stream, so we may4128// parse them now.4129PP.EnterTokenStream(Toks, /*DisableMacroExpansion*/ true,4130/*IsReinject*/ true);4131// Drop the current token and bring the first cached one. It's the same token4132// as when we entered this function.4133ConsumeAnyToken();41344135if (ParseAs >= CompoundLiteral) {4136// Parse the type declarator.4137DeclSpec DS(AttrFactory);4138Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),4139DeclaratorContext::TypeName);4140{4141ColonProtectionRAIIObject InnerColonProtection(*this);4142ParseSpecifierQualifierList(DS);4143ParseDeclarator(DeclaratorInfo);4144}41454146// Match the ')'.4147Tracker.consumeClose();4148ColonProt.restore();41494150// Consume EOF marker for Toks buffer.4151assert(Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData());4152ConsumeAnyToken();41534154if (ParseAs == CompoundLiteral) {4155ExprType = CompoundLiteral;4156if (DeclaratorInfo.isInvalidType())4157return ExprError();41584159TypeResult Ty = Actions.ActOnTypeName(DeclaratorInfo);4160return ParseCompoundLiteralExpression(Ty.get(),4161Tracker.getOpenLocation(),4162Tracker.getCloseLocation());4163}41644165// We parsed '(' type-id ')' and the thing after it wasn't a '{'.4166assert(ParseAs == CastExpr);41674168if (DeclaratorInfo.isInvalidType())4169return ExprError();41704171// Result is what ParseCastExpression returned earlier.4172if (!Result.isInvalid())4173Result = Actions.ActOnCastExpr(getCurScope(), Tracker.getOpenLocation(),4174DeclaratorInfo, CastTy,4175Tracker.getCloseLocation(), Result.get());4176return Result;4177}41784179// Not a compound literal, and not followed by a cast-expression.4180assert(ParseAs == SimpleExpr);41814182ExprType = SimpleExpr;4183Result = ParseExpression();4184if (!Result.isInvalid() && Tok.is(tok::r_paren))4185Result = Actions.ActOnParenExpr(Tracker.getOpenLocation(),4186Tok.getLocation(), Result.get());41874188// Match the ')'.4189if (Result.isInvalid()) {4190while (Tok.isNot(tok::eof))4191ConsumeAnyToken();4192assert(Tok.getEofData() == AttrEnd.getEofData());4193ConsumeAnyToken();4194return ExprError();4195}41964197Tracker.consumeClose();4198// Consume EOF marker for Toks buffer.4199assert(Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData());4200ConsumeAnyToken();4201return Result;4202}42034204/// Parse a __builtin_bit_cast(T, E).4205ExprResult Parser::ParseBuiltinBitCast() {4206SourceLocation KWLoc = ConsumeToken();42074208BalancedDelimiterTracker T(*this, tok::l_paren);4209if (T.expectAndConsume(diag::err_expected_lparen_after, "__builtin_bit_cast"))4210return ExprError();42114212// Parse the common declaration-specifiers piece.4213DeclSpec DS(AttrFactory);4214ParseSpecifierQualifierList(DS);42154216// Parse the abstract-declarator, if present.4217Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),4218DeclaratorContext::TypeName);4219ParseDeclarator(DeclaratorInfo);42204221if (ExpectAndConsume(tok::comma)) {4222Diag(Tok.getLocation(), diag::err_expected) << tok::comma;4223SkipUntil(tok::r_paren, StopAtSemi);4224return ExprError();4225}42264227ExprResult Operand = ParseExpression();42284229if (T.consumeClose())4230return ExprError();42314232if (Operand.isInvalid() || DeclaratorInfo.isInvalidType())4233return ExprError();42344235return Actions.ActOnBuiltinBitCastExpr(KWLoc, DeclaratorInfo, Operand,4236T.getCloseLocation());4237}423842394240