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