brintos

brintos / llvm-project-archived public Read only

0
0
Text · 300.5 KiB · 8688ccf Raw
8196 lines · cpp
1//===--- ParseDecl.cpp - 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 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/AddressSpaces.h"17#include "clang/Basic/AttributeCommonInfo.h"18#include "clang/Basic/Attributes.h"19#include "clang/Basic/CharInfo.h"20#include "clang/Basic/DiagnosticParse.h"21#include "clang/Basic/TargetInfo.h"22#include "clang/Basic/TokenKinds.h"23#include "clang/Parse/Parser.h"24#include "clang/Parse/RAIIObjectsForParser.h"25#include "clang/Sema/EnterExpressionEvaluationContext.h"26#include "clang/Sema/Lookup.h"27#include "clang/Sema/ParsedAttr.h"28#include "clang/Sema/ParsedTemplate.h"29#include "clang/Sema/Scope.h"30#include "clang/Sema/SemaCUDA.h"31#include "clang/Sema/SemaCodeCompletion.h"32#include "clang/Sema/SemaObjC.h"33#include "clang/Sema/SemaOpenMP.h"34#include "llvm/ADT/SmallSet.h"35#include "llvm/ADT/StringSwitch.h"36#include <optional>37 38using namespace clang;39 40//===----------------------------------------------------------------------===//41// C99 6.7: Declarations.42//===----------------------------------------------------------------------===//43 44TypeResult Parser::ParseTypeName(SourceRange *Range, DeclaratorContext Context,45                                 AccessSpecifier AS, Decl **OwnedType,46                                 ParsedAttributes *Attrs) {47  DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);48  if (DSC == DeclSpecContext::DSC_normal)49    DSC = DeclSpecContext::DSC_type_specifier;50 51  // Parse the common declaration-specifiers piece.52  DeclSpec DS(AttrFactory);53  if (Attrs)54    DS.addAttributes(*Attrs);55  ParseSpecifierQualifierList(DS, AS, DSC);56  if (OwnedType)57    *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : nullptr;58 59  // Move declspec attributes to ParsedAttributes60  if (Attrs) {61    llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;62    for (ParsedAttr &AL : DS.getAttributes()) {63      if (AL.isDeclspecAttribute())64        ToBeMoved.push_back(&AL);65    }66 67    for (ParsedAttr *AL : ToBeMoved)68      Attrs->takeOneFrom(DS.getAttributes(), AL);69  }70 71  // Parse the abstract-declarator, if present.72  Declarator DeclaratorInfo(DS, ParsedAttributesView::none(), Context);73  ParseDeclarator(DeclaratorInfo);74  if (Range)75    *Range = DeclaratorInfo.getSourceRange();76 77  if (DeclaratorInfo.isInvalidType())78    return true;79 80  return Actions.ActOnTypeName(DeclaratorInfo);81}82 83/// Normalizes an attribute name by dropping prefixed and suffixed __.84static StringRef normalizeAttrName(StringRef Name) {85  if (Name.size() >= 4 && Name.starts_with("__") && Name.ends_with("__"))86    return Name.drop_front(2).drop_back(2);87  return Name;88}89 90/// returns true iff attribute is annotated with `LateAttrParseExperimentalExt`91/// in `Attr.td`.92static bool IsAttributeLateParsedExperimentalExt(const IdentifierInfo &II) {93#define CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST94  return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))95#include "clang/Parse/AttrParserStringSwitches.inc"96      .Default(false);97#undef CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST98}99 100/// returns true iff attribute is annotated with `LateAttrParseStandard` in101/// `Attr.td`.102static bool IsAttributeLateParsedStandard(const IdentifierInfo &II) {103#define CLANG_ATTR_LATE_PARSED_LIST104  return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))105#include "clang/Parse/AttrParserStringSwitches.inc"106      .Default(false);107#undef CLANG_ATTR_LATE_PARSED_LIST108}109 110/// Check if the a start and end source location expand to the same macro.111static bool FindLocsWithCommonFileID(Preprocessor &PP, SourceLocation StartLoc,112                                     SourceLocation EndLoc) {113  if (!StartLoc.isMacroID() || !EndLoc.isMacroID())114    return false;115 116  SourceManager &SM = PP.getSourceManager();117  if (SM.getFileID(StartLoc) != SM.getFileID(EndLoc))118    return false;119 120  bool AttrStartIsInMacro =121      Lexer::isAtStartOfMacroExpansion(StartLoc, SM, PP.getLangOpts());122  bool AttrEndIsInMacro =123      Lexer::isAtEndOfMacroExpansion(EndLoc, SM, PP.getLangOpts());124  return AttrStartIsInMacro && AttrEndIsInMacro;125}126 127void Parser::ParseAttributes(unsigned WhichAttrKinds, ParsedAttributes &Attrs,128                             LateParsedAttrList *LateAttrs) {129  bool MoreToParse;130  do {131    // Assume there's nothing left to parse, but if any attributes are in fact132    // parsed, loop to ensure all specified attribute combinations are parsed.133    MoreToParse = false;134    if (WhichAttrKinds & PAKM_CXX11)135      MoreToParse |= MaybeParseCXX11Attributes(Attrs);136    if (WhichAttrKinds & PAKM_GNU)137      MoreToParse |= MaybeParseGNUAttributes(Attrs, LateAttrs);138    if (WhichAttrKinds & PAKM_Declspec)139      MoreToParse |= MaybeParseMicrosoftDeclSpecs(Attrs);140  } while (MoreToParse);141}142 143bool Parser::ParseSingleGNUAttribute(ParsedAttributes &Attrs,144                                     SourceLocation &EndLoc,145                                     LateParsedAttrList *LateAttrs,146                                     Declarator *D) {147  IdentifierInfo *AttrName = Tok.getIdentifierInfo();148  if (!AttrName)149    return true;150 151  SourceLocation AttrNameLoc = ConsumeToken();152 153  if (Tok.isNot(tok::l_paren)) {154    Attrs.addNew(AttrName, AttrNameLoc, AttributeScopeInfo(), nullptr, 0,155                 ParsedAttr::Form::GNU());156    return false;157  }158 159  bool LateParse = false;160  if (!LateAttrs)161    LateParse = false;162  else if (LateAttrs->lateAttrParseExperimentalExtOnly()) {163    // The caller requested that this attribute **only** be late164    // parsed for `LateAttrParseExperimentalExt` attributes. This will165    // only be late parsed if the experimental language option is enabled.166    LateParse = getLangOpts().ExperimentalLateParseAttributes &&167                IsAttributeLateParsedExperimentalExt(*AttrName);168  } else {169    // The caller did not restrict late parsing to only170    // `LateAttrParseExperimentalExt` attributes so late parse171    // both `LateAttrParseStandard` and `LateAttrParseExperimentalExt`172    // attributes.173    LateParse = IsAttributeLateParsedExperimentalExt(*AttrName) ||174                IsAttributeLateParsedStandard(*AttrName);175  }176 177  // Handle "parameterized" attributes178  if (!LateParse) {179    ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc, nullptr,180                          SourceLocation(), ParsedAttr::Form::GNU(), D);181    return false;182  }183 184  // Handle attributes with arguments that require late parsing.185  LateParsedAttribute *LA =186      new LateParsedAttribute(this, *AttrName, AttrNameLoc);187  LateAttrs->push_back(LA);188 189  // Attributes in a class are parsed at the end of the class, along190  // with other late-parsed declarations.191  if (!ClassStack.empty() && !LateAttrs->parseSoon())192    getCurrentClass().LateParsedDeclarations.push_back(LA);193 194  // Be sure ConsumeAndStoreUntil doesn't see the start l_paren, since it195  // recursively consumes balanced parens.196  LA->Toks.push_back(Tok);197  ConsumeParen();198  // Consume everything up to and including the matching right parens.199  ConsumeAndStoreUntil(tok::r_paren, LA->Toks, /*StopAtSemi=*/true);200 201  Token Eof;202  Eof.startToken();203  Eof.setLocation(Tok.getLocation());204  LA->Toks.push_back(Eof);205 206  return false;207}208 209void Parser::ParseGNUAttributes(ParsedAttributes &Attrs,210                                LateParsedAttrList *LateAttrs, Declarator *D) {211  assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");212 213  SourceLocation StartLoc = Tok.getLocation();214  SourceLocation EndLoc = StartLoc;215 216  while (Tok.is(tok::kw___attribute)) {217    SourceLocation AttrTokLoc = ConsumeToken();218    unsigned OldNumAttrs = Attrs.size();219    unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;220 221    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,222                         "attribute")) {223      SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ;224      return;225    }226    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {227      SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ;228      return;229    }230    // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))231    do {232      // Eat preceeding commas to allow __attribute__((,,,foo))233      while (TryConsumeToken(tok::comma))234        ;235 236      // Expect an identifier or declaration specifier (const, int, etc.)237      if (Tok.isAnnotation())238        break;239      if (Tok.is(tok::code_completion)) {240        cutOffParsing();241        Actions.CodeCompletion().CodeCompleteAttribute(242            AttributeCommonInfo::Syntax::AS_GNU);243        break;244      }245 246      if (ParseSingleGNUAttribute(Attrs, EndLoc, LateAttrs, D))247        break;248    } while (Tok.is(tok::comma));249 250    if (ExpectAndConsume(tok::r_paren))251      SkipUntil(tok::r_paren, StopAtSemi);252    SourceLocation Loc = Tok.getLocation();253    if (ExpectAndConsume(tok::r_paren))254      SkipUntil(tok::r_paren, StopAtSemi);255    EndLoc = Loc;256 257    // If this was declared in a macro, attach the macro IdentifierInfo to the258    // parsed attribute.259    auto &SM = PP.getSourceManager();260    if (!SM.isWrittenInBuiltinFile(SM.getSpellingLoc(AttrTokLoc)) &&261        FindLocsWithCommonFileID(PP, AttrTokLoc, Loc)) {262      CharSourceRange ExpansionRange = SM.getExpansionRange(AttrTokLoc);263      StringRef FoundName =264          Lexer::getSourceText(ExpansionRange, SM, PP.getLangOpts());265      IdentifierInfo *MacroII = PP.getIdentifierInfo(FoundName);266 267      for (unsigned i = OldNumAttrs; i < Attrs.size(); ++i)268        Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.getBegin());269 270      if (LateAttrs) {271        for (unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)272          (*LateAttrs)[i]->MacroII = MacroII;273      }274    }275  }276 277  Attrs.Range = SourceRange(StartLoc, EndLoc);278}279 280/// Determine whether the given attribute has an identifier argument.281static bool attributeHasIdentifierArg(const llvm::Triple &T,282                                      const IdentifierInfo &II,283                                      ParsedAttr::Syntax Syntax,284                                      IdentifierInfo *ScopeName) {285#define CLANG_ATTR_IDENTIFIER_ARG_LIST286  return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))287#include "clang/Parse/AttrParserStringSwitches.inc"288      .Default(false);289#undef CLANG_ATTR_IDENTIFIER_ARG_LIST290}291 292/// Determine whether the given attribute has string arguments.293static ParsedAttributeArgumentsProperties294attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II,295                              ParsedAttr::Syntax Syntax,296                              IdentifierInfo *ScopeName) {297#define CLANG_ATTR_STRING_LITERAL_ARG_LIST298  return llvm::StringSwitch<uint32_t>(normalizeAttrName(II.getName()))299#include "clang/Parse/AttrParserStringSwitches.inc"300      .Default(0);301#undef CLANG_ATTR_STRING_LITERAL_ARG_LIST302}303 304/// Determine whether the given attribute has a variadic identifier argument.305static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II,306                                              ParsedAttr::Syntax Syntax,307                                              IdentifierInfo *ScopeName) {308#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST309  return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))310#include "clang/Parse/AttrParserStringSwitches.inc"311      .Default(false);312#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST313}314 315/// Determine whether the given attribute treats kw_this as an identifier.316static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II,317                                                   ParsedAttr::Syntax Syntax,318                                                   IdentifierInfo *ScopeName) {319#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST320  return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))321#include "clang/Parse/AttrParserStringSwitches.inc"322      .Default(false);323#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST324}325 326/// Determine if an attribute accepts parameter packs.327static bool attributeAcceptsExprPack(const IdentifierInfo &II,328                                     ParsedAttr::Syntax Syntax,329                                     IdentifierInfo *ScopeName) {330#define CLANG_ATTR_ACCEPTS_EXPR_PACK331  return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))332#include "clang/Parse/AttrParserStringSwitches.inc"333      .Default(false);334#undef CLANG_ATTR_ACCEPTS_EXPR_PACK335}336 337/// Determine whether the given attribute parses a type argument.338static bool attributeIsTypeArgAttr(const IdentifierInfo &II,339                                   ParsedAttr::Syntax Syntax,340                                   IdentifierInfo *ScopeName) {341#define CLANG_ATTR_TYPE_ARG_LIST342  return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))343#include "clang/Parse/AttrParserStringSwitches.inc"344      .Default(false);345#undef CLANG_ATTR_TYPE_ARG_LIST346}347 348/// Determine whether the given attribute takes a strict identifier argument.349static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II,350                                             ParsedAttr::Syntax Syntax,351                                             IdentifierInfo *ScopeName) {352#define CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST353  return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))354#include "clang/Parse/AttrParserStringSwitches.inc"355      .Default(false);356#undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST357}358 359/// Determine whether the given attribute requires parsing its arguments360/// in an unevaluated context or not.361static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II,362                                           ParsedAttr::Syntax Syntax,363                                           IdentifierInfo *ScopeName) {364#define CLANG_ATTR_ARG_CONTEXT_LIST365  return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))366#include "clang/Parse/AttrParserStringSwitches.inc"367      .Default(false);368#undef CLANG_ATTR_ARG_CONTEXT_LIST369}370 371IdentifierLoc *Parser::ParseIdentifierLoc() {372  assert(Tok.is(tok::identifier) && "expected an identifier");373  IdentifierLoc *IL = new (Actions.Context)374      IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());375  ConsumeToken();376  return IL;377}378 379void Parser::ParseAttributeWithTypeArg(IdentifierInfo &AttrName,380                                       SourceLocation AttrNameLoc,381                                       ParsedAttributes &Attrs,382                                       IdentifierInfo *ScopeName,383                                       SourceLocation ScopeLoc,384                                       ParsedAttr::Form Form) {385  BalancedDelimiterTracker Parens(*this, tok::l_paren);386  Parens.consumeOpen();387 388  TypeResult T;389  if (Tok.isNot(tok::r_paren))390    T = ParseTypeName();391 392  if (Parens.consumeClose())393    return;394 395  if (T.isInvalid())396    return;397 398  if (T.isUsable())399    Attrs.addNewTypeAttr(400        &AttrName, SourceRange(AttrNameLoc, Parens.getCloseLocation()),401        AttributeScopeInfo(ScopeName, ScopeLoc), T.get(), Form);402  else403    Attrs.addNew(&AttrName, SourceRange(AttrNameLoc, Parens.getCloseLocation()),404                 AttributeScopeInfo(ScopeName, ScopeLoc), nullptr, 0, Form);405}406 407ExprResult408Parser::ParseUnevaluatedStringInAttribute(const IdentifierInfo &AttrName) {409  if (Tok.is(tok::l_paren)) {410    BalancedDelimiterTracker Paren(*this, tok::l_paren);411    Paren.consumeOpen();412    ExprResult Res = ParseUnevaluatedStringInAttribute(AttrName);413    Paren.consumeClose();414    return Res;415  }416  if (!isTokenStringLiteral()) {417    Diag(Tok.getLocation(), diag::err_expected_string_literal)418        << /*in attribute...*/ 4 << AttrName.getName();419    return ExprError();420  }421  return ParseUnevaluatedStringLiteralExpression();422}423 424bool Parser::ParseAttributeArgumentList(425    const IdentifierInfo &AttrName, SmallVectorImpl<Expr *> &Exprs,426    ParsedAttributeArgumentsProperties ArgsProperties) {427  bool SawError = false;428  unsigned Arg = 0;429  while (true) {430    ExprResult Expr;431    if (ArgsProperties.isStringLiteralArg(Arg)) {432      Expr = ParseUnevaluatedStringInAttribute(AttrName);433    } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {434      Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);435      Expr = ParseBraceInitializer();436    } else {437      Expr = ParseAssignmentExpression();438    }439 440    if (Tok.is(tok::ellipsis))441      Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken());442    else if (Tok.is(tok::code_completion)) {443      // There's nothing to suggest in here as we parsed a full expression.444      // Instead fail and propagate the error since caller might have something445      // the suggest, e.g. signature help in function call. Note that this is446      // performed before pushing the \p Expr, so that signature help can report447      // current argument correctly.448      SawError = true;449      cutOffParsing();450      break;451    }452 453    if (Expr.isInvalid()) {454      SawError = true;455      break;456    }457 458    if (Actions.DiagnoseUnexpandedParameterPack(Expr.get())) {459      SawError = true;460      break;461    }462 463    Exprs.push_back(Expr.get());464 465    if (Tok.isNot(tok::comma))466      break;467    // Move to the next argument, remember where the comma was.468    Token Comma = Tok;469    ConsumeToken();470    checkPotentialAngleBracketDelimiter(Comma);471    Arg++;472  }473 474  return SawError;475}476 477unsigned Parser::ParseAttributeArgsCommon(478    IdentifierInfo *AttrName, SourceLocation AttrNameLoc,479    ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,480    SourceLocation ScopeLoc, ParsedAttr::Form Form) {481  // Ignore the left paren location for now.482  ConsumeParen();483 484  bool ChangeKWThisToIdent = attributeTreatsKeywordThisAsIdentifier(485      *AttrName, Form.getSyntax(), ScopeName);486  bool AttributeIsTypeArgAttr =487      attributeIsTypeArgAttr(*AttrName, Form.getSyntax(), ScopeName);488  bool AttributeHasVariadicIdentifierArg =489      attributeHasVariadicIdentifierArg(*AttrName, Form.getSyntax(), ScopeName);490 491  // Interpret "kw_this" as an identifier if the attributed requests it.492  if (ChangeKWThisToIdent && Tok.is(tok::kw_this))493    Tok.setKind(tok::identifier);494 495  ArgsVector ArgExprs;496  if (Tok.is(tok::identifier)) {497    // If this attribute wants an 'identifier' argument, make it so.498    bool IsIdentifierArg =499        AttributeHasVariadicIdentifierArg ||500        attributeHasIdentifierArg(getTargetInfo().getTriple(), *AttrName,501                                  Form.getSyntax(), ScopeName);502    ParsedAttr::Kind AttrKind =503        ParsedAttr::getParsedKind(AttrName, ScopeName, Form.getSyntax());504 505    // If we don't know how to parse this attribute, but this is the only506    // token in this argument, assume it's meant to be an identifier.507    if (AttrKind == ParsedAttr::UnknownAttribute ||508        AttrKind == ParsedAttr::IgnoredAttribute) {509      const Token &Next = NextToken();510      IsIdentifierArg = Next.isOneOf(tok::r_paren, tok::comma);511    }512 513    if (IsIdentifierArg)514      ArgExprs.push_back(ParseIdentifierLoc());515  }516 517  ParsedType TheParsedType;518  if (!ArgExprs.empty() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren)) {519    // Eat the comma.520    if (!ArgExprs.empty())521      ConsumeToken();522 523    if (AttributeIsTypeArgAttr) {524      // FIXME: Multiple type arguments are not implemented.525      TypeResult T = ParseTypeName();526      if (T.isInvalid()) {527        SkipUntil(tok::r_paren, StopAtSemi);528        return 0;529      }530      if (T.isUsable())531        TheParsedType = T.get();532    } else if (AttributeHasVariadicIdentifierArg ||533               attributeHasStrictIdentifierArgs(*AttrName, Form.getSyntax(),534                                                ScopeName)) {535      // Parse variadic identifier arg. This can either consume identifiers or536      // expressions. Variadic identifier args do not support parameter packs537      // because those are typically used for attributes with enumeration538      // arguments, and those enumerations are not something the user could539      // express via a pack.540      do {541        // Interpret "kw_this" as an identifier if the attributed requests it.542        if (ChangeKWThisToIdent && Tok.is(tok::kw_this))543          Tok.setKind(tok::identifier);544 545        ExprResult ArgExpr;546        if (Tok.is(tok::identifier)) {547          ArgExprs.push_back(ParseIdentifierLoc());548        } else {549          bool Uneval = attributeParsedArgsUnevaluated(550              *AttrName, Form.getSyntax(), ScopeName);551          EnterExpressionEvaluationContext Unevaluated(552              Actions,553              Uneval ? Sema::ExpressionEvaluationContext::Unevaluated554                     : Sema::ExpressionEvaluationContext::ConstantEvaluated,555              nullptr,556              Sema::ExpressionEvaluationContextRecord::EK_AttrArgument);557 558          ExprResult ArgExpr = ParseAssignmentExpression();559          if (ArgExpr.isInvalid()) {560            SkipUntil(tok::r_paren, StopAtSemi);561            return 0;562          }563          ArgExprs.push_back(ArgExpr.get());564        }565        // Eat the comma, move to the next argument566      } while (TryConsumeToken(tok::comma));567    } else {568      // General case. Parse all available expressions.569      bool Uneval = attributeParsedArgsUnevaluated(*AttrName, Form.getSyntax(),570                                                   ScopeName);571      EnterExpressionEvaluationContext Unevaluated(572          Actions,573          Uneval ? Sema::ExpressionEvaluationContext::Unevaluated574                 : Sema::ExpressionEvaluationContext::ConstantEvaluated,575          nullptr,576          Sema::ExpressionEvaluationContextRecord::ExpressionKind::577              EK_AttrArgument);578 579      ExprVector ParsedExprs;580      ParsedAttributeArgumentsProperties ArgProperties =581          attributeStringLiteralListArg(getTargetInfo().getTriple(), *AttrName,582                                        Form.getSyntax(), ScopeName);583      if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties)) {584        SkipUntil(tok::r_paren, StopAtSemi);585        return 0;586      }587 588      // Pack expansion must currently be explicitly supported by an attribute.589      for (size_t I = 0; I < ParsedExprs.size(); ++I) {590        if (!isa<PackExpansionExpr>(ParsedExprs[I]))591          continue;592 593        if (!attributeAcceptsExprPack(*AttrName, Form.getSyntax(), ScopeName)) {594          Diag(Tok.getLocation(),595               diag::err_attribute_argument_parm_pack_not_supported)596              << AttrName;597          SkipUntil(tok::r_paren, StopAtSemi);598          return 0;599        }600      }601 602      llvm::append_range(ArgExprs, ParsedExprs);603    }604  }605 606  SourceLocation RParen = Tok.getLocation();607  if (!ExpectAndConsume(tok::r_paren)) {608    SourceLocation AttrLoc = ScopeLoc.isValid() ? ScopeLoc : AttrNameLoc;609 610    if (AttributeIsTypeArgAttr && !TheParsedType.get().isNull()) {611      Attrs.addNewTypeAttr(AttrName, SourceRange(AttrNameLoc, RParen),612                           AttributeScopeInfo(ScopeName, ScopeLoc),613                           TheParsedType, Form);614    } else {615      Attrs.addNew(AttrName, SourceRange(AttrLoc, RParen),616                   AttributeScopeInfo(ScopeName, ScopeLoc), ArgExprs.data(),617                   ArgExprs.size(), Form);618    }619  }620 621  if (EndLoc)622    *EndLoc = RParen;623 624  return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.get().isNull());625}626 627void Parser::ParseGNUAttributeArgs(628    IdentifierInfo *AttrName, SourceLocation AttrNameLoc,629    ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,630    SourceLocation ScopeLoc, ParsedAttr::Form Form, Declarator *D) {631 632  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");633 634  ParsedAttr::Kind AttrKind =635      ParsedAttr::getParsedKind(AttrName, ScopeName, Form.getSyntax());636 637  if (AttrKind == ParsedAttr::AT_Availability) {638    ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,639                               ScopeLoc, Form);640    return;641  } else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {642    ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,643                                       ScopeName, ScopeLoc, Form);644    return;645  } else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {646    ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,647                                    ScopeName, ScopeLoc, Form);648    return;649  } else if (AttrKind == ParsedAttr::AT_SwiftNewType) {650    ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,651                               ScopeLoc, Form);652    return;653  } else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {654    ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,655                                     ScopeName, ScopeLoc, Form);656    return;657  } else if (attributeIsTypeArgAttr(*AttrName, Form.getSyntax(), ScopeName)) {658    ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName,659                              ScopeLoc, Form);660    return;661  } else if (AttrKind == ParsedAttr::AT_CountedBy ||662             AttrKind == ParsedAttr::AT_CountedByOrNull ||663             AttrKind == ParsedAttr::AT_SizedBy ||664             AttrKind == ParsedAttr::AT_SizedByOrNull) {665    ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,666                         Form);667    return;668  } else if (AttrKind == ParsedAttr::AT_CXXAssume) {669    ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,670                               ScopeLoc, EndLoc, Form);671    return;672  }673 674  // These may refer to the function arguments, but need to be parsed early to675  // participate in determining whether it's a redeclaration.676  std::optional<ParseScope> PrototypeScope;677  if (normalizeAttrName(AttrName->getName()) == "enable_if" &&678      D && D->isFunctionDeclarator()) {679    const DeclaratorChunk::FunctionTypeInfo& FTI = D->getFunctionTypeInfo();680    PrototypeScope.emplace(this, Scope::FunctionPrototypeScope |681                                     Scope::FunctionDeclarationScope |682                                     Scope::DeclScope);683    for (unsigned i = 0; i != FTI.NumParams; ++i) {684      ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[i].Param);685      Actions.ActOnReenterCXXMethodParameter(getCurScope(), Param);686    }687  }688 689  ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,690                           ScopeLoc, Form);691}692 693unsigned Parser::ParseClangAttributeArgs(694    IdentifierInfo *AttrName, SourceLocation AttrNameLoc,695    ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,696    SourceLocation ScopeLoc, ParsedAttr::Form Form) {697  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");698 699  ParsedAttr::Kind AttrKind =700      ParsedAttr::getParsedKind(AttrName, ScopeName, Form.getSyntax());701 702  switch (AttrKind) {703  default:704    return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,705                                    ScopeName, ScopeLoc, Form);706  case ParsedAttr::AT_ExternalSourceSymbol:707    ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,708                                       ScopeName, ScopeLoc, Form);709    break;710  case ParsedAttr::AT_Availability:711    ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,712                               ScopeLoc, Form);713    break;714  case ParsedAttr::AT_ObjCBridgeRelated:715    ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,716                                    ScopeName, ScopeLoc, Form);717    break;718  case ParsedAttr::AT_SwiftNewType:719    ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,720                               ScopeLoc, Form);721    break;722  case ParsedAttr::AT_TypeTagForDatatype:723    ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,724                                     ScopeName, ScopeLoc, Form);725    break;726 727  case ParsedAttr::AT_CXXAssume:728    ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,729                               ScopeLoc, EndLoc, Form);730    break;731  }732  return !Attrs.empty() ? Attrs.begin()->getNumArgs() : 0;733}734 735bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,736                                        SourceLocation AttrNameLoc,737                                        ParsedAttributes &Attrs) {738  unsigned ExistingAttrs = Attrs.size();739 740  // If the attribute isn't known, we will not attempt to parse any741  // arguments.742  if (!hasAttribute(AttributeCommonInfo::Syntax::AS_Declspec, nullptr, AttrName,743                    getTargetInfo(), getLangOpts())) {744    // Eat the left paren, then skip to the ending right paren.745    ConsumeParen();746    SkipUntil(tok::r_paren);747    return false;748  }749 750  SourceLocation OpenParenLoc = Tok.getLocation();751 752  if (AttrName->getName() == "property") {753    // The property declspec is more complex in that it can take one or two754    // assignment expressions as a parameter, but the lhs of the assignment755    // must be named get or put.756 757    BalancedDelimiterTracker T(*this, tok::l_paren);758    T.expectAndConsume(diag::err_expected_lparen_after,759                       AttrName->getNameStart(), tok::r_paren);760 761    enum AccessorKind {762      AK_Invalid = -1,763      AK_Put = 0,764      AK_Get = 1 // indices into AccessorNames765    };766    IdentifierInfo *AccessorNames[] = {nullptr, nullptr};767    bool HasInvalidAccessor = false;768 769    // Parse the accessor specifications.770    while (true) {771      // Stop if this doesn't look like an accessor spec.772      if (!Tok.is(tok::identifier)) {773        // If the user wrote a completely empty list, use a special diagnostic.774        if (Tok.is(tok::r_paren) && !HasInvalidAccessor &&775            AccessorNames[AK_Put] == nullptr &&776            AccessorNames[AK_Get] == nullptr) {777          Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);778          break;779        }780 781        Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor);782        break;783      }784 785      AccessorKind Kind;786      SourceLocation KindLoc = Tok.getLocation();787      StringRef KindStr = Tok.getIdentifierInfo()->getName();788      if (KindStr == "get") {789        Kind = AK_Get;790      } else if (KindStr == "put") {791        Kind = AK_Put;792 793        // Recover from the common mistake of using 'set' instead of 'put'.794      } else if (KindStr == "set") {795        Diag(KindLoc, diag::err_ms_property_has_set_accessor)796            << FixItHint::CreateReplacement(KindLoc, "put");797        Kind = AK_Put;798 799        // Handle the mistake of forgetting the accessor kind by skipping800        // this accessor.801      } else if (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)) {802        Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);803        ConsumeToken();804        HasInvalidAccessor = true;805        goto next_property_accessor;806 807        // Otherwise, complain about the unknown accessor kind.808      } else {809        Diag(KindLoc, diag::err_ms_property_unknown_accessor);810        HasInvalidAccessor = true;811        Kind = AK_Invalid;812 813        // Try to keep parsing unless it doesn't look like an accessor spec.814        if (!NextToken().is(tok::equal))815          break;816      }817 818      // Consume the identifier.819      ConsumeToken();820 821      // Consume the '='.822      if (!TryConsumeToken(tok::equal)) {823        Diag(Tok.getLocation(), diag::err_ms_property_expected_equal)824            << KindStr;825        break;826      }827 828      // Expect the method name.829      if (!Tok.is(tok::identifier)) {830        Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name);831        break;832      }833 834      if (Kind == AK_Invalid) {835        // Just drop invalid accessors.836      } else if (AccessorNames[Kind] != nullptr) {837        // Complain about the repeated accessor, ignore it, and keep parsing.838        Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;839      } else {840        AccessorNames[Kind] = Tok.getIdentifierInfo();841      }842      ConsumeToken();843 844    next_property_accessor:845      // Keep processing accessors until we run out.846      if (TryConsumeToken(tok::comma))847        continue;848 849      // If we run into the ')', stop without consuming it.850      if (Tok.is(tok::r_paren))851        break;852 853      Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen);854      break;855    }856 857    // Only add the property attribute if it was well-formed.858    if (!HasInvalidAccessor)859      Attrs.addNewPropertyAttr(AttrName, AttrNameLoc, AttributeScopeInfo(),860                               AccessorNames[AK_Get], AccessorNames[AK_Put],861                               ParsedAttr::Form::Declspec());862    T.skipToEnd();863    return !HasInvalidAccessor;864  }865 866  unsigned NumArgs =867      ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, nullptr, nullptr,868                               SourceLocation(), ParsedAttr::Form::Declspec());869 870  // If this attribute's args were parsed, and it was expected to have871  // arguments but none were provided, emit a diagnostic.872  if (ExistingAttrs < Attrs.size() && Attrs.back().getMaxArgs() && !NumArgs) {873    Diag(OpenParenLoc, diag::err_attribute_requires_arguments) << AttrName;874    return false;875  }876  return true;877}878 879void Parser::ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs) {880  assert(getLangOpts().DeclSpecKeyword && "__declspec keyword is not enabled");881  assert(Tok.is(tok::kw___declspec) && "Not a declspec!");882 883  SourceLocation StartLoc = Tok.getLocation();884  SourceLocation EndLoc = StartLoc;885 886  while (Tok.is(tok::kw___declspec)) {887    ConsumeToken();888    BalancedDelimiterTracker T(*this, tok::l_paren);889    if (T.expectAndConsume(diag::err_expected_lparen_after, "__declspec",890                           tok::r_paren))891      return;892 893    // An empty declspec is perfectly legal and should not warn.  Additionally,894    // you can specify multiple attributes per declspec.895    while (Tok.isNot(tok::r_paren)) {896      // Attribute not present.897      if (TryConsumeToken(tok::comma))898        continue;899 900      if (Tok.is(tok::code_completion)) {901        cutOffParsing();902        Actions.CodeCompletion().CodeCompleteAttribute(903            AttributeCommonInfo::AS_Declspec);904        return;905      }906 907      // We expect either a well-known identifier or a generic string.  Anything908      // else is a malformed declspec.909      bool IsString = Tok.getKind() == tok::string_literal;910      if (!IsString && Tok.getKind() != tok::identifier &&911          Tok.getKind() != tok::kw_restrict) {912        Diag(Tok, diag::err_ms_declspec_type);913        T.skipToEnd();914        return;915      }916 917      IdentifierInfo *AttrName;918      SourceLocation AttrNameLoc;919      if (IsString) {920        SmallString<8> StrBuffer;921        bool Invalid = false;922        StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);923        if (Invalid) {924          T.skipToEnd();925          return;926        }927        AttrName = PP.getIdentifierInfo(Str);928        AttrNameLoc = ConsumeStringToken();929      } else {930        AttrName = Tok.getIdentifierInfo();931        AttrNameLoc = ConsumeToken();932      }933 934      bool AttrHandled = false;935 936      // Parse attribute arguments.937      if (Tok.is(tok::l_paren))938        AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);939      else if (AttrName->getName() == "property")940        // The property attribute must have an argument list.941        Diag(Tok.getLocation(), diag::err_expected_lparen_after)942            << AttrName->getName();943 944      if (!AttrHandled)945        Attrs.addNew(AttrName, AttrNameLoc, AttributeScopeInfo(), nullptr, 0,946                     ParsedAttr::Form::Declspec());947    }948    T.consumeClose();949    EndLoc = T.getCloseLocation();950  }951 952  Attrs.Range = SourceRange(StartLoc, EndLoc);953}954 955void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {956  // Treat these like attributes957  while (true) {958    auto Kind = Tok.getKind();959    switch (Kind) {960    case tok::kw___fastcall:961    case tok::kw___stdcall:962    case tok::kw___thiscall:963    case tok::kw___regcall:964    case tok::kw___cdecl:965    case tok::kw___vectorcall:966    case tok::kw___ptr64:967    case tok::kw___w64:968    case tok::kw___ptr32:969    case tok::kw___sptr:970    case tok::kw___uptr: {971      IdentifierInfo *AttrName = Tok.getIdentifierInfo();972      SourceLocation AttrNameLoc = ConsumeToken();973      attrs.addNew(AttrName, AttrNameLoc, AttributeScopeInfo(), nullptr, 0,974                   Kind);975      break;976    }977    default:978      return;979    }980  }981}982 983void Parser::ParseWebAssemblyFuncrefTypeAttribute(ParsedAttributes &attrs) {984  assert(Tok.is(tok::kw___funcref));985  SourceLocation StartLoc = Tok.getLocation();986  if (!getTargetInfo().getTriple().isWasm()) {987    ConsumeToken();988    Diag(StartLoc, diag::err_wasm_funcref_not_wasm);989    return;990  }991 992  IdentifierInfo *AttrName = Tok.getIdentifierInfo();993  SourceLocation AttrNameLoc = ConsumeToken();994  attrs.addNew(AttrName, AttrNameLoc, AttributeScopeInfo(), /*Args=*/nullptr,995               /*numArgs=*/0, tok::kw___funcref);996}997 998void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {999  SourceLocation StartLoc = Tok.getLocation();1000  SourceLocation EndLoc = SkipExtendedMicrosoftTypeAttributes();1001 1002  if (EndLoc.isValid()) {1003    SourceRange Range(StartLoc, EndLoc);1004    Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) << Range;1005  }1006}1007 1008SourceLocation Parser::SkipExtendedMicrosoftTypeAttributes() {1009  SourceLocation EndLoc;1010 1011  while (true) {1012    switch (Tok.getKind()) {1013    case tok::kw_const:1014    case tok::kw_volatile:1015    case tok::kw___fastcall:1016    case tok::kw___stdcall:1017    case tok::kw___thiscall:1018    case tok::kw___cdecl:1019    case tok::kw___vectorcall:1020    case tok::kw___ptr32:1021    case tok::kw___ptr64:1022    case tok::kw___w64:1023    case tok::kw___unaligned:1024    case tok::kw___sptr:1025    case tok::kw___uptr:1026      EndLoc = ConsumeToken();1027      break;1028    default:1029      return EndLoc;1030    }1031  }1032}1033 1034void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {1035  // Treat these like attributes1036  while (Tok.is(tok::kw___pascal)) {1037    IdentifierInfo *AttrName = Tok.getIdentifierInfo();1038    SourceLocation AttrNameLoc = ConsumeToken();1039    attrs.addNew(AttrName, AttrNameLoc, AttributeScopeInfo(), nullptr, 0,1040                 tok::kw___pascal);1041  }1042}1043 1044void Parser::ParseOpenCLKernelAttributes(ParsedAttributes &attrs) {1045  // Treat these like attributes1046  while (Tok.is(tok::kw___kernel)) {1047    IdentifierInfo *AttrName = Tok.getIdentifierInfo();1048    SourceLocation AttrNameLoc = ConsumeToken();1049    attrs.addNew(AttrName, AttrNameLoc, AttributeScopeInfo(), nullptr, 0,1050                 tok::kw___kernel);1051  }1052}1053 1054void Parser::ParseCUDAFunctionAttributes(ParsedAttributes &attrs) {1055  while (Tok.is(tok::kw___noinline__)) {1056    IdentifierInfo *AttrName = Tok.getIdentifierInfo();1057    SourceLocation AttrNameLoc = ConsumeToken();1058    attrs.addNew(AttrName, AttrNameLoc, AttributeScopeInfo(), nullptr, 0,1059                 tok::kw___noinline__);1060  }1061}1062 1063void Parser::ParseOpenCLQualifiers(ParsedAttributes &Attrs) {1064  IdentifierInfo *AttrName = Tok.getIdentifierInfo();1065  SourceLocation AttrNameLoc = Tok.getLocation();1066  Attrs.addNew(AttrName, AttrNameLoc, AttributeScopeInfo(), nullptr, 0,1067               Tok.getKind());1068}1069 1070bool Parser::isHLSLQualifier(const Token &Tok) const {1071  return Tok.is(tok::kw_groupshared);1072}1073 1074void Parser::ParseHLSLQualifiers(ParsedAttributes &Attrs) {1075  IdentifierInfo *AttrName = Tok.getIdentifierInfo();1076  auto Kind = Tok.getKind();1077  SourceLocation AttrNameLoc = ConsumeToken();1078  Attrs.addNew(AttrName, AttrNameLoc, AttributeScopeInfo(), nullptr, 0, Kind);1079}1080 1081void Parser::ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs) {1082  // Treat these like attributes, even though they're type specifiers.1083  while (true) {1084    auto Kind = Tok.getKind();1085    switch (Kind) {1086    case tok::kw__Nonnull:1087    case tok::kw__Nullable:1088    case tok::kw__Nullable_result:1089    case tok::kw__Null_unspecified: {1090      IdentifierInfo *AttrName = Tok.getIdentifierInfo();1091      SourceLocation AttrNameLoc = ConsumeToken();1092      if (!getLangOpts().ObjC)1093        Diag(AttrNameLoc, diag::ext_nullability)1094          << AttrName;1095      attrs.addNew(AttrName, AttrNameLoc, AttributeScopeInfo(), nullptr, 0,1096                   Kind);1097      break;1098    }1099    default:1100      return;1101    }1102  }1103}1104 1105static bool VersionNumberSeparator(const char Separator) {1106  return (Separator == '.' || Separator == '_');1107}1108 1109VersionTuple Parser::ParseVersionTuple(SourceRange &Range) {1110  Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());1111 1112  if (!Tok.is(tok::numeric_constant)) {1113    Diag(Tok, diag::err_expected_version);1114    SkipUntil(tok::comma, tok::r_paren,1115              StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);1116    return VersionTuple();1117  }1118 1119  // Parse the major (and possibly minor and subminor) versions, which1120  // are stored in the numeric constant. We utilize a quirk of the1121  // lexer, which is that it handles something like 1.2.3 as a single1122  // numeric constant, rather than two separate tokens.1123  SmallString<512> Buffer;1124  Buffer.resize(Tok.getLength()+1);1125  const char *ThisTokBegin = &Buffer[0];1126 1127  // Get the spelling of the token, which eliminates trigraphs, etc.1128  bool Invalid = false;1129  unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);1130  if (Invalid)1131    return VersionTuple();1132 1133  // Parse the major version.1134  unsigned AfterMajor = 0;1135  unsigned Major = 0;1136  while (AfterMajor < ActualLength && isDigit(ThisTokBegin[AfterMajor])) {1137    Major = Major * 10 + ThisTokBegin[AfterMajor] - '0';1138    ++AfterMajor;1139  }1140 1141  if (AfterMajor == 0) {1142    Diag(Tok, diag::err_expected_version);1143    SkipUntil(tok::comma, tok::r_paren,1144              StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);1145    return VersionTuple();1146  }1147 1148  if (AfterMajor == ActualLength) {1149    ConsumeToken();1150 1151    // We only had a single version component.1152    if (Major == 0) {1153      Diag(Tok, diag::err_zero_version);1154      return VersionTuple();1155    }1156 1157    return VersionTuple(Major);1158  }1159 1160  const char AfterMajorSeparator = ThisTokBegin[AfterMajor];1161  if (!VersionNumberSeparator(AfterMajorSeparator)1162      || (AfterMajor + 1 == ActualLength)) {1163    Diag(Tok, diag::err_expected_version);1164    SkipUntil(tok::comma, tok::r_paren,1165              StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);1166    return VersionTuple();1167  }1168 1169  // Parse the minor version.1170  unsigned AfterMinor = AfterMajor + 1;1171  unsigned Minor = 0;1172  while (AfterMinor < ActualLength && isDigit(ThisTokBegin[AfterMinor])) {1173    Minor = Minor * 10 + ThisTokBegin[AfterMinor] - '0';1174    ++AfterMinor;1175  }1176 1177  if (AfterMinor == ActualLength) {1178    ConsumeToken();1179 1180    // We had major.minor.1181    if (Major == 0 && Minor == 0) {1182      Diag(Tok, diag::err_zero_version);1183      return VersionTuple();1184    }1185 1186    return VersionTuple(Major, Minor);1187  }1188 1189  const char AfterMinorSeparator = ThisTokBegin[AfterMinor];1190  // If what follows is not a '.' or '_', we have a problem.1191  if (!VersionNumberSeparator(AfterMinorSeparator)) {1192    Diag(Tok, diag::err_expected_version);1193    SkipUntil(tok::comma, tok::r_paren,1194              StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);1195    return VersionTuple();1196  }1197 1198  // Warn if separators, be it '.' or '_', do not match.1199  if (AfterMajorSeparator != AfterMinorSeparator)1200    Diag(Tok, diag::warn_expected_consistent_version_separator);1201 1202  // Parse the subminor version.1203  unsigned AfterSubminor = AfterMinor + 1;1204  unsigned Subminor = 0;1205  while (AfterSubminor < ActualLength && isDigit(ThisTokBegin[AfterSubminor])) {1206    Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] - '0';1207    ++AfterSubminor;1208  }1209 1210  if (AfterSubminor != ActualLength) {1211    Diag(Tok, diag::err_expected_version);1212    SkipUntil(tok::comma, tok::r_paren,1213              StopAtSemi | StopBeforeMatch | StopAtCodeCompletion);1214    return VersionTuple();1215  }1216  ConsumeToken();1217  return VersionTuple(Major, Minor, Subminor);1218}1219 1220void Parser::ParseAvailabilityAttribute(1221    IdentifierInfo &Availability, SourceLocation AvailabilityLoc,1222    ParsedAttributes &attrs, SourceLocation *endLoc, IdentifierInfo *ScopeName,1223    SourceLocation ScopeLoc, ParsedAttr::Form Form) {1224  enum { Introduced, Deprecated, Obsoleted, Unknown };1225  AvailabilityChange Changes[Unknown];1226  ExprResult MessageExpr, ReplacementExpr;1227  IdentifierLoc *EnvironmentLoc = nullptr;1228 1229  // Opening '('.1230  BalancedDelimiterTracker T(*this, tok::l_paren);1231  if (T.consumeOpen()) {1232    Diag(Tok, diag::err_expected) << tok::l_paren;1233    return;1234  }1235 1236  // Parse the platform name.1237  if (Tok.isNot(tok::identifier)) {1238    Diag(Tok, diag::err_availability_expected_platform);1239    SkipUntil(tok::r_paren, StopAtSemi);1240    return;1241  }1242  IdentifierLoc *Platform = ParseIdentifierLoc();1243  if (const IdentifierInfo *const Ident = Platform->getIdentifierInfo()) {1244    // Disallow xrOS for availability attributes.1245    if (Ident->getName().contains("xrOS") || Ident->getName().contains("xros"))1246      Diag(Platform->getLoc(), diag::warn_availability_unknown_platform)1247          << Ident;1248    // Canonicalize platform name from "macosx" to "macos".1249    else if (Ident->getName() == "macosx")1250      Platform->setIdentifierInfo(PP.getIdentifierInfo("macos"));1251    // Canonicalize platform name from "macosx_app_extension" to1252    // "macos_app_extension".1253    else if (Ident->getName() == "macosx_app_extension")1254      Platform->setIdentifierInfo(PP.getIdentifierInfo("macos_app_extension"));1255    else1256      Platform->setIdentifierInfo(PP.getIdentifierInfo(1257          AvailabilityAttr::canonicalizePlatformName(Ident->getName())));1258  }1259 1260  // Parse the ',' following the platform name.1261  if (ExpectAndConsume(tok::comma)) {1262    SkipUntil(tok::r_paren, StopAtSemi);1263    return;1264  }1265 1266  // If we haven't grabbed the pointers for the identifiers1267  // "introduced", "deprecated", and "obsoleted", do so now.1268  if (!Ident_introduced) {1269    Ident_introduced = PP.getIdentifierInfo("introduced");1270    Ident_deprecated = PP.getIdentifierInfo("deprecated");1271    Ident_obsoleted = PP.getIdentifierInfo("obsoleted");1272    Ident_unavailable = PP.getIdentifierInfo("unavailable");1273    Ident_message = PP.getIdentifierInfo("message");1274    Ident_strict = PP.getIdentifierInfo("strict");1275    Ident_replacement = PP.getIdentifierInfo("replacement");1276    Ident_environment = PP.getIdentifierInfo("environment");1277  }1278 1279  // Parse the optional "strict", the optional "replacement" and the set of1280  // introductions/deprecations/removals.1281  SourceLocation UnavailableLoc, StrictLoc;1282  do {1283    if (Tok.isNot(tok::identifier)) {1284      Diag(Tok, diag::err_availability_expected_change);1285      SkipUntil(tok::r_paren, StopAtSemi);1286      return;1287    }1288    IdentifierInfo *Keyword = Tok.getIdentifierInfo();1289    SourceLocation KeywordLoc = ConsumeToken();1290 1291    if (Keyword == Ident_strict) {1292      if (StrictLoc.isValid()) {1293        Diag(KeywordLoc, diag::err_availability_redundant)1294          << Keyword << SourceRange(StrictLoc);1295      }1296      StrictLoc = KeywordLoc;1297      continue;1298    }1299 1300    if (Keyword == Ident_unavailable) {1301      if (UnavailableLoc.isValid()) {1302        Diag(KeywordLoc, diag::err_availability_redundant)1303          << Keyword << SourceRange(UnavailableLoc);1304      }1305      UnavailableLoc = KeywordLoc;1306      continue;1307    }1308 1309    if (Keyword == Ident_deprecated && Platform->getIdentifierInfo() &&1310        Platform->getIdentifierInfo()->isStr("swift")) {1311      // For swift, we deprecate for all versions.1312      if (Changes[Deprecated].KeywordLoc.isValid()) {1313        Diag(KeywordLoc, diag::err_availability_redundant)1314          << Keyword1315          << SourceRange(Changes[Deprecated].KeywordLoc);1316      }1317 1318      Changes[Deprecated].KeywordLoc = KeywordLoc;1319      // Use a fake version here.1320      Changes[Deprecated].Version = VersionTuple(1);1321      continue;1322    }1323 1324    if (Keyword == Ident_environment) {1325      if (EnvironmentLoc != nullptr) {1326        Diag(KeywordLoc, diag::err_availability_redundant)1327            << Keyword << SourceRange(EnvironmentLoc->getLoc());1328      }1329    }1330 1331    if (Tok.isNot(tok::equal)) {1332      Diag(Tok, diag::err_expected_after) << Keyword << tok::equal;1333      SkipUntil(tok::r_paren, StopAtSemi);1334      return;1335    }1336    ConsumeToken();1337    if (Keyword == Ident_message || Keyword == Ident_replacement) {1338      if (!isTokenStringLiteral()) {1339        Diag(Tok, diag::err_expected_string_literal)1340          << /*Source='availability attribute'*/2;1341        SkipUntil(tok::r_paren, StopAtSemi);1342        return;1343      }1344      if (Keyword == Ident_message) {1345        MessageExpr = ParseUnevaluatedStringLiteralExpression();1346        break;1347      } else {1348        ReplacementExpr = ParseUnevaluatedStringLiteralExpression();1349        continue;1350      }1351    }1352    if (Keyword == Ident_environment) {1353      if (Tok.isNot(tok::identifier)) {1354        Diag(Tok, diag::err_availability_expected_environment);1355        SkipUntil(tok::r_paren, StopAtSemi);1356        return;1357      }1358      EnvironmentLoc = ParseIdentifierLoc();1359      continue;1360    }1361 1362    // Special handling of 'NA' only when applied to introduced or1363    // deprecated.1364    if ((Keyword == Ident_introduced || Keyword == Ident_deprecated) &&1365        Tok.is(tok::identifier)) {1366      IdentifierInfo *NA = Tok.getIdentifierInfo();1367      if (NA->getName() == "NA") {1368        ConsumeToken();1369        if (Keyword == Ident_introduced)1370          UnavailableLoc = KeywordLoc;1371        continue;1372      }1373    }1374 1375    SourceRange VersionRange;1376    VersionTuple Version = ParseVersionTuple(VersionRange);1377 1378    if (Version.empty()) {1379      SkipUntil(tok::r_paren, StopAtSemi);1380      return;1381    }1382 1383    unsigned Index;1384    if (Keyword == Ident_introduced)1385      Index = Introduced;1386    else if (Keyword == Ident_deprecated)1387      Index = Deprecated;1388    else if (Keyword == Ident_obsoleted)1389      Index = Obsoleted;1390    else1391      Index = Unknown;1392 1393    if (Index < Unknown) {1394      if (!Changes[Index].KeywordLoc.isInvalid()) {1395        Diag(KeywordLoc, diag::err_availability_redundant)1396          << Keyword1397          << SourceRange(Changes[Index].KeywordLoc,1398                         Changes[Index].VersionRange.getEnd());1399      }1400 1401      Changes[Index].KeywordLoc = KeywordLoc;1402      Changes[Index].Version = Version;1403      Changes[Index].VersionRange = VersionRange;1404    } else {1405      Diag(KeywordLoc, diag::err_availability_unknown_change)1406        << Keyword << VersionRange;1407    }1408 1409  } while (TryConsumeToken(tok::comma));1410 1411  // Closing ')'.1412  if (T.consumeClose())1413    return;1414 1415  if (endLoc)1416    *endLoc = T.getCloseLocation();1417 1418  // The 'unavailable' availability cannot be combined with any other1419  // availability changes. Make sure that hasn't happened.1420  if (UnavailableLoc.isValid()) {1421    bool Complained = false;1422    for (unsigned Index = Introduced; Index != Unknown; ++Index) {1423      if (Changes[Index].KeywordLoc.isValid()) {1424        if (!Complained) {1425          Diag(UnavailableLoc, diag::warn_availability_and_unavailable)1426            << SourceRange(Changes[Index].KeywordLoc,1427                           Changes[Index].VersionRange.getEnd());1428          Complained = true;1429        }1430 1431        // Clear out the availability.1432        Changes[Index] = AvailabilityChange();1433      }1434    }1435  }1436 1437  // Record this attribute1438  attrs.addNew(&Availability,1439               SourceRange(AvailabilityLoc, T.getCloseLocation()),1440               AttributeScopeInfo(ScopeName, ScopeLoc), Platform,1441               Changes[Introduced], Changes[Deprecated], Changes[Obsoleted],1442               UnavailableLoc, MessageExpr.get(), Form, StrictLoc,1443               ReplacementExpr.get(), EnvironmentLoc);1444}1445 1446void Parser::ParseExternalSourceSymbolAttribute(1447    IdentifierInfo &ExternalSourceSymbol, SourceLocation Loc,1448    ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,1449    SourceLocation ScopeLoc, ParsedAttr::Form Form) {1450  // Opening '('.1451  BalancedDelimiterTracker T(*this, tok::l_paren);1452  if (T.expectAndConsume())1453    return;1454 1455  // Initialize the pointers for the keyword identifiers when required.1456  if (!Ident_language) {1457    Ident_language = PP.getIdentifierInfo("language");1458    Ident_defined_in = PP.getIdentifierInfo("defined_in");1459    Ident_generated_declaration = PP.getIdentifierInfo("generated_declaration");1460    Ident_USR = PP.getIdentifierInfo("USR");1461  }1462 1463  ExprResult Language;1464  bool HasLanguage = false;1465  ExprResult DefinedInExpr;1466  bool HasDefinedIn = false;1467  IdentifierLoc *GeneratedDeclaration = nullptr;1468  ExprResult USR;1469  bool HasUSR = false;1470 1471  // Parse the language/defined_in/generated_declaration keywords1472  do {1473    if (Tok.isNot(tok::identifier)) {1474      Diag(Tok, diag::err_external_source_symbol_expected_keyword);1475      SkipUntil(tok::r_paren, StopAtSemi);1476      return;1477    }1478 1479    SourceLocation KeywordLoc = Tok.getLocation();1480    IdentifierInfo *Keyword = Tok.getIdentifierInfo();1481    if (Keyword == Ident_generated_declaration) {1482      if (GeneratedDeclaration) {1483        Diag(Tok, diag::err_external_source_symbol_duplicate_clause) << Keyword;1484        SkipUntil(tok::r_paren, StopAtSemi);1485        return;1486      }1487      GeneratedDeclaration = ParseIdentifierLoc();1488      continue;1489    }1490 1491    if (Keyword != Ident_language && Keyword != Ident_defined_in &&1492        Keyword != Ident_USR) {1493      Diag(Tok, diag::err_external_source_symbol_expected_keyword);1494      SkipUntil(tok::r_paren, StopAtSemi);1495      return;1496    }1497 1498    ConsumeToken();1499    if (ExpectAndConsume(tok::equal, diag::err_expected_after,1500                         Keyword->getName())) {1501      SkipUntil(tok::r_paren, StopAtSemi);1502      return;1503    }1504 1505    bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,1506         HadUSR = HasUSR;1507    if (Keyword == Ident_language)1508      HasLanguage = true;1509    else if (Keyword == Ident_USR)1510      HasUSR = true;1511    else1512      HasDefinedIn = true;1513 1514    if (!isTokenStringLiteral()) {1515      Diag(Tok, diag::err_expected_string_literal)1516          << /*Source='external_source_symbol attribute'*/ 31517          << /*language | source container | USR*/ (1518                 Keyword == Ident_language1519                     ? 01520                     : (Keyword == Ident_defined_in ? 1 : 2));1521      SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch);1522      continue;1523    }1524    if (Keyword == Ident_language) {1525      if (HadLanguage) {1526        Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)1527            << Keyword;1528        ParseUnevaluatedStringLiteralExpression();1529        continue;1530      }1531      Language = ParseUnevaluatedStringLiteralExpression();1532    } else if (Keyword == Ident_USR) {1533      if (HadUSR) {1534        Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)1535            << Keyword;1536        ParseUnevaluatedStringLiteralExpression();1537        continue;1538      }1539      USR = ParseUnevaluatedStringLiteralExpression();1540    } else {1541      assert(Keyword == Ident_defined_in && "Invalid clause keyword!");1542      if (HadDefinedIn) {1543        Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)1544            << Keyword;1545        ParseUnevaluatedStringLiteralExpression();1546        continue;1547      }1548      DefinedInExpr = ParseUnevaluatedStringLiteralExpression();1549    }1550  } while (TryConsumeToken(tok::comma));1551 1552  // Closing ')'.1553  if (T.consumeClose())1554    return;1555  if (EndLoc)1556    *EndLoc = T.getCloseLocation();1557 1558  ArgsUnion Args[] = {Language.get(), DefinedInExpr.get(), GeneratedDeclaration,1559                      USR.get()};1560  Attrs.addNew(&ExternalSourceSymbol, SourceRange(Loc, T.getCloseLocation()),1561               AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),1562               Form);1563}1564 1565void Parser::ParseObjCBridgeRelatedAttribute(1566    IdentifierInfo &ObjCBridgeRelated, SourceLocation ObjCBridgeRelatedLoc,1567    ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,1568    SourceLocation ScopeLoc, ParsedAttr::Form Form) {1569  // Opening '('.1570  BalancedDelimiterTracker T(*this, tok::l_paren);1571  if (T.consumeOpen()) {1572    Diag(Tok, diag::err_expected) << tok::l_paren;1573    return;1574  }1575 1576  // Parse the related class name.1577  if (Tok.isNot(tok::identifier)) {1578    Diag(Tok, diag::err_objcbridge_related_expected_related_class);1579    SkipUntil(tok::r_paren, StopAtSemi);1580    return;1581  }1582  IdentifierLoc *RelatedClass = ParseIdentifierLoc();1583  if (ExpectAndConsume(tok::comma)) {1584    SkipUntil(tok::r_paren, StopAtSemi);1585    return;1586  }1587 1588  // Parse class method name.  It's non-optional in the sense that a trailing1589  // comma is required, but it can be the empty string, and then we record a1590  // nullptr.1591  IdentifierLoc *ClassMethod = nullptr;1592  if (Tok.is(tok::identifier)) {1593    ClassMethod = ParseIdentifierLoc();1594    if (!TryConsumeToken(tok::colon)) {1595      Diag(Tok, diag::err_objcbridge_related_selector_name);1596      SkipUntil(tok::r_paren, StopAtSemi);1597      return;1598    }1599  }1600  if (!TryConsumeToken(tok::comma)) {1601    if (Tok.is(tok::colon))1602      Diag(Tok, diag::err_objcbridge_related_selector_name);1603    else1604      Diag(Tok, diag::err_expected) << tok::comma;1605    SkipUntil(tok::r_paren, StopAtSemi);1606    return;1607  }1608 1609  // Parse instance method name.  Also non-optional but empty string is1610  // permitted.1611  IdentifierLoc *InstanceMethod = nullptr;1612  if (Tok.is(tok::identifier))1613    InstanceMethod = ParseIdentifierLoc();1614  else if (Tok.isNot(tok::r_paren)) {1615    Diag(Tok, diag::err_expected) << tok::r_paren;1616    SkipUntil(tok::r_paren, StopAtSemi);1617    return;1618  }1619 1620  // Closing ')'.1621  if (T.consumeClose())1622    return;1623 1624  if (EndLoc)1625    *EndLoc = T.getCloseLocation();1626 1627  // Record this attribute1628  Attrs.addNew(&ObjCBridgeRelated,1629               SourceRange(ObjCBridgeRelatedLoc, T.getCloseLocation()),1630               AttributeScopeInfo(ScopeName, ScopeLoc), RelatedClass,1631               ClassMethod, InstanceMethod, Form);1632}1633 1634void Parser::ParseSwiftNewTypeAttribute(1635    IdentifierInfo &AttrName, SourceLocation AttrNameLoc,1636    ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,1637    SourceLocation ScopeLoc, ParsedAttr::Form Form) {1638  BalancedDelimiterTracker T(*this, tok::l_paren);1639 1640  // Opening '('1641  if (T.consumeOpen()) {1642    Diag(Tok, diag::err_expected) << tok::l_paren;1643    return;1644  }1645 1646  if (Tok.is(tok::r_paren)) {1647    Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);1648    T.consumeClose();1649    return;1650  }1651  if (Tok.isNot(tok::kw_struct) && Tok.isNot(tok::kw_enum)) {1652    Diag(Tok, diag::warn_attribute_type_not_supported)1653        << &AttrName << Tok.getIdentifierInfo();1654    if (!isTokenSpecial())1655      ConsumeToken();1656    T.consumeClose();1657    return;1658  }1659 1660  auto *SwiftType = new (Actions.Context)1661      IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());1662  ConsumeToken();1663 1664  // Closing ')'1665  if (T.consumeClose())1666    return;1667  if (EndLoc)1668    *EndLoc = T.getCloseLocation();1669 1670  ArgsUnion Args[] = {SwiftType};1671  Attrs.addNew(&AttrName, SourceRange(AttrNameLoc, T.getCloseLocation()),1672               AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),1673               Form);1674}1675 1676void Parser::ParseTypeTagForDatatypeAttribute(1677    IdentifierInfo &AttrName, SourceLocation AttrNameLoc,1678    ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,1679    SourceLocation ScopeLoc, ParsedAttr::Form Form) {1680  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");1681 1682  BalancedDelimiterTracker T(*this, tok::l_paren);1683  T.consumeOpen();1684 1685  if (Tok.isNot(tok::identifier)) {1686    Diag(Tok, diag::err_expected) << tok::identifier;1687    T.skipToEnd();1688    return;1689  }1690  IdentifierLoc *ArgumentKind = ParseIdentifierLoc();1691 1692  if (ExpectAndConsume(tok::comma)) {1693    T.skipToEnd();1694    return;1695  }1696 1697  SourceRange MatchingCTypeRange;1698  TypeResult MatchingCType = ParseTypeName(&MatchingCTypeRange);1699  if (MatchingCType.isInvalid()) {1700    T.skipToEnd();1701    return;1702  }1703 1704  bool LayoutCompatible = false;1705  bool MustBeNull = false;1706  while (TryConsumeToken(tok::comma)) {1707    if (Tok.isNot(tok::identifier)) {1708      Diag(Tok, diag::err_expected) << tok::identifier;1709      T.skipToEnd();1710      return;1711    }1712    IdentifierInfo *Flag = Tok.getIdentifierInfo();1713    if (Flag->isStr("layout_compatible"))1714      LayoutCompatible = true;1715    else if (Flag->isStr("must_be_null"))1716      MustBeNull = true;1717    else {1718      Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;1719      T.skipToEnd();1720      return;1721    }1722    ConsumeToken(); // consume flag1723  }1724 1725  if (!T.consumeClose()) {1726    Attrs.addNewTypeTagForDatatype(1727        &AttrName, AttrNameLoc, AttributeScopeInfo(ScopeName, ScopeLoc),1728        ArgumentKind, MatchingCType.get(), LayoutCompatible, MustBeNull, Form);1729  }1730 1731  if (EndLoc)1732    *EndLoc = T.getCloseLocation();1733}1734 1735bool Parser::DiagnoseProhibitedCXX11Attribute() {1736  assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square));1737 1738  switch (isCXX11AttributeSpecifier(/*Disambiguate*/true)) {1739  case CXX11AttributeKind::NotAttributeSpecifier:1740    // No diagnostic: we're in Obj-C++11 and this is not actually an attribute.1741    return false;1742 1743  case CXX11AttributeKind::InvalidAttributeSpecifier:1744    Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);1745    return false;1746 1747  case CXX11AttributeKind::AttributeSpecifier:1748    // Parse and discard the attributes.1749    SourceLocation BeginLoc = ConsumeBracket();1750    ConsumeBracket();1751    SkipUntil(tok::r_square);1752    assert(Tok.is(tok::r_square) && "isCXX11AttributeSpecifier lied");1753    SourceLocation EndLoc = ConsumeBracket();1754    Diag(BeginLoc, diag::err_attributes_not_allowed)1755      << SourceRange(BeginLoc, EndLoc);1756    return true;1757  }1758  llvm_unreachable("All cases handled above.");1759}1760 1761void Parser::DiagnoseMisplacedCXX11Attribute(ParsedAttributes &Attrs,1762                                             SourceLocation CorrectLocation) {1763  assert((Tok.is(tok::l_square) && NextToken().is(tok::l_square)) ||1764         Tok.is(tok::kw_alignas) || Tok.isRegularKeywordAttribute());1765 1766  // Consume the attributes.1767  auto Keyword =1768      Tok.isRegularKeywordAttribute() ? Tok.getIdentifierInfo() : nullptr;1769  SourceLocation Loc = Tok.getLocation();1770  ParseCXX11Attributes(Attrs);1771  CharSourceRange AttrRange(SourceRange(Loc, Attrs.Range.getEnd()), true);1772  // FIXME: use err_attributes_misplaced1773  (Keyword ? Diag(Loc, diag::err_keyword_not_allowed) << Keyword1774           : Diag(Loc, diag::err_attributes_not_allowed))1775      << FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange)1776      << FixItHint::CreateRemoval(AttrRange);1777}1778 1779void Parser::DiagnoseProhibitedAttributes(1780    const ParsedAttributesView &Attrs, const SourceLocation CorrectLocation) {1781  auto *FirstAttr = Attrs.empty() ? nullptr : &Attrs.front();1782  if (CorrectLocation.isValid()) {1783    CharSourceRange AttrRange(Attrs.Range, true);1784    (FirstAttr && FirstAttr->isRegularKeywordAttribute()1785         ? Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr1786         : Diag(CorrectLocation, diag::err_attributes_misplaced))1787        << FixItHint::CreateInsertionFromRange(CorrectLocation, AttrRange)1788        << FixItHint::CreateRemoval(AttrRange);1789  } else {1790    const SourceRange &Range = Attrs.Range;1791    (FirstAttr && FirstAttr->isRegularKeywordAttribute()1792         ? Diag(Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr1793         : Diag(Range.getBegin(), diag::err_attributes_not_allowed))1794        << Range;1795  }1796}1797 1798void Parser::ProhibitCXX11Attributes(ParsedAttributes &Attrs,1799                                     unsigned AttrDiagID,1800                                     unsigned KeywordDiagID,1801                                     bool DiagnoseEmptyAttrs,1802                                     bool WarnOnUnknownAttrs) {1803 1804  if (DiagnoseEmptyAttrs && Attrs.empty() && Attrs.Range.isValid()) {1805    // An attribute list has been parsed, but it was empty.1806    // This is the case for [[]].1807    const auto &LangOpts = getLangOpts();1808    auto &SM = PP.getSourceManager();1809    Token FirstLSquare;1810    Lexer::getRawToken(Attrs.Range.getBegin(), FirstLSquare, SM, LangOpts);1811 1812    if (FirstLSquare.is(tok::l_square)) {1813      std::optional<Token> SecondLSquare =1814          Lexer::findNextToken(FirstLSquare.getLocation(), SM, LangOpts);1815 1816      if (SecondLSquare && SecondLSquare->is(tok::l_square)) {1817        // The attribute range starts with [[, but is empty. So this must1818        // be [[]], which we are supposed to diagnose because1819        // DiagnoseEmptyAttrs is true.1820        Diag(Attrs.Range.getBegin(), AttrDiagID) << Attrs.Range;1821        return;1822      }1823    }1824  }1825 1826  for (const ParsedAttr &AL : Attrs) {1827    if (AL.isRegularKeywordAttribute()) {1828      Diag(AL.getLoc(), KeywordDiagID) << AL;1829      AL.setInvalid();1830      continue;1831    }1832    if (!AL.isStandardAttributeSyntax())1833      continue;1834    if (AL.getKind() == ParsedAttr::UnknownAttribute) {1835      if (WarnOnUnknownAttrs) {1836        Actions.DiagnoseUnknownAttribute(AL);1837        AL.setInvalid();1838      }1839    } else {1840      Diag(AL.getLoc(), AttrDiagID) << AL;1841      AL.setInvalid();1842    }1843  }1844}1845 1846void Parser::DiagnoseCXX11AttributeExtension(ParsedAttributes &Attrs) {1847  for (const ParsedAttr &PA : Attrs) {1848    if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())1849      Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)1850          << PA << PA.isRegularKeywordAttribute() << PA.getRange();1851  }1852}1853 1854void Parser::stripTypeAttributesOffDeclSpec(ParsedAttributes &Attrs,1855                                            DeclSpec &DS, TagUseKind TUK) {1856  if (TUK == TagUseKind::Reference)1857    return;1858 1859  llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;1860 1861  for (ParsedAttr &AL : DS.getAttributes()) {1862    if ((AL.getKind() == ParsedAttr::AT_Aligned &&1863         AL.isDeclspecAttribute()) ||1864        AL.isMicrosoftAttribute())1865      ToBeMoved.push_back(&AL);1866  }1867 1868  for (ParsedAttr *AL : ToBeMoved) {1869    DS.getAttributes().remove(AL);1870    Attrs.addAtEnd(AL);1871  }1872}1873 1874Parser::DeclGroupPtrTy Parser::ParseDeclaration(DeclaratorContext Context,1875                                                SourceLocation &DeclEnd,1876                                                ParsedAttributes &DeclAttrs,1877                                                ParsedAttributes &DeclSpecAttrs,1878                                                SourceLocation *DeclSpecStart) {1879  ParenBraceBracketBalancer BalancerRAIIObj(*this);1880  // Must temporarily exit the objective-c container scope for1881  // parsing c none objective-c decls.1882  ObjCDeclContextSwitch ObjCDC(*this);1883 1884  Decl *SingleDecl = nullptr;1885  switch (Tok.getKind()) {1886  case tok::kw_template:1887  case tok::kw_export:1888    ProhibitAttributes(DeclAttrs);1889    ProhibitAttributes(DeclSpecAttrs);1890    return ParseDeclarationStartingWithTemplate(Context, DeclEnd, DeclAttrs);1891  case tok::kw_inline:1892    // Could be the start of an inline namespace. Allowed as an ext in C++03.1893    if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) {1894      ProhibitAttributes(DeclAttrs);1895      ProhibitAttributes(DeclSpecAttrs);1896      SourceLocation InlineLoc = ConsumeToken();1897      return ParseNamespace(Context, DeclEnd, InlineLoc);1898    }1899    return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,1900                                  true, nullptr, DeclSpecStart);1901 1902  case tok::kw_cbuffer:1903  case tok::kw_tbuffer:1904    SingleDecl = ParseHLSLBuffer(DeclEnd, DeclAttrs);1905    break;1906  case tok::kw_namespace:1907    ProhibitAttributes(DeclAttrs);1908    ProhibitAttributes(DeclSpecAttrs);1909    return ParseNamespace(Context, DeclEnd);1910  case tok::kw_using: {1911    takeAndConcatenateAttrs(DeclAttrs, std::move(DeclSpecAttrs));1912    return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),1913                                            DeclEnd, DeclAttrs);1914  }1915  case tok::kw_static_assert:1916  case tok::kw__Static_assert:1917    ProhibitAttributes(DeclAttrs);1918    ProhibitAttributes(DeclSpecAttrs);1919    SingleDecl = ParseStaticAssertDeclaration(DeclEnd);1920    break;1921  default:1922    return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,1923                                  true, nullptr, DeclSpecStart);1924  }1925 1926  // This routine returns a DeclGroup, if the thing we parsed only contains a1927  // single decl, convert it now.1928  return Actions.ConvertDeclToDeclGroup(SingleDecl);1929}1930 1931Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(1932    DeclaratorContext Context, SourceLocation &DeclEnd,1933    ParsedAttributes &DeclAttrs, ParsedAttributes &DeclSpecAttrs,1934    bool RequireSemi, ForRangeInit *FRI, SourceLocation *DeclSpecStart) {1935  // Need to retain these for diagnostics before we add them to the DeclSepc.1936  ParsedAttributesView OriginalDeclSpecAttrs;1937  OriginalDeclSpecAttrs.prepend(DeclSpecAttrs.begin(), DeclSpecAttrs.end());1938  OriginalDeclSpecAttrs.Range = DeclSpecAttrs.Range;1939 1940  // Parse the common declaration-specifiers piece.1941  ParsingDeclSpec DS(*this);1942  DS.takeAttributesAppendingingFrom(DeclSpecAttrs);1943 1944  ParsedTemplateInfo TemplateInfo;1945  DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);1946  ParseDeclarationSpecifiers(DS, TemplateInfo, AS_none, DSContext);1947 1948  // If we had a free-standing type definition with a missing semicolon, we1949  // may get this far before the problem becomes obvious.1950  if (DS.hasTagDefinition() &&1951      DiagnoseMissingSemiAfterTagDefinition(DS, AS_none, DSContext))1952    return nullptr;1953 1954  // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"1955  // declaration-specifiers init-declarator-list[opt] ';'1956  if (Tok.is(tok::semi)) {1957    ProhibitAttributes(DeclAttrs);1958    DeclEnd = Tok.getLocation();1959    if (RequireSemi) ConsumeToken();1960    RecordDecl *AnonRecord = nullptr;1961    Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(1962        getCurScope(), AS_none, DS, ParsedAttributesView::none(), AnonRecord);1963    Actions.ActOnDefinedDeclarationSpecifier(TheDecl);1964    DS.complete(TheDecl);1965    if (AnonRecord) {1966      Decl* decls[] = {AnonRecord, TheDecl};1967      return Actions.BuildDeclaratorGroup(decls);1968    }1969    return Actions.ConvertDeclToDeclGroup(TheDecl);1970  }1971 1972  if (DS.hasTagDefinition())1973    Actions.ActOnDefinedDeclarationSpecifier(DS.getRepAsDecl());1974 1975  if (DeclSpecStart)1976    DS.SetRangeStart(*DeclSpecStart);1977 1978  return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);1979}1980 1981bool Parser::MightBeDeclarator(DeclaratorContext Context) {1982  switch (Tok.getKind()) {1983  case tok::annot_cxxscope:1984  case tok::annot_template_id:1985  case tok::caret:1986  case tok::code_completion:1987  case tok::coloncolon:1988  case tok::ellipsis:1989  case tok::kw___attribute:1990  case tok::kw_operator:1991  case tok::l_paren:1992  case tok::star:1993    return true;1994 1995  case tok::amp:1996  case tok::ampamp:1997    return getLangOpts().CPlusPlus;1998 1999  case tok::l_square: // Might be an attribute on an unnamed bit-field.2000    return Context == DeclaratorContext::Member && getLangOpts().CPlusPlus11 &&2001           NextToken().is(tok::l_square);2002 2003  case tok::colon: // Might be a typo for '::' or an unnamed bit-field.2004    return Context == DeclaratorContext::Member || getLangOpts().CPlusPlus;2005 2006  case tok::identifier:2007    switch (NextToken().getKind()) {2008    case tok::code_completion:2009    case tok::coloncolon:2010    case tok::comma:2011    case tok::equal:2012    case tok::equalequal: // Might be a typo for '='.2013    case tok::kw_alignas:2014    case tok::kw_asm:2015    case tok::kw___attribute:2016    case tok::l_brace:2017    case tok::l_paren:2018    case tok::l_square:2019    case tok::less:2020    case tok::r_brace:2021    case tok::r_paren:2022    case tok::r_square:2023    case tok::semi:2024      return true;2025 2026    case tok::colon:2027      // At namespace scope, 'identifier:' is probably a typo for 'identifier::'2028      // and in block scope it's probably a label. Inside a class definition,2029      // this is a bit-field.2030      return Context == DeclaratorContext::Member ||2031             (getLangOpts().CPlusPlus && Context == DeclaratorContext::File);2032 2033    case tok::identifier: // Possible virt-specifier.2034      return getLangOpts().CPlusPlus11 && isCXX11VirtSpecifier(NextToken());2035 2036    default:2037      return Tok.isRegularKeywordAttribute();2038    }2039 2040  default:2041    return Tok.isRegularKeywordAttribute();2042  }2043}2044 2045void Parser::SkipMalformedDecl() {2046  while (true) {2047    switch (Tok.getKind()) {2048    case tok::l_brace:2049      // Skip until matching }, then stop. We've probably skipped over2050      // a malformed class or function definition or similar.2051      ConsumeBrace();2052      SkipUntil(tok::r_brace);2053      if (Tok.isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {2054        // This declaration isn't over yet. Keep skipping.2055        continue;2056      }2057      TryConsumeToken(tok::semi);2058      return;2059 2060    case tok::l_square:2061      ConsumeBracket();2062      SkipUntil(tok::r_square);2063      continue;2064 2065    case tok::l_paren:2066      ConsumeParen();2067      SkipUntil(tok::r_paren);2068      continue;2069 2070    case tok::r_brace:2071      return;2072 2073    case tok::semi:2074      ConsumeToken();2075      return;2076 2077    case tok::kw_inline:2078      // 'inline namespace' at the start of a line is almost certainly2079      // a good place to pick back up parsing, except in an Objective-C2080      // @interface context.2081      if (Tok.isAtStartOfLine() && NextToken().is(tok::kw_namespace) &&2082          (!ParsingInObjCContainer || CurParsedObjCImpl))2083        return;2084      break;2085 2086    case tok::kw_extern:2087      // 'extern' at the start of a line is almost certainly a good2088      // place to pick back up parsing2089    case tok::kw_namespace:2090      // 'namespace' at the start of a line is almost certainly a good2091      // place to pick back up parsing, except in an Objective-C2092      // @interface context.2093      if (Tok.isAtStartOfLine() &&2094          (!ParsingInObjCContainer || CurParsedObjCImpl))2095        return;2096      break;2097 2098    case tok::at:2099      // @end is very much like } in Objective-C contexts.2100      if (NextToken().isObjCAtKeyword(tok::objc_end) &&2101          ParsingInObjCContainer)2102        return;2103      break;2104 2105    case tok::minus:2106    case tok::plus:2107      // - and + probably start new method declarations in Objective-C contexts.2108      if (Tok.isAtStartOfLine() && ParsingInObjCContainer)2109        return;2110      break;2111 2112    case tok::eof:2113    case tok::annot_module_begin:2114    case tok::annot_module_end:2115    case tok::annot_module_include:2116    case tok::annot_repl_input_end:2117      return;2118 2119    default:2120      break;2121    }2122 2123    ConsumeAnyToken();2124  }2125}2126 2127Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,2128                                              DeclaratorContext Context,2129                                              ParsedAttributes &Attrs,2130                                              ParsedTemplateInfo &TemplateInfo,2131                                              SourceLocation *DeclEnd,2132                                              ForRangeInit *FRI) {2133  // Parse the first declarator.2134  // Consume all of the attributes from `Attrs` by moving them to our own local2135  // list. This ensures that we will not attempt to interpret them as statement2136  // attributes higher up the callchain.2137  ParsedAttributes LocalAttrs(AttrFactory);2138  LocalAttrs.takeAllPrependingFrom(Attrs);2139  ParsingDeclarator D(*this, DS, LocalAttrs, Context);2140  if (TemplateInfo.TemplateParams)2141    D.setTemplateParameterLists(*TemplateInfo.TemplateParams);2142 2143  bool IsTemplateSpecOrInst =2144      (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation ||2145       TemplateInfo.Kind == ParsedTemplateKind::ExplicitSpecialization);2146  SuppressAccessChecks SAC(*this, IsTemplateSpecOrInst);2147 2148  ParseDeclarator(D);2149 2150  if (IsTemplateSpecOrInst)2151    SAC.done();2152 2153  // Bail out if the first declarator didn't seem well-formed.2154  if (!D.hasName() && !D.mayOmitIdentifier()) {2155    SkipMalformedDecl();2156    return nullptr;2157  }2158 2159  if (getLangOpts().HLSL)2160    while (MaybeParseHLSLAnnotations(D))2161      ;2162 2163  if (Tok.is(tok::kw_requires))2164    ParseTrailingRequiresClause(D);2165 2166  // Save late-parsed attributes for now; they need to be parsed in the2167  // appropriate function scope after the function Decl has been constructed.2168  // These will be parsed in ParseFunctionDefinition or ParseLexedAttrList.2169  LateParsedAttrList LateParsedAttrs(true);2170  if (D.isFunctionDeclarator()) {2171    MaybeParseGNUAttributes(D, &LateParsedAttrs);2172 2173    // The _Noreturn keyword can't appear here, unlike the GNU noreturn2174    // attribute. If we find the keyword here, tell the user to put it2175    // at the start instead.2176    if (Tok.is(tok::kw__Noreturn)) {2177      SourceLocation Loc = ConsumeToken();2178      const char *PrevSpec;2179      unsigned DiagID;2180 2181      // We can offer a fixit if it's valid to mark this function as _Noreturn2182      // and we don't have any other declarators in this declaration.2183      bool Fixit = !DS.setFunctionSpecNoreturn(Loc, PrevSpec, DiagID);2184      MaybeParseGNUAttributes(D, &LateParsedAttrs);2185      Fixit &= Tok.isOneOf(tok::semi, tok::l_brace, tok::kw_try);2186 2187      Diag(Loc, diag::err_c11_noreturn_misplaced)2188          << (Fixit ? FixItHint::CreateRemoval(Loc) : FixItHint())2189          << (Fixit ? FixItHint::CreateInsertion(D.getBeginLoc(), "_Noreturn ")2190                    : FixItHint());2191    }2192 2193    // Check to see if we have a function *definition* which must have a body.2194    if (Tok.is(tok::equal) && NextToken().is(tok::code_completion)) {2195      cutOffParsing();2196      Actions.CodeCompletion().CodeCompleteAfterFunctionEquals(D);2197      return nullptr;2198    }2199    // We're at the point where the parsing of function declarator is finished.2200    //2201    // A common error is that users accidently add a virtual specifier2202    // (e.g. override) in an out-line method definition.2203    // We attempt to recover by stripping all these specifiers coming after2204    // the declarator.2205    while (auto Specifier = isCXX11VirtSpecifier()) {2206      Diag(Tok, diag::err_virt_specifier_outside_class)2207          << VirtSpecifiers::getSpecifierName(Specifier)2208          << FixItHint::CreateRemoval(Tok.getLocation());2209      ConsumeToken();2210    }2211    // Look at the next token to make sure that this isn't a function2212    // declaration.  We have to check this because __attribute__ might be the2213    // start of a function definition in GCC-extended K&R C.2214    if (!isDeclarationAfterDeclarator()) {2215 2216      // Function definitions are only allowed at file scope and in C++ classes.2217      // The C++ inline method definition case is handled elsewhere, so we only2218      // need to handle the file scope definition case.2219      if (Context == DeclaratorContext::File) {2220        if (isStartOfFunctionDefinition(D)) {2221          // C++23 [dcl.typedef] p1:2222          //   The typedef specifier shall not be [...], and it shall not be2223          //   used in the decl-specifier-seq of a parameter-declaration nor in2224          //   the decl-specifier-seq of a function-definition.2225          if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {2226            // If the user intended to write 'typename', we should have already2227            // suggested adding it elsewhere. In any case, recover by ignoring2228            // 'typedef' and suggest removing it.2229            Diag(DS.getStorageClassSpecLoc(),2230                 diag::err_function_declared_typedef)2231                << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());2232            DS.ClearStorageClassSpecs();2233          }2234          Decl *TheDecl = nullptr;2235 2236          if (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation) {2237            if (D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) {2238              // If the declarator-id is not a template-id, issue a diagnostic2239              // and recover by ignoring the 'template' keyword.2240              Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;2241              TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(),2242                                                &LateParsedAttrs);2243            } else {2244              SourceLocation LAngleLoc =2245                  PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);2246              Diag(D.getIdentifierLoc(),2247                   diag::err_explicit_instantiation_with_definition)2248                  << SourceRange(TemplateInfo.TemplateLoc)2249                  << FixItHint::CreateInsertion(LAngleLoc, "<>");2250 2251              // Recover as if it were an explicit specialization.2252              TemplateParameterLists FakedParamLists;2253              FakedParamLists.push_back(Actions.ActOnTemplateParameterList(2254                  0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},2255                  LAngleLoc, nullptr));2256 2257              TheDecl = ParseFunctionDefinition(2258                  D,2259                  ParsedTemplateInfo(&FakedParamLists,2260                                     /*isSpecialization=*/true,2261                                     /*lastParameterListWasEmpty=*/true),2262                  &LateParsedAttrs);2263            }2264          } else {2265            TheDecl =2266                ParseFunctionDefinition(D, TemplateInfo, &LateParsedAttrs);2267          }2268 2269          return Actions.ConvertDeclToDeclGroup(TheDecl);2270        }2271 2272        if (isDeclarationSpecifier(ImplicitTypenameContext::No) ||2273            Tok.is(tok::kw_namespace)) {2274          // If there is an invalid declaration specifier or a namespace2275          // definition right after the function prototype, then we must be in a2276          // missing semicolon case where this isn't actually a body.  Just fall2277          // through into the code that handles it as a prototype, and let the2278          // top-level code handle the erroneous declspec where it would2279          // otherwise expect a comma or semicolon. Note that2280          // isDeclarationSpecifier already covers 'inline namespace', since2281          // 'inline' can be a declaration specifier.2282        } else {2283          Diag(Tok, diag::err_expected_fn_body);2284          SkipUntil(tok::semi);2285          return nullptr;2286        }2287      } else {2288        if (Tok.is(tok::l_brace)) {2289          Diag(Tok, diag::err_function_definition_not_allowed);2290          SkipMalformedDecl();2291          return nullptr;2292        }2293      }2294    }2295  }2296 2297  if (ParseAsmAttributesAfterDeclarator(D))2298    return nullptr;2299 2300  // C++0x [stmt.iter]p1: Check if we have a for-range-declarator. If so, we2301  // must parse and analyze the for-range-initializer before the declaration is2302  // analyzed.2303  //2304  // Handle the Objective-C for-in loop variable similarly, although we2305  // don't need to parse the container in advance.2306  if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {2307    bool IsForRangeLoop = false;2308    if (TryConsumeToken(tok::colon, FRI->ColonLoc)) {2309      IsForRangeLoop = true;2310      EnterExpressionEvaluationContext ForRangeInitContext(2311          Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated,2312          /*LambdaContextDecl=*/nullptr,2313          Sema::ExpressionEvaluationContextRecord::EK_Other,2314          getLangOpts().CPlusPlus23);2315 2316      // P2718R0 - Lifetime extension in range-based for loops.2317      if (getLangOpts().CPlusPlus23) {2318        auto &LastRecord = Actions.currentEvaluationContext();2319        LastRecord.InLifetimeExtendingContext = true;2320        LastRecord.RebuildDefaultArgOrDefaultInit = true;2321      }2322 2323      if (getLangOpts().OpenMP)2324        Actions.OpenMP().startOpenMPCXXRangeFor();2325      if (Tok.is(tok::l_brace))2326        FRI->RangeExpr = ParseBraceInitializer();2327      else2328        FRI->RangeExpr = ParseExpression();2329 2330      // Before c++23, ForRangeLifetimeExtendTemps should be empty.2331      assert(2332          getLangOpts().CPlusPlus23 ||2333          Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());2334 2335      // Move the collected materialized temporaries into ForRangeInit before2336      // ForRangeInitContext exit.2337      FRI->LifetimeExtendTemps = std::move(2338          Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps);2339    }2340 2341    Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);2342    if (IsForRangeLoop) {2343      Actions.ActOnCXXForRangeDecl(ThisDecl);2344    } else {2345      // Obj-C for loop2346      if (auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))2347        VD->setObjCForDecl(true);2348    }2349    Actions.FinalizeDeclaration(ThisDecl);2350    D.complete(ThisDecl);2351    return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, ThisDecl);2352  }2353 2354  SmallVector<Decl *, 8> DeclsInGroup;2355  Decl *FirstDecl =2356      ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo, FRI);2357  if (LateParsedAttrs.size() > 0)2358    ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false);2359  D.complete(FirstDecl);2360  if (FirstDecl)2361    DeclsInGroup.push_back(FirstDecl);2362 2363  bool ExpectSemi = Context != DeclaratorContext::ForInit;2364 2365  // If we don't have a comma, it is either the end of the list (a ';') or an2366  // error, bail out.2367  SourceLocation CommaLoc;2368  while (TryConsumeToken(tok::comma, CommaLoc)) {2369    if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {2370      // This comma was followed by a line-break and something which can't be2371      // the start of a declarator. The comma was probably a typo for a2372      // semicolon.2373      Diag(CommaLoc, diag::err_expected_semi_declaration)2374        << FixItHint::CreateReplacement(CommaLoc, ";");2375      ExpectSemi = false;2376      break;2377    }2378 2379    // C++23 [temp.pre]p5:2380    //   In a template-declaration, explicit specialization, or explicit2381    //   instantiation the init-declarator-list in the declaration shall2382    //   contain at most one declarator.2383    if (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate &&2384        D.isFirstDeclarator()) {2385      Diag(CommaLoc, diag::err_multiple_template_declarators)2386          << TemplateInfo.Kind;2387    }2388 2389    // Parse the next declarator.2390    D.clear();2391    D.setCommaLoc(CommaLoc);2392 2393    // Accept attributes in an init-declarator.  In the first declarator in a2394    // declaration, these would be part of the declspec.  In subsequent2395    // declarators, they become part of the declarator itself, so that they2396    // don't apply to declarators after *this* one.  Examples:2397    //    short __attribute__((common)) var;    -> declspec2398    //    short var __attribute__((common));    -> declarator2399    //    short x, __attribute__((common)) var;    -> declarator2400    MaybeParseGNUAttributes(D);2401 2402    // MSVC parses but ignores qualifiers after the comma as an extension.2403    if (getLangOpts().MicrosoftExt)2404      DiagnoseAndSkipExtendedMicrosoftTypeAttributes();2405 2406    ParseDeclarator(D);2407 2408    if (getLangOpts().HLSL)2409      MaybeParseHLSLAnnotations(D);2410 2411    if (!D.isInvalidType()) {2412      // C++2a [dcl.decl]p12413      //    init-declarator:2414      //	      declarator initializer[opt]2415      //        declarator requires-clause2416      if (Tok.is(tok::kw_requires))2417        ParseTrailingRequiresClause(D);2418      Decl *ThisDecl = ParseDeclarationAfterDeclarator(D, TemplateInfo);2419      D.complete(ThisDecl);2420      if (ThisDecl)2421        DeclsInGroup.push_back(ThisDecl);2422    }2423  }2424 2425  if (DeclEnd)2426    *DeclEnd = Tok.getLocation();2427 2428  if (ExpectSemi && ExpectAndConsumeSemi(2429                        Context == DeclaratorContext::File2430                            ? diag::err_invalid_token_after_toplevel_declarator2431                            : diag::err_expected_semi_declaration)) {2432    // Okay, there was no semicolon and one was expected.  If we see a2433    // declaration specifier, just assume it was missing and continue parsing.2434    // Otherwise things are very confused and we skip to recover.2435    if (!isDeclarationSpecifier(ImplicitTypenameContext::No))2436      SkipMalformedDecl();2437  }2438 2439  return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, DeclsInGroup);2440}2441 2442bool Parser::ParseAsmAttributesAfterDeclarator(Declarator &D) {2443  // If a simple-asm-expr is present, parse it.2444  if (Tok.is(tok::kw_asm)) {2445    SourceLocation Loc;2446    ExprResult AsmLabel(ParseSimpleAsm(/*ForAsmLabel*/ true, &Loc));2447    if (AsmLabel.isInvalid()) {2448      SkipUntil(tok::semi, StopBeforeMatch);2449      return true;2450    }2451 2452    D.setAsmLabel(AsmLabel.get());2453    D.SetRangeEnd(Loc);2454  }2455 2456  MaybeParseGNUAttributes(D);2457  return false;2458}2459 2460Decl *Parser::ParseDeclarationAfterDeclarator(2461    Declarator &D, const ParsedTemplateInfo &TemplateInfo) {2462  if (ParseAsmAttributesAfterDeclarator(D))2463    return nullptr;2464 2465  return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);2466}2467 2468Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(2469    Declarator &D, const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {2470  // RAII type used to track whether we're inside an initializer.2471  struct InitializerScopeRAII {2472    Parser &P;2473    Declarator &D;2474    Decl *ThisDecl;2475    bool Entered;2476 2477    InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl)2478        : P(P), D(D), ThisDecl(ThisDecl), Entered(false) {2479      if (ThisDecl && P.getLangOpts().CPlusPlus) {2480        Scope *S = nullptr;2481        if (D.getCXXScopeSpec().isSet()) {2482          P.EnterScope(0);2483          S = P.getCurScope();2484        }2485        if (ThisDecl && !ThisDecl->isInvalidDecl()) {2486          P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);2487          Entered = true;2488        }2489      }2490    }2491    ~InitializerScopeRAII() {2492      if (ThisDecl && P.getLangOpts().CPlusPlus) {2493        Scope *S = nullptr;2494        if (D.getCXXScopeSpec().isSet())2495          S = P.getCurScope();2496 2497        if (Entered)2498          P.Actions.ActOnCXXExitDeclInitializer(S, ThisDecl);2499        if (S)2500          P.ExitScope();2501      }2502      ThisDecl = nullptr;2503    }2504  };2505 2506  enum class InitKind { Uninitialized, Equal, CXXDirect, CXXBraced };2507  InitKind TheInitKind;2508  // If a '==' or '+=' is found, suggest a fixit to '='.2509  if (isTokenEqualOrEqualTypo())2510    TheInitKind = InitKind::Equal;2511  else if (Tok.is(tok::l_paren))2512    TheInitKind = InitKind::CXXDirect;2513  else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace) &&2514           (!CurParsedObjCImpl || !D.isFunctionDeclarator()))2515    TheInitKind = InitKind::CXXBraced;2516  else2517    TheInitKind = InitKind::Uninitialized;2518  if (TheInitKind != InitKind::Uninitialized)2519    D.setHasInitializer();2520 2521  // Inform Sema that we just parsed this declarator.2522  Decl *ThisDecl = nullptr;2523  Decl *OuterDecl = nullptr;2524  switch (TemplateInfo.Kind) {2525  case ParsedTemplateKind::NonTemplate:2526    ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);2527    break;2528 2529  case ParsedTemplateKind::Template:2530  case ParsedTemplateKind::ExplicitSpecialization: {2531    ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),2532                                               *TemplateInfo.TemplateParams,2533                                               D);2534    if (VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {2535      // Re-direct this decl to refer to the templated decl so that we can2536      // initialize it.2537      ThisDecl = VT->getTemplatedDecl();2538      OuterDecl = VT;2539    }2540    break;2541  }2542  case ParsedTemplateKind::ExplicitInstantiation: {2543    if (Tok.is(tok::semi)) {2544      DeclResult ThisRes = Actions.ActOnExplicitInstantiation(2545          getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);2546      if (ThisRes.isInvalid()) {2547        SkipUntil(tok::semi, StopBeforeMatch);2548        return nullptr;2549      }2550      ThisDecl = ThisRes.get();2551    } else {2552      // FIXME: This check should be for a variable template instantiation only.2553 2554      // Check that this is a valid instantiation2555      if (D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) {2556        // If the declarator-id is not a template-id, issue a diagnostic and2557        // recover by ignoring the 'template' keyword.2558        Diag(Tok, diag::err_template_defn_explicit_instantiation)2559            << 2 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc);2560        ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);2561      } else {2562        SourceLocation LAngleLoc =2563            PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);2564        Diag(D.getIdentifierLoc(),2565             diag::err_explicit_instantiation_with_definition)2566            << SourceRange(TemplateInfo.TemplateLoc)2567            << FixItHint::CreateInsertion(LAngleLoc, "<>");2568 2569        // Recover as if it were an explicit specialization.2570        TemplateParameterLists FakedParamLists;2571        FakedParamLists.push_back(Actions.ActOnTemplateParameterList(2572            0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},2573            LAngleLoc, nullptr));2574 2575        ThisDecl =2576            Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D);2577      }2578    }2579    break;2580    }2581  }2582 2583  SemaCUDA::CUDATargetContextRAII X(Actions.CUDA(),2584                                    SemaCUDA::CTCK_InitGlobalVar, ThisDecl);2585  switch (TheInitKind) {2586  // Parse declarator '=' initializer.2587  case InitKind::Equal: {2588    SourceLocation EqualLoc = ConsumeToken();2589 2590    if (Tok.is(tok::kw_delete)) {2591      if (D.isFunctionDeclarator())2592        Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)2593          << 1 /* delete */;2594      else2595        Diag(ConsumeToken(), diag::err_deleted_non_function);2596      SkipDeletedFunctionBody();2597    } else if (Tok.is(tok::kw_default)) {2598      if (D.isFunctionDeclarator())2599        Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)2600          << 0 /* default */;2601      else2602        Diag(ConsumeToken(), diag::err_default_special_members)2603            << getLangOpts().CPlusPlus20;2604    } else {2605      InitializerScopeRAII InitScope(*this, D, ThisDecl);2606 2607      if (Tok.is(tok::code_completion)) {2608        cutOffParsing();2609        Actions.CodeCompletion().CodeCompleteInitializer(getCurScope(),2610                                                         ThisDecl);2611        Actions.FinalizeDeclaration(ThisDecl);2612        return nullptr;2613      }2614 2615      PreferredType.enterVariableInit(Tok.getLocation(), ThisDecl);2616      ExprResult Init = ParseInitializer(ThisDecl);2617 2618      // If this is the only decl in (possibly) range based for statement,2619      // our best guess is that the user meant ':' instead of '='.2620      if (Tok.is(tok::r_paren) && FRI && D.isFirstDeclarator()) {2621        Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)2622            << FixItHint::CreateReplacement(EqualLoc, ":");2623        // We are trying to stop parser from looking for ';' in this for2624        // statement, therefore preventing spurious errors to be issued.2625        FRI->ColonLoc = EqualLoc;2626        Init = ExprError();2627        FRI->RangeExpr = Init;2628      }2629 2630      if (Init.isInvalid()) {2631        SmallVector<tok::TokenKind, 2> StopTokens;2632        StopTokens.push_back(tok::comma);2633        if (D.getContext() == DeclaratorContext::ForInit ||2634            D.getContext() == DeclaratorContext::SelectionInit)2635          StopTokens.push_back(tok::r_paren);2636        SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch);2637        Actions.ActOnInitializerError(ThisDecl);2638      } else2639        Actions.AddInitializerToDecl(ThisDecl, Init.get(),2640                                     /*DirectInit=*/false);2641    }2642    break;2643  }2644  case InitKind::CXXDirect: {2645    // Parse C++ direct initializer: '(' expression-list ')'2646    BalancedDelimiterTracker T(*this, tok::l_paren);2647    T.consumeOpen();2648 2649    ExprVector Exprs;2650 2651    InitializerScopeRAII InitScope(*this, D, ThisDecl);2652 2653    auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);2654    auto RunSignatureHelp = [&]() {2655      QualType PreferredType =2656          Actions.CodeCompletion().ProduceConstructorSignatureHelp(2657              ThisVarDecl->getType()->getCanonicalTypeInternal(),2658              ThisDecl->getLocation(), Exprs, T.getOpenLocation(),2659              /*Braced=*/false);2660      CalledSignatureHelp = true;2661      return PreferredType;2662    };2663    auto SetPreferredType = [&] {2664      PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp);2665    };2666 2667    llvm::function_ref<void()> ExpressionStarts;2668    if (ThisVarDecl) {2669      // ParseExpressionList can sometimes succeed even when ThisDecl is not2670      // VarDecl. This is an error and it is reported in a call to2671      // Actions.ActOnInitializerError(). However, we call2672      // ProduceConstructorSignatureHelp only on VarDecls.2673      ExpressionStarts = SetPreferredType;2674    }2675 2676    bool SawError = ParseExpressionList(Exprs, ExpressionStarts);2677 2678    if (SawError) {2679      if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {2680        Actions.CodeCompletion().ProduceConstructorSignatureHelp(2681            ThisVarDecl->getType()->getCanonicalTypeInternal(),2682            ThisDecl->getLocation(), Exprs, T.getOpenLocation(),2683            /*Braced=*/false);2684        CalledSignatureHelp = true;2685      }2686      Actions.ActOnInitializerError(ThisDecl);2687      SkipUntil(tok::r_paren, StopAtSemi);2688    } else {2689      // Match the ')'.2690      T.consumeClose();2691 2692      ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(),2693                                                          T.getCloseLocation(),2694                                                          Exprs);2695      Actions.AddInitializerToDecl(ThisDecl, Initializer.get(),2696                                   /*DirectInit=*/true);2697    }2698    break;2699  }2700  case InitKind::CXXBraced: {2701    // Parse C++0x braced-init-list.2702    Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);2703 2704    InitializerScopeRAII InitScope(*this, D, ThisDecl);2705 2706    PreferredType.enterVariableInit(Tok.getLocation(), ThisDecl);2707    ExprResult Init(ParseBraceInitializer());2708 2709    if (Init.isInvalid()) {2710      Actions.ActOnInitializerError(ThisDecl);2711    } else2712      Actions.AddInitializerToDecl(ThisDecl, Init.get(), /*DirectInit=*/true);2713    break;2714  }2715  case InitKind::Uninitialized: {2716    InitializerScopeRAII InitScope(*this, D, ThisDecl);2717    Actions.ActOnUninitializedDecl(ThisDecl);2718    break;2719  }2720  }2721 2722  Actions.FinalizeDeclaration(ThisDecl);2723  return OuterDecl ? OuterDecl : ThisDecl;2724}2725 2726void Parser::ParseSpecifierQualifierList(2727    DeclSpec &DS, ImplicitTypenameContext AllowImplicitTypename,2728    AccessSpecifier AS, DeclSpecContext DSC) {2729  ParsedTemplateInfo TemplateInfo;2730  /// specifier-qualifier-list is a subset of declaration-specifiers.  Just2731  /// parse declaration-specifiers and complain about extra stuff.2732  /// TODO: diagnose attribute-specifiers and alignment-specifiers.2733  ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC, nullptr,2734                             AllowImplicitTypename);2735 2736  // Validate declspec for type-name.2737  unsigned Specs = DS.getParsedSpecifiers();2738  if (isTypeSpecifier(DSC) && !DS.hasTypeSpecifier()) {2739    Diag(Tok, diag::err_expected_type);2740    DS.SetTypeSpecError();2741  } else if (Specs == DeclSpec::PQ_None && !DS.hasAttributes()) {2742    Diag(Tok, diag::err_typename_requires_specqual);2743    if (!DS.hasTypeSpecifier())2744      DS.SetTypeSpecError();2745  }2746 2747  // Issue diagnostic and remove storage class if present.2748  if (Specs & DeclSpec::PQ_StorageClassSpecifier) {2749    if (DS.getStorageClassSpecLoc().isValid())2750      Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass);2751    else2752      Diag(DS.getThreadStorageClassSpecLoc(),2753           diag::err_typename_invalid_storageclass);2754    DS.ClearStorageClassSpecs();2755  }2756 2757  // Issue diagnostic and remove function specifier if present.2758  if (Specs & DeclSpec::PQ_FunctionSpecifier) {2759    if (DS.isInlineSpecified())2760      Diag(DS.getInlineSpecLoc(), diag::err_typename_invalid_functionspec);2761    if (DS.isVirtualSpecified())2762      Diag(DS.getVirtualSpecLoc(), diag::err_typename_invalid_functionspec);2763    if (DS.hasExplicitSpecifier())2764      Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);2765    if (DS.isNoreturnSpecified())2766      Diag(DS.getNoreturnSpecLoc(), diag::err_typename_invalid_functionspec);2767    DS.ClearFunctionSpecs();2768  }2769 2770  // Issue diagnostic and remove constexpr specifier if present.2771  if (DS.hasConstexprSpecifier() && DSC != DeclSpecContext::DSC_condition) {2772    Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr)2773        << static_cast<int>(DS.getConstexprSpecifier());2774    DS.ClearConstexprSpec();2775  }2776}2777 2778/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the2779/// specified token is valid after the identifier in a declarator which2780/// immediately follows the declspec.  For example, these things are valid:2781///2782///      int x   [             4];         // direct-declarator2783///      int x   (             int y);     // direct-declarator2784///  int(int x   )                         // direct-declarator2785///      int x   ;                         // simple-declaration2786///      int x   =             17;         // init-declarator-list2787///      int x   ,             y;          // init-declarator-list2788///      int x   __asm__       ("foo");    // init-declarator-list2789///      int x   :             4;          // struct-declarator2790///      int x   {             5};         // C++'0x unified initializers2791///2792/// This is not, because 'x' does not immediately follow the declspec (though2793/// ')' happens to be valid anyway).2794///    int (x)2795///2796static bool isValidAfterIdentifierInDeclarator(const Token &T) {2797  return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,2798                   tok::comma, tok::equal, tok::kw_asm, tok::l_brace,2799                   tok::colon);2800}2801 2802bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,2803                              ParsedTemplateInfo &TemplateInfo,2804                              AccessSpecifier AS, DeclSpecContext DSC,2805                              ParsedAttributes &Attrs) {2806  assert(Tok.is(tok::identifier) && "should have identifier");2807 2808  SourceLocation Loc = Tok.getLocation();2809  // If we see an identifier that is not a type name, we normally would2810  // parse it as the identifier being declared.  However, when a typename2811  // is typo'd or the definition is not included, this will incorrectly2812  // parse the typename as the identifier name and fall over misparsing2813  // later parts of the diagnostic.2814  //2815  // As such, we try to do some look-ahead in cases where this would2816  // otherwise be an "implicit-int" case to see if this is invalid.  For2817  // example: "static foo_t x = 4;"  In this case, if we parsed foo_t as2818  // an identifier with implicit int, we'd get a parse error because the2819  // next token is obviously invalid for a type.  Parse these as a case2820  // with an invalid type specifier.2821  assert(!DS.hasTypeSpecifier() && "Type specifier checked above");2822 2823  // Since we know that this either implicit int (which is rare) or an2824  // error, do lookahead to try to do better recovery. This never applies2825  // within a type specifier. Outside of C++, we allow this even if the2826  // language doesn't "officially" support implicit int -- we support2827  // implicit int as an extension in some language modes.2828  if (!isTypeSpecifier(DSC) && getLangOpts().isImplicitIntAllowed() &&2829      isValidAfterIdentifierInDeclarator(NextToken())) {2830    // If this token is valid for implicit int, e.g. "static x = 4", then2831    // we just avoid eating the identifier, so it will be parsed as the2832    // identifier in the declarator.2833    return false;2834  }2835 2836  // Early exit as Sema has a dedicated missing_actual_pipe_type diagnostic2837  // for incomplete declarations such as `pipe p`.2838  if (getLangOpts().OpenCLCPlusPlus && DS.isTypeSpecPipe())2839    return false;2840 2841  if (getLangOpts().CPlusPlus &&2842      DS.getStorageClassSpec() == DeclSpec::SCS_auto) {2843    // Don't require a type specifier if we have the 'auto' storage class2844    // specifier in C++98 -- we'll promote it to a type specifier.2845    if (SS)2846      AnnotateScopeToken(*SS, /*IsNewAnnotation*/false);2847    return false;2848  }2849 2850  if (getLangOpts().CPlusPlus && (!SS || SS->isEmpty()) &&2851      getLangOpts().MSVCCompat) {2852    // Lookup of an unqualified type name has failed in MSVC compatibility mode.2853    // Give Sema a chance to recover if we are in a template with dependent base2854    // classes.2855    if (ParsedType T = Actions.ActOnMSVCUnknownTypeName(2856            *Tok.getIdentifierInfo(), Tok.getLocation(),2857            DSC == DeclSpecContext::DSC_template_type_arg)) {2858      const char *PrevSpec;2859      unsigned DiagID;2860      DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T,2861                         Actions.getASTContext().getPrintingPolicy());2862      DS.SetRangeEnd(Tok.getLocation());2863      ConsumeToken();2864      return false;2865    }2866  }2867 2868  // Otherwise, if we don't consume this token, we are going to emit an2869  // error anyway.  Try to recover from various common problems.  Check2870  // to see if this was a reference to a tag name without a tag specified.2871  // This is a common problem in C (saying 'foo' instead of 'struct foo').2872  //2873  // C++ doesn't need this, and isTagName doesn't take SS.2874  if (SS == nullptr) {2875    const char *TagName = nullptr, *FixitTagName = nullptr;2876    tok::TokenKind TagKind = tok::unknown;2877 2878    switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) {2879      default: break;2880      case DeclSpec::TST_enum:2881        TagName="enum"  ; FixitTagName = "enum "  ; TagKind=tok::kw_enum ;break;2882      case DeclSpec::TST_union:2883        TagName="union" ; FixitTagName = "union " ;TagKind=tok::kw_union ;break;2884      case DeclSpec::TST_struct:2885        TagName="struct"; FixitTagName = "struct ";TagKind=tok::kw_struct;break;2886      case DeclSpec::TST_interface:2887        TagName="__interface"; FixitTagName = "__interface ";2888        TagKind=tok::kw___interface;break;2889      case DeclSpec::TST_class:2890        TagName="class" ; FixitTagName = "class " ;TagKind=tok::kw_class ;break;2891    }2892 2893    if (TagName) {2894      IdentifierInfo *TokenName = Tok.getIdentifierInfo();2895      LookupResult R(Actions, TokenName, SourceLocation(),2896                     Sema::LookupOrdinaryName);2897 2898      Diag(Loc, diag::err_use_of_tag_name_without_tag)2899        << TokenName << TagName << getLangOpts().CPlusPlus2900        << FixItHint::CreateInsertion(Tok.getLocation(), FixitTagName);2901 2902      if (Actions.LookupName(R, getCurScope())) {2903        for (LookupResult::iterator I = R.begin(), IEnd = R.end();2904             I != IEnd; ++I)2905          Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)2906            << TokenName << TagName;2907      }2908 2909      // Parse this as a tag as if the missing tag were present.2910      if (TagKind == tok::kw_enum)2911        ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,2912                           DeclSpecContext::DSC_normal);2913      else2914        ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,2915                            /*EnteringContext*/ false,2916                            DeclSpecContext::DSC_normal, Attrs);2917      return true;2918    }2919  }2920 2921  // Determine whether this identifier could plausibly be the name of something2922  // being declared (with a missing type).2923  if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||2924                                DSC == DeclSpecContext::DSC_class)) {2925    // Look ahead to the next token to try to figure out what this declaration2926    // was supposed to be.2927    switch (NextToken().getKind()) {2928    case tok::l_paren: {2929      // static x(4); // 'x' is not a type2930      // x(int n);    // 'x' is not a type2931      // x (*p)[];    // 'x' is a type2932      //2933      // Since we're in an error case, we can afford to perform a tentative2934      // parse to determine which case we're in.2935      TentativeParsingAction PA(*this);2936      ConsumeToken();2937      TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false);2938      PA.Revert();2939 2940      if (TPR != TPResult::False) {2941        // The identifier is followed by a parenthesized declarator.2942        // It's supposed to be a type.2943        break;2944      }2945 2946      // If we're in a context where we could be declaring a constructor,2947      // check whether this is a constructor declaration with a bogus name.2948      if (DSC == DeclSpecContext::DSC_class ||2949          (DSC == DeclSpecContext::DSC_top_level && SS)) {2950        IdentifierInfo *II = Tok.getIdentifierInfo();2951        if (Actions.isCurrentClassNameTypo(II, SS)) {2952          Diag(Loc, diag::err_constructor_bad_name)2953            << Tok.getIdentifierInfo() << II2954            << FixItHint::CreateReplacement(Tok.getLocation(), II->getName());2955          Tok.setIdentifierInfo(II);2956        }2957      }2958      // Fall through.2959      [[fallthrough]];2960    }2961    case tok::comma:2962    case tok::equal:2963    case tok::kw_asm:2964    case tok::l_brace:2965    case tok::l_square:2966    case tok::semi:2967      // This looks like a variable or function declaration. The type is2968      // probably missing. We're done parsing decl-specifiers.2969      // But only if we are not in a function prototype scope.2970      if (getCurScope()->isFunctionPrototypeScope())2971        break;2972      if (SS)2973        AnnotateScopeToken(*SS, /*IsNewAnnotation*/false);2974      return false;2975 2976    default:2977      // This is probably supposed to be a type. This includes cases like:2978      //   int f(itn);2979      //   struct S { unsigned : 4; };2980      break;2981    }2982  }2983 2984  // This is almost certainly an invalid type name. Let Sema emit a diagnostic2985  // and attempt to recover.2986  ParsedType T;2987  IdentifierInfo *II = Tok.getIdentifierInfo();2988  bool IsTemplateName = getLangOpts().CPlusPlus && NextToken().is(tok::less);2989  Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T,2990                                  IsTemplateName);2991  if (T) {2992    // The action has suggested that the type T could be used. Set that as2993    // the type in the declaration specifiers, consume the would-be type2994    // name token, and we're done.2995    const char *PrevSpec;2996    unsigned DiagID;2997    DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T,2998                       Actions.getASTContext().getPrintingPolicy());2999    DS.SetRangeEnd(Tok.getLocation());3000    ConsumeToken();3001    // There may be other declaration specifiers after this.3002    return true;3003  } else if (II != Tok.getIdentifierInfo()) {3004    // If no type was suggested, the correction is to a keyword3005    Tok.setKind(II->getTokenID());3006    // There may be other declaration specifiers after this.3007    return true;3008  }3009 3010  // Otherwise, the action had no suggestion for us.  Mark this as an error.3011  DS.SetTypeSpecError();3012  DS.SetRangeEnd(Tok.getLocation());3013  ConsumeToken();3014 3015  // Eat any following template arguments.3016  if (IsTemplateName) {3017    SourceLocation LAngle, RAngle;3018    TemplateArgList Args;3019    ParseTemplateIdAfterTemplateName(true, LAngle, Args, RAngle);3020  }3021 3022  // TODO: Could inject an invalid typedef decl in an enclosing scope to3023  // avoid rippling error messages on subsequent uses of the same type,3024  // could be useful if #include was forgotten.3025  return true;3026}3027 3028Parser::DeclSpecContext3029Parser::getDeclSpecContextFromDeclaratorContext(DeclaratorContext Context) {3030  switch (Context) {3031  case DeclaratorContext::Member:3032    return DeclSpecContext::DSC_class;3033  case DeclaratorContext::File:3034    return DeclSpecContext::DSC_top_level;3035  case DeclaratorContext::TemplateParam:3036    return DeclSpecContext::DSC_template_param;3037  case DeclaratorContext::TemplateArg:3038    return DeclSpecContext::DSC_template_arg;3039  case DeclaratorContext::TemplateTypeArg:3040    return DeclSpecContext::DSC_template_type_arg;3041  case DeclaratorContext::TrailingReturn:3042  case DeclaratorContext::TrailingReturnVar:3043    return DeclSpecContext::DSC_trailing;3044  case DeclaratorContext::AliasDecl:3045  case DeclaratorContext::AliasTemplate:3046    return DeclSpecContext::DSC_alias_declaration;3047  case DeclaratorContext::Association:3048    return DeclSpecContext::DSC_association;3049  case DeclaratorContext::TypeName:3050    return DeclSpecContext::DSC_type_specifier;3051  case DeclaratorContext::Condition:3052    return DeclSpecContext::DSC_condition;3053  case DeclaratorContext::ConversionId:3054    return DeclSpecContext::DSC_conv_operator;3055  case DeclaratorContext::CXXNew:3056    return DeclSpecContext::DSC_new;3057  case DeclaratorContext::Prototype:3058  case DeclaratorContext::ObjCResult:3059  case DeclaratorContext::ObjCParameter:3060  case DeclaratorContext::KNRTypeList:3061  case DeclaratorContext::FunctionalCast:3062  case DeclaratorContext::Block:3063  case DeclaratorContext::ForInit:3064  case DeclaratorContext::SelectionInit:3065  case DeclaratorContext::CXXCatch:3066  case DeclaratorContext::ObjCCatch:3067  case DeclaratorContext::BlockLiteral:3068  case DeclaratorContext::LambdaExpr:3069  case DeclaratorContext::LambdaExprParameter:3070  case DeclaratorContext::RequiresExpr:3071    return DeclSpecContext::DSC_normal;3072  }3073 3074  llvm_unreachable("Missing DeclaratorContext case");3075}3076 3077ExprResult Parser::ParseAlignArgument(StringRef KWName, SourceLocation Start,3078                                      SourceLocation &EllipsisLoc, bool &IsType,3079                                      ParsedType &TypeResult) {3080  ExprResult ER;3081  if (isTypeIdInParens()) {3082    SourceLocation TypeLoc = Tok.getLocation();3083    ParsedType Ty = ParseTypeName().get();3084    SourceRange TypeRange(Start, Tok.getLocation());3085    if (Actions.ActOnAlignasTypeArgument(KWName, Ty, TypeLoc, TypeRange))3086      return ExprError();3087    TypeResult = Ty;3088    IsType = true;3089  } else {3090    ER = ParseConstantExpression();3091    IsType = false;3092  }3093 3094  if (getLangOpts().CPlusPlus11)3095    TryConsumeToken(tok::ellipsis, EllipsisLoc);3096 3097  return ER;3098}3099 3100void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,3101                                     SourceLocation *EndLoc) {3102  assert(Tok.isOneOf(tok::kw_alignas, tok::kw__Alignas) &&3103         "Not an alignment-specifier!");3104  Token KWTok = Tok;3105  IdentifierInfo *KWName = KWTok.getIdentifierInfo();3106  auto Kind = KWTok.getKind();3107  SourceLocation KWLoc = ConsumeToken();3108 3109  BalancedDelimiterTracker T(*this, tok::l_paren);3110  if (T.expectAndConsume())3111    return;3112 3113  bool IsType;3114  ParsedType TypeResult;3115  SourceLocation EllipsisLoc;3116  ExprResult ArgExpr =3117      ParseAlignArgument(PP.getSpelling(KWTok), T.getOpenLocation(),3118                         EllipsisLoc, IsType, TypeResult);3119  if (ArgExpr.isInvalid()) {3120    T.skipToEnd();3121    return;3122  }3123 3124  T.consumeClose();3125  if (EndLoc)3126    *EndLoc = T.getCloseLocation();3127 3128  if (IsType) {3129    Attrs.addNewTypeAttr(KWName, KWLoc, AttributeScopeInfo(), TypeResult, Kind,3130                         EllipsisLoc);3131  } else {3132    ArgsVector ArgExprs;3133    ArgExprs.push_back(ArgExpr.get());3134    Attrs.addNew(KWName, KWLoc, AttributeScopeInfo(), ArgExprs.data(), 1, Kind,3135                 EllipsisLoc);3136  }3137}3138 3139void Parser::DistributeCLateParsedAttrs(Decl *Dcl,3140                                        LateParsedAttrList *LateAttrs) {3141  if (!LateAttrs)3142    return;3143 3144  if (Dcl) {3145    for (auto *LateAttr : *LateAttrs) {3146      if (LateAttr->Decls.empty())3147        LateAttr->addDecl(Dcl);3148    }3149  }3150}3151 3152void Parser::ParsePtrauthQualifier(ParsedAttributes &Attrs) {3153  assert(Tok.is(tok::kw___ptrauth));3154 3155  IdentifierInfo *KwName = Tok.getIdentifierInfo();3156  SourceLocation KwLoc = ConsumeToken();3157 3158  BalancedDelimiterTracker T(*this, tok::l_paren);3159  if (T.expectAndConsume())3160    return;3161 3162  ArgsVector ArgExprs;3163  do {3164    ExprResult ER = ParseAssignmentExpression();3165    if (ER.isInvalid()) {3166      T.skipToEnd();3167      return;3168    }3169    ArgExprs.push_back(ER.get());3170  } while (TryConsumeToken(tok::comma));3171 3172  T.consumeClose();3173  SourceLocation EndLoc = T.getCloseLocation();3174 3175  if (ArgExprs.empty() || ArgExprs.size() > 3) {3176    Diag(KwLoc, diag::err_ptrauth_qualifier_bad_arg_count);3177    return;3178  }3179 3180  Attrs.addNew(KwName, SourceRange(KwLoc, EndLoc), AttributeScopeInfo(),3181               ArgExprs.data(), ArgExprs.size(),3182               ParsedAttr::Form::Keyword(/*IsAlignAs=*/false,3183                                         /*IsRegularKeywordAttribute=*/false));3184}3185 3186void Parser::ParseBoundsAttribute(IdentifierInfo &AttrName,3187                                  SourceLocation AttrNameLoc,3188                                  ParsedAttributes &Attrs,3189                                  IdentifierInfo *ScopeName,3190                                  SourceLocation ScopeLoc,3191                                  ParsedAttr::Form Form) {3192  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");3193 3194  BalancedDelimiterTracker Parens(*this, tok::l_paren);3195  Parens.consumeOpen();3196 3197  if (Tok.is(tok::r_paren)) {3198    Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);3199    Parens.consumeClose();3200    return;3201  }3202 3203  ArgsVector ArgExprs;3204  // Don't evaluate argument when the attribute is ignored.3205  using ExpressionKind =3206      Sema::ExpressionEvaluationContextRecord::ExpressionKind;3207  EnterExpressionEvaluationContext EC(3208      Actions, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, nullptr,3209      ExpressionKind::EK_AttrArgument);3210 3211  ExprResult ArgExpr = ParseAssignmentExpression();3212  if (ArgExpr.isInvalid()) {3213    Parens.skipToEnd();3214    return;3215  }3216 3217  ArgExprs.push_back(ArgExpr.get());3218  Parens.consumeClose();3219 3220  ASTContext &Ctx = Actions.getASTContext();3221 3222  ArgExprs.push_back(IntegerLiteral::Create(3223      Ctx, llvm::APInt(Ctx.getTypeSize(Ctx.getSizeType()), 0),3224      Ctx.getSizeType(), SourceLocation()));3225 3226  Attrs.addNew(&AttrName, SourceRange(AttrNameLoc, Parens.getCloseLocation()),3227               AttributeScopeInfo(), ArgExprs.data(), ArgExprs.size(), Form);3228}3229 3230ExprResult Parser::ParseExtIntegerArgument() {3231  assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&3232         "Not an extended int type");3233  ConsumeToken();3234 3235  BalancedDelimiterTracker T(*this, tok::l_paren);3236  if (T.expectAndConsume())3237    return ExprError();3238 3239  ExprResult ER = ParseConstantExpression();3240  if (ER.isInvalid()) {3241    T.skipToEnd();3242    return ExprError();3243  }3244 3245  if(T.consumeClose())3246    return ExprError();3247  return ER;3248}3249 3250bool3251Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,3252                                              DeclSpecContext DSContext,3253                                              LateParsedAttrList *LateAttrs) {3254  assert(DS.hasTagDefinition() && "shouldn't call this");3255 3256  bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||3257                          DSContext == DeclSpecContext::DSC_top_level);3258 3259  if (getLangOpts().CPlusPlus &&3260      Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,3261                  tok::annot_template_id) &&3262      TryAnnotateCXXScopeToken(EnteringContext)) {3263    SkipMalformedDecl();3264    return true;3265  }3266 3267  bool HasScope = Tok.is(tok::annot_cxxscope);3268  // Make a copy in case GetLookAheadToken invalidates the result of NextToken.3269  Token AfterScope = HasScope ? NextToken() : Tok;3270 3271  // Determine whether the following tokens could possibly be a3272  // declarator.3273  bool MightBeDeclarator = true;3274  if (Tok.isOneOf(tok::kw_typename, tok::annot_typename)) {3275    // A declarator-id can't start with 'typename'.3276    MightBeDeclarator = false;3277  } else if (AfterScope.is(tok::annot_template_id)) {3278    // If we have a type expressed as a template-id, this cannot be a3279    // declarator-id (such a type cannot be redeclared in a simple-declaration).3280    TemplateIdAnnotation *Annot =3281        static_cast<TemplateIdAnnotation *>(AfterScope.getAnnotationValue());3282    if (Annot->Kind == TNK_Type_template)3283      MightBeDeclarator = false;3284  } else if (AfterScope.is(tok::identifier)) {3285    const Token &Next = HasScope ? GetLookAheadToken(2) : NextToken();3286 3287    // These tokens cannot come after the declarator-id in a3288    // simple-declaration, and are likely to come after a type-specifier.3289    if (Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,3290                     tok::annot_cxxscope, tok::coloncolon)) {3291      // Missing a semicolon.3292      MightBeDeclarator = false;3293    } else if (HasScope) {3294      // If the declarator-id has a scope specifier, it must redeclare a3295      // previously-declared entity. If that's a type (and this is not a3296      // typedef), that's an error.3297      CXXScopeSpec SS;3298      Actions.RestoreNestedNameSpecifierAnnotation(3299          Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);3300      IdentifierInfo *Name = AfterScope.getIdentifierInfo();3301      Sema::NameClassification Classification = Actions.ClassifyName(3302          getCurScope(), SS, Name, AfterScope.getLocation(), Next,3303          /*CCC=*/nullptr);3304      switch (Classification.getKind()) {3305      case NameClassificationKind::Error:3306        SkipMalformedDecl();3307        return true;3308 3309      case NameClassificationKind::Keyword:3310        llvm_unreachable("typo correction is not possible here");3311 3312      case NameClassificationKind::Type:3313      case NameClassificationKind::TypeTemplate:3314      case NameClassificationKind::UndeclaredNonType:3315      case NameClassificationKind::UndeclaredTemplate:3316      case NameClassificationKind::Concept:3317        // Not a previously-declared non-type entity.3318        MightBeDeclarator = false;3319        break;3320 3321      case NameClassificationKind::Unknown:3322      case NameClassificationKind::NonType:3323      case NameClassificationKind::DependentNonType:3324      case NameClassificationKind::OverloadSet:3325      case NameClassificationKind::VarTemplate:3326      case NameClassificationKind::FunctionTemplate:3327        // Might be a redeclaration of a prior entity.3328        break;3329      }3330    }3331  }3332 3333  if (MightBeDeclarator)3334    return false;3335 3336  const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();3337  Diag(PP.getLocForEndOfToken(DS.getRepAsDecl()->getEndLoc()),3338       diag::err_expected_after)3339      << DeclSpec::getSpecifierName(DS.getTypeSpecType(), PPol) << tok::semi;3340 3341  // Try to recover from the typo, by dropping the tag definition and parsing3342  // the problematic tokens as a type.3343  //3344  // FIXME: Split the DeclSpec into pieces for the standalone3345  // declaration and pieces for the following declaration, instead3346  // of assuming that all the other pieces attach to new declaration,3347  // and call ParsedFreeStandingDeclSpec as appropriate.3348  DS.ClearTypeSpecType();3349  ParsedTemplateInfo NotATemplate;3350  ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);3351  return false;3352}3353 3354void Parser::ParseDeclarationSpecifiers(3355    DeclSpec &DS, ParsedTemplateInfo &TemplateInfo, AccessSpecifier AS,3356    DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,3357    ImplicitTypenameContext AllowImplicitTypename) {3358  if (DS.getSourceRange().isInvalid()) {3359    // Start the range at the current token but make the end of the range3360    // invalid.  This will make the entire range invalid unless we successfully3361    // consume a token.3362    DS.SetRangeStart(Tok.getLocation());3363    DS.SetRangeEnd(SourceLocation());3364  }3365 3366  // If we are in a operator context, convert it back into a type specifier3367  // context for better error handling later on.3368  if (DSContext == DeclSpecContext::DSC_conv_operator) {3369    // No implicit typename here.3370    AllowImplicitTypename = ImplicitTypenameContext::No;3371    DSContext = DeclSpecContext::DSC_type_specifier;3372  }3373 3374  bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||3375                          DSContext == DeclSpecContext::DSC_top_level);3376  bool AttrsLastTime = false;3377  ParsedAttributes attrs(AttrFactory);3378  // We use Sema's policy to get bool macros right.3379  PrintingPolicy Policy = Actions.getPrintingPolicy();3380  while (true) {3381    bool isInvalid = false;3382    bool isStorageClass = false;3383    const char *PrevSpec = nullptr;3384    unsigned DiagID = 0;3385 3386    // This value needs to be set to the location of the last token if the last3387    // token of the specifier is already consumed.3388    SourceLocation ConsumedEnd;3389 3390    // HACK: MSVC doesn't consider _Atomic to be a keyword and its STL3391    // implementation for VS2013 uses _Atomic as an identifier for one of the3392    // classes in <atomic>.3393    //3394    // A typedef declaration containing _Atomic<...> is among the places where3395    // the class is used.  If we are currently parsing such a declaration, treat3396    // the token as an identifier.3397    if (getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&3398        DS.getStorageClassSpec() == clang::DeclSpec::SCS_typedef &&3399        !DS.hasTypeSpecifier() && GetLookAheadToken(1).is(tok::less))3400      Tok.setKind(tok::identifier);3401 3402    SourceLocation Loc = Tok.getLocation();3403 3404    // Helper for image types in OpenCL.3405    auto handleOpenCLImageKW = [&] (StringRef Ext, TypeSpecifierType ImageTypeSpec) {3406      // Check if the image type is supported and otherwise turn the keyword into an identifier3407      // because image types from extensions are not reserved identifiers.3408      if (!StringRef(Ext).empty() && !getActions().getOpenCLOptions().isSupported(Ext, getLangOpts())) {3409        Tok.getIdentifierInfo()->revertTokenIDToIdentifier();3410        Tok.setKind(tok::identifier);3411        return false;3412      }3413      isInvalid = DS.SetTypeSpecType(ImageTypeSpec, Loc, PrevSpec, DiagID, Policy);3414      return true;3415    };3416 3417    // Turn off usual access checking for template specializations and3418    // instantiations.3419    bool IsTemplateSpecOrInst =3420        (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation ||3421         TemplateInfo.Kind == ParsedTemplateKind::ExplicitSpecialization);3422 3423    switch (Tok.getKind()) {3424    default:3425      if (Tok.isRegularKeywordAttribute())3426        goto Attribute;3427 3428    DoneWithDeclSpec:3429      if (!AttrsLastTime)3430        ProhibitAttributes(attrs);3431      else {3432        // Reject C++11 / C23 attributes that aren't type attributes.3433        for (const ParsedAttr &PA : attrs) {3434          if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&3435              !PA.isRegularKeywordAttribute())3436            continue;3437          if (PA.getKind() == ParsedAttr::UnknownAttribute)3438            // We will warn about the unknown attribute elsewhere (in3439            // SemaDeclAttr.cpp)3440            continue;3441          // GCC ignores this attribute when placed on the DeclSpec in [[]]3442          // syntax, so we do the same.3443          if (PA.getKind() == ParsedAttr::AT_VectorSize) {3444            Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;3445            PA.setInvalid();3446            continue;3447          }3448          // We reject AT_LifetimeBound and AT_AnyX86NoCfCheck, even though they3449          // are type attributes, because we historically haven't allowed these3450          // to be used as type attributes in C++11 / C23 syntax.3451          if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&3452              PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)3453            continue;3454 3455          if (PA.getKind() == ParsedAttr::AT_LifetimeBound)3456            Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type)3457                << PA << PA.isRegularKeywordAttribute()3458                << ExpectedParameterOrImplicitObjectParameter;3459          else3460            Diag(PA.getLoc(), diag::err_attribute_not_type_attr)3461                << PA << PA.isRegularKeywordAttribute();3462          PA.setInvalid();3463        }3464 3465        DS.takeAttributesAppendingingFrom(attrs);3466      }3467 3468      // If this is not a declaration specifier token, we're done reading decl3469      // specifiers.  First verify that DeclSpec's are consistent.3470      DS.Finish(Actions, Policy);3471      return;3472 3473    // alignment-specifier3474    case tok::kw__Alignas:3475      diagnoseUseOfC11Keyword(Tok);3476      [[fallthrough]];3477    case tok::kw_alignas:3478      // _Alignas and alignas (C23, not C++) should parse the same way. The C++3479      // parsing for alignas happens through the usual attribute parsing. This3480      // ensures that an alignas specifier can appear in a type position in C3481      // despite that not being valid in C++.3482      if (getLangOpts().C23 || Tok.getKind() == tok::kw__Alignas) {3483        if (Tok.getKind() == tok::kw_alignas)3484          Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();3485        ParseAlignmentSpecifier(DS.getAttributes());3486        continue;3487      }3488      [[fallthrough]];3489    case tok::l_square:3490      if (!isAllowedCXX11AttributeSpecifier())3491        goto DoneWithDeclSpec;3492 3493    Attribute:3494      ProhibitAttributes(attrs);3495      // FIXME: It would be good to recover by accepting the attributes,3496      //        but attempting to do that now would cause serious3497      //        madness in terms of diagnostics.3498      attrs.clear();3499      attrs.Range = SourceRange();3500 3501      ParseCXX11Attributes(attrs);3502      AttrsLastTime = true;3503      continue;3504 3505    case tok::code_completion: {3506      SemaCodeCompletion::ParserCompletionContext CCC =3507          SemaCodeCompletion::PCC_Namespace;3508      if (DS.hasTypeSpecifier()) {3509        bool AllowNonIdentifiers3510          = (getCurScope()->getFlags() & (Scope::ControlScope |3511                                          Scope::BlockScope |3512                                          Scope::TemplateParamScope |3513                                          Scope::FunctionPrototypeScope |3514                                          Scope::AtCatchScope)) == 0;3515        bool AllowNestedNameSpecifiers3516          = DSContext == DeclSpecContext::DSC_top_level ||3517            (DSContext == DeclSpecContext::DSC_class && DS.isFriendSpecified());3518 3519        cutOffParsing();3520        Actions.CodeCompletion().CodeCompleteDeclSpec(3521            getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);3522        return;3523      }3524 3525      // Class context can appear inside a function/block, so prioritise that.3526      if (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate)3527        CCC = DSContext == DeclSpecContext::DSC_class3528                  ? SemaCodeCompletion::PCC_MemberTemplate3529                  : SemaCodeCompletion::PCC_Template;3530      else if (DSContext == DeclSpecContext::DSC_class)3531        CCC = SemaCodeCompletion::PCC_Class;3532      else if (getCurScope()->getFnParent() || getCurScope()->getBlockParent())3533        CCC = SemaCodeCompletion::PCC_LocalDeclarationSpecifiers;3534      else if (CurParsedObjCImpl)3535        CCC = SemaCodeCompletion::PCC_ObjCImplementation;3536 3537      cutOffParsing();3538      Actions.CodeCompletion().CodeCompleteOrdinaryName(getCurScope(), CCC);3539      return;3540    }3541 3542    case tok::coloncolon: // ::foo::bar3543      // C++ scope specifier.  Annotate and loop, or bail out on error.3544      if (getLangOpts().CPlusPlus &&3545          TryAnnotateCXXScopeToken(EnteringContext)) {3546        if (!DS.hasTypeSpecifier())3547          DS.SetTypeSpecError();3548        goto DoneWithDeclSpec;3549      }3550      if (Tok.is(tok::coloncolon)) // ::new or ::delete3551        goto DoneWithDeclSpec;3552      continue;3553 3554    case tok::annot_cxxscope: {3555      if (DS.hasTypeSpecifier() || DS.isTypeAltiVecVector())3556        goto DoneWithDeclSpec;3557 3558      CXXScopeSpec SS;3559      if (TemplateInfo.TemplateParams)3560        SS.setTemplateParamLists(*TemplateInfo.TemplateParams);3561      Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),3562                                                   Tok.getAnnotationRange(),3563                                                   SS);3564 3565      // We are looking for a qualified typename.3566      Token Next = NextToken();3567 3568      TemplateIdAnnotation *TemplateId = Next.is(tok::annot_template_id)3569                                             ? takeTemplateIdAnnotation(Next)3570                                             : nullptr;3571      if (TemplateId && TemplateId->hasInvalidName()) {3572        // We found something like 'T::U<Args> x', but U is not a template.3573        // Assume it was supposed to be a type.3574        DS.SetTypeSpecError();3575        ConsumeAnnotationToken();3576        break;3577      }3578 3579      if (TemplateId && TemplateId->Kind == TNK_Type_template) {3580        // We have a qualified template-id, e.g., N::A<int>3581 3582        // If this would be a valid constructor declaration with template3583        // arguments, we will reject the attempt to form an invalid type-id3584        // referring to the injected-class-name when we annotate the token,3585        // per C++ [class.qual]p2.3586        //3587        // To improve diagnostics for this case, parse the declaration as a3588        // constructor (and reject the extra template arguments later).3589        if ((DSContext == DeclSpecContext::DSC_top_level ||3590             DSContext == DeclSpecContext::DSC_class) &&3591            TemplateId->Name &&3592            Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS) &&3593            isConstructorDeclarator(/*Unqualified=*/false,3594                                    /*DeductionGuide=*/false,3595                                    DS.isFriendSpecified())) {3596          // The user meant this to be an out-of-line constructor3597          // definition, but template arguments are not allowed3598          // there.  Just allow this as a constructor; we'll3599          // complain about it later.3600          goto DoneWithDeclSpec;3601        }3602 3603        DS.getTypeSpecScope() = SS;3604        ConsumeAnnotationToken(); // The C++ scope.3605        assert(Tok.is(tok::annot_template_id) &&3606               "ParseOptionalCXXScopeSpecifier not working");3607        AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);3608        continue;3609      }3610 3611      if (TemplateId && TemplateId->Kind == TNK_Concept_template) {3612        DS.getTypeSpecScope() = SS;3613        // This is probably a qualified placeholder-specifier, e.g., ::C<int>3614        // auto ... Consume the scope annotation and continue to consume the3615        // template-id as a placeholder-specifier. Let the next iteration3616        // diagnose a missing auto.3617        ConsumeAnnotationToken();3618        continue;3619      }3620 3621      if (Next.is(tok::annot_typename)) {3622        DS.getTypeSpecScope() = SS;3623        ConsumeAnnotationToken(); // The C++ scope.3624        TypeResult T = getTypeAnnotation(Tok);3625        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename,3626                                       Tok.getAnnotationEndLoc(),3627                                       PrevSpec, DiagID, T, Policy);3628        if (isInvalid)3629          break;3630        DS.SetRangeEnd(Tok.getAnnotationEndLoc());3631        ConsumeAnnotationToken(); // The typename3632      }3633 3634      if (AllowImplicitTypename == ImplicitTypenameContext::Yes &&3635          Next.is(tok::annot_template_id) &&3636          static_cast<TemplateIdAnnotation *>(Next.getAnnotationValue())3637                  ->Kind == TNK_Dependent_template_name) {3638        DS.getTypeSpecScope() = SS;3639        ConsumeAnnotationToken(); // The C++ scope.3640        AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);3641        continue;3642      }3643 3644      if (Next.isNot(tok::identifier))3645        goto DoneWithDeclSpec;3646 3647      // Check whether this is a constructor declaration. If we're in a3648      // context where the identifier could be a class name, and it has the3649      // shape of a constructor declaration, process it as one.3650      if ((DSContext == DeclSpecContext::DSC_top_level ||3651           DSContext == DeclSpecContext::DSC_class) &&3652          Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(),3653                                     &SS) &&3654          isConstructorDeclarator(/*Unqualified=*/false,3655                                  /*DeductionGuide=*/false,3656                                  DS.isFriendSpecified(),3657                                  &TemplateInfo))3658        goto DoneWithDeclSpec;3659 3660      // C++20 [temp.spec] 13.9/6.3661      // This disables the access checking rules for function template explicit3662      // instantiation and explicit specialization:3663      // - `return type`.3664      SuppressAccessChecks SAC(*this, IsTemplateSpecOrInst);3665 3666      ParsedType TypeRep = Actions.getTypeName(3667          *Next.getIdentifierInfo(), Next.getLocation(), getCurScope(), &SS,3668          false, false, nullptr,3669          /*IsCtorOrDtorName=*/false,3670          /*WantNontrivialTypeSourceInfo=*/true,3671          isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);3672 3673      if (IsTemplateSpecOrInst)3674        SAC.done();3675 3676      // If the referenced identifier is not a type, then this declspec is3677      // erroneous: We already checked about that it has no type specifier, and3678      // C++ doesn't have implicit int.  Diagnose it as a typo w.r.t. to the3679      // typename.3680      if (!TypeRep) {3681        if (TryAnnotateTypeConstraint())3682          goto DoneWithDeclSpec;3683        if (Tok.isNot(tok::annot_cxxscope) ||3684            NextToken().isNot(tok::identifier))3685          continue;3686        // Eat the scope spec so the identifier is current.3687        ConsumeAnnotationToken();3688        ParsedAttributes Attrs(AttrFactory);3689        if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {3690          if (!Attrs.empty()) {3691            AttrsLastTime = true;3692            attrs.takeAllAppendingFrom(Attrs);3693          }3694          continue;3695        }3696        goto DoneWithDeclSpec;3697      }3698 3699      DS.getTypeSpecScope() = SS;3700      ConsumeAnnotationToken(); // The C++ scope.3701 3702      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,3703                                     DiagID, TypeRep, Policy);3704      if (isInvalid)3705        break;3706 3707      DS.SetRangeEnd(Tok.getLocation());3708      ConsumeToken(); // The typename.3709 3710      continue;3711    }3712 3713    case tok::annot_typename: {3714      // If we've previously seen a tag definition, we were almost surely3715      // missing a semicolon after it.3716      if (DS.hasTypeSpecifier() && DS.hasTagDefinition())3717        goto DoneWithDeclSpec;3718 3719      TypeResult T = getTypeAnnotation(Tok);3720      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,3721                                     DiagID, T, Policy);3722      if (isInvalid)3723        break;3724 3725      DS.SetRangeEnd(Tok.getAnnotationEndLoc());3726      ConsumeAnnotationToken(); // The typename3727 3728      continue;3729    }3730 3731    case tok::kw___is_signed:3732      // HACK: before 2022-12, libstdc++ uses __is_signed as an identifier,3733      // but Clang typically treats it as a trait.3734      // If we see __is_signed as it appears in libstdc++, e.g.,3735      //3736      //   static const bool __is_signed;3737      //3738      // then treat __is_signed as an identifier rather than as a keyword.3739      // This was fixed by libstdc++ in December 2022.3740      if (DS.getTypeSpecType() == TST_bool &&3741          DS.getTypeQualifiers() == DeclSpec::TQ_const &&3742          DS.getStorageClassSpec() == DeclSpec::SCS_static)3743        TryKeywordIdentFallback(true);3744 3745      // We're done with the declaration-specifiers.3746      goto DoneWithDeclSpec;3747 3748      // typedef-name3749    case tok::kw___super:3750    case tok::kw_decltype:3751    case tok::identifier:3752    ParseIdentifier: {3753      // This identifier can only be a typedef name if we haven't already seen3754      // a type-specifier.  Without this check we misparse:3755      //  typedef int X; struct Y { short X; };  as 'short int'.3756      if (DS.hasTypeSpecifier())3757        goto DoneWithDeclSpec;3758 3759      // If the token is an identifier named "__declspec" and Microsoft3760      // extensions are not enabled, it is likely that there will be cascading3761      // parse errors if this really is a __declspec attribute. Attempt to3762      // recognize that scenario and recover gracefully.3763      if (!getLangOpts().DeclSpecKeyword && Tok.is(tok::identifier) &&3764          Tok.getIdentifierInfo()->getName() == "__declspec") {3765        Diag(Loc, diag::err_ms_attributes_not_enabled);3766 3767        // The next token should be an open paren. If it is, eat the entire3768        // attribute declaration and continue.3769        if (NextToken().is(tok::l_paren)) {3770          // Consume the __declspec identifier.3771          ConsumeToken();3772 3773          // Eat the parens and everything between them.3774          BalancedDelimiterTracker T(*this, tok::l_paren);3775          if (T.consumeOpen()) {3776            assert(false && "Not a left paren?");3777            return;3778          }3779          T.skipToEnd();3780          continue;3781        }3782      }3783 3784      // In C++, check to see if this is a scope specifier like foo::bar::, if3785      // so handle it as such.  This is important for ctor parsing.3786      if (getLangOpts().CPlusPlus) {3787        // C++20 [temp.spec] 13.9/6.3788        // This disables the access checking rules for function template3789        // explicit instantiation and explicit specialization:3790        // - `return type`.3791        SuppressAccessChecks SAC(*this, IsTemplateSpecOrInst);3792 3793        const bool Success = TryAnnotateCXXScopeToken(EnteringContext);3794 3795        if (IsTemplateSpecOrInst)3796          SAC.done();3797 3798        if (Success) {3799          if (IsTemplateSpecOrInst)3800            SAC.redelay();3801          DS.SetTypeSpecError();3802          goto DoneWithDeclSpec;3803        }3804 3805        if (!Tok.is(tok::identifier))3806          continue;3807      }3808 3809      // Check for need to substitute AltiVec keyword tokens.3810      if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))3811        break;3812 3813      // [AltiVec] 2.2: [If the 'vector' specifier is used] The syntax does not3814      //                allow the use of a typedef name as a type specifier.3815      if (DS.isTypeAltiVecVector())3816        goto DoneWithDeclSpec;3817 3818      if (DSContext == DeclSpecContext::DSC_objc_method_result &&3819          isObjCInstancetype()) {3820        ParsedType TypeRep = Actions.ObjC().ActOnObjCInstanceType(Loc);3821        assert(TypeRep);3822        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,3823                                       DiagID, TypeRep, Policy);3824        if (isInvalid)3825          break;3826 3827        DS.SetRangeEnd(Loc);3828        ConsumeToken();3829        continue;3830      }3831 3832      // If we're in a context where the identifier could be a class name,3833      // check whether this is a constructor declaration.3834      if (getLangOpts().CPlusPlus && DSContext == DeclSpecContext::DSC_class &&3835          Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&3836          isConstructorDeclarator(/*Unqualified=*/true,3837                                  /*DeductionGuide=*/false,3838                                  DS.isFriendSpecified()))3839        goto DoneWithDeclSpec;3840 3841      ParsedType TypeRep = Actions.getTypeName(3842          *Tok.getIdentifierInfo(), Tok.getLocation(), getCurScope(), nullptr,3843          false, false, nullptr, false, false,3844          isClassTemplateDeductionContext(DSContext));3845 3846      // If this is not a typedef name, don't parse it as part of the declspec,3847      // it must be an implicit int or an error.3848      if (!TypeRep) {3849        if (TryAnnotateTypeConstraint())3850          goto DoneWithDeclSpec;3851        if (Tok.isNot(tok::identifier))3852          continue;3853        ParsedAttributes Attrs(AttrFactory);3854        if (ParseImplicitInt(DS, nullptr, TemplateInfo, AS, DSContext, Attrs)) {3855          if (!Attrs.empty()) {3856            AttrsLastTime = true;3857            attrs.takeAllAppendingFrom(Attrs);3858          }3859          continue;3860        }3861        goto DoneWithDeclSpec;3862      }3863 3864      // Likewise, if this is a context where the identifier could be a template3865      // name, check whether this is a deduction guide declaration.3866      CXXScopeSpec SS;3867      if (getLangOpts().CPlusPlus17 &&3868          (DSContext == DeclSpecContext::DSC_class ||3869           DSContext == DeclSpecContext::DSC_top_level) &&3870          Actions.isDeductionGuideName(getCurScope(), *Tok.getIdentifierInfo(),3871                                       Tok.getLocation(), SS) &&3872          isConstructorDeclarator(/*Unqualified*/ true,3873                                  /*DeductionGuide*/ true))3874        goto DoneWithDeclSpec;3875 3876      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,3877                                     DiagID, TypeRep, Policy);3878      if (isInvalid)3879        break;3880 3881      DS.SetRangeEnd(Tok.getLocation());3882      ConsumeToken(); // The identifier3883 3884      // Objective-C supports type arguments and protocol references3885      // following an Objective-C object or object pointer3886      // type. Handle either one of them.3887      if (Tok.is(tok::less) && getLangOpts().ObjC) {3888        SourceLocation NewEndLoc;3889        TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(3890                                  Loc, TypeRep, /*consumeLastToken=*/true,3891                                  NewEndLoc);3892        if (NewTypeRep.isUsable()) {3893          DS.UpdateTypeRep(NewTypeRep.get());3894          DS.SetRangeEnd(NewEndLoc);3895        }3896      }3897 3898      // Need to support trailing type qualifiers (e.g. "id<p> const").3899      // If a type specifier follows, it will be diagnosed elsewhere.3900      continue;3901    }3902 3903      // type-name or placeholder-specifier3904    case tok::annot_template_id: {3905      TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);3906 3907      if (TemplateId->hasInvalidName()) {3908        DS.SetTypeSpecError();3909        break;3910      }3911 3912      if (TemplateId->Kind == TNK_Concept_template) {3913        // If we've already diagnosed that this type-constraint has invalid3914        // arguments, drop it and just form 'auto' or 'decltype(auto)'.3915        if (TemplateId->hasInvalidArgs())3916          TemplateId = nullptr;3917 3918        // Any of the following tokens are likely the start of the user3919        // forgetting 'auto' or 'decltype(auto)', so diagnose.3920        // Note: if updating this list, please make sure we update3921        // isCXXDeclarationSpecifier's check for IsPlaceholderSpecifier to have3922        // a matching list.3923        if (NextToken().isOneOf(tok::identifier, tok::kw_const,3924                                tok::kw_volatile, tok::kw_restrict, tok::amp,3925                                tok::ampamp)) {3926          Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)3927              << FixItHint::CreateInsertion(NextToken().getLocation(), "auto");3928          // Attempt to continue as if 'auto' was placed here.3929          isInvalid = DS.SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID,3930                                         TemplateId, Policy);3931          break;3932        }3933        if (!NextToken().isOneOf(tok::kw_auto, tok::kw_decltype))3934            goto DoneWithDeclSpec;3935 3936        if (TemplateId && !isInvalid && Actions.CheckTypeConstraint(TemplateId))3937            TemplateId = nullptr;3938 3939        ConsumeAnnotationToken();3940        SourceLocation AutoLoc = Tok.getLocation();3941        if (TryConsumeToken(tok::kw_decltype)) {3942          BalancedDelimiterTracker Tracker(*this, tok::l_paren);3943          if (Tracker.consumeOpen()) {3944            // Something like `void foo(Iterator decltype i)`3945            Diag(Tok, diag::err_expected) << tok::l_paren;3946          } else {3947            if (!TryConsumeToken(tok::kw_auto)) {3948              // Something like `void foo(Iterator decltype(int) i)`3949              Tracker.skipToEnd();3950              Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)3951                << FixItHint::CreateReplacement(SourceRange(AutoLoc,3952                                                            Tok.getLocation()),3953                                                "auto");3954            } else {3955              Tracker.consumeClose();3956            }3957          }3958          ConsumedEnd = Tok.getLocation();3959          DS.setTypeArgumentRange(Tracker.getRange());3960          // Even if something went wrong above, continue as if we've seen3961          // `decltype(auto)`.3962          isInvalid = DS.SetTypeSpecType(TST_decltype_auto, Loc, PrevSpec,3963                                         DiagID, TemplateId, Policy);3964        } else {3965          isInvalid = DS.SetTypeSpecType(TST_auto, AutoLoc, PrevSpec, DiagID,3966                                         TemplateId, Policy);3967        }3968        break;3969      }3970 3971      if (TemplateId->Kind != TNK_Type_template &&3972          TemplateId->Kind != TNK_Undeclared_template) {3973        // This template-id does not refer to a type name, so we're3974        // done with the type-specifiers.3975        goto DoneWithDeclSpec;3976      }3977 3978      // If we're in a context where the template-id could be a3979      // constructor name or specialization, check whether this is a3980      // constructor declaration.3981      if (getLangOpts().CPlusPlus && DSContext == DeclSpecContext::DSC_class &&3982          Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) &&3983          isConstructorDeclarator(/*Unqualified=*/true,3984                                  /*DeductionGuide=*/false,3985                                  DS.isFriendSpecified()))3986        goto DoneWithDeclSpec;3987 3988      // Turn the template-id annotation token into a type annotation3989      // token, then try again to parse it as a type-specifier.3990      CXXScopeSpec SS;3991      AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);3992      continue;3993    }3994 3995    // Attributes support.3996    case tok::kw___attribute:3997    case tok::kw___declspec:3998      ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.getAttributes(), LateAttrs);3999      continue;4000 4001    // Microsoft single token adornments.4002    case tok::kw___forceinline: {4003      isInvalid = DS.setFunctionSpecForceInline(Loc, PrevSpec, DiagID);4004      IdentifierInfo *AttrName = Tok.getIdentifierInfo();4005      SourceLocation AttrNameLoc = Tok.getLocation();4006      DS.getAttributes().addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),4007                                nullptr, 0, tok::kw___forceinline);4008      break;4009    }4010 4011    case tok::kw___unaligned:4012      isInvalid = DS.SetTypeQual(DeclSpec::TQ_unaligned, Loc, PrevSpec, DiagID,4013                                 getLangOpts());4014      break;4015 4016    // __ptrauth qualifier.4017    case tok::kw___ptrauth:4018      ParsePtrauthQualifier(DS.getAttributes());4019      continue;4020 4021    case tok::kw___sptr:4022    case tok::kw___uptr:4023    case tok::kw___ptr64:4024    case tok::kw___ptr32:4025    case tok::kw___w64:4026    case tok::kw___cdecl:4027    case tok::kw___stdcall:4028    case tok::kw___fastcall:4029    case tok::kw___thiscall:4030    case tok::kw___regcall:4031    case tok::kw___vectorcall:4032      ParseMicrosoftTypeAttributes(DS.getAttributes());4033      continue;4034 4035    case tok::kw___funcref:4036      ParseWebAssemblyFuncrefTypeAttribute(DS.getAttributes());4037      continue;4038 4039    // Borland single token adornments.4040    case tok::kw___pascal:4041      ParseBorlandTypeAttributes(DS.getAttributes());4042      continue;4043 4044    // OpenCL single token adornments.4045    case tok::kw___kernel:4046      ParseOpenCLKernelAttributes(DS.getAttributes());4047      continue;4048 4049    // CUDA/HIP single token adornments.4050    case tok::kw___noinline__:4051      ParseCUDAFunctionAttributes(DS.getAttributes());4052      continue;4053 4054    // Nullability type specifiers.4055    case tok::kw__Nonnull:4056    case tok::kw__Nullable:4057    case tok::kw__Nullable_result:4058    case tok::kw__Null_unspecified:4059      ParseNullabilityTypeSpecifiers(DS.getAttributes());4060      continue;4061 4062    // Objective-C 'kindof' types.4063    case tok::kw___kindof:4064      DS.getAttributes().addNew(Tok.getIdentifierInfo(), Loc,4065                                AttributeScopeInfo(), nullptr, 0,4066                                tok::kw___kindof);4067      (void)ConsumeToken();4068      continue;4069 4070    // storage-class-specifier4071    case tok::kw_typedef:4072      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,4073                                         PrevSpec, DiagID, Policy);4074      isStorageClass = true;4075      break;4076    case tok::kw_extern:4077      if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)4078        Diag(Tok, diag::ext_thread_before) << "extern";4079      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,4080                                         PrevSpec, DiagID, Policy);4081      isStorageClass = true;4082      break;4083    case tok::kw___private_extern__:4084      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern,4085                                         Loc, PrevSpec, DiagID, Policy);4086      isStorageClass = true;4087      break;4088    case tok::kw_static:4089      if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)4090        Diag(Tok, diag::ext_thread_before) << "static";4091      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,4092                                         PrevSpec, DiagID, Policy);4093      isStorageClass = true;4094      break;4095    case tok::kw_auto:4096      if (getLangOpts().CPlusPlus11 || getLangOpts().C23) {4097        if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {4098          isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,4099                                             PrevSpec, DiagID, Policy);4100          if (!isInvalid && !getLangOpts().C23)4101            Diag(Tok, diag::ext_auto_storage_class)4102              << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());4103        } else4104          isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,4105                                         DiagID, Policy);4106      } else4107        isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,4108                                           PrevSpec, DiagID, Policy);4109      isStorageClass = true;4110      break;4111    case tok::kw___auto_type:4112      Diag(Tok, diag::ext_auto_type);4113      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto_type, Loc, PrevSpec,4114                                     DiagID, Policy);4115      break;4116    case tok::kw_register:4117      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,4118                                         PrevSpec, DiagID, Policy);4119      isStorageClass = true;4120      break;4121    case tok::kw_mutable:4122      isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc,4123                                         PrevSpec, DiagID, Policy);4124      isStorageClass = true;4125      break;4126    case tok::kw___thread:4127      isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS___thread, Loc,4128                                               PrevSpec, DiagID);4129      isStorageClass = true;4130      break;4131    case tok::kw_thread_local:4132      if (getLangOpts().C23)4133        Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();4134      // We map thread_local to _Thread_local in C23 mode so it retains the C4135      // semantics rather than getting the C++ semantics.4136      // FIXME: diagnostics will show _Thread_local when the user wrote4137      // thread_local in source in C23 mode; we need some general way to4138      // identify which way the user spelled the keyword in source.4139      isInvalid = DS.SetStorageClassSpecThread(4140          getLangOpts().C23 ? DeclSpec::TSCS__Thread_local4141                            : DeclSpec::TSCS_thread_local,4142          Loc, PrevSpec, DiagID);4143      isStorageClass = true;4144      break;4145    case tok::kw__Thread_local:4146      diagnoseUseOfC11Keyword(Tok);4147      isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS__Thread_local,4148                                               Loc, PrevSpec, DiagID);4149      isStorageClass = true;4150      break;4151 4152    // function-specifier4153    case tok::kw_inline:4154      isInvalid = DS.setFunctionSpecInline(Loc, PrevSpec, DiagID);4155      break;4156    case tok::kw_virtual:4157      // C++ for OpenCL does not allow virtual function qualifier, to avoid4158      // function pointers restricted in OpenCL v2.0 s6.9.a.4159      if (getLangOpts().OpenCLCPlusPlus &&4160          !getActions().getOpenCLOptions().isAvailableOption(4161              "__cl_clang_function_pointers", getLangOpts())) {4162        DiagID = diag::err_openclcxx_virtual_function;4163        PrevSpec = Tok.getIdentifierInfo()->getNameStart();4164        isInvalid = true;4165      } else if (getLangOpts().HLSL) {4166        DiagID = diag::err_hlsl_virtual_function;4167        PrevSpec = Tok.getIdentifierInfo()->getNameStart();4168        isInvalid = true;4169      } else {4170        isInvalid = DS.setFunctionSpecVirtual(Loc, PrevSpec, DiagID);4171      }4172      break;4173    case tok::kw_explicit: {4174      SourceLocation ExplicitLoc = Loc;4175      SourceLocation CloseParenLoc;4176      ExplicitSpecifier ExplicitSpec(nullptr, ExplicitSpecKind::ResolvedTrue);4177      ConsumedEnd = ExplicitLoc;4178      ConsumeToken(); // kw_explicit4179      if (Tok.is(tok::l_paren)) {4180        if (getLangOpts().CPlusPlus20 || isExplicitBool() == TPResult::True) {4181          Diag(Tok.getLocation(), getLangOpts().CPlusPlus204182                                      ? diag::warn_cxx17_compat_explicit_bool4183                                      : diag::ext_explicit_bool);4184 4185          ExprResult ExplicitExpr(static_cast<Expr *>(nullptr));4186          BalancedDelimiterTracker Tracker(*this, tok::l_paren);4187          Tracker.consumeOpen();4188 4189          EnterExpressionEvaluationContext ConstantEvaluated(4190              Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);4191 4192          ExplicitExpr = ParseConstantExpressionInExprEvalContext();4193          ConsumedEnd = Tok.getLocation();4194          if (ExplicitExpr.isUsable()) {4195            CloseParenLoc = Tok.getLocation();4196            Tracker.consumeClose();4197            ExplicitSpec =4198                Actions.ActOnExplicitBoolSpecifier(ExplicitExpr.get());4199          } else4200            Tracker.skipToEnd();4201        } else {4202          Diag(Tok.getLocation(), diag::warn_cxx20_compat_explicit_bool);4203        }4204      }4205      isInvalid = DS.setFunctionSpecExplicit(ExplicitLoc, PrevSpec, DiagID,4206                                             ExplicitSpec, CloseParenLoc);4207      break;4208    }4209    case tok::kw__Noreturn:4210      diagnoseUseOfC11Keyword(Tok);4211      isInvalid = DS.setFunctionSpecNoreturn(Loc, PrevSpec, DiagID);4212      break;4213 4214    // friend4215    case tok::kw_friend:4216      if (DSContext == DeclSpecContext::DSC_class) {4217        isInvalid = DS.SetFriendSpec(Loc, PrevSpec, DiagID);4218        Scope *CurS = getCurScope();4219        if (!isInvalid && CurS)4220          CurS->setFlags(CurS->getFlags() | Scope::FriendScope);4221      } else {4222        PrevSpec = ""; // not actually used by the diagnostic4223        DiagID = diag::err_friend_invalid_in_context;4224        isInvalid = true;4225      }4226      break;4227 4228    // Modules4229    case tok::kw___module_private__:4230      isInvalid = DS.setModulePrivateSpec(Loc, PrevSpec, DiagID);4231      break;4232 4233    // constexpr, consteval, constinit specifiers4234    case tok::kw_constexpr:4235      if (getLangOpts().C23)4236        Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();4237      isInvalid = DS.SetConstexprSpec(ConstexprSpecKind::Constexpr, Loc,4238                                      PrevSpec, DiagID);4239      break;4240    case tok::kw_consteval:4241      isInvalid = DS.SetConstexprSpec(ConstexprSpecKind::Consteval, Loc,4242                                      PrevSpec, DiagID);4243      break;4244    case tok::kw_constinit:4245      isInvalid = DS.SetConstexprSpec(ConstexprSpecKind::Constinit, Loc,4246                                      PrevSpec, DiagID);4247      break;4248 4249    // type-specifier4250    case tok::kw_short:4251      if (!getLangOpts().NativeInt16Type) {4252        Diag(Tok, diag::err_unknown_typename) << Tok.getName();4253        DS.SetTypeSpecError();4254        DS.SetRangeEnd(Tok.getLocation());4255        ConsumeToken();4256        goto DoneWithDeclSpec;4257      }4258      isInvalid = DS.SetTypeSpecWidth(TypeSpecifierWidth::Short, Loc, PrevSpec,4259                                      DiagID, Policy);4260      break;4261    case tok::kw_long:4262      if (DS.getTypeSpecWidth() != TypeSpecifierWidth::Long)4263        isInvalid = DS.SetTypeSpecWidth(TypeSpecifierWidth::Long, Loc, PrevSpec,4264                                        DiagID, Policy);4265      else4266        isInvalid = DS.SetTypeSpecWidth(TypeSpecifierWidth::LongLong, Loc,4267                                        PrevSpec, DiagID, Policy);4268      break;4269    case tok::kw___int64:4270      isInvalid = DS.SetTypeSpecWidth(TypeSpecifierWidth::LongLong, Loc,4271                                      PrevSpec, DiagID, Policy);4272      break;4273    case tok::kw_signed:4274      isInvalid =4275          DS.SetTypeSpecSign(TypeSpecifierSign::Signed, Loc, PrevSpec, DiagID);4276      break;4277    case tok::kw_unsigned:4278      isInvalid = DS.SetTypeSpecSign(TypeSpecifierSign::Unsigned, Loc, PrevSpec,4279                                     DiagID);4280      break;4281    case tok::kw__Complex:4282      if (!getLangOpts().C99)4283        Diag(Tok, diag::ext_c99_feature) << Tok.getName();4284      isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,4285                                        DiagID);4286      break;4287    case tok::kw__Imaginary:4288      if (!getLangOpts().C99)4289        Diag(Tok, diag::ext_c99_feature) << Tok.getName();4290      isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,4291                                        DiagID);4292      break;4293    case tok::kw_void:4294      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec,4295                                     DiagID, Policy);4296      break;4297    case tok::kw_char:4298      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec,4299                                     DiagID, Policy);4300      break;4301    case tok::kw_int:4302      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,4303                                     DiagID, Policy);4304      break;4305    case tok::kw__ExtInt:4306    case tok::kw__BitInt: {4307      DiagnoseBitIntUse(Tok);4308      ExprResult ER = ParseExtIntegerArgument();4309      if (ER.isInvalid())4310        continue;4311      isInvalid = DS.SetBitIntType(Loc, ER.get(), PrevSpec, DiagID, Policy);4312      ConsumedEnd = PrevTokLocation;4313      break;4314    }4315    case tok::kw___int128:4316      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec,4317                                     DiagID, Policy);4318      break;4319    case tok::kw_half:4320      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,4321                                     DiagID, Policy);4322      break;4323    case tok::kw___bf16:4324      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_BFloat16, Loc, PrevSpec,4325                                     DiagID, Policy);4326      break;4327    case tok::kw_float:4328      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec,4329                                     DiagID, Policy);4330      break;4331    case tok::kw_double:4332      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,4333                                     DiagID, Policy);4334      break;4335    case tok::kw__Float16:4336      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float16, Loc, PrevSpec,4337                                     DiagID, Policy);4338      break;4339    case tok::kw__Accum:4340      assert(getLangOpts().FixedPoint &&4341             "This keyword is only used when fixed point types are enabled "4342             "with `-ffixed-point`");4343      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_accum, Loc, PrevSpec, DiagID,4344                                     Policy);4345      break;4346    case tok::kw__Fract:4347      assert(getLangOpts().FixedPoint &&4348             "This keyword is only used when fixed point types are enabled "4349             "with `-ffixed-point`");4350      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_fract, Loc, PrevSpec, DiagID,4351                                     Policy);4352      break;4353    case tok::kw__Sat:4354      assert(getLangOpts().FixedPoint &&4355             "This keyword is only used when fixed point types are enabled "4356             "with `-ffixed-point`");4357      isInvalid = DS.SetTypeSpecSat(Loc, PrevSpec, DiagID);4358      break;4359    case tok::kw___float128:4360      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec,4361                                     DiagID, Policy);4362      break;4363    case tok::kw___ibm128:4364      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_ibm128, Loc, PrevSpec,4365                                     DiagID, Policy);4366      break;4367    case tok::kw_wchar_t:4368      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,4369                                     DiagID, Policy);4370      break;4371    case tok::kw_char8_t:4372      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char8, Loc, PrevSpec,4373                                     DiagID, Policy);4374      break;4375    case tok::kw_char16_t:4376      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec,4377                                     DiagID, Policy);4378      break;4379    case tok::kw_char32_t:4380      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec,4381                                     DiagID, Policy);4382      break;4383    case tok::kw_bool:4384      if (getLangOpts().C23)4385        Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();4386      [[fallthrough]];4387    case tok::kw__Bool:4388      if (Tok.is(tok::kw__Bool) && !getLangOpts().C99)4389        Diag(Tok, diag::ext_c99_feature) << Tok.getName();4390 4391      if (Tok.is(tok::kw_bool) &&4392          DS.getTypeSpecType() != DeclSpec::TST_unspecified &&4393          DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {4394        PrevSpec = ""; // Not used by the diagnostic.4395        DiagID = diag::err_bool_redeclaration;4396        // For better error recovery.4397        Tok.setKind(tok::identifier);4398        isInvalid = true;4399      } else {4400        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec,4401                                       DiagID, Policy);4402      }4403      break;4404    case tok::kw__Decimal32:4405      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,4406                                     DiagID, Policy);4407      break;4408    case tok::kw__Decimal64:4409      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,4410                                     DiagID, Policy);4411      break;4412    case tok::kw__Decimal128:4413      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,4414                                     DiagID, Policy);4415      break;4416    case tok::kw___vector:4417      isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID, Policy);4418      break;4419    case tok::kw___pixel:4420      isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID, Policy);4421      break;4422    case tok::kw___bool:4423      isInvalid = DS.SetTypeAltiVecBool(true, Loc, PrevSpec, DiagID, Policy);4424      break;4425    case tok::kw_pipe:4426      if (!getLangOpts().OpenCL ||4427          getLangOpts().getOpenCLCompatibleVersion() < 200) {4428        // OpenCL 2.0 and later define this keyword. OpenCL 1.2 and earlier4429        // should support the "pipe" word as identifier.4430        Tok.getIdentifierInfo()->revertTokenIDToIdentifier();4431        Tok.setKind(tok::identifier);4432        goto DoneWithDeclSpec;4433      } else if (!getLangOpts().OpenCLPipes) {4434        DiagID = diag::err_opencl_unknown_type_specifier;4435        PrevSpec = Tok.getIdentifierInfo()->getNameStart();4436        isInvalid = true;4437      } else4438        isInvalid = DS.SetTypePipe(true, Loc, PrevSpec, DiagID, Policy);4439      break;4440// We only need to enumerate each image type once.4441#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)4442#define IMAGE_WRITE_TYPE(Type, Id, Ext)4443#define IMAGE_READ_TYPE(ImgType, Id, Ext) \4444    case tok::kw_##ImgType##_t: \4445      if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \4446        goto DoneWithDeclSpec; \4447      break;4448#include "clang/Basic/OpenCLImageTypes.def"4449    case tok::kw___unknown_anytype:4450      isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc,4451                                     PrevSpec, DiagID, Policy);4452      break;4453 4454    // class-specifier:4455    case tok::kw_class:4456    case tok::kw_struct:4457    case tok::kw___interface:4458    case tok::kw_union: {4459      tok::TokenKind Kind = Tok.getKind();4460      ConsumeToken();4461 4462      // These are attributes following class specifiers.4463      // To produce better diagnostic, we parse them when4464      // parsing class specifier.4465      ParsedAttributes Attributes(AttrFactory);4466      ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,4467                          EnteringContext, DSContext, Attributes);4468 4469      // If there are attributes following class specifier,4470      // take them over and handle them here.4471      if (!Attributes.empty()) {4472        AttrsLastTime = true;4473        attrs.takeAllAppendingFrom(Attributes);4474      }4475      continue;4476    }4477 4478    // enum-specifier:4479    case tok::kw_enum:4480      ConsumeToken();4481      ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);4482      continue;4483 4484    // cv-qualifier:4485    case tok::kw_const:4486      isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,4487                                 getLangOpts());4488      break;4489    case tok::kw_volatile:4490      isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,4491                                 getLangOpts());4492      break;4493    case tok::kw_restrict:4494      isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,4495                                 getLangOpts());4496      break;4497 4498    // C++ typename-specifier:4499    case tok::kw_typename:4500      if (TryAnnotateTypeOrScopeToken()) {4501        DS.SetTypeSpecError();4502        goto DoneWithDeclSpec;4503      }4504      if (!Tok.is(tok::kw_typename))4505        continue;4506      break;4507 4508    // C23/GNU typeof support.4509    case tok::kw_typeof:4510    case tok::kw_typeof_unqual:4511      ParseTypeofSpecifier(DS);4512      continue;4513 4514    case tok::annot_decltype:4515      ParseDecltypeSpecifier(DS);4516      continue;4517 4518    case tok::annot_pack_indexing_type:4519      ParsePackIndexingType(DS);4520      continue;4521 4522    case tok::annot_pragma_pack:4523      HandlePragmaPack();4524      continue;4525 4526    case tok::annot_pragma_ms_pragma:4527      HandlePragmaMSPragma();4528      continue;4529 4530    case tok::annot_pragma_ms_vtordisp:4531      HandlePragmaMSVtorDisp();4532      continue;4533 4534    case tok::annot_pragma_ms_pointers_to_members:4535      HandlePragmaMSPointersToMembers();4536      continue;4537 4538#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:4539#include "clang/Basic/TransformTypeTraits.def"4540      // HACK: libstdc++ already uses '__remove_cv' as an alias template so we4541      // work around this by expecting all transform type traits to be suffixed4542      // with '('. They're an identifier otherwise.4543      if (!MaybeParseTypeTransformTypeSpecifier(DS))4544        goto ParseIdentifier;4545      continue;4546 4547    case tok::kw__Atomic:4548      // C11 6.7.2.4/4:4549      //   If the _Atomic keyword is immediately followed by a left parenthesis,4550      //   it is interpreted as a type specifier (with a type name), not as a4551      //   type qualifier.4552      diagnoseUseOfC11Keyword(Tok);4553      if (NextToken().is(tok::l_paren)) {4554        ParseAtomicSpecifier(DS);4555        continue;4556      }4557      isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID,4558                                 getLangOpts());4559      break;4560 4561    // OpenCL address space qualifiers:4562    case tok::kw___generic:4563      // generic address space is introduced only in OpenCL v2.04564      // see OpenCL C Spec v2.0 s6.5.54565      // OpenCL v3.0 introduces __opencl_c_generic_address_space4566      // feature macro to indicate if generic address space is supported4567      if (!Actions.getLangOpts().OpenCLGenericAddressSpace) {4568        DiagID = diag::err_opencl_unknown_type_specifier;4569        PrevSpec = Tok.getIdentifierInfo()->getNameStart();4570        isInvalid = true;4571        break;4572      }4573      [[fallthrough]];4574    case tok::kw_private:4575      // It's fine (but redundant) to check this for __generic on the4576      // fallthrough path; we only form the __generic token in OpenCL mode.4577      if (!getLangOpts().OpenCL)4578        goto DoneWithDeclSpec;4579      [[fallthrough]];4580    case tok::kw___private:4581    case tok::kw___global:4582    case tok::kw___local:4583    case tok::kw___constant:4584    // OpenCL access qualifiers:4585    case tok::kw___read_only:4586    case tok::kw___write_only:4587    case tok::kw___read_write:4588      ParseOpenCLQualifiers(DS.getAttributes());4589      break;4590 4591    case tok::kw_groupshared:4592    case tok::kw_in:4593    case tok::kw_inout:4594    case tok::kw_out:4595      // NOTE: ParseHLSLQualifiers will consume the qualifier token.4596      ParseHLSLQualifiers(DS.getAttributes());4597      continue;4598 4599#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \4600  case tok::kw_##Name:                                                         \4601    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec,        \4602                                   DiagID, Policy);                            \4603    break;4604#include "clang/Basic/HLSLIntangibleTypes.def"4605 4606    case tok::less:4607      // GCC ObjC supports types like "<SomeProtocol>" as a synonym for4608      // "id<SomeProtocol>".  This is hopelessly old fashioned and dangerous,4609      // but we support it.4610      if (DS.hasTypeSpecifier() || !getLangOpts().ObjC)4611        goto DoneWithDeclSpec;4612 4613      SourceLocation StartLoc = Tok.getLocation();4614      SourceLocation EndLoc;4615      TypeResult Type = parseObjCProtocolQualifierType(EndLoc);4616      if (Type.isUsable()) {4617        if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc, StartLoc,4618                               PrevSpec, DiagID, Type.get(),4619                               Actions.getASTContext().getPrintingPolicy()))4620          Diag(StartLoc, DiagID) << PrevSpec;4621 4622        DS.SetRangeEnd(EndLoc);4623      } else {4624        DS.SetTypeSpecError();4625      }4626 4627      // Need to support trailing type qualifiers (e.g. "id<p> const").4628      // If a type specifier follows, it will be diagnosed elsewhere.4629      continue;4630    }4631 4632    DS.SetRangeEnd(ConsumedEnd.isValid() ? ConsumedEnd : Tok.getLocation());4633 4634    // If the specifier wasn't legal, issue a diagnostic.4635    if (isInvalid) {4636      assert(PrevSpec && "Method did not return previous specifier!");4637      assert(DiagID);4638 4639      if (DiagID == diag::ext_duplicate_declspec ||4640          DiagID == diag::ext_warn_duplicate_declspec ||4641          DiagID == diag::err_duplicate_declspec)4642        Diag(Loc, DiagID) << PrevSpec4643                          << FixItHint::CreateRemoval(4644                                 SourceRange(Loc, DS.getEndLoc()));4645      else if (DiagID == diag::err_opencl_unknown_type_specifier) {4646        Diag(Loc, DiagID) << getLangOpts().getOpenCLVersionString() << PrevSpec4647                          << isStorageClass;4648      } else4649        Diag(Loc, DiagID) << PrevSpec;4650    }4651 4652    if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.isInvalid())4653      // After an error the next token can be an annotation token.4654      ConsumeAnyToken();4655 4656    AttrsLastTime = false;4657  }4658}4659 4660static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS,4661                                                     Parser &P) {4662 4663  if (DS.getTypeSpecType() != DeclSpec::TST_struct)4664    return;4665 4666  auto *RD = dyn_cast<RecordDecl>(DS.getRepAsDecl());4667  // We're only interested in unnamed, non-anonymous struct4668  if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())4669    return;4670 4671  for (auto *I : RD->decls()) {4672    auto *VD = dyn_cast<ValueDecl>(I);4673    if (!VD)4674      continue;4675 4676    auto *CAT = VD->getType()->getAs<CountAttributedType>();4677    if (!CAT)4678      continue;4679 4680    for (const auto &DD : CAT->dependent_decls()) {4681      if (!RD->containsDecl(DD.getDecl())) {4682        P.Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)4683            << DD.getDecl() << CAT->getKind() << CAT->isArrayType();4684        P.Diag(DD.getDecl()->getBeginLoc(),4685               diag::note_flexible_array_counted_by_attr_field)4686            << DD.getDecl();4687      }4688    }4689  }4690}4691 4692void Parser::ParseStructDeclaration(4693    ParsingDeclSpec &DS,4694    llvm::function_ref<Decl *(ParsingFieldDeclarator &)> FieldsCallback,4695    LateParsedAttrList *LateFieldAttrs) {4696 4697  if (Tok.is(tok::kw___extension__)) {4698    // __extension__ silences extension warnings in the subexpression.4699    ExtensionRAIIObject O(Diags);  // Use RAII to do this.4700    ConsumeToken();4701    return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);4702  }4703 4704  // Parse leading attributes.4705  ParsedAttributes Attrs(AttrFactory);4706  MaybeParseCXX11Attributes(Attrs);4707 4708  // Parse the common specifier-qualifiers-list piece.4709  ParseSpecifierQualifierList(DS);4710 4711  // If there are no declarators, this is a free-standing declaration4712  // specifier. Let the actions module cope with it.4713  if (Tok.is(tok::semi)) {4714    // C23 6.7.2.1p9 : "The optional attribute specifier sequence in a4715    // member declaration appertains to each of the members declared by the4716    // member declarator list; it shall not appear if the optional member4717    // declarator list is omitted."4718    ProhibitAttributes(Attrs);4719    RecordDecl *AnonRecord = nullptr;4720    Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(4721        getCurScope(), AS_none, DS, ParsedAttributesView::none(), AnonRecord);4722    assert(!AnonRecord && "Did not expect anonymous struct or union here");4723    DS.complete(TheDecl);4724    return;4725  }4726 4727  // Read struct-declarators until we find the semicolon.4728  bool FirstDeclarator = true;4729  SourceLocation CommaLoc;4730  while (true) {4731    ParsingFieldDeclarator DeclaratorInfo(*this, DS, Attrs);4732    DeclaratorInfo.D.setCommaLoc(CommaLoc);4733 4734    // Attributes are only allowed here on successive declarators.4735    if (!FirstDeclarator) {4736      // However, this does not apply for [[]] attributes (which could show up4737      // before or after the __attribute__ attributes).4738      DiagnoseAndSkipCXX11Attributes();4739      MaybeParseGNUAttributes(DeclaratorInfo.D);4740      DiagnoseAndSkipCXX11Attributes();4741    }4742 4743    /// struct-declarator: declarator4744    /// struct-declarator: declarator[opt] ':' constant-expression4745    if (Tok.isNot(tok::colon)) {4746      // Don't parse FOO:BAR as if it were a typo for FOO::BAR.4747      ColonProtectionRAIIObject X(*this);4748      ParseDeclarator(DeclaratorInfo.D);4749    } else4750      DeclaratorInfo.D.SetIdentifier(nullptr, Tok.getLocation());4751 4752    // Here, we now know that the unnamed struct is not an anonymous struct.4753    // Report an error if a counted_by attribute refers to a field in a4754    // different named struct.4755    DiagnoseCountAttributedTypeInUnnamedAnon(DS, *this);4756 4757    if (TryConsumeToken(tok::colon)) {4758      ExprResult Res(ParseConstantExpression());4759      if (Res.isInvalid())4760        SkipUntil(tok::semi, StopBeforeMatch);4761      else4762        DeclaratorInfo.BitfieldSize = Res.get();4763    }4764 4765    // If attributes exist after the declarator, parse them.4766    MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);4767 4768    // We're done with this declarator;  invoke the callback.4769    Decl *Field = FieldsCallback(DeclaratorInfo);4770    if (Field)4771      DistributeCLateParsedAttrs(Field, LateFieldAttrs);4772 4773    // If we don't have a comma, it is either the end of the list (a ';')4774    // or an error, bail out.4775    if (!TryConsumeToken(tok::comma, CommaLoc))4776      return;4777 4778    FirstDeclarator = false;4779  }4780}4781 4782// TODO: All callers of this function should be moved to4783// `Parser::ParseLexedAttributeList`.4784void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs, bool EnterScope,4785                                      ParsedAttributes *OutAttrs) {4786  assert(LAs.parseSoon() &&4787         "Attribute list should be marked for immediate parsing.");4788  for (auto *LA : LAs) {4789    ParseLexedCAttribute(*LA, EnterScope, OutAttrs);4790    delete LA;4791  }4792  LAs.clear();4793}4794 4795void Parser::ParseLexedCAttribute(LateParsedAttribute &LA, bool EnterScope,4796                                  ParsedAttributes *OutAttrs) {4797  // Create a fake EOF so that attribute parsing won't go off the end of the4798  // attribute.4799  Token AttrEnd;4800  AttrEnd.startToken();4801  AttrEnd.setKind(tok::eof);4802  AttrEnd.setLocation(Tok.getLocation());4803  AttrEnd.setEofData(LA.Toks.data());4804  LA.Toks.push_back(AttrEnd);4805 4806  // Append the current token at the end of the new token stream so that it4807  // doesn't get lost.4808  LA.Toks.push_back(Tok);4809  PP.EnterTokenStream(LA.Toks, /*DisableMacroExpansion=*/true,4810                      /*IsReinject=*/true);4811  // Drop the current token and bring the first cached one. It's the same token4812  // as when we entered this function.4813  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);4814 4815  // TODO: Use `EnterScope`4816  (void)EnterScope;4817 4818  ParsedAttributes Attrs(AttrFactory);4819 4820  assert(LA.Decls.size() <= 1 &&4821         "late field attribute expects to have at most one declaration.");4822 4823  // Dispatch based on the attribute and parse it4824  ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, nullptr, nullptr,4825                        SourceLocation(), ParsedAttr::Form::GNU(), nullptr);4826 4827  for (auto *D : LA.Decls)4828    Actions.ActOnFinishDelayedAttribute(getCurScope(), D, Attrs);4829 4830  // Due to a parsing error, we either went over the cached tokens or4831  // there are still cached tokens left, so we skip the leftover tokens.4832  while (Tok.isNot(tok::eof))4833    ConsumeAnyToken();4834 4835  // Consume the fake EOF token if it's there4836  if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())4837    ConsumeAnyToken();4838 4839  if (OutAttrs) {4840    OutAttrs->takeAllAppendingFrom(Attrs);4841  }4842}4843 4844void Parser::ParseStructUnionBody(SourceLocation RecordLoc,4845                                  DeclSpec::TST TagType, RecordDecl *TagDecl) {4846  PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc,4847                                      "parsing struct/union body");4848  assert(!getLangOpts().CPlusPlus && "C++ declarations not supported");4849 4850  BalancedDelimiterTracker T(*this, tok::l_brace);4851  if (T.consumeOpen())4852    return;4853 4854  ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);4855  Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);4856 4857  // `LateAttrParseExperimentalExtOnly=true` requests that only attributes4858  // marked with `LateAttrParseExperimentalExt` are late parsed.4859  LateParsedAttrList LateFieldAttrs(/*PSoon=*/true,4860                                    /*LateAttrParseExperimentalExtOnly=*/true);4861 4862  // While we still have something to read, read the declarations in the struct.4863  while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&4864         Tok.isNot(tok::eof)) {4865    // Each iteration of this loop reads one struct-declaration.4866 4867    // Check for extraneous top-level semicolon.4868    if (Tok.is(tok::semi)) {4869      ConsumeExtraSemi(ExtraSemiKind::InsideStruct, TagType);4870      continue;4871    }4872 4873    // Parse _Static_assert declaration.4874    if (Tok.isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {4875      SourceLocation DeclEnd;4876      ParseStaticAssertDeclaration(DeclEnd);4877      continue;4878    }4879 4880    if (Tok.is(tok::annot_pragma_pack)) {4881      HandlePragmaPack();4882      continue;4883    }4884 4885    if (Tok.is(tok::annot_pragma_align)) {4886      HandlePragmaAlign();4887      continue;4888    }4889 4890    if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {4891      // Result can be ignored, because it must be always empty.4892      AccessSpecifier AS = AS_none;4893      ParsedAttributes Attrs(AttrFactory);4894      (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);4895      continue;4896    }4897 4898    if (Tok.is(tok::annot_pragma_openacc)) {4899      AccessSpecifier AS = AS_none;4900      ParsedAttributes Attrs(AttrFactory);4901      ParseOpenACCDirectiveDecl(AS, Attrs, TagType, TagDecl);4902      continue;4903    }4904 4905    if (tok::isPragmaAnnotation(Tok.getKind())) {4906      Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)4907          << DeclSpec::getSpecifierName(4908                 TagType, Actions.getASTContext().getPrintingPolicy());4909      ConsumeAnnotationToken();4910      continue;4911    }4912 4913    if (!Tok.is(tok::at)) {4914      auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {4915        // Install the declarator into the current TagDecl.4916        Decl *Field =4917            Actions.ActOnField(getCurScope(), TagDecl,4918                               FD.D.getDeclSpec().getSourceRange().getBegin(),4919                               FD.D, FD.BitfieldSize);4920        FD.complete(Field);4921        return Field;4922      };4923 4924      // Parse all the comma separated declarators.4925      ParsingDeclSpec DS(*this);4926      ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);4927    } else { // Handle @defs4928      ConsumeToken();4929      if (!Tok.isObjCAtKeyword(tok::objc_defs)) {4930        Diag(Tok, diag::err_unexpected_at);4931        SkipUntil(tok::semi);4932        continue;4933      }4934      ConsumeToken();4935      ExpectAndConsume(tok::l_paren);4936      if (!Tok.is(tok::identifier)) {4937        Diag(Tok, diag::err_expected) << tok::identifier;4938        SkipUntil(tok::semi);4939        continue;4940      }4941      SmallVector<Decl *, 16> Fields;4942      Actions.ObjC().ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(),4943                               Tok.getIdentifierInfo(), Fields);4944      ConsumeToken();4945      ExpectAndConsume(tok::r_paren);4946    }4947 4948    if (TryConsumeToken(tok::semi))4949      continue;4950 4951    if (Tok.is(tok::r_brace)) {4952      ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);4953      break;4954    }4955 4956    ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);4957    // Skip to end of block or statement to avoid ext-warning on extra ';'.4958    SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);4959    // If we stopped at a ';', eat it.4960    TryConsumeToken(tok::semi);4961  }4962 4963  T.consumeClose();4964 4965  ParsedAttributes attrs(AttrFactory);4966  // If attributes exist after struct contents, parse them.4967  MaybeParseGNUAttributes(attrs, &LateFieldAttrs);4968 4969  // Late parse field attributes if necessary.4970  ParseLexedCAttributeList(LateFieldAttrs, /*EnterScope=*/false);4971 4972  SmallVector<Decl *, 32> FieldDecls(TagDecl->fields());4973 4974  Actions.ActOnFields(getCurScope(), RecordLoc, TagDecl, FieldDecls,4975                      T.getOpenLocation(), T.getCloseLocation(), attrs);4976  StructScope.Exit();4977  Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, T.getRange());4978}4979 4980void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,4981                                const ParsedTemplateInfo &TemplateInfo,4982                                AccessSpecifier AS, DeclSpecContext DSC) {4983  // Parse the tag portion of this.4984  if (Tok.is(tok::code_completion)) {4985    // Code completion for an enum name.4986    cutOffParsing();4987    Actions.CodeCompletion().CodeCompleteTag(getCurScope(), DeclSpec::TST_enum);4988    DS.SetTypeSpecError(); // Needed by ActOnUsingDeclaration.4989    return;4990  }4991 4992  // If attributes exist after tag, parse them.4993  ParsedAttributes attrs(AttrFactory);4994  MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);4995 4996  SourceLocation ScopedEnumKWLoc;4997  bool IsScopedUsingClassTag = false;4998 4999  // In C++11, recognize 'enum class' and 'enum struct'.5000  if (Tok.isOneOf(tok::kw_class, tok::kw_struct) && getLangOpts().CPlusPlus) {5001    Diag(Tok, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_scoped_enum5002                                        : diag::ext_scoped_enum);5003    IsScopedUsingClassTag = Tok.is(tok::kw_class);5004    ScopedEnumKWLoc = ConsumeToken();5005 5006    // Attributes are not allowed between these keywords.  Diagnose,5007    // but then just treat them like they appeared in the right place.5008    ProhibitAttributes(attrs);5009 5010    // They are allowed afterwards, though.5011    MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);5012  }5013 5014  // C++11 [temp.explicit]p12:5015  //   The usual access controls do not apply to names used to specify5016  //   explicit instantiations.5017  // We extend this to also cover explicit specializations.  Note that5018  // we don't suppress if this turns out to be an elaborated type5019  // specifier.5020  bool shouldDelayDiagsInTag =5021    (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation ||5022     TemplateInfo.Kind == ParsedTemplateKind::ExplicitSpecialization);5023  SuppressAccessChecks diagsFromTag(*this, shouldDelayDiagsInTag);5024 5025  // Determine whether this declaration is permitted to have an enum-base.5026  AllowDefiningTypeSpec AllowEnumSpecifier =5027      isDefiningTypeSpecifierContext(DSC, getLangOpts().CPlusPlus);5028  bool CanBeOpaqueEnumDeclaration =5029      DS.isEmpty() && isOpaqueEnumDeclarationContext(DSC);5030  bool CanHaveEnumBase = (getLangOpts().CPlusPlus11 || getLangOpts().ObjC ||5031                          getLangOpts().MicrosoftExt) &&5032                         (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||5033                          CanBeOpaqueEnumDeclaration);5034 5035  CXXScopeSpec &SS = DS.getTypeSpecScope();5036  if (getLangOpts().CPlusPlus) {5037    // "enum foo : bar;" is not a potential typo for "enum foo::bar;".5038    ColonProtectionRAIIObject X(*this);5039 5040    CXXScopeSpec Spec;5041    if (ParseOptionalCXXScopeSpecifier(Spec, /*ObjectType=*/nullptr,5042                                       /*ObjectHasErrors=*/false,5043                                       /*EnteringContext=*/true))5044      return;5045 5046    if (Spec.isSet() && Tok.isNot(tok::identifier)) {5047      Diag(Tok, diag::err_expected) << tok::identifier;5048      DS.SetTypeSpecError();5049      if (Tok.isNot(tok::l_brace)) {5050        // Has no name and is not a definition.5051        // Skip the rest of this declarator, up until the comma or semicolon.5052        SkipUntil(tok::comma, StopAtSemi);5053        return;5054      }5055    }5056 5057    SS = Spec;5058  }5059 5060  // Must have either 'enum name' or 'enum {...}' or (rarely) 'enum : T { ... }'.5061  if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&5062      Tok.isNot(tok::colon)) {5063    Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;5064 5065    DS.SetTypeSpecError();5066    // Skip the rest of this declarator, up until the comma or semicolon.5067    SkipUntil(tok::comma, StopAtSemi);5068    return;5069  }5070 5071  // If an identifier is present, consume and remember it.5072  IdentifierInfo *Name = nullptr;5073  SourceLocation NameLoc;5074  if (Tok.is(tok::identifier)) {5075    Name = Tok.getIdentifierInfo();5076    NameLoc = ConsumeToken();5077  }5078 5079  if (!Name && ScopedEnumKWLoc.isValid()) {5080    // C++0x 7.2p2: The optional identifier shall not be omitted in the5081    // declaration of a scoped enumeration.5082    Diag(Tok, diag::err_scoped_enum_missing_identifier);5083    ScopedEnumKWLoc = SourceLocation();5084    IsScopedUsingClassTag = false;5085  }5086 5087  // Okay, end the suppression area.  We'll decide whether to emit the5088  // diagnostics in a second.5089  if (shouldDelayDiagsInTag)5090    diagsFromTag.done();5091 5092  TypeResult BaseType;5093  SourceRange BaseRange;5094 5095  bool CanBeBitfield =5096      getCurScope()->isClassScope() && ScopedEnumKWLoc.isInvalid() && Name;5097 5098  // Parse the fixed underlying type.5099  if (Tok.is(tok::colon)) {5100    // This might be an enum-base or part of some unrelated enclosing context.5101    //5102    // 'enum E : base' is permitted in two circumstances:5103    //5104    // 1) As a defining-type-specifier, when followed by '{'.5105    // 2) As the sole constituent of a complete declaration -- when DS is empty5106    //    and the next token is ';'.5107    //5108    // The restriction to defining-type-specifiers is important to allow parsing5109    //   a ? new enum E : int{}5110    //   _Generic(a, enum E : int{})5111    // properly.5112    //5113    // One additional consideration applies:5114    //5115    // C++ [dcl.enum]p1:5116    //   A ':' following "enum nested-name-specifier[opt] identifier" within5117    //   the decl-specifier-seq of a member-declaration is parsed as part of5118    //   an enum-base.5119    //5120    // Other language modes supporting enumerations with fixed underlying types5121    // do not have clear rules on this, so we disambiguate to determine whether5122    // the tokens form a bit-field width or an enum-base.5123 5124    if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {5125      // Outside C++11, do not interpret the tokens as an enum-base if they do5126      // not make sense as one. In C++11, it's an error if this happens.5127      if (getLangOpts().CPlusPlus11)5128        Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);5129    } else if (CanHaveEnumBase || !ColonIsSacred) {5130      SourceLocation ColonLoc = ConsumeToken();5131 5132      // Parse a type-specifier-seq as a type. We can't just ParseTypeName here,5133      // because under -fms-extensions,5134      //   enum E : int *p;5135      // declares 'enum E : int; E *p;' not 'enum E : int*; E p;'.5136      DeclSpec DS(AttrFactory);5137      // enum-base is not assumed to be a type and therefore requires the5138      // typename keyword [p0634r3].5139      ParseSpecifierQualifierList(DS, ImplicitTypenameContext::No, AS,5140                                  DeclSpecContext::DSC_type_specifier);5141      Declarator DeclaratorInfo(DS, ParsedAttributesView::none(),5142                                DeclaratorContext::TypeName);5143      BaseType = Actions.ActOnTypeName(DeclaratorInfo);5144 5145      BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());5146 5147      if (!getLangOpts().ObjC) {5148        if (getLangOpts().CPlusPlus)5149          DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)5150              << BaseRange;5151        else if (getLangOpts().MicrosoftExt && !getLangOpts().C23)5152          Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)5153              << BaseRange;5154        else5155          Diag(ColonLoc, getLangOpts().C235156                             ? diag::warn_c17_compat_enum_fixed_underlying_type5157                             : diag::ext_c23_enum_fixed_underlying_type)5158              << BaseRange;5159      }5160    }5161  }5162 5163  // There are four options here.  If we have 'friend enum foo;' then this is a5164  // friend declaration, and cannot have an accompanying definition. If we have5165  // 'enum foo;', then this is a forward declaration.  If we have5166  // 'enum foo {...' then this is a definition. Otherwise we have something5167  // like 'enum foo xyz', a reference.5168  //5169  // This is needed to handle stuff like this right (C99 6.7.2.3p11):5170  // enum foo {..};  void bar() { enum foo; }    <- new foo in bar.5171  // enum foo {..};  void bar() { enum foo x; }  <- use of old foo.5172  //5173  TagUseKind TUK;5174  if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)5175    TUK = TagUseKind::Reference;5176  else if (Tok.is(tok::l_brace)) {5177    if (DS.isFriendSpecified()) {5178      Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)5179        << SourceRange(DS.getFriendSpecLoc());5180      ConsumeBrace();5181      SkipUntil(tok::r_brace, StopAtSemi);5182      // Discard any other definition-only pieces.5183      attrs.clear();5184      ScopedEnumKWLoc = SourceLocation();5185      IsScopedUsingClassTag = false;5186      BaseType = TypeResult();5187      TUK = TagUseKind::Friend;5188    } else {5189      TUK = TagUseKind::Definition;5190    }5191  } else if (!isTypeSpecifier(DSC) &&5192             (Tok.is(tok::semi) ||5193              (Tok.isAtStartOfLine() &&5194               !isValidAfterTypeSpecifier(CanBeBitfield)))) {5195    // An opaque-enum-declaration is required to be standalone (no preceding or5196    // following tokens in the declaration). Sema enforces this separately by5197    // diagnosing anything else in the DeclSpec.5198    TUK = DS.isFriendSpecified() ? TagUseKind::Friend : TagUseKind::Declaration;5199    if (Tok.isNot(tok::semi)) {5200      // A semicolon was missing after this declaration. Diagnose and recover.5201      ExpectAndConsume(tok::semi, diag::err_expected_after, "enum");5202      PP.EnterToken(Tok, /*IsReinject=*/true);5203      Tok.setKind(tok::semi);5204    }5205  } else {5206    TUK = TagUseKind::Reference;5207  }5208 5209  bool IsElaboratedTypeSpecifier =5210      TUK == TagUseKind::Reference || TUK == TagUseKind::Friend;5211 5212  // If this is an elaborated type specifier nested in a larger declaration,5213  // and we delayed diagnostics before, just merge them into the current pool.5214  if (TUK == TagUseKind::Reference && shouldDelayDiagsInTag) {5215    diagsFromTag.redelay();5216  }5217 5218  MultiTemplateParamsArg TParams;5219  if (TemplateInfo.Kind != ParsedTemplateKind::NonTemplate &&5220      TUK != TagUseKind::Reference) {5221    if (!getLangOpts().CPlusPlus11 || !SS.isSet()) {5222      // Skip the rest of this declarator, up until the comma or semicolon.5223      Diag(Tok, diag::err_enum_template);5224      SkipUntil(tok::comma, StopAtSemi);5225      return;5226    }5227 5228    if (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation) {5229      // Enumerations can't be explicitly instantiated.5230      DS.SetTypeSpecError();5231      Diag(StartLoc, diag::err_explicit_instantiation_enum);5232      return;5233    }5234 5235    assert(TemplateInfo.TemplateParams && "no template parameters");5236    TParams = MultiTemplateParamsArg(TemplateInfo.TemplateParams->data(),5237                                     TemplateInfo.TemplateParams->size());5238    SS.setTemplateParamLists(TParams);5239  }5240 5241  if (!Name && TUK != TagUseKind::Definition) {5242    Diag(Tok, diag::err_enumerator_unnamed_no_def);5243 5244    DS.SetTypeSpecError();5245    // Skip the rest of this declarator, up until the comma or semicolon.5246    SkipUntil(tok::comma, StopAtSemi);5247    return;5248  }5249 5250  // An elaborated-type-specifier has a much more constrained grammar:5251  //5252  //   'enum' nested-name-specifier[opt] identifier5253  //5254  // If we parsed any other bits, reject them now.5255  //5256  // MSVC and (for now at least) Objective-C permit a full enum-specifier5257  // or opaque-enum-declaration anywhere.5258  if (IsElaboratedTypeSpecifier && !getLangOpts().MicrosoftExt &&5259      !getLangOpts().ObjC) {5260    ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,5261                            diag::err_keyword_not_allowed,5262                            /*DiagnoseEmptyAttrs=*/true);5263    if (BaseType.isUsable())5264      Diag(BaseRange.getBegin(), diag::ext_enum_base_in_type_specifier)5265          << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;5266    else if (ScopedEnumKWLoc.isValid())5267      Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)5268        << FixItHint::CreateRemoval(ScopedEnumKWLoc) << IsScopedUsingClassTag;5269  }5270 5271  stripTypeAttributesOffDeclSpec(attrs, DS, TUK);5272 5273  SkipBodyInfo SkipBody;5274  if (!Name && TUK == TagUseKind::Definition && Tok.is(tok::l_brace) &&5275      NextToken().is(tok::identifier))5276    SkipBody = Actions.shouldSkipAnonEnumBody(getCurScope(),5277                                              NextToken().getIdentifierInfo(),5278                                              NextToken().getLocation());5279 5280  bool Owned = false;5281  bool IsDependent = false;5282  const char *PrevSpec = nullptr;5283  unsigned DiagID;5284  Decl *TagDecl =5285      Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK, StartLoc, SS,5286                    Name, NameLoc, attrs, AS, DS.getModulePrivateSpecLoc(),5287                    TParams, Owned, IsDependent, ScopedEnumKWLoc,5288                    IsScopedUsingClassTag,5289                    BaseType, DSC == DeclSpecContext::DSC_type_specifier,5290                    DSC == DeclSpecContext::DSC_template_param ||5291                        DSC == DeclSpecContext::DSC_template_type_arg,5292                    OffsetOfState, &SkipBody).get();5293 5294  if (SkipBody.ShouldSkip) {5295    assert(TUK == TagUseKind::Definition && "can only skip a definition");5296 5297    BalancedDelimiterTracker T(*this, tok::l_brace);5298    T.consumeOpen();5299    T.skipToEnd();5300 5301    if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,5302                           NameLoc.isValid() ? NameLoc : StartLoc,5303                           PrevSpec, DiagID, TagDecl, Owned,5304                           Actions.getASTContext().getPrintingPolicy()))5305      Diag(StartLoc, DiagID) << PrevSpec;5306    return;5307  }5308 5309  if (IsDependent) {5310    // This enum has a dependent nested-name-specifier. Handle it as a5311    // dependent tag.5312    if (!Name) {5313      DS.SetTypeSpecError();5314      Diag(Tok, diag::err_expected_type_name_after_typename);5315      return;5316    }5317 5318    TypeResult Type = Actions.ActOnDependentTag(5319        getCurScope(), DeclSpec::TST_enum, TUK, SS, Name, StartLoc, NameLoc);5320    if (Type.isInvalid()) {5321      DS.SetTypeSpecError();5322      return;5323    }5324 5325    if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,5326                           NameLoc.isValid() ? NameLoc : StartLoc,5327                           PrevSpec, DiagID, Type.get(),5328                           Actions.getASTContext().getPrintingPolicy()))5329      Diag(StartLoc, DiagID) << PrevSpec;5330 5331    return;5332  }5333 5334  if (!TagDecl) {5335    // The action failed to produce an enumeration tag. If this is a5336    // definition, consume the entire definition.5337    if (Tok.is(tok::l_brace) && TUK != TagUseKind::Reference) {5338      ConsumeBrace();5339      SkipUntil(tok::r_brace, StopAtSemi);5340    }5341 5342    DS.SetTypeSpecError();5343    return;5344  }5345 5346  if (Tok.is(tok::l_brace) && TUK == TagUseKind::Definition) {5347    Decl *D = SkipBody.CheckSameAsPrevious ? SkipBody.New : TagDecl;5348    ParseEnumBody(StartLoc, D, &SkipBody);5349    if (SkipBody.CheckSameAsPrevious &&5350        !Actions.ActOnDuplicateDefinition(getCurScope(), TagDecl, SkipBody)) {5351      DS.SetTypeSpecError();5352      return;5353    }5354  }5355 5356  if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,5357                         NameLoc.isValid() ? NameLoc : StartLoc,5358                         PrevSpec, DiagID, TagDecl, Owned,5359                         Actions.getASTContext().getPrintingPolicy()))5360    Diag(StartLoc, DiagID) << PrevSpec;5361}5362 5363void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl,5364                           SkipBodyInfo *SkipBody) {5365  // Enter the scope of the enum body and start the definition.5366  ParseScope EnumScope(this, Scope::DeclScope | Scope::EnumScope);5367  Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl);5368 5369  BalancedDelimiterTracker T(*this, tok::l_brace);5370  T.consumeOpen();5371 5372  // C does not allow an empty enumerator-list, C++ does [dcl.enum].5373  if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus) {5374    if (getLangOpts().MicrosoftExt)5375      Diag(T.getOpenLocation(), diag::ext_ms_c_empty_enum_type)5376          << SourceRange(T.getOpenLocation(), Tok.getLocation());5377    else5378      Diag(Tok, diag::err_empty_enum);5379  }5380 5381  SmallVector<Decl *, 32> EnumConstantDecls;5382  SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;5383 5384  Decl *LastEnumConstDecl = nullptr;5385 5386  // Parse the enumerator-list.5387  while (Tok.isNot(tok::r_brace)) {5388    // Parse enumerator. If failed, try skipping till the start of the next5389    // enumerator definition.5390    if (Tok.isNot(tok::identifier)) {5391      Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;5392      if (SkipUntil(tok::comma, tok::r_brace, StopBeforeMatch) &&5393          TryConsumeToken(tok::comma))5394        continue;5395      break;5396    }5397    IdentifierInfo *Ident = Tok.getIdentifierInfo();5398    SourceLocation IdentLoc = ConsumeToken();5399 5400    // If attributes exist after the enumerator, parse them.5401    ParsedAttributes attrs(AttrFactory);5402    MaybeParseGNUAttributes(attrs);5403    if (isAllowedCXX11AttributeSpecifier()) {5404      if (getLangOpts().CPlusPlus)5405        Diag(Tok.getLocation(), getLangOpts().CPlusPlus175406                                    ? diag::warn_cxx14_compat_ns_enum_attribute5407                                    : diag::ext_ns_enum_attribute)5408            << 1 /*enumerator*/;5409      ParseCXX11Attributes(attrs);5410    }5411 5412    SourceLocation EqualLoc;5413    ExprResult AssignedVal;5414    EnumAvailabilityDiags.emplace_back(*this);5415 5416    EnterExpressionEvaluationContext ConstantEvaluated(5417        Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);5418    if (TryConsumeToken(tok::equal, EqualLoc)) {5419      AssignedVal = ParseConstantExpressionInExprEvalContext();5420      if (AssignedVal.isInvalid())5421        SkipUntil(tok::comma, tok::r_brace, StopBeforeMatch);5422    }5423 5424    // Install the enumerator constant into EnumDecl.5425    Decl *EnumConstDecl = Actions.ActOnEnumConstant(5426        getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,5427        EqualLoc, AssignedVal.get(), SkipBody);5428    EnumAvailabilityDiags.back().done();5429 5430    EnumConstantDecls.push_back(EnumConstDecl);5431    LastEnumConstDecl = EnumConstDecl;5432 5433    if (Tok.is(tok::identifier)) {5434      // We're missing a comma between enumerators.5435      SourceLocation Loc = getEndOfPreviousToken();5436      Diag(Loc, diag::err_enumerator_list_missing_comma)5437        << FixItHint::CreateInsertion(Loc, ", ");5438      continue;5439    }5440 5441    // Emumerator definition must be finished, only comma or r_brace are5442    // allowed here.5443    SourceLocation CommaLoc;5444    if (Tok.isNot(tok::r_brace) && !TryConsumeToken(tok::comma, CommaLoc)) {5445      if (EqualLoc.isValid())5446        Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace5447                                                           << tok::comma;5448      else5449        Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);5450      if (SkipUntil(tok::comma, tok::r_brace, StopBeforeMatch)) {5451        if (TryConsumeToken(tok::comma, CommaLoc))5452          continue;5453      } else {5454        break;5455      }5456    }5457 5458    // If comma is followed by r_brace, emit appropriate warning.5459    if (Tok.is(tok::r_brace) && CommaLoc.isValid()) {5460      if (!getLangOpts().C99 && !getLangOpts().CPlusPlus11)5461        Diag(CommaLoc, getLangOpts().CPlusPlus ?5462               diag::ext_enumerator_list_comma_cxx :5463               diag::ext_enumerator_list_comma_c)5464          << FixItHint::CreateRemoval(CommaLoc);5465      else if (getLangOpts().CPlusPlus11)5466        Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)5467          << FixItHint::CreateRemoval(CommaLoc);5468      break;5469    }5470  }5471 5472  // Eat the }.5473  T.consumeClose();5474 5475  // If attributes exist after the identifier list, parse them.5476  ParsedAttributes attrs(AttrFactory);5477  MaybeParseGNUAttributes(attrs);5478 5479  Actions.ActOnEnumBody(StartLoc, T.getRange(), EnumDecl, EnumConstantDecls,5480                        getCurScope(), attrs);5481 5482  // Now handle enum constant availability diagnostics.5483  assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());5484  for (size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {5485    ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);5486    EnumAvailabilityDiags[i].redelay();5487    PD.complete(EnumConstantDecls[i]);5488  }5489 5490  EnumScope.Exit();5491  Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, T.getRange());5492 5493  // The next token must be valid after an enum definition. If not, a ';'5494  // was probably forgotten.5495  bool CanBeBitfield = getCurScope()->isClassScope();5496  if (!isValidAfterTypeSpecifier(CanBeBitfield)) {5497    ExpectAndConsume(tok::semi, diag::err_expected_after, "enum");5498    // Push this token back into the preprocessor and change our current token5499    // to ';' so that the rest of the code recovers as though there were an5500    // ';' after the definition.5501    PP.EnterToken(Tok, /*IsReinject=*/true);5502    Tok.setKind(tok::semi);5503  }5504}5505 5506bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {5507  switch (Tok.getKind()) {5508  default: return false;5509    // type-specifiers5510  case tok::kw_short:5511  case tok::kw_long:5512  case tok::kw___int64:5513  case tok::kw___int128:5514  case tok::kw_signed:5515  case tok::kw_unsigned:5516  case tok::kw__Complex:5517  case tok::kw__Imaginary:5518  case tok::kw_void:5519  case tok::kw_char:5520  case tok::kw_wchar_t:5521  case tok::kw_char8_t:5522  case tok::kw_char16_t:5523  case tok::kw_char32_t:5524  case tok::kw_int:5525  case tok::kw__ExtInt:5526  case tok::kw__BitInt:5527  case tok::kw___bf16:5528  case tok::kw_half:5529  case tok::kw_float:5530  case tok::kw_double:5531  case tok::kw__Accum:5532  case tok::kw__Fract:5533  case tok::kw__Float16:5534  case tok::kw___float128:5535  case tok::kw___ibm128:5536  case tok::kw_bool:5537  case tok::kw__Bool:5538  case tok::kw__Decimal32:5539  case tok::kw__Decimal64:5540  case tok::kw__Decimal128:5541  case tok::kw___vector:5542#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:5543#include "clang/Basic/OpenCLImageTypes.def"5544#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:5545#include "clang/Basic/HLSLIntangibleTypes.def"5546 5547    // struct-or-union-specifier (C99) or class-specifier (C++)5548  case tok::kw_class:5549  case tok::kw_struct:5550  case tok::kw___interface:5551  case tok::kw_union:5552    // enum-specifier5553  case tok::kw_enum:5554 5555    // typedef-name5556  case tok::annot_typename:5557    return true;5558  }5559}5560 5561bool Parser::isTypeSpecifierQualifier() {5562  switch (Tok.getKind()) {5563  default: return false;5564 5565  case tok::identifier:   // foo::bar5566    if (TryAltiVecVectorToken())5567      return true;5568    [[fallthrough]];5569  case tok::kw_typename:  // typename T::type5570    // Annotate typenames and C++ scope specifiers.  If we get one, just5571    // recurse to handle whatever we get.5572    if (TryAnnotateTypeOrScopeToken())5573      return true;5574    if (Tok.is(tok::identifier))5575      return false;5576    return isTypeSpecifierQualifier();5577 5578  case tok::coloncolon:   // ::foo::bar5579    if (NextToken().is(tok::kw_new) ||    // ::new5580        NextToken().is(tok::kw_delete))   // ::delete5581      return false;5582 5583    if (TryAnnotateTypeOrScopeToken())5584      return true;5585    return isTypeSpecifierQualifier();5586 5587    // GNU attributes support.5588  case tok::kw___attribute:5589    // C23/GNU typeof support.5590  case tok::kw_typeof:5591  case tok::kw_typeof_unqual:5592 5593    // type-specifiers5594  case tok::kw_short:5595  case tok::kw_long:5596  case tok::kw___int64:5597  case tok::kw___int128:5598  case tok::kw_signed:5599  case tok::kw_unsigned:5600  case tok::kw__Complex:5601  case tok::kw__Imaginary:5602  case tok::kw_void:5603  case tok::kw_char:5604  case tok::kw_wchar_t:5605  case tok::kw_char8_t:5606  case tok::kw_char16_t:5607  case tok::kw_char32_t:5608  case tok::kw_int:5609  case tok::kw__ExtInt:5610  case tok::kw__BitInt:5611  case tok::kw_half:5612  case tok::kw___bf16:5613  case tok::kw_float:5614  case tok::kw_double:5615  case tok::kw__Accum:5616  case tok::kw__Fract:5617  case tok::kw__Float16:5618  case tok::kw___float128:5619  case tok::kw___ibm128:5620  case tok::kw_bool:5621  case tok::kw__Bool:5622  case tok::kw__Decimal32:5623  case tok::kw__Decimal64:5624  case tok::kw__Decimal128:5625  case tok::kw___vector:5626#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:5627#include "clang/Basic/OpenCLImageTypes.def"5628#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:5629#include "clang/Basic/HLSLIntangibleTypes.def"5630 5631    // struct-or-union-specifier (C99) or class-specifier (C++)5632  case tok::kw_class:5633  case tok::kw_struct:5634  case tok::kw___interface:5635  case tok::kw_union:5636    // enum-specifier5637  case tok::kw_enum:5638 5639    // type-qualifier5640  case tok::kw_const:5641  case tok::kw_volatile:5642  case tok::kw_restrict:5643  case tok::kw__Sat:5644 5645    // Debugger support.5646  case tok::kw___unknown_anytype:5647 5648    // typedef-name5649  case tok::annot_typename:5650    return true;5651 5652    // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.5653  case tok::less:5654    return getLangOpts().ObjC;5655 5656  case tok::kw___cdecl:5657  case tok::kw___stdcall:5658  case tok::kw___fastcall:5659  case tok::kw___thiscall:5660  case tok::kw___regcall:5661  case tok::kw___vectorcall:5662  case tok::kw___w64:5663  case tok::kw___ptr64:5664  case tok::kw___ptr32:5665  case tok::kw___pascal:5666  case tok::kw___unaligned:5667  case tok::kw___ptrauth:5668 5669  case tok::kw__Nonnull:5670  case tok::kw__Nullable:5671  case tok::kw__Nullable_result:5672  case tok::kw__Null_unspecified:5673 5674  case tok::kw___kindof:5675 5676  case tok::kw___private:5677  case tok::kw___local:5678  case tok::kw___global:5679  case tok::kw___constant:5680  case tok::kw___generic:5681  case tok::kw___read_only:5682  case tok::kw___read_write:5683  case tok::kw___write_only:5684  case tok::kw___funcref:5685    return true;5686 5687  case tok::kw_private:5688    return getLangOpts().OpenCL;5689 5690  // C11 _Atomic5691  case tok::kw__Atomic:5692    return true;5693 5694  // HLSL type qualifiers5695  case tok::kw_groupshared:5696  case tok::kw_in:5697  case tok::kw_inout:5698  case tok::kw_out:5699    return getLangOpts().HLSL;5700  }5701}5702 5703Parser::DeclGroupPtrTy Parser::ParseTopLevelStmtDecl() {5704  assert(PP.isIncrementalProcessingEnabled() && "Not in incremental mode");5705 5706  // Parse a top-level-stmt.5707  Parser::StmtVector Stmts;5708  ParsedStmtContext SubStmtCtx = ParsedStmtContext();5709  ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope |5710                               Scope::CompoundStmtScope);5711  TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(getCurScope());5712  StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);5713  Actions.ActOnFinishTopLevelStmtDecl(TLSD, R.get());5714  if (!R.isUsable())5715    R = Actions.ActOnNullStmt(Tok.getLocation());5716 5717  if (Tok.is(tok::annot_repl_input_end) &&5718      Tok.getAnnotationValue() != nullptr) {5719    ConsumeAnnotationToken();5720    TLSD->setSemiMissing();5721  }5722 5723  SmallVector<Decl *, 2> DeclsInGroup;5724  DeclsInGroup.push_back(TLSD);5725 5726  // Currently happens for things like -fms-extensions and use `__if_exists`.5727  for (Stmt *S : Stmts) {5728    // Here we should be safe as `__if_exists` and friends are not introducing5729    // new variables which need to live outside file scope.5730    TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(getCurScope());5731    Actions.ActOnFinishTopLevelStmtDecl(D, S);5732    DeclsInGroup.push_back(D);5733  }5734 5735  return Actions.BuildDeclaratorGroup(DeclsInGroup);5736}5737 5738bool Parser::isDeclarationSpecifier(5739    ImplicitTypenameContext AllowImplicitTypename,5740    bool DisambiguatingWithExpression) {5741  switch (Tok.getKind()) {5742  default: return false;5743 5744  // OpenCL 2.0 and later define this keyword.5745  case tok::kw_pipe:5746    return getLangOpts().OpenCL &&5747           getLangOpts().getOpenCLCompatibleVersion() >= 200;5748 5749  case tok::identifier:   // foo::bar5750    // Unfortunate hack to support "Class.factoryMethod" notation.5751    if (getLangOpts().ObjC && NextToken().is(tok::period))5752      return false;5753    if (TryAltiVecVectorToken())5754      return true;5755    [[fallthrough]];5756  case tok::kw_decltype: // decltype(T())::type5757  case tok::kw_typename: // typename T::type5758    // Annotate typenames and C++ scope specifiers.  If we get one, just5759    // recurse to handle whatever we get.5760    if (TryAnnotateTypeOrScopeToken(AllowImplicitTypename))5761      return true;5762    if (TryAnnotateTypeConstraint())5763      return true;5764    if (Tok.is(tok::identifier))5765      return false;5766 5767    // If we're in Objective-C and we have an Objective-C class type followed5768    // by an identifier and then either ':' or ']', in a place where an5769    // expression is permitted, then this is probably a class message send5770    // missing the initial '['. In this case, we won't consider this to be5771    // the start of a declaration.5772    if (DisambiguatingWithExpression &&5773        isStartOfObjCClassMessageMissingOpenBracket())5774      return false;5775 5776    return isDeclarationSpecifier(AllowImplicitTypename);5777 5778  case tok::coloncolon:   // ::foo::bar5779    if (!getLangOpts().CPlusPlus)5780      return false;5781    if (NextToken().is(tok::kw_new) ||    // ::new5782        NextToken().is(tok::kw_delete))   // ::delete5783      return false;5784 5785    // Annotate typenames and C++ scope specifiers.  If we get one, just5786    // recurse to handle whatever we get.5787    if (TryAnnotateTypeOrScopeToken())5788      return true;5789    return isDeclarationSpecifier(ImplicitTypenameContext::No);5790 5791    // storage-class-specifier5792  case tok::kw_typedef:5793  case tok::kw_extern:5794  case tok::kw___private_extern__:5795  case tok::kw_static:5796  case tok::kw_auto:5797  case tok::kw___auto_type:5798  case tok::kw_register:5799  case tok::kw___thread:5800  case tok::kw_thread_local:5801  case tok::kw__Thread_local:5802 5803    // Modules5804  case tok::kw___module_private__:5805 5806    // Debugger support5807  case tok::kw___unknown_anytype:5808 5809    // type-specifiers5810  case tok::kw_short:5811  case tok::kw_long:5812  case tok::kw___int64:5813  case tok::kw___int128:5814  case tok::kw_signed:5815  case tok::kw_unsigned:5816  case tok::kw__Complex:5817  case tok::kw__Imaginary:5818  case tok::kw_void:5819  case tok::kw_char:5820  case tok::kw_wchar_t:5821  case tok::kw_char8_t:5822  case tok::kw_char16_t:5823  case tok::kw_char32_t:5824 5825  case tok::kw_int:5826  case tok::kw__ExtInt:5827  case tok::kw__BitInt:5828  case tok::kw_half:5829  case tok::kw___bf16:5830  case tok::kw_float:5831  case tok::kw_double:5832  case tok::kw__Accum:5833  case tok::kw__Fract:5834  case tok::kw__Float16:5835  case tok::kw___float128:5836  case tok::kw___ibm128:5837  case tok::kw_bool:5838  case tok::kw__Bool:5839  case tok::kw__Decimal32:5840  case tok::kw__Decimal64:5841  case tok::kw__Decimal128:5842  case tok::kw___vector:5843 5844    // struct-or-union-specifier (C99) or class-specifier (C++)5845  case tok::kw_class:5846  case tok::kw_struct:5847  case tok::kw_union:5848  case tok::kw___interface:5849    // enum-specifier5850  case tok::kw_enum:5851 5852    // type-qualifier5853  case tok::kw_const:5854  case tok::kw_volatile:5855  case tok::kw_restrict:5856  case tok::kw__Sat:5857 5858    // function-specifier5859  case tok::kw_inline:5860  case tok::kw_virtual:5861  case tok::kw_explicit:5862  case tok::kw__Noreturn:5863 5864    // alignment-specifier5865  case tok::kw__Alignas:5866 5867    // friend keyword.5868  case tok::kw_friend:5869 5870    // static_assert-declaration5871  case tok::kw_static_assert:5872  case tok::kw__Static_assert:5873 5874    // C23/GNU typeof support.5875  case tok::kw_typeof:5876  case tok::kw_typeof_unqual:5877 5878    // GNU attributes.5879  case tok::kw___attribute:5880 5881    // C++11 decltype and constexpr.5882  case tok::annot_decltype:5883  case tok::annot_pack_indexing_type:5884  case tok::kw_constexpr:5885 5886    // C++20 consteval and constinit.5887  case tok::kw_consteval:5888  case tok::kw_constinit:5889 5890    // C11 _Atomic5891  case tok::kw__Atomic:5892    return true;5893 5894  case tok::kw_alignas:5895    // alignas is a type-specifier-qualifier in C23, which is a kind of5896    // declaration-specifier. Outside of C23 mode (including in C++), it is not.5897    return getLangOpts().C23;5898 5899    // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.5900  case tok::less:5901    return getLangOpts().ObjC;5902 5903    // typedef-name5904  case tok::annot_typename:5905    return !DisambiguatingWithExpression ||5906           !isStartOfObjCClassMessageMissingOpenBracket();5907 5908    // placeholder-type-specifier5909  case tok::annot_template_id: {5910    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);5911    if (TemplateId->hasInvalidName())5912      return true;5913    // FIXME: What about type templates that have only been annotated as5914    // annot_template_id, not as annot_typename?5915    return isTypeConstraintAnnotation() &&5916           (NextToken().is(tok::kw_auto) || NextToken().is(tok::kw_decltype));5917  }5918 5919  case tok::annot_cxxscope: {5920    TemplateIdAnnotation *TemplateId =5921        NextToken().is(tok::annot_template_id)5922            ? takeTemplateIdAnnotation(NextToken())5923            : nullptr;5924    if (TemplateId && TemplateId->hasInvalidName())5925      return true;5926    // FIXME: What about type templates that have only been annotated as5927    // annot_template_id, not as annot_typename?5928    if (NextToken().is(tok::identifier) && TryAnnotateTypeConstraint())5929      return true;5930    return isTypeConstraintAnnotation() &&5931        GetLookAheadToken(2).isOneOf(tok::kw_auto, tok::kw_decltype);5932  }5933 5934  case tok::kw___declspec:5935  case tok::kw___cdecl:5936  case tok::kw___stdcall:5937  case tok::kw___fastcall:5938  case tok::kw___thiscall:5939  case tok::kw___regcall:5940  case tok::kw___vectorcall:5941  case tok::kw___w64:5942  case tok::kw___sptr:5943  case tok::kw___uptr:5944  case tok::kw___ptr64:5945  case tok::kw___ptr32:5946  case tok::kw___forceinline:5947  case tok::kw___pascal:5948  case tok::kw___unaligned:5949  case tok::kw___ptrauth:5950 5951  case tok::kw__Nonnull:5952  case tok::kw__Nullable:5953  case tok::kw__Nullable_result:5954  case tok::kw__Null_unspecified:5955 5956  case tok::kw___kindof:5957 5958  case tok::kw___private:5959  case tok::kw___local:5960  case tok::kw___global:5961  case tok::kw___constant:5962  case tok::kw___generic:5963  case tok::kw___read_only:5964  case tok::kw___read_write:5965  case tok::kw___write_only:5966#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:5967#include "clang/Basic/OpenCLImageTypes.def"5968#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:5969#include "clang/Basic/HLSLIntangibleTypes.def"5970 5971  case tok::kw___funcref:5972  case tok::kw_groupshared:5973    return true;5974 5975  case tok::kw_private:5976    return getLangOpts().OpenCL;5977  }5978}5979 5980bool Parser::isConstructorDeclarator(bool IsUnqualified, bool DeductionGuide,5981                                     DeclSpec::FriendSpecified IsFriend,5982                                     const ParsedTemplateInfo *TemplateInfo) {5983  RevertingTentativeParsingAction TPA(*this);5984  // Parse the C++ scope specifier.5985  CXXScopeSpec SS;5986  if (TemplateInfo && TemplateInfo->TemplateParams)5987    SS.setTemplateParamLists(*TemplateInfo->TemplateParams);5988 5989  if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,5990                                     /*ObjectHasErrors=*/false,5991                                     /*EnteringContext=*/true)) {5992    return false;5993  }5994 5995  // Parse the constructor name.5996  if (Tok.is(tok::identifier)) {5997    // We already know that we have a constructor name; just consume5998    // the token.5999    ConsumeToken();6000  } else if (Tok.is(tok::annot_template_id)) {6001    ConsumeAnnotationToken();6002  } else {6003    return false;6004  }6005 6006  // There may be attributes here, appertaining to the constructor name or type6007  // we just stepped past.6008  SkipCXX11Attributes();6009 6010  // Current class name must be followed by a left parenthesis.6011  if (Tok.isNot(tok::l_paren)) {6012    return false;6013  }6014  ConsumeParen();6015 6016  // A right parenthesis, or ellipsis followed by a right parenthesis signals6017  // that we have a constructor.6018  if (Tok.is(tok::r_paren) ||6019      (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren))) {6020    return true;6021  }6022 6023  // A C++11 attribute here signals that we have a constructor, and is an6024  // attribute on the first constructor parameter.6025  if (isCXX11AttributeSpecifier(/*Disambiguate=*/false,6026                                /*OuterMightBeMessageSend=*/true) !=6027      CXX11AttributeKind::NotAttributeSpecifier) {6028    return true;6029  }6030 6031  // If we need to, enter the specified scope.6032  DeclaratorScopeObj DeclScopeObj(*this, SS);6033  if (SS.isSet() && Actions.ShouldEnterDeclaratorScope(getCurScope(), SS))6034    DeclScopeObj.EnterDeclaratorScope();6035 6036  // Optionally skip Microsoft attributes.6037  ParsedAttributes Attrs(AttrFactory);6038  MaybeParseMicrosoftAttributes(Attrs);6039 6040  // Check whether the next token(s) are part of a declaration6041  // specifier, in which case we have the start of a parameter and,6042  // therefore, we know that this is a constructor.6043  // Due to an ambiguity with implicit typename, the above is not enough.6044  // Additionally, check to see if we are a friend.6045  // If we parsed a scope specifier as well as friend,6046  // we might be parsing a friend constructor.6047  bool IsConstructor = false;6048  ImplicitTypenameContext ITC = IsFriend && !SS.isSet()6049                                    ? ImplicitTypenameContext::No6050                                    : ImplicitTypenameContext::Yes;6051  // Constructors cannot have this parameters, but we support that scenario here6052  // to improve diagnostic.6053  if (Tok.is(tok::kw_this)) {6054    ConsumeToken();6055    return isDeclarationSpecifier(ITC);6056  }6057 6058  if (isDeclarationSpecifier(ITC))6059    IsConstructor = true;6060  else if (Tok.is(tok::identifier) ||6061           (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) {6062    // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type.6063    // This might be a parenthesized member name, but is more likely to6064    // be a constructor declaration with an invalid argument type. Keep6065    // looking.6066    if (Tok.is(tok::annot_cxxscope))6067      ConsumeAnnotationToken();6068    ConsumeToken();6069 6070    // If this is not a constructor, we must be parsing a declarator,6071    // which must have one of the following syntactic forms (see the6072    // grammar extract at the start of ParseDirectDeclarator):6073    switch (Tok.getKind()) {6074    case tok::l_paren:6075      // C(X   (   int));6076    case tok::l_square:6077      // C(X   [   5]);6078      // C(X   [   [attribute]]);6079    case tok::coloncolon:6080      // C(X   ::   Y);6081      // C(X   ::   *p);6082      // Assume this isn't a constructor, rather than assuming it's a6083      // constructor with an unnamed parameter of an ill-formed type.6084      break;6085 6086    case tok::r_paren:6087      // C(X   )6088 6089      // Skip past the right-paren and any following attributes to get to6090      // the function body or trailing-return-type.6091      ConsumeParen();6092      SkipCXX11Attributes();6093 6094      if (DeductionGuide) {6095        // C(X) -> ... is a deduction guide.6096        IsConstructor = Tok.is(tok::arrow);6097        break;6098      }6099      if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {6100        // Assume these were meant to be constructors:6101        //   C(X)   :    (the name of a bit-field cannot be parenthesized).6102        //   C(X)   try  (this is otherwise ill-formed).6103        IsConstructor = true;6104      }6105      if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {6106        // If we have a constructor name within the class definition,6107        // assume these were meant to be constructors:6108        //   C(X)   {6109        //   C(X)   ;6110        // ... because otherwise we would be declaring a non-static data6111        // member that is ill-formed because it's of the same type as its6112        // surrounding class.6113        //6114        // FIXME: We can actually do this whether or not the name is qualified,6115        // because if it is qualified in this context it must be being used as6116        // a constructor name.6117        // currently, so we're somewhat conservative here.6118        IsConstructor = IsUnqualified;6119      }6120      break;6121 6122    default:6123      IsConstructor = true;6124      break;6125    }6126  }6127  return IsConstructor;6128}6129 6130void Parser::ParseTypeQualifierListOpt(6131    DeclSpec &DS, unsigned AttrReqs, bool AtomicOrPtrauthAllowed,6132    bool IdentifierRequired, llvm::function_ref<void()> CodeCompletionHandler) {6133  if ((AttrReqs & AR_CXX11AttributesParsed) &&6134      isAllowedCXX11AttributeSpecifier()) {6135    ParsedAttributes Attrs(AttrFactory);6136    ParseCXX11Attributes(Attrs);6137    DS.takeAttributesAppendingingFrom(Attrs);6138  }6139 6140  SourceLocation EndLoc;6141 6142  while (true) {6143    bool isInvalid = false;6144    const char *PrevSpec = nullptr;6145    unsigned DiagID = 0;6146    SourceLocation Loc = Tok.getLocation();6147 6148    switch (Tok.getKind()) {6149    case tok::code_completion:6150      cutOffParsing();6151      if (CodeCompletionHandler)6152        CodeCompletionHandler();6153      else6154        Actions.CodeCompletion().CodeCompleteTypeQualifiers(DS);6155      return;6156 6157    case tok::kw_const:6158      isInvalid = DS.SetTypeQual(DeclSpec::TQ_const   , Loc, PrevSpec, DiagID,6159                                 getLangOpts());6160      break;6161    case tok::kw_volatile:6162      isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,6163                                 getLangOpts());6164      break;6165    case tok::kw_restrict:6166      isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,6167                                 getLangOpts());6168      break;6169    case tok::kw__Atomic:6170      if (!AtomicOrPtrauthAllowed)6171        goto DoneWithTypeQuals;6172      diagnoseUseOfC11Keyword(Tok);6173      isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID,6174                                 getLangOpts());6175      break;6176 6177    // OpenCL qualifiers:6178    case tok::kw_private:6179      if (!getLangOpts().OpenCL)6180        goto DoneWithTypeQuals;6181      [[fallthrough]];6182    case tok::kw___private:6183    case tok::kw___global:6184    case tok::kw___local:6185    case tok::kw___constant:6186    case tok::kw___generic:6187    case tok::kw___read_only:6188    case tok::kw___write_only:6189    case tok::kw___read_write:6190      ParseOpenCLQualifiers(DS.getAttributes());6191      break;6192 6193    case tok::kw_groupshared:6194    case tok::kw_in:6195    case tok::kw_inout:6196    case tok::kw_out:6197      // NOTE: ParseHLSLQualifiers will consume the qualifier token.6198      ParseHLSLQualifiers(DS.getAttributes());6199      continue;6200 6201    // __ptrauth qualifier.6202    case tok::kw___ptrauth:6203      if (!AtomicOrPtrauthAllowed)6204        goto DoneWithTypeQuals;6205      ParsePtrauthQualifier(DS.getAttributes());6206      EndLoc = PrevTokLocation;6207      continue;6208 6209    case tok::kw___unaligned:6210      isInvalid = DS.SetTypeQual(DeclSpec::TQ_unaligned, Loc, PrevSpec, DiagID,6211                                 getLangOpts());6212      break;6213    case tok::kw___uptr:6214      // GNU libc headers in C mode use '__uptr' as an identifier which conflicts6215      // with the MS modifier keyword.6216      if ((AttrReqs & AR_DeclspecAttributesParsed) && !getLangOpts().CPlusPlus &&6217          IdentifierRequired && DS.isEmpty() && NextToken().is(tok::semi)) {6218        if (TryKeywordIdentFallback(false))6219          continue;6220      }6221      [[fallthrough]];6222    case tok::kw___sptr:6223    case tok::kw___w64:6224    case tok::kw___ptr64:6225    case tok::kw___ptr32:6226    case tok::kw___cdecl:6227    case tok::kw___stdcall:6228    case tok::kw___fastcall:6229    case tok::kw___thiscall:6230    case tok::kw___regcall:6231    case tok::kw___vectorcall:6232      if (AttrReqs & AR_DeclspecAttributesParsed) {6233        ParseMicrosoftTypeAttributes(DS.getAttributes());6234        continue;6235      }6236      goto DoneWithTypeQuals;6237 6238    case tok::kw___funcref:6239      ParseWebAssemblyFuncrefTypeAttribute(DS.getAttributes());6240      continue;6241 6242    case tok::kw___pascal:6243      if (AttrReqs & AR_VendorAttributesParsed) {6244        ParseBorlandTypeAttributes(DS.getAttributes());6245        continue;6246      }6247      goto DoneWithTypeQuals;6248 6249    // Nullability type specifiers.6250    case tok::kw__Nonnull:6251    case tok::kw__Nullable:6252    case tok::kw__Nullable_result:6253    case tok::kw__Null_unspecified:6254      ParseNullabilityTypeSpecifiers(DS.getAttributes());6255      continue;6256 6257    // Objective-C 'kindof' types.6258    case tok::kw___kindof:6259      DS.getAttributes().addNew(Tok.getIdentifierInfo(), Loc,6260                                AttributeScopeInfo(), nullptr, 0,6261                                tok::kw___kindof);6262      (void)ConsumeToken();6263      continue;6264 6265    case tok::kw___attribute:6266      if (AttrReqs & AR_GNUAttributesParsedAndRejected)6267        // When GNU attributes are expressly forbidden, diagnose their usage.6268        Diag(Tok, diag::err_attributes_not_allowed);6269 6270      // Parse the attributes even if they are rejected to ensure that error6271      // recovery is graceful.6272      if (AttrReqs & AR_GNUAttributesParsed ||6273          AttrReqs & AR_GNUAttributesParsedAndRejected) {6274        ParseGNUAttributes(DS.getAttributes());6275        continue; // do *not* consume the next token!6276      }6277      // otherwise, FALL THROUGH!6278      [[fallthrough]];6279    default:6280      DoneWithTypeQuals:6281      // If this is not a type-qualifier token, we're done reading type6282      // qualifiers.  First verify that DeclSpec's are consistent.6283      DS.Finish(Actions, Actions.getASTContext().getPrintingPolicy());6284      if (EndLoc.isValid())6285        DS.SetRangeEnd(EndLoc);6286      return;6287    }6288 6289    // If the specifier combination wasn't legal, issue a diagnostic.6290    if (isInvalid) {6291      assert(PrevSpec && "Method did not return previous specifier!");6292      Diag(Tok, DiagID) << PrevSpec;6293    }6294    EndLoc = ConsumeToken();6295  }6296}6297 6298void Parser::ParseDeclarator(Declarator &D) {6299  /// This implements the 'declarator' production in the C grammar, then checks6300  /// for well-formedness and issues diagnostics.6301  Actions.runWithSufficientStackSpace(D.getBeginLoc(), [&] {6302    ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);6303  });6304}6305 6306static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang,6307                               DeclaratorContext TheContext) {6308  if (Kind == tok::star || Kind == tok::caret)6309    return true;6310 6311  // OpenCL 2.0 and later define this keyword.6312  if (Kind == tok::kw_pipe && Lang.OpenCL &&6313      Lang.getOpenCLCompatibleVersion() >= 200)6314    return true;6315 6316  if (!Lang.CPlusPlus)6317    return false;6318 6319  if (Kind == tok::amp)6320    return true;6321 6322  // We parse rvalue refs in C++03, because otherwise the errors are scary.6323  // But we must not parse them in conversion-type-ids and new-type-ids, since6324  // those can be legitimately followed by a && operator.6325  // (The same thing can in theory happen after a trailing-return-type, but6326  // since those are a C++11 feature, there is no rejects-valid issue there.)6327  if (Kind == tok::ampamp)6328    return Lang.CPlusPlus11 || (TheContext != DeclaratorContext::ConversionId &&6329                                TheContext != DeclaratorContext::CXXNew);6330 6331  return false;6332}6333 6334// Indicates whether the given declarator is a pipe declarator.6335static bool isPipeDeclarator(const Declarator &D) {6336  const unsigned NumTypes = D.getNumTypeObjects();6337 6338  for (unsigned Idx = 0; Idx != NumTypes; ++Idx)6339    if (DeclaratorChunk::Pipe == D.getTypeObject(Idx).Kind)6340      return true;6341 6342  return false;6343}6344 6345void Parser::ParseDeclaratorInternal(Declarator &D,6346                                     DirectDeclParseFunction DirectDeclParser) {6347  if (Diags.hasAllExtensionsSilenced())6348    D.setExtension();6349 6350  // C++ member pointers start with a '::' or a nested-name.6351  // Member pointers get special handling, since there's no place for the6352  // scope spec in the generic path below.6353  if (getLangOpts().CPlusPlus &&6354      (Tok.is(tok::coloncolon) || Tok.is(tok::kw_decltype) ||6355       (Tok.is(tok::identifier) &&6356        (NextToken().is(tok::coloncolon) || NextToken().is(tok::less))) ||6357       Tok.is(tok::annot_cxxscope))) {6358    TentativeParsingAction TPA(*this, /*Unannotated=*/true);6359    bool EnteringContext = D.getContext() == DeclaratorContext::File ||6360                           D.getContext() == DeclaratorContext::Member;6361    CXXScopeSpec SS;6362    SS.setTemplateParamLists(D.getTemplateParameterLists());6363 6364    if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,6365                                       /*ObjectHasErrors=*/false,6366                                       /*EnteringContext=*/false,6367                                       /*MayBePseudoDestructor=*/nullptr,6368                                       /*IsTypename=*/false, /*LastII=*/nullptr,6369                                       /*OnlyNamespace=*/false,6370                                       /*InUsingDeclaration=*/false,6371                                       /*Disambiguation=*/EnteringContext) ||6372 6373        SS.isEmpty() || SS.isInvalid() || !EnteringContext ||6374        Tok.is(tok::star)) {6375      TPA.Commit();6376      if (SS.isNotEmpty() && Tok.is(tok::star)) {6377        if (SS.isValid()) {6378          checkCompoundToken(SS.getEndLoc(), tok::coloncolon,6379                             CompoundToken::MemberPtr);6380        }6381 6382        SourceLocation StarLoc = ConsumeToken();6383        D.SetRangeEnd(StarLoc);6384        DeclSpec DS(AttrFactory);6385        ParseTypeQualifierListOpt(DS);6386        D.ExtendWithDeclSpec(DS);6387 6388        // Recurse to parse whatever is left.6389        Actions.runWithSufficientStackSpace(D.getBeginLoc(), [&] {6390          ParseDeclaratorInternal(D, DirectDeclParser);6391        });6392 6393        // Sema will have to catch (syntactically invalid) pointers into global6394        // scope. It has to catch pointers into namespace scope anyway.6395        D.AddTypeInfo(DeclaratorChunk::getMemberPointer(6396                          SS, DS.getTypeQualifiers(), StarLoc, DS.getEndLoc()),6397                      std::move(DS.getAttributes()),6398                      /*EndLoc=*/SourceLocation());6399        return;6400      }6401    } else {6402      TPA.Revert();6403      SS.clear();6404      ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,6405                                     /*ObjectHasErrors=*/false,6406                                     /*EnteringContext=*/true);6407    }6408 6409    if (SS.isNotEmpty()) {6410      // The scope spec really belongs to the direct-declarator.6411      if (D.mayHaveIdentifier())6412        D.getCXXScopeSpec() = SS;6413      else6414        AnnotateScopeToken(SS, true);6415 6416      if (DirectDeclParser)6417        (this->*DirectDeclParser)(D);6418      return;6419    }6420  }6421 6422  tok::TokenKind Kind = Tok.getKind();6423 6424  if (D.getDeclSpec().isTypeSpecPipe() && !isPipeDeclarator(D)) {6425    DeclSpec DS(AttrFactory);6426    ParseTypeQualifierListOpt(DS);6427 6428    D.AddTypeInfo(6429        DeclaratorChunk::getPipe(DS.getTypeQualifiers(), DS.getPipeLoc()),6430        std::move(DS.getAttributes()), SourceLocation());6431  }6432 6433  // Not a pointer, C++ reference, or block.6434  if (!isPtrOperatorToken(Kind, getLangOpts(), D.getContext())) {6435    if (DirectDeclParser)6436      (this->*DirectDeclParser)(D);6437    return;6438  }6439 6440  // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,6441  // '&&' -> rvalue reference6442  SourceLocation Loc = ConsumeToken();  // Eat the *, ^, & or &&.6443  D.SetRangeEnd(Loc);6444 6445  if (Kind == tok::star || Kind == tok::caret) {6446    // Is a pointer.6447    DeclSpec DS(AttrFactory);6448 6449    // GNU attributes are not allowed here in a new-type-id, but Declspec and6450    // C++11 attributes are allowed.6451    unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |6452                    ((D.getContext() != DeclaratorContext::CXXNew)6453                         ? AR_GNUAttributesParsed6454                         : AR_GNUAttributesParsedAndRejected);6455    ParseTypeQualifierListOpt(DS, Reqs, /*AtomicOrPtrauthAllowed=*/true,6456                              !D.mayOmitIdentifier());6457    D.ExtendWithDeclSpec(DS);6458 6459    // Recursively parse the declarator.6460    Actions.runWithSufficientStackSpace(6461        D.getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });6462    if (Kind == tok::star)6463      // Remember that we parsed a pointer type, and remember the type-quals.6464      D.AddTypeInfo(DeclaratorChunk::getPointer(6465                        DS.getTypeQualifiers(), Loc, DS.getConstSpecLoc(),6466                        DS.getVolatileSpecLoc(), DS.getRestrictSpecLoc(),6467                        DS.getAtomicSpecLoc(), DS.getUnalignedSpecLoc()),6468                    std::move(DS.getAttributes()), SourceLocation());6469    else6470      // Remember that we parsed a Block type, and remember the type-quals.6471      D.AddTypeInfo(6472          DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(), Loc),6473          std::move(DS.getAttributes()), SourceLocation());6474  } else {6475    // Is a reference6476    DeclSpec DS(AttrFactory);6477 6478    // Complain about rvalue references in C++03, but then go on and build6479    // the declarator.6480    if (Kind == tok::ampamp)6481      Diag(Loc, getLangOpts().CPlusPlus11 ?6482           diag::warn_cxx98_compat_rvalue_reference :6483           diag::ext_rvalue_reference);6484 6485    // GNU-style and C++11 attributes are allowed here, as is restrict.6486    ParseTypeQualifierListOpt(DS);6487    D.ExtendWithDeclSpec(DS);6488 6489    // C++ 8.3.2p1: cv-qualified references are ill-formed except when the6490    // cv-qualifiers are introduced through the use of a typedef or of a6491    // template type argument, in which case the cv-qualifiers are ignored.6492    if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {6493      if (DS.getTypeQualifiers() & DeclSpec::TQ_const)6494        Diag(DS.getConstSpecLoc(),6495             diag::err_invalid_reference_qualifier_application) << "const";6496      if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)6497        Diag(DS.getVolatileSpecLoc(),6498             diag::err_invalid_reference_qualifier_application) << "volatile";6499      // 'restrict' is permitted as an extension.6500      if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic)6501        Diag(DS.getAtomicSpecLoc(),6502             diag::err_invalid_reference_qualifier_application) << "_Atomic";6503    }6504 6505    // Recursively parse the declarator.6506    Actions.runWithSufficientStackSpace(6507        D.getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });6508 6509    if (D.getNumTypeObjects() > 0) {6510      // C++ [dcl.ref]p4: There shall be no references to references.6511      DeclaratorChunk& InnerChunk = D.getTypeObject(D.getNumTypeObjects() - 1);6512      if (InnerChunk.Kind == DeclaratorChunk::Reference) {6513        if (const IdentifierInfo *II = D.getIdentifier())6514          Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)6515           << II;6516        else6517          Diag(InnerChunk.Loc, diag::err_illegal_decl_reference_to_reference)6518            << "type name";6519 6520        // Once we've complained about the reference-to-reference, we6521        // can go ahead and build the (technically ill-formed)6522        // declarator: reference collapsing will take care of it.6523      }6524    }6525 6526    // Remember that we parsed a reference type.6527    D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,6528                                                Kind == tok::amp),6529                  std::move(DS.getAttributes()), SourceLocation());6530  }6531}6532 6533// When correcting from misplaced brackets before the identifier, the location6534// is saved inside the declarator so that other diagnostic messages can use6535// them.  This extracts and returns that location, or returns the provided6536// location if a stored location does not exist.6537static SourceLocation getMissingDeclaratorIdLoc(Declarator &D,6538                                                SourceLocation Loc) {6539  if (D.getName().StartLocation.isInvalid() &&6540      D.getName().EndLocation.isValid())6541    return D.getName().EndLocation;6542 6543  return Loc;6544}6545 6546void Parser::ParseDirectDeclarator(Declarator &D) {6547  DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());6548 6549  if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) {6550    // This might be a C++17 structured binding.6551    if (Tok.is(tok::l_square) && !D.mayOmitIdentifier() &&6552        D.getCXXScopeSpec().isEmpty())6553      return ParseDecompositionDeclarator(D);6554 6555    // Don't parse FOO:BAR as if it were a typo for FOO::BAR inside a class, in6556    // this context it is a bitfield. Also in range-based for statement colon6557    // may delimit for-range-declaration.6558    ColonProtectionRAIIObject X(6559        *this, D.getContext() == DeclaratorContext::Member ||6560                   (D.getContext() == DeclaratorContext::ForInit &&6561                    getLangOpts().CPlusPlus11));6562 6563    // ParseDeclaratorInternal might already have parsed the scope.6564    if (D.getCXXScopeSpec().isEmpty()) {6565      bool EnteringContext = D.getContext() == DeclaratorContext::File ||6566                             D.getContext() == DeclaratorContext::Member;6567      ParseOptionalCXXScopeSpecifier(6568          D.getCXXScopeSpec(), /*ObjectType=*/nullptr,6569          /*ObjectHasErrors=*/false, EnteringContext);6570    }6571 6572    // C++23 [basic.scope.namespace]p1:6573    //   For each non-friend redeclaration or specialization whose target scope6574    //   is or is contained by the scope, the portion after the declarator-id,6575    //   class-head-name, or enum-head-name is also included in the scope.6576    // C++23 [basic.scope.class]p1:6577    //   For each non-friend redeclaration or specialization whose target scope6578    //   is or is contained by the scope, the portion after the declarator-id,6579    //   class-head-name, or enum-head-name is also included in the scope.6580    //6581    // FIXME: We should not be doing this for friend declarations; they have6582    // their own special lookup semantics specified by [basic.lookup.unqual]p6.6583    if (D.getCXXScopeSpec().isValid()) {6584      if (Actions.ShouldEnterDeclaratorScope(getCurScope(),6585                                             D.getCXXScopeSpec()))6586        // Change the declaration context for name lookup, until this function6587        // is exited (and the declarator has been parsed).6588        DeclScopeObj.EnterDeclaratorScope();6589      else if (getObjCDeclContext()) {6590        // Ensure that we don't interpret the next token as an identifier when6591        // dealing with declarations in an Objective-C container.6592        D.SetIdentifier(nullptr, Tok.getLocation());6593        D.setInvalidType(true);6594        ConsumeToken();6595        goto PastIdentifier;6596      }6597    }6598 6599    // C++0x [dcl.fct]p14:6600    //   There is a syntactic ambiguity when an ellipsis occurs at the end of a6601    //   parameter-declaration-clause without a preceding comma. In this case,6602    //   the ellipsis is parsed as part of the abstract-declarator if the type6603    //   of the parameter either names a template parameter pack that has not6604    //   been expanded or contains auto; otherwise, it is parsed as part of the6605    //   parameter-declaration-clause.6606    if (Tok.is(tok::ellipsis) && D.getCXXScopeSpec().isEmpty() &&6607        !((D.getContext() == DeclaratorContext::Prototype ||6608           D.getContext() == DeclaratorContext::LambdaExprParameter ||6609           D.getContext() == DeclaratorContext::BlockLiteral) &&6610          NextToken().is(tok::r_paren) && !D.hasGroupingParens() &&6611          !Actions.containsUnexpandedParameterPacks(D) &&6612          D.getDeclSpec().getTypeSpecType() != TST_auto)) {6613      SourceLocation EllipsisLoc = ConsumeToken();6614      if (isPtrOperatorToken(Tok.getKind(), getLangOpts(), D.getContext())) {6615        // The ellipsis was put in the wrong place. Recover, and explain to6616        // the user what they should have done.6617        ParseDeclarator(D);6618        if (EllipsisLoc.isValid())6619          DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);6620        return;6621      } else6622        D.setEllipsisLoc(EllipsisLoc);6623 6624      // The ellipsis can't be followed by a parenthesized declarator. We6625      // check for that in ParseParenDeclarator, after we have disambiguated6626      // the l_paren token.6627    }6628 6629    if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,6630                    tok::tilde)) {6631      // We found something that indicates the start of an unqualified-id.6632      // Parse that unqualified-id.6633      bool AllowConstructorName;6634      bool AllowDeductionGuide;6635      if (D.getDeclSpec().hasTypeSpecifier()) {6636        AllowConstructorName = false;6637        AllowDeductionGuide = false;6638      } else if (D.getCXXScopeSpec().isSet()) {6639        AllowConstructorName = (D.getContext() == DeclaratorContext::File ||6640                                D.getContext() == DeclaratorContext::Member);6641        AllowDeductionGuide = false;6642      } else {6643        AllowConstructorName = (D.getContext() == DeclaratorContext::Member);6644        AllowDeductionGuide = (D.getContext() == DeclaratorContext::File ||6645                               D.getContext() == DeclaratorContext::Member);6646      }6647 6648      bool HadScope = D.getCXXScopeSpec().isValid();6649      SourceLocation TemplateKWLoc;6650      if (ParseUnqualifiedId(D.getCXXScopeSpec(),6651                             /*ObjectType=*/nullptr,6652                             /*ObjectHadErrors=*/false,6653                             /*EnteringContext=*/true,6654                             /*AllowDestructorName=*/true, AllowConstructorName,6655                             AllowDeductionGuide, &TemplateKWLoc,6656                             D.getName()) ||6657          // Once we're past the identifier, if the scope was bad, mark the6658          // whole declarator bad.6659          D.getCXXScopeSpec().isInvalid()) {6660        D.SetIdentifier(nullptr, Tok.getLocation());6661        D.setInvalidType(true);6662      } else {6663        // ParseUnqualifiedId might have parsed a scope specifier during error6664        // recovery. If it did so, enter that scope.6665        if (!HadScope && D.getCXXScopeSpec().isValid() &&6666            Actions.ShouldEnterDeclaratorScope(getCurScope(),6667                                               D.getCXXScopeSpec()))6668          DeclScopeObj.EnterDeclaratorScope();6669 6670        // Parsed the unqualified-id; update range information and move along.6671        if (D.getSourceRange().getBegin().isInvalid())6672          D.SetRangeBegin(D.getName().getSourceRange().getBegin());6673        D.SetRangeEnd(D.getName().getSourceRange().getEnd());6674      }6675      goto PastIdentifier;6676    }6677 6678    if (D.getCXXScopeSpec().isNotEmpty()) {6679      // We have a scope specifier but no following unqualified-id.6680      Diag(PP.getLocForEndOfToken(D.getCXXScopeSpec().getEndLoc()),6681           diag::err_expected_unqualified_id)6682          << /*C++*/1;6683      D.SetIdentifier(nullptr, Tok.getLocation());6684      goto PastIdentifier;6685    }6686  } else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {6687    assert(!getLangOpts().CPlusPlus &&6688           "There's a C++-specific check for tok::identifier above");6689    assert(Tok.getIdentifierInfo() && "Not an identifier?");6690    D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());6691    D.SetRangeEnd(Tok.getLocation());6692    ConsumeToken();6693    goto PastIdentifier;6694  } else if (Tok.is(tok::identifier) && !D.mayHaveIdentifier()) {6695    // We're not allowed an identifier here, but we got one. Try to figure out6696    // if the user was trying to attach a name to the type, or whether the name6697    // is some unrelated trailing syntax.6698    bool DiagnoseIdentifier = false;6699    if (D.hasGroupingParens())6700      // An identifier within parens is unlikely to be intended to be anything6701      // other than a name being "declared".6702      DiagnoseIdentifier = true;6703    else if (D.getContext() == DeclaratorContext::TemplateArg)6704      // T<int N> is an accidental identifier; T<int N indicates a missing '>'.6705      DiagnoseIdentifier =6706          NextToken().isOneOf(tok::comma, tok::greater, tok::greatergreater);6707    else if (D.getContext() == DeclaratorContext::AliasDecl ||6708             D.getContext() == DeclaratorContext::AliasTemplate)6709      // The most likely error is that the ';' was forgotten.6710      DiagnoseIdentifier = NextToken().isOneOf(tok::comma, tok::semi);6711    else if ((D.getContext() == DeclaratorContext::TrailingReturn ||6712              D.getContext() == DeclaratorContext::TrailingReturnVar) &&6713             !isCXX11VirtSpecifier(Tok))6714      DiagnoseIdentifier = NextToken().isOneOf(6715          tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);6716    if (DiagnoseIdentifier) {6717      Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)6718        << FixItHint::CreateRemoval(Tok.getLocation());6719      D.SetIdentifier(nullptr, Tok.getLocation());6720      ConsumeToken();6721      goto PastIdentifier;6722    }6723  }6724 6725  if (Tok.is(tok::l_paren)) {6726    // If this might be an abstract-declarator followed by a direct-initializer,6727    // check whether this is a valid declarator chunk. If it can't be, assume6728    // that it's an initializer instead.6729    if (D.mayOmitIdentifier() && D.mayBeFollowedByCXXDirectInit()) {6730      RevertingTentativeParsingAction PA(*this);6731      if (TryParseDeclarator(true, D.mayHaveIdentifier(), true,6732                             D.getDeclSpec().getTypeSpecType() == TST_auto) ==6733          TPResult::False) {6734        D.SetIdentifier(nullptr, Tok.getLocation());6735        goto PastIdentifier;6736      }6737    }6738 6739    // direct-declarator: '(' declarator ')'6740    // direct-declarator: '(' attributes declarator ')'6741    // Example: 'char (*X)'   or 'int (*XX)(void)'6742    ParseParenDeclarator(D);6743 6744    // If the declarator was parenthesized, we entered the declarator6745    // scope when parsing the parenthesized declarator, then exited6746    // the scope already. Re-enter the scope, if we need to.6747    if (D.getCXXScopeSpec().isSet()) {6748      // If there was an error parsing parenthesized declarator, declarator6749      // scope may have been entered before. Don't do it again.6750      if (!D.isInvalidType() &&6751          Actions.ShouldEnterDeclaratorScope(getCurScope(),6752                                             D.getCXXScopeSpec()))6753        // Change the declaration context for name lookup, until this function6754        // is exited (and the declarator has been parsed).6755        DeclScopeObj.EnterDeclaratorScope();6756    }6757  } else if (D.mayOmitIdentifier()) {6758    // This could be something simple like "int" (in which case the declarator6759    // portion is empty), if an abstract-declarator is allowed.6760    D.SetIdentifier(nullptr, Tok.getLocation());6761 6762    // The grammar for abstract-pack-declarator does not allow grouping parens.6763    // FIXME: Revisit this once core issue 1488 is resolved.6764    if (D.hasEllipsis() && D.hasGroupingParens())6765      Diag(PP.getLocForEndOfToken(D.getEllipsisLoc()),6766           diag::ext_abstract_pack_declarator_parens);6767  } else {6768    if (Tok.getKind() == tok::annot_pragma_parser_crash)6769      LLVM_BUILTIN_TRAP;6770    if (Tok.is(tok::l_square))6771      return ParseMisplacedBracketDeclarator(D);6772    if (D.getContext() == DeclaratorContext::Member) {6773      // Objective-C++: Detect C++ keywords and try to prevent further errors by6774      // treating these keyword as valid member names.6775      if (getLangOpts().ObjC && getLangOpts().CPlusPlus &&6776          !Tok.isAnnotation() && Tok.getIdentifierInfo() &&6777          Tok.getIdentifierInfo()->isCPlusPlusKeyword(getLangOpts())) {6778        Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),6779             diag::err_expected_member_name_or_semi_objcxx_keyword)6780            << Tok.getIdentifierInfo()6781            << (D.getDeclSpec().isEmpty() ? SourceRange()6782                                          : D.getDeclSpec().getSourceRange());6783        D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());6784        D.SetRangeEnd(Tok.getLocation());6785        ConsumeToken();6786        goto PastIdentifier;6787      }6788      Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),6789           diag::err_expected_member_name_or_semi)6790          << (D.getDeclSpec().isEmpty() ? SourceRange()6791                                        : D.getDeclSpec().getSourceRange());6792    } else {6793      if (Tok.getKind() == tok::TokenKind::kw_while) {6794        Diag(Tok, diag::err_while_loop_outside_of_a_function);6795      } else if (getLangOpts().CPlusPlus) {6796        if (Tok.isOneOf(tok::period, tok::arrow))6797          Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);6798        else {6799          SourceLocation Loc = D.getCXXScopeSpec().getEndLoc();6800          if (Tok.isAtStartOfLine() && Loc.isValid())6801            Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)6802                << getLangOpts().CPlusPlus;6803          else6804            Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),6805                 diag::err_expected_unqualified_id)6806                << getLangOpts().CPlusPlus;6807        }6808      } else {6809        Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),6810             diag::err_expected_either)6811            << tok::identifier << tok::l_paren;6812      }6813    }6814    D.SetIdentifier(nullptr, Tok.getLocation());6815    D.setInvalidType(true);6816  }6817 6818 PastIdentifier:6819  assert(D.isPastIdentifier() &&6820         "Haven't past the location of the identifier yet?");6821 6822  // Don't parse attributes unless we have parsed an unparenthesized name.6823  if (D.hasName() && !D.getNumTypeObjects())6824    MaybeParseCXX11Attributes(D);6825 6826  while (true) {6827    if (Tok.is(tok::l_paren)) {6828      bool IsFunctionDeclaration = D.isFunctionDeclaratorAFunctionDeclaration();6829      // Enter function-declaration scope, limiting any declarators to the6830      // function prototype scope, including parameter declarators.6831      ParseScope PrototypeScope(6832          this, Scope::FunctionPrototypeScope | Scope::DeclScope |6833                    (IsFunctionDeclaration ? Scope::FunctionDeclarationScope6834                                           : Scope::NoScope));6835 6836      // The paren may be part of a C++ direct initializer, eg. "int x(1);".6837      // In such a case, check if we actually have a function declarator; if it6838      // is not, the declarator has been fully parsed.6839      bool IsAmbiguous = false;6840      if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {6841        // C++2a [temp.res]p56842        // A qualified-id is assumed to name a type if6843        //   - [...]6844        //   - it is a decl-specifier of the decl-specifier-seq of a6845        //     - [...]6846        //     - parameter-declaration in a member-declaration [...]6847        //     - parameter-declaration in a declarator of a function or function6848        //       template declaration whose declarator-id is qualified [...]6849        auto AllowImplicitTypename = ImplicitTypenameContext::No;6850        if (D.getCXXScopeSpec().isSet())6851          AllowImplicitTypename =6852              (ImplicitTypenameContext)Actions.isDeclaratorFunctionLike(D);6853        else if (D.getContext() == DeclaratorContext::Member) {6854          AllowImplicitTypename = ImplicitTypenameContext::Yes;6855        }6856 6857        // The name of the declarator, if any, is tentatively declared within6858        // a possible direct initializer.6859        TentativelyDeclaredIdentifiers.push_back(D.getIdentifier());6860        bool IsFunctionDecl =6861            isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);6862        TentativelyDeclaredIdentifiers.pop_back();6863        if (!IsFunctionDecl)6864          break;6865      }6866      ParsedAttributes attrs(AttrFactory);6867      BalancedDelimiterTracker T(*this, tok::l_paren);6868      T.consumeOpen();6869      if (IsFunctionDeclaration)6870        Actions.ActOnStartFunctionDeclarationDeclarator(D,6871                                                        TemplateParameterDepth);6872      ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);6873      if (IsFunctionDeclaration)6874        Actions.ActOnFinishFunctionDeclarationDeclarator(D);6875      PrototypeScope.Exit();6876    } else if (Tok.is(tok::l_square)) {6877      ParseBracketDeclarator(D);6878    } else if (Tok.isRegularKeywordAttribute()) {6879      // For consistency with attribute parsing.6880      Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();6881      bool TakesArgs = doesKeywordAttributeTakeArgs(Tok.getKind());6882      ConsumeToken();6883      if (TakesArgs) {6884        BalancedDelimiterTracker T(*this, tok::l_paren);6885        if (!T.consumeOpen())6886          T.skipToEnd();6887      }6888    } else if (Tok.is(tok::kw_requires) && D.hasGroupingParens()) {6889      // This declarator is declaring a function, but the requires clause is6890      // in the wrong place:6891      //   void (f() requires true);6892      // instead of6893      //   void f() requires true;6894      // or6895      //   void (f()) requires true;6896      Diag(Tok, diag::err_requires_clause_inside_parens);6897      ConsumeToken();6898      ExprResult TrailingRequiresClause =6899          ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true);6900      if (TrailingRequiresClause.isUsable() && D.isFunctionDeclarator() &&6901          !D.hasTrailingRequiresClause())6902        // We're already ill-formed if we got here but we'll accept it anyway.6903        D.setTrailingRequiresClause(TrailingRequiresClause.get());6904    } else {6905      break;6906    }6907  }6908}6909 6910void Parser::ParseDecompositionDeclarator(Declarator &D) {6911  assert(Tok.is(tok::l_square));6912 6913  TentativeParsingAction PA(*this);6914  BalancedDelimiterTracker T(*this, tok::l_square);6915  T.consumeOpen();6916 6917  if (isCXX11AttributeSpecifier() != CXX11AttributeKind::NotAttributeSpecifier)6918    DiagnoseAndSkipCXX11Attributes();6919 6920  // If this doesn't look like a structured binding, maybe it's a misplaced6921  // array declarator.6922  if (!(Tok.isOneOf(tok::identifier, tok::ellipsis) &&6923        NextToken().isOneOf(tok::comma, tok::r_square, tok::kw_alignas,6924                            tok::identifier, tok::l_square, tok::ellipsis)) &&6925      !(Tok.is(tok::r_square) &&6926        NextToken().isOneOf(tok::equal, tok::l_brace))) {6927    PA.Revert();6928    return ParseMisplacedBracketDeclarator(D);6929  }6930 6931  SourceLocation PrevEllipsisLoc;6932  SmallVector<DecompositionDeclarator::Binding, 32> Bindings;6933  while (Tok.isNot(tok::r_square)) {6934    if (!Bindings.empty()) {6935      if (Tok.is(tok::comma))6936        ConsumeToken();6937      else {6938        if (Tok.is(tok::identifier)) {6939          SourceLocation EndLoc = getEndOfPreviousToken();6940          Diag(EndLoc, diag::err_expected)6941              << tok::comma << FixItHint::CreateInsertion(EndLoc, ",");6942        } else {6943          Diag(Tok, diag::err_expected_comma_or_rsquare);6944        }6945 6946        SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis},6947                  StopAtSemi | StopBeforeMatch);6948        if (Tok.is(tok::comma))6949          ConsumeToken();6950        else if (Tok.is(tok::r_square))6951          break;6952      }6953    }6954 6955    if (isCXX11AttributeSpecifier() !=6956        CXX11AttributeKind::NotAttributeSpecifier)6957      DiagnoseAndSkipCXX11Attributes();6958 6959    SourceLocation EllipsisLoc;6960 6961    if (Tok.is(tok::ellipsis)) {6962      Diag(Tok, getLangOpts().CPlusPlus26 ? diag::warn_cxx23_compat_binding_pack6963                                          : diag::ext_cxx_binding_pack);6964      if (PrevEllipsisLoc.isValid()) {6965        Diag(Tok, diag::err_binding_multiple_ellipses);6966        Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);6967        break;6968      }6969      EllipsisLoc = Tok.getLocation();6970      PrevEllipsisLoc = EllipsisLoc;6971      ConsumeToken();6972    }6973 6974    if (Tok.isNot(tok::identifier)) {6975      Diag(Tok, diag::err_expected) << tok::identifier;6976      break;6977    }6978 6979    IdentifierInfo *II = Tok.getIdentifierInfo();6980    SourceLocation Loc = Tok.getLocation();6981    ConsumeToken();6982 6983    if (Tok.is(tok::ellipsis) && !PrevEllipsisLoc.isValid()) {6984      DiagnoseMisplacedEllipsis(Tok.getLocation(), Loc, EllipsisLoc.isValid(),6985                                true);6986      EllipsisLoc = Tok.getLocation();6987      ConsumeToken();6988    }6989 6990    ParsedAttributes Attrs(AttrFactory);6991    if (isCXX11AttributeSpecifier() !=6992        CXX11AttributeKind::NotAttributeSpecifier) {6993      Diag(Tok, getLangOpts().CPlusPlus266994                    ? diag::warn_cxx23_compat_decl_attrs_on_binding6995                    : diag::ext_decl_attrs_on_binding);6996      MaybeParseCXX11Attributes(Attrs);6997    }6998 6999    Bindings.push_back({II, Loc, std::move(Attrs), EllipsisLoc});7000  }7001 7002  if (Tok.isNot(tok::r_square))7003    // We've already diagnosed a problem here.7004    T.skipToEnd();7005  else {7006    // C++17 does not allow the identifier-list in a structured binding7007    // to be empty.7008    if (Bindings.empty())7009      Diag(Tok.getLocation(), diag::ext_decomp_decl_empty);7010 7011    T.consumeClose();7012  }7013 7014  PA.Commit();7015 7016  return D.setDecompositionBindings(T.getOpenLocation(), Bindings,7017                                    T.getCloseLocation());7018}7019 7020void Parser::ParseParenDeclarator(Declarator &D) {7021  BalancedDelimiterTracker T(*this, tok::l_paren);7022  T.consumeOpen();7023 7024  assert(!D.isPastIdentifier() && "Should be called before passing identifier");7025 7026  // Eat any attributes before we look at whether this is a grouping or function7027  // declarator paren.  If this is a grouping paren, the attribute applies to7028  // the type being built up, for example:7029  //     int (__attribute__(()) *x)(long y)7030  // If this ends up not being a grouping paren, the attribute applies to the7031  // first argument, for example:7032  //     int (__attribute__(()) int x)7033  // In either case, we need to eat any attributes to be able to determine what7034  // sort of paren this is.7035  //7036  ParsedAttributes attrs(AttrFactory);7037  bool RequiresArg = false;7038  if (Tok.is(tok::kw___attribute)) {7039    ParseGNUAttributes(attrs);7040 7041    // We require that the argument list (if this is a non-grouping paren) be7042    // present even if the attribute list was empty.7043    RequiresArg = true;7044  }7045 7046  // Eat any Microsoft extensions.7047  ParseMicrosoftTypeAttributes(attrs);7048 7049  // Eat any Borland extensions.7050  if  (Tok.is(tok::kw___pascal))7051    ParseBorlandTypeAttributes(attrs);7052 7053  // If we haven't past the identifier yet (or where the identifier would be7054  // stored, if this is an abstract declarator), then this is probably just7055  // grouping parens. However, if this could be an abstract-declarator, then7056  // this could also be the start of function arguments (consider 'void()').7057  bool isGrouping;7058 7059  if (!D.mayOmitIdentifier()) {7060    // If this can't be an abstract-declarator, this *must* be a grouping7061    // paren, because we haven't seen the identifier yet.7062    isGrouping = true;7063  } else if (Tok.is(tok::r_paren) || // 'int()' is a function.7064             ((getLangOpts().CPlusPlus || getLangOpts().C23) &&7065              Tok.is(tok::ellipsis) &&7066              NextToken().is(tok::r_paren)) || // C++ int(...)7067             isDeclarationSpecifier(7068                 ImplicitTypenameContext::No) || // 'int(int)' is a function.7069             isCXX11AttributeSpecifier() !=7070                 CXX11AttributeKind::NotAttributeSpecifier) { // 'int([[]]int)'7071                                                              // is a function.7072    // This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is7073    // considered to be a type, not a K&R identifier-list.7074    isGrouping = false;7075  } else {7076    // Otherwise, this is a grouping paren, e.g. 'int (*X)' or 'int(X)'.7077    isGrouping = true;7078  }7079 7080  // If this is a grouping paren, handle:7081  // direct-declarator: '(' declarator ')'7082  // direct-declarator: '(' attributes declarator ')'7083  if (isGrouping) {7084    SourceLocation EllipsisLoc = D.getEllipsisLoc();7085    D.setEllipsisLoc(SourceLocation());7086 7087    bool hadGroupingParens = D.hasGroupingParens();7088    D.setGroupingParens(true);7089    ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);7090    // Match the ')'.7091    T.consumeClose();7092    D.AddTypeInfo(7093        DeclaratorChunk::getParen(T.getOpenLocation(), T.getCloseLocation()),7094        std::move(attrs), T.getCloseLocation());7095 7096    D.setGroupingParens(hadGroupingParens);7097 7098    // An ellipsis cannot be placed outside parentheses.7099    if (EllipsisLoc.isValid())7100      DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);7101 7102    return;7103  }7104 7105  // Okay, if this wasn't a grouping paren, it must be the start of a function7106  // argument list.  Recognize that this declarator will never have an7107  // identifier (and remember where it would have been), then call into7108  // ParseFunctionDeclarator to handle of argument list.7109  D.SetIdentifier(nullptr, Tok.getLocation());7110 7111  // Enter function-declaration scope, limiting any declarators to the7112  // function prototype scope, including parameter declarators.7113  ParseScope PrototypeScope(this,7114                            Scope::FunctionPrototypeScope | Scope::DeclScope |7115                                (D.isFunctionDeclaratorAFunctionDeclaration()7116                                     ? Scope::FunctionDeclarationScope7117                                     : Scope::NoScope));7118  ParseFunctionDeclarator(D, attrs, T, false, RequiresArg);7119  PrototypeScope.Exit();7120}7121 7122void Parser::InitCXXThisScopeForDeclaratorIfRelevant(7123    const Declarator &D, const DeclSpec &DS,7124    std::optional<Sema::CXXThisScopeRAII> &ThisScope) {7125  // C++11 [expr.prim.general]p3:7126  //   If a declaration declares a member function or member function7127  //   template of a class X, the expression this is a prvalue of type7128  //   "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq7129  //   and the end of the function-definition, member-declarator, or7130  //   declarator.7131  // FIXME: currently, "static" case isn't handled correctly.7132  bool IsCXX11MemberFunction =7133      getLangOpts().CPlusPlus11 &&7134      D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&7135      (D.getContext() == DeclaratorContext::Member7136           ? !D.getDeclSpec().isFriendSpecified()7137           : D.getContext() == DeclaratorContext::File &&7138                 D.getCXXScopeSpec().isValid() &&7139                 Actions.CurContext->isRecord());7140  if (!IsCXX11MemberFunction)7141    return;7142 7143  Qualifiers Q = Qualifiers::fromCVRUMask(DS.getTypeQualifiers());7144  if (D.getDeclSpec().hasConstexprSpecifier() && !getLangOpts().CPlusPlus14)7145    Q.addConst();7146  // FIXME: Collect C++ address spaces.7147  // If there are multiple different address spaces, the source is invalid.7148  // Carry on using the first addr space for the qualifiers of 'this'.7149  // The diagnostic will be given later while creating the function7150  // prototype for the method.7151  if (getLangOpts().OpenCLCPlusPlus) {7152    for (ParsedAttr &attr : DS.getAttributes()) {7153      LangAS ASIdx = attr.asOpenCLLangAS();7154      if (ASIdx != LangAS::Default) {7155        Q.addAddressSpace(ASIdx);7156        break;7157      }7158    }7159  }7160  ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,7161                    IsCXX11MemberFunction);7162}7163 7164void Parser::ParseFunctionDeclarator(Declarator &D,7165                                     ParsedAttributes &FirstArgAttrs,7166                                     BalancedDelimiterTracker &Tracker,7167                                     bool IsAmbiguous,7168                                     bool RequiresArg) {7169  assert(getCurScope()->isFunctionPrototypeScope() &&7170         "Should call from a Function scope");7171  // lparen is already consumed!7172  assert(D.isPastIdentifier() && "Should not call before identifier!");7173 7174  // This should be true when the function has typed arguments.7175  // Otherwise, it is treated as a K&R-style function.7176  bool HasProto = false;7177  // Build up an array of information about the parsed arguments.7178  SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;7179  // Remember where we see an ellipsis, if any.7180  SourceLocation EllipsisLoc;7181 7182  DeclSpec DS(AttrFactory);7183  bool RefQualifierIsLValueRef = true;7184  SourceLocation RefQualifierLoc;7185  ExceptionSpecificationType ESpecType = EST_None;7186  SourceRange ESpecRange;7187  SmallVector<ParsedType, 2> DynamicExceptions;7188  SmallVector<SourceRange, 2> DynamicExceptionRanges;7189  ExprResult NoexceptExpr;7190  CachedTokens *ExceptionSpecTokens = nullptr;7191  ParsedAttributes FnAttrs(AttrFactory);7192  TypeResult TrailingReturnType;7193  SourceLocation TrailingReturnTypeLoc;7194 7195  /* LocalEndLoc is the end location for the local FunctionTypeLoc.7196     EndLoc is the end location for the function declarator.7197     They differ for trailing return types. */7198  SourceLocation StartLoc, LocalEndLoc, EndLoc;7199  SourceLocation LParenLoc, RParenLoc;7200  LParenLoc = Tracker.getOpenLocation();7201  StartLoc = LParenLoc;7202 7203  if (isFunctionDeclaratorIdentifierList()) {7204    if (RequiresArg)7205      Diag(Tok, diag::err_argument_required_after_attribute);7206 7207    ParseFunctionDeclaratorIdentifierList(D, ParamInfo);7208 7209    Tracker.consumeClose();7210    RParenLoc = Tracker.getCloseLocation();7211    LocalEndLoc = RParenLoc;7212    EndLoc = RParenLoc;7213 7214    // If there are attributes following the identifier list, parse them and7215    // prohibit them.7216    MaybeParseCXX11Attributes(FnAttrs);7217    ProhibitAttributes(FnAttrs);7218  } else {7219    if (Tok.isNot(tok::r_paren))7220      ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);7221    else if (RequiresArg)7222      Diag(Tok, diag::err_argument_required_after_attribute);7223 7224    // OpenCL disallows functions without a prototype, but it doesn't enforce7225    // strict prototypes as in C23 because it allows a function definition to7226    // have an identifier list. See OpenCL 3.0 6.11/g for more details.7227    HasProto = ParamInfo.size() || getLangOpts().requiresStrictPrototypes() ||7228               getLangOpts().OpenCL;7229 7230    // If we have the closing ')', eat it.7231    Tracker.consumeClose();7232    RParenLoc = Tracker.getCloseLocation();7233    LocalEndLoc = RParenLoc;7234    EndLoc = RParenLoc;7235 7236    if (getLangOpts().CPlusPlus) {7237      // FIXME: Accept these components in any order, and produce fixits to7238      // correct the order if the user gets it wrong. Ideally we should deal7239      // with the pure-specifier in the same way.7240 7241      // Parse cv-qualifier-seq[opt].7242      ParseTypeQualifierListOpt(7243          DS, AR_NoAttributesParsed,7244          /*AtomicOrPtrauthAllowed=*/false,7245          /*IdentifierRequired=*/false, [&]() {7246            Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);7247          });7248      if (!DS.getSourceRange().getEnd().isInvalid()) {7249        EndLoc = DS.getSourceRange().getEnd();7250      }7251 7252      // Parse ref-qualifier[opt].7253      if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))7254        EndLoc = RefQualifierLoc;7255 7256      std::optional<Sema::CXXThisScopeRAII> ThisScope;7257      InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);7258 7259      // C++ [class.mem.general]p8:7260      //   A complete-class context of a class (template) is a7261      //     - function body,7262      //     - default argument,7263      //     - default template argument,7264      //     - noexcept-specifier, or7265      //     - default member initializer7266      //   within the member-specification of the class or class template.7267      //7268      // Parse exception-specification[opt]. If we are in the7269      // member-specification of a class or class template, this is a7270      // complete-class context and parsing of the noexcept-specifier should be7271      // delayed (even if this is a friend declaration).7272      bool Delayed = D.getContext() == DeclaratorContext::Member &&7273                     D.isFunctionDeclaratorAFunctionDeclaration();7274      if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&7275          GetLookAheadToken(0).is(tok::kw_noexcept) &&7276          GetLookAheadToken(1).is(tok::l_paren) &&7277          GetLookAheadToken(2).is(tok::kw_noexcept) &&7278          GetLookAheadToken(3).is(tok::l_paren) &&7279          GetLookAheadToken(4).is(tok::identifier) &&7280          GetLookAheadToken(4).getIdentifierInfo()->isStr("swap")) {7281        // HACK: We've got an exception-specification7282        //   noexcept(noexcept(swap(...)))7283        // or7284        //   noexcept(noexcept(swap(...)) && noexcept(swap(...)))7285        // on a 'swap' member function. This is a libstdc++ bug; the lookup7286        // for 'swap' will only find the function we're currently declaring,7287        // whereas it expects to find a non-member swap through ADL. Turn off7288        // delayed parsing to give it a chance to find what it expects.7289        Delayed = false;7290      }7291      ESpecType = tryParseExceptionSpecification(Delayed,7292                                                 ESpecRange,7293                                                 DynamicExceptions,7294                                                 DynamicExceptionRanges,7295                                                 NoexceptExpr,7296                                                 ExceptionSpecTokens);7297      if (ESpecType != EST_None)7298        EndLoc = ESpecRange.getEnd();7299 7300      // Parse attribute-specifier-seq[opt]. Per DR 979 and DR 1297, this goes7301      // after the exception-specification.7302      MaybeParseCXX11Attributes(FnAttrs);7303 7304      // Parse trailing-return-type[opt].7305      LocalEndLoc = EndLoc;7306      if (getLangOpts().CPlusPlus11 && Tok.is(tok::arrow)) {7307        Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);7308        if (D.getDeclSpec().getTypeSpecType() == TST_auto)7309          StartLoc = D.getDeclSpec().getTypeSpecTypeLoc();7310        LocalEndLoc = Tok.getLocation();7311        SourceRange Range;7312        TrailingReturnType =7313            ParseTrailingReturnType(Range, D.mayBeFollowedByCXXDirectInit());7314        TrailingReturnTypeLoc = Range.getBegin();7315        EndLoc = Range.getEnd();7316      }7317    } else {7318      MaybeParseCXX11Attributes(FnAttrs);7319    }7320  }7321 7322  // Collect non-parameter declarations from the prototype if this is a function7323  // declaration. They will be moved into the scope of the function. Only do7324  // this in C and not C++, where the decls will continue to live in the7325  // surrounding context.7326  SmallVector<NamedDecl *, 0> DeclsInPrototype;7327  if (getCurScope()->isFunctionDeclarationScope() && !getLangOpts().CPlusPlus) {7328    for (Decl *D : getCurScope()->decls()) {7329      NamedDecl *ND = dyn_cast<NamedDecl>(D);7330      if (!ND || isa<ParmVarDecl>(ND))7331        continue;7332      DeclsInPrototype.push_back(ND);7333    }7334    // Sort DeclsInPrototype based on raw encoding of the source location.7335    // Scope::decls() is iterating over a SmallPtrSet so sort the Decls before7336    // moving to DeclContext. This provides a stable ordering for traversing7337    // Decls in DeclContext, which is important for tasks like ASTWriter for7338    // deterministic output.7339    llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) {7340      return D1->getLocation().getRawEncoding() <7341             D2->getLocation().getRawEncoding();7342    });7343  }7344 7345  // Remember that we parsed a function type, and remember the attributes.7346  D.AddTypeInfo(DeclaratorChunk::getFunction(7347                    HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),7348                    ParamInfo.size(), EllipsisLoc, RParenLoc,7349                    RefQualifierIsLValueRef, RefQualifierLoc,7350                    /*MutableLoc=*/SourceLocation(),7351                    ESpecType, ESpecRange, DynamicExceptions.data(),7352                    DynamicExceptionRanges.data(), DynamicExceptions.size(),7353                    NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr,7354                    ExceptionSpecTokens, DeclsInPrototype, StartLoc,7355                    LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,7356                    &DS),7357                std::move(FnAttrs), EndLoc);7358}7359 7360bool Parser::ParseRefQualifier(bool &RefQualifierIsLValueRef,7361                               SourceLocation &RefQualifierLoc) {7362  if (Tok.isOneOf(tok::amp, tok::ampamp)) {7363    Diag(Tok, getLangOpts().CPlusPlus11 ?7364         diag::warn_cxx98_compat_ref_qualifier :7365         diag::ext_ref_qualifier);7366 7367    RefQualifierIsLValueRef = Tok.is(tok::amp);7368    RefQualifierLoc = ConsumeToken();7369    return true;7370  }7371  return false;7372}7373 7374bool Parser::isFunctionDeclaratorIdentifierList() {7375  return !getLangOpts().requiresStrictPrototypes()7376         && Tok.is(tok::identifier)7377         && !TryAltiVecVectorToken()7378         // K&R identifier lists can't have typedefs as identifiers, per C997379         // 6.7.5.3p11.7380         && (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename))7381         // Identifier lists follow a really simple grammar: the identifiers can7382         // be followed *only* by a ", identifier" or ")".  However, K&R7383         // identifier lists are really rare in the brave new modern world, and7384         // it is very common for someone to typo a type in a non-K&R style7385         // list.  If we are presented with something like: "void foo(intptr x,7386         // float y)", we don't want to start parsing the function declarator as7387         // though it is a K&R style declarator just because intptr is an7388         // invalid type.7389         //7390         // To handle this, we check to see if the token after the first7391         // identifier is a "," or ")".  Only then do we parse it as an7392         // identifier list.7393         && (!Tok.is(tok::eof) &&7394             (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)));7395}7396 7397void Parser::ParseFunctionDeclaratorIdentifierList(7398       Declarator &D,7399       SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo) {7400  // We should never reach this point in C23 or C++.7401  assert(!getLangOpts().requiresStrictPrototypes() &&7402         "Cannot parse an identifier list in C23 or C++");7403 7404  // If there was no identifier specified for the declarator, either we are in7405  // an abstract-declarator, or we are in a parameter declarator which was found7406  // to be abstract.  In abstract-declarators, identifier lists are not valid:7407  // diagnose this.7408  if (!D.getIdentifier())7409    Diag(Tok, diag::ext_ident_list_in_param);7410 7411  // Maintain an efficient lookup of params we have seen so far.7412  llvm::SmallPtrSet<const IdentifierInfo *, 16> ParamsSoFar;7413 7414  do {7415    // If this isn't an identifier, report the error and skip until ')'.7416    if (Tok.isNot(tok::identifier)) {7417      Diag(Tok, diag::err_expected) << tok::identifier;7418      SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);7419      // Forget we parsed anything.7420      ParamInfo.clear();7421      return;7422    }7423 7424    IdentifierInfo *ParmII = Tok.getIdentifierInfo();7425 7426    // Reject 'typedef int y; int test(x, y)', but continue parsing.7427    if (Actions.getTypeName(*ParmII, Tok.getLocation(), getCurScope()))7428      Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;7429 7430    // Verify that the argument identifier has not already been mentioned.7431    if (!ParamsSoFar.insert(ParmII).second) {7432      Diag(Tok, diag::err_param_redefinition) << ParmII;7433    } else {7434      // Remember this identifier in ParamInfo.7435      ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,7436                                                     Tok.getLocation(),7437                                                     nullptr));7438    }7439 7440    // Eat the identifier.7441    ConsumeToken();7442    // The list continues if we see a comma.7443  } while (TryConsumeToken(tok::comma));7444}7445 7446void Parser::ParseParameterDeclarationClause(7447    DeclaratorContext DeclaratorCtx, ParsedAttributes &FirstArgAttrs,7448    SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,7449    SourceLocation &EllipsisLoc, bool IsACXXFunctionDeclaration) {7450 7451  // Avoid exceeding the maximum function scope depth.7452  // See https://bugs.llvm.org/show_bug.cgi?id=196077453  // Note Sema::ActOnParamDeclarator calls ParmVarDecl::setScopeInfo with7454  // getFunctionPrototypeDepth() - 1.7455  if (getCurScope()->getFunctionPrototypeDepth() - 1 >7456      ParmVarDecl::getMaxFunctionScopeDepth()) {7457    Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)7458        << ParmVarDecl::getMaxFunctionScopeDepth();7459    cutOffParsing();7460    return;7461  }7462 7463  // C++2a [temp.res]p57464  // A qualified-id is assumed to name a type if7465  //   - [...]7466  //   - it is a decl-specifier of the decl-specifier-seq of a7467  //     - [...]7468  //     - parameter-declaration in a member-declaration [...]7469  //     - parameter-declaration in a declarator of a function or function7470  //       template declaration whose declarator-id is qualified [...]7471  //     - parameter-declaration in a lambda-declarator [...]7472  auto AllowImplicitTypename = ImplicitTypenameContext::No;7473  if (DeclaratorCtx == DeclaratorContext::Member ||7474      DeclaratorCtx == DeclaratorContext::LambdaExpr ||7475      DeclaratorCtx == DeclaratorContext::RequiresExpr ||7476      IsACXXFunctionDeclaration) {7477    AllowImplicitTypename = ImplicitTypenameContext::Yes;7478  }7479 7480  do {7481    // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq7482    // before deciding this was a parameter-declaration-clause.7483    if (TryConsumeToken(tok::ellipsis, EllipsisLoc))7484      break;7485 7486    // Parse the declaration-specifiers.7487    // Just use the ParsingDeclaration "scope" of the declarator.7488    DeclSpec DS(AttrFactory);7489 7490    ParsedAttributes ArgDeclAttrs(AttrFactory);7491    ParsedAttributes ArgDeclSpecAttrs(AttrFactory);7492 7493    if (FirstArgAttrs.Range.isValid()) {7494      // If the caller parsed attributes for the first argument, add them now.7495      // Take them so that we only apply the attributes to the first parameter.7496      // We have already started parsing the decl-specifier sequence, so don't7497      // parse any parameter-declaration pieces that precede it.7498      ArgDeclSpecAttrs.takeAllPrependingFrom(FirstArgAttrs);7499    } else {7500      // Parse any C++11 attributes.7501      MaybeParseCXX11Attributes(ArgDeclAttrs);7502 7503      // Skip any Microsoft attributes before a param.7504      MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);7505    }7506 7507    SourceLocation DSStart = Tok.getLocation();7508 7509    // Parse a C++23 Explicit Object Parameter7510    // We do that in all language modes to produce a better diagnostic.7511    SourceLocation ThisLoc;7512    if (getLangOpts().CPlusPlus && Tok.is(tok::kw_this))7513      ThisLoc = ConsumeToken();7514 7515    ParsedTemplateInfo TemplateInfo;7516    ParseDeclarationSpecifiers(DS, TemplateInfo, AS_none,7517                               DeclSpecContext::DSC_normal,7518                               /*LateAttrs=*/nullptr, AllowImplicitTypename);7519 7520    DS.takeAttributesAppendingingFrom(ArgDeclSpecAttrs);7521 7522    // Parse the declarator.  This is "PrototypeContext" or7523    // "LambdaExprParameterContext", because we must accept either7524    // 'declarator' or 'abstract-declarator' here.7525    Declarator ParmDeclarator(DS, ArgDeclAttrs,7526                              DeclaratorCtx == DeclaratorContext::RequiresExpr7527                                  ? DeclaratorContext::RequiresExpr7528                              : DeclaratorCtx == DeclaratorContext::LambdaExpr7529                                  ? DeclaratorContext::LambdaExprParameter7530                                  : DeclaratorContext::Prototype);7531    ParseDeclarator(ParmDeclarator);7532 7533    if (ThisLoc.isValid())7534      ParmDeclarator.SetRangeBegin(ThisLoc);7535 7536    // Parse GNU attributes, if present.7537    MaybeParseGNUAttributes(ParmDeclarator);7538    if (getLangOpts().HLSL)7539      MaybeParseHLSLAnnotations(DS.getAttributes());7540 7541    if (Tok.is(tok::kw_requires)) {7542      // User tried to define a requires clause in a parameter declaration,7543      // which is surely not a function declaration.7544      // void f(int (*g)(int, int) requires true);7545      Diag(Tok,7546           diag::err_requires_clause_on_declarator_not_declaring_a_function);7547      ConsumeToken();7548      ParseConstraintLogicalOrExpression(/*IsTrailingRequiresClause=*/true);7549    }7550 7551    // Remember this parsed parameter in ParamInfo.7552    const IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();7553 7554    // DefArgToks is used when the parsing of default arguments needs7555    // to be delayed.7556    std::unique_ptr<CachedTokens> DefArgToks;7557 7558    // If no parameter was specified, verify that *something* was specified,7559    // otherwise we have a missing type and identifier.7560    if (DS.isEmpty() && ParmDeclarator.getIdentifier() == nullptr &&7561        ParmDeclarator.getNumTypeObjects() == 0) {7562      // Completely missing, emit error.7563      Diag(DSStart, diag::err_missing_param);7564    } else {7565      // Otherwise, we have something.  Add it and let semantic analysis try7566      // to grok it and add the result to the ParamInfo we are building.7567 7568      // Last chance to recover from a misplaced ellipsis in an attempted7569      // parameter pack declaration.7570      if (Tok.is(tok::ellipsis) &&7571          (NextToken().isNot(tok::r_paren) ||7572           (!ParmDeclarator.getEllipsisLoc().isValid() &&7573            !Actions.isUnexpandedParameterPackPermitted())) &&7574          Actions.containsUnexpandedParameterPacks(ParmDeclarator))7575        DiagnoseMisplacedEllipsisInDeclarator(ConsumeToken(), ParmDeclarator);7576 7577      // Now we are at the point where declarator parsing is finished.7578      //7579      // Try to catch keywords in place of the identifier in a declarator, and7580      // in particular the common case where:7581      //   1 identifier comes at the end of the declarator7582      //   2 if the identifier is dropped, the declarator is valid but anonymous7583      //     (no identifier)7584      //   3 declarator parsing succeeds, and then we have a trailing keyword,7585      //     which is never valid in a param list (e.g. missing a ',')7586      // And we can't handle this in ParseDeclarator because in general keywords7587      // may be allowed to follow the declarator. (And in some cases there'd be7588      // better recovery like inserting punctuation). ParseDeclarator is just7589      // treating this as an anonymous parameter, and fortunately at this point7590      // we've already almost done that.7591      //7592      // We care about case 1) where the declarator type should be known, and7593      // the identifier should be null.7594      if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&7595          Tok.isNot(tok::raw_identifier) && !Tok.isAnnotation() &&7596          Tok.getIdentifierInfo() &&7597          Tok.getIdentifierInfo()->isKeyword(getLangOpts())) {7598        Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok);7599        // Consume the keyword.7600        ConsumeToken();7601      }7602 7603      // We can only store so many parameters7604      // Skip until the the end of the parameter list, ignoring7605      // parameters that would overflow.7606      if (ParamInfo.size() == Type::FunctionTypeNumParamsLimit) {7607        Diag(ParmDeclarator.getBeginLoc(),7608             diag::err_function_parameter_limit_exceeded);7609        SkipUntil(tok::r_paren, SkipUntilFlags::StopBeforeMatch);7610        break;7611      }7612 7613      // Inform the actions module about the parameter declarator, so it gets7614      // added to the current scope.7615      Decl *Param =7616          Actions.ActOnParamDeclarator(getCurScope(), ParmDeclarator, ThisLoc);7617      // Parse the default argument, if any. We parse the default7618      // arguments in all dialects; the semantic analysis in7619      // ActOnParamDefaultArgument will reject the default argument in7620      // C.7621      if (Tok.is(tok::equal)) {7622        SourceLocation EqualLoc = Tok.getLocation();7623 7624        // Parse the default argument7625        if (DeclaratorCtx == DeclaratorContext::Member) {7626          // If we're inside a class definition, cache the tokens7627          // corresponding to the default argument. We'll actually parse7628          // them when we see the end of the class definition.7629          DefArgToks.reset(new CachedTokens);7630 7631          SourceLocation ArgStartLoc = NextToken().getLocation();7632          ConsumeAndStoreInitializer(*DefArgToks,7633                                     CachedInitKind::DefaultArgument);7634          Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,7635                                                    ArgStartLoc);7636        } else {7637          // Consume the '='.7638          ConsumeToken();7639 7640          // The argument isn't actually potentially evaluated unless it is7641          // used.7642          EnterExpressionEvaluationContext Eval(7643              Actions,7644              Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed,7645              Param);7646 7647          ExprResult DefArgResult;7648          if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {7649            Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);7650            DefArgResult = ParseBraceInitializer();7651          } else {7652            if (Tok.is(tok::l_paren) && NextToken().is(tok::l_brace)) {7653              Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;7654              Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,7655                                                     /*DefaultArg=*/nullptr);7656              // Skip the statement expression and continue parsing7657              SkipUntil(tok::comma, StopBeforeMatch);7658              continue;7659            }7660            DefArgResult = ParseAssignmentExpression();7661          }7662          if (DefArgResult.isInvalid()) {7663            Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,7664                                                   /*DefaultArg=*/nullptr);7665            SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch);7666          } else {7667            // Inform the actions module about the default argument7668            Actions.ActOnParamDefaultArgument(Param, EqualLoc,7669                                              DefArgResult.get());7670          }7671        }7672      }7673 7674      ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,7675                                          ParmDeclarator.getIdentifierLoc(),7676                                          Param, std::move(DefArgToks)));7677    }7678 7679    if (TryConsumeToken(tok::ellipsis, EllipsisLoc)) {7680      if (getLangOpts().CPlusPlus26) {7681        // C++26 [dcl.dcl.fct]p3:7682        //   A parameter-declaration-clause of the form7683        //   parameter-list '...' is deprecated.7684        Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)7685            << FixItHint::CreateInsertion(EllipsisLoc, ", ");7686      }7687 7688      if (!getLangOpts().CPlusPlus) {7689        // We have ellipsis without a preceding ',', which is ill-formed7690        // in C. Complain and provide the fix.7691        Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)7692            << FixItHint::CreateInsertion(EllipsisLoc, ", ");7693      } else if (ParmDeclarator.getEllipsisLoc().isValid() ||7694                 Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {7695        // It looks like this was supposed to be a parameter pack. Warn and7696        // point out where the ellipsis should have gone.7697        SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();7698        Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)7699          << ParmEllipsis.isValid() << ParmEllipsis;7700        if (ParmEllipsis.isValid()) {7701          Diag(ParmEllipsis,7702               diag::note_misplaced_ellipsis_vararg_existing_ellipsis);7703        } else {7704          Diag(ParmDeclarator.getIdentifierLoc(),7705               diag::note_misplaced_ellipsis_vararg_add_ellipsis)7706            << FixItHint::CreateInsertion(ParmDeclarator.getIdentifierLoc(),7707                                          "...")7708            << !ParmDeclarator.hasName();7709        }7710        Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)7711          << FixItHint::CreateInsertion(EllipsisLoc, ", ");7712      }7713 7714      // We can't have any more parameters after an ellipsis.7715      break;7716    }7717 7718    // If the next token is a comma, consume it and keep reading arguments.7719  } while (TryConsumeToken(tok::comma));7720}7721 7722void Parser::ParseBracketDeclarator(Declarator &D) {7723  if (CheckProhibitedCXX11Attribute())7724    return;7725 7726  BalancedDelimiterTracker T(*this, tok::l_square);7727  T.consumeOpen();7728 7729  // C array syntax has many features, but by-far the most common is [] and [4].7730  // This code does a fast path to handle some of the most obvious cases.7731  if (Tok.getKind() == tok::r_square) {7732    T.consumeClose();7733    ParsedAttributes attrs(AttrFactory);7734    MaybeParseCXX11Attributes(attrs);7735 7736    // Remember that we parsed the empty array type.7737    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, nullptr,7738                                            T.getOpenLocation(),7739                                            T.getCloseLocation()),7740                  std::move(attrs), T.getCloseLocation());7741    return;7742  } else if (Tok.getKind() == tok::numeric_constant &&7743             GetLookAheadToken(1).is(tok::r_square)) {7744    // [4] is very common.  Parse the numeric constant expression.7745    ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope()));7746    ConsumeToken();7747 7748    T.consumeClose();7749    ParsedAttributes attrs(AttrFactory);7750    MaybeParseCXX11Attributes(attrs);7751 7752    // Remember that we parsed a array type, and remember its features.7753    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, ExprRes.get(),7754                                            T.getOpenLocation(),7755                                            T.getCloseLocation()),7756                  std::move(attrs), T.getCloseLocation());7757    return;7758  } else if (Tok.getKind() == tok::code_completion) {7759    cutOffParsing();7760    Actions.CodeCompletion().CodeCompleteBracketDeclarator(getCurScope());7761    return;7762  }7763 7764  // If valid, this location is the position where we read the 'static' keyword.7765  SourceLocation StaticLoc;7766  TryConsumeToken(tok::kw_static, StaticLoc);7767 7768  // If there is a type-qualifier-list, read it now.7769  // Type qualifiers in an array subscript are a C99 feature.7770  DeclSpec DS(AttrFactory);7771  ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);7772 7773  // If we haven't already read 'static', check to see if there is one after the7774  // type-qualifier-list.7775  if (!StaticLoc.isValid())7776    TryConsumeToken(tok::kw_static, StaticLoc);7777 7778  // Handle "direct-declarator [ type-qual-list[opt] * ]".7779  bool isStar = false;7780  ExprResult NumElements;7781 7782  // Handle the case where we have '[*]' as the array size.  However, a leading7783  // star could be the start of an expression, for example 'X[*p + 4]'.  Verify7784  // the token after the star is a ']'.  Since stars in arrays are7785  // infrequent, use of lookahead is not costly here.7786  if (Tok.is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {7787    ConsumeToken();  // Eat the '*'.7788 7789    if (StaticLoc.isValid()) {7790      Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);7791      StaticLoc = SourceLocation();  // Drop the static.7792    }7793    isStar = true;7794  } else if (Tok.isNot(tok::r_square)) {7795    // Note, in C89, this production uses the constant-expr production instead7796    // of assignment-expr.  The only difference is that assignment-expr allows7797    // things like '=' and '*='.  Sema rejects these in C89 mode because they7798    // are not i-c-e's, so we don't need to distinguish between the two here.7799 7800    // Parse the constant-expression or assignment-expression now (depending7801    // on dialect).7802    if (getLangOpts().CPlusPlus) {7803      NumElements = ParseArrayBoundExpression();7804    } else {7805      EnterExpressionEvaluationContext Unevaluated(7806          Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);7807      NumElements = ParseAssignmentExpression();7808    }7809  } else {7810    if (StaticLoc.isValid()) {7811      Diag(StaticLoc, diag::err_unspecified_size_with_static);7812      StaticLoc = SourceLocation();  // Drop the static.7813    }7814  }7815 7816  // If there was an error parsing the assignment-expression, recover.7817  if (NumElements.isInvalid()) {7818    D.setInvalidType(true);7819    // If the expression was invalid, skip it.7820    SkipUntil(tok::r_square, StopAtSemi);7821    return;7822  }7823 7824  T.consumeClose();7825 7826  MaybeParseCXX11Attributes(DS.getAttributes());7827 7828  // Remember that we parsed a array type, and remember its features.7829  D.AddTypeInfo(7830      DeclaratorChunk::getArray(DS.getTypeQualifiers(), StaticLoc.isValid(),7831                                isStar, NumElements.get(), T.getOpenLocation(),7832                                T.getCloseLocation()),7833      std::move(DS.getAttributes()), T.getCloseLocation());7834}7835 7836void Parser::ParseMisplacedBracketDeclarator(Declarator &D) {7837  assert(Tok.is(tok::l_square) && "Missing opening bracket");7838  assert(!D.mayOmitIdentifier() && "Declarator cannot omit identifier");7839 7840  SourceLocation StartBracketLoc = Tok.getLocation();7841  Declarator TempDeclarator(D.getDeclSpec(), ParsedAttributesView::none(),7842                            D.getContext());7843 7844  while (Tok.is(tok::l_square)) {7845    ParseBracketDeclarator(TempDeclarator);7846  }7847 7848  // Stuff the location of the start of the brackets into the Declarator.7849  // The diagnostics from ParseDirectDeclarator will make more sense if7850  // they use this location instead.7851  if (Tok.is(tok::semi))7852    D.getName().EndLocation = StartBracketLoc;7853 7854  SourceLocation SuggestParenLoc = Tok.getLocation();7855 7856  // Now that the brackets are removed, try parsing the declarator again.7857  ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);7858 7859  // Something went wrong parsing the brackets, in which case,7860  // ParseBracketDeclarator has emitted an error, and we don't need to emit7861  // one here.7862  if (TempDeclarator.getNumTypeObjects() == 0)7863    return;7864 7865  // Determine if parens will need to be suggested in the diagnostic.7866  bool NeedParens = false;7867  if (D.getNumTypeObjects() != 0) {7868    switch (D.getTypeObject(D.getNumTypeObjects() - 1).Kind) {7869    case DeclaratorChunk::Pointer:7870    case DeclaratorChunk::Reference:7871    case DeclaratorChunk::BlockPointer:7872    case DeclaratorChunk::MemberPointer:7873    case DeclaratorChunk::Pipe:7874      NeedParens = true;7875      break;7876    case DeclaratorChunk::Array:7877    case DeclaratorChunk::Function:7878    case DeclaratorChunk::Paren:7879      break;7880    }7881  }7882 7883  if (NeedParens) {7884    // Create a DeclaratorChunk for the inserted parens.7885    SourceLocation EndLoc = PP.getLocForEndOfToken(D.getEndLoc());7886    D.AddTypeInfo(DeclaratorChunk::getParen(SuggestParenLoc, EndLoc),7887                  SourceLocation());7888  }7889 7890  // Adding back the bracket info to the end of the Declarator.7891  for (unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {7892    const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);7893    D.AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());7894  }7895 7896  // The missing name would have been diagnosed in ParseDirectDeclarator.7897  // If parentheses are required, always suggest them.7898  if (!D.hasName() && !NeedParens)7899    return;7900 7901  SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();7902 7903  // Generate the move bracket error message.7904  SourceRange BracketRange(StartBracketLoc, EndBracketLoc);7905  SourceLocation EndLoc = PP.getLocForEndOfToken(D.getEndLoc());7906 7907  if (NeedParens) {7908    Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)7909        << getLangOpts().CPlusPlus7910        << FixItHint::CreateInsertion(SuggestParenLoc, "(")7911        << FixItHint::CreateInsertion(EndLoc, ")")7912        << FixItHint::CreateInsertionFromRange(7913               EndLoc, CharSourceRange(BracketRange, true))7914        << FixItHint::CreateRemoval(BracketRange);7915  } else {7916    Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)7917        << getLangOpts().CPlusPlus7918        << FixItHint::CreateInsertionFromRange(7919               EndLoc, CharSourceRange(BracketRange, true))7920        << FixItHint::CreateRemoval(BracketRange);7921  }7922}7923 7924void Parser::ParseTypeofSpecifier(DeclSpec &DS) {7925  assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&7926         "Not a typeof specifier");7927 7928  bool IsUnqual = Tok.is(tok::kw_typeof_unqual);7929  const IdentifierInfo *II = Tok.getIdentifierInfo();7930  if (getLangOpts().C23 && !II->getName().starts_with("__"))7931    Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName();7932 7933  Token OpTok = Tok;7934  SourceLocation StartLoc = ConsumeToken();7935  bool HasParens = Tok.is(tok::l_paren);7936 7937  EnterExpressionEvaluationContext Unevaluated(7938      Actions, Sema::ExpressionEvaluationContext::Unevaluated,7939      Sema::ReuseLambdaContextDecl);7940 7941  bool isCastExpr;7942  ParsedType CastTy;7943  SourceRange CastRange;7944  ExprResult Operand =7945      ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);7946  if (HasParens)7947    DS.setTypeArgumentRange(CastRange);7948 7949  if (CastRange.getEnd().isInvalid())7950    // FIXME: Not accurate, the range gets one token more than it should.7951    DS.SetRangeEnd(Tok.getLocation());7952  else7953    DS.SetRangeEnd(CastRange.getEnd());7954 7955  if (isCastExpr) {7956    if (!CastTy) {7957      DS.SetTypeSpecError();7958      return;7959    }7960 7961    const char *PrevSpec = nullptr;7962    unsigned DiagID;7963    // Check for duplicate type specifiers (e.g. "int typeof(int)").7964    if (DS.SetTypeSpecType(IsUnqual ? DeclSpec::TST_typeof_unqualType7965                                    : DeclSpec::TST_typeofType,7966                           StartLoc, PrevSpec,7967                           DiagID, CastTy,7968                           Actions.getASTContext().getPrintingPolicy()))7969      Diag(StartLoc, DiagID) << PrevSpec;7970    return;7971  }7972 7973  // If we get here, the operand to the typeof was an expression.7974  if (Operand.isInvalid()) {7975    DS.SetTypeSpecError();7976    return;7977  }7978 7979  // We might need to transform the operand if it is potentially evaluated.7980  Operand = Actions.HandleExprEvaluationContextForTypeof(Operand.get());7981  if (Operand.isInvalid()) {7982    DS.SetTypeSpecError();7983    return;7984  }7985 7986  const char *PrevSpec = nullptr;7987  unsigned DiagID;7988  // Check for duplicate type specifiers (e.g. "int typeof(int)").7989  if (DS.SetTypeSpecType(IsUnqual ? DeclSpec::TST_typeof_unqualExpr7990                                  : DeclSpec::TST_typeofExpr,7991                         StartLoc, PrevSpec,7992                         DiagID, Operand.get(),7993                         Actions.getASTContext().getPrintingPolicy()))7994    Diag(StartLoc, DiagID) << PrevSpec;7995}7996 7997void Parser::ParseAtomicSpecifier(DeclSpec &DS) {7998  assert(Tok.is(tok::kw__Atomic) && NextToken().is(tok::l_paren) &&7999         "Not an atomic specifier");8000 8001  SourceLocation StartLoc = ConsumeToken();8002  BalancedDelimiterTracker T(*this, tok::l_paren);8003  if (T.consumeOpen())8004    return;8005 8006  TypeResult Result = ParseTypeName();8007  if (Result.isInvalid()) {8008    SkipUntil(tok::r_paren, StopAtSemi);8009    return;8010  }8011 8012  // Match the ')'8013  T.consumeClose();8014 8015  if (T.getCloseLocation().isInvalid())8016    return;8017 8018  DS.setTypeArgumentRange(T.getRange());8019  DS.SetRangeEnd(T.getCloseLocation());8020 8021  const char *PrevSpec = nullptr;8022  unsigned DiagID;8023  if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec,8024                         DiagID, Result.get(),8025                         Actions.getASTContext().getPrintingPolicy()))8026    Diag(StartLoc, DiagID) << PrevSpec;8027}8028 8029bool Parser::TryAltiVecVectorTokenOutOfLine() {8030  Token Next = NextToken();8031  switch (Next.getKind()) {8032  default: return false;8033  case tok::kw_short:8034  case tok::kw_long:8035  case tok::kw_signed:8036  case tok::kw_unsigned:8037  case tok::kw_void:8038  case tok::kw_char:8039  case tok::kw_int:8040  case tok::kw_float:8041  case tok::kw_double:8042  case tok::kw_bool:8043  case tok::kw__Bool:8044  case tok::kw___bool:8045  case tok::kw___pixel:8046    Tok.setKind(tok::kw___vector);8047    return true;8048  case tok::identifier:8049    if (Next.getIdentifierInfo() == Ident_pixel) {8050      Tok.setKind(tok::kw___vector);8051      return true;8052    }8053    if (Next.getIdentifierInfo() == Ident_bool ||8054        Next.getIdentifierInfo() == Ident_Bool) {8055      Tok.setKind(tok::kw___vector);8056      return true;8057    }8058    return false;8059  }8060}8061 8062bool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,8063                                      const char *&PrevSpec, unsigned &DiagID,8064                                      bool &isInvalid) {8065  const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();8066  if (Tok.getIdentifierInfo() == Ident_vector) {8067    Token Next = NextToken();8068    switch (Next.getKind()) {8069    case tok::kw_short:8070    case tok::kw_long:8071    case tok::kw_signed:8072    case tok::kw_unsigned:8073    case tok::kw_void:8074    case tok::kw_char:8075    case tok::kw_int:8076    case tok::kw_float:8077    case tok::kw_double:8078    case tok::kw_bool:8079    case tok::kw__Bool:8080    case tok::kw___bool:8081    case tok::kw___pixel:8082      isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID, Policy);8083      return true;8084    case tok::identifier:8085      if (Next.getIdentifierInfo() == Ident_pixel) {8086        isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID,Policy);8087        return true;8088      }8089      if (Next.getIdentifierInfo() == Ident_bool ||8090          Next.getIdentifierInfo() == Ident_Bool) {8091        isInvalid =8092            DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID, Policy);8093        return true;8094      }8095      break;8096    default:8097      break;8098    }8099  } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&8100             DS.isTypeAltiVecVector()) {8101    isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID, Policy);8102    return true;8103  } else if ((Tok.getIdentifierInfo() == Ident_bool) &&8104             DS.isTypeAltiVecVector()) {8105    isInvalid = DS.SetTypeAltiVecBool(true, Loc, PrevSpec, DiagID, Policy);8106    return true;8107  }8108  return false;8109}8110 8111TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,8112                                       SourceLocation IncludeLoc) {8113  // Consume (unexpanded) tokens up to the end-of-directive.8114  SmallVector<Token, 4> Tokens;8115  {8116    // Create a new buffer from which we will parse the type.8117    auto &SourceMgr = PP.getSourceManager();8118    FileID FID = SourceMgr.createFileID(8119        llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context), SrcMgr::C_User,8120        0, 0, IncludeLoc);8121 8122    // Form a new lexer that references the buffer.8123    Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);8124    L.setParsingPreprocessorDirective(true);8125 8126    // Lex the tokens from that buffer.8127    Token Tok;8128    do {8129      L.Lex(Tok);8130      Tokens.push_back(Tok);8131    } while (Tok.isNot(tok::eod));8132  }8133 8134  // Replace the "eod" token with an "eof" token identifying the end of8135  // the provided string.8136  Token &EndToken = Tokens.back();8137  EndToken.startToken();8138  EndToken.setKind(tok::eof);8139  EndToken.setLocation(Tok.getLocation());8140  EndToken.setEofData(TypeStr.data());8141 8142  // Add the current token back.8143  Tokens.push_back(Tok);8144 8145  // Enter the tokens into the token stream.8146  PP.EnterTokenStream(Tokens, /*DisableMacroExpansion=*/false,8147                      /*IsReinject=*/false);8148 8149  // Consume the current token so that we'll start parsing the tokens we8150  // added to the stream.8151  ConsumeAnyToken();8152 8153  // Enter a new scope.8154  ParseScope LocalScope(this, 0);8155 8156  // Parse the type.8157  TypeResult Result = ParseTypeName(nullptr);8158 8159  // Check if we parsed the whole thing.8160  if (Result.isUsable() &&8161      (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {8162    Diag(Tok.getLocation(), diag::err_type_unparsed);8163  }8164 8165  // There could be leftover tokens (e.g. because of an error).8166  // Skip through until we reach the 'end of directive' token.8167  while (Tok.isNot(tok::eof))8168    ConsumeAnyToken();8169 8170  // Consume the end token.8171  if (Tok.is(tok::eof) && Tok.getEofData() == TypeStr.data())8172    ConsumeAnyToken();8173  return Result;8174}8175 8176void Parser::DiagnoseBitIntUse(const Token &Tok) {8177  // If the token is for _ExtInt, diagnose it as being deprecated. Otherwise,8178  // the token is about _BitInt and gets (potentially) diagnosed as use of an8179  // extension.8180  assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&8181         "expected either an _ExtInt or _BitInt token!");8182 8183  SourceLocation Loc = Tok.getLocation();8184  if (Tok.is(tok::kw__ExtInt)) {8185    Diag(Loc, diag::warn_ext_int_deprecated)8186        << FixItHint::CreateReplacement(Loc, "_BitInt");8187  } else {8188    // In C23 mode, diagnose that the use is not compatible with pre-C23 modes.8189    // Otherwise, diagnose that the use is a Clang extension.8190    if (getLangOpts().C23)8191      Diag(Loc, diag::warn_c23_compat_keyword) << Tok.getName();8192    else8193      Diag(Loc, diag::ext_bit_int) << getLangOpts().CPlusPlus;8194  }8195}8196