brintos

brintos / llvm-project-archived public Read only

0
0
Text · 188.7 KiB · d8ed7e3 Raw
5100 lines · cpp
1//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9//  This file implements the C++ Declaration portions of the Parser interfaces.10//11//===----------------------------------------------------------------------===//12 13#include "clang/AST/ASTContext.h"14#include "clang/AST/DeclTemplate.h"15#include "clang/AST/PrettyDeclStackTrace.h"16#include "clang/Basic/AttributeCommonInfo.h"17#include "clang/Basic/Attributes.h"18#include "clang/Basic/CharInfo.h"19#include "clang/Basic/DiagnosticParse.h"20#include "clang/Basic/TargetInfo.h"21#include "clang/Basic/TokenKinds.h"22#include "clang/Lex/LiteralSupport.h"23#include "clang/Parse/ParseHLSLRootSignature.h"24#include "clang/Parse/Parser.h"25#include "clang/Parse/RAIIObjectsForParser.h"26#include "clang/Sema/DeclSpec.h"27#include "clang/Sema/EnterExpressionEvaluationContext.h"28#include "clang/Sema/ParsedTemplate.h"29#include "clang/Sema/Scope.h"30#include "clang/Sema/SemaCodeCompletion.h"31#include "clang/Sema/SemaHLSL.h"32#include "llvm/Support/TimeProfiler.h"33#include <optional>34 35using namespace clang;36 37Parser::DeclGroupPtrTy Parser::ParseNamespace(DeclaratorContext Context,38                                              SourceLocation &DeclEnd,39                                              SourceLocation InlineLoc) {40  assert(Tok.is(tok::kw_namespace) && "Not a namespace!");41  SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'.42  ObjCDeclContextSwitch ObjCDC(*this);43 44  if (Tok.is(tok::code_completion)) {45    cutOffParsing();46    Actions.CodeCompletion().CodeCompleteNamespaceDecl(getCurScope());47    return nullptr;48  }49 50  SourceLocation IdentLoc;51  IdentifierInfo *Ident = nullptr;52  InnerNamespaceInfoList ExtraNSs;53  SourceLocation FirstNestedInlineLoc;54 55  ParsedAttributes attrs(AttrFactory);56 57  while (MaybeParseGNUAttributes(attrs) || isAllowedCXX11AttributeSpecifier()) {58    if (isAllowedCXX11AttributeSpecifier()) {59      if (getLangOpts().CPlusPlus11)60        Diag(Tok.getLocation(), getLangOpts().CPlusPlus1761                                    ? diag::warn_cxx14_compat_ns_enum_attribute62                                    : diag::ext_ns_enum_attribute)63            << 0 /*namespace*/;64      ParseCXX11Attributes(attrs);65    }66  }67 68  if (Tok.is(tok::identifier)) {69    Ident = Tok.getIdentifierInfo();70    IdentLoc = ConsumeToken(); // eat the identifier.71    while (Tok.is(tok::coloncolon) &&72           (NextToken().is(tok::identifier) ||73            (NextToken().is(tok::kw_inline) &&74             GetLookAheadToken(2).is(tok::identifier)))) {75 76      InnerNamespaceInfo Info;77      Info.NamespaceLoc = ConsumeToken();78 79      if (Tok.is(tok::kw_inline)) {80        Info.InlineLoc = ConsumeToken();81        if (FirstNestedInlineLoc.isInvalid())82          FirstNestedInlineLoc = Info.InlineLoc;83      }84 85      Info.Ident = Tok.getIdentifierInfo();86      Info.IdentLoc = ConsumeToken();87 88      ExtraNSs.push_back(Info);89    }90  }91 92  DiagnoseAndSkipCXX11Attributes();93  MaybeParseGNUAttributes(attrs);94  DiagnoseAndSkipCXX11Attributes();95 96  SourceLocation attrLoc = attrs.Range.getBegin();97 98  // A nested namespace definition cannot have attributes.99  if (!ExtraNSs.empty() && attrLoc.isValid())100    Diag(attrLoc, diag::err_unexpected_nested_namespace_attribute);101 102  if (Tok.is(tok::equal)) {103    if (!Ident) {104      Diag(Tok, diag::err_expected) << tok::identifier;105      // Skip to end of the definition and eat the ';'.106      SkipUntil(tok::semi);107      return nullptr;108    }109    if (!ExtraNSs.empty()) {110      Diag(ExtraNSs.front().NamespaceLoc,111           diag::err_unexpected_qualified_namespace_alias)112          << SourceRange(ExtraNSs.front().NamespaceLoc,113                         ExtraNSs.back().IdentLoc);114      SkipUntil(tok::semi);115      return nullptr;116    }117    if (attrLoc.isValid())118      Diag(attrLoc, diag::err_unexpected_namespace_attributes_alias);119    if (InlineLoc.isValid())120      Diag(InlineLoc, diag::err_inline_namespace_alias)121          << FixItHint::CreateRemoval(InlineLoc);122    Decl *NSAlias = ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);123    return Actions.ConvertDeclToDeclGroup(NSAlias);124  }125 126  BalancedDelimiterTracker T(*this, tok::l_brace);127  if (T.consumeOpen()) {128    if (Ident)129      Diag(Tok, diag::err_expected) << tok::l_brace;130    else131      Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;132    return nullptr;133  }134 135  if (getCurScope()->isClassScope() || getCurScope()->isTemplateParamScope() ||136      getCurScope()->isInObjcMethodScope() || getCurScope()->getBlockParent() ||137      getCurScope()->getFnParent()) {138    Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope);139    SkipUntil(tok::r_brace);140    return nullptr;141  }142 143  if (ExtraNSs.empty()) {144    // Normal namespace definition, not a nested-namespace-definition.145  } else if (InlineLoc.isValid()) {146    Diag(InlineLoc, diag::err_inline_nested_namespace_definition);147  } else if (getLangOpts().CPlusPlus20) {148    Diag(ExtraNSs[0].NamespaceLoc,149         diag::warn_cxx14_compat_nested_namespace_definition);150    if (FirstNestedInlineLoc.isValid())151      Diag(FirstNestedInlineLoc,152           diag::warn_cxx17_compat_inline_nested_namespace_definition);153  } else if (getLangOpts().CPlusPlus17) {154    Diag(ExtraNSs[0].NamespaceLoc,155         diag::warn_cxx14_compat_nested_namespace_definition);156    if (FirstNestedInlineLoc.isValid())157      Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition);158  } else {159    TentativeParsingAction TPA(*this);160    SkipUntil(tok::r_brace, StopBeforeMatch);161    Token rBraceToken = Tok;162    TPA.Revert();163 164    if (!rBraceToken.is(tok::r_brace)) {165      Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition)166          << SourceRange(ExtraNSs.front().NamespaceLoc,167                         ExtraNSs.back().IdentLoc);168    } else {169      std::string NamespaceFix;170      for (const auto &ExtraNS : ExtraNSs) {171        NamespaceFix += " { ";172        if (ExtraNS.InlineLoc.isValid())173          NamespaceFix += "inline ";174        NamespaceFix += "namespace ";175        NamespaceFix += ExtraNS.Ident->getName();176      }177 178      std::string RBraces;179      for (unsigned i = 0, e = ExtraNSs.size(); i != e; ++i)180        RBraces += "} ";181 182      Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition)183          << FixItHint::CreateReplacement(184                 SourceRange(ExtraNSs.front().NamespaceLoc,185                             ExtraNSs.back().IdentLoc),186                 NamespaceFix)187          << FixItHint::CreateInsertion(rBraceToken.getLocation(), RBraces);188    }189 190    // Warn about nested inline namespaces.191    if (FirstNestedInlineLoc.isValid())192      Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition);193  }194 195  // If we're still good, complain about inline namespaces in non-C++0x now.196  if (InlineLoc.isValid())197    Diag(InlineLoc, getLangOpts().CPlusPlus11198                        ? diag::warn_cxx98_compat_inline_namespace199                        : diag::ext_inline_namespace);200 201  // Enter a scope for the namespace.202  ParseScope NamespaceScope(this, Scope::DeclScope);203 204  UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr;205  Decl *NamespcDecl = Actions.ActOnStartNamespaceDef(206      getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident,207      T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl, false);208 209  PrettyDeclStackTraceEntry CrashInfo(Actions.Context, NamespcDecl,210                                      NamespaceLoc, "parsing namespace");211 212  // Parse the contents of the namespace.  This includes parsing recovery on213  // any improperly nested namespaces.214  ParseInnerNamespace(ExtraNSs, 0, InlineLoc, attrs, T);215 216  // Leave the namespace scope.217  NamespaceScope.Exit();218 219  DeclEnd = T.getCloseLocation();220  Actions.ActOnFinishNamespaceDef(NamespcDecl, DeclEnd);221 222  return Actions.ConvertDeclToDeclGroup(NamespcDecl,223                                        ImplicitUsingDirectiveDecl);224}225 226void Parser::ParseInnerNamespace(const InnerNamespaceInfoList &InnerNSs,227                                 unsigned int index, SourceLocation &InlineLoc,228                                 ParsedAttributes &attrs,229                                 BalancedDelimiterTracker &Tracker) {230  if (index == InnerNSs.size()) {231    while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&232           Tok.isNot(tok::eof)) {233      ParsedAttributes DeclAttrs(AttrFactory);234      MaybeParseCXX11Attributes(DeclAttrs);235      ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);236      ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);237    }238 239    // The caller is what called check -- we are simply calling240    // the close for it.241    Tracker.consumeClose();242 243    return;244  }245 246  // Handle a nested namespace definition.247  // FIXME: Preserve the source information through to the AST rather than248  // desugaring it here.249  ParseScope NamespaceScope(this, Scope::DeclScope);250  UsingDirectiveDecl *ImplicitUsingDirectiveDecl = nullptr;251  Decl *NamespcDecl = Actions.ActOnStartNamespaceDef(252      getCurScope(), InnerNSs[index].InlineLoc, InnerNSs[index].NamespaceLoc,253      InnerNSs[index].IdentLoc, InnerNSs[index].Ident,254      Tracker.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl, true);255  assert(!ImplicitUsingDirectiveDecl &&256         "nested namespace definition cannot define anonymous namespace");257 258  ParseInnerNamespace(InnerNSs, ++index, InlineLoc, attrs, Tracker);259 260  NamespaceScope.Exit();261  Actions.ActOnFinishNamespaceDef(NamespcDecl, Tracker.getCloseLocation());262}263 264Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,265                                  SourceLocation AliasLoc,266                                  IdentifierInfo *Alias,267                                  SourceLocation &DeclEnd) {268  assert(Tok.is(tok::equal) && "Not equal token");269 270  ConsumeToken(); // eat the '='.271 272  if (Tok.is(tok::code_completion)) {273    cutOffParsing();274    Actions.CodeCompletion().CodeCompleteNamespaceAliasDecl(getCurScope());275    return nullptr;276  }277 278  CXXScopeSpec SS;279  // Parse (optional) nested-name-specifier.280  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,281                                 /*ObjectHasErrors=*/false,282                                 /*EnteringContext=*/false,283                                 /*MayBePseudoDestructor=*/nullptr,284                                 /*IsTypename=*/false,285                                 /*LastII=*/nullptr,286                                 /*OnlyNamespace=*/true);287 288  if (Tok.isNot(tok::identifier)) {289    Diag(Tok, diag::err_expected_namespace_name);290    // Skip to end of the definition and eat the ';'.291    SkipUntil(tok::semi);292    return nullptr;293  }294 295  if (SS.isInvalid()) {296    // Diagnostics have been emitted in ParseOptionalCXXScopeSpecifier.297    // Skip to end of the definition and eat the ';'.298    SkipUntil(tok::semi);299    return nullptr;300  }301 302  // Parse identifier.303  IdentifierInfo *Ident = Tok.getIdentifierInfo();304  SourceLocation IdentLoc = ConsumeToken();305 306  // Eat the ';'.307  DeclEnd = Tok.getLocation();308  if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name))309    SkipUntil(tok::semi);310 311  return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc,312                                        Alias, SS, IdentLoc, Ident);313}314 315Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) {316  assert(isTokenStringLiteral() && "Not a string literal!");317  ExprResult Lang = ParseUnevaluatedStringLiteralExpression();318 319  ParseScope LinkageScope(this, Scope::DeclScope);320  Decl *LinkageSpec =321      Lang.isInvalid()322          ? nullptr323          : Actions.ActOnStartLinkageSpecification(324                getCurScope(), DS.getSourceRange().getBegin(), Lang.get(),325                Tok.is(tok::l_brace) ? Tok.getLocation() : SourceLocation());326 327  ParsedAttributes DeclAttrs(AttrFactory);328  ParsedAttributes DeclSpecAttrs(AttrFactory);329 330  while (MaybeParseCXX11Attributes(DeclAttrs) ||331         MaybeParseGNUAttributes(DeclSpecAttrs))332    ;333 334  if (Tok.isNot(tok::l_brace)) {335    // Reset the source range in DS, as the leading "extern"336    // does not really belong to the inner declaration ...337    DS.SetRangeStart(SourceLocation());338    DS.SetRangeEnd(SourceLocation());339    // ... but anyway remember that such an "extern" was seen.340    DS.setExternInLinkageSpec(true);341    ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs, &DS);342    return LinkageSpec ? Actions.ActOnFinishLinkageSpecification(343                             getCurScope(), LinkageSpec, SourceLocation())344                       : nullptr;345  }346 347  DS.abort();348 349  ProhibitAttributes(DeclAttrs);350 351  BalancedDelimiterTracker T(*this, tok::l_brace);352  T.consumeOpen();353 354  unsigned NestedModules = 0;355  while (true) {356    switch (Tok.getKind()) {357    case tok::annot_module_begin:358      ++NestedModules;359      ParseTopLevelDecl();360      continue;361 362    case tok::annot_module_end:363      if (!NestedModules)364        break;365      --NestedModules;366      ParseTopLevelDecl();367      continue;368 369    case tok::annot_module_include:370      ParseTopLevelDecl();371      continue;372 373    case tok::eof:374      break;375 376    case tok::r_brace:377      if (!NestedModules)378        break;379      [[fallthrough]];380    default:381      ParsedAttributes DeclAttrs(AttrFactory);382      ParsedAttributes DeclSpecAttrs(AttrFactory);383      while (MaybeParseCXX11Attributes(DeclAttrs) ||384             MaybeParseGNUAttributes(DeclSpecAttrs))385        ;386      ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs);387      continue;388    }389 390    break;391  }392 393  T.consumeClose();394  return LinkageSpec ? Actions.ActOnFinishLinkageSpecification(395                           getCurScope(), LinkageSpec, T.getCloseLocation())396                     : nullptr;397}398 399Decl *Parser::ParseExportDeclaration() {400  assert(Tok.is(tok::kw_export));401  SourceLocation ExportLoc = ConsumeToken();402 403  if (Tok.is(tok::code_completion)) {404    cutOffParsing();405    Actions.CodeCompletion().CodeCompleteOrdinaryName(406        getCurScope(), PP.isIncrementalProcessingEnabled()407                           ? SemaCodeCompletion::PCC_TopLevelOrExpression408                           : SemaCodeCompletion::PCC_Namespace);409    return nullptr;410  }411 412  ParseScope ExportScope(this, Scope::DeclScope);413  Decl *ExportDecl = Actions.ActOnStartExportDecl(414      getCurScope(), ExportLoc,415      Tok.is(tok::l_brace) ? Tok.getLocation() : SourceLocation());416 417  if (Tok.isNot(tok::l_brace)) {418    // FIXME: Factor out a ParseExternalDeclarationWithAttrs.419    ParsedAttributes DeclAttrs(AttrFactory);420    MaybeParseCXX11Attributes(DeclAttrs);421    ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);422    ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);423    return Actions.ActOnFinishExportDecl(getCurScope(), ExportDecl,424                                         SourceLocation());425  }426 427  BalancedDelimiterTracker T(*this, tok::l_brace);428  T.consumeOpen();429 430  while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&431         Tok.isNot(tok::eof)) {432    ParsedAttributes DeclAttrs(AttrFactory);433    MaybeParseCXX11Attributes(DeclAttrs);434    ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);435    ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);436  }437 438  T.consumeClose();439  return Actions.ActOnFinishExportDecl(getCurScope(), ExportDecl,440                                       T.getCloseLocation());441}442 443Parser::DeclGroupPtrTy Parser::ParseUsingDirectiveOrDeclaration(444    DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,445    SourceLocation &DeclEnd, ParsedAttributes &Attrs) {446  assert(Tok.is(tok::kw_using) && "Not using token");447  ObjCDeclContextSwitch ObjCDC(*this);448 449  // Eat 'using'.450  SourceLocation UsingLoc = ConsumeToken();451 452  if (Tok.is(tok::code_completion)) {453    cutOffParsing();454    Actions.CodeCompletion().CodeCompleteUsing(getCurScope());455    return nullptr;456  }457 458  // Consume unexpected 'template' keywords.459  while (Tok.is(tok::kw_template)) {460    SourceLocation TemplateLoc = ConsumeToken();461    Diag(TemplateLoc, diag::err_unexpected_template_after_using)462        << FixItHint::CreateRemoval(TemplateLoc);463  }464 465  // 'using namespace' means this is a using-directive.466  if (Tok.is(tok::kw_namespace)) {467    // Template parameters are always an error here.468    if (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate) {469      SourceRange R = TemplateInfo.getSourceRange();470      Diag(UsingLoc, diag::err_templated_using_directive_declaration)471          << 0 /* directive */ << R << FixItHint::CreateRemoval(R);472    }473 474    Decl *UsingDir = ParseUsingDirective(Context, UsingLoc, DeclEnd, Attrs);475    return Actions.ConvertDeclToDeclGroup(UsingDir);476  }477 478  // Otherwise, it must be a using-declaration or an alias-declaration.479  return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd, Attrs,480                               AS_none);481}482 483Decl *Parser::ParseUsingDirective(DeclaratorContext Context,484                                  SourceLocation UsingLoc,485                                  SourceLocation &DeclEnd,486                                  ParsedAttributes &attrs) {487  assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");488 489  // Eat 'namespace'.490  SourceLocation NamespcLoc = ConsumeToken();491 492  if (Tok.is(tok::code_completion)) {493    cutOffParsing();494    Actions.CodeCompletion().CodeCompleteUsingDirective(getCurScope());495    return nullptr;496  }497 498  CXXScopeSpec SS;499  // Parse (optional) nested-name-specifier.500  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,501                                 /*ObjectHasErrors=*/false,502                                 /*EnteringContext=*/false,503                                 /*MayBePseudoDestructor=*/nullptr,504                                 /*IsTypename=*/false,505                                 /*LastII=*/nullptr,506                                 /*OnlyNamespace=*/true);507 508  IdentifierInfo *NamespcName = nullptr;509  SourceLocation IdentLoc = SourceLocation();510 511  // Parse namespace-name.512  if (Tok.isNot(tok::identifier)) {513    Diag(Tok, diag::err_expected_namespace_name);514    // If there was invalid namespace name, skip to end of decl, and eat ';'.515    SkipUntil(tok::semi);516    // FIXME: Are there cases, when we would like to call ActOnUsingDirective?517    return nullptr;518  }519 520  if (SS.isInvalid()) {521    // Diagnostics have been emitted in ParseOptionalCXXScopeSpecifier.522    // Skip to end of the definition and eat the ';'.523    SkipUntil(tok::semi);524    return nullptr;525  }526 527  // Parse identifier.528  NamespcName = Tok.getIdentifierInfo();529  IdentLoc = ConsumeToken();530 531  // Parse (optional) attributes (most likely GNU strong-using extension).532  bool GNUAttr = false;533  if (Tok.is(tok::kw___attribute)) {534    GNUAttr = true;535    ParseGNUAttributes(attrs);536  }537 538  // Eat ';'.539  DeclEnd = Tok.getLocation();540  if (ExpectAndConsume(tok::semi,541                       GNUAttr ? diag::err_expected_semi_after_attribute_list542                               : diag::err_expected_semi_after_namespace_name))543    SkipUntil(tok::semi);544 545  return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,546                                     IdentLoc, NamespcName, attrs);547}548 549bool Parser::ParseUsingDeclarator(DeclaratorContext Context,550                                  UsingDeclarator &D) {551  D.clear();552 553  // Ignore optional 'typename'.554  // FIXME: This is wrong; we should parse this as a typename-specifier.555  TryConsumeToken(tok::kw_typename, D.TypenameLoc);556 557  if (Tok.is(tok::kw___super)) {558    Diag(Tok.getLocation(), diag::err_super_in_using_declaration);559    return true;560  }561 562  // Parse nested-name-specifier.563  const IdentifierInfo *LastII = nullptr;564  if (ParseOptionalCXXScopeSpecifier(D.SS, /*ObjectType=*/nullptr,565                                     /*ObjectHasErrors=*/false,566                                     /*EnteringContext=*/false,567                                     /*MayBePseudoDtor=*/nullptr,568                                     /*IsTypename=*/false,569                                     /*LastII=*/&LastII,570                                     /*OnlyNamespace=*/false,571                                     /*InUsingDeclaration=*/true))572 573    return true;574  if (D.SS.isInvalid())575    return true;576 577  // Parse the unqualified-id. We allow parsing of both constructor and578  // destructor names and allow the action module to diagnose any semantic579  // errors.580  //581  // C++11 [class.qual]p2:582  //   [...] in a using-declaration that is a member-declaration, if the name583  //   specified after the nested-name-specifier is the same as the identifier584  //   or the simple-template-id's template-name in the last component of the585  //   nested-name-specifier, the name is [...] considered to name the586  //   constructor.587  if (getLangOpts().CPlusPlus11 && Context == DeclaratorContext::Member &&588      Tok.is(tok::identifier) &&589      (NextToken().is(tok::semi) || NextToken().is(tok::comma) ||590       NextToken().is(tok::ellipsis) || NextToken().is(tok::l_square) ||591       NextToken().isRegularKeywordAttribute() ||592       NextToken().is(tok::kw___attribute)) &&593      D.SS.isNotEmpty() && LastII == Tok.getIdentifierInfo() &&594      D.SS.getScopeRep().getKind() != NestedNameSpecifier::Kind::Namespace) {595    SourceLocation IdLoc = ConsumeToken();596    ParsedType Type =597        Actions.getInheritingConstructorName(D.SS, IdLoc, *LastII);598    D.Name.setConstructorName(Type, IdLoc, IdLoc);599  } else {600    if (ParseUnqualifiedId(601            D.SS, /*ObjectType=*/nullptr,602            /*ObjectHadErrors=*/false, /*EnteringContext=*/false,603            /*AllowDestructorName=*/true,604            /*AllowConstructorName=*/605            !(Tok.is(tok::identifier) && NextToken().is(tok::equal)),606            /*AllowDeductionGuide=*/false, nullptr, D.Name))607      return true;608  }609 610  if (TryConsumeToken(tok::ellipsis, D.EllipsisLoc))611    Diag(Tok.getLocation(), getLangOpts().CPlusPlus17612                                ? diag::warn_cxx17_compat_using_declaration_pack613                                : diag::ext_using_declaration_pack);614 615  return false;616}617 618Parser::DeclGroupPtrTy Parser::ParseUsingDeclaration(619    DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,620    SourceLocation UsingLoc, SourceLocation &DeclEnd,621    ParsedAttributes &PrefixAttrs, AccessSpecifier AS) {622  SourceLocation UELoc;623  bool InInitStatement = Context == DeclaratorContext::SelectionInit ||624                         Context == DeclaratorContext::ForInit;625 626  if (TryConsumeToken(tok::kw_enum, UELoc) && !InInitStatement) {627    // C++20 using-enum628    Diag(UELoc, getLangOpts().CPlusPlus20629                    ? diag::warn_cxx17_compat_using_enum_declaration630                    : diag::ext_using_enum_declaration);631 632    DiagnoseCXX11AttributeExtension(PrefixAttrs);633 634    if (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate) {635      SourceRange R = TemplateInfo.getSourceRange();636      Diag(UsingLoc, diag::err_templated_using_directive_declaration)637          << 1 /* declaration */ << R << FixItHint::CreateRemoval(R);638      SkipUntil(tok::semi);639      return nullptr;640    }641    CXXScopeSpec SS;642    if (ParseOptionalCXXScopeSpecifier(SS, /*ParsedType=*/nullptr,643                                       /*ObectHasErrors=*/false,644                                       /*EnteringConttext=*/false,645                                       /*MayBePseudoDestructor=*/nullptr,646                                       /*IsTypename=*/true,647                                       /*IdentifierInfo=*/nullptr,648                                       /*OnlyNamespace=*/false,649                                       /*InUsingDeclaration=*/true)) {650      SkipUntil(tok::semi);651      return nullptr;652    }653 654    if (Tok.is(tok::code_completion)) {655      cutOffParsing();656      Actions.CodeCompletion().CodeCompleteUsing(getCurScope());657      return nullptr;658    }659 660    Decl *UED = nullptr;661 662    // FIXME: identifier and annot_template_id handling is very similar to663    // ParseBaseTypeSpecifier. It should be factored out into a function.664    if (Tok.is(tok::identifier)) {665      IdentifierInfo *IdentInfo = Tok.getIdentifierInfo();666      SourceLocation IdentLoc = ConsumeToken();667 668      ParsedType Type = Actions.getTypeName(669          *IdentInfo, IdentLoc, getCurScope(), &SS, /*isClassName=*/true,670          /*HasTrailingDot=*/false,671          /*ObjectType=*/nullptr, /*IsCtorOrDtorName=*/false,672          /*WantNontrivialTypeSourceInfo=*/true);673 674      UED = Actions.ActOnUsingEnumDeclaration(675          getCurScope(), AS, UsingLoc, UELoc, IdentLoc, *IdentInfo, Type, SS);676    } else if (Tok.is(tok::annot_template_id)) {677      TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);678 679      if (TemplateId->mightBeType()) {680        AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::No,681                                      /*IsClassName=*/true);682 683        assert(Tok.is(tok::annot_typename) && "template-id -> type failed");684        TypeResult Type = getTypeAnnotation(Tok);685        SourceRange Loc = Tok.getAnnotationRange();686        ConsumeAnnotationToken();687 688        UED = Actions.ActOnUsingEnumDeclaration(getCurScope(), AS, UsingLoc,689                                                UELoc, Loc, *TemplateId->Name,690                                                Type.get(), SS);691      } else {692        Diag(Tok.getLocation(), diag::err_using_enum_not_enum)693            << TemplateId->Name->getName()694            << SourceRange(TemplateId->TemplateNameLoc, TemplateId->RAngleLoc);695      }696    } else {697      Diag(Tok.getLocation(), diag::err_using_enum_expect_identifier)698          << Tok.is(tok::kw_enum);699      SkipUntil(tok::semi);700      return nullptr;701    }702 703    if (!UED) {704      SkipUntil(tok::semi);705      return nullptr;706    }707 708    DeclEnd = Tok.getLocation();709    if (ExpectAndConsume(tok::semi, diag::err_expected_after,710                         "using-enum declaration"))711      SkipUntil(tok::semi);712 713    return Actions.ConvertDeclToDeclGroup(UED);714  }715 716  // Check for misplaced attributes before the identifier in an717  // alias-declaration.718  ParsedAttributes MisplacedAttrs(AttrFactory);719  MaybeParseCXX11Attributes(MisplacedAttrs);720 721  if (InInitStatement && Tok.isNot(tok::identifier))722    return nullptr;723 724  UsingDeclarator D;725  bool InvalidDeclarator = ParseUsingDeclarator(Context, D);726 727  ParsedAttributes Attrs(AttrFactory);728  MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);729 730  // If we had any misplaced attributes from earlier, this is where they731  // should have been written.732  if (MisplacedAttrs.Range.isValid()) {733    auto *FirstAttr =734        MisplacedAttrs.empty() ? nullptr : &MisplacedAttrs.front();735    auto &Range = MisplacedAttrs.Range;736    (FirstAttr && FirstAttr->isRegularKeywordAttribute()737         ? Diag(Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr738         : Diag(Range.getBegin(), diag::err_attributes_not_allowed))739        << FixItHint::CreateInsertionFromRange(740               Tok.getLocation(), CharSourceRange::getTokenRange(Range))741        << FixItHint::CreateRemoval(Range);742    Attrs.takeAllPrependingFrom(MisplacedAttrs);743  }744 745  // Maybe this is an alias-declaration.746  if (Tok.is(tok::equal) || InInitStatement) {747    if (InvalidDeclarator) {748      SkipUntil(tok::semi);749      return nullptr;750    }751 752    ProhibitAttributes(PrefixAttrs);753 754    Decl *DeclFromDeclSpec = nullptr;755    Scope *CurScope = getCurScope();756    if (CurScope)757      CurScope->setFlags(Scope::ScopeFlags::TypeAliasScope |758                         CurScope->getFlags());759 760    Decl *AD = ParseAliasDeclarationAfterDeclarator(761        TemplateInfo, UsingLoc, D, DeclEnd, AS, Attrs, &DeclFromDeclSpec);762 763    if (!AD)764      return nullptr;765 766    return Actions.ConvertDeclToDeclGroup(AD, DeclFromDeclSpec);767  }768 769  DiagnoseCXX11AttributeExtension(PrefixAttrs);770 771  // Diagnose an attempt to declare a templated using-declaration.772  // In C++11, alias-declarations can be templates:773  //   template <...> using id = type;774  if (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate) {775    SourceRange R = TemplateInfo.getSourceRange();776    Diag(UsingLoc, diag::err_templated_using_directive_declaration)777        << 1 /* declaration */ << R << FixItHint::CreateRemoval(R);778 779    // Unfortunately, we have to bail out instead of recovering by780    // ignoring the parameters, just in case the nested name specifier781    // depends on the parameters.782    return nullptr;783  }784 785  SmallVector<Decl *, 8> DeclsInGroup;786  while (true) {787    // Parse (optional) attributes.788    MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);789    DiagnoseCXX11AttributeExtension(Attrs);790    Attrs.prepend(PrefixAttrs.begin(), PrefixAttrs.end());791 792    if (InvalidDeclarator)793      SkipUntil(tok::comma, tok::semi, StopBeforeMatch);794    else {795      // "typename" keyword is allowed for identifiers only,796      // because it may be a type definition.797      if (D.TypenameLoc.isValid() &&798          D.Name.getKind() != UnqualifiedIdKind::IK_Identifier) {799        Diag(D.Name.getSourceRange().getBegin(),800             diag::err_typename_identifiers_only)801            << FixItHint::CreateRemoval(SourceRange(D.TypenameLoc));802        // Proceed parsing, but discard the typename keyword.803        D.TypenameLoc = SourceLocation();804      }805 806      Decl *UD = Actions.ActOnUsingDeclaration(getCurScope(), AS, UsingLoc,807                                               D.TypenameLoc, D.SS, D.Name,808                                               D.EllipsisLoc, Attrs);809      if (UD)810        DeclsInGroup.push_back(UD);811    }812 813    if (!TryConsumeToken(tok::comma))814      break;815 816    // Parse another using-declarator.817    Attrs.clear();818    InvalidDeclarator = ParseUsingDeclarator(Context, D);819  }820 821  if (DeclsInGroup.size() > 1)822    Diag(Tok.getLocation(),823         getLangOpts().CPlusPlus17824             ? diag::warn_cxx17_compat_multi_using_declaration825             : diag::ext_multi_using_declaration);826 827  // Eat ';'.828  DeclEnd = Tok.getLocation();829  if (ExpectAndConsume(tok::semi, diag::err_expected_after,830                       !Attrs.empty()    ? "attributes list"831                       : UELoc.isValid() ? "using-enum declaration"832                                         : "using declaration"))833    SkipUntil(tok::semi);834 835  return Actions.BuildDeclaratorGroup(DeclsInGroup);836}837 838Decl *Parser::ParseAliasDeclarationAfterDeclarator(839    const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc,840    UsingDeclarator &D, SourceLocation &DeclEnd, AccessSpecifier AS,841    ParsedAttributes &Attrs, Decl **OwnedType) {842  if (ExpectAndConsume(tok::equal)) {843    SkipUntil(tok::semi);844    return nullptr;845  }846 847  Diag(Tok.getLocation(), getLangOpts().CPlusPlus11848                              ? diag::warn_cxx98_compat_alias_declaration849                              : diag::ext_alias_declaration);850 851  // Type alias templates cannot be specialized.852  int SpecKind = -1;853  if (TemplateInfo.Kind == ParsedTemplateKind::Template &&854      D.Name.getKind() == UnqualifiedIdKind::IK_TemplateId)855    SpecKind = 0;856  if (TemplateInfo.Kind == ParsedTemplateKind::ExplicitSpecialization)857    SpecKind = 1;858  if (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation)859    SpecKind = 2;860  if (SpecKind != -1) {861    SourceRange Range;862    if (SpecKind == 0)863      Range = SourceRange(D.Name.TemplateId->LAngleLoc,864                          D.Name.TemplateId->RAngleLoc);865    else866      Range = TemplateInfo.getSourceRange();867    Diag(Range.getBegin(), diag::err_alias_declaration_specialization)868        << SpecKind << Range;869    SkipUntil(tok::semi);870    return nullptr;871  }872 873  // Name must be an identifier.874  if (D.Name.getKind() != UnqualifiedIdKind::IK_Identifier) {875    Diag(D.Name.StartLocation, diag::err_alias_declaration_not_identifier);876    // No removal fixit: can't recover from this.877    SkipUntil(tok::semi);878    return nullptr;879  } else if (D.TypenameLoc.isValid())880    Diag(D.TypenameLoc, diag::err_alias_declaration_not_identifier)881        << FixItHint::CreateRemoval(882               SourceRange(D.TypenameLoc, D.SS.isNotEmpty() ? D.SS.getEndLoc()883                                                            : D.TypenameLoc));884  else if (D.SS.isNotEmpty())885    Diag(D.SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)886        << FixItHint::CreateRemoval(D.SS.getRange());887  if (D.EllipsisLoc.isValid())888    Diag(D.EllipsisLoc, diag::err_alias_declaration_pack_expansion)889        << FixItHint::CreateRemoval(SourceRange(D.EllipsisLoc));890 891  Decl *DeclFromDeclSpec = nullptr;892  TypeResult TypeAlias =893      ParseTypeName(nullptr,894                    TemplateInfo.Kind != ParsedTemplateKind::NonTemplate ? DeclaratorContext::AliasTemplate895                                      : DeclaratorContext::AliasDecl,896                    AS, &DeclFromDeclSpec, &Attrs);897  if (OwnedType)898    *OwnedType = DeclFromDeclSpec;899 900  // Eat ';'.901  DeclEnd = Tok.getLocation();902  if (ExpectAndConsume(tok::semi, diag::err_expected_after,903                       !Attrs.empty() ? "attributes list"904                                      : "alias declaration"))905    SkipUntil(tok::semi);906 907  TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;908  MultiTemplateParamsArg TemplateParamsArg(909      TemplateParams ? TemplateParams->data() : nullptr,910      TemplateParams ? TemplateParams->size() : 0);911  return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg,912                                       UsingLoc, D.Name, Attrs, TypeAlias,913                                       DeclFromDeclSpec);914}915 916static FixItHint getStaticAssertNoMessageFixIt(const Expr *AssertExpr,917                                               SourceLocation EndExprLoc) {918  if (const auto *BO = dyn_cast_or_null<BinaryOperator>(AssertExpr)) {919    if (BO->getOpcode() == BO_LAnd &&920        isa<StringLiteral>(BO->getRHS()->IgnoreImpCasts()))921      return FixItHint::CreateReplacement(BO->getOperatorLoc(), ",");922  }923  return FixItHint::CreateInsertion(EndExprLoc, ", \"\"");924}925 926Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {927  assert(Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert) &&928         "Not a static_assert declaration");929 930  // Save the token name used for static assertion.931  const char *TokName = Tok.getName();932 933  if (Tok.is(tok::kw__Static_assert))934    diagnoseUseOfC11Keyword(Tok);935  else if (Tok.is(tok::kw_static_assert)) {936    if (!getLangOpts().CPlusPlus) {937      if (getLangOpts().C23)938        Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();939    } else940      Diag(Tok, diag::warn_cxx98_compat_static_assert);941  }942 943  SourceLocation StaticAssertLoc = ConsumeToken();944 945  BalancedDelimiterTracker T(*this, tok::l_paren);946  if (T.consumeOpen()) {947    Diag(Tok, diag::err_expected) << tok::l_paren;948    SkipMalformedDecl();949    return nullptr;950  }951 952  EnterExpressionEvaluationContext ConstantEvaluated(953      Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);954  ExprResult AssertExpr(ParseConstantExpressionInExprEvalContext());955  if (AssertExpr.isInvalid()) {956    SkipMalformedDecl();957    return nullptr;958  }959 960  ExprResult AssertMessage;961  if (Tok.is(tok::r_paren)) {962    unsigned DiagVal;963    if (getLangOpts().CPlusPlus17)964      DiagVal = diag::warn_cxx14_compat_static_assert_no_message;965    else if (getLangOpts().CPlusPlus)966      DiagVal = diag::ext_cxx_static_assert_no_message;967    else if (getLangOpts().C23)968      DiagVal = diag::warn_c17_compat_static_assert_no_message;969    else970      DiagVal = diag::ext_c_static_assert_no_message;971    Diag(Tok, DiagVal) << getStaticAssertNoMessageFixIt(AssertExpr.get(),972                                                        Tok.getLocation());973  } else {974    if (ExpectAndConsume(tok::comma)) {975      SkipUntil(tok::semi);976      return nullptr;977    }978 979    bool ParseAsExpression = false;980    if (getLangOpts().CPlusPlus11) {981      for (unsigned I = 0;; ++I) {982        const Token &T = GetLookAheadToken(I);983        if (T.is(tok::r_paren))984          break;985        if (!tokenIsLikeStringLiteral(T, getLangOpts()) || T.hasUDSuffix()) {986          ParseAsExpression = true;987          break;988        }989      }990    }991 992    if (ParseAsExpression) {993      Diag(Tok,994           getLangOpts().CPlusPlus26995               ? diag::warn_cxx20_compat_static_assert_user_generated_message996               : diag::ext_cxx_static_assert_user_generated_message);997      AssertMessage = ParseConstantExpressionInExprEvalContext();998    } else if (tokenIsLikeStringLiteral(Tok, getLangOpts()))999      AssertMessage = ParseUnevaluatedStringLiteralExpression();1000    else {1001      Diag(Tok, diag::err_expected_string_literal)1002          << /*Source='static_assert'*/ 1;1003      SkipMalformedDecl();1004      return nullptr;1005    }1006 1007    if (AssertMessage.isInvalid()) {1008      SkipMalformedDecl();1009      return nullptr;1010    }1011  }1012 1013  if (T.consumeClose())1014    return nullptr;1015 1016  DeclEnd = Tok.getLocation();1017  ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, TokName);1018 1019  return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, AssertExpr.get(),1020                                              AssertMessage.get(),1021                                              T.getCloseLocation());1022}1023 1024SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {1025  assert(Tok.isOneOf(tok::kw_decltype, tok::annot_decltype) &&1026         "Not a decltype specifier");1027 1028  ExprResult Result;1029  SourceLocation StartLoc = Tok.getLocation();1030  SourceLocation EndLoc;1031 1032  if (Tok.is(tok::annot_decltype)) {1033    Result = getExprAnnotation(Tok);1034    EndLoc = Tok.getAnnotationEndLoc();1035    // Unfortunately, we don't know the LParen source location as the annotated1036    // token doesn't have it.1037    DS.setTypeArgumentRange(SourceRange(SourceLocation(), EndLoc));1038    ConsumeAnnotationToken();1039    if (Result.isInvalid()) {1040      DS.SetTypeSpecError();1041      return EndLoc;1042    }1043  } else {1044    if (Tok.getIdentifierInfo()->isStr("decltype"))1045      Diag(Tok, diag::warn_cxx98_compat_decltype);1046 1047    ConsumeToken();1048 1049    BalancedDelimiterTracker T(*this, tok::l_paren);1050    if (T.expectAndConsume(diag::err_expected_lparen_after, "decltype",1051                           tok::r_paren)) {1052      DS.SetTypeSpecError();1053      return T.getOpenLocation() == Tok.getLocation() ? StartLoc1054                                                      : T.getOpenLocation();1055    }1056 1057    // Check for C++1y 'decltype(auto)'.1058    if (Tok.is(tok::kw_auto) && NextToken().is(tok::r_paren)) {1059      // the typename-specifier in a function-style cast expression may1060      // be 'auto' since C++23.1061      Diag(Tok.getLocation(),1062           getLangOpts().CPlusPlus141063               ? diag::warn_cxx11_compat_decltype_auto_type_specifier1064               : diag::ext_decltype_auto_type_specifier);1065      ConsumeToken();1066    } else {1067      // Parse the expression1068 1069      // C++11 [dcl.type.simple]p4:1070      //   The operand of the decltype specifier is an unevaluated operand.1071      EnterExpressionEvaluationContext Unevaluated(1072          Actions, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,1073          Sema::ExpressionEvaluationContextRecord::EK_Decltype);1074      Result = ParseExpression();1075      if (Result.isInvalid()) {1076        DS.SetTypeSpecError();1077        if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) {1078          EndLoc = ConsumeParen();1079        } else {1080          if (PP.isBacktrackEnabled() && Tok.is(tok::semi)) {1081            // Backtrack to get the location of the last token before the semi.1082            PP.RevertCachedTokens(2);1083            ConsumeToken(); // the semi.1084            EndLoc = ConsumeAnyToken();1085            assert(Tok.is(tok::semi));1086          } else {1087            EndLoc = Tok.getLocation();1088          }1089        }1090        return EndLoc;1091      }1092 1093      Result = Actions.ActOnDecltypeExpression(Result.get());1094    }1095 1096    // Match the ')'1097    T.consumeClose();1098    DS.setTypeArgumentRange(T.getRange());1099    if (T.getCloseLocation().isInvalid()) {1100      DS.SetTypeSpecError();1101      // FIXME: this should return the location of the last token1102      //        that was consumed (by "consumeClose()")1103      return T.getCloseLocation();1104    }1105 1106    if (Result.isInvalid()) {1107      DS.SetTypeSpecError();1108      return T.getCloseLocation();1109    }1110 1111    EndLoc = T.getCloseLocation();1112  }1113  assert(!Result.isInvalid());1114 1115  const char *PrevSpec = nullptr;1116  unsigned DiagID;1117  const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();1118  // Check for duplicate type specifiers (e.g. "int decltype(a)").1119  if (Result.get() ? DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc,1120                                        PrevSpec, DiagID, Result.get(), Policy)1121                   : DS.SetTypeSpecType(DeclSpec::TST_decltype_auto, StartLoc,1122                                        PrevSpec, DiagID, Policy)) {1123    Diag(StartLoc, DiagID) << PrevSpec;1124    DS.SetTypeSpecError();1125  }1126  return EndLoc;1127}1128 1129void Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,1130                                               SourceLocation StartLoc,1131                                               SourceLocation EndLoc) {1132  // make sure we have a token we can turn into an annotation token1133  if (PP.isBacktrackEnabled()) {1134    PP.RevertCachedTokens(1);1135  } else1136    PP.EnterToken(Tok, /*IsReinject*/ true);1137 1138  Tok.setKind(tok::annot_decltype);1139  setExprAnnotation(Tok,1140                    DS.getTypeSpecType() == TST_decltype ? DS.getRepAsExpr()1141                    : DS.getTypeSpecType() == TST_decltype_auto ? ExprResult()1142                                                                : ExprError());1143  Tok.setAnnotationEndLoc(EndLoc);1144  Tok.setLocation(StartLoc);1145  PP.AnnotateCachedTokens(Tok);1146}1147 1148SourceLocation Parser::ParsePackIndexingType(DeclSpec &DS) {1149  assert(Tok.isOneOf(tok::annot_pack_indexing_type, tok::identifier) &&1150         "Expected an identifier");1151 1152  TypeResult Type;1153  SourceLocation StartLoc;1154  SourceLocation EllipsisLoc;1155  const char *PrevSpec;1156  unsigned DiagID;1157  const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();1158 1159  if (Tok.is(tok::annot_pack_indexing_type)) {1160    StartLoc = Tok.getLocation();1161    SourceLocation EndLoc;1162    Type = getTypeAnnotation(Tok);1163    EndLoc = Tok.getAnnotationEndLoc();1164    // Unfortunately, we don't know the LParen source location as the annotated1165    // token doesn't have it.1166    DS.setTypeArgumentRange(SourceRange(SourceLocation(), EndLoc));1167    ConsumeAnnotationToken();1168    if (Type.isInvalid()) {1169      DS.SetTypeSpecError();1170      return EndLoc;1171    }1172    DS.SetTypeSpecType(DeclSpec::TST_typename_pack_indexing, StartLoc, PrevSpec,1173                       DiagID, Type, Policy);1174    return EndLoc;1175  }1176  if (!NextToken().is(tok::ellipsis) ||1177      !GetLookAheadToken(2).is(tok::l_square)) {1178    DS.SetTypeSpecError();1179    return Tok.getEndLoc();1180  }1181 1182  ParsedType Ty = Actions.getTypeName(*Tok.getIdentifierInfo(),1183                                      Tok.getLocation(), getCurScope());1184  if (!Ty) {1185    DS.SetTypeSpecError();1186    return Tok.getEndLoc();1187  }1188  Type = Ty;1189 1190  StartLoc = ConsumeToken();1191  EllipsisLoc = ConsumeToken();1192  BalancedDelimiterTracker T(*this, tok::l_square);1193  T.consumeOpen();1194  ExprResult IndexExpr = ParseConstantExpression();1195  T.consumeClose();1196 1197  DS.SetRangeStart(StartLoc);1198  DS.SetRangeEnd(T.getCloseLocation());1199 1200  if (!IndexExpr.isUsable()) {1201    ASTContext &C = Actions.getASTContext();1202    IndexExpr = IntegerLiteral::Create(C, C.MakeIntValue(0, C.getSizeType()),1203                                       C.getSizeType(), SourceLocation());1204  }1205 1206  DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, PrevSpec, DiagID, Type,1207                     Policy);1208  DS.SetPackIndexingExpr(EllipsisLoc, IndexExpr.get());1209  return T.getCloseLocation();1210}1211 1212void Parser::AnnotateExistingIndexedTypeNamePack(ParsedType T,1213                                                 SourceLocation StartLoc,1214                                                 SourceLocation EndLoc) {1215  // make sure we have a token we can turn into an annotation token1216  if (PP.isBacktrackEnabled()) {1217    PP.RevertCachedTokens(1);1218    if (!T) {1219      // We encountered an error in parsing 'decltype(...)' so lets annotate all1220      // the tokens in the backtracking cache - that we likely had to skip over1221      // to get to a token that allows us to resume parsing, such as a1222      // semi-colon.1223      EndLoc = PP.getLastCachedTokenLocation();1224    }1225  } else1226    PP.EnterToken(Tok, /*IsReinject*/ true);1227 1228  Tok.setKind(tok::annot_pack_indexing_type);1229  setTypeAnnotation(Tok, T);1230  Tok.setAnnotationEndLoc(EndLoc);1231  Tok.setLocation(StartLoc);1232  PP.AnnotateCachedTokens(Tok);1233}1234 1235DeclSpec::TST Parser::TypeTransformTokToDeclSpec() {1236  switch (Tok.getKind()) {1237#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait)                                     \1238  case tok::kw___##Trait:                                                      \1239    return DeclSpec::TST_##Trait;1240#include "clang/Basic/TransformTypeTraits.def"1241  default:1242    llvm_unreachable("passed in an unhandled type transformation built-in");1243  }1244}1245 1246bool Parser::MaybeParseTypeTransformTypeSpecifier(DeclSpec &DS) {1247  if (!NextToken().is(tok::l_paren)) {1248    Tok.setKind(tok::identifier);1249    return false;1250  }1251  DeclSpec::TST TypeTransformTST = TypeTransformTokToDeclSpec();1252  SourceLocation StartLoc = ConsumeToken();1253 1254  BalancedDelimiterTracker T(*this, tok::l_paren);1255  if (T.expectAndConsume(diag::err_expected_lparen_after, Tok.getName(),1256                         tok::r_paren))1257    return true;1258 1259  TypeResult Result = ParseTypeName();1260  if (Result.isInvalid()) {1261    SkipUntil(tok::r_paren, StopAtSemi);1262    return true;1263  }1264 1265  T.consumeClose();1266  if (T.getCloseLocation().isInvalid())1267    return true;1268 1269  const char *PrevSpec = nullptr;1270  unsigned DiagID;1271  if (DS.SetTypeSpecType(TypeTransformTST, StartLoc, PrevSpec, DiagID,1272                         Result.get(),1273                         Actions.getASTContext().getPrintingPolicy()))1274    Diag(StartLoc, DiagID) << PrevSpec;1275  DS.setTypeArgumentRange(T.getRange());1276  return true;1277}1278 1279TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,1280                                          SourceLocation &EndLocation) {1281  // Ignore attempts to use typename1282  if (Tok.is(tok::kw_typename)) {1283    Diag(Tok, diag::err_expected_class_name_not_template)1284        << FixItHint::CreateRemoval(Tok.getLocation());1285    ConsumeToken();1286  }1287 1288  // Parse optional nested-name-specifier1289  CXXScopeSpec SS;1290  if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,1291                                     /*ObjectHasErrors=*/false,1292                                     /*EnteringContext=*/false))1293    return true;1294 1295  BaseLoc = Tok.getLocation();1296 1297  // Parse decltype-specifier1298  // tok == kw_decltype is just error recovery, it can only happen when SS1299  // isn't empty1300  if (Tok.isOneOf(tok::kw_decltype, tok::annot_decltype)) {1301    if (SS.isNotEmpty())1302      Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype)1303          << FixItHint::CreateRemoval(SS.getRange());1304    // Fake up a Declarator to use with ActOnTypeName.1305    DeclSpec DS(AttrFactory);1306 1307    EndLocation = ParseDecltypeSpecifier(DS);1308 1309    Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),1310                              DeclaratorContext::TypeName);1311    return Actions.ActOnTypeName(DeclaratorInfo);1312  }1313 1314  if (Tok.is(tok::annot_pack_indexing_type)) {1315    DeclSpec DS(AttrFactory);1316    ParsePackIndexingType(DS);1317    Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),1318                              DeclaratorContext::TypeName);1319    return Actions.ActOnTypeName(DeclaratorInfo);1320  }1321 1322  // Check whether we have a template-id that names a type.1323  // FIXME: identifier and annot_template_id handling in ParseUsingDeclaration1324  // work very similarly. It should be refactored into a separate function.1325  if (Tok.is(tok::annot_template_id)) {1326    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);1327    if (TemplateId->mightBeType()) {1328      AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::No,1329                                    /*IsClassName=*/true);1330 1331      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");1332      TypeResult Type = getTypeAnnotation(Tok);1333      EndLocation = Tok.getAnnotationEndLoc();1334      ConsumeAnnotationToken();1335      return Type;1336    }1337 1338    // Fall through to produce an error below.1339  }1340 1341  if (Tok.isNot(tok::identifier)) {1342    Diag(Tok, diag::err_expected_class_name);1343    return true;1344  }1345 1346  IdentifierInfo *Id = Tok.getIdentifierInfo();1347  SourceLocation IdLoc = ConsumeToken();1348 1349  if (Tok.is(tok::less)) {1350    // It looks the user intended to write a template-id here, but the1351    // template-name was wrong. Try to fix that.1352    // FIXME: Invoke ParseOptionalCXXScopeSpecifier in a "'template' is neither1353    // required nor permitted" mode, and do this there.1354    TemplateNameKind TNK = TNK_Non_template;1355    TemplateTy Template;1356    if (!Actions.DiagnoseUnknownTemplateName(*Id, IdLoc, getCurScope(), &SS,1357                                             Template, TNK)) {1358      Diag(IdLoc, diag::err_unknown_template_name) << Id;1359    }1360 1361    // Form the template name1362    UnqualifiedId TemplateName;1363    TemplateName.setIdentifier(Id, IdLoc);1364 1365    // Parse the full template-id, then turn it into a type.1366    if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),1367                                TemplateName))1368      return true;1369    if (Tok.is(tok::annot_template_id) &&1370        takeTemplateIdAnnotation(Tok)->mightBeType())1371      AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::No,1372                                    /*IsClassName=*/true);1373 1374    // If we didn't end up with a typename token, there's nothing more we1375    // can do.1376    if (Tok.isNot(tok::annot_typename))1377      return true;1378 1379    // Retrieve the type from the annotation token, consume that token, and1380    // return.1381    EndLocation = Tok.getAnnotationEndLoc();1382    TypeResult Type = getTypeAnnotation(Tok);1383    ConsumeAnnotationToken();1384    return Type;1385  }1386 1387  // We have an identifier; check whether it is actually a type.1388  IdentifierInfo *CorrectedII = nullptr;1389  ParsedType Type = Actions.getTypeName(1390      *Id, IdLoc, getCurScope(), &SS, /*isClassName=*/true, false, nullptr,1391      /*IsCtorOrDtorName=*/false,1392      /*WantNontrivialTypeSourceInfo=*/true,1393      /*IsClassTemplateDeductionContext=*/false, ImplicitTypenameContext::No,1394      &CorrectedII);1395  if (!Type) {1396    Diag(IdLoc, diag::err_expected_class_name);1397    return true;1398  }1399 1400  // Consume the identifier.1401  EndLocation = IdLoc;1402 1403  // Fake up a Declarator to use with ActOnTypeName.1404  DeclSpec DS(AttrFactory);1405  DS.SetRangeStart(IdLoc);1406  DS.SetRangeEnd(EndLocation);1407  DS.getTypeSpecScope() = SS;1408 1409  const char *PrevSpec = nullptr;1410  unsigned DiagID;1411  DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type,1412                     Actions.getASTContext().getPrintingPolicy());1413 1414  Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),1415                            DeclaratorContext::TypeName);1416  return Actions.ActOnTypeName(DeclaratorInfo);1417}1418 1419void Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) {1420  while (Tok.isOneOf(tok::kw___single_inheritance,1421                     tok::kw___multiple_inheritance,1422                     tok::kw___virtual_inheritance)) {1423    IdentifierInfo *AttrName = Tok.getIdentifierInfo();1424    auto Kind = Tok.getKind();1425    SourceLocation AttrNameLoc = ConsumeToken();1426    attrs.addNew(AttrName, AttrNameLoc, AttributeScopeInfo(), nullptr, 0, Kind);1427  }1428}1429 1430void Parser::ParseNullabilityClassAttributes(ParsedAttributes &attrs) {1431  while (Tok.is(tok::kw__Nullable)) {1432    IdentifierInfo *AttrName = Tok.getIdentifierInfo();1433    auto Kind = Tok.getKind();1434    SourceLocation AttrNameLoc = ConsumeToken();1435    attrs.addNew(AttrName, AttrNameLoc, AttributeScopeInfo(), nullptr, 0, Kind);1436  }1437}1438 1439bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {1440  // This switch enumerates the valid "follow" set for type-specifiers.1441  switch (Tok.getKind()) {1442  default:1443    if (Tok.isRegularKeywordAttribute())1444      return true;1445    break;1446  case tok::semi:              // struct foo {...} ;1447  case tok::star:              // struct foo {...} *         P;1448  case tok::amp:               // struct foo {...} &         R = ...1449  case tok::ampamp:            // struct foo {...} &&        R = ...1450  case tok::identifier:        // struct foo {...} V         ;1451  case tok::r_paren:           //(struct foo {...} )         {4}1452  case tok::coloncolon:        // struct foo {...} ::        a::b;1453  case tok::annot_cxxscope:    // struct foo {...} a::       b;1454  case tok::annot_typename:    // struct foo {...} a         ::b;1455  case tok::annot_template_id: // struct foo {...} a<int>    ::b;1456  case tok::kw_decltype:       // struct foo {...} decltype  (a)::b;1457  case tok::l_paren:           // struct foo {...} (         x);1458  case tok::comma:             // __builtin_offsetof(struct foo{...} ,1459  case tok::kw_operator:       // struct foo       operator  ++() {...}1460  case tok::kw___declspec:     // struct foo {...} __declspec(...)1461  case tok::l_square:          // void f(struct f  [         3])1462  case tok::ellipsis:          // void f(struct f  ...       [Ns])1463  // FIXME: we should emit semantic diagnostic when declaration1464  // attribute is in type attribute position.1465  case tok::kw___attribute:    // struct foo __attribute__((used)) x;1466  case tok::annot_pragma_pack: // struct foo {...} _Pragma(pack(pop));1467  // struct foo {...} _Pragma(section(...));1468  case tok::annot_pragma_ms_pragma:1469  // struct foo {...} _Pragma(vtordisp(pop));1470  case tok::annot_pragma_ms_vtordisp:1471  // struct foo {...} _Pragma(pointers_to_members(...));1472  case tok::annot_pragma_ms_pointers_to_members:1473    return true;1474  case tok::colon:1475    return CouldBeBitfield || // enum E { ... }   :         2;1476           ColonIsSacred;     // _Generic(..., enum E :     2);1477  // Microsoft compatibility1478  case tok::kw___cdecl:      // struct foo {...} __cdecl      x;1479  case tok::kw___fastcall:   // struct foo {...} __fastcall   x;1480  case tok::kw___stdcall:    // struct foo {...} __stdcall    x;1481  case tok::kw___thiscall:   // struct foo {...} __thiscall   x;1482  case tok::kw___vectorcall: // struct foo {...} __vectorcall x;1483    // We will diagnose these calling-convention specifiers on non-function1484    // declarations later, so claim they are valid after a type specifier.1485    return getLangOpts().MicrosoftExt;1486  // Type qualifiers1487  case tok::kw_const:       // struct foo {...} const     x;1488  case tok::kw_volatile:    // struct foo {...} volatile  x;1489  case tok::kw_restrict:    // struct foo {...} restrict  x;1490  case tok::kw__Atomic:     // struct foo {...} _Atomic   x;1491  case tok::kw___unaligned: // struct foo {...} __unaligned *x;1492  // Function specifiers1493  // Note, no 'explicit'. An explicit function must be either a conversion1494  // operator or a constructor. Either way, it can't have a return type.1495  case tok::kw_inline:  // struct foo       inline    f();1496  case tok::kw_virtual: // struct foo       virtual   f();1497  case tok::kw_friend:  // struct foo       friend    f();1498  // Storage-class specifiers1499  case tok::kw_static:       // struct foo {...} static    x;1500  case tok::kw_extern:       // struct foo {...} extern    x;1501  case tok::kw_typedef:      // struct foo {...} typedef   x;1502  case tok::kw_register:     // struct foo {...} register  x;1503  case tok::kw_auto:         // struct foo {...} auto      x;1504  case tok::kw_mutable:      // struct foo {...} mutable   x;1505  case tok::kw_thread_local: // struct foo {...} thread_local x;1506  case tok::kw_constexpr:    // struct foo {...} constexpr x;1507  case tok::kw_consteval:    // struct foo {...} consteval x;1508  case tok::kw_constinit:    // struct foo {...} constinit x;1509    // As shown above, type qualifiers and storage class specifiers absolutely1510    // can occur after class specifiers according to the grammar.  However,1511    // almost no one actually writes code like this.  If we see one of these,1512    // it is much more likely that someone missed a semi colon and the1513    // type/storage class specifier we're seeing is part of the *next*1514    // intended declaration, as in:1515    //1516    //   struct foo { ... }1517    //   typedef int X;1518    //1519    // We'd really like to emit a missing semicolon error instead of emitting1520    // an error on the 'int' saying that you can't have two type specifiers in1521    // the same declaration of X.  Because of this, we look ahead past this1522    // token to see if it's a type specifier.  If so, we know the code is1523    // otherwise invalid, so we can produce the expected semi error.1524    if (!isKnownToBeTypeSpecifier(NextToken()))1525      return true;1526    break;1527  case tok::r_brace: // struct bar { struct foo {...} }1528    // Missing ';' at end of struct is accepted as an extension in C mode.1529    if (!getLangOpts().CPlusPlus)1530      return true;1531    break;1532  case tok::greater:1533    // template<class T = class X>1534    return getLangOpts().CPlusPlus;1535  }1536  return false;1537}1538 1539void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,1540                                 SourceLocation StartLoc, DeclSpec &DS,1541                                 ParsedTemplateInfo &TemplateInfo,1542                                 AccessSpecifier AS, bool EnteringContext,1543                                 DeclSpecContext DSC,1544                                 ParsedAttributes &Attributes) {1545  DeclSpec::TST TagType;1546  if (TagTokKind == tok::kw_struct)1547    TagType = DeclSpec::TST_struct;1548  else if (TagTokKind == tok::kw___interface)1549    TagType = DeclSpec::TST_interface;1550  else if (TagTokKind == tok::kw_class)1551    TagType = DeclSpec::TST_class;1552  else {1553    assert(TagTokKind == tok::kw_union && "Not a class specifier");1554    TagType = DeclSpec::TST_union;1555  }1556 1557  if (Tok.is(tok::code_completion)) {1558    // Code completion for a struct, class, or union name.1559    cutOffParsing();1560    Actions.CodeCompletion().CodeCompleteTag(getCurScope(), TagType);1561    return;1562  }1563 1564  // C++20 [temp.class.spec] 13.7.5/101565  //   The usual access checking rules do not apply to non-dependent names1566  //   used to specify template arguments of the simple-template-id of the1567  //   partial specialization.1568  // C++20 [temp.spec] 13.9/6:1569  //   The usual access checking rules do not apply to names in a declaration1570  //   of an explicit instantiation or explicit specialization...1571  const bool shouldDelayDiagsInTag =1572      (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate);1573  SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);1574 1575  ParsedAttributes attrs(AttrFactory);1576  // If attributes exist after tag, parse them.1577  for (;;) {1578    MaybeParseAttributes(PAKM_CXX11 | PAKM_Declspec | PAKM_GNU, attrs);1579    // Parse inheritance specifiers.1580    if (Tok.isOneOf(tok::kw___single_inheritance,1581                    tok::kw___multiple_inheritance,1582                    tok::kw___virtual_inheritance)) {1583      ParseMicrosoftInheritanceClassAttributes(attrs);1584      continue;1585    }1586    if (Tok.is(tok::kw__Nullable)) {1587      ParseNullabilityClassAttributes(attrs);1588      continue;1589    }1590    break;1591  }1592 1593  // Source location used by FIXIT to insert misplaced1594  // C++11 attributes1595  SourceLocation AttrFixitLoc = Tok.getLocation();1596 1597  if (TagType == DeclSpec::TST_struct && Tok.isNot(tok::identifier) &&1598      !Tok.isAnnotation() && Tok.getIdentifierInfo() &&1599      Tok.isOneOf(1600#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait,1601#include "clang/Basic/TransformTypeTraits.def"1602          tok::kw___is_abstract,1603          tok::kw___is_aggregate,1604          tok::kw___is_arithmetic,1605          tok::kw___is_array,1606          tok::kw___is_assignable,1607          tok::kw___is_base_of,1608          tok::kw___is_bounded_array,1609          tok::kw___is_class,1610          tok::kw___is_complete_type,1611          tok::kw___is_compound,1612          tok::kw___is_const,1613          tok::kw___is_constructible,1614          tok::kw___is_convertible,1615          tok::kw___is_convertible_to,1616          tok::kw___is_destructible,1617          tok::kw___is_empty,1618          tok::kw___is_enum,1619          tok::kw___is_floating_point,1620          tok::kw___is_final,1621          tok::kw___is_function,1622          tok::kw___is_fundamental,1623          tok::kw___is_integral,1624          tok::kw___is_interface_class,1625          tok::kw___is_literal,1626          tok::kw___is_lvalue_expr,1627          tok::kw___is_lvalue_reference,1628          tok::kw___is_member_function_pointer,1629          tok::kw___is_member_object_pointer,1630          tok::kw___is_member_pointer,1631          tok::kw___is_nothrow_assignable,1632          tok::kw___is_nothrow_constructible,1633          tok::kw___is_nothrow_convertible,1634          tok::kw___is_nothrow_destructible,1635          tok::kw___is_object,1636          tok::kw___is_pod,1637          tok::kw___is_pointer,1638          tok::kw___is_polymorphic,1639          tok::kw___is_reference,1640          tok::kw___is_rvalue_expr,1641          tok::kw___is_rvalue_reference,1642          tok::kw___is_same,1643          tok::kw___is_scalar,1644          tok::kw___is_scoped_enum,1645          tok::kw___is_sealed,1646          tok::kw___is_signed,1647          tok::kw___is_standard_layout,1648          tok::kw___is_trivial,1649          tok::kw___is_trivially_equality_comparable,1650          tok::kw___is_trivially_assignable,1651          tok::kw___is_trivially_constructible,1652          tok::kw___is_trivially_copyable,1653          tok::kw___is_unbounded_array,1654          tok::kw___is_union,1655          tok::kw___is_unsigned,1656          tok::kw___is_void,1657          tok::kw___is_volatile1658      ))1659    // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the1660    // name of struct templates, but some are keywords in GCC >= 4.31661    // and Clang. Therefore, when we see the token sequence "struct1662    // X", make X into a normal identifier rather than a keyword, to1663    // allow libstdc++ 4.2 and libc++ to work properly.1664    TryKeywordIdentFallback(true);1665 1666  struct PreserveAtomicIdentifierInfoRAII {1667    PreserveAtomicIdentifierInfoRAII(Token &Tok, bool Enabled)1668        : AtomicII(nullptr) {1669      if (!Enabled)1670        return;1671      assert(Tok.is(tok::kw__Atomic));1672      AtomicII = Tok.getIdentifierInfo();1673      AtomicII->revertTokenIDToIdentifier();1674      Tok.setKind(tok::identifier);1675    }1676    ~PreserveAtomicIdentifierInfoRAII() {1677      if (!AtomicII)1678        return;1679      AtomicII->revertIdentifierToTokenID(tok::kw__Atomic);1680    }1681    IdentifierInfo *AtomicII;1682  };1683 1684  // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL1685  // implementation for VS2013 uses _Atomic as an identifier for one of the1686  // classes in <atomic>.  When we are parsing 'struct _Atomic', don't consider1687  // '_Atomic' to be a keyword.  We are careful to undo this so that clang can1688  // use '_Atomic' in its own header files.1689  bool ShouldChangeAtomicToIdentifier = getLangOpts().MSVCCompat &&1690                                        Tok.is(tok::kw__Atomic) &&1691                                        TagType == DeclSpec::TST_struct;1692  PreserveAtomicIdentifierInfoRAII AtomicTokenGuard(1693      Tok, ShouldChangeAtomicToIdentifier);1694 1695  // Parse the (optional) nested-name-specifier.1696  CXXScopeSpec &SS = DS.getTypeSpecScope();1697  if (getLangOpts().CPlusPlus) {1698    // "FOO : BAR" is not a potential typo for "FOO::BAR".  In this context it1699    // is a base-specifier-list.1700    ColonProtectionRAIIObject X(*this);1701 1702    CXXScopeSpec Spec;1703    if (TemplateInfo.TemplateParams)1704      Spec.setTemplateParamLists(*TemplateInfo.TemplateParams);1705 1706    bool HasValidSpec = true;1707    if (ParseOptionalCXXScopeSpecifier(Spec, /*ObjectType=*/nullptr,1708                                       /*ObjectHasErrors=*/false,1709                                       EnteringContext)) {1710      DS.SetTypeSpecError();1711      HasValidSpec = false;1712    }1713    if (Spec.isSet())1714      if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) {1715        Diag(Tok, diag::err_expected) << tok::identifier;1716        HasValidSpec = false;1717      }1718    if (HasValidSpec)1719      SS = Spec;1720  }1721 1722  TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;1723 1724  auto RecoverFromUndeclaredTemplateName = [&](IdentifierInfo *Name,1725                                               SourceLocation NameLoc,1726                                               SourceRange TemplateArgRange,1727                                               bool KnownUndeclared) {1728    Diag(NameLoc, diag::err_explicit_spec_non_template)1729        << (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation)1730        << TagTokKind << Name << TemplateArgRange << KnownUndeclared;1731 1732    // Strip off the last template parameter list if it was empty, since1733    // we've removed its template argument list.1734    if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {1735      if (TemplateParams->size() > 1) {1736        TemplateParams->pop_back();1737      } else {1738        TemplateParams = nullptr;1739        TemplateInfo.Kind = ParsedTemplateKind::NonTemplate;1740      }1741    } else if (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation) {1742      // Pretend this is just a forward declaration.1743      TemplateParams = nullptr;1744      TemplateInfo.Kind = ParsedTemplateKind::NonTemplate;1745      TemplateInfo.TemplateLoc = SourceLocation();1746      TemplateInfo.ExternLoc = SourceLocation();1747    }1748  };1749 1750  // Parse the (optional) class name or simple-template-id.1751  IdentifierInfo *Name = nullptr;1752  SourceLocation NameLoc;1753  TemplateIdAnnotation *TemplateId = nullptr;1754  if (Tok.is(tok::identifier)) {1755    Name = Tok.getIdentifierInfo();1756    NameLoc = ConsumeToken();1757    DS.SetRangeEnd(NameLoc);1758 1759    if (Tok.is(tok::less) && getLangOpts().CPlusPlus) {1760      // The name was supposed to refer to a template, but didn't.1761      // Eat the template argument list and try to continue parsing this as1762      // a class (or template thereof).1763      TemplateArgList TemplateArgs;1764      SourceLocation LAngleLoc, RAngleLoc;1765      if (ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs,1766                                           RAngleLoc)) {1767        // We couldn't parse the template argument list at all, so don't1768        // try to give any location information for the list.1769        LAngleLoc = RAngleLoc = SourceLocation();1770      }1771      RecoverFromUndeclaredTemplateName(1772          Name, NameLoc, SourceRange(LAngleLoc, RAngleLoc), false);1773    }1774  } else if (Tok.is(tok::annot_template_id)) {1775    TemplateId = takeTemplateIdAnnotation(Tok);1776    NameLoc = ConsumeAnnotationToken();1777 1778    if (TemplateId->Kind == TNK_Undeclared_template) {1779      // Try to resolve the template name to a type template. May update Kind.1780      Actions.ActOnUndeclaredTypeTemplateName(1781          getCurScope(), TemplateId->Template, TemplateId->Kind, NameLoc, Name);1782      if (TemplateId->Kind == TNK_Undeclared_template) {1783        RecoverFromUndeclaredTemplateName(1784            Name, NameLoc,1785            SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc), true);1786        TemplateId = nullptr;1787      }1788    }1789 1790    if (TemplateId && !TemplateId->mightBeType()) {1791      // The template-name in the simple-template-id refers to1792      // something other than a type template. Give an appropriate1793      // error message and skip to the ';'.1794      SourceRange Range(NameLoc);1795      if (SS.isNotEmpty())1796        Range.setBegin(SS.getBeginLoc());1797 1798      // FIXME: Name may be null here.1799      Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)1800          << TemplateId->Name << static_cast<int>(TemplateId->Kind) << Range;1801 1802      DS.SetTypeSpecError();1803      SkipUntil(tok::semi, StopBeforeMatch);1804      return;1805    }1806  }1807 1808  // There are four options here.1809  //  - If we are in a trailing return type, this is always just a reference,1810  //    and we must not try to parse a definition. For instance,1811  //      [] () -> struct S { };1812  //    does not define a type.1813  //  - If we have 'struct foo {...', 'struct foo :...',1814  //    'struct foo final :' or 'struct foo final {', then this is a definition.1815  //  - If we have 'struct foo;', then this is either a forward declaration1816  //    or a friend declaration, which have to be treated differently.1817  //  - Otherwise we have something like 'struct foo xyz', a reference.1818  //1819  //  We also detect these erroneous cases to provide better diagnostic for1820  //  C++11 attributes parsing.1821  //  - attributes follow class name:1822  //    struct foo [[]] {};1823  //  - attributes appear before or after 'final':1824  //    struct foo [[]] final [[]] {};1825  //1826  // However, in type-specifier-seq's, things look like declarations but are1827  // just references, e.g.1828  //   new struct s;1829  // or1830  //   &T::operator struct s;1831  // For these, DSC is DeclSpecContext::DSC_type_specifier or1832  // DeclSpecContext::DSC_alias_declaration.1833 1834  // If there are attributes after class name, parse them.1835  MaybeParseCXX11Attributes(Attributes);1836 1837  const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();1838  TagUseKind TUK;1839 1840  // C++26 [class.mem.general]p10: If a name-declaration matches the1841  // syntactic requirements of friend-type-declaration, it is a1842  // friend-type-declaration.1843  if (getLangOpts().CPlusPlus && DS.isFriendSpecifiedFirst() &&1844      Tok.isOneOf(tok::comma, tok::ellipsis))1845    TUK = TagUseKind::Friend;1846  else if (isDefiningTypeSpecifierContext(DSC, getLangOpts().CPlusPlus) ==1847               AllowDefiningTypeSpec::No ||1848           (getLangOpts().OpenMP && OpenMPDirectiveParsing))1849    TUK = TagUseKind::Reference;1850  else if (Tok.is(tok::l_brace) ||1851           (DSC != DeclSpecContext::DSC_association &&1852            getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||1853           (isClassCompatibleKeyword() &&1854            (NextToken().is(tok::l_brace) || NextToken().is(tok::colon) ||1855             isClassCompatibleKeyword(NextToken())))) {1856    if (DS.isFriendSpecified()) {1857      // C++ [class.friend]p2:1858      //   A class shall not be defined in a friend declaration.1859      Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)1860          << SourceRange(DS.getFriendSpecLoc());1861 1862      // Skip everything up to the semicolon, so that this looks like a proper1863      // friend class (or template thereof) declaration.1864      SkipUntil(tok::semi, StopBeforeMatch);1865      TUK = TagUseKind::Friend;1866    } else {1867      // Okay, this is a class definition.1868      TUK = TagUseKind::Definition;1869    }1870  } else if (isClassCompatibleKeyword() &&1871             (NextToken().is(tok::l_square) ||1872              NextToken().is(tok::kw_alignas) ||1873              NextToken().isRegularKeywordAttribute() ||1874              isCXX11VirtSpecifier(NextToken()) != VirtSpecifiers::VS_None ||1875              isCXX2CTriviallyRelocatableKeyword())) {1876    // We can't tell if this is a definition or reference1877    // until we skipped the 'final' and C++11 attribute specifiers.1878    TentativeParsingAction PA(*this);1879 1880    // Skip the 'final', abstract'... keywords.1881    while (isClassCompatibleKeyword())1882      ConsumeToken();1883 1884    // Skip C++11 attribute specifiers.1885    while (true) {1886      if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) {1887        ConsumeBracket();1888        if (!SkipUntil(tok::r_square, StopAtSemi))1889          break;1890      } else if (Tok.is(tok::kw_alignas) && NextToken().is(tok::l_paren)) {1891        ConsumeToken();1892        ConsumeParen();1893        if (!SkipUntil(tok::r_paren, StopAtSemi))1894          break;1895      } else if (Tok.isRegularKeywordAttribute()) {1896        bool TakesArgs = doesKeywordAttributeTakeArgs(Tok.getKind());1897        ConsumeToken();1898        if (TakesArgs) {1899          BalancedDelimiterTracker T(*this, tok::l_paren);1900          if (!T.consumeOpen())1901            T.skipToEnd();1902        }1903      } else {1904        break;1905      }1906    }1907 1908    if (Tok.isOneOf(tok::l_brace, tok::colon))1909      TUK = TagUseKind::Definition;1910    else1911      TUK = TagUseKind::Reference;1912 1913    PA.Revert();1914  } else if (!isTypeSpecifier(DSC) &&1915             (Tok.is(tok::semi) ||1916              (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) {1917    TUK = DS.isFriendSpecified() ? TagUseKind::Friend : TagUseKind::Declaration;1918    if (Tok.isNot(tok::semi)) {1919      const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();1920      // A semicolon was missing after this declaration. Diagnose and recover.1921      ExpectAndConsume(tok::semi, diag::err_expected_after,1922                       DeclSpec::getSpecifierName(TagType, PPol));1923      PP.EnterToken(Tok, /*IsReinject*/ true);1924      Tok.setKind(tok::semi);1925    }1926  } else1927    TUK = TagUseKind::Reference;1928 1929  // Forbid misplaced attributes. In cases of a reference, we pass attributes1930  // to caller to handle.1931  if (TUK != TagUseKind::Reference) {1932    // If this is not a reference, then the only possible1933    // valid place for C++11 attributes to appear here1934    // is between class-key and class-name. If there are1935    // any attributes after class-name, we try a fixit to move1936    // them to the right place.1937    SourceRange AttrRange = Attributes.Range;1938    if (AttrRange.isValid()) {1939      auto *FirstAttr = Attributes.empty() ? nullptr : &Attributes.front();1940      auto Loc = AttrRange.getBegin();1941      (FirstAttr && FirstAttr->isRegularKeywordAttribute()1942           ? Diag(Loc, diag::err_keyword_not_allowed) << FirstAttr1943           : Diag(Loc, diag::err_attributes_not_allowed))1944          << AttrRange1945          << FixItHint::CreateInsertionFromRange(1946                 AttrFixitLoc, CharSourceRange(AttrRange, true))1947          << FixItHint::CreateRemoval(AttrRange);1948 1949      // Recover by adding misplaced attributes to the attribute list1950      // of the class so they can be applied on the class later.1951      attrs.takeAllAppendingFrom(Attributes);1952    }1953  }1954 1955  if (!Name && !TemplateId &&1956      (DS.getTypeSpecType() == DeclSpec::TST_error ||1957       TUK != TagUseKind::Definition)) {1958    if (DS.getTypeSpecType() != DeclSpec::TST_error) {1959      // We have a declaration or reference to an anonymous class.1960      Diag(StartLoc, diag::err_anon_type_definition)1961          << DeclSpec::getSpecifierName(TagType, Policy);1962    }1963 1964    // If we are parsing a definition and stop at a base-clause, continue on1965    // until the semicolon.  Continuing from the comma will just trick us into1966    // thinking we are seeing a variable declaration.1967    if (TUK == TagUseKind::Definition && Tok.is(tok::colon))1968      SkipUntil(tok::semi, StopBeforeMatch);1969    else1970      SkipUntil(tok::comma, StopAtSemi);1971    return;1972  }1973 1974  // Create the tag portion of the class or class template.1975  DeclResult TagOrTempResult = true; // invalid1976  TypeResult TypeResult = true;      // invalid1977 1978  bool Owned = false;1979  SkipBodyInfo SkipBody;1980  if (TemplateId) {1981    // Explicit specialization, class template partial specialization,1982    // or explicit instantiation.1983    ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),1984                                       TemplateId->NumArgs);1985    if (TemplateId->isInvalid()) {1986      // Can't build the declaration.1987    } else if (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation &&1988               TUK == TagUseKind::Declaration) {1989      // This is an explicit instantiation of a class template.1990      ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,1991                              diag::err_keyword_not_allowed,1992                              /*DiagnoseEmptyAttrs=*/true);1993 1994      TagOrTempResult = Actions.ActOnExplicitInstantiation(1995          getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,1996          TagType, StartLoc, SS, TemplateId->Template,1997          TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr,1998          TemplateId->RAngleLoc, attrs);1999 2000      // Friend template-ids are treated as references unless2001      // they have template headers, in which case they're ill-formed2002      // (FIXME: "template <class T> friend class A<T>::B<int>;").2003      // We diagnose this error in ActOnClassTemplateSpecialization.2004    } else if (TUK == TagUseKind::Reference ||2005               (TUK == TagUseKind::Friend &&2006                TemplateInfo.Kind == ParsedTemplateKind::NonTemplate)) {2007      ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,2008                              diag::err_keyword_not_allowed,2009                              /*DiagnoseEmptyAttrs=*/true);2010      TypeResult = Actions.ActOnTagTemplateIdType(2011          TUK, TagType, StartLoc, SS, TemplateId->TemplateKWLoc,2012          TemplateId->Template, TemplateId->TemplateNameLoc,2013          TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc);2014    } else {2015      // This is an explicit specialization or a class template2016      // partial specialization.2017      TemplateParameterLists FakedParamLists;2018      if (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation) {2019        // This looks like an explicit instantiation, because we have2020        // something like2021        //2022        //   template class Foo<X>2023        //2024        // but it actually has a definition. Most likely, this was2025        // meant to be an explicit specialization, but the user forgot2026        // the '<>' after 'template'.2027        // It this is friend declaration however, since it cannot have a2028        // template header, it is most likely that the user meant to2029        // remove the 'template' keyword.2030        assert((TUK == TagUseKind::Definition || TUK == TagUseKind::Friend) &&2031               "Expected a definition here");2032 2033        if (TUK == TagUseKind::Friend) {2034          Diag(DS.getFriendSpecLoc(), diag::err_friend_explicit_instantiation);2035          TemplateParams = nullptr;2036        } else {2037          SourceLocation LAngleLoc =2038              PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);2039          Diag(TemplateId->TemplateNameLoc,2040               diag::err_explicit_instantiation_with_definition)2041              << SourceRange(TemplateInfo.TemplateLoc)2042              << FixItHint::CreateInsertion(LAngleLoc, "<>");2043 2044          // Create a fake template parameter list that contains only2045          // "template<>", so that we treat this construct as a class2046          // template specialization.2047          FakedParamLists.push_back(Actions.ActOnTemplateParameterList(2048              0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},2049              LAngleLoc, nullptr));2050          TemplateParams = &FakedParamLists;2051        }2052      }2053 2054      // Build the class template specialization.2055      TagOrTempResult = Actions.ActOnClassTemplateSpecialization(2056          getCurScope(), TagType, TUK, StartLoc, DS.getModulePrivateSpecLoc(),2057          SS, *TemplateId, attrs,2058          MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0]2059                                                : nullptr,2060                                 TemplateParams ? TemplateParams->size() : 0),2061          &SkipBody);2062    }2063  } else if (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation &&2064             TUK == TagUseKind::Declaration) {2065    // Explicit instantiation of a member of a class template2066    // specialization, e.g.,2067    //2068    //   template struct Outer<int>::Inner;2069    //2070    ProhibitAttributes(attrs);2071 2072    TagOrTempResult = Actions.ActOnExplicitInstantiation(2073        getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,2074        TagType, StartLoc, SS, Name, NameLoc, attrs);2075  } else if (TUK == TagUseKind::Friend &&2076             TemplateInfo.Kind != ParsedTemplateKind::NonTemplate) {2077    ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,2078                            diag::err_keyword_not_allowed,2079                            /*DiagnoseEmptyAttrs=*/true);2080 2081    // Consume '...' first so we error on the ',' after it if there is one.2082    SourceLocation EllipsisLoc;2083    TryConsumeToken(tok::ellipsis, EllipsisLoc);2084 2085    // CWG 2917: In a template-declaration whose declaration is a2086    // friend-type-declaration, the friend-type-specifier-list shall2087    // consist of exactly one friend-type-specifier.2088    //2089    // Essentially, the following is obviously nonsense, so disallow it:2090    //2091    //   template <typename>2092    //   friend class S, int;2093    //2094    if (Tok.is(tok::comma)) {2095      Diag(Tok.getLocation(),2096           diag::err_friend_template_decl_multiple_specifiers);2097      SkipUntil(tok::semi, StopBeforeMatch);2098    }2099 2100    TagOrTempResult = Actions.ActOnTemplatedFriendTag(2101        getCurScope(), DS.getFriendSpecLoc(), TagType, StartLoc, SS, Name,2102        NameLoc, EllipsisLoc, attrs,2103        MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] : nullptr,2104                               TemplateParams ? TemplateParams->size() : 0));2105  } else {2106    if (TUK != TagUseKind::Declaration && TUK != TagUseKind::Definition)2107      ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,2108                              diag::err_keyword_not_allowed,2109                              /* DiagnoseEmptyAttrs=*/true);2110 2111    if (TUK == TagUseKind::Definition &&2112        TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation) {2113      // If the declarator-id is not a template-id, issue a diagnostic and2114      // recover by ignoring the 'template' keyword.2115      Diag(Tok, diag::err_template_defn_explicit_instantiation)2116          << 1 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc);2117      TemplateParams = nullptr;2118    }2119 2120    bool IsDependent = false;2121 2122    // Don't pass down template parameter lists if this is just a tag2123    // reference.  For example, we don't need the template parameters here:2124    //   template <class T> class A *makeA(T t);2125    MultiTemplateParamsArg TParams;2126    if (TUK != TagUseKind::Reference && TemplateParams)2127      TParams =2128          MultiTemplateParamsArg(&(*TemplateParams)[0], TemplateParams->size());2129 2130    stripTypeAttributesOffDeclSpec(attrs, DS, TUK);2131 2132    // Declaration or definition of a class type2133    TagOrTempResult = Actions.ActOnTag(2134        getCurScope(), TagType, TUK, StartLoc, SS, Name, NameLoc, attrs, AS,2135        DS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent,2136        SourceLocation(), false, clang::TypeResult(),2137        DSC == DeclSpecContext::DSC_type_specifier,2138        DSC == DeclSpecContext::DSC_template_param ||2139            DSC == DeclSpecContext::DSC_template_type_arg,2140        OffsetOfState, &SkipBody);2141 2142    // If ActOnTag said the type was dependent, try again with the2143    // less common call.2144    if (IsDependent) {2145      assert(TUK == TagUseKind::Reference || TUK == TagUseKind::Friend);2146      TypeResult = Actions.ActOnDependentTag(getCurScope(), TagType, TUK, SS,2147                                             Name, StartLoc, NameLoc);2148    }2149  }2150 2151  // If this is an elaborated type specifier in function template,2152  // and we delayed diagnostics before,2153  // just merge them into the current pool.2154  if (shouldDelayDiagsInTag) {2155    diagsFromTag.done();2156    if (TUK == TagUseKind::Reference &&2157        TemplateInfo.Kind == ParsedTemplateKind::Template)2158      diagsFromTag.redelay();2159  }2160 2161  // If there is a body, parse it and inform the actions module.2162  if (TUK == TagUseKind::Definition) {2163    assert(Tok.is(tok::l_brace) ||2164           (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||2165           isClassCompatibleKeyword());2166    if (SkipBody.ShouldSkip)2167      SkipCXXMemberSpecification(StartLoc, AttrFixitLoc, TagType,2168                                 TagOrTempResult.get());2169    else if (getLangOpts().CPlusPlus)2170      ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs, TagType,2171                                  TagOrTempResult.get());2172    else {2173      Decl *D =2174          SkipBody.CheckSameAsPrevious ? SkipBody.New : TagOrTempResult.get();2175      // Parse the definition body.2176      ParseStructUnionBody(StartLoc, TagType, cast<RecordDecl>(D));2177      if (SkipBody.CheckSameAsPrevious &&2178          !Actions.ActOnDuplicateDefinition(getCurScope(),2179                                            TagOrTempResult.get(), SkipBody)) {2180        DS.SetTypeSpecError();2181        return;2182      }2183    }2184  }2185 2186  if (!TagOrTempResult.isInvalid())2187    // Delayed processing of attributes.2188    Actions.ProcessDeclAttributeDelayed(TagOrTempResult.get(), attrs);2189 2190  const char *PrevSpec = nullptr;2191  unsigned DiagID;2192  bool Result;2193  if (!TypeResult.isInvalid()) {2194    Result = DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,2195                                NameLoc.isValid() ? NameLoc : StartLoc,2196                                PrevSpec, DiagID, TypeResult.get(), Policy);2197  } else if (!TagOrTempResult.isInvalid()) {2198    Result = DS.SetTypeSpecType(2199        TagType, StartLoc, NameLoc.isValid() ? NameLoc : StartLoc, PrevSpec,2200        DiagID, TagOrTempResult.get(), Owned, Policy);2201  } else {2202    DS.SetTypeSpecError();2203    return;2204  }2205 2206  if (Result)2207    Diag(StartLoc, DiagID) << PrevSpec;2208 2209  // At this point, we've successfully parsed a class-specifier in 'definition'2210  // form (e.g. "struct foo { int x; }".  While we could just return here, we're2211  // going to look at what comes after it to improve error recovery.  If an2212  // impossible token occurs next, we assume that the programmer forgot a ; at2213  // the end of the declaration and recover that way.2214  //2215  // Also enforce C++ [temp]p3:2216  //   In a template-declaration which defines a class, no declarator2217  //   is permitted.2218  //2219  // After a type-specifier, we don't expect a semicolon. This only happens in2220  // C, since definitions are not permitted in this context in C++.2221  if (TUK == TagUseKind::Definition &&2222      (getLangOpts().CPlusPlus || !isTypeSpecifier(DSC)) &&2223      (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate || !isValidAfterTypeSpecifier(false))) {2224    if (Tok.isNot(tok::semi)) {2225      const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();2226      ExpectAndConsume(tok::semi, diag::err_expected_after,2227                       DeclSpec::getSpecifierName(TagType, PPol));2228      // Push this token back into the preprocessor and change our current token2229      // to ';' so that the rest of the code recovers as though there were an2230      // ';' after the definition.2231      PP.EnterToken(Tok, /*IsReinject=*/true);2232      Tok.setKind(tok::semi);2233    }2234  }2235}2236 2237void Parser::ParseBaseClause(Decl *ClassDecl) {2238  assert(Tok.is(tok::colon) && "Not a base clause");2239  ConsumeToken();2240 2241  // Build up an array of parsed base specifiers.2242  SmallVector<CXXBaseSpecifier *, 8> BaseInfo;2243 2244  while (true) {2245    // Parse a base-specifier.2246    BaseResult Result = ParseBaseSpecifier(ClassDecl);2247    if (!Result.isUsable()) {2248      // Skip the rest of this base specifier, up until the comma or2249      // opening brace.2250      SkipUntil(tok::comma, tok::l_brace, StopAtSemi | StopBeforeMatch);2251    } else {2252      // Add this to our array of base specifiers.2253      BaseInfo.push_back(Result.get());2254    }2255 2256    // If the next token is a comma, consume it and keep reading2257    // base-specifiers.2258    if (!TryConsumeToken(tok::comma))2259      break;2260  }2261 2262  // Attach the base specifiers2263  Actions.ActOnBaseSpecifiers(ClassDecl, BaseInfo);2264}2265 2266BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {2267  bool IsVirtual = false;2268  SourceLocation StartLoc = Tok.getLocation();2269 2270  ParsedAttributes Attributes(AttrFactory);2271  MaybeParseCXX11Attributes(Attributes);2272 2273  // Parse the 'virtual' keyword.2274  if (TryConsumeToken(tok::kw_virtual))2275    IsVirtual = true;2276 2277  CheckMisplacedCXX11Attribute(Attributes, StartLoc);2278 2279  // Parse an (optional) access specifier.2280  AccessSpecifier Access = getAccessSpecifierIfPresent();2281  if (Access != AS_none) {2282    ConsumeToken();2283    if (getLangOpts().HLSL)2284      Diag(Tok.getLocation(), diag::ext_hlsl_access_specifiers);2285  }2286 2287  CheckMisplacedCXX11Attribute(Attributes, StartLoc);2288 2289  // Parse the 'virtual' keyword (again!), in case it came after the2290  // access specifier.2291  if (Tok.is(tok::kw_virtual)) {2292    SourceLocation VirtualLoc = ConsumeToken();2293    if (IsVirtual) {2294      // Complain about duplicate 'virtual'2295      Diag(VirtualLoc, diag::err_dup_virtual)2296          << FixItHint::CreateRemoval(VirtualLoc);2297    }2298 2299    IsVirtual = true;2300  }2301 2302  if (getLangOpts().HLSL && IsVirtual)2303    Diag(Tok.getLocation(), diag::err_hlsl_virtual_inheritance);2304 2305  CheckMisplacedCXX11Attribute(Attributes, StartLoc);2306 2307  // Parse the class-name.2308 2309  // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL2310  // implementation for VS2013 uses _Atomic as an identifier for one of the2311  // classes in <atomic>.  Treat '_Atomic' to be an identifier when we are2312  // parsing the class-name for a base specifier.2313  if (getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&2314      NextToken().is(tok::less))2315    Tok.setKind(tok::identifier);2316 2317  SourceLocation EndLocation;2318  SourceLocation BaseLoc;2319  TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation);2320  if (BaseType.isInvalid())2321    return true;2322 2323  // Parse the optional ellipsis (for a pack expansion). The ellipsis is2324  // actually part of the base-specifier-list grammar productions, but we2325  // parse it here for convenience.2326  SourceLocation EllipsisLoc;2327  TryConsumeToken(tok::ellipsis, EllipsisLoc);2328 2329  // Find the complete source range for the base-specifier.2330  SourceRange Range(StartLoc, EndLocation);2331 2332  // Notify semantic analysis that we have parsed a complete2333  // base-specifier.2334  return Actions.ActOnBaseSpecifier(ClassDecl, Range, Attributes, IsVirtual,2335                                    Access, BaseType.get(), BaseLoc,2336                                    EllipsisLoc);2337}2338 2339AccessSpecifier Parser::getAccessSpecifierIfPresent() const {2340  switch (Tok.getKind()) {2341  default:2342    return AS_none;2343  case tok::kw_private:2344    return AS_private;2345  case tok::kw_protected:2346    return AS_protected;2347  case tok::kw_public:2348    return AS_public;2349  }2350}2351 2352void Parser::HandleMemberFunctionDeclDelays(Declarator &DeclaratorInfo,2353                                            Decl *ThisDecl) {2354  DeclaratorChunk::FunctionTypeInfo &FTI = DeclaratorInfo.getFunctionTypeInfo();2355  // If there was a late-parsed exception-specification, we'll need a2356  // late parse2357  bool NeedLateParse = FTI.getExceptionSpecType() == EST_Unparsed;2358 2359  if (!NeedLateParse) {2360    // Look ahead to see if there are any default args2361    for (unsigned ParamIdx = 0; ParamIdx < FTI.NumParams; ++ParamIdx) {2362      const auto *Param = cast<ParmVarDecl>(FTI.Params[ParamIdx].Param);2363      if (Param->hasUnparsedDefaultArg()) {2364        NeedLateParse = true;2365        break;2366      }2367    }2368  }2369 2370  if (NeedLateParse) {2371    // Push this method onto the stack of late-parsed method2372    // declarations.2373    auto LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);2374    getCurrentClass().LateParsedDeclarations.push_back(LateMethod);2375 2376    // Push tokens for each parameter. Those that do not have defaults will be2377    // NULL. We need to track all the parameters so that we can push them into2378    // scope for later parameters and perhaps for the exception specification.2379    LateMethod->DefaultArgs.reserve(FTI.NumParams);2380    for (unsigned ParamIdx = 0; ParamIdx < FTI.NumParams; ++ParamIdx)2381      LateMethod->DefaultArgs.push_back(LateParsedDefaultArgument(2382          FTI.Params[ParamIdx].Param,2383          std::move(FTI.Params[ParamIdx].DefaultArgTokens)));2384 2385    // Stash the exception-specification tokens in the late-pased method.2386    if (FTI.getExceptionSpecType() == EST_Unparsed) {2387      LateMethod->ExceptionSpecTokens = FTI.ExceptionSpecTokens;2388      FTI.ExceptionSpecTokens = nullptr;2389    }2390  }2391}2392 2393VirtSpecifiers::Specifier Parser::isCXX11VirtSpecifier(const Token &Tok) const {2394  if (!getLangOpts().CPlusPlus || Tok.isNot(tok::identifier))2395    return VirtSpecifiers::VS_None;2396 2397  const IdentifierInfo *II = Tok.getIdentifierInfo();2398 2399  // Initialize the contextual keywords.2400  if (!Ident_final) {2401    Ident_final = &PP.getIdentifierTable().get("final");2402    if (getLangOpts().GNUKeywords)2403      Ident_GNU_final = &PP.getIdentifierTable().get("__final");2404    if (getLangOpts().MicrosoftExt) {2405      Ident_sealed = &PP.getIdentifierTable().get("sealed");2406      Ident_abstract = &PP.getIdentifierTable().get("abstract");2407    }2408    Ident_override = &PP.getIdentifierTable().get("override");2409  }2410 2411  if (II == Ident_override)2412    return VirtSpecifiers::VS_Override;2413 2414  if (II == Ident_sealed)2415    return VirtSpecifiers::VS_Sealed;2416 2417  if (II == Ident_abstract)2418    return VirtSpecifiers::VS_Abstract;2419 2420  if (II == Ident_final)2421    return VirtSpecifiers::VS_Final;2422 2423  if (II == Ident_GNU_final)2424    return VirtSpecifiers::VS_GNU_Final;2425 2426  return VirtSpecifiers::VS_None;2427}2428 2429void Parser::ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS,2430                                                bool IsInterface,2431                                                SourceLocation FriendLoc) {2432  while (true) {2433    VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier();2434    if (Specifier == VirtSpecifiers::VS_None)2435      return;2436 2437    if (FriendLoc.isValid()) {2438      Diag(Tok.getLocation(), diag::err_friend_decl_spec)2439          << VirtSpecifiers::getSpecifierName(Specifier)2440          << FixItHint::CreateRemoval(Tok.getLocation())2441          << SourceRange(FriendLoc, FriendLoc);2442      ConsumeToken();2443      continue;2444    }2445 2446    // C++ [class.mem]p8:2447    //   A virt-specifier-seq shall contain at most one of each virt-specifier.2448    const char *PrevSpec = nullptr;2449    if (VS.SetSpecifier(Specifier, Tok.getLocation(), PrevSpec))2450      Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier)2451          << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());2452 2453    if (IsInterface && (Specifier == VirtSpecifiers::VS_Final ||2454                        Specifier == VirtSpecifiers::VS_Sealed)) {2455      Diag(Tok.getLocation(), diag::err_override_control_interface)2456          << VirtSpecifiers::getSpecifierName(Specifier);2457    } else if (Specifier == VirtSpecifiers::VS_Sealed) {2458      Diag(Tok.getLocation(), diag::ext_ms_sealed_keyword);2459    } else if (Specifier == VirtSpecifiers::VS_Abstract) {2460      Diag(Tok.getLocation(), diag::ext_ms_abstract_keyword);2461    } else if (Specifier == VirtSpecifiers::VS_GNU_Final) {2462      Diag(Tok.getLocation(), diag::ext_warn_gnu_final);2463    } else {2464      Diag(Tok.getLocation(),2465           getLangOpts().CPlusPlus112466               ? diag::warn_cxx98_compat_override_control_keyword2467               : diag::ext_override_control_keyword)2468          << VirtSpecifiers::getSpecifierName(Specifier);2469    }2470    ConsumeToken();2471  }2472}2473 2474bool Parser::isCXX11FinalKeyword() const {2475  VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier();2476  return Specifier == VirtSpecifiers::VS_Final ||2477         Specifier == VirtSpecifiers::VS_GNU_Final ||2478         Specifier == VirtSpecifiers::VS_Sealed;2479}2480 2481bool Parser::isCXX2CTriviallyRelocatableKeyword(Token Tok) const {2482  if (!getLangOpts().CPlusPlus || Tok.isNot(tok::identifier))2483    return false;2484  if (!Ident_trivially_relocatable_if_eligible)2485    Ident_trivially_relocatable_if_eligible =2486        &PP.getIdentifierTable().get("trivially_relocatable_if_eligible");2487  IdentifierInfo *II = Tok.getIdentifierInfo();2488  return II == Ident_trivially_relocatable_if_eligible;2489}2490 2491bool Parser::isCXX2CTriviallyRelocatableKeyword() const {2492  return isCXX2CTriviallyRelocatableKeyword(Tok);2493}2494 2495void Parser::ParseCXX2CTriviallyRelocatableSpecifier(SourceLocation &TRS) {2496  assert(isCXX2CTriviallyRelocatableKeyword() &&2497         "expected a trivially_relocatable specifier");2498 2499  Diag(Tok.getLocation(), getLangOpts().CPlusPlus262500                              ? diag::warn_relocatable_keyword2501                              : diag::ext_relocatable_keyword)2502      << /*relocatable*/ 0;2503 2504  TRS = ConsumeToken();2505}2506 2507bool Parser::isCXX2CReplaceableKeyword(Token Tok) const {2508  if (!getLangOpts().CPlusPlus || Tok.isNot(tok::identifier))2509    return false;2510  if (!Ident_replaceable_if_eligible)2511    Ident_replaceable_if_eligible =2512        &PP.getIdentifierTable().get("replaceable_if_eligible");2513  IdentifierInfo *II = Tok.getIdentifierInfo();2514  return II == Ident_replaceable_if_eligible;2515}2516 2517bool Parser::isCXX2CReplaceableKeyword() const {2518  return isCXX2CReplaceableKeyword(Tok);2519}2520 2521void Parser::ParseCXX2CReplaceableSpecifier(SourceLocation &MRS) {2522  assert(isCXX2CReplaceableKeyword() &&2523         "expected a replaceable_if_eligible specifier");2524 2525  Diag(Tok.getLocation(), getLangOpts().CPlusPlus262526                              ? diag::warn_relocatable_keyword2527                              : diag::ext_relocatable_keyword)2528      << /*replaceable*/ 1;2529 2530  MRS = ConsumeToken();2531}2532 2533bool Parser::isClassCompatibleKeyword(Token Tok) const {2534  if (isCXX2CTriviallyRelocatableKeyword(Tok) || isCXX2CReplaceableKeyword(Tok))2535    return true;2536  VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier(Tok);2537  return Specifier == VirtSpecifiers::VS_Final ||2538         Specifier == VirtSpecifiers::VS_GNU_Final ||2539         Specifier == VirtSpecifiers::VS_Sealed ||2540         Specifier == VirtSpecifiers::VS_Abstract;2541}2542 2543bool Parser::isClassCompatibleKeyword() const {2544  return isClassCompatibleKeyword(Tok);2545}2546 2547/// Parse a C++ member-declarator up to, but not including, the optional2548/// brace-or-equal-initializer or pure-specifier.2549bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(2550    Declarator &DeclaratorInfo, VirtSpecifiers &VS, ExprResult &BitfieldSize,2551    LateParsedAttrList &LateParsedAttrs) {2552  // member-declarator:2553  //   declarator virt-specifier-seq[opt] pure-specifier[opt]2554  //   declarator requires-clause2555  //   declarator brace-or-equal-initializer[opt]2556  //   identifier attribute-specifier-seq[opt] ':' constant-expression2557  //       brace-or-equal-initializer[opt]2558  //   ':' constant-expression2559  //2560  // NOTE: the latter two productions are a proposed bugfix rather than the2561  // current grammar rules as of C++20.2562  if (Tok.isNot(tok::colon))2563    ParseDeclarator(DeclaratorInfo);2564  else2565    DeclaratorInfo.SetIdentifier(nullptr, Tok.getLocation());2566 2567  if (getLangOpts().HLSL)2568    MaybeParseHLSLAnnotations(DeclaratorInfo, nullptr,2569                              /*CouldBeBitField*/ true);2570 2571  if (!DeclaratorInfo.isFunctionDeclarator() && TryConsumeToken(tok::colon)) {2572    assert(DeclaratorInfo.isPastIdentifier() &&2573           "don't know where identifier would go yet?");2574    BitfieldSize = ParseConstantExpression();2575    if (BitfieldSize.isInvalid())2576      SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);2577  } else if (Tok.is(tok::kw_requires)) {2578    ParseTrailingRequiresClause(DeclaratorInfo);2579  } else {2580    ParseOptionalCXX11VirtSpecifierSeq(2581        VS, getCurrentClass().IsInterface,2582        DeclaratorInfo.getDeclSpec().getFriendSpecLoc());2583    if (!VS.isUnset())2584      MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo,2585                                                              VS);2586  }2587 2588  // If a simple-asm-expr is present, parse it.2589  if (Tok.is(tok::kw_asm)) {2590    SourceLocation Loc;2591    ExprResult AsmLabel(ParseSimpleAsm(/*ForAsmLabel*/ true, &Loc));2592    if (AsmLabel.isInvalid())2593      SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);2594 2595    DeclaratorInfo.setAsmLabel(AsmLabel.get());2596    DeclaratorInfo.SetRangeEnd(Loc);2597  }2598 2599  // If attributes exist after the declarator, but before an '{', parse them.2600  // However, this does not apply for [[]] attributes (which could show up2601  // before or after the __attribute__ attributes).2602  DiagnoseAndSkipCXX11Attributes();2603  MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);2604  DiagnoseAndSkipCXX11Attributes();2605 2606  // For compatibility with code written to older Clang, also accept a2607  // virt-specifier *after* the GNU attributes.2608  if (BitfieldSize.isUnset() && VS.isUnset()) {2609    ParseOptionalCXX11VirtSpecifierSeq(2610        VS, getCurrentClass().IsInterface,2611        DeclaratorInfo.getDeclSpec().getFriendSpecLoc());2612    if (!VS.isUnset()) {2613      // If we saw any GNU-style attributes that are known to GCC followed by a2614      // virt-specifier, issue a GCC-compat warning.2615      for (const ParsedAttr &AL : DeclaratorInfo.getAttributes())2616        if (AL.isKnownToGCC() && !AL.isCXX11Attribute())2617          Diag(AL.getLoc(), diag::warn_gcc_attribute_location);2618 2619      MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo,2620                                                              VS);2621    }2622  }2623 2624  // If this has neither a name nor a bit width, something has gone seriously2625  // wrong. Skip until the semi-colon or }.2626  if (!DeclaratorInfo.hasName() && BitfieldSize.isUnset()) {2627    // If so, skip until the semi-colon or a }.2628    SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);2629    return true;2630  }2631  return false;2632}2633 2634void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(2635    Declarator &D, VirtSpecifiers &VS) {2636  DeclSpec DS(AttrFactory);2637 2638  // GNU-style and C++11 attributes are not allowed here, but they will be2639  // handled by the caller.  Diagnose everything else.2640  ParseTypeQualifierListOpt(2641      DS, AR_NoAttributesParsed, /*AtomicOrPtrauthAllowed=*/false,2642      /*IdentifierRequired=*/false, [&]() {2643        Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D, &VS);2644      });2645  D.ExtendWithDeclSpec(DS);2646 2647  if (D.isFunctionDeclarator()) {2648    auto &Function = D.getFunctionTypeInfo();2649    if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {2650      auto DeclSpecCheck = [&](DeclSpec::TQ TypeQual, StringRef FixItName,2651                               SourceLocation SpecLoc) {2652        FixItHint Insertion;2653        auto &MQ = Function.getOrCreateMethodQualifiers();2654        if (!(MQ.getTypeQualifiers() & TypeQual)) {2655          std::string Name(FixItName.data());2656          Name += " ";2657          Insertion = FixItHint::CreateInsertion(VS.getFirstLocation(), Name);2658          MQ.SetTypeQual(TypeQual, SpecLoc);2659        }2660        Diag(SpecLoc, diag::err_declspec_after_virtspec)2661            << FixItName2662            << VirtSpecifiers::getSpecifierName(VS.getLastSpecifier())2663            << FixItHint::CreateRemoval(SpecLoc) << Insertion;2664      };2665      DS.forEachQualifier(DeclSpecCheck);2666    }2667 2668    // Parse ref-qualifiers.2669    bool RefQualifierIsLValueRef = true;2670    SourceLocation RefQualifierLoc;2671    if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc)) {2672      const char *Name = (RefQualifierIsLValueRef ? "& " : "&& ");2673      FixItHint Insertion =2674          FixItHint::CreateInsertion(VS.getFirstLocation(), Name);2675      Function.RefQualifierIsLValueRef = RefQualifierIsLValueRef;2676      Function.RefQualifierLoc = RefQualifierLoc;2677 2678      Diag(RefQualifierLoc, diag::err_declspec_after_virtspec)2679          << (RefQualifierIsLValueRef ? "&" : "&&")2680          << VirtSpecifiers::getSpecifierName(VS.getLastSpecifier())2681          << FixItHint::CreateRemoval(RefQualifierLoc) << Insertion;2682      D.SetRangeEnd(RefQualifierLoc);2683    }2684  }2685}2686 2687Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration(2688    AccessSpecifier AS, ParsedAttributes &AccessAttrs,2689    ParsedTemplateInfo &TemplateInfo, ParsingDeclRAIIObject *TemplateDiags) {2690  assert(getLangOpts().CPlusPlus &&2691         "ParseCXXClassMemberDeclaration should only be called in C++ mode");2692  if (Tok.is(tok::at)) {2693    if (getLangOpts().ObjC && NextToken().isObjCAtKeyword(tok::objc_defs))2694      Diag(Tok, diag::err_at_defs_cxx);2695    else2696      Diag(Tok, diag::err_at_in_class);2697 2698    ConsumeToken();2699    SkipUntil(tok::r_brace, StopAtSemi);2700    return nullptr;2701  }2702 2703  // Turn on colon protection early, while parsing declspec, although there is2704  // nothing to protect there. It prevents from false errors if error recovery2705  // incorrectly determines where the declspec ends, as in the example:2706  //   struct A { enum class B { C }; };2707  //   const int C = 4;2708  //   struct D { A::B : C; };2709  ColonProtectionRAIIObject X(*this);2710 2711  // Access declarations.2712  bool MalformedTypeSpec = false;2713  if (TemplateInfo.Kind == ParsedTemplateKind::NonTemplate &&2714      Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw___super)) {2715    if (TryAnnotateCXXScopeToken())2716      MalformedTypeSpec = true;2717 2718    bool isAccessDecl;2719    if (Tok.isNot(tok::annot_cxxscope))2720      isAccessDecl = false;2721    else if (NextToken().is(tok::identifier))2722      isAccessDecl = GetLookAheadToken(2).is(tok::semi);2723    else2724      isAccessDecl = NextToken().is(tok::kw_operator);2725 2726    if (isAccessDecl) {2727      // Collect the scope specifier token we annotated earlier.2728      CXXScopeSpec SS;2729      ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,2730                                     /*ObjectHasErrors=*/false,2731                                     /*EnteringContext=*/false);2732 2733      if (SS.isInvalid()) {2734        SkipUntil(tok::semi);2735        return nullptr;2736      }2737 2738      // Try to parse an unqualified-id.2739      SourceLocation TemplateKWLoc;2740      UnqualifiedId Name;2741      if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr,2742                             /*ObjectHadErrors=*/false, false, true, true,2743                             false, &TemplateKWLoc, Name)) {2744        SkipUntil(tok::semi);2745        return nullptr;2746      }2747 2748      // TODO: recover from mistakenly-qualified operator declarations.2749      if (ExpectAndConsume(tok::semi, diag::err_expected_after,2750                           "access declaration")) {2751        SkipUntil(tok::semi);2752        return nullptr;2753      }2754 2755      // FIXME: We should do something with the 'template' keyword here.2756      return DeclGroupPtrTy::make(DeclGroupRef(Actions.ActOnUsingDeclaration(2757          getCurScope(), AS, /*UsingLoc*/ SourceLocation(),2758          /*TypenameLoc*/ SourceLocation(), SS, Name,2759          /*EllipsisLoc*/ SourceLocation(),2760          /*AttrList*/ ParsedAttributesView())));2761    }2762  }2763 2764  // static_assert-declaration. A templated static_assert declaration is2765  // diagnosed in Parser::ParseDeclarationAfterTemplate.2766  if (TemplateInfo.Kind == ParsedTemplateKind::NonTemplate &&2767      Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {2768    SourceLocation DeclEnd;2769    return DeclGroupPtrTy::make(2770        DeclGroupRef(ParseStaticAssertDeclaration(DeclEnd)));2771  }2772 2773  if (Tok.is(tok::kw_template)) {2774    assert(!TemplateInfo.TemplateParams &&2775           "Nested template improperly parsed?");2776    ObjCDeclContextSwitch ObjCDC(*this);2777    SourceLocation DeclEnd;2778    return ParseTemplateDeclarationOrSpecialization(DeclaratorContext::Member,2779                                                    DeclEnd, AccessAttrs, AS);2780  }2781 2782  // Handle:  member-declaration ::= '__extension__' member-declaration2783  if (Tok.is(tok::kw___extension__)) {2784    // __extension__ silences extension warnings in the subexpression.2785    ExtensionRAIIObject O(Diags); // Use RAII to do this.2786    ConsumeToken();2787    return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,2788                                          TemplateDiags);2789  }2790 2791  ParsedAttributes DeclAttrs(AttrFactory);2792  // Optional C++11 attribute-specifier2793  MaybeParseCXX11Attributes(DeclAttrs);2794 2795  // The next token may be an OpenMP pragma annotation token. That would2796  // normally be handled from ParseCXXClassMemberDeclarationWithPragmas, but in2797  // this case, it came from an *attribute* rather than a pragma. Handle it now.2798  if (Tok.is(tok::annot_attr_openmp))2799    return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, DeclAttrs);2800 2801  if (Tok.is(tok::kw_using)) {2802    // Eat 'using'.2803    SourceLocation UsingLoc = ConsumeToken();2804 2805    // Consume unexpected 'template' keywords.2806    while (Tok.is(tok::kw_template)) {2807      SourceLocation TemplateLoc = ConsumeToken();2808      Diag(TemplateLoc, diag::err_unexpected_template_after_using)2809          << FixItHint::CreateRemoval(TemplateLoc);2810    }2811 2812    if (Tok.is(tok::kw_namespace)) {2813      Diag(UsingLoc, diag::err_using_namespace_in_class);2814      SkipUntil(tok::semi, StopBeforeMatch);2815      return nullptr;2816    }2817    SourceLocation DeclEnd;2818    // Otherwise, it must be a using-declaration or an alias-declaration.2819    return ParseUsingDeclaration(DeclaratorContext::Member, TemplateInfo,2820                                 UsingLoc, DeclEnd, DeclAttrs, AS);2821  }2822 2823  ParsedAttributes DeclSpecAttrs(AttrFactory);2824  // Hold late-parsed attributes so we can attach a Decl to them later.2825  LateParsedAttrList CommonLateParsedAttrs;2826 2827  while (MaybeParseCXX11Attributes(DeclAttrs) ||2828         MaybeParseGNUAttributes(DeclSpecAttrs, &CommonLateParsedAttrs) ||2829         MaybeParseMicrosoftAttributes(DeclSpecAttrs))2830    ;2831 2832  SourceLocation DeclStart;2833  if (DeclAttrs.Range.isValid()) {2834    DeclStart = DeclSpecAttrs.Range.isInvalid()2835                    ? DeclAttrs.Range.getBegin()2836                    : std::min(DeclAttrs.Range.getBegin(),2837                               DeclSpecAttrs.Range.getBegin());2838  } else {2839    DeclStart = DeclSpecAttrs.Range.getBegin();2840  }2841 2842  // decl-specifier-seq:2843  // Parse the common declaration-specifiers piece.2844  ParsingDeclSpec DS(*this, TemplateDiags);2845  DS.takeAttributesAppendingingFrom(DeclSpecAttrs);2846 2847  if (MalformedTypeSpec)2848    DS.SetTypeSpecError();2849 2850  // Turn off usual access checking for templates explicit specialization2851  // and instantiation.2852  // C++20 [temp.spec] 13.9/6.2853  // This disables the access checking rules for member function template2854  // explicit instantiation and explicit specialization.2855  bool IsTemplateSpecOrInst =2856      (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation ||2857       TemplateInfo.Kind == ParsedTemplateKind::ExplicitSpecialization);2858  SuppressAccessChecks diagsFromTag(*this, IsTemplateSpecOrInst);2859 2860  ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DeclSpecContext::DSC_class,2861                             &CommonLateParsedAttrs);2862 2863  if (IsTemplateSpecOrInst)2864    diagsFromTag.done();2865 2866  // Turn off colon protection that was set for declspec.2867  X.restore();2868 2869  if (DeclStart.isValid())2870    DS.SetRangeStart(DeclStart);2871 2872  // If we had a free-standing type definition with a missing semicolon, we2873  // may get this far before the problem becomes obvious.2874  if (DS.hasTagDefinition() &&2875      TemplateInfo.Kind == ParsedTemplateKind::NonTemplate &&2876      DiagnoseMissingSemiAfterTagDefinition(DS, AS, DeclSpecContext::DSC_class,2877                                            &CommonLateParsedAttrs))2878    return nullptr;2879 2880  MultiTemplateParamsArg TemplateParams(2881      TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data()2882                                  : nullptr,2883      TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);2884 2885  if (TryConsumeToken(tok::semi)) {2886    if (DS.isFriendSpecified())2887      ProhibitAttributes(DeclAttrs);2888 2889    RecordDecl *AnonRecord = nullptr;2890    Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(2891        getCurScope(), AS, DS, DeclAttrs, TemplateParams, false, AnonRecord);2892    Actions.ActOnDefinedDeclarationSpecifier(TheDecl);2893    DS.complete(TheDecl);2894    if (AnonRecord) {2895      Decl *decls[] = {AnonRecord, TheDecl};2896      return Actions.BuildDeclaratorGroup(decls);2897    }2898    return Actions.ConvertDeclToDeclGroup(TheDecl);2899  }2900 2901  if (DS.hasTagDefinition())2902    Actions.ActOnDefinedDeclarationSpecifier(DS.getRepAsDecl());2903 2904  // Handle C++26's variadic friend declarations. These don't even have2905  // declarators, so we get them out of the way early here.2906  if (DS.isFriendSpecifiedFirst() && Tok.isOneOf(tok::comma, tok::ellipsis)) {2907    Diag(Tok.getLocation(), getLangOpts().CPlusPlus262908                                ? diag::warn_cxx23_variadic_friends2909                                : diag::ext_variadic_friends);2910 2911    SourceLocation FriendLoc = DS.getFriendSpecLoc();2912    SmallVector<Decl *> Decls;2913 2914    // Handles a single friend-type-specifier.2915    auto ParsedFriendDecl = [&](ParsingDeclSpec &DeclSpec) {2916      SourceLocation VariadicLoc;2917      TryConsumeToken(tok::ellipsis, VariadicLoc);2918 2919      RecordDecl *AnonRecord = nullptr;2920      Decl *D = Actions.ParsedFreeStandingDeclSpec(2921          getCurScope(), AS, DeclSpec, DeclAttrs, TemplateParams, false,2922          AnonRecord, VariadicLoc);2923      DeclSpec.complete(D);2924      if (!D) {2925        SkipUntil(tok::semi, tok::r_brace);2926        return true;2927      }2928 2929      Decls.push_back(D);2930      return false;2931    };2932 2933    if (ParsedFriendDecl(DS))2934      return nullptr;2935 2936    while (TryConsumeToken(tok::comma)) {2937      ParsingDeclSpec DeclSpec(*this, TemplateDiags);2938      const char *PrevSpec = nullptr;2939      unsigned DiagId = 0;2940      DeclSpec.SetFriendSpec(FriendLoc, PrevSpec, DiagId);2941      ParseDeclarationSpecifiers(DeclSpec, TemplateInfo, AS,2942                                 DeclSpecContext::DSC_class, nullptr);2943      if (ParsedFriendDecl(DeclSpec))2944        return nullptr;2945    }2946 2947    ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt,2948                     "friend declaration");2949 2950    return Actions.BuildDeclaratorGroup(Decls);2951  }2952 2953  // Befriending a concept is invalid and would already fail if2954  // we did nothing here, but this allows us to issue a more2955  // helpful diagnostic.2956  if (Tok.is(tok::kw_concept)) {2957    Diag(2958        Tok.getLocation(),2959        DS.isFriendSpecified() || NextToken().is(tok::kw_friend)2960            ? llvm::to_underlying(diag::err_friend_concept)2961            : llvm::to_underlying(2962                  diag::2963                      err_concept_decls_may_only_appear_in_global_namespace_scope));2964    SkipUntil(tok::semi, tok::r_brace, StopBeforeMatch);2965    return nullptr;2966  }2967 2968  ParsingDeclarator DeclaratorInfo(*this, DS, DeclAttrs,2969                                   DeclaratorContext::Member);2970  if (TemplateInfo.TemplateParams)2971    DeclaratorInfo.setTemplateParameterLists(TemplateParams);2972  VirtSpecifiers VS;2973 2974  // Hold late-parsed attributes so we can attach a Decl to them later.2975  LateParsedAttrList LateParsedAttrs;2976 2977  SourceLocation EqualLoc;2978  SourceLocation PureSpecLoc;2979 2980  auto TryConsumePureSpecifier = [&](bool AllowDefinition) {2981    if (Tok.isNot(tok::equal))2982      return false;2983 2984    auto &Zero = NextToken();2985    SmallString<8> Buffer;2986    if (Zero.isNot(tok::numeric_constant) ||2987        PP.getSpelling(Zero, Buffer) != "0")2988      return false;2989 2990    auto &After = GetLookAheadToken(2);2991    if (!After.isOneOf(tok::semi, tok::comma) &&2992        !(AllowDefinition &&2993          After.isOneOf(tok::l_brace, tok::colon, tok::kw_try)))2994      return false;2995 2996    EqualLoc = ConsumeToken();2997    PureSpecLoc = ConsumeToken();2998    return true;2999  };3000 3001  SmallVector<Decl *, 8> DeclsInGroup;3002  ExprResult BitfieldSize;3003  ExprResult TrailingRequiresClause;3004  bool ExpectSemi = true;3005 3006  // C++20 [temp.spec] 13.9/6.3007  // This disables the access checking rules for member function template3008  // explicit instantiation and explicit specialization.3009  SuppressAccessChecks SAC(*this, IsTemplateSpecOrInst);3010 3011  // Parse the first declarator.3012  if (ParseCXXMemberDeclaratorBeforeInitializer(3013          DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs)) {3014    TryConsumeToken(tok::semi);3015    return nullptr;3016  }3017 3018  if (IsTemplateSpecOrInst)3019    SAC.done();3020 3021  // Check for a member function definition.3022  if (BitfieldSize.isUnset()) {3023    // MSVC permits pure specifier on inline functions defined at class scope.3024    // Hence check for =0 before checking for function definition.3025    if (getLangOpts().MicrosoftExt && DeclaratorInfo.isDeclarationOfFunction())3026      TryConsumePureSpecifier(/*AllowDefinition*/ true);3027 3028    FunctionDefinitionKind DefinitionKind = FunctionDefinitionKind::Declaration;3029    // function-definition:3030    //3031    // In C++11, a non-function declarator followed by an open brace is a3032    // braced-init-list for an in-class member initialization, not an3033    // erroneous function definition.3034    if (Tok.is(tok::l_brace) && !getLangOpts().CPlusPlus11) {3035      DefinitionKind = FunctionDefinitionKind::Definition;3036    } else if (DeclaratorInfo.isFunctionDeclarator()) {3037      if (Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try)) {3038        DefinitionKind = FunctionDefinitionKind::Definition;3039      } else if (Tok.is(tok::equal)) {3040        const Token &KW = NextToken();3041        if (KW.is(tok::kw_default))3042          DefinitionKind = FunctionDefinitionKind::Defaulted;3043        else if (KW.is(tok::kw_delete))3044          DefinitionKind = FunctionDefinitionKind::Deleted;3045        else if (KW.is(tok::code_completion)) {3046          cutOffParsing();3047          Actions.CodeCompletion().CodeCompleteAfterFunctionEquals(3048              DeclaratorInfo);3049          return nullptr;3050        }3051      }3052    }3053    DeclaratorInfo.setFunctionDefinitionKind(DefinitionKind);3054 3055    // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains3056    // to a friend declaration, that declaration shall be a definition.3057    if (DeclaratorInfo.isFunctionDeclarator() &&3058        DefinitionKind == FunctionDefinitionKind::Declaration &&3059        DS.isFriendSpecified()) {3060      // Diagnose attributes that appear before decl specifier:3061      // [[]] friend int foo();3062      ProhibitAttributes(DeclAttrs);3063    }3064 3065    if (DefinitionKind != FunctionDefinitionKind::Declaration) {3066      if (!DeclaratorInfo.isFunctionDeclarator()) {3067        Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params);3068        ConsumeBrace();3069        SkipUntil(tok::r_brace);3070 3071        // Consume the optional ';'3072        TryConsumeToken(tok::semi);3073 3074        return nullptr;3075      }3076 3077      if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {3078        Diag(DeclaratorInfo.getIdentifierLoc(),3079             diag::err_function_declared_typedef);3080 3081        // Recover by treating the 'typedef' as spurious.3082        DS.ClearStorageClassSpecs();3083      }3084 3085      Decl *FunDecl = ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo,3086                                              TemplateInfo, VS, PureSpecLoc);3087 3088      if (FunDecl) {3089        for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {3090          CommonLateParsedAttrs[i]->addDecl(FunDecl);3091        }3092        for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {3093          LateParsedAttrs[i]->addDecl(FunDecl);3094        }3095      }3096      LateParsedAttrs.clear();3097 3098      // Consume the ';' - it's optional unless we have a delete or default3099      if (Tok.is(tok::semi))3100        ConsumeExtraSemi(ExtraSemiKind::AfterMemberFunctionDefinition);3101 3102      return DeclGroupPtrTy::make(DeclGroupRef(FunDecl));3103    }3104  }3105 3106  // member-declarator-list:3107  //   member-declarator3108  //   member-declarator-list ',' member-declarator3109 3110  while (true) {3111    InClassInitStyle HasInClassInit = ICIS_NoInit;3112    bool HasStaticInitializer = false;3113    if (Tok.isOneOf(tok::equal, tok::l_brace) && PureSpecLoc.isInvalid()) {3114      // DRXXXX: Anonymous bit-fields cannot have a brace-or-equal-initializer.3115      if (BitfieldSize.isUsable() && !DeclaratorInfo.hasName()) {3116        // Diagnose the error and pretend there is no in-class initializer.3117        Diag(Tok, diag::err_anon_bitfield_member_init);3118        SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);3119      } else if (DeclaratorInfo.isDeclarationOfFunction()) {3120        // It's a pure-specifier.3121        if (!TryConsumePureSpecifier(/*AllowFunctionDefinition*/ false))3122          // Parse it as an expression so that Sema can diagnose it.3123          HasStaticInitializer = true;3124      } else if (DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=3125                     DeclSpec::SCS_static &&3126                 DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=3127                     DeclSpec::SCS_typedef &&3128                 !DS.isFriendSpecified() &&3129                 TemplateInfo.Kind == ParsedTemplateKind::NonTemplate) {3130        // It's a default member initializer.3131        if (BitfieldSize.get())3132          Diag(Tok, getLangOpts().CPlusPlus203133                        ? diag::warn_cxx17_compat_bitfield_member_init3134                        : diag::ext_bitfield_member_init);3135        HasInClassInit = Tok.is(tok::equal) ? ICIS_CopyInit : ICIS_ListInit;3136      } else {3137        HasStaticInitializer = true;3138      }3139    }3140 3141    // NOTE: If Sema is the Action module and declarator is an instance field,3142    // this call will *not* return the created decl; It will return null.3143    // See Sema::ActOnCXXMemberDeclarator for details.3144 3145    NamedDecl *ThisDecl = nullptr;3146    if (DS.isFriendSpecified()) {3147      // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains3148      // to a friend declaration, that declaration shall be a definition.3149      //3150      // Diagnose attributes that appear in a friend member function declarator:3151      //   friend int foo [[]] ();3152      for (const ParsedAttr &AL : DeclaratorInfo.getAttributes())3153        if (AL.isCXX11Attribute() || AL.isRegularKeywordAttribute()) {3154          auto Loc = AL.getRange().getBegin();3155          (AL.isRegularKeywordAttribute()3156               ? Diag(Loc, diag::err_keyword_not_allowed) << AL3157               : Diag(Loc, diag::err_attributes_not_allowed))3158              << AL.getRange();3159        }3160 3161      ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo,3162                                                 TemplateParams);3163    } else {3164      ThisDecl = Actions.ActOnCXXMemberDeclarator(3165          getCurScope(), AS, DeclaratorInfo, TemplateParams, BitfieldSize.get(),3166          VS, HasInClassInit);3167 3168      if (VarTemplateDecl *VT =3169              ThisDecl ? dyn_cast<VarTemplateDecl>(ThisDecl) : nullptr)3170        // Re-direct this decl to refer to the templated decl so that we can3171        // initialize it.3172        ThisDecl = VT->getTemplatedDecl();3173 3174      if (ThisDecl)3175        Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs);3176    }3177 3178    // Error recovery might have converted a non-static member into a static3179    // member.3180    if (HasInClassInit != ICIS_NoInit &&3181        DeclaratorInfo.getDeclSpec().getStorageClassSpec() ==3182            DeclSpec::SCS_static) {3183      HasInClassInit = ICIS_NoInit;3184      HasStaticInitializer = true;3185    }3186 3187    if (PureSpecLoc.isValid() && VS.getAbstractLoc().isValid()) {3188      Diag(PureSpecLoc, diag::err_duplicate_virt_specifier) << "abstract";3189    }3190    if (ThisDecl && PureSpecLoc.isValid())3191      Actions.ActOnPureSpecifier(ThisDecl, PureSpecLoc);3192    else if (ThisDecl && VS.getAbstractLoc().isValid())3193      Actions.ActOnPureSpecifier(ThisDecl, VS.getAbstractLoc());3194 3195    // Handle the initializer.3196    if (HasInClassInit != ICIS_NoInit) {3197      // The initializer was deferred; parse it and cache the tokens.3198      Diag(Tok, getLangOpts().CPlusPlus113199                    ? diag::warn_cxx98_compat_nonstatic_member_init3200                    : diag::ext_nonstatic_member_init);3201 3202      if (DeclaratorInfo.isArrayOfUnknownBound()) {3203        // C++11 [dcl.array]p3: An array bound may also be omitted when the3204        // declarator is followed by an initializer.3205        //3206        // A brace-or-equal-initializer for a member-declarator is not an3207        // initializer in the grammar, so this is ill-formed.3208        Diag(Tok, diag::err_incomplete_array_member_init);3209        SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);3210 3211        // Avoid later warnings about a class member of incomplete type.3212        if (ThisDecl)3213          ThisDecl->setInvalidDecl();3214      } else3215        ParseCXXNonStaticMemberInitializer(ThisDecl);3216    } else if (HasStaticInitializer) {3217      // Normal initializer.3218      ExprResult Init = ParseCXXMemberInitializer(3219          ThisDecl, DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);3220 3221      if (Init.isInvalid()) {3222        if (ThisDecl)3223          Actions.ActOnUninitializedDecl(ThisDecl);3224        SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);3225      } else if (ThisDecl)3226        Actions.AddInitializerToDecl(ThisDecl, Init.get(),3227                                     EqualLoc.isInvalid());3228    } else if (ThisDecl && DeclaratorInfo.isStaticMember())3229      // No initializer.3230      Actions.ActOnUninitializedDecl(ThisDecl);3231 3232    if (ThisDecl) {3233      if (!ThisDecl->isInvalidDecl()) {3234        // Set the Decl for any late parsed attributes3235        for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i)3236          CommonLateParsedAttrs[i]->addDecl(ThisDecl);3237 3238        for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i)3239          LateParsedAttrs[i]->addDecl(ThisDecl);3240      }3241      Actions.FinalizeDeclaration(ThisDecl);3242      DeclsInGroup.push_back(ThisDecl);3243 3244      if (DeclaratorInfo.isFunctionDeclarator() &&3245          DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=3246              DeclSpec::SCS_typedef)3247        HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);3248    }3249    LateParsedAttrs.clear();3250 3251    DeclaratorInfo.complete(ThisDecl);3252 3253    // If we don't have a comma, it is either the end of the list (a ';')3254    // or an error, bail out.3255    SourceLocation CommaLoc;3256    if (!TryConsumeToken(tok::comma, CommaLoc))3257      break;3258 3259    if (Tok.isAtStartOfLine() &&3260        !MightBeDeclarator(DeclaratorContext::Member)) {3261      // This comma was followed by a line-break and something which can't be3262      // the start of a declarator. The comma was probably a typo for a3263      // semicolon.3264      Diag(CommaLoc, diag::err_expected_semi_declaration)3265          << FixItHint::CreateReplacement(CommaLoc, ";");3266      ExpectSemi = false;3267      break;3268    }3269 3270    // C++23 [temp.pre]p5:3271    //   In a template-declaration, explicit specialization, or explicit3272    //   instantiation the init-declarator-list in the declaration shall3273    //   contain at most one declarator.3274    if (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate &&3275        DeclaratorInfo.isFirstDeclarator()) {3276      Diag(CommaLoc, diag::err_multiple_template_declarators)3277          << TemplateInfo.Kind;3278    }3279 3280    // Parse the next declarator.3281    DeclaratorInfo.clear();3282    VS.clear();3283    BitfieldSize = ExprResult(/*Invalid=*/false);3284    EqualLoc = PureSpecLoc = SourceLocation();3285    DeclaratorInfo.setCommaLoc(CommaLoc);3286 3287    // GNU attributes are allowed before the second and subsequent declarator.3288    // However, this does not apply for [[]] attributes (which could show up3289    // before or after the __attribute__ attributes).3290    DiagnoseAndSkipCXX11Attributes();3291    MaybeParseGNUAttributes(DeclaratorInfo);3292    DiagnoseAndSkipCXX11Attributes();3293 3294    if (ParseCXXMemberDeclaratorBeforeInitializer(3295            DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs))3296      break;3297  }3298 3299  if (ExpectSemi &&3300      ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {3301    // Skip to end of block or statement.3302    SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);3303    // If we stopped at a ';', eat it.3304    TryConsumeToken(tok::semi);3305    return nullptr;3306  }3307 3308  return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);3309}3310 3311ExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction,3312                                             SourceLocation &EqualLoc) {3313  assert(Tok.isOneOf(tok::equal, tok::l_brace) &&3314         "Data member initializer not starting with '=' or '{'");3315 3316  bool IsFieldInitialization = isa_and_present<FieldDecl>(D);3317 3318  EnterExpressionEvaluationContext Context(3319      Actions,3320      IsFieldInitialization3321          ? Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed3322          : Sema::ExpressionEvaluationContext::PotentiallyEvaluated,3323      D);3324 3325  // CWG27603326  // Default member initializers used to initialize a base or member subobject3327  // [...] are considered to be part of the function body3328  Actions.ExprEvalContexts.back().InImmediateEscalatingFunctionContext =3329      IsFieldInitialization;3330 3331  if (TryConsumeToken(tok::equal, EqualLoc)) {3332    if (Tok.is(tok::kw_delete)) {3333      // In principle, an initializer of '= delete p;' is legal, but it will3334      // never type-check. It's better to diagnose it as an ill-formed3335      // expression than as an ill-formed deleted non-function member. An3336      // initializer of '= delete p, foo' will never be parsed, because a3337      // top-level comma always ends the initializer expression.3338      const Token &Next = NextToken();3339      if (IsFunction || Next.isOneOf(tok::semi, tok::comma, tok::eof)) {3340        if (IsFunction)3341          Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)3342              << 1 /* delete */;3343        else3344          Diag(ConsumeToken(), diag::err_deleted_non_function);3345        SkipDeletedFunctionBody();3346        return ExprError();3347      }3348    } else if (Tok.is(tok::kw_default)) {3349      if (IsFunction)3350        Diag(Tok, diag::err_default_delete_in_multiple_declaration)3351            << 0 /* default */;3352      else3353        Diag(ConsumeToken(), diag::err_default_special_members)3354            << getLangOpts().CPlusPlus20;3355      return ExprError();3356    }3357  }3358  if (const auto *PD = dyn_cast_or_null<MSPropertyDecl>(D)) {3359    Diag(Tok, diag::err_ms_property_initializer) << PD;3360    return ExprError();3361  }3362  return ParseInitializer(D);3363}3364 3365void Parser::SkipCXXMemberSpecification(SourceLocation RecordLoc,3366                                        SourceLocation AttrFixitLoc,3367                                        unsigned TagType, Decl *TagDecl) {3368  // Skip the optional 'final' keyword.3369  while (isClassCompatibleKeyword())3370    ConsumeToken();3371 3372  // Diagnose any C++11 attributes after 'final' keyword.3373  // We deliberately discard these attributes.3374  ParsedAttributes Attrs(AttrFactory);3375  CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);3376 3377  // This can only happen if we had malformed misplaced attributes;3378  // we only get called if there is a colon or left-brace after the3379  // attributes.3380  if (Tok.isNot(tok::colon) && Tok.isNot(tok::l_brace))3381    return;3382 3383  // Skip the base clauses. This requires actually parsing them, because3384  // otherwise we can't be sure where they end (a left brace may appear3385  // within a template argument).3386  if (Tok.is(tok::colon)) {3387    // Enter the scope of the class so that we can correctly parse its bases.3388    ParseScope ClassScope(this, Scope::ClassScope | Scope::DeclScope);3389    ParsingClassDefinition ParsingDef(*this, TagDecl, /*NonNestedClass*/ true,3390                                      TagType == DeclSpec::TST_interface);3391    auto OldContext =3392        Actions.ActOnTagStartSkippedDefinition(getCurScope(), TagDecl);3393 3394    // Parse the bases but don't attach them to the class.3395    ParseBaseClause(nullptr);3396 3397    Actions.ActOnTagFinishSkippedDefinition(OldContext);3398 3399    if (!Tok.is(tok::l_brace)) {3400      Diag(PP.getLocForEndOfToken(PrevTokLocation),3401           diag::err_expected_lbrace_after_base_specifiers);3402      return;3403    }3404  }3405 3406  // Skip the body.3407  assert(Tok.is(tok::l_brace));3408  BalancedDelimiterTracker T(*this, tok::l_brace);3409  T.consumeOpen();3410  T.skipToEnd();3411 3412  // Parse and discard any trailing attributes.3413  if (Tok.is(tok::kw___attribute)) {3414    ParsedAttributes Attrs(AttrFactory);3415    MaybeParseGNUAttributes(Attrs);3416  }3417}3418 3419Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(3420    AccessSpecifier &AS, ParsedAttributes &AccessAttrs, DeclSpec::TST TagType,3421    Decl *TagDecl) {3422  ParenBraceBracketBalancer BalancerRAIIObj(*this);3423 3424  switch (Tok.getKind()) {3425  case tok::kw___if_exists:3426  case tok::kw___if_not_exists:3427    ParseMicrosoftIfExistsClassDeclaration(TagType, AccessAttrs, AS);3428    return nullptr;3429 3430  case tok::semi:3431    // Check for extraneous top-level semicolon.3432    ConsumeExtraSemi(ExtraSemiKind::InsideStruct, TagType);3433    return nullptr;3434 3435    // Handle pragmas that can appear as member declarations.3436  case tok::annot_pragma_vis:3437    HandlePragmaVisibility();3438    return nullptr;3439  case tok::annot_pragma_pack:3440    HandlePragmaPack();3441    return nullptr;3442  case tok::annot_pragma_align:3443    HandlePragmaAlign();3444    return nullptr;3445  case tok::annot_pragma_ms_pointers_to_members:3446    HandlePragmaMSPointersToMembers();3447    return nullptr;3448  case tok::annot_pragma_ms_pragma:3449    HandlePragmaMSPragma();3450    return nullptr;3451  case tok::annot_pragma_ms_vtordisp:3452    HandlePragmaMSVtorDisp();3453    return nullptr;3454  case tok::annot_pragma_dump:3455    HandlePragmaDump();3456    return nullptr;3457 3458  case tok::kw_namespace:3459    // If we see a namespace here, a close brace was missing somewhere.3460    DiagnoseUnexpectedNamespace(cast<NamedDecl>(TagDecl));3461    return nullptr;3462 3463  case tok::kw_private:3464    // FIXME: We don't accept GNU attributes on access specifiers in OpenCL mode3465    // yet.3466    if (getLangOpts().OpenCL && !NextToken().is(tok::colon)) {3467      ParsedTemplateInfo TemplateInfo;3468      return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo);3469    }3470    [[fallthrough]];3471  case tok::kw_public:3472  case tok::kw_protected: {3473    if (getLangOpts().HLSL)3474      Diag(Tok.getLocation(), diag::ext_hlsl_access_specifiers);3475    AccessSpecifier NewAS = getAccessSpecifierIfPresent();3476    assert(NewAS != AS_none);3477    // Current token is a C++ access specifier.3478    AS = NewAS;3479    SourceLocation ASLoc = Tok.getLocation();3480    unsigned TokLength = Tok.getLength();3481    ConsumeToken();3482    AccessAttrs.clear();3483    MaybeParseGNUAttributes(AccessAttrs);3484 3485    SourceLocation EndLoc;3486    if (TryConsumeToken(tok::colon, EndLoc)) {3487    } else if (TryConsumeToken(tok::semi, EndLoc)) {3488      Diag(EndLoc, diag::err_expected)3489          << tok::colon << FixItHint::CreateReplacement(EndLoc, ":");3490    } else {3491      EndLoc = ASLoc.getLocWithOffset(TokLength);3492      Diag(EndLoc, diag::err_expected)3493          << tok::colon << FixItHint::CreateInsertion(EndLoc, ":");3494    }3495 3496    // The Microsoft extension __interface does not permit non-public3497    // access specifiers.3498    if (TagType == DeclSpec::TST_interface && AS != AS_public) {3499      Diag(ASLoc, diag::err_access_specifier_interface) << (AS == AS_protected);3500    }3501 3502    if (Actions.ActOnAccessSpecifier(NewAS, ASLoc, EndLoc, AccessAttrs)) {3503      // found another attribute than only annotations3504      AccessAttrs.clear();3505    }3506 3507    return nullptr;3508  }3509 3510  case tok::annot_attr_openmp:3511  case tok::annot_pragma_openmp:3512    return ParseOpenMPDeclarativeDirectiveWithExtDecl(3513        AS, AccessAttrs, /*Delayed=*/true, TagType, TagDecl);3514  case tok::annot_pragma_openacc:3515    return ParseOpenACCDirectiveDecl(AS, AccessAttrs, TagType, TagDecl);3516 3517  default:3518    if (tok::isPragmaAnnotation(Tok.getKind())) {3519      Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)3520          << DeclSpec::getSpecifierName(3521                 TagType, Actions.getASTContext().getPrintingPolicy());3522      ConsumeAnnotationToken();3523      return nullptr;3524    }3525    ParsedTemplateInfo TemplateInfo;3526    return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo);3527  }3528}3529 3530void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,3531                                         SourceLocation AttrFixitLoc,3532                                         ParsedAttributes &Attrs,3533                                         unsigned TagType, Decl *TagDecl) {3534  assert((TagType == DeclSpec::TST_struct ||3535          TagType == DeclSpec::TST_interface ||3536          TagType == DeclSpec::TST_union || TagType == DeclSpec::TST_class) &&3537         "Invalid TagType!");3538 3539  llvm::TimeTraceScope TimeScope("ParseClass", [&]() {3540    if (auto *TD = dyn_cast_or_null<NamedDecl>(TagDecl))3541      return TD->getQualifiedNameAsString();3542    return std::string("<anonymous>");3543  });3544 3545  PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc,3546                                      "parsing struct/union/class body");3547 3548  // Determine whether this is a non-nested class. Note that local3549  // classes are *not* considered to be nested classes.3550  bool NonNestedClass = true;3551  if (!ClassStack.empty()) {3552    for (const Scope *S = getCurScope(); S; S = S->getParent()) {3553      if (S->isClassScope()) {3554        // We're inside a class scope, so this is a nested class.3555        NonNestedClass = false;3556 3557        // The Microsoft extension __interface does not permit nested classes.3558        if (getCurrentClass().IsInterface) {3559          Diag(RecordLoc, diag::err_invalid_member_in_interface)3560              << /*ErrorType=*/63561              << (isa<NamedDecl>(TagDecl)3562                      ? cast<NamedDecl>(TagDecl)->getQualifiedNameAsString()3563                      : "(anonymous)");3564        }3565        break;3566      }3567 3568      if (S->isFunctionScope())3569        // If we're in a function or function template then this is a local3570        // class rather than a nested class.3571        break;3572    }3573  }3574 3575  // Enter a scope for the class.3576  ParseScope ClassScope(this, Scope::ClassScope | Scope::DeclScope);3577 3578  // Note that we are parsing a new (potentially-nested) class definition.3579  ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass,3580                                    TagType == DeclSpec::TST_interface);3581 3582  if (TagDecl)3583    Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);3584 3585  SourceLocation FinalLoc;3586  SourceLocation AbstractLoc;3587  bool IsFinalSpelledSealed = false;3588  bool IsAbstract = false;3589  SourceLocation TriviallyRelocatable;3590  SourceLocation Replaceable;3591 3592  // Parse the optional 'final' keyword.3593  if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) {3594    while (true) {3595      VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier(Tok);3596      if (Specifier == VirtSpecifiers::VS_None) {3597        if (isCXX2CTriviallyRelocatableKeyword(Tok)) {3598          if (TriviallyRelocatable.isValid()) {3599            auto Skipped = Tok;3600            ConsumeToken();3601            Diag(Skipped, diag::err_duplicate_class_relocation_specifier)3602                << /*trivial_relocatable*/ 0 << TriviallyRelocatable;3603          } else {3604            ParseCXX2CTriviallyRelocatableSpecifier(TriviallyRelocatable);3605          }3606          continue;3607        }3608        if (isCXX2CReplaceableKeyword(Tok)) {3609          if (Replaceable.isValid()) {3610            auto Skipped = Tok;3611            ConsumeToken();3612            Diag(Skipped, diag::err_duplicate_class_relocation_specifier)3613                << /*replaceable*/ 1 << Replaceable;3614          } else {3615            ParseCXX2CReplaceableSpecifier(Replaceable);3616          }3617          continue;3618        }3619        break;3620      }3621      if (isCXX11FinalKeyword()) {3622        if (FinalLoc.isValid()) {3623          auto Skipped = ConsumeToken();3624          Diag(Skipped, diag::err_duplicate_class_virt_specifier)3625              << VirtSpecifiers::getSpecifierName(Specifier);3626        } else {3627          FinalLoc = ConsumeToken();3628          if (Specifier == VirtSpecifiers::VS_Sealed)3629            IsFinalSpelledSealed = true;3630        }3631      } else {3632        if (AbstractLoc.isValid()) {3633          auto Skipped = ConsumeToken();3634          Diag(Skipped, diag::err_duplicate_class_virt_specifier)3635              << VirtSpecifiers::getSpecifierName(Specifier);3636        } else {3637          AbstractLoc = ConsumeToken();3638          IsAbstract = true;3639        }3640      }3641      if (TagType == DeclSpec::TST_interface)3642        Diag(FinalLoc, diag::err_override_control_interface)3643            << VirtSpecifiers::getSpecifierName(Specifier);3644      else if (Specifier == VirtSpecifiers::VS_Final)3645        Diag(FinalLoc, getLangOpts().CPlusPlus113646                           ? diag::warn_cxx98_compat_override_control_keyword3647                           : diag::ext_override_control_keyword)3648            << VirtSpecifiers::getSpecifierName(Specifier);3649      else if (Specifier == VirtSpecifiers::VS_Sealed)3650        Diag(FinalLoc, diag::ext_ms_sealed_keyword);3651      else if (Specifier == VirtSpecifiers::VS_Abstract)3652        Diag(AbstractLoc, diag::ext_ms_abstract_keyword);3653      else if (Specifier == VirtSpecifiers::VS_GNU_Final)3654        Diag(FinalLoc, diag::ext_warn_gnu_final);3655    }3656    assert((FinalLoc.isValid() || AbstractLoc.isValid() ||3657            TriviallyRelocatable.isValid() || Replaceable.isValid()) &&3658           "not a class definition");3659 3660    // Parse any C++11 attributes after 'final' keyword.3661    // These attributes are not allowed to appear here,3662    // and the only possible place for them to appertain3663    // to the class would be between class-key and class-name.3664    CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);3665 3666    // ParseClassSpecifier() does only a superficial check for attributes before3667    // deciding to call this method.  For example, for3668    // `class C final alignas ([l) {` it will decide that this looks like a3669    // misplaced attribute since it sees `alignas '(' ')'`.  But the actual3670    // attribute parsing code will try to parse the '[' as a constexpr lambda3671    // and consume enough tokens that the alignas parsing code will eat the3672    // opening '{'.  So bail out if the next token isn't one we expect.3673    if (!Tok.is(tok::colon) && !Tok.is(tok::l_brace)) {3674      if (TagDecl)3675        Actions.ActOnTagDefinitionError(getCurScope(), TagDecl);3676      return;3677    }3678  }3679 3680  if (Tok.is(tok::colon)) {3681    ParseScope InheritanceScope(this, getCurScope()->getFlags() |3682                                          Scope::ClassInheritanceScope);3683 3684    ParseBaseClause(TagDecl);3685    if (!Tok.is(tok::l_brace)) {3686      bool SuggestFixIt = false;3687      SourceLocation BraceLoc = PP.getLocForEndOfToken(PrevTokLocation);3688      if (Tok.isAtStartOfLine()) {3689        switch (Tok.getKind()) {3690        case tok::kw_private:3691        case tok::kw_protected:3692        case tok::kw_public:3693          SuggestFixIt = NextToken().getKind() == tok::colon;3694          break;3695        case tok::kw_static_assert:3696        case tok::r_brace:3697        case tok::kw_using:3698        // base-clause can have simple-template-id; 'template' can't be there3699        case tok::kw_template:3700          SuggestFixIt = true;3701          break;3702        case tok::identifier:3703          SuggestFixIt = isConstructorDeclarator(true);3704          break;3705        default:3706          SuggestFixIt = isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false);3707          break;3708        }3709      }3710      DiagnosticBuilder LBraceDiag =3711          Diag(BraceLoc, diag::err_expected_lbrace_after_base_specifiers);3712      if (SuggestFixIt) {3713        LBraceDiag << FixItHint::CreateInsertion(BraceLoc, " {");3714        // Try recovering from missing { after base-clause.3715        PP.EnterToken(Tok, /*IsReinject*/ true);3716        Tok.setKind(tok::l_brace);3717      } else {3718        if (TagDecl)3719          Actions.ActOnTagDefinitionError(getCurScope(), TagDecl);3720        return;3721      }3722    }3723  }3724 3725  assert(Tok.is(tok::l_brace));3726  BalancedDelimiterTracker T(*this, tok::l_brace);3727  T.consumeOpen();3728 3729  if (TagDecl)3730    Actions.ActOnStartCXXMemberDeclarations(3731        getCurScope(), TagDecl, FinalLoc, IsFinalSpelledSealed, IsAbstract,3732        TriviallyRelocatable, Replaceable, T.getOpenLocation());3733 3734  // C++ 11p3: Members of a class defined with the keyword class are private3735  // by default. Members of a class defined with the keywords struct or union3736  // are public by default.3737  // HLSL: In HLSL members of a class are public by default.3738  AccessSpecifier CurAS;3739  if (TagType == DeclSpec::TST_class && !getLangOpts().HLSL)3740    CurAS = AS_private;3741  else3742    CurAS = AS_public;3743  ParsedAttributes AccessAttrs(AttrFactory);3744 3745  if (TagDecl) {3746    // While we still have something to read, read the member-declarations.3747    while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&3748           Tok.isNot(tok::eof)) {3749      // Each iteration of this loop reads one member-declaration.3750      ParseCXXClassMemberDeclarationWithPragmas(3751          CurAS, AccessAttrs, static_cast<DeclSpec::TST>(TagType), TagDecl);3752      MaybeDestroyTemplateIds();3753    }3754    T.consumeClose();3755  } else {3756    SkipUntil(tok::r_brace);3757  }3758 3759  // If attributes exist after class contents, parse them.3760  ParsedAttributes attrs(AttrFactory);3761  MaybeParseGNUAttributes(attrs);3762 3763  if (TagDecl)3764    Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,3765                                              T.getOpenLocation(),3766                                              T.getCloseLocation(), attrs);3767 3768  // C++11 [class.mem]p2:3769  //   Within the class member-specification, the class is regarded as complete3770  //   within function bodies, default arguments, exception-specifications, and3771  //   brace-or-equal-initializers for non-static data members (including such3772  //   things in nested classes).3773  if (TagDecl && NonNestedClass) {3774    // We are not inside a nested class. This class and its nested classes3775    // are complete and we can parse the delayed portions of method3776    // declarations and the lexed inline method definitions, along with any3777    // delayed attributes.3778 3779    SourceLocation SavedPrevTokLocation = PrevTokLocation;3780    ParseLexedPragmas(getCurrentClass());3781    ParseLexedAttributes(getCurrentClass());3782    ParseLexedMethodDeclarations(getCurrentClass());3783 3784    // We've finished with all pending member declarations.3785    Actions.ActOnFinishCXXMemberDecls();3786 3787    ParseLexedMemberInitializers(getCurrentClass());3788    ParseLexedMethodDefs(getCurrentClass());3789    PrevTokLocation = SavedPrevTokLocation;3790 3791    // We've finished parsing everything, including default argument3792    // initializers.3793    Actions.ActOnFinishCXXNonNestedClass();3794  }3795 3796  if (TagDecl)3797    Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, T.getRange());3798 3799  // Leave the class scope.3800  ParsingDef.Pop();3801  ClassScope.Exit();3802}3803 3804void Parser::DiagnoseUnexpectedNamespace(NamedDecl *D) {3805  assert(Tok.is(tok::kw_namespace));3806 3807  // FIXME: Suggest where the close brace should have gone by looking3808  // at indentation changes within the definition body.3809  Diag(D->getLocation(), diag::err_missing_end_of_definition) << D;3810  Diag(Tok.getLocation(), diag::note_missing_end_of_definition_before) << D;3811 3812  // Push '};' onto the token stream to recover.3813  PP.EnterToken(Tok, /*IsReinject*/ true);3814 3815  Tok.startToken();3816  Tok.setLocation(PP.getLocForEndOfToken(PrevTokLocation));3817  Tok.setKind(tok::semi);3818  PP.EnterToken(Tok, /*IsReinject*/ true);3819 3820  Tok.setKind(tok::r_brace);3821}3822 3823void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {3824  assert(Tok.is(tok::colon) &&3825         "Constructor initializer always starts with ':'");3826 3827  // Poison the SEH identifiers so they are flagged as illegal in constructor3828  // initializers.3829  PoisonSEHIdentifiersRAIIObject PoisonSEHIdentifiers(*this, true);3830  SourceLocation ColonLoc = ConsumeToken();3831 3832  SmallVector<CXXCtorInitializer *, 4> MemInitializers;3833  bool AnyErrors = false;3834 3835  do {3836    if (Tok.is(tok::code_completion)) {3837      cutOffParsing();3838      Actions.CodeCompletion().CodeCompleteConstructorInitializer(3839          ConstructorDecl, MemInitializers);3840      return;3841    }3842 3843    MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);3844    if (!MemInit.isInvalid())3845      MemInitializers.push_back(MemInit.get());3846    else3847      AnyErrors = true;3848 3849    if (Tok.is(tok::comma))3850      ConsumeToken();3851    else if (Tok.is(tok::l_brace))3852      break;3853    // If the previous initializer was valid and the next token looks like a3854    // base or member initializer, assume that we're just missing a comma.3855    else if (!MemInit.isInvalid() &&3856             Tok.isOneOf(tok::identifier, tok::coloncolon)) {3857      SourceLocation Loc = PP.getLocForEndOfToken(PrevTokLocation);3858      Diag(Loc, diag::err_ctor_init_missing_comma)3859          << FixItHint::CreateInsertion(Loc, ", ");3860    } else {3861      // Skip over garbage, until we get to '{'.  Don't eat the '{'.3862      if (!MemInit.isInvalid())3863        Diag(Tok.getLocation(), diag::err_expected_either)3864            << tok::l_brace << tok::comma;3865      SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);3866      break;3867    }3868  } while (true);3869 3870  Actions.ActOnMemInitializers(ConstructorDecl, ColonLoc, MemInitializers,3871                               AnyErrors);3872}3873 3874MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {3875  // parse '::'[opt] nested-name-specifier[opt]3876  CXXScopeSpec SS;3877  if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,3878                                     /*ObjectHasErrors=*/false,3879                                     /*EnteringContext=*/false))3880    return true;3881 3882  // : identifier3883  IdentifierInfo *II = nullptr;3884  SourceLocation IdLoc = Tok.getLocation();3885  // : declype(...)3886  DeclSpec DS(AttrFactory);3887  // : template_name<...>3888  TypeResult TemplateTypeTy;3889 3890  if (Tok.is(tok::identifier)) {3891    // Get the identifier. This may be a member name or a class name,3892    // but we'll let the semantic analysis determine which it is.3893    II = Tok.getIdentifierInfo();3894    ConsumeToken();3895  } else if (Tok.is(tok::annot_decltype)) {3896    // Get the decltype expression, if there is one.3897    // Uses of decltype will already have been converted to annot_decltype by3898    // ParseOptionalCXXScopeSpecifier at this point.3899    // FIXME: Can we get here with a scope specifier?3900    ParseDecltypeSpecifier(DS);3901  } else if (Tok.is(tok::annot_pack_indexing_type)) {3902    // Uses of T...[N] will already have been converted to3903    // annot_pack_indexing_type by ParseOptionalCXXScopeSpecifier at this point.3904    ParsePackIndexingType(DS);3905  } else {3906    TemplateIdAnnotation *TemplateId = Tok.is(tok::annot_template_id)3907                                           ? takeTemplateIdAnnotation(Tok)3908                                           : nullptr;3909    if (TemplateId && TemplateId->mightBeType()) {3910      AnnotateTemplateIdTokenAsType(SS, ImplicitTypenameContext::No,3911                                    /*IsClassName=*/true);3912      assert(Tok.is(tok::annot_typename) && "template-id -> type failed");3913      TemplateTypeTy = getTypeAnnotation(Tok);3914      ConsumeAnnotationToken();3915    } else {3916      Diag(Tok, diag::err_expected_member_or_base_name);3917      return true;3918    }3919  }3920 3921  // Parse the '('.3922  if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {3923    Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);3924 3925    // FIXME: Add support for signature help inside initializer lists.3926    ExprResult InitList = ParseBraceInitializer();3927    if (InitList.isInvalid())3928      return true;3929 3930    SourceLocation EllipsisLoc;3931    TryConsumeToken(tok::ellipsis, EllipsisLoc);3932 3933    if (TemplateTypeTy.isInvalid())3934      return true;3935    return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,3936                                       TemplateTypeTy.get(), DS, IdLoc,3937                                       InitList.get(), EllipsisLoc);3938  } else if (Tok.is(tok::l_paren)) {3939    BalancedDelimiterTracker T(*this, tok::l_paren);3940    T.consumeOpen();3941 3942    // Parse the optional expression-list.3943    ExprVector ArgExprs;3944    auto RunSignatureHelp = [&] {3945      if (TemplateTypeTy.isInvalid())3946        return QualType();3947      QualType PreferredType =3948          Actions.CodeCompletion().ProduceCtorInitMemberSignatureHelp(3949              ConstructorDecl, SS, TemplateTypeTy.get(), ArgExprs, II,3950              T.getOpenLocation(), /*Braced=*/false);3951      CalledSignatureHelp = true;3952      return PreferredType;3953    };3954    if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, [&] {3955          PreferredType.enterFunctionArgument(Tok.getLocation(),3956                                              RunSignatureHelp);3957        })) {3958      if (PP.isCodeCompletionReached() && !CalledSignatureHelp)3959        RunSignatureHelp();3960      SkipUntil(tok::r_paren, StopAtSemi);3961      return true;3962    }3963 3964    T.consumeClose();3965 3966    SourceLocation EllipsisLoc;3967    TryConsumeToken(tok::ellipsis, EllipsisLoc);3968 3969    if (TemplateTypeTy.isInvalid())3970      return true;3971    return Actions.ActOnMemInitializer(3972        ConstructorDecl, getCurScope(), SS, II, TemplateTypeTy.get(), DS, IdLoc,3973        T.getOpenLocation(), ArgExprs, T.getCloseLocation(), EllipsisLoc);3974  }3975 3976  if (TemplateTypeTy.isInvalid())3977    return true;3978 3979  if (getLangOpts().CPlusPlus11)3980    return Diag(Tok, diag::err_expected_either) << tok::l_paren << tok::l_brace;3981  else3982    return Diag(Tok, diag::err_expected) << tok::l_paren;3983}3984 3985ExceptionSpecificationType Parser::tryParseExceptionSpecification(3986    bool Delayed, SourceRange &SpecificationRange,3987    SmallVectorImpl<ParsedType> &DynamicExceptions,3988    SmallVectorImpl<SourceRange> &DynamicExceptionRanges,3989    ExprResult &NoexceptExpr, CachedTokens *&ExceptionSpecTokens) {3990  ExceptionSpecificationType Result = EST_None;3991  ExceptionSpecTokens = nullptr;3992 3993  // Handle delayed parsing of exception-specifications.3994  if (Delayed) {3995    if (Tok.isNot(tok::kw_throw) && Tok.isNot(tok::kw_noexcept))3996      return EST_None;3997 3998    // Consume and cache the starting token.3999    bool IsNoexcept = Tok.is(tok::kw_noexcept);4000    Token StartTok = Tok;4001    SpecificationRange = SourceRange(ConsumeToken());4002 4003    // Check for a '('.4004    if (!Tok.is(tok::l_paren)) {4005      // If this is a bare 'noexcept', we're done.4006      if (IsNoexcept) {4007        Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);4008        NoexceptExpr = nullptr;4009        return EST_BasicNoexcept;4010      }4011 4012      Diag(Tok, diag::err_expected_lparen_after) << "throw";4013      return EST_DynamicNone;4014    }4015 4016    // Cache the tokens for the exception-specification.4017    ExceptionSpecTokens = new CachedTokens;4018    ExceptionSpecTokens->push_back(StartTok);  // 'throw' or 'noexcept'4019    ExceptionSpecTokens->push_back(Tok);       // '('4020    SpecificationRange.setEnd(ConsumeParen()); // '('4021 4022    ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens,4023                         /*StopAtSemi=*/true,4024                         /*ConsumeFinalToken=*/true);4025    SpecificationRange.setEnd(ExceptionSpecTokens->back().getLocation());4026 4027    return EST_Unparsed;4028  }4029 4030  // See if there's a dynamic specification.4031  if (Tok.is(tok::kw_throw)) {4032    Result = ParseDynamicExceptionSpecification(4033        SpecificationRange, DynamicExceptions, DynamicExceptionRanges);4034    assert(DynamicExceptions.size() == DynamicExceptionRanges.size() &&4035           "Produced different number of exception types and ranges.");4036  }4037 4038  // If there's no noexcept specification, we're done.4039  if (Tok.isNot(tok::kw_noexcept))4040    return Result;4041 4042  Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);4043 4044  // If we already had a dynamic specification, parse the noexcept for,4045  // recovery, but emit a diagnostic and don't store the results.4046  SourceRange NoexceptRange;4047  ExceptionSpecificationType NoexceptType = EST_None;4048 4049  SourceLocation KeywordLoc = ConsumeToken();4050  if (Tok.is(tok::l_paren)) {4051    // There is an argument.4052    BalancedDelimiterTracker T(*this, tok::l_paren);4053    T.consumeOpen();4054 4055    EnterExpressionEvaluationContext ConstantEvaluated(4056        Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);4057    NoexceptExpr = ParseConstantExpressionInExprEvalContext();4058 4059    T.consumeClose();4060    if (!NoexceptExpr.isInvalid()) {4061      NoexceptExpr =4062          Actions.ActOnNoexceptSpec(NoexceptExpr.get(), NoexceptType);4063      NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation());4064    } else {4065      NoexceptType = EST_BasicNoexcept;4066    }4067  } else {4068    // There is no argument.4069    NoexceptType = EST_BasicNoexcept;4070    NoexceptRange = SourceRange(KeywordLoc, KeywordLoc);4071  }4072 4073  if (Result == EST_None) {4074    SpecificationRange = NoexceptRange;4075    Result = NoexceptType;4076 4077    // If there's a dynamic specification after a noexcept specification,4078    // parse that and ignore the results.4079    if (Tok.is(tok::kw_throw)) {4080      Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);4081      ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions,4082                                         DynamicExceptionRanges);4083    }4084  } else {4085    Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);4086  }4087 4088  return Result;4089}4090 4091static void diagnoseDynamicExceptionSpecification(Parser &P, SourceRange Range,4092                                                  bool IsNoexcept) {4093  if (P.getLangOpts().CPlusPlus11) {4094    const char *Replacement = IsNoexcept ? "noexcept" : "noexcept(false)";4095    P.Diag(Range.getBegin(), P.getLangOpts().CPlusPlus17 && !IsNoexcept4096                                 ? diag::ext_dynamic_exception_spec4097                                 : diag::warn_exception_spec_deprecated)4098        << Range;4099    P.Diag(Range.getBegin(), diag::note_exception_spec_deprecated)4100        << Replacement << FixItHint::CreateReplacement(Range, Replacement);4101  }4102}4103 4104ExceptionSpecificationType Parser::ParseDynamicExceptionSpecification(4105    SourceRange &SpecificationRange, SmallVectorImpl<ParsedType> &Exceptions,4106    SmallVectorImpl<SourceRange> &Ranges) {4107  assert(Tok.is(tok::kw_throw) && "expected throw");4108 4109  SpecificationRange.setBegin(ConsumeToken());4110  BalancedDelimiterTracker T(*this, tok::l_paren);4111  if (T.consumeOpen()) {4112    Diag(Tok, diag::err_expected_lparen_after) << "throw";4113    SpecificationRange.setEnd(SpecificationRange.getBegin());4114    return EST_DynamicNone;4115  }4116 4117  // Parse throw(...), a Microsoft extension that means "this function4118  // can throw anything".4119  if (Tok.is(tok::ellipsis)) {4120    SourceLocation EllipsisLoc = ConsumeToken();4121    if (!getLangOpts().MicrosoftExt)4122      Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);4123    T.consumeClose();4124    SpecificationRange.setEnd(T.getCloseLocation());4125    diagnoseDynamicExceptionSpecification(*this, SpecificationRange, false);4126    return EST_MSAny;4127  }4128 4129  // Parse the sequence of type-ids.4130  SourceRange Range;4131  while (Tok.isNot(tok::r_paren)) {4132    TypeResult Res(ParseTypeName(&Range));4133 4134    if (Tok.is(tok::ellipsis)) {4135      // C++0x [temp.variadic]p5:4136      //   - In a dynamic-exception-specification (15.4); the pattern is a4137      //     type-id.4138      SourceLocation Ellipsis = ConsumeToken();4139      Range.setEnd(Ellipsis);4140      if (!Res.isInvalid())4141        Res = Actions.ActOnPackExpansion(Res.get(), Ellipsis);4142    }4143 4144    if (!Res.isInvalid()) {4145      Exceptions.push_back(Res.get());4146      Ranges.push_back(Range);4147    }4148 4149    if (!TryConsumeToken(tok::comma))4150      break;4151  }4152 4153  T.consumeClose();4154  SpecificationRange.setEnd(T.getCloseLocation());4155  diagnoseDynamicExceptionSpecification(*this, SpecificationRange,4156                                        Exceptions.empty());4157  return Exceptions.empty() ? EST_DynamicNone : EST_Dynamic;4158}4159 4160TypeResult Parser::ParseTrailingReturnType(SourceRange &Range,4161                                           bool MayBeFollowedByDirectInit) {4162  assert(Tok.is(tok::arrow) && "expected arrow");4163 4164  ConsumeToken();4165 4166  return ParseTypeName(&Range, MayBeFollowedByDirectInit4167                                   ? DeclaratorContext::TrailingReturnVar4168                                   : DeclaratorContext::TrailingReturn);4169}4170 4171void Parser::ParseTrailingRequiresClause(Declarator &D) {4172  assert(Tok.is(tok::kw_requires) && "expected requires");4173 4174  SourceLocation RequiresKWLoc = ConsumeToken();4175 4176  // C++23 [basic.scope.namespace]p1:4177  //   For each non-friend redeclaration or specialization whose target scope4178  //   is or is contained by the scope, the portion after the declarator-id,4179  //   class-head-name, or enum-head-name is also included in the scope.4180  // C++23 [basic.scope.class]p1:4181  //   For each non-friend redeclaration or specialization whose target scope4182  //   is or is contained by the scope, the portion after the declarator-id,4183  //   class-head-name, or enum-head-name is also included in the scope.4184  //4185  // FIXME: We should really be calling ParseTrailingRequiresClause in4186  // ParseDirectDeclarator, when we are already in the declarator scope.4187  // This would also correctly suppress access checks for specializations4188  // and explicit instantiations, which we currently do not do.4189  CXXScopeSpec &SS = D.getCXXScopeSpec();4190  DeclaratorScopeObj DeclScopeObj(*this, SS);4191  if (SS.isValid() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))4192    DeclScopeObj.EnterDeclaratorScope();4193 4194  ExprResult TrailingRequiresClause;4195  ParseScope ParamScope(this, Scope::DeclScope |4196                                  Scope::FunctionDeclarationScope |4197                                  Scope::FunctionPrototypeScope);4198 4199  Actions.ActOnStartTrailingRequiresClause(getCurScope(), D);4200 4201  std::optional<Sema::CXXThisScopeRAII> ThisScope;4202  InitCXXThisScopeForDeclaratorIfRelevant(D, D.getDeclSpec(), ThisScope);4203 4204  TrailingRequiresClause =4205      ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true);4206 4207  TrailingRequiresClause =4208      Actions.ActOnFinishTrailingRequiresClause(TrailingRequiresClause);4209 4210  if (!D.isDeclarationOfFunction()) {4211    Diag(RequiresKWLoc,4212         diag::err_requires_clause_on_declarator_not_declaring_a_function);4213    return;4214  }4215 4216  if (TrailingRequiresClause.isInvalid())4217    SkipUntil({tok::l_brace, tok::arrow, tok::kw_try, tok::comma, tok::colon},4218              StopAtSemi | StopBeforeMatch);4219  else4220    D.setTrailingRequiresClause(TrailingRequiresClause.get());4221 4222  // Did the user swap the trailing return type and requires clause?4223  if (D.isFunctionDeclarator() && Tok.is(tok::arrow) &&4224      D.getDeclSpec().getTypeSpecType() == TST_auto) {4225    SourceLocation ArrowLoc = Tok.getLocation();4226    SourceRange Range;4227    TypeResult TrailingReturnType =4228        ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit=*/false);4229 4230    if (!TrailingReturnType.isInvalid()) {4231      Diag(ArrowLoc,4232           diag::err_requires_clause_must_appear_after_trailing_return)4233          << Range;4234      auto &FunctionChunk = D.getFunctionTypeInfo();4235      FunctionChunk.HasTrailingReturnType = TrailingReturnType.isUsable();4236      FunctionChunk.TrailingReturnType = TrailingReturnType.get();4237      FunctionChunk.TrailingReturnTypeLoc = Range.getBegin();4238    } else4239      SkipUntil({tok::equal, tok::l_brace, tok::arrow, tok::kw_try, tok::comma},4240                StopAtSemi | StopBeforeMatch);4241  }4242}4243 4244Sema::ParsingClassState Parser::PushParsingClass(Decl *ClassDecl,4245                                                 bool NonNestedClass,4246                                                 bool IsInterface) {4247  assert((NonNestedClass || !ClassStack.empty()) &&4248         "Nested class without outer class");4249  ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass, IsInterface));4250  return Actions.PushParsingClass();4251}4252 4253void Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {4254  for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I)4255    delete Class->LateParsedDeclarations[I];4256  delete Class;4257}4258 4259void Parser::PopParsingClass(Sema::ParsingClassState state) {4260  assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");4261 4262  Actions.PopParsingClass(state);4263 4264  ParsingClass *Victim = ClassStack.top();4265  ClassStack.pop();4266  if (Victim->TopLevelClass) {4267    // Deallocate all of the nested classes of this class,4268    // recursively: we don't need to keep any of this information.4269    DeallocateParsedClasses(Victim);4270    return;4271  }4272  assert(!ClassStack.empty() && "Missing top-level class?");4273 4274  if (Victim->LateParsedDeclarations.empty()) {4275    // The victim is a nested class, but we will not need to perform4276    // any processing after the definition of this class since it has4277    // no members whose handling was delayed. Therefore, we can just4278    // remove this nested class.4279    DeallocateParsedClasses(Victim);4280    return;4281  }4282 4283  // This nested class has some members that will need to be processed4284  // after the top-level class is completely defined. Therefore, add4285  // it to the list of nested classes within its parent.4286  assert(getCurScope()->isClassScope() &&4287         "Nested class outside of class scope?");4288  ClassStack.top()->LateParsedDeclarations.push_back(4289      new LateParsedClass(this, Victim));4290}4291 4292IdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(4293    SourceLocation &Loc, SemaCodeCompletion::AttributeCompletion Completion,4294    const IdentifierInfo *Scope) {4295  switch (Tok.getKind()) {4296  default:4297    // Identifiers and keywords have identifier info attached.4298    if (!Tok.isAnnotation()) {4299      if (IdentifierInfo *II = Tok.getIdentifierInfo()) {4300        Loc = ConsumeToken();4301        return II;4302      }4303    }4304    return nullptr;4305 4306  case tok::code_completion:4307    cutOffParsing();4308    Actions.CodeCompletion().CodeCompleteAttribute(4309        getLangOpts().CPlusPlus ? ParsedAttr::AS_CXX11 : ParsedAttr::AS_C23,4310        Completion, Scope);4311    return nullptr;4312 4313  case tok::numeric_constant: {4314    // If we got a numeric constant, check to see if it comes from a macro that4315    // corresponds to the predefined __clang__ macro. If it does, warn the user4316    // and recover by pretending they said _Clang instead.4317    if (Tok.getLocation().isMacroID()) {4318      SmallString<8> ExpansionBuf;4319      SourceLocation ExpansionLoc =4320          PP.getSourceManager().getExpansionLoc(Tok.getLocation());4321      StringRef Spelling = PP.getSpelling(ExpansionLoc, ExpansionBuf);4322      if (Spelling == "__clang__") {4323        SourceRange TokRange(4324            ExpansionLoc,4325            PP.getSourceManager().getExpansionLoc(Tok.getEndLoc()));4326        Diag(Tok, diag::warn_wrong_clang_attr_namespace)4327            << FixItHint::CreateReplacement(TokRange, "_Clang");4328        Loc = ConsumeToken();4329        return &PP.getIdentifierTable().get("_Clang");4330      }4331    }4332    return nullptr;4333  }4334 4335  case tok::ampamp:       // 'and'4336  case tok::pipe:         // 'bitor'4337  case tok::pipepipe:     // 'or'4338  case tok::caret:        // 'xor'4339  case tok::tilde:        // 'compl'4340  case tok::amp:          // 'bitand'4341  case tok::ampequal:     // 'and_eq'4342  case tok::pipeequal:    // 'or_eq'4343  case tok::caretequal:   // 'xor_eq'4344  case tok::exclaim:      // 'not'4345  case tok::exclaimequal: // 'not_eq'4346    // Alternative tokens do not have identifier info, but their spelling4347    // starts with an alphabetical character.4348    SmallString<8> SpellingBuf;4349    SourceLocation SpellingLoc =4350        PP.getSourceManager().getSpellingLoc(Tok.getLocation());4351    StringRef Spelling = PP.getSpelling(SpellingLoc, SpellingBuf);4352    if (isLetter(Spelling[0])) {4353      Loc = ConsumeToken();4354      return &PP.getIdentifierTable().get(Spelling);4355    }4356    return nullptr;4357  }4358}4359 4360void Parser::ParseOpenMPAttributeArgs(const IdentifierInfo *AttrName,4361                                      CachedTokens &OpenMPTokens) {4362  // Both 'sequence' and 'directive' attributes require arguments, so parse the4363  // open paren for the argument list.4364  BalancedDelimiterTracker T(*this, tok::l_paren);4365  if (T.consumeOpen()) {4366    Diag(Tok, diag::err_expected) << tok::l_paren;4367    return;4368  }4369 4370  if (AttrName->isStr("directive")) {4371    // If the attribute is named `directive`, we can consume its argument list4372    // and push the tokens from it into the cached token stream for a new OpenMP4373    // pragma directive.4374    Token OMPBeginTok;4375    OMPBeginTok.startToken();4376    OMPBeginTok.setKind(tok::annot_attr_openmp);4377    OMPBeginTok.setLocation(Tok.getLocation());4378    OpenMPTokens.push_back(OMPBeginTok);4379 4380    ConsumeAndStoreUntil(tok::r_paren, OpenMPTokens, /*StopAtSemi=*/false,4381                         /*ConsumeFinalToken*/ false);4382    Token OMPEndTok;4383    OMPEndTok.startToken();4384    OMPEndTok.setKind(tok::annot_pragma_openmp_end);4385    OMPEndTok.setLocation(Tok.getLocation());4386    OpenMPTokens.push_back(OMPEndTok);4387  } else {4388    assert(AttrName->isStr("sequence") &&4389           "Expected either 'directive' or 'sequence'");4390    // If the attribute is named 'sequence', its argument is a list of one or4391    // more OpenMP attributes (either 'omp::directive' or 'omp::sequence',4392    // where the 'omp::' is optional).4393    do {4394      // We expect to see one of the following:4395      //  * An identifier (omp) for the attribute namespace followed by ::4396      //  * An identifier (directive) or an identifier (sequence).4397      SourceLocation IdentLoc;4398      const IdentifierInfo *Ident = TryParseCXX11AttributeIdentifier(IdentLoc);4399 4400      // If there is an identifier and it is 'omp', a double colon is required4401      // followed by the actual identifier we're after.4402      if (Ident && Ident->isStr("omp") && !ExpectAndConsume(tok::coloncolon))4403        Ident = TryParseCXX11AttributeIdentifier(IdentLoc);4404 4405      // If we failed to find an identifier (scoped or otherwise), or we found4406      // an unexpected identifier, diagnose.4407      if (!Ident || (!Ident->isStr("directive") && !Ident->isStr("sequence"))) {4408        Diag(Tok.getLocation(), diag::err_expected_sequence_or_directive);4409        SkipUntil(tok::r_paren, StopBeforeMatch);4410        continue;4411      }4412      // We read an identifier. If the identifier is one of the ones we4413      // expected, we can recurse to parse the args.4414      ParseOpenMPAttributeArgs(Ident, OpenMPTokens);4415 4416      // There may be a comma to signal that we expect another directive in the4417      // sequence.4418    } while (TryConsumeToken(tok::comma));4419  }4420  // Parse the closing paren for the argument list.4421  T.consumeClose();4422}4423 4424static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName,4425                                              IdentifierInfo *ScopeName) {4426  switch (4427      ParsedAttr::getParsedKind(AttrName, ScopeName, ParsedAttr::AS_CXX11)) {4428  case ParsedAttr::AT_CarriesDependency:4429  case ParsedAttr::AT_Deprecated:4430  case ParsedAttr::AT_FallThrough:4431  case ParsedAttr::AT_CXX11NoReturn:4432  case ParsedAttr::AT_NoUniqueAddress:4433  case ParsedAttr::AT_Likely:4434  case ParsedAttr::AT_Unlikely:4435    return true;4436  case ParsedAttr::AT_WarnUnusedResult:4437    return !ScopeName && AttrName->getName() == "nodiscard";4438  case ParsedAttr::AT_Unused:4439    return !ScopeName && AttrName->getName() == "maybe_unused";4440  default:4441    return false;4442  }4443}4444 4445bool Parser::ParseCXXAssumeAttributeArg(4446    ParsedAttributes &Attrs, IdentifierInfo *AttrName,4447    SourceLocation AttrNameLoc, IdentifierInfo *ScopeName,4448    SourceLocation ScopeLoc, SourceLocation *EndLoc, ParsedAttr::Form Form) {4449  assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list");4450  BalancedDelimiterTracker T(*this, tok::l_paren);4451  T.consumeOpen();4452 4453  // [dcl.attr.assume]: The expression is potentially evaluated.4454  EnterExpressionEvaluationContext Unevaluated(4455      Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);4456 4457  TentativeParsingAction TPA(*this);4458  ExprResult Res = ParseConditionalExpression();4459  if (Res.isInvalid()) {4460    TPA.Commit();4461    SkipUntil(tok::r_paren, tok::r_square, StopAtSemi | StopBeforeMatch);4462    if (Tok.is(tok::r_paren))4463      T.consumeClose();4464    return true;4465  }4466 4467  if (!Tok.isOneOf(tok::r_paren, tok::r_square)) {4468    // Emit a better diagnostic if this is an otherwise valid expression that4469    // is not allowed here.4470    TPA.Revert();4471    Res = ParseExpression();4472    if (!Res.isInvalid()) {4473      auto *E = Res.get();4474      Diag(E->getExprLoc(), diag::err_assume_attr_expects_cond_expr)4475          << AttrName << FixItHint::CreateInsertion(E->getBeginLoc(), "(")4476          << FixItHint::CreateInsertion(PP.getLocForEndOfToken(E->getEndLoc()),4477                                        ")")4478          << E->getSourceRange();4479    }4480 4481    T.consumeClose();4482    return true;4483  }4484 4485  TPA.Commit();4486  ArgsUnion Assumption = Res.get();4487  auto RParen = Tok.getLocation();4488  T.consumeClose();4489  Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen),4490               AttributeScopeInfo(ScopeName, ScopeLoc), &Assumption, 1, Form);4491 4492  if (EndLoc)4493    *EndLoc = RParen;4494 4495  return false;4496}4497 4498bool Parser::ParseCXX11AttributeArgs(4499    IdentifierInfo *AttrName, SourceLocation AttrNameLoc,4500    ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,4501    SourceLocation ScopeLoc, CachedTokens &OpenMPTokens) {4502  assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list");4503  SourceLocation LParenLoc = Tok.getLocation();4504  const LangOptions &LO = getLangOpts();4505  ParsedAttr::Form Form =4506      LO.CPlusPlus ? ParsedAttr::Form::CXX11() : ParsedAttr::Form::C23();4507 4508  // Try parsing microsoft attributes4509  if (getLangOpts().MicrosoftExt || getLangOpts().HLSL) {4510    if (hasAttribute(AttributeCommonInfo::Syntax::AS_Microsoft, ScopeName,4511                     AttrName, getTargetInfo(), getLangOpts()))4512      Form = ParsedAttr::Form::Microsoft();4513  }4514 4515  if (LO.CPlusPlus) {4516    TentativeParsingAction TPA(*this);4517    bool HasInvalidArgument = false;4518    while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eof)) {4519      if (Tok.isOneOf(tok::hash, tok::hashhash)) {4520        Diag(Tok.getLocation(), diag::ext_invalid_attribute_argument)4521            << PP.getSpelling(Tok);4522        HasInvalidArgument = true;4523      }4524      ConsumeAnyToken();4525    }4526 4527    if (HasInvalidArgument) {4528      SkipUntil(tok::r_paren);4529      TPA.Commit();4530      return true;4531    }4532 4533    TPA.Revert();4534  }4535 4536  // If the attribute isn't known, we will not attempt to parse any4537  // arguments.4538  if (Form.getSyntax() != ParsedAttr::AS_Microsoft &&4539      !hasAttribute(LO.CPlusPlus ? AttributeCommonInfo::Syntax::AS_CXX114540                                 : AttributeCommonInfo::Syntax::AS_C23,4541                    ScopeName, AttrName, getTargetInfo(), getLangOpts())) {4542    // Eat the left paren, then skip to the ending right paren.4543    ConsumeParen();4544    SkipUntil(tok::r_paren);4545    return false;4546  }4547 4548  if (ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"))) {4549    // GNU-scoped attributes have some special cases to handle GNU-specific4550    // behaviors.4551    ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,4552                          ScopeLoc, Form, nullptr);4553    return true;4554  }4555 4556  // [[omp::directive]] and [[omp::sequence]] need special handling.4557  if (ScopeName && ScopeName->isStr("omp") &&4558      (AttrName->isStr("directive") || AttrName->isStr("sequence"))) {4559    Diag(AttrNameLoc, getLangOpts().OpenMP >= 514560                          ? diag::warn_omp51_compat_attributes4561                          : diag::ext_omp_attributes);4562 4563    ParseOpenMPAttributeArgs(AttrName, OpenMPTokens);4564 4565    // We claim that an attribute was parsed and added so that one is not4566    // created for us by the caller.4567    return true;4568  }4569 4570  unsigned NumArgs;4571  // Some Clang-scoped attributes have some special parsing behavior.4572  if (ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang")))4573    NumArgs = ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc,4574                                      ScopeName, ScopeLoc, Form);4575  // So does C++23's assume() attribute.4576  else if (!ScopeName && AttrName->isStr("assume")) {4577    if (ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, nullptr,4578                                   SourceLocation{}, EndLoc, Form))4579      return true;4580    NumArgs = 1;4581  } else4582    NumArgs = ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,4583                                       ScopeName, ScopeLoc, Form);4584 4585  if (!Attrs.empty() &&4586      IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {4587    ParsedAttr &Attr = Attrs.back();4588 4589    // Ignore attributes that don't exist for the target.4590    if (!Attr.existsInTarget(getTargetInfo())) {4591      Actions.DiagnoseUnknownAttribute(Attr);4592      Attr.setInvalid(true);4593      return true;4594    }4595 4596    // If the attribute is a standard or built-in attribute and we are4597    // parsing an argument list, we need to determine whether this attribute4598    // was allowed to have an argument list (such as [[deprecated]]), and how4599    // many arguments were parsed (so we can diagnose on [[deprecated()]]).4600    if (Attr.getMaxArgs() && !NumArgs) {4601      // The attribute was allowed to have arguments, but none were provided4602      // even though the attribute parsed successfully. This is an error.4603      Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;4604      Attr.setInvalid(true);4605    } else if (!Attr.getMaxArgs()) {4606      // The attribute parsed successfully, but was not allowed to have any4607      // arguments. It doesn't matter whether any were provided -- the4608      // presence of the argument list (even if empty) is diagnosed.4609      Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)4610          << AttrName4611          << FixItHint::CreateRemoval(SourceRange(LParenLoc, *EndLoc));4612      Attr.setInvalid(true);4613    }4614  }4615  return true;4616}4617 4618void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,4619                                                  CachedTokens &OpenMPTokens,4620                                                  SourceLocation *EndLoc) {4621  if (Tok.is(tok::kw_alignas)) {4622    // alignas is a valid token in C23 but it is not an attribute, it's a type-4623    // specifier-qualifier, which means it has different parsing behavior. We4624    // handle this in ParseDeclarationSpecifiers() instead of here in C. We4625    // should not get here for C any longer.4626    assert(getLangOpts().CPlusPlus && "'alignas' is not an attribute in C");4627    Diag(Tok.getLocation(), diag::warn_cxx98_compat_alignas);4628    ParseAlignmentSpecifier(Attrs, EndLoc);4629    return;4630  }4631 4632  if (Tok.isRegularKeywordAttribute()) {4633    SourceLocation Loc = Tok.getLocation();4634    IdentifierInfo *AttrName = Tok.getIdentifierInfo();4635    ParsedAttr::Form Form = ParsedAttr::Form(Tok.getKind());4636    bool TakesArgs = doesKeywordAttributeTakeArgs(Tok.getKind());4637    ConsumeToken();4638    if (TakesArgs) {4639      if (!Tok.is(tok::l_paren))4640        Diag(Tok.getLocation(), diag::err_expected_lparen_after) << AttrName;4641      else4642        ParseAttributeArgsCommon(AttrName, Loc, Attrs, EndLoc,4643                                 /*ScopeName*/ nullptr,4644                                 /*ScopeLoc*/ Loc, Form);4645    } else4646      Attrs.addNew(AttrName, Loc, AttributeScopeInfo(), nullptr, 0, Form);4647    return;4648  }4649 4650  assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square) &&4651         "Not a double square bracket attribute list");4652 4653  SourceLocation OpenLoc = Tok.getLocation();4654  if (getLangOpts().CPlusPlus) {4655    Diag(OpenLoc, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_attribute4656                                            : diag::warn_ext_cxx11_attributes);4657  } else {4658    Diag(OpenLoc, getLangOpts().C23 ? diag::warn_pre_c23_compat_attributes4659                                    : diag::warn_ext_c23_attributes);4660  }4661 4662  ConsumeBracket();4663  checkCompoundToken(OpenLoc, tok::l_square, CompoundToken::AttrBegin);4664  ConsumeBracket();4665 4666  SourceLocation CommonScopeLoc;4667  IdentifierInfo *CommonScopeName = nullptr;4668  if (Tok.is(tok::kw_using)) {4669    Diag(Tok.getLocation(), getLangOpts().CPlusPlus174670                                ? diag::warn_cxx14_compat_using_attribute_ns4671                                : diag::ext_using_attribute_ns);4672    ConsumeToken();4673 4674    CommonScopeName = TryParseCXX11AttributeIdentifier(4675        CommonScopeLoc, SemaCodeCompletion::AttributeCompletion::Scope);4676    if (!CommonScopeName) {4677      Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;4678      SkipUntil(tok::r_square, tok::colon, StopBeforeMatch);4679    }4680    if (!TryConsumeToken(tok::colon) && CommonScopeName)4681      Diag(Tok.getLocation(), diag::err_expected) << tok::colon;4682  }4683 4684  bool AttrParsed = false;4685  while (!Tok.isOneOf(tok::r_square, tok::semi, tok::eof)) {4686    if (AttrParsed) {4687      // If we parsed an attribute, a comma is required before parsing any4688      // additional attributes.4689      if (ExpectAndConsume(tok::comma)) {4690        SkipUntil(tok::r_square, StopAtSemi | StopBeforeMatch);4691        continue;4692      }4693      AttrParsed = false;4694    }4695 4696    // Eat all remaining superfluous commas before parsing the next attribute.4697    while (TryConsumeToken(tok::comma))4698      ;4699 4700    SourceLocation ScopeLoc, AttrLoc;4701    IdentifierInfo *ScopeName = nullptr, *AttrName = nullptr;4702 4703    AttrName = TryParseCXX11AttributeIdentifier(4704        AttrLoc, SemaCodeCompletion::AttributeCompletion::Attribute,4705        CommonScopeName);4706    if (!AttrName)4707      // Break out to the "expected ']'" diagnostic.4708      break;4709 4710    // scoped attribute4711    if (TryConsumeToken(tok::coloncolon)) {4712      ScopeName = AttrName;4713      ScopeLoc = AttrLoc;4714 4715      AttrName = TryParseCXX11AttributeIdentifier(4716          AttrLoc, SemaCodeCompletion::AttributeCompletion::Attribute,4717          ScopeName);4718      if (!AttrName) {4719        Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;4720        SkipUntil(tok::r_square, tok::comma, StopAtSemi | StopBeforeMatch);4721        continue;4722      }4723    }4724 4725    if (CommonScopeName) {4726      if (ScopeName) {4727        Diag(ScopeLoc, diag::err_using_attribute_ns_conflict)4728            << SourceRange(CommonScopeLoc);4729      } else {4730        ScopeName = CommonScopeName;4731        ScopeLoc = CommonScopeLoc;4732      }4733    }4734 4735    // Parse attribute arguments4736    if (Tok.is(tok::l_paren))4737      AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc,4738                                           ScopeName, ScopeLoc, OpenMPTokens);4739 4740    if (!AttrParsed) {4741      Attrs.addNew(AttrName,4742                   SourceRange(ScopeLoc.isValid() && CommonScopeLoc.isInvalid()4743                                   ? ScopeLoc4744                                   : AttrLoc,4745                               AttrLoc),4746                   AttributeScopeInfo(ScopeName, ScopeLoc, CommonScopeLoc),4747                   nullptr, 0,4748                   getLangOpts().CPlusPlus ? ParsedAttr::Form::CXX11()4749                                           : ParsedAttr::Form::C23());4750      AttrParsed = true;4751    }4752 4753    if (TryConsumeToken(tok::ellipsis))4754      Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) << AttrName;4755  }4756 4757  // If we hit an error and recovered by parsing up to a semicolon, eat the4758  // semicolon and don't issue further diagnostics about missing brackets.4759  if (Tok.is(tok::semi)) {4760    ConsumeToken();4761    return;4762  }4763 4764  SourceLocation CloseLoc = Tok.getLocation();4765  if (ExpectAndConsume(tok::r_square))4766    SkipUntil(tok::r_square);4767  else if (Tok.is(tok::r_square))4768    checkCompoundToken(CloseLoc, tok::r_square, CompoundToken::AttrEnd);4769  if (EndLoc)4770    *EndLoc = Tok.getLocation();4771  if (ExpectAndConsume(tok::r_square))4772    SkipUntil(tok::r_square);4773}4774 4775void Parser::ParseCXX11Attributes(ParsedAttributes &Attrs) {4776  SourceLocation StartLoc = Tok.getLocation();4777  SourceLocation EndLoc = StartLoc;4778 4779  do {4780    ParseCXX11AttributeSpecifier(Attrs, &EndLoc);4781  } while (isAllowedCXX11AttributeSpecifier());4782 4783  Attrs.Range = SourceRange(StartLoc, EndLoc);4784}4785 4786void Parser::DiagnoseAndSkipCXX11Attributes() {4787  auto Keyword =4788      Tok.isRegularKeywordAttribute() ? Tok.getIdentifierInfo() : nullptr;4789  // Start and end location of an attribute or an attribute list.4790  SourceLocation StartLoc = Tok.getLocation();4791  SourceLocation EndLoc = SkipCXX11Attributes();4792 4793  if (EndLoc.isValid()) {4794    SourceRange Range(StartLoc, EndLoc);4795    (Keyword ? Diag(StartLoc, diag::err_keyword_not_allowed) << Keyword4796             : Diag(StartLoc, diag::err_attributes_not_allowed))4797        << Range;4798  }4799}4800 4801SourceLocation Parser::SkipCXX11Attributes() {4802  SourceLocation EndLoc;4803 4804  if (isCXX11AttributeSpecifier() == CXX11AttributeKind::NotAttributeSpecifier)4805    return EndLoc;4806 4807  do {4808    if (Tok.is(tok::l_square)) {4809      BalancedDelimiterTracker T(*this, tok::l_square);4810      T.consumeOpen();4811      T.skipToEnd();4812      EndLoc = T.getCloseLocation();4813    } else if (Tok.isRegularKeywordAttribute() &&4814               !doesKeywordAttributeTakeArgs(Tok.getKind())) {4815      EndLoc = Tok.getLocation();4816      ConsumeToken();4817    } else {4818      assert((Tok.is(tok::kw_alignas) || Tok.isRegularKeywordAttribute()) &&4819             "not an attribute specifier");4820      ConsumeToken();4821      BalancedDelimiterTracker T(*this, tok::l_paren);4822      if (!T.consumeOpen())4823        T.skipToEnd();4824      EndLoc = T.getCloseLocation();4825    }4826  } while (isCXX11AttributeSpecifier() !=4827           CXX11AttributeKind::NotAttributeSpecifier);4828 4829  return EndLoc;4830}4831 4832void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) {4833  assert(Tok.is(tok::identifier) && "Not a Microsoft attribute list");4834  IdentifierInfo *UuidIdent = Tok.getIdentifierInfo();4835  assert(UuidIdent->getName() == "uuid" && "Not a Microsoft attribute list");4836 4837  SourceLocation UuidLoc = Tok.getLocation();4838  ConsumeToken();4839 4840  // Ignore the left paren location for now.4841  BalancedDelimiterTracker T(*this, tok::l_paren);4842  if (T.consumeOpen()) {4843    Diag(Tok, diag::err_expected) << tok::l_paren;4844    return;4845  }4846 4847  ArgsVector ArgExprs;4848  if (isTokenStringLiteral()) {4849    // Easy case: uuid("...") -- quoted string.4850    ExprResult StringResult = ParseUnevaluatedStringLiteralExpression();4851    if (StringResult.isInvalid())4852      return;4853    ArgExprs.push_back(StringResult.get());4854  } else {4855    // something like uuid({000000A0-0000-0000-C000-000000000049}) -- no4856    // quotes in the parens. Just append the spelling of all tokens encountered4857    // until the closing paren.4858 4859    SmallString<42> StrBuffer; // 2 "", 36 bytes UUID, 2 optional {}, 1 nul4860    StrBuffer += "\"";4861 4862    // Since none of C++'s keywords match [a-f]+, accepting just tok::l_brace,4863    // tok::r_brace, tok::minus, tok::identifier (think C000) and4864    // tok::numeric_constant (0000) should be enough. But the spelling of the4865    // uuid argument is checked later anyways, so there's no harm in accepting4866    // almost anything here.4867    // cl is very strict about whitespace in this form and errors out if any4868    // is present, so check the space flags on the tokens.4869    SourceLocation StartLoc = Tok.getLocation();4870    while (Tok.isNot(tok::r_paren)) {4871      if (Tok.hasLeadingSpace() || Tok.isAtStartOfLine()) {4872        Diag(Tok, diag::err_attribute_uuid_malformed_guid);4873        SkipUntil(tok::r_paren, StopAtSemi);4874        return;4875      }4876      SmallString<16> SpellingBuffer;4877      SpellingBuffer.resize(Tok.getLength() + 1);4878      bool Invalid = false;4879      StringRef TokSpelling = PP.getSpelling(Tok, SpellingBuffer, &Invalid);4880      if (Invalid) {4881        SkipUntil(tok::r_paren, StopAtSemi);4882        return;4883      }4884      StrBuffer += TokSpelling;4885      ConsumeAnyToken();4886    }4887    StrBuffer += "\"";4888 4889    if (Tok.hasLeadingSpace() || Tok.isAtStartOfLine()) {4890      Diag(Tok, diag::err_attribute_uuid_malformed_guid);4891      ConsumeParen();4892      return;4893    }4894 4895    // Pretend the user wrote the appropriate string literal here.4896    // ActOnStringLiteral() copies the string data into the literal, so it's4897    // ok that the Token points to StrBuffer.4898    Token Toks[1];4899    Toks[0].startToken();4900    Toks[0].setKind(tok::string_literal);4901    Toks[0].setLocation(StartLoc);4902    Toks[0].setLiteralData(StrBuffer.data());4903    Toks[0].setLength(StrBuffer.size());4904    StringLiteral *UuidString =4905        cast<StringLiteral>(Actions.ActOnUnevaluatedStringLiteral(Toks).get());4906    ArgExprs.push_back(UuidString);4907  }4908 4909  if (!T.consumeClose()) {4910    Attrs.addNew(UuidIdent, SourceRange(UuidLoc, T.getCloseLocation()),4911                 AttributeScopeInfo(), ArgExprs.data(), ArgExprs.size(),4912                 ParsedAttr::Form::Microsoft());4913  }4914}4915 4916void Parser::ParseHLSLRootSignatureAttributeArgs(ParsedAttributes &Attrs) {4917  assert(Tok.is(tok::identifier) &&4918         "Expected an identifier to denote which MS attribute to consider");4919  IdentifierInfo *RootSignatureIdent = Tok.getIdentifierInfo();4920  assert(RootSignatureIdent->getName() == "RootSignature" &&4921         "Expected RootSignature identifier for root signature attribute");4922 4923  SourceLocation RootSignatureLoc = Tok.getLocation();4924  ConsumeToken();4925 4926  // Ignore the left paren location for now.4927  BalancedDelimiterTracker T(*this, tok::l_paren);4928  if (T.consumeOpen()) {4929    Diag(Tok, diag::err_expected) << tok::l_paren;4930    return;4931  }4932 4933  auto ProcessStringLiteral = [this]() -> std::optional<StringLiteral *> {4934    if (!isTokenStringLiteral())4935      return std::nullopt;4936 4937    ExprResult StringResult = ParseUnevaluatedStringLiteralExpression();4938    if (StringResult.isInvalid())4939      return std::nullopt;4940 4941    if (auto Lit = dyn_cast<StringLiteral>(StringResult.get()))4942      return Lit;4943 4944    return std::nullopt;4945  };4946 4947  auto Signature = ProcessStringLiteral();4948  if (!Signature.has_value()) {4949    Diag(Tok, diag::err_expected_string_literal)4950        << /*in attributes...*/ 4 << "RootSignature";4951    return;4952  }4953 4954  // Construct our identifier4955  IdentifierInfo *DeclIdent = hlsl::ParseHLSLRootSignature(4956      Actions, getLangOpts().HLSLRootSigVer, *Signature);4957  if (!DeclIdent) {4958    SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);4959    T.consumeClose();4960    return;4961  }4962 4963  // Create the arg for the ParsedAttr4964  IdentifierLoc *ILoc = ::new (Actions.getASTContext())4965      IdentifierLoc(RootSignatureLoc, DeclIdent);4966 4967  ArgsVector Args = {ILoc};4968 4969  if (!T.consumeClose())4970    Attrs.addNew(RootSignatureIdent,4971                 SourceRange(RootSignatureLoc, T.getCloseLocation()),4972                 AttributeScopeInfo(), Args.data(), Args.size(),4973                 ParsedAttr::Form::Microsoft());4974}4975 4976void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) {4977  assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");4978 4979  SourceLocation StartLoc = Tok.getLocation();4980  SourceLocation EndLoc = StartLoc;4981  do {4982    // FIXME: If this is actually a C++11 attribute, parse it as one.4983    BalancedDelimiterTracker T(*this, tok::l_square);4984    T.consumeOpen();4985 4986    // Skip most ms attributes except for a specific list.4987    while (true) {4988      SkipUntil(tok::r_square, tok::identifier,4989                StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);4990      if (Tok.is(tok::code_completion)) {4991        cutOffParsing();4992        Actions.CodeCompletion().CodeCompleteAttribute(4993            AttributeCommonInfo::AS_Microsoft,4994            SemaCodeCompletion::AttributeCompletion::Attribute,4995            /*Scope=*/nullptr);4996        break;4997      }4998      if (Tok.isNot(tok::identifier)) // ']', but also eof4999        break;5000      if (Tok.getIdentifierInfo()->getName() == "uuid")5001        ParseMicrosoftUuidAttributeArgs(Attrs);5002      else if (Tok.getIdentifierInfo()->getName() == "RootSignature")5003        ParseHLSLRootSignatureAttributeArgs(Attrs);5004      else {5005        IdentifierInfo *II = Tok.getIdentifierInfo();5006        SourceLocation NameLoc = Tok.getLocation();5007        ConsumeToken();5008        ParsedAttr::Kind AttrKind =5009            ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_Microsoft);5010        // For HLSL we want to handle all attributes, but for MSVC compat, we5011        // silently ignore unknown Microsoft attributes.5012        if (getLangOpts().HLSL || AttrKind != ParsedAttr::UnknownAttribute) {5013          bool AttrParsed = false;5014          if (Tok.is(tok::l_paren)) {5015            CachedTokens OpenMPTokens;5016            AttrParsed =5017                ParseCXX11AttributeArgs(II, NameLoc, Attrs, &EndLoc, nullptr,5018                                        SourceLocation(), OpenMPTokens);5019            ReplayOpenMPAttributeTokens(OpenMPTokens);5020          }5021          if (!AttrParsed) {5022            Attrs.addNew(II, NameLoc, AttributeScopeInfo(), nullptr, 0,5023                         ParsedAttr::Form::Microsoft());5024          }5025        }5026      }5027    }5028 5029    T.consumeClose();5030    EndLoc = T.getCloseLocation();5031  } while (Tok.is(tok::l_square));5032 5033  Attrs.Range = SourceRange(StartLoc, EndLoc);5034}5035 5036void Parser::ParseMicrosoftIfExistsClassDeclaration(5037    DeclSpec::TST TagType, ParsedAttributes &AccessAttrs,5038    AccessSpecifier &CurAS) {5039  IfExistsCondition Result;5040  if (ParseMicrosoftIfExistsCondition(Result))5041    return;5042 5043  BalancedDelimiterTracker Braces(*this, tok::l_brace);5044  if (Braces.consumeOpen()) {5045    Diag(Tok, diag::err_expected) << tok::l_brace;5046    return;5047  }5048 5049  switch (Result.Behavior) {5050  case IfExistsBehavior::Parse:5051    // Parse the declarations below.5052    break;5053 5054  case IfExistsBehavior::Dependent:5055    Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)5056        << Result.IsIfExists;5057    // Fall through to skip.5058    [[fallthrough]];5059 5060  case IfExistsBehavior::Skip:5061    Braces.skipToEnd();5062    return;5063  }5064 5065  while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {5066    // __if_exists, __if_not_exists can nest.5067    if (Tok.isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) {5068      ParseMicrosoftIfExistsClassDeclaration(TagType, AccessAttrs, CurAS);5069      continue;5070    }5071 5072    // Check for extraneous top-level semicolon.5073    if (Tok.is(tok::semi)) {5074      ConsumeExtraSemi(ExtraSemiKind::InsideStruct, TagType);5075      continue;5076    }5077 5078    AccessSpecifier AS = getAccessSpecifierIfPresent();5079    if (AS != AS_none) {5080      // Current token is a C++ access specifier.5081      CurAS = AS;5082      SourceLocation ASLoc = Tok.getLocation();5083      ConsumeToken();5084      if (Tok.is(tok::colon))5085        Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation(),5086                                     ParsedAttributesView{});5087      else5088        Diag(Tok, diag::err_expected) << tok::colon;5089      ConsumeToken();5090      continue;5091    }5092 5093    ParsedTemplateInfo TemplateInfo;5094    // Parse all the comma separated declarators.5095    ParseCXXClassMemberDeclaration(CurAS, AccessAttrs, TemplateInfo);5096  }5097 5098  Braces.consumeClose();5099}5100