34#include "llvm/ADT/SmallSet.h"
35#include "llvm/ADT/StringSwitch.h"
47 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
48 if (DSC == DeclSpecContext::DSC_normal)
49 DSC = DeclSpecContext::DSC_type_specifier;
55 ParseSpecifierQualifierList(DS, AS, DSC);
63 if (AL.isDeclspecAttribute())
64 ToBeMoved.push_back(&AL);
73 ParseDeclarator(DeclaratorInfo);
85 if (Name.size() >= 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
86 return Name.drop_front(2).drop_back(2);
93#define CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
95#include "clang/Parse/AttrParserStringSwitches.inc"
97#undef CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
103#define CLANG_ATTR_LATE_PARSED_LIST
105#include "clang/Parse/AttrParserStringSwitches.inc"
107#undef CLANG_ATTR_LATE_PARSED_LIST
117 if (
SM.getFileID(StartLoc) !=
SM.getFileID(EndLoc))
120 bool AttrStartIsInMacro =
122 bool AttrEndIsInMacro =
124 return AttrStartIsInMacro && AttrEndIsInMacro;
127void Parser::ParseAttributes(
unsigned WhichAttrKinds,
ParsedAttributes &Attrs,
128 LateParsedAttrList *LateAttrs) {
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);
145 LateParsedAttrList *LateAttrs,
153 if (Tok.
isNot(tok::l_paren)) {
155 ParsedAttr::Form::GNU());
159 bool LateParse =
false;
162 else if (LateAttrs->lateAttrParseExperimentalExtOnly()) {
166 LateParse =
getLangOpts().ExperimentalLateParseAttributes &&
179 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc,
nullptr,
185 LateParsedAttribute *LA =
186 new LateParsedAttribute(
this, *AttrName, AttrNameLoc);
187 LateAttrs->push_back(LA);
191 if (!ClassStack.empty() && !LateAttrs->parseSoon())
192 getCurrentClass().LateParsedDeclarations.push_back(LA);
196 LA->Toks.push_back(Tok);
199 ConsumeAndStoreUntil(tok::r_paren, LA->Toks,
true);
204 LA->Toks.push_back(Eof);
211 assert(Tok.
is(tok::kw___attribute) &&
"Not a GNU attribute list!");
216 while (Tok.
is(tok::kw___attribute)) {
218 unsigned OldNumAttrs = Attrs.
size();
219 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
221 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
226 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"(")) {
239 if (Tok.
is(tok::code_completion)) {
246 if (ParseSingleGNUAttribute(Attrs, EndLoc, LateAttrs,
D))
248 }
while (Tok.
is(tok::comma));
250 if (ExpectAndConsume(tok::r_paren))
253 if (ExpectAndConsume(tok::r_paren))
260 if (!
SM.isWrittenInBuiltinFile(
SM.getSpellingLoc(AttrTokLoc)) &&
263 StringRef FoundName =
267 for (
unsigned i = OldNumAttrs; i < Attrs.
size(); ++i)
268 Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.
getBegin());
271 for (
unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
272 (*LateAttrs)[i]->MacroII = MacroII;
285#define CLANG_ATTR_IDENTIFIER_ARG_LIST
287#include "clang/Parse/AttrParserStringSwitches.inc"
289#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
297#define CLANG_ATTR_STRING_LITERAL_ARG_LIST
299#include "clang/Parse/AttrParserStringSwitches.inc"
301#undef CLANG_ATTR_STRING_LITERAL_ARG_LIST
308#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
310#include "clang/Parse/AttrParserStringSwitches.inc"
312#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
319#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
321#include "clang/Parse/AttrParserStringSwitches.inc"
323#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
330#define CLANG_ATTR_ACCEPTS_EXPR_PACK
332#include "clang/Parse/AttrParserStringSwitches.inc"
334#undef CLANG_ATTR_ACCEPTS_EXPR_PACK
341#define CLANG_ATTR_TYPE_ARG_LIST
343#include "clang/Parse/AttrParserStringSwitches.inc"
345#undef CLANG_ATTR_TYPE_ARG_LIST
352#define CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
354#include "clang/Parse/AttrParserStringSwitches.inc"
356#undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
364#define CLANG_ATTR_ARG_CONTEXT_LIST
366#include "clang/Parse/AttrParserStringSwitches.inc"
368#undef CLANG_ATTR_ARG_CONTEXT_LIST
372 assert(Tok.
is(tok::identifier) &&
"expected an identifier");
389 if (Tok.
isNot(tok::r_paren))
392 if (
Parens.consumeClose())
408Parser::ParseUnevaluatedStringInAttribute(
const IdentifierInfo &AttrName) {
409 if (Tok.
is(tok::l_paren)) {
412 ExprResult Res = ParseUnevaluatedStringInAttribute(AttrName);
413 Paren.consumeClose();
416 if (!isTokenStringLiteral()) {
424bool Parser::ParseAttributeArgumentList(
427 bool SawError =
false;
432 Expr = ParseUnevaluatedStringInAttribute(AttrName);
434 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
435 Expr = ParseBraceInitializer();
440 if (Tok.
is(tok::ellipsis))
442 else if (Tok.
is(tok::code_completion)) {
453 if (
Expr.isInvalid()) {
463 Exprs.push_back(
Expr.get());
465 if (Tok.
isNot(tok::comma))
470 checkPotentialAngleBracketDelimiter(Comma);
477unsigned Parser::ParseAttributeArgsCommon(
486 bool AttributeIsTypeArgAttr =
488 bool AttributeHasVariadicIdentifierArg =
492 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
496 if (Tok.
is(tok::identifier)) {
498 bool IsIdentifierArg =
499 AttributeHasVariadicIdentifierArg ||
510 IsIdentifierArg = Next.isOneOf(tok::r_paren, tok::comma);
514 ArgExprs.push_back(ParseIdentifierLoc());
518 if (!ArgExprs.empty() ? Tok.
is(tok::comma) : Tok.
isNot(tok::r_paren)) {
520 if (!ArgExprs.empty())
523 if (AttributeIsTypeArgAttr) {
531 TheParsedType =
T.get();
532 }
else if (AttributeHasVariadicIdentifierArg ||
542 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
546 if (Tok.
is(tok::identifier)) {
547 ArgExprs.push_back(ParseIdentifierLoc());
563 ArgExprs.push_back(ArgExpr.
get());
579 ExprVector ParsedExprs;
583 if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties)) {
589 for (
size_t I = 0; I < ParsedExprs.size(); ++I) {
590 if (!isa<PackExpansionExpr>(ParsedExprs[I]))
595 diag::err_attribute_argument_parm_pack_not_supported)
602 llvm::append_range(ArgExprs, ParsedExprs);
607 if (!ExpectAndConsume(tok::r_paren)) {
610 if (AttributeIsTypeArgAttr && !TheParsedType.
get().
isNull()) {
613 TheParsedType, Form);
617 ArgExprs.size(), Form);
624 return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.
get().
isNull());
627void Parser::ParseGNUAttributeArgs(
632 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
637 if (AttrKind == ParsedAttr::AT_Availability) {
638 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
641 }
else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
642 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
643 ScopeName, ScopeLoc, Form);
645 }
else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
646 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
647 ScopeName, ScopeLoc, Form);
649 }
else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
650 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
653 }
else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
654 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
655 ScopeName, ScopeLoc, Form);
658 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName,
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,
668 }
else if (AttrKind == ParsedAttr::AT_CXXAssume) {
669 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
670 ScopeLoc, EndLoc, Form);
676 std::optional<ParseScope> PrototypeScope;
678 D &&
D->isFunctionDeclarator()) {
683 for (
unsigned i = 0; i != FTI.
NumParams; ++i) {
689 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
693unsigned Parser::ParseClangAttributeArgs(
697 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
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);
710 case ParsedAttr::AT_Availability:
711 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
714 case ParsedAttr::AT_ObjCBridgeRelated:
715 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
716 ScopeName, ScopeLoc, Form);
718 case ParsedAttr::AT_SwiftNewType:
719 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
722 case ParsedAttr::AT_TypeTagForDatatype:
723 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
724 ScopeName, ScopeLoc, Form);
727 case ParsedAttr::AT_CXXAssume:
728 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
729 ScopeLoc, EndLoc, Form);
732 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
738 unsigned ExistingAttrs = Attrs.
size();
752 if (
AttrName->getName() ==
"property") {
758 T.expectAndConsume(diag::err_expected_lparen_after,
759 AttrName->getNameStart(), tok::r_paren);
767 bool HasInvalidAccessor =
false;
772 if (!Tok.
is(tok::identifier)) {
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);
788 if (KindStr ==
"get") {
790 }
else if (KindStr ==
"put") {
794 }
else if (KindStr ==
"set") {
795 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
802 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
804 HasInvalidAccessor =
true;
805 goto next_property_accessor;
809 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
810 HasInvalidAccessor =
true;
829 if (!Tok.
is(tok::identifier)) {
834 if (Kind == AK_Invalid) {
836 }
else if (AccessorNames[Kind] !=
nullptr) {
838 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
844 next_property_accessor:
850 if (Tok.
is(tok::r_paren))
853 Diag(Tok.
getLocation(), diag::err_ms_property_expected_comma_or_rparen);
858 if (!HasInvalidAccessor)
860 AccessorNames[AK_Get], AccessorNames[AK_Put],
861 ParsedAttr::Form::Declspec());
863 return !HasInvalidAccessor;
867 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
873 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) <<
AttrName;
880 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
881 assert(Tok.
is(tok::kw___declspec) &&
"Not a declspec!");
886 while (Tok.
is(tok::kw___declspec)) {
889 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
895 while (Tok.
isNot(tok::r_paren)) {
900 if (Tok.
is(tok::code_completion)) {
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);
922 StringRef Str = PP.
getSpelling(Tok, StrBuffer, &Invalid);
928 AttrNameLoc = ConsumeStringToken();
934 bool AttrHandled =
false;
937 if (Tok.
is(tok::l_paren))
938 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
939 else if (
AttrName->getName() ==
"property")
946 ParsedAttr::Form::Declspec());
949 EndLoc =
T.getCloseLocation();
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:
968 case tok::kw___ptr32:
970 case tok::kw___uptr: {
984 assert(Tok.
is(tok::kw___funcref));
988 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
995 0, tok::kw___funcref);
998void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
1004 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) <<
Range;
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:
1023 case tok::kw___unaligned:
1024 case tok::kw___sptr:
1025 case tok::kw___uptr:
1036 while (Tok.
is(tok::kw___pascal)) {
1046 while (Tok.
is(tok::kw___kernel)) {
1055 while (Tok.
is(tok::kw___noinline__)) {
1059 tok::kw___noinline__);
1070bool Parser::isHLSLQualifier(
const Token &Tok)
const {
1071 return Tok.
is(tok::kw_groupshared);
1086 case tok::kw__Nonnull:
1087 case tok::kw__Nullable:
1088 case tok::kw__Nullable_result:
1089 case tok::kw__Null_unspecified: {
1093 Diag(AttrNameLoc, diag::ext_nullability)
1106 return (Separator ==
'.' || Separator ==
'_');
1112 if (!Tok.
is(tok::numeric_constant)) {
1113 Diag(Tok, diag::err_expected_version);
1116 return VersionTuple();
1125 const char *ThisTokBegin = &Buffer[0];
1129 unsigned ActualLength = PP.
getSpelling(Tok, ThisTokBegin, &Invalid);
1131 return VersionTuple();
1134 unsigned AfterMajor = 0;
1136 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
1137 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
1141 if (AfterMajor == 0) {
1142 Diag(Tok, diag::err_expected_version);
1145 return VersionTuple();
1148 if (AfterMajor == ActualLength) {
1153 Diag(Tok, diag::err_zero_version);
1154 return VersionTuple();
1157 return VersionTuple(Major);
1160 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1162 || (AfterMajor + 1 == ActualLength)) {
1163 Diag(Tok, diag::err_expected_version);
1166 return VersionTuple();
1170 unsigned AfterMinor = AfterMajor + 1;
1172 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
1173 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
1177 if (AfterMinor == ActualLength) {
1181 if (Major == 0 && Minor == 0) {
1182 Diag(Tok, diag::err_zero_version);
1183 return VersionTuple();
1186 return VersionTuple(Major, Minor);
1189 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1192 Diag(Tok, diag::err_expected_version);
1195 return VersionTuple();
1199 if (AfterMajorSeparator != AfterMinorSeparator)
1200 Diag(Tok, diag::warn_expected_consistent_version_separator);
1203 unsigned AfterSubminor = AfterMinor + 1;
1204 unsigned Subminor = 0;
1205 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
1206 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
1210 if (AfterSubminor != ActualLength) {
1211 Diag(Tok, diag::err_expected_version);
1214 return VersionTuple();
1217 return VersionTuple(Major, Minor, Subminor);
1220void Parser::ParseAvailabilityAttribute(
1224 enum { Introduced, Deprecated, Obsoleted,
Unknown };
1231 if (
T.consumeOpen()) {
1232 Diag(Tok, diag::err_expected) << tok::l_paren;
1237 if (Tok.
isNot(tok::identifier)) {
1238 Diag(Tok, diag::err_availability_expected_platform);
1245 if (Ident->getName().contains(
"xrOS") || Ident->getName().contains(
"xros"))
1246 Diag(Platform->
getLoc(), diag::warn_availability_unknown_platform)
1249 else if (Ident->getName() ==
"macosx")
1253 else if (Ident->getName() ==
"macosx_app_extension")
1257 AvailabilityAttr::canonicalizePlatformName(Ident->getName())));
1261 if (ExpectAndConsume(tok::comma)) {
1268 if (!Ident_introduced) {
1283 if (Tok.
isNot(tok::identifier)) {
1284 Diag(Tok, diag::err_availability_expected_change);
1291 if (
Keyword == Ident_strict) {
1293 Diag(KeywordLoc, diag::err_availability_redundant)
1296 StrictLoc = KeywordLoc;
1300 if (
Keyword == Ident_unavailable) {
1301 if (UnavailableLoc.
isValid()) {
1302 Diag(KeywordLoc, diag::err_availability_redundant)
1305 UnavailableLoc = KeywordLoc;
1312 if (Changes[Deprecated].KeywordLoc.
isValid()) {
1313 Diag(KeywordLoc, diag::err_availability_redundant)
1320 Changes[Deprecated].
Version = VersionTuple(1);
1324 if (
Keyword == Ident_environment) {
1325 if (EnvironmentLoc !=
nullptr) {
1326 Diag(KeywordLoc, diag::err_availability_redundant)
1331 if (Tok.
isNot(tok::equal)) {
1332 Diag(Tok, diag::err_expected_after) <<
Keyword << tok::equal;
1338 if (!isTokenStringLiteral()) {
1339 Diag(Tok, diag::err_expected_string_literal)
1344 if (
Keyword == Ident_message) {
1352 if (
Keyword == Ident_environment) {
1353 if (Tok.
isNot(tok::identifier)) {
1354 Diag(Tok, diag::err_availability_expected_environment);
1358 EnvironmentLoc = ParseIdentifierLoc();
1364 if ((
Keyword == Ident_introduced ||
Keyword == Ident_deprecated) &&
1365 Tok.
is(tok::identifier)) {
1369 if (
Keyword == Ident_introduced)
1370 UnavailableLoc = KeywordLoc;
1376 VersionTuple Version = ParseVersionTuple(VersionRange);
1378 if (Version.empty()) {
1384 if (
Keyword == Ident_introduced)
1386 else if (
Keyword == Ident_deprecated)
1388 else if (
Keyword == Ident_obsoleted)
1394 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1395 Diag(KeywordLoc, diag::err_availability_redundant)
1398 Changes[Index].VersionRange.
getEnd());
1402 Changes[Index].
Version = Version;
1405 Diag(KeywordLoc, diag::err_availability_unknown_change)
1412 if (
T.consumeClose())
1416 *endLoc =
T.getCloseLocation();
1420 if (UnavailableLoc.
isValid()) {
1421 bool Complained =
false;
1422 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1423 if (Changes[Index].KeywordLoc.
isValid()) {
1425 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1427 Changes[Index].VersionRange.
getEnd());
1438 attrs.
addNew(&Availability,
1441 Changes[Introduced], Changes[Deprecated], Changes[Obsoleted],
1442 UnavailableLoc, MessageExpr.
get(), Form, StrictLoc,
1443 ReplacementExpr.
get(), EnvironmentLoc);
1446void Parser::ParseExternalSourceSymbolAttribute(
1452 if (
T.expectAndConsume())
1456 if (!Ident_language) {
1464 bool HasLanguage =
false;
1466 bool HasDefinedIn =
false;
1469 bool HasUSR =
false;
1473 if (Tok.
isNot(tok::identifier)) {
1474 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1481 if (
Keyword == Ident_generated_declaration) {
1482 if (GeneratedDeclaration) {
1483 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) <<
Keyword;
1487 GeneratedDeclaration = ParseIdentifierLoc();
1493 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1499 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1505 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1507 if (
Keyword == Ident_language)
1509 else if (
Keyword == Ident_USR)
1512 HasDefinedIn =
true;
1514 if (!isTokenStringLiteral()) {
1515 Diag(Tok, diag::err_expected_string_literal)
1520 : (
Keyword == Ident_defined_in ? 1 : 2));
1524 if (
Keyword == Ident_language) {
1526 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1532 }
else if (
Keyword == Ident_USR) {
1534 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1541 assert(
Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1543 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1553 if (
T.consumeClose())
1556 *EndLoc =
T.getCloseLocation();
1565void Parser::ParseObjCBridgeRelatedAttribute(
1571 if (
T.consumeOpen()) {
1572 Diag(Tok, diag::err_expected) << tok::l_paren;
1577 if (Tok.
isNot(tok::identifier)) {
1578 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1583 if (ExpectAndConsume(tok::comma)) {
1592 if (Tok.
is(tok::identifier)) {
1595 Diag(Tok, diag::err_objcbridge_related_selector_name);
1601 if (Tok.
is(tok::colon))
1602 Diag(Tok, diag::err_objcbridge_related_selector_name);
1604 Diag(Tok, diag::err_expected) << tok::comma;
1612 if (Tok.
is(tok::identifier))
1614 else if (Tok.
isNot(tok::r_paren)) {
1615 Diag(Tok, diag::err_expected) << tok::r_paren;
1621 if (
T.consumeClose())
1625 *EndLoc =
T.getCloseLocation();
1628 Attrs.
addNew(&ObjCBridgeRelated,
1629 SourceRange(ObjCBridgeRelatedLoc,
T.getCloseLocation()),
1631 ClassMethod, InstanceMethod, Form);
1634void Parser::ParseSwiftNewTypeAttribute(
1641 if (
T.consumeOpen()) {
1642 Diag(Tok, diag::err_expected) << tok::l_paren;
1646 if (Tok.
is(tok::r_paren)) {
1651 if (Tok.
isNot(tok::kw_struct) && Tok.
isNot(tok::kw_enum)) {
1652 Diag(Tok, diag::warn_attribute_type_not_supported)
1654 if (!isTokenSpecial())
1660 auto *SwiftType =
new (Actions.
Context)
1665 if (
T.consumeClose())
1668 *EndLoc =
T.getCloseLocation();
1676void Parser::ParseTypeTagForDatatypeAttribute(
1680 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1685 if (Tok.
isNot(tok::identifier)) {
1686 Diag(Tok, diag::err_expected) << tok::identifier;
1692 if (ExpectAndConsume(tok::comma)) {
1704 bool LayoutCompatible =
false;
1705 bool MustBeNull =
false;
1707 if (Tok.
isNot(tok::identifier)) {
1708 Diag(Tok, diag::err_expected) << tok::identifier;
1713 if (Flag->
isStr(
"layout_compatible"))
1714 LayoutCompatible =
true;
1715 else if (Flag->
isStr(
"must_be_null"))
1718 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1725 if (!
T.consumeClose()) {
1728 ArgumentKind, MatchingCType.
get(), LayoutCompatible, MustBeNull, Form);
1732 *EndLoc =
T.getCloseLocation();
1735bool Parser::DiagnoseProhibitedCXX11Attribute() {
1736 assert(Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square));
1738 switch (isCXX11AttributeSpecifier(
true)) {
1752 assert(Tok.
is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1754 Diag(BeginLoc, diag::err_attributes_not_allowed)
1758 llvm_unreachable(
"All cases handled above.");
1763 assert((Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square)) ||
1770 ParseCXX11Attributes(Attrs);
1774 :
Diag(
Loc, diag::err_attributes_not_allowed))
1779void Parser::DiagnoseProhibitedAttributes(
1781 auto *FirstAttr = Attrs.
empty() ? nullptr : &Attrs.
front();
1782 if (CorrectLocation.
isValid()) {
1784 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1785 ?
Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1786 :
Diag(CorrectLocation, diag::err_attributes_misplaced))
1791 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1799 unsigned AttrDiagID,
1800 unsigned KeywordDiagID,
1801 bool DiagnoseEmptyAttrs,
1802 bool WarnOnUnknownAttrs) {
1812 if (FirstLSquare.
is(tok::l_square)) {
1813 std::optional<Token> SecondLSquare =
1816 if (SecondLSquare && SecondLSquare->is(tok::l_square)) {
1827 if (AL.isRegularKeywordAttribute()) {
1828 Diag(AL.getLoc(), KeywordDiagID) << AL;
1832 if (!AL.isStandardAttributeSyntax())
1835 if (WarnOnUnknownAttrs) {
1840 Diag(AL.getLoc(), AttrDiagID) << AL;
1848 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1849 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1850 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
1862 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1863 AL.isDeclspecAttribute()) ||
1864 AL.isMicrosoftAttribute())
1865 ToBeMoved.push_back(&AL);
1884 Decl *SingleDecl =
nullptr;
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:
1894 ProhibitAttributes(DeclAttrs);
1895 ProhibitAttributes(DeclSpecAttrs);
1897 return ParseNamespace(Context, DeclEnd, InlineLoc);
1899 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1900 true,
nullptr, DeclSpecStart);
1902 case tok::kw_cbuffer:
1903 case tok::kw_tbuffer:
1904 SingleDecl = ParseHLSLBuffer(DeclEnd, DeclAttrs);
1906 case tok::kw_namespace:
1907 ProhibitAttributes(DeclAttrs);
1908 ProhibitAttributes(DeclSpecAttrs);
1909 return ParseNamespace(Context, DeclEnd);
1910 case tok::kw_using: {
1912 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1913 DeclEnd, DeclAttrs);
1915 case tok::kw_static_assert:
1916 case tok::kw__Static_assert:
1917 ProhibitAttributes(DeclAttrs);
1918 ProhibitAttributes(DeclSpecAttrs);
1919 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1922 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1923 true,
nullptr, DeclSpecStart);
1934 bool RequireSemi, ForRangeInit *FRI,
SourceLocation *DeclSpecStart) {
1937 OriginalDeclSpecAttrs.
addAll(DeclSpecAttrs.
begin(), DeclSpecAttrs.
end());
1938 OriginalDeclSpecAttrs.
Range = DeclSpecAttrs.
Range;
1944 ParsedTemplateInfo TemplateInfo;
1945 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
1946 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none, DSContext);
1951 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
1956 if (Tok.
is(tok::semi)) {
1957 ProhibitAttributes(DeclAttrs);
1964 DS.complete(TheDecl);
1966 Decl* decls[] = {AnonRecord, TheDecl};
1978 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
1983 case tok::annot_cxxscope:
1984 case tok::annot_template_id:
1986 case tok::code_completion:
1987 case tok::coloncolon:
1989 case tok::kw___attribute:
1990 case tok::kw_operator:
2006 case tok::identifier:
2008 case tok::code_completion:
2009 case tok::coloncolon:
2012 case tok::equalequal:
2013 case tok::kw_alignas:
2015 case tok::kw___attribute:
2033 case tok::identifier:
2053 if (Tok.
isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
2077 case tok::kw_inline:
2082 (!ParsingInObjCContainer || CurParsedObjCImpl))
2086 case tok::kw_namespace:
2091 (!ParsingInObjCContainer || CurParsedObjCImpl))
2097 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2098 ParsingInObjCContainer)
2110 case tok::annot_module_begin:
2111 case tok::annot_module_end:
2112 case tok::annot_module_include:
2113 case tok::annot_repl_input_end:
2127 ParsedTemplateInfo &TemplateInfo,
2129 ForRangeInit *FRI) {
2135 LocalAttrs.takeAllFrom(Attrs);
2137 if (TemplateInfo.TemplateParams)
2138 D.setTemplateParameterLists(*TemplateInfo.TemplateParams);
2140 bool IsTemplateSpecOrInst =
2147 if (IsTemplateSpecOrInst)
2151 if (!
D.hasName() && !
D.mayOmitIdentifier()) {
2157 while (MaybeParseHLSLAnnotations(
D))
2160 if (Tok.
is(tok::kw_requires))
2161 ParseTrailingRequiresClause(
D);
2166 LateParsedAttrList LateParsedAttrs(
true);
2167 if (
D.isFunctionDeclarator()) {
2168 MaybeParseGNUAttributes(
D, &LateParsedAttrs);
2173 if (Tok.
is(tok::kw__Noreturn)) {
2175 const char *PrevSpec;
2181 MaybeParseGNUAttributes(
D, &LateParsedAttrs);
2182 Fixit &= Tok.
isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2184 Diag(
Loc, diag::err_c11_noreturn_misplaced)
2186 << (Fixit ?
FixItHint::CreateInsertion(
D.getBeginLoc(),
"_Noreturn ")
2191 if (Tok.
is(tok::equal) &&
NextToken().is(tok::code_completion)) {
2202 while (
auto Specifier = isCXX11VirtSpecifier()) {
2203 Diag(Tok, diag::err_virt_specifier_outside_class)
2211 if (!isDeclarationAfterDeclarator()) {
2217 if (isStartOfFunctionDefinition(
D)) {
2227 diag::err_function_declared_typedef)
2231 Decl *TheDecl =
nullptr;
2237 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2238 TheDecl = ParseFunctionDefinition(
D, ParsedTemplateInfo(),
2243 Diag(
D.getIdentifierLoc(),
2244 diag::err_explicit_instantiation_with_definition)
2252 LAngleLoc,
nullptr));
2254 TheDecl = ParseFunctionDefinition(
2256 ParsedTemplateInfo(&FakedParamLists,
2263 ParseFunctionDefinition(
D, TemplateInfo, &LateParsedAttrs);
2270 Tok.
is(tok::kw_namespace)) {
2280 Diag(Tok, diag::err_expected_fn_body);
2285 if (Tok.
is(tok::l_brace)) {
2286 Diag(Tok, diag::err_function_definition_not_allowed);
2294 if (ParseAsmAttributesAfterDeclarator(
D))
2303 if (FRI && (Tok.
is(tok::colon) || isTokIdentifier_in())) {
2304 bool IsForRangeLoop =
false;
2306 IsForRangeLoop =
true;
2317 LastRecord.RebuildDefaultArgOrDefaultInit =
true;
2322 if (Tok.
is(tok::l_brace))
2323 FRI->RangeExpr = ParseBraceInitializer();
2334 FRI->LifetimeExtendTemps = std::move(
2339 if (IsForRangeLoop) {
2343 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2344 VD->setObjCForDecl(
true);
2347 D.complete(ThisDecl);
2353 ParseDeclarationAfterDeclaratorAndAttributes(
D, TemplateInfo, FRI);
2354 if (LateParsedAttrs.size() > 0)
2355 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2356 D.complete(FirstDecl);
2358 DeclsInGroup.push_back(FirstDecl);
2366 if (Tok.
isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2370 Diag(CommaLoc, diag::err_expected_semi_declaration)
2381 D.isFirstDeclarator()) {
2382 Diag(CommaLoc, diag::err_multiple_template_declarators)
2383 << TemplateInfo.Kind;
2388 D.setCommaLoc(CommaLoc);
2397 MaybeParseGNUAttributes(
D);
2401 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2406 MaybeParseHLSLAnnotations(
D);
2408 if (!
D.isInvalidType()) {
2413 if (Tok.
is(tok::kw_requires))
2414 ParseTrailingRequiresClause(
D);
2415 Decl *ThisDecl = ParseDeclarationAfterDeclarator(
D, TemplateInfo);
2416 D.complete(ThisDecl);
2418 DeclsInGroup.push_back(ThisDecl);
2425 if (ExpectSemi && ExpectAndConsumeSemi(
2427 ? diag::err_invalid_token_after_toplevel_declarator
2428 : diag::err_expected_semi_declaration)) {
2439bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &
D) {
2441 if (Tok.
is(tok::kw_asm)) {
2444 if (AsmLabel.isInvalid()) {
2449 D.setAsmLabel(AsmLabel.get());
2453 MaybeParseGNUAttributes(
D);
2457Decl *Parser::ParseDeclarationAfterDeclarator(
2458 Declarator &
D,
const ParsedTemplateInfo &TemplateInfo) {
2459 if (ParseAsmAttributesAfterDeclarator(
D))
2462 return ParseDeclarationAfterDeclaratorAndAttributes(
D, TemplateInfo);
2465Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2466 Declarator &
D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2468 struct InitializerScopeRAII {
2475 :
P(
P),
D(
D), ThisDecl(ThisDecl), Entered(
false) {
2476 if (ThisDecl &&
P.getLangOpts().CPlusPlus) {
2478 if (
D.getCXXScopeSpec().isSet()) {
2480 S =
P.getCurScope();
2483 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2488 ~InitializerScopeRAII() {
2489 if (ThisDecl &&
P.getLangOpts().CPlusPlus) {
2491 if (
D.getCXXScopeSpec().isSet())
2492 S =
P.getCurScope();
2495 P.Actions.ActOnCXXExitDeclInitializer(S, ThisDecl);
2504 InitKind TheInitKind;
2506 if (isTokenEqualOrEqualTypo())
2507 TheInitKind = InitKind::Equal;
2508 else if (Tok.
is(tok::l_paren))
2509 TheInitKind = InitKind::CXXDirect;
2511 (!CurParsedObjCImpl || !
D.isFunctionDeclarator()))
2512 TheInitKind = InitKind::CXXBraced;
2514 TheInitKind = InitKind::Uninitialized;
2515 if (TheInitKind != InitKind::Uninitialized)
2516 D.setHasInitializer();
2519 Decl *ThisDecl =
nullptr;
2520 Decl *OuterDecl =
nullptr;
2521 switch (TemplateInfo.Kind) {
2529 *TemplateInfo.TemplateParams,
2531 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2534 ThisDecl = VT->getTemplatedDecl();
2540 if (Tok.
is(tok::semi)) {
2542 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
D);
2547 ThisDecl = ThisRes.
get();
2555 Diag(Tok, diag::err_template_defn_explicit_instantiation)
2561 Diag(
D.getIdentifierLoc(),
2562 diag::err_explicit_instantiation_with_definition)
2570 LAngleLoc,
nullptr));
2582 switch (TheInitKind) {
2584 case InitKind::Equal: {
2587 if (Tok.
is(tok::kw_delete)) {
2588 if (
D.isFunctionDeclarator())
2593 SkipDeletedFunctionBody();
2594 }
else if (Tok.
is(tok::kw_default)) {
2595 if (
D.isFunctionDeclarator())
2602 InitializerScopeRAII
InitScope(*
this,
D, ThisDecl);
2604 if (Tok.
is(tok::code_completion)) {
2617 if (Tok.
is(tok::r_paren) && FRI &&
D.isFirstDeclarator()) {
2618 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2622 FRI->ColonLoc = EqualLoc;
2624 FRI->RangeExpr =
Init;
2627 if (
Init.isInvalid()) {
2629 StopTokens.push_back(tok::comma);
2632 StopTokens.push_back(tok::r_paren);
2641 case InitKind::CXXDirect: {
2648 InitializerScopeRAII
InitScope(*
this,
D, ThisDecl);
2650 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2651 auto RunSignatureHelp = [&]() {
2654 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2657 CalledSignatureHelp =
true;
2658 return PreferredType;
2660 auto SetPreferredType = [&] {
2661 PreferredType.enterFunctionArgument(Tok.
getLocation(), RunSignatureHelp);
2664 llvm::function_ref<void()> ExpressionStarts;
2670 ExpressionStarts = SetPreferredType;
2673 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2678 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2681 CalledSignatureHelp =
true;
2690 T.getCloseLocation(),
2697 case InitKind::CXXBraced: {
2699 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2701 InitializerScopeRAII
InitScope(*
this,
D, ThisDecl);
2703 PreferredType.enterVariableInit(Tok.
getLocation(), ThisDecl);
2706 if (
Init.isInvalid()) {
2712 case InitKind::Uninitialized: {
2713 InitializerScopeRAII
InitScope(*
this,
D, ThisDecl);
2720 return OuterDecl ? OuterDecl : ThisDecl;
2723void Parser::ParseSpecifierQualifierList(
2726 ParsedTemplateInfo TemplateInfo;
2730 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC,
nullptr,
2731 AllowImplicitTypename);
2736 Diag(Tok, diag::err_expected_type);
2739 Diag(Tok, diag::err_typename_requires_specqual);
2750 diag::err_typename_invalid_storageclass);
2794 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2795 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2800 ParsedTemplateInfo &TemplateInfo,
2803 assert(Tok.
is(tok::identifier) &&
"should have identifier");
2825 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
2843 AnnotateScopeToken(*SS,
false);
2854 DSC == DeclSpecContext::DSC_template_type_arg)) {
2855 const char *PrevSpec;
2871 if (SS ==
nullptr) {
2872 const char *TagName =
nullptr, *FixitTagName =
nullptr;
2878 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
2880 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
2882 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
2884 TagName=
"__interface"; FixitTagName =
"__interface ";
2885 TagKind=tok::kw___interface;
break;
2887 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
2895 Diag(
Loc, diag::err_use_of_tag_name_without_tag)
2896 << TokenName << TagName <<
getLangOpts().CPlusPlus
2902 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2903 << TokenName << TagName;
2907 if (TagKind == tok::kw_enum)
2908 ParseEnumSpecifier(
Loc, DS, TemplateInfo, AS,
2909 DeclSpecContext::DSC_normal);
2911 ParseClassSpecifier(TagKind,
Loc, DS, TemplateInfo, AS,
2913 DeclSpecContext::DSC_normal, Attrs);
2920 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
2921 DSC == DeclSpecContext::DSC_class)) {
2925 case tok::l_paren: {
2932 TentativeParsingAction PA(*
this);
2934 TPResult TPR = TryParseDeclarator(
false);
2937 if (TPR != TPResult::False) {
2945 if (DSC == DeclSpecContext::DSC_class ||
2946 (DSC == DeclSpecContext::DSC_top_level && SS)) {
2949 Diag(
Loc, diag::err_constructor_bad_name)
2970 AnnotateScopeToken(*SS,
false);
2992 const char *PrevSpec;
3013 if (IsTemplateName) {
3015 TemplateArgList Args;
3016 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3025Parser::DeclSpecContext
3029 return DeclSpecContext::DSC_class;
3031 return DeclSpecContext::DSC_top_level;
3033 return DeclSpecContext::DSC_template_param;
3035 return DeclSpecContext::DSC_template_arg;
3037 return DeclSpecContext::DSC_template_type_arg;
3040 return DeclSpecContext::DSC_trailing;
3043 return DeclSpecContext::DSC_alias_declaration;
3045 return DeclSpecContext::DSC_association;
3047 return DeclSpecContext::DSC_type_specifier;
3049 return DeclSpecContext::DSC_condition;
3051 return DeclSpecContext::DSC_conv_operator;
3053 return DeclSpecContext::DSC_new;
3068 return DeclSpecContext::DSC_normal;
3071 llvm_unreachable(
"Missing DeclaratorContext case");
3078 if (isTypeIdInParens()) {
3099 assert(Tok.
isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3100 "Not an alignment-specifier!");
3107 if (
T.expectAndConsume())
3114 ParseAlignArgument(PP.
getSpelling(KWTok),
T.getOpenLocation(),
3123 *EndLoc =
T.getCloseLocation();
3130 ArgExprs.push_back(ArgExpr.
get());
3136void Parser::DistributeCLateParsedAttrs(
Decl *Dcl,
3137 LateParsedAttrList *LateAttrs) {
3142 for (
auto *LateAttr : *LateAttrs) {
3143 if (LateAttr->Decls.empty())
3144 LateAttr->addDecl(Dcl);
3150 assert(Tok.
is(tok::kw___ptrauth));
3156 if (
T.expectAndConsume())
3166 ArgExprs.push_back(ER.
get());
3172 if (ArgExprs.empty() || ArgExprs.size() > 3) {
3173 Diag(KwLoc, diag::err_ptrauth_qualifier_bad_arg_count);
3178 ArgExprs.data(), ArgExprs.size(),
3179 ParsedAttr::Form::Keyword(
false,
3189 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3194 if (Tok.
is(tok::r_paren)) {
3202 using ExpressionKind =
3206 ExpressionKind::EK_AttrArgument);
3214 ArgExprs.push_back(ArgExpr.
get());
3227ExprResult Parser::ParseExtIntegerArgument() {
3228 assert(Tok.
isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3229 "Not an extended int type");
3233 if (
T.expectAndConsume())
3242 if(
T.consumeClose())
3249 DeclSpecContext DSContext,
3250 LateParsedAttrList *LateAttrs) {
3253 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3254 DSContext == DeclSpecContext::DSC_top_level);
3257 Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
3258 tok::annot_template_id) &&
3264 bool HasScope = Tok.
is(tok::annot_cxxscope);
3270 bool MightBeDeclarator =
true;
3271 if (Tok.
isOneOf(tok::kw_typename, tok::annot_typename)) {
3273 MightBeDeclarator =
false;
3274 }
else if (AfterScope.
is(tok::annot_template_id)) {
3280 MightBeDeclarator =
false;
3281 }
else if (AfterScope.
is(tok::identifier)) {
3286 if (Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3287 tok::annot_cxxscope, tok::coloncolon)) {
3289 MightBeDeclarator =
false;
3290 }
else if (HasScope) {
3301 switch (Classification.
getKind()) {
3307 llvm_unreachable(
"typo correction is not possible here");
3315 MightBeDeclarator =
false;
3330 if (MightBeDeclarator)
3335 diag::err_expected_after)
3346 ParsedTemplateInfo NotATemplate;
3347 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3351void Parser::ParseDeclarationSpecifiers(
3353 DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
3365 if (DSContext == DeclSpecContext::DSC_conv_operator) {
3368 DSContext = DeclSpecContext::DSC_type_specifier;
3371 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3372 DSContext == DeclSpecContext::DSC_top_level);
3373 bool AttrsLastTime =
false;
3379 bool isStorageClass =
false;
3380 const char *PrevSpec =
nullptr;
3381 unsigned DiagID = 0;
3402 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3416 bool IsTemplateSpecOrInst =
3427 ProhibitAttributes(attrs);
3431 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3432 !PA.isRegularKeywordAttribute())
3440 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3441 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3448 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3449 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3452 if (PA.getKind() == ParsedAttr::AT_LifetimeBound)
3453 Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type)
3454 << PA << PA.isRegularKeywordAttribute()
3457 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3458 << PA << PA.isRegularKeywordAttribute();
3467 DS.
Finish(Actions, Policy);
3471 case tok::kw__Alignas:
3472 diagnoseUseOfC11Keyword(Tok);
3474 case tok::kw_alignas:
3480 if (Tok.
getKind() == tok::kw_alignas)
3481 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
3487 if (!isAllowedCXX11AttributeSpecifier())
3488 goto DoneWithDeclSpec;
3491 ProhibitAttributes(attrs);
3498 ParseCXX11Attributes(attrs);
3499 AttrsLastTime =
true;
3502 case tok::code_completion: {
3506 bool AllowNonIdentifiers
3512 bool AllowNestedNameSpecifiers
3513 = DSContext == DeclSpecContext::DSC_top_level ||
3518 getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3524 CCC = DSContext == DeclSpecContext::DSC_class
3527 else if (DSContext == DeclSpecContext::DSC_class)
3531 else if (CurParsedObjCImpl)
3539 case tok::coloncolon:
3545 goto DoneWithDeclSpec;
3547 if (Tok.
is(tok::coloncolon))
3548 goto DoneWithDeclSpec;
3551 case tok::annot_cxxscope: {
3553 goto DoneWithDeclSpec;
3556 if (TemplateInfo.TemplateParams)
3566 ? takeTemplateIdAnnotation(Next)
3572 ConsumeAnnotationToken();
3586 if ((DSContext == DeclSpecContext::DSC_top_level ||
3587 DSContext == DeclSpecContext::DSC_class) &&
3590 isConstructorDeclarator(
false,
3597 goto DoneWithDeclSpec;
3601 ConsumeAnnotationToken();
3602 assert(Tok.
is(tok::annot_template_id) &&
3603 "ParseOptionalCXXScopeSpecifier not working");
3604 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3614 ConsumeAnnotationToken();
3618 if (Next.is(tok::annot_typename)) {
3620 ConsumeAnnotationToken();
3624 PrevSpec, DiagID,
T, Policy);
3628 ConsumeAnnotationToken();
3632 Next.is(tok::annot_template_id) &&
3636 ConsumeAnnotationToken();
3637 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3641 if (Next.isNot(tok::identifier))
3642 goto DoneWithDeclSpec;
3647 if ((DSContext == DeclSpecContext::DSC_top_level ||
3648 DSContext == DeclSpecContext::DSC_class) &&
3651 isConstructorDeclarator(
false,
3655 goto DoneWithDeclSpec;
3664 *Next.getIdentifierInfo(), Next.getLocation(),
getCurScope(), &SS,
3665 false,
false,
nullptr,
3668 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3670 if (IsTemplateSpecOrInst)
3678 if (TryAnnotateTypeConstraint())
3679 goto DoneWithDeclSpec;
3680 if (Tok.
isNot(tok::annot_cxxscope) ||
3684 ConsumeAnnotationToken();
3686 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3687 if (!Attrs.
empty()) {
3688 AttrsLastTime =
true;
3689 attrs.takeAllFrom(Attrs);
3693 goto DoneWithDeclSpec;
3697 ConsumeAnnotationToken();
3700 DiagID, TypeRep, Policy);
3710 case tok::annot_typename: {
3714 goto DoneWithDeclSpec;
3723 ConsumeAnnotationToken();
3728 case tok::kw___is_signed:
3740 TryKeywordIdentFallback(
true);
3743 goto DoneWithDeclSpec;
3746 case tok::kw___super:
3747 case tok::kw_decltype:
3748 case tok::identifier:
3754 goto DoneWithDeclSpec;
3760 if (!
getLangOpts().DeclSpecKeyword && Tok.
is(tok::identifier) &&
3762 Diag(
Loc, diag::err_ms_attributes_not_enabled);
3772 if (
T.consumeOpen()) {
3773 assert(
false &&
"Not a left paren?");
3792 if (IsTemplateSpecOrInst)
3796 if (IsTemplateSpecOrInst)
3799 goto DoneWithDeclSpec;
3802 if (!Tok.
is(tok::identifier))
3807 if (TryAltiVecToken(DS,
Loc, PrevSpec, DiagID,
isInvalid))
3813 goto DoneWithDeclSpec;
3815 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3816 isObjCInstancetype()) {
3820 DiagID, TypeRep, Policy);
3833 isConstructorDeclarator(
true,
3836 goto DoneWithDeclSpec;
3840 false,
false,
nullptr,
false,
false,
3841 isClassTemplateDeductionContext(DSContext));
3846 if (TryAnnotateTypeConstraint())
3847 goto DoneWithDeclSpec;
3848 if (Tok.
isNot(tok::identifier))
3851 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
3852 if (!Attrs.
empty()) {
3853 AttrsLastTime =
true;
3854 attrs.takeAllFrom(Attrs);
3858 goto DoneWithDeclSpec;
3865 (DSContext == DeclSpecContext::DSC_class ||
3866 DSContext == DeclSpecContext::DSC_top_level) &&
3869 isConstructorDeclarator(
true,
3871 goto DoneWithDeclSpec;
3874 DiagID, TypeRep, Policy);
3886 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3901 case tok::annot_template_id: {
3913 TemplateId =
nullptr;
3921 tok::kw_volatile, tok::kw_restrict, tok::amp,
3923 Diag(
Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
3927 TemplateId, Policy);
3931 goto DoneWithDeclSpec;
3934 TemplateId =
nullptr;
3936 ConsumeAnnotationToken();
3940 if (Tracker.consumeOpen()) {
3942 Diag(Tok, diag::err_expected) << tok::l_paren;
3946 Tracker.skipToEnd();
3947 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
3952 Tracker.consumeClose();
3960 DiagID, TemplateId, Policy);
3963 TemplateId, Policy);
3972 goto DoneWithDeclSpec;
3980 isConstructorDeclarator(
true,
3983 goto DoneWithDeclSpec;
3988 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3993 case tok::kw___attribute:
3994 case tok::kw___declspec:
3995 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
3999 case tok::kw___forceinline: {
4004 nullptr, 0, tok::kw___forceinline);
4008 case tok::kw___unaligned:
4014 case tok::kw___ptrauth:
4018 case tok::kw___sptr:
4019 case tok::kw___uptr:
4020 case tok::kw___ptr64:
4021 case tok::kw___ptr32:
4023 case tok::kw___cdecl:
4024 case tok::kw___stdcall:
4025 case tok::kw___fastcall:
4026 case tok::kw___thiscall:
4027 case tok::kw___regcall:
4028 case tok::kw___vectorcall:
4032 case tok::kw___funcref:
4037 case tok::kw___pascal:
4042 case tok::kw___kernel:
4047 case tok::kw___noinline__:
4052 case tok::kw__Nonnull:
4053 case tok::kw__Nullable:
4054 case tok::kw__Nullable_result:
4055 case tok::kw__Null_unspecified:
4060 case tok::kw___kindof:
4068 case tok::kw_typedef:
4070 PrevSpec, DiagID, Policy);
4071 isStorageClass =
true;
4073 case tok::kw_extern:
4075 Diag(Tok, diag::ext_thread_before) <<
"extern";
4077 PrevSpec, DiagID, Policy);
4078 isStorageClass =
true;
4080 case tok::kw___private_extern__:
4082 Loc, PrevSpec, DiagID, Policy);
4083 isStorageClass =
true;
4085 case tok::kw_static:
4087 Diag(Tok, diag::ext_thread_before) <<
"static";
4089 PrevSpec, DiagID, Policy);
4090 isStorageClass =
true;
4096 PrevSpec, DiagID, Policy);
4098 Diag(Tok, diag::ext_auto_storage_class)
4105 PrevSpec, DiagID, Policy);
4106 isStorageClass =
true;
4108 case tok::kw___auto_type:
4109 Diag(Tok, diag::ext_auto_type);
4113 case tok::kw_register:
4115 PrevSpec, DiagID, Policy);
4116 isStorageClass =
true;
4118 case tok::kw_mutable:
4120 PrevSpec, DiagID, Policy);
4121 isStorageClass =
true;
4123 case tok::kw___thread:
4126 isStorageClass =
true;
4128 case tok::kw_thread_local:
4130 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4139 Loc, PrevSpec, DiagID);
4140 isStorageClass =
true;
4142 case tok::kw__Thread_local:
4143 diagnoseUseOfC11Keyword(Tok);
4145 Loc, PrevSpec, DiagID);
4146 isStorageClass =
true;
4150 case tok::kw_inline:
4153 case tok::kw_virtual:
4157 !
getActions().getOpenCLOptions().isAvailableOption(
4159 DiagID = diag::err_openclcxx_virtual_function;
4163 DiagID = diag::err_hlsl_virtual_function;
4170 case tok::kw_explicit: {
4174 ConsumedEnd = ExplicitLoc;
4176 if (Tok.
is(tok::l_paren)) {
4179 ? diag::warn_cxx17_compat_explicit_bool
4180 : diag::ext_explicit_bool);
4184 Tracker.consumeOpen();
4191 if (ExplicitExpr.isUsable()) {
4193 Tracker.consumeClose();
4197 Tracker.skipToEnd();
4203 ExplicitSpec, CloseParenLoc);
4206 case tok::kw__Noreturn:
4207 diagnoseUseOfC11Keyword(Tok);
4212 case tok::kw_friend:
4213 if (DSContext == DeclSpecContext::DSC_class) {
4220 DiagID = diag::err_friend_invalid_in_context;
4226 case tok::kw___module_private__:
4231 case tok::kw_constexpr:
4233 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4237 case tok::kw_consteval:
4241 case tok::kw_constinit:
4257 PrevSpec, DiagID, Policy);
4259 case tok::kw___int64:
4261 PrevSpec, DiagID, Policy);
4263 case tok::kw_signed:
4267 case tok::kw_unsigned:
4271 case tok::kw__Complex:
4273 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4277 case tok::kw__Imaginary:
4279 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4295 case tok::kw__ExtInt:
4296 case tok::kw__BitInt: {
4297 DiagnoseBitIntUse(Tok);
4302 ConsumedEnd = PrevTokLocation;
4305 case tok::kw___int128:
4313 case tok::kw___bf16:
4321 case tok::kw_double:
4325 case tok::kw__Float16:
4329 case tok::kw__Accum:
4331 "This keyword is only used when fixed point types are enabled "
4332 "with `-ffixed-point`");
4336 case tok::kw__Fract:
4338 "This keyword is only used when fixed point types are enabled "
4339 "with `-ffixed-point`");
4345 "This keyword is only used when fixed point types are enabled "
4346 "with `-ffixed-point`");
4349 case tok::kw___float128:
4353 case tok::kw___ibm128:
4357 case tok::kw_wchar_t:
4361 case tok::kw_char8_t:
4365 case tok::kw_char16_t:
4369 case tok::kw_char32_t:
4375 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4379 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4381 if (Tok.
is(tok::kw_bool) &&
4385 DiagID = diag::err_bool_redeclaration;
4394 case tok::kw__Decimal32:
4398 case tok::kw__Decimal64:
4402 case tok::kw__Decimal128:
4406 case tok::kw___vector:
4409 case tok::kw___pixel:
4412 case tok::kw___bool:
4417 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4422 goto DoneWithDeclSpec;
4424 DiagID = diag::err_opencl_unknown_type_specifier;
4431#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4432#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4433#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4434 case tok::kw_##ImgType##_t: \
4435 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4436 goto DoneWithDeclSpec; \
4438#include "clang/Basic/OpenCLImageTypes.def"
4439 case tok::kw___unknown_anytype:
4441 PrevSpec, DiagID, Policy);
4446 case tok::kw_struct:
4447 case tok::kw___interface:
4448 case tok::kw_union: {
4456 ParseClassSpecifier(Kind,
Loc, DS, TemplateInfo, AS,
4457 EnteringContext, DSContext, Attributes);
4461 if (!Attributes.empty()) {
4462 AttrsLastTime =
true;
4463 attrs.takeAllFrom(Attributes);
4471 ParseEnumSpecifier(
Loc, DS, TemplateInfo, AS, DSContext);
4479 case tok::kw_volatile:
4483 case tok::kw_restrict:
4489 case tok::kw_typename:
4492 goto DoneWithDeclSpec;
4494 if (!Tok.
is(tok::kw_typename))
4499 case tok::kw_typeof:
4500 case tok::kw_typeof_unqual:
4501 ParseTypeofSpecifier(DS);
4504 case tok::annot_decltype:
4505 ParseDecltypeSpecifier(DS);
4508 case tok::annot_pack_indexing_type:
4509 ParsePackIndexingType(DS);
4512 case tok::annot_pragma_pack:
4516 case tok::annot_pragma_ms_pragma:
4517 HandlePragmaMSPragma();
4520 case tok::annot_pragma_ms_vtordisp:
4521 HandlePragmaMSVtorDisp();
4524 case tok::annot_pragma_ms_pointers_to_members:
4525 HandlePragmaMSPointersToMembers();
4528#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4529#include "clang/Basic/TransformTypeTraits.def"
4533 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4534 goto ParseIdentifier;
4537 case tok::kw__Atomic:
4542 diagnoseUseOfC11Keyword(Tok);
4544 ParseAtomicSpecifier(DS);
4552 case tok::kw___generic:
4557 if (!Actions.
getLangOpts().OpenCLGenericAddressSpace) {
4558 DiagID = diag::err_opencl_unknown_type_specifier;
4564 case tok::kw_private:
4568 goto DoneWithDeclSpec;
4570 case tok::kw___private:
4571 case tok::kw___global:
4572 case tok::kw___local:
4573 case tok::kw___constant:
4575 case tok::kw___read_only:
4576 case tok::kw___write_only:
4577 case tok::kw___read_write:
4581 case tok::kw_groupshared:
4589#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
4590 case tok::kw_##Name: \
4591 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4594#include "clang/Basic/HLSLIntangibleTypes.def"
4601 goto DoneWithDeclSpec;
4606 if (
Type.isUsable()) {
4608 PrevSpec, DiagID,
Type.get(),
4610 Diag(StartLoc, DiagID) << PrevSpec;
4626 assert(PrevSpec &&
"Method did not return previous specifier!");
4629 if (DiagID == diag::ext_duplicate_declspec ||
4630 DiagID == diag::ext_warn_duplicate_declspec ||
4631 DiagID == diag::err_duplicate_declspec)
4635 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4639 Diag(
Loc, DiagID) << PrevSpec;
4642 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4646 AttrsLastTime =
false;
4658 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4661 for (
auto *I : RD->decls()) {
4662 auto *VD = dyn_cast<ValueDecl>(I);
4670 for (
const auto &DD : CAT->dependent_decls()) {
4671 if (!RD->containsDecl(DD.getDecl())) {
4672 P.Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4673 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4674 P.Diag(DD.getDecl()->getBeginLoc(),
4675 diag::note_flexible_array_counted_by_attr_field)
4682void Parser::ParseStructDeclaration(
4685 LateParsedAttrList *LateFieldAttrs) {
4687 if (Tok.
is(tok::kw___extension__)) {
4691 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4696 MaybeParseCXX11Attributes(Attrs);
4699 ParseSpecifierQualifierList(DS);
4703 if (Tok.
is(tok::semi)) {
4708 ProhibitAttributes(Attrs);
4712 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4718 bool FirstDeclarator =
true;
4722 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4725 if (!FirstDeclarator) {
4728 DiagnoseAndSkipCXX11Attributes();
4729 MaybeParseGNUAttributes(DeclaratorInfo.D);
4730 DiagnoseAndSkipCXX11Attributes();
4735 if (Tok.
isNot(tok::colon)) {
4738 ParseDeclarator(DeclaratorInfo.D);
4740 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.
getLocation());
4752 DeclaratorInfo.BitfieldSize = Res.
get();
4756 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
4759 Decl *
Field = FieldsCallback(DeclaratorInfo);
4761 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
4768 FirstDeclarator =
false;
4774void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs,
bool EnterScope,
4776 assert(LAs.parseSoon() &&
4777 "Attribute list should be marked for immediate parsing.");
4778 for (
auto *LA : LAs) {
4779 ParseLexedCAttribute(*LA,
EnterScope, OutAttrs);
4785void Parser::ParseLexedCAttribute(LateParsedAttribute &LA,
bool EnterScope,
4794 LA.Toks.push_back(AttrEnd);
4798 LA.Toks.push_back(Tok);
4799 PP.EnterTokenStream(LA.Toks,
true,
4810 assert(LA.Decls.size() <= 1 &&
4811 "late field attribute expects to have at most one declaration.");
4814 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
nullptr,
nullptr,
4817 for (
auto *
D : LA.Decls)
4822 while (Tok.
isNot(tok::eof))
4837 "parsing struct/union body");
4841 if (
T.consumeOpen())
4849 LateParsedAttrList LateFieldAttrs(
true,
4853 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
4854 Tok.
isNot(tok::eof)) {
4858 if (Tok.
is(tok::semi)) {
4864 if (Tok.
isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4866 ParseStaticAssertDeclaration(DeclEnd);
4870 if (Tok.
is(tok::annot_pragma_pack)) {
4875 if (Tok.
is(tok::annot_pragma_align)) {
4876 HandlePragmaAlign();
4880 if (Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4884 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4888 if (Tok.
is(tok::annot_pragma_openacc)) {
4899 ConsumeAnnotationToken();
4903 if (!Tok.
is(tok::at)) {
4909 FD.D, FD.BitfieldSize);
4916 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
4920 Diag(Tok, diag::err_unexpected_at);
4925 ExpectAndConsume(tok::l_paren);
4926 if (!Tok.
is(tok::identifier)) {
4927 Diag(Tok, diag::err_expected) << tok::identifier;
4935 ExpectAndConsume(tok::r_paren);
4941 if (Tok.
is(tok::r_brace)) {
4942 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
4946 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
4957 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
4960 ParseLexedCAttributeList(LateFieldAttrs,
false);
4965 T.getOpenLocation(),
T.getCloseLocation(), attrs);
4971 const ParsedTemplateInfo &TemplateInfo,
4974 if (Tok.
is(tok::code_completion)) {
4984 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
4987 bool IsScopedUsingClassTag =
false;
4992 : diag::ext_scoped_enum);
4993 IsScopedUsingClassTag = Tok.
is(tok::kw_class);
4998 ProhibitAttributes(attrs);
5001 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5010 bool shouldDelayDiagsInTag =
5016 AllowDefiningTypeSpec AllowEnumSpecifier =
5018 bool CanBeOpaqueEnumDeclaration =
5019 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5022 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5023 CanBeOpaqueEnumDeclaration);
5031 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5036 if (Spec.
isSet() && Tok.
isNot(tok::identifier)) {
5037 Diag(Tok, diag::err_expected) << tok::identifier;
5039 if (Tok.
isNot(tok::l_brace)) {
5051 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::l_brace) &&
5052 Tok.
isNot(tok::colon)) {
5053 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5064 if (Tok.
is(tok::identifier)) {
5069 if (!Name && ScopedEnumKWLoc.
isValid()) {
5072 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5074 IsScopedUsingClassTag =
false;
5079 if (shouldDelayDiagsInTag)
5080 diagsFromTag.done();
5085 bool CanBeBitfield =
5089 if (Tok.
is(tok::colon)) {
5114 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5119 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5130 DeclSpecContext::DSC_type_specifier);
5135 BaseRange =
SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5139 DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)
5142 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5146 ? diag::warn_c17_compat_enum_fixed_underlying_type
5147 : diag::ext_c23_enum_fixed_underlying_type)
5164 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5166 else if (Tok.
is(tok::l_brace)) {
5175 IsScopedUsingClassTag =
false;
5181 }
else if (!isTypeSpecifier(DSC) &&
5182 (Tok.
is(tok::semi) ||
5184 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5189 if (Tok.
isNot(tok::semi)) {
5191 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5199 bool IsElaboratedTypeSpecifier =
5205 diagsFromTag.redelay();
5213 Diag(Tok, diag::err_enum_template);
5221 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5225 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5227 TemplateInfo.TemplateParams->size());
5232 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5248 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5250 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5251 diag::err_keyword_not_allowed,
5254 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5255 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5256 else if (ScopedEnumKWLoc.
isValid())
5257 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5261 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5271 bool IsDependent =
false;
5272 const char *PrevSpec =
nullptr;
5277 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5278 IsScopedUsingClassTag,
5279 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5280 DSC == DeclSpecContext::DSC_template_param ||
5281 DSC == DeclSpecContext::DSC_template_type_arg,
5282 OffsetOfState, &SkipBody).
get();
5292 NameLoc.
isValid() ? NameLoc : StartLoc,
5293 PrevSpec, DiagID,
TagDecl, Owned,
5295 Diag(StartLoc, DiagID) << PrevSpec;
5304 Diag(Tok, diag::err_expected_type_name_after_typename);
5310 if (
Type.isInvalid()) {
5316 NameLoc.
isValid() ? NameLoc : StartLoc,
5317 PrevSpec, DiagID,
Type.get(),
5319 Diag(StartLoc, DiagID) << PrevSpec;
5338 ParseEnumBody(StartLoc,
D, &SkipBody);
5347 NameLoc.
isValid() ? NameLoc : StartLoc,
5348 PrevSpec, DiagID,
TagDecl, Owned,
5350 Diag(StartLoc, DiagID) << PrevSpec;
5364 Diag(Tok, diag::err_empty_enum);
5369 Decl *LastEnumConstDecl =
nullptr;
5372 while (Tok.
isNot(tok::r_brace)) {
5375 if (Tok.
isNot(tok::identifier)) {
5387 MaybeParseGNUAttributes(attrs);
5388 if (isAllowedCXX11AttributeSpecifier()) {
5391 ? diag::warn_cxx14_compat_ns_enum_attribute
5392 : diag::ext_ns_enum_attribute)
5394 ParseCXX11Attributes(attrs);
5399 EnumAvailabilityDiags.emplace_back(*
this);
5412 EqualLoc, AssignedVal.
get(), SkipBody);
5413 EnumAvailabilityDiags.back().done();
5415 EnumConstantDecls.push_back(EnumConstDecl);
5416 LastEnumConstDecl = EnumConstDecl;
5418 if (Tok.
is(tok::identifier)) {
5421 Diag(
Loc, diag::err_enumerator_list_missing_comma)
5444 if (Tok.
is(tok::r_brace) && CommaLoc.
isValid()) {
5447 diag::ext_enumerator_list_comma_cxx :
5448 diag::ext_enumerator_list_comma_c)
5451 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5462 MaybeParseGNUAttributes(attrs);
5468 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5469 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5471 EnumAvailabilityDiags[i].redelay();
5472 PD.complete(EnumConstantDecls[i]);
5481 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5482 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5491bool Parser::isKnownToBeTypeSpecifier(
const Token &Tok)
const {
5493 default:
return false;
5497 case tok::kw___int64:
5498 case tok::kw___int128:
5499 case tok::kw_signed:
5500 case tok::kw_unsigned:
5501 case tok::kw__Complex:
5502 case tok::kw__Imaginary:
5505 case tok::kw_wchar_t:
5506 case tok::kw_char8_t:
5507 case tok::kw_char16_t:
5508 case tok::kw_char32_t:
5510 case tok::kw__ExtInt:
5511 case tok::kw__BitInt:
5512 case tok::kw___bf16:
5515 case tok::kw_double:
5516 case tok::kw__Accum:
5517 case tok::kw__Fract:
5518 case tok::kw__Float16:
5519 case tok::kw___float128:
5520 case tok::kw___ibm128:
5523 case tok::kw__Decimal32:
5524 case tok::kw__Decimal64:
5525 case tok::kw__Decimal128:
5526 case tok::kw___vector:
5527#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5528#include "clang/Basic/OpenCLImageTypes.def"
5529#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5530#include "clang/Basic/HLSLIntangibleTypes.def"
5534 case tok::kw_struct:
5535 case tok::kw___interface:
5541 case tok::annot_typename:
5546bool Parser::isTypeSpecifierQualifier() {
5548 default:
return false;
5550 case tok::identifier:
5551 if (TryAltiVecVectorToken())
5554 case tok::kw_typename:
5559 if (Tok.
is(tok::identifier))
5561 return isTypeSpecifierQualifier();
5563 case tok::coloncolon:
5570 return isTypeSpecifierQualifier();
5573 case tok::kw___attribute:
5575 case tok::kw_typeof:
5576 case tok::kw_typeof_unqual:
5581 case tok::kw___int64:
5582 case tok::kw___int128:
5583 case tok::kw_signed:
5584 case tok::kw_unsigned:
5585 case tok::kw__Complex:
5586 case tok::kw__Imaginary:
5589 case tok::kw_wchar_t:
5590 case tok::kw_char8_t:
5591 case tok::kw_char16_t:
5592 case tok::kw_char32_t:
5594 case tok::kw__ExtInt:
5595 case tok::kw__BitInt:
5597 case tok::kw___bf16:
5599 case tok::kw_double:
5600 case tok::kw__Accum:
5601 case tok::kw__Fract:
5602 case tok::kw__Float16:
5603 case tok::kw___float128:
5604 case tok::kw___ibm128:
5607 case tok::kw__Decimal32:
5608 case tok::kw__Decimal64:
5609 case tok::kw__Decimal128:
5610 case tok::kw___vector:
5611#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5612#include "clang/Basic/OpenCLImageTypes.def"
5613#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5614#include "clang/Basic/HLSLIntangibleTypes.def"
5618 case tok::kw_struct:
5619 case tok::kw___interface:
5626 case tok::kw_volatile:
5627 case tok::kw_restrict:
5631 case tok::kw___unknown_anytype:
5634 case tok::annot_typename:
5641 case tok::kw___cdecl:
5642 case tok::kw___stdcall:
5643 case tok::kw___fastcall:
5644 case tok::kw___thiscall:
5645 case tok::kw___regcall:
5646 case tok::kw___vectorcall:
5648 case tok::kw___ptr64:
5649 case tok::kw___ptr32:
5650 case tok::kw___pascal:
5651 case tok::kw___unaligned:
5652 case tok::kw___ptrauth:
5654 case tok::kw__Nonnull:
5655 case tok::kw__Nullable:
5656 case tok::kw__Nullable_result:
5657 case tok::kw__Null_unspecified:
5659 case tok::kw___kindof:
5661 case tok::kw___private:
5662 case tok::kw___local:
5663 case tok::kw___global:
5664 case tok::kw___constant:
5665 case tok::kw___generic:
5666 case tok::kw___read_only:
5667 case tok::kw___read_write:
5668 case tok::kw___write_only:
5669 case tok::kw___funcref:
5672 case tok::kw_private:
5676 case tok::kw__Atomic:
5680 case tok::kw_groupshared:
5693 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5697 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5702 if (Tok.
is(tok::annot_repl_input_end) &&
5704 ConsumeAnnotationToken();
5709 DeclsInGroup.push_back(TLSD);
5712 for (
Stmt *S : Stmts) {
5717 DeclsInGroup.push_back(
D);
5723bool Parser::isDeclarationSpecifier(
5725 bool DisambiguatingWithExpression) {
5727 default:
return false;
5734 case tok::identifier:
5738 if (TryAltiVecVectorToken())
5741 case tok::kw_decltype:
5742 case tok::kw_typename:
5747 if (TryAnnotateTypeConstraint())
5749 if (Tok.
is(tok::identifier))
5757 if (DisambiguatingWithExpression &&
5758 isStartOfObjCClassMessageMissingOpenBracket())
5761 return isDeclarationSpecifier(AllowImplicitTypename);
5763 case tok::coloncolon:
5777 case tok::kw_typedef:
5778 case tok::kw_extern:
5779 case tok::kw___private_extern__:
5780 case tok::kw_static:
5782 case tok::kw___auto_type:
5783 case tok::kw_register:
5784 case tok::kw___thread:
5785 case tok::kw_thread_local:
5786 case tok::kw__Thread_local:
5789 case tok::kw___module_private__:
5792 case tok::kw___unknown_anytype:
5797 case tok::kw___int64:
5798 case tok::kw___int128:
5799 case tok::kw_signed:
5800 case tok::kw_unsigned:
5801 case tok::kw__Complex:
5802 case tok::kw__Imaginary:
5805 case tok::kw_wchar_t:
5806 case tok::kw_char8_t:
5807 case tok::kw_char16_t:
5808 case tok::kw_char32_t:
5811 case tok::kw__ExtInt:
5812 case tok::kw__BitInt:
5814 case tok::kw___bf16:
5816 case tok::kw_double:
5817 case tok::kw__Accum:
5818 case tok::kw__Fract:
5819 case tok::kw__Float16:
5820 case tok::kw___float128:
5821 case tok::kw___ibm128:
5824 case tok::kw__Decimal32:
5825 case tok::kw__Decimal64:
5826 case tok::kw__Decimal128:
5827 case tok::kw___vector:
5831 case tok::kw_struct:
5833 case tok::kw___interface:
5839 case tok::kw_volatile:
5840 case tok::kw_restrict:
5844 case tok::kw_inline:
5845 case tok::kw_virtual:
5846 case tok::kw_explicit:
5847 case tok::kw__Noreturn:
5850 case tok::kw__Alignas:
5853 case tok::kw_friend:
5856 case tok::kw_static_assert:
5857 case tok::kw__Static_assert:
5860 case tok::kw_typeof:
5861 case tok::kw_typeof_unqual:
5864 case tok::kw___attribute:
5867 case tok::annot_decltype:
5868 case tok::annot_pack_indexing_type:
5869 case tok::kw_constexpr:
5872 case tok::kw_consteval:
5873 case tok::kw_constinit:
5876 case tok::kw__Atomic:
5879 case tok::kw_alignas:
5889 case tok::annot_typename:
5890 return !DisambiguatingWithExpression ||
5891 !isStartOfObjCClassMessageMissingOpenBracket();
5894 case tok::annot_template_id: {
5900 return isTypeConstraintAnnotation() &&
5904 case tok::annot_cxxscope: {
5913 if (
NextToken().is(tok::identifier) && TryAnnotateTypeConstraint())
5915 return isTypeConstraintAnnotation() &&
5919 case tok::kw___declspec:
5920 case tok::kw___cdecl:
5921 case tok::kw___stdcall:
5922 case tok::kw___fastcall:
5923 case tok::kw___thiscall:
5924 case tok::kw___regcall:
5925 case tok::kw___vectorcall:
5927 case tok::kw___sptr:
5928 case tok::kw___uptr:
5929 case tok::kw___ptr64:
5930 case tok::kw___ptr32:
5931 case tok::kw___forceinline:
5932 case tok::kw___pascal:
5933 case tok::kw___unaligned:
5934 case tok::kw___ptrauth:
5936 case tok::kw__Nonnull:
5937 case tok::kw__Nullable:
5938 case tok::kw__Nullable_result:
5939 case tok::kw__Null_unspecified:
5941 case tok::kw___kindof:
5943 case tok::kw___private:
5944 case tok::kw___local:
5945 case tok::kw___global:
5946 case tok::kw___constant:
5947 case tok::kw___generic:
5948 case tok::kw___read_only:
5949 case tok::kw___read_write:
5950 case tok::kw___write_only:
5951#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5952#include "clang/Basic/OpenCLImageTypes.def"
5953#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5954#include "clang/Basic/HLSLIntangibleTypes.def"
5956 case tok::kw___funcref:
5957 case tok::kw_groupshared:
5960 case tok::kw_private:
5965bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
5967 const ParsedTemplateInfo *TemplateInfo) {
5968 RevertingTentativeParsingAction TPA(*
this);
5971 if (TemplateInfo && TemplateInfo->TemplateParams)
5974 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
5981 if (Tok.
is(tok::identifier)) {
5985 }
else if (Tok.
is(tok::annot_template_id)) {
5986 ConsumeAnnotationToken();
5993 SkipCXX11Attributes();
5996 if (Tok.
isNot(tok::l_paren)) {
6003 if (Tok.
is(tok::r_paren) ||
6004 (Tok.
is(tok::ellipsis) &&
NextToken().is(tok::r_paren))) {
6011 isCXX11AttributeSpecifier(
false,
6018 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6020 DeclScopeObj.EnterDeclaratorScope();
6024 MaybeParseMicrosoftAttributes(Attrs);
6033 bool IsConstructor =
false;
6039 if (Tok.
is(tok::kw_this)) {
6041 return isDeclarationSpecifier(ITC);
6044 if (isDeclarationSpecifier(ITC))
6045 IsConstructor =
true;
6046 else if (Tok.
is(tok::identifier) ||
6047 (Tok.
is(tok::annot_cxxscope) &&
NextToken().is(tok::identifier))) {
6052 if (Tok.
is(tok::annot_cxxscope))
6053 ConsumeAnnotationToken();
6065 case tok::coloncolon:
6078 SkipCXX11Attributes();
6080 if (DeductionGuide) {
6082 IsConstructor = Tok.
is(tok::arrow);
6085 if (Tok.
is(tok::colon) || Tok.
is(tok::kw_try)) {
6089 IsConstructor =
true;
6091 if (Tok.
is(tok::semi) || Tok.
is(tok::l_brace)) {
6104 IsConstructor = IsUnqualified;
6109 IsConstructor =
true;
6113 return IsConstructor;
6116void Parser::ParseTypeQualifierListOpt(
6117 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicOrPtrauthAllowed,
6119 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6120 isAllowedCXX11AttributeSpecifier()) {
6122 ParseCXX11Attributes(Attrs);
6130 const char *PrevSpec =
nullptr;
6131 unsigned DiagID = 0;
6135 case tok::code_completion:
6147 case tok::kw_volatile:
6151 case tok::kw_restrict:
6155 case tok::kw__Atomic:
6156 if (!AtomicOrPtrauthAllowed)
6157 goto DoneWithTypeQuals;
6158 diagnoseUseOfC11Keyword(Tok);
6164 case tok::kw_private:
6166 goto DoneWithTypeQuals;
6168 case tok::kw___private:
6169 case tok::kw___global:
6170 case tok::kw___local:
6171 case tok::kw___constant:
6172 case tok::kw___generic:
6173 case tok::kw___read_only:
6174 case tok::kw___write_only:
6175 case tok::kw___read_write:
6179 case tok::kw_groupshared:
6188 case tok::kw___ptrauth:
6189 if (!AtomicOrPtrauthAllowed)
6190 goto DoneWithTypeQuals;
6192 EndLoc = PrevTokLocation;
6195 case tok::kw___unaligned:
6199 case tok::kw___uptr:
6204 if (TryKeywordIdentFallback(
false))
6208 case tok::kw___sptr:
6210 case tok::kw___ptr64:
6211 case tok::kw___ptr32:
6212 case tok::kw___cdecl:
6213 case tok::kw___stdcall:
6214 case tok::kw___fastcall:
6215 case tok::kw___thiscall:
6216 case tok::kw___regcall:
6217 case tok::kw___vectorcall:
6218 if (AttrReqs & AR_DeclspecAttributesParsed) {
6222 goto DoneWithTypeQuals;
6224 case tok::kw___funcref:
6228 case tok::kw___pascal:
6229 if (AttrReqs & AR_VendorAttributesParsed) {
6233 goto DoneWithTypeQuals;
6236 case tok::kw__Nonnull:
6237 case tok::kw__Nullable:
6238 case tok::kw__Nullable_result:
6239 case tok::kw__Null_unspecified:
6244 case tok::kw___kindof:
6251 case tok::kw___attribute:
6252 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6254 Diag(Tok, diag::err_attributes_not_allowed);
6258 if (AttrReqs & AR_GNUAttributesParsed ||
6259 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6277 assert(PrevSpec &&
"Method did not return previous specifier!");
6278 Diag(Tok, DiagID) << PrevSpec;
6288 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6294 if (Kind == tok::star || Kind == tok::caret)
6298 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6299 Lang.getOpenCLCompatibleVersion() >= 200)
6302 if (!Lang.CPlusPlus)
6305 if (Kind == tok::amp)
6313 if (Kind == tok::ampamp)
6322 const unsigned NumTypes =
D.getNumTypeObjects();
6324 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6331void Parser::ParseDeclaratorInternal(
Declarator &
D,
6332 DirectDeclParseFunction DirectDeclParser) {
6340 (Tok.
is(tok::coloncolon) || Tok.
is(tok::kw_decltype) ||
6341 (Tok.
is(tok::identifier) &&
6343 Tok.
is(tok::annot_cxxscope))) {
6344 TentativeParsingAction TPA(*
this,
true);
6350 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6360 Tok.
is(tok::star)) {
6364 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6365 CompoundToken::MemberPtr);
6369 D.SetRangeEnd(StarLoc);
6371 ParseTypeQualifierListOpt(DS);
6372 D.ExtendWithDeclSpec(DS);
6376 ParseDeclaratorInternal(D, DirectDeclParser);
6390 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6397 if (
D.mayHaveIdentifier())
6398 D.getCXXScopeSpec() = SS;
6400 AnnotateScopeToken(SS,
true);
6402 if (DirectDeclParser)
6403 (this->*DirectDeclParser)(
D);
6412 ParseTypeQualifierListOpt(DS);
6421 if (DirectDeclParser)
6422 (this->*DirectDeclParser)(
D);
6431 if (Kind == tok::star || Kind == tok::caret) {
6437 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6439 ? AR_GNUAttributesParsed
6440 : AR_GNUAttributesParsedAndRejected);
6441 ParseTypeQualifierListOpt(DS, Reqs,
true,
6442 !
D.mayOmitIdentifier());
6443 D.ExtendWithDeclSpec(DS);
6447 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6448 if (Kind == tok::star)
6466 if (Kind == tok::ampamp)
6468 diag::warn_cxx98_compat_rvalue_reference :
6469 diag::ext_rvalue_reference);
6472 ParseTypeQualifierListOpt(DS);
6473 D.ExtendWithDeclSpec(DS);
6481 diag::err_invalid_reference_qualifier_application) <<
"const";
6484 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6488 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6493 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6495 if (
D.getNumTypeObjects() > 0) {
6500 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6503 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6525 if (
D.getName().StartLocation.isInvalid() &&
6526 D.getName().EndLocation.isValid())
6527 return D.getName().EndLocation;
6532void Parser::ParseDirectDeclarator(
Declarator &
D) {
6533 DeclaratorScopeObj DeclScopeObj(*
this,
D.getCXXScopeSpec());
6537 if (Tok.
is(tok::l_square) && !
D.mayOmitIdentifier() &&
6538 D.getCXXScopeSpec().isEmpty())
6539 return ParseDecompositionDeclarator(
D);
6550 if (
D.getCXXScopeSpec().isEmpty()) {
6553 ParseOptionalCXXScopeSpecifier(
6554 D.getCXXScopeSpec(),
nullptr,
6555 false, EnteringContext);
6569 if (
D.getCXXScopeSpec().isValid()) {
6571 D.getCXXScopeSpec()))
6574 DeclScopeObj.EnterDeclaratorScope();
6579 D.setInvalidType(
true);
6581 goto PastIdentifier;
6592 if (Tok.
is(tok::ellipsis) &&
D.getCXXScopeSpec().isEmpty() &&
6596 NextToken().is(tok::r_paren) && !
D.hasGroupingParens() &&
6598 D.getDeclSpec().getTypeSpecType() !=
TST_auto)) {
6605 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc,
D);
6608 D.setEllipsisLoc(EllipsisLoc);
6615 if (Tok.
isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6619 bool AllowConstructorName;
6620 bool AllowDeductionGuide;
6621 if (
D.getDeclSpec().hasTypeSpecifier()) {
6622 AllowConstructorName =
false;
6623 AllowDeductionGuide =
false;
6624 }
else if (
D.getCXXScopeSpec().isSet()) {
6627 AllowDeductionGuide =
false;
6634 bool HadScope =
D.getCXXScopeSpec().isValid();
6640 true, AllowConstructorName,
6641 AllowDeductionGuide, &TemplateKWLoc,
6645 D.getCXXScopeSpec().isInvalid()) {
6647 D.setInvalidType(
true);
6651 if (!HadScope &&
D.getCXXScopeSpec().isValid() &&
6653 D.getCXXScopeSpec()))
6654 DeclScopeObj.EnterDeclaratorScope();
6661 goto PastIdentifier;
6664 if (
D.getCXXScopeSpec().isNotEmpty()) {
6667 diag::err_expected_unqualified_id)
6670 goto PastIdentifier;
6672 }
else if (Tok.
is(tok::identifier) &&
D.mayHaveIdentifier()) {
6674 "There's a C++-specific check for tok::identifier above");
6679 goto PastIdentifier;
6680 }
else if (Tok.
is(tok::identifier) && !
D.mayHaveIdentifier()) {
6684 bool DiagnoseIdentifier =
false;
6685 if (
D.hasGroupingParens())
6688 DiagnoseIdentifier =
true;
6691 DiagnoseIdentifier =
6699 !isCXX11VirtSpecifier(Tok))
6701 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6702 if (DiagnoseIdentifier) {
6707 goto PastIdentifier;
6711 if (Tok.
is(tok::l_paren)) {
6715 if (
D.mayOmitIdentifier() &&
D.mayBeFollowedByCXXDirectInit()) {
6716 RevertingTentativeParsingAction PA(*
this);
6717 if (TryParseDeclarator(
true,
D.mayHaveIdentifier(),
true,
6718 D.getDeclSpec().getTypeSpecType() ==
TST_auto) ==
6721 goto PastIdentifier;
6728 ParseParenDeclarator(
D);
6733 if (
D.getCXXScopeSpec().isSet()) {
6736 if (!
D.isInvalidType() &&
6738 D.getCXXScopeSpec()))
6741 DeclScopeObj.EnterDeclaratorScope();
6743 }
else if (
D.mayOmitIdentifier()) {
6750 if (
D.hasEllipsis() &&
D.hasGroupingParens())
6752 diag::ext_abstract_pack_declarator_parens);
6754 if (Tok.
getKind() == tok::annot_pragma_parser_crash)
6756 if (Tok.
is(tok::l_square))
6757 return ParseMisplacedBracketDeclarator(
D);
6765 diag::err_expected_member_name_or_semi_objcxx_keyword)
6772 goto PastIdentifier;
6775 diag::err_expected_member_name_or_semi)
6779 if (Tok.
getKind() == tok::TokenKind::kw_while) {
6780 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6782 if (Tok.
isOneOf(tok::period, tok::arrow))
6783 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.
is(tok::arrow);
6791 diag::err_expected_unqualified_id)
6796 diag::err_expected_either)
6797 << tok::identifier << tok::l_paren;
6801 D.setInvalidType(
true);
6805 assert(
D.isPastIdentifier() &&
6806 "Haven't past the location of the identifier yet?");
6809 if (
D.hasName() && !
D.getNumTypeObjects())
6810 MaybeParseCXX11Attributes(
D);
6813 if (Tok.
is(tok::l_paren)) {
6814 bool IsFunctionDeclaration =
D.isFunctionDeclaratorAFunctionDeclaration();
6817 ParseScope PrototypeScope(
this,
6819 (IsFunctionDeclaration
6825 bool IsAmbiguous =
false;
6836 if (
D.getCXXScopeSpec().isSet())
6837 AllowImplicitTypename =
6845 TentativelyDeclaredIdentifiers.push_back(
D.getIdentifier());
6846 bool IsFunctionDecl =
6847 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
6848 TentativelyDeclaredIdentifiers.pop_back();
6849 if (!IsFunctionDecl)
6855 if (IsFunctionDeclaration)
6857 TemplateParameterDepth);
6858 ParseFunctionDeclarator(
D, attrs,
T, IsAmbiguous);
6859 if (IsFunctionDeclaration)
6861 PrototypeScope.Exit();
6862 }
else if (Tok.
is(tok::l_square)) {
6863 ParseBracketDeclarator(
D);
6871 if (!
T.consumeOpen())
6874 }
else if (Tok.
is(tok::kw_requires) &&
D.hasGroupingParens()) {
6882 Diag(Tok, diag::err_requires_clause_inside_parens);
6886 if (TrailingRequiresClause.
isUsable() &&
D.isFunctionDeclarator() &&
6887 !
D.hasTrailingRequiresClause())
6889 D.setTrailingRequiresClause(TrailingRequiresClause.
get());
6896void Parser::ParseDecompositionDeclarator(
Declarator &
D) {
6897 assert(Tok.
is(tok::l_square));
6899 TentativeParsingAction PA(*
this);
6904 DiagnoseAndSkipCXX11Attributes();
6908 if (!(Tok.
isOneOf(tok::identifier, tok::ellipsis) &&
6910 tok::identifier, tok::l_square, tok::ellipsis)) &&
6911 !(Tok.
is(tok::r_square) &&
6914 return ParseMisplacedBracketDeclarator(
D);
6919 while (Tok.
isNot(tok::r_square)) {
6921 if (Tok.
is(tok::comma))
6924 if (Tok.
is(tok::identifier)) {
6926 Diag(EndLoc, diag::err_expected)
6929 Diag(Tok, diag::err_expected_comma_or_rsquare);
6932 SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis},
6934 if (Tok.
is(tok::comma))
6936 else if (Tok.
is(tok::r_square))
6941 if (isCXX11AttributeSpecifier() !=
6943 DiagnoseAndSkipCXX11Attributes();
6947 if (Tok.
is(tok::ellipsis)) {
6949 : diag::ext_cxx_binding_pack);
6950 if (PrevEllipsisLoc.
isValid()) {
6951 Diag(Tok, diag::err_binding_multiple_ellipses);
6952 Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
6956 PrevEllipsisLoc = EllipsisLoc;
6960 if (Tok.
isNot(tok::identifier)) {
6961 Diag(Tok, diag::err_expected) << tok::identifier;
6969 if (Tok.
is(tok::ellipsis) && !PrevEllipsisLoc.
isValid()) {
6977 if (isCXX11AttributeSpecifier() !=
6980 ? diag::warn_cxx23_compat_decl_attrs_on_binding
6981 : diag::ext_decl_attrs_on_binding);
6982 MaybeParseCXX11Attributes(Attrs);
6985 Bindings.push_back({II,
Loc, std::move(Attrs), EllipsisLoc});
6988 if (Tok.
isNot(tok::r_square))
7002 return D.setDecompositionBindings(
T.getOpenLocation(),
Bindings,
7003 T.getCloseLocation());
7010 assert(!
D.isPastIdentifier() &&
"Should be called before passing identifier");
7023 bool RequiresArg =
false;
7024 if (Tok.
is(tok::kw___attribute)) {
7025 ParseGNUAttributes(attrs);
7033 ParseMicrosoftTypeAttributes(attrs);
7036 if (Tok.
is(tok::kw___pascal))
7037 ParseBorlandTypeAttributes(attrs);
7045 if (!
D.mayOmitIdentifier()) {
7049 }
else if (Tok.
is(tok::r_paren) ||
7051 Tok.
is(tok::ellipsis) &&
7053 isDeclarationSpecifier(
7055 isCXX11AttributeSpecifier() !=
7073 bool hadGroupingParens =
D.hasGroupingParens();
7074 D.setGroupingParens(
true);
7075 ParseDeclaratorInternal(
D, &Parser::ParseDirectDeclarator);
7080 std::move(attrs),
T.getCloseLocation());
7082 D.setGroupingParens(hadGroupingParens);
7086 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc,
D);
7099 ParseScope PrototypeScope(
this,
7101 (
D.isFunctionDeclaratorAFunctionDeclaration()
7103 ParseFunctionDeclarator(
D, attrs,
T,
false, RequiresArg);
7104 PrototypeScope.Exit();
7107void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7109 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7117 bool IsCXX11MemberFunction =
7121 ? !
D.getDeclSpec().isFriendSpecified()
7123 D.getCXXScopeSpec().isValid() &&
7125 if (!IsCXX11MemberFunction)
7145 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.
CurContext), Q,
7146 IsCXX11MemberFunction);
7149void Parser::ParseFunctionDeclarator(
Declarator &
D,
7154 assert(
getCurScope()->isFunctionPrototypeScope() &&
7155 "Should call from a Function scope");
7157 assert(
D.isPastIdentifier() &&
"Should not call before identifier!");
7161 bool HasProto =
false;
7168 bool RefQualifierIsLValueRef =
true;
7186 StartLoc = LParenLoc;
7188 if (isFunctionDeclaratorIdentifierList()) {
7190 Diag(Tok, diag::err_argument_required_after_attribute);
7192 ParseFunctionDeclaratorIdentifierList(
D, ParamInfo);
7196 LocalEndLoc = RParenLoc;
7201 MaybeParseCXX11Attributes(FnAttrs);
7202 ProhibitAttributes(FnAttrs);
7204 if (Tok.
isNot(tok::r_paren))
7205 ParseParameterDeclarationClause(
D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7206 else if (RequiresArg)
7207 Diag(Tok, diag::err_argument_required_after_attribute);
7218 LocalEndLoc = RParenLoc;
7227 ParseTypeQualifierListOpt(
7228 DS, AR_NoAttributesParsed,
7238 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7239 EndLoc = RefQualifierLoc;
7241 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7242 InitCXXThisScopeForDeclaratorIfRelevant(
D, DS, ThisScope);
7258 D.isFunctionDeclaratorAFunctionDeclaration();
7276 ESpecType = tryParseExceptionSpecification(Delayed,
7279 DynamicExceptionRanges,
7281 ExceptionSpecTokens);
7283 EndLoc = ESpecRange.
getEnd();
7287 MaybeParseCXX11Attributes(FnAttrs);
7290 LocalEndLoc = EndLoc;
7292 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7293 if (
D.getDeclSpec().getTypeSpecType() ==
TST_auto)
7294 StartLoc =
D.getDeclSpec().getTypeSpecTypeLoc();
7297 TrailingReturnType =
7298 ParseTrailingReturnType(
Range,
D.mayBeFollowedByCXXDirectInit());
7303 MaybeParseCXX11Attributes(FnAttrs);
7315 if (!ND || isa<ParmVarDecl>(ND))
7317 DeclsInPrototype.push_back(ND);
7324 llvm::sort(DeclsInPrototype, [](
Decl *D1,
Decl *D2) {
7332 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7333 ParamInfo.size(), EllipsisLoc, RParenLoc,
7334 RefQualifierIsLValueRef, RefQualifierLoc,
7336 ESpecType, ESpecRange, DynamicExceptions.data(),
7337 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7338 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7339 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7340 LocalEndLoc,
D, TrailingReturnType, TrailingReturnTypeLoc,
7342 std::move(FnAttrs), EndLoc);
7345bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7347 if (Tok.
isOneOf(tok::amp, tok::ampamp)) {
7349 diag::warn_cxx98_compat_ref_qualifier :
7350 diag::ext_ref_qualifier);
7352 RefQualifierIsLValueRef = Tok.
is(tok::amp);
7359bool Parser::isFunctionDeclaratorIdentifierList() {
7361 && Tok.
is(tok::identifier)
7362 && !TryAltiVecVectorToken()
7378 && (!Tok.
is(tok::eof) &&
7382void Parser::ParseFunctionDeclaratorIdentifierList(
7386 assert(!
getLangOpts().requiresStrictPrototypes() &&
7387 "Cannot parse an identifier list in C23 or C++");
7393 if (!
D.getIdentifier())
7394 Diag(Tok, diag::ext_ident_list_in_param);
7401 if (Tok.
isNot(tok::identifier)) {
7402 Diag(Tok, diag::err_expected) << tok::identifier;
7413 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7416 if (!ParamsSoFar.insert(ParmII).second) {
7417 Diag(Tok, diag::err_param_redefinition) << ParmII;
7431void Parser::ParseParameterDeclarationClause(
7440 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7461 IsACXXFunctionDeclaration) {
7483 ArgDeclSpecAttrs.takeAllFrom(FirstArgAttrs);
7486 MaybeParseCXX11Attributes(ArgDeclAttrs);
7489 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7500 ParsedTemplateInfo TemplateInfo;
7501 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7502 DeclSpecContext::DSC_normal,
7503 nullptr, AllowImplicitTypename);
7516 ParseDeclarator(ParmDeclarator);
7519 ParmDeclarator.SetRangeBegin(ThisLoc);
7522 MaybeParseGNUAttributes(ParmDeclarator);
7526 if (Tok.
is(tok::kw_requires)) {
7531 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7541 std::unique_ptr<CachedTokens> DefArgToks;
7545 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7546 ParmDeclarator.getNumTypeObjects() == 0) {
7548 Diag(DSStart, diag::err_missing_param);
7555 if (Tok.
is(tok::ellipsis) &&
7557 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7560 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7579 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7592 Diag(ParmDeclarator.getBeginLoc(),
7593 diag::err_function_parameter_limit_exceeded);
7606 if (Tok.
is(tok::equal)) {
7617 ConsumeAndStoreInitializer(*DefArgToks,
7634 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7635 DefArgResult = ParseBraceInitializer();
7637 if (Tok.
is(tok::l_paren) &&
NextToken().is(tok::l_brace)) {
7638 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7654 DefArgResult.
get());
7660 ParmDeclarator.getIdentifierLoc(),
7661 Param, std::move(DefArgToks)));
7669 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
7676 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7678 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7683 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7684 << ParmEllipsis.
isValid() << ParmEllipsis;
7687 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7689 Diag(ParmDeclarator.getIdentifierLoc(),
7690 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7693 << !ParmDeclarator.hasName();
7695 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7707void Parser::ParseBracketDeclarator(
Declarator &
D) {
7708 if (CheckProhibitedCXX11Attribute())
7716 if (Tok.
getKind() == tok::r_square) {
7719 MaybeParseCXX11Attributes(attrs);
7723 T.getOpenLocation(),
7724 T.getCloseLocation()),
7725 std::move(attrs),
T.getCloseLocation());
7727 }
else if (Tok.
getKind() == tok::numeric_constant &&
7735 MaybeParseCXX11Attributes(attrs);
7739 T.getOpenLocation(),
7740 T.getCloseLocation()),
7741 std::move(attrs),
T.getCloseLocation());
7743 }
else if (Tok.
getKind() == tok::code_completion) {
7756 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
7764 bool isStar =
false;
7775 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7779 }
else if (Tok.
isNot(tok::r_square)) {
7796 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7803 D.setInvalidType(
true);
7816 isStar, NumElements.
get(),
T.getOpenLocation(),
7817 T.getCloseLocation()),
7821void Parser::ParseMisplacedBracketDeclarator(
Declarator &
D) {
7822 assert(Tok.
is(tok::l_square) &&
"Missing opening bracket");
7823 assert(!
D.mayOmitIdentifier() &&
"Declarator cannot omit identifier");
7829 while (Tok.
is(tok::l_square)) {
7830 ParseBracketDeclarator(TempDeclarator);
7836 if (Tok.
is(tok::semi))
7837 D.getName().EndLocation = StartBracketLoc;
7842 ParseDeclaratorInternal(
D, &Parser::ParseDirectDeclarator);
7847 if (TempDeclarator.getNumTypeObjects() == 0)
7851 bool NeedParens =
false;
7852 if (
D.getNumTypeObjects() != 0) {
7853 switch (
D.getTypeObject(
D.getNumTypeObjects() - 1).
Kind) {
7876 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
7878 D.AddTypeInfo(Chunk, TempDeclarator.getAttributePool(),
SourceLocation());
7883 if (!
D.hasName() && !NeedParens)
7889 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
7893 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7901 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7909void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
7910 assert(Tok.
isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
7911 "Not a typeof specifier");
7913 bool IsUnqual = Tok.
is(tok::kw_typeof_unqual);
7920 bool HasParens = Tok.
is(tok::l_paren);
7930 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);
7946 const char *PrevSpec =
nullptr;
7954 Diag(StartLoc, DiagID) << PrevSpec;
7971 const char *PrevSpec =
nullptr;
7979 Diag(StartLoc, DiagID) << PrevSpec;
7982void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
7983 assert(Tok.
is(tok::kw__Atomic) &&
NextToken().is(tok::l_paren) &&
7984 "Not an atomic specifier");
7988 if (
T.consumeOpen())
7992 if (
Result.isInvalid()) {
8000 if (
T.getCloseLocation().isInvalid())
8006 const char *PrevSpec =
nullptr;
8011 Diag(StartLoc, DiagID) << PrevSpec;
8014bool Parser::TryAltiVecVectorTokenOutOfLine() {
8016 switch (Next.getKind()) {
8017 default:
return false;
8020 case tok::kw_signed:
8021 case tok::kw_unsigned:
8026 case tok::kw_double:
8029 case tok::kw___bool:
8030 case tok::kw___pixel:
8031 Tok.
setKind(tok::kw___vector);
8033 case tok::identifier:
8034 if (Next.getIdentifierInfo() == Ident_pixel) {
8035 Tok.
setKind(tok::kw___vector);
8038 if (Next.getIdentifierInfo() == Ident_bool ||
8039 Next.getIdentifierInfo() == Ident_Bool) {
8040 Tok.
setKind(tok::kw___vector);
8048 const char *&PrevSpec,
unsigned &DiagID,
8053 switch (Next.getKind()) {
8056 case tok::kw_signed:
8057 case tok::kw_unsigned:
8062 case tok::kw_double:
8065 case tok::kw___bool:
8066 case tok::kw___pixel:
8069 case tok::identifier:
8070 if (Next.getIdentifierInfo() == Ident_pixel) {
8074 if (Next.getIdentifierInfo() == Ident_bool ||
8075 Next.getIdentifierInfo() == Ident_Bool) {
8096TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8103 FileID FID = SourceMgr.createFileID(
8104 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8108 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8109 L.setParsingPreprocessorDirective(
true);
8115 Tokens.push_back(Tok);
8116 }
while (Tok.
isNot(tok::eod));
8121 Token &EndToken = Tokens.back();
8128 Tokens.push_back(Tok);
8131 PP.EnterTokenStream(Tokens,
false,
8139 ParseScope LocalScope(
this, 0);
8152 while (Tok.
isNot(tok::eof))
8156 if (Tok.
is(tok::eof) && Tok.
getEofData() == TypeStr.data())
8161void Parser::DiagnoseBitIntUse(
const Token &Tok) {
8165 assert(Tok.
isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8166 "expected either an _ExtInt or _BitInt token!");
8169 if (Tok.
is(tok::kw__ExtInt)) {
8170 Diag(
Loc, diag::warn_ext_int_deprecated)
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
static StringRef normalizeAttrName(StringRef AttrName, StringRef NormalizedScopeName, AttributeCommonInfo::Syntax SyntaxUsed)
static Decl::Kind getKind(const Decl *D)
Defines the C++ template declaration subclasses.
llvm::MachO::RecordLoc RecordLoc
static bool IsAttributeLateParsedExperimentalExt(const IdentifierInfo &II)
returns true iff attribute is annotated with LateAttrParseExperimentalExt in Attr....
static bool FindLocsWithCommonFileID(Preprocessor &PP, SourceLocation StartLoc, SourceLocation EndLoc)
Check if the a start and end source location expand to the same macro.
static bool IsAttributeLateParsedStandard(const IdentifierInfo &II)
returns true iff attribute is annotated with LateAttrParseStandard in Attr.td.
static ParsedAttributeArgumentsProperties attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has string arguments.
static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute takes a strict identifier argument.
static bool attributeIsTypeArgAttr(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute parses a type argument.
static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute treats kw_this as an identifier.
static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute requires parsing its arguments in an unevaluated context or not...
static bool attributeHasIdentifierArg(const llvm::Triple &T, const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has an identifier argument.
static bool isValidAfterIdentifierInDeclarator(const Token &T)
isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the specified token is valid after t...
static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has a variadic identifier argument.
static bool isPipeDeclarator(const Declarator &D)
static SourceLocation getMissingDeclaratorIdLoc(Declarator &D, SourceLocation Loc)
static bool attributeAcceptsExprPack(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine if an attribute accepts parameter packs.
static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS, Parser &P)
static bool VersionNumberSeparator(const char Separator)
static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, DeclaratorContext TheContext)
llvm::SmallVector< std::pair< const MemRegion *, SVal >, 4 > Bindings
static constexpr bool isOneOf()
This file declares semantic analysis for CUDA constructs.
This file declares facilities that support code completion.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenMP constructs and clauses.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the clang::TokenKind enum and support functions.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const clang::PrintingPolicy & getPrintingPolicy() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
The result of parsing/analyzing an expression, statement etc.
Syntax
The style used to specify an attribute.
@ AS_Declspec
__declspec(...)
Kind getParsedKind() const
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
SourceLocation getOpenLocation() const
SourceLocation getCloseLocation() const
Represents a C++ nested-name-specifier or a global scope specifier.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
SourceLocation getEndLoc() const
bool isSet() const
Deprecated.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
void setTemplateParamLists(ArrayRef< TemplateParameterList * > L)
bool isEmpty() const
No scope specifier.
Represents a character-granular source range.
SourceLocation getBegin() const
Callback handler that receives notifications when performing code completion within the preprocessor.
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed.
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Captures information about "declaration specifiers".
bool isVirtualSpecified() const
bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, ExplicitSpecifier ExplicitSpec, SourceLocation CloseParenLoc)
bool isTypeSpecPipe() const
static const TSCS TSCS___thread
static const TST TST_typeof_unqualType
void setTypeArgumentRange(SourceRange range)
bool SetTypePipe(bool isPipe, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
SourceLocation getPipeLoc() const
static const TST TST_typename
SourceLocation getEndLoc() const LLVM_READONLY
bool hasTypeSpecifier() const
Return true if any type-specifier has been found.
bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec and return false if there was no error.
static const TST TST_char8
static const TST TST_BFloat16
void ClearStorageClassSpecs()
bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TSCS TSCS__Thread_local
bool SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec, but return true and ignore the request if ...
bool isNoreturnSpecified() const
TST getTypeSpecType() const
SourceLocation getStorageClassSpecLoc() const
SCS getStorageClassSpec() const
bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceRange getSourceRange() const LLVM_READONLY
bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void SetRangeEnd(SourceLocation Loc)
bool SetBitIntType(SourceLocation KWLoc, Expr *BitWidth, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_auto_type
static const TST TST_interface
static const TST TST_double
static const TST TST_typeofExpr
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
void SetRangeStart(SourceLocation Loc)
bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getNoreturnSpecLoc() const
static const TST TST_union
static const TST TST_char
static const TST TST_bool
static const TST TST_char16
SourceLocation getExplicitSpecLoc() const
SourceLocation getFriendSpecLoc() const
SourceLocation getModulePrivateSpecLoc() const
bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void UpdateTypeRep(ParsedType Rep)
TSCS getThreadStorageClassSpec() const
bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasAttributes() const
static const TST TST_accum
static const TST TST_half
ParsedAttributes & getAttributes()
SourceLocation getConstSpecLoc() const
static const TST TST_ibm128
void addAttributes(const ParsedAttributesView &AL)
Concatenates two attribute lists.
static const TST TST_enum
bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_float128
void Finish(Sema &S, const PrintingPolicy &Policy)
Finish - This does final analysis of the declspec, issuing diagnostics for things like "_Complex" (la...
bool isInlineSpecified() const
SourceLocation getRestrictSpecLoc() const
static const TST TST_typeof_unqualExpr
static const TST TST_class
bool hasTagDefinition() const
static const TST TST_decimal64
unsigned getParsedSpecifiers() const
Return a bitmask of which flavors of specifiers this DeclSpec includes.
void ClearFunctionSpecs()
bool SetTypeQual(TQ T, SourceLocation Loc)
static const TST TST_wchar
static const TST TST_void
bool isTypeAltiVecVector() const
void ClearConstexprSpec()
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
static const TST TST_float
static const TST TST_atomic
static const TST TST_fract
SourceLocation getThreadStorageClassSpecLoc() const
Decl * getRepAsDecl() const
static const TST TST_float16
static const TST TST_unspecified
SourceLocation getAtomicSpecLoc() const
SourceLocation getVirtualSpecLoc() const
SourceLocation getConstexprSpecLoc() const
CXXScopeSpec & getTypeSpecScope()
bool isEmpty() const
isEmpty - Return true if this declaration specifier is completely empty: no tokens were parsed in the...
static const TSCS TSCS_thread_local
bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal32
bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
TypeSpecifierWidth getTypeSpecWidth() const
static const TST TST_char32
bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal128
bool isTypeSpecOwned() const
SourceLocation getInlineSpecLoc() const
SourceLocation getUnalignedSpecLoc() const
static const TST TST_int128
SourceLocation getVolatileSpecLoc() const
FriendSpecified isFriendSpecified() const
bool hasExplicitSpecifier() const
bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasConstexprSpecifier() const
void takeAttributesFrom(ParsedAttributes &attrs)
static const TST TST_typeofType
bool SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_auto
@ PQ_StorageClassSpecifier
ConstexprSpecKind getConstexprSpecifier() const
static const TST TST_struct
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
Kind
Lists the kind of concrete classes of Decl.
bool isInvalidDecl() const
SourceLocation getLocation() const
SourceLocation getBeginLoc() const LLVM_READONLY
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Information about one declarator, including the parsed type information and the identifier.
bool isInvalidType() const
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
bool hasAllExtensionsSilenced()
RAII object that enters a new expression evaluation context.
Store information needed for an explicit specifier.
This represents one expression.
ExtensionRAIIObject - This saves the state of extension warnings when constructed and disables them.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code from FromRange at a specific location.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
bool isCPlusPlusKeyword(const LangOptions &LangOpts) const
Return true if this token is a C++ keyword in the specified language.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
void revertTokenIDToIdentifier()
Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2 compatibility.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
SourceLocation getLoc() const
void setIdentifierInfo(IdentifierInfo *Ident)
IdentifierInfo * getIdentifierInfo() const
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool requiresStrictPrototypes() const
Returns true if functions without prototypes or functions with an identifier list (aka K&R C function...
std::string getOpenCLVersionString() const
Return the OpenCL C or C++ for OpenCL language name and version as a string.
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static bool isAtStartOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroBegin=nullptr)
Returns true if the given MacroID location points at the first token of the macro expansion.
static bool isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroEnd=nullptr)
Returns true if the given MacroID location points at the last token of the macro expansion.
static std::optional< Token > findNextToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeComments=false)
Finds the token that comes right after the given location.
static bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, const LangOptions &LangOpts, bool IgnoreWhiteSpace=false)
Relex the token at the specified location.
Represents the results of name lookup.
This represents a decl that may have a name.
bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...
Represents a parameter to a function.
static constexpr unsigned getMaxFunctionScopeDepth()
ParsedAttr - Represents a syntactic attribute.
unsigned getMaxArgs() const
static const ParsedAttributesView & none()
void addAtEnd(ParsedAttr *newAttr)
void addAll(iterator B, iterator E)
void remove(ParsedAttr *ToBeRemoved)
ParsedAttributes - A collection of parsed attributes.
void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA)
ParsedAttr * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Form formUsed)
Add microsoft __delspec(property) attribute.
ParsedAttr * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ParsedType typeArg, ParsedAttr::Form formUsed, SourceLocation ellipsisLoc=SourceLocation())
Add an attribute with a single type argument.
void takeAllFrom(ParsedAttributes &Other)
ParsedAttr * addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, ParsedAttr::Form form)
Add type_tag_for_datatype attribute.
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
Parser - This implements a parser for the C family of languages.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation getEndOfPreviousToken() const
DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagId)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Sema & getActions() const
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
ExprResult ParseConstantExpressionInExprEvalContext(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
DeclGroupPtrTy ParseOpenACCDirectiveDecl(AccessSpecifier &AS, ParsedAttributes &Attrs, DeclSpec::TST TagType, Decl *TagDecl)
Parse OpenACC directive on a declaration.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
const Token & GetLookAheadToken(unsigned N)
GetLookAheadToken - This peeks ahead N tokens and returns that token without consuming any tokens.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
Scope * getCurScope() const
ExprResult ParseArrayBoundExpression()
const TargetInfo & getTargetInfo() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
friend class ObjCDeclContextSwitch
const LangOptions & getLangOpts() const
ExprResult ParseExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtCodeCompletion
Stop at code completion.
@ StopAtSemi
Stop skipping at semicolon.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
ExprResult ParseUnevaluatedStringLiteralExpression()
ObjCContainerDecl * getObjCDeclContext() const
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
SmallVector< TemplateParameterList *, 4 > TemplateParameterLists
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
RAII object used to inform the actions that we're currently parsing a declaration.
A class for parsing a DeclSpec.
A class for parsing a declarator.
A class for parsing a field declarator.
void enterVariableInit(SourceLocation Tok, Decl *D)
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool isIncrementalProcessingEnabled() const
Returns true if incremental processing is enabled.
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
const LangOptions & getLangOpts() const
bool isCodeCompletionReached() const
Returns true if code-completion is enabled and we have hit the code-completion point.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
PrettyDeclStackTraceEntry - If a crash occurs in the parser while parsing something related to a decl...
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
The collection of all-type qualifiers we support.
void addAddressSpace(LangAS space)
static Qualifiers fromCVRUMask(unsigned CVRU)
Represents a struct/union/class.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isClassScope() const
isClassScope - Return true if this scope is a class/struct/union scope.
unsigned getFlags() const
getFlags - Return the flags for this scope.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ BlockScope
This is a scope that corresponds to a block/closure object.
@ FriendScope
This is a scope of friend declaration.
@ ControlScope
The controlling scope in a if/switch/while/for statement.
@ AtCatchScope
This is a scope that corresponds to the Objective-C @catch statement.
@ TemplateParamScope
This is a scope that corresponds to the template parameters of a C++ template.
@ CompoundStmtScope
This is a compound statement scope.
@ ClassScope
The scope of a struct/union/class definition.
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ EnumScope
This scope corresponds to an enum.
@ DeclScope
This is a scope that can contain a declaration.
@ CTCK_InitGlobalVar
Unknown context.
void CodeCompleteAttribute(AttributeCommonInfo::Syntax Syntax, AttributeCompletion Completion=AttributeCompletion::Attribute, const IdentifierInfo *Scope=nullptr)
ParserCompletionContext
Describes the context in which code completion occurs.
@ PCC_LocalDeclarationSpecifiers
Code completion occurs within a sequence of declaration specifiers within a function,...
@ PCC_MemberTemplate
Code completion occurs following one or more template headers within a class.
@ PCC_Class
Code completion occurs within a class, struct, or union.
@ PCC_ObjCImplementation
Code completion occurs within an Objective-C implementation or category implementation.
@ PCC_Namespace
Code completion occurs at top-level or namespace context.
@ PCC_Template
Code completion occurs following one or more template headers.
void CodeCompleteTypeQualifiers(DeclSpec &DS)
void CodeCompleteAfterFunctionEquals(Declarator &D)
QualType ProduceConstructorSignatureHelp(QualType Type, SourceLocation Loc, ArrayRef< Expr * > Args, SourceLocation OpenParLoc, bool Braced)
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
void CodeCompleteInitializer(Scope *S, Decl *D)
void CodeCompleteBracketDeclarator(Scope *S)
void CodeCompleteTag(Scope *S, unsigned TagSpec)
void CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, bool AllowNonIdentifiers, bool AllowNestedNameSpecifiers)
ParsedType ActOnObjCInstanceType(SourceLocation Loc)
The parser has parsed the context-sensitive type 'instancetype' in an Objective-C message declaration...
void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, const IdentifierInfo *ClassName, SmallVectorImpl< Decl * > &Decls)
Called whenever @defs(ClassName) is encountered in the source.
void startOpenMPCXXRangeFor()
If the current region is a range loop-based region, mark the start of the loop construct.
NameClassificationKind getKind() const
bool containsUnexpandedParameterPacks(Declarator &D)
Determine whether the given declarator contains any unexpanded parameter packs.
void ActOnParamUnparsedDefaultArgument(Decl *param, SourceLocation EqualLoc, SourceLocation ArgLoc)
ActOnParamUnparsedDefaultArgument - We've seen a default argument for a function parameter,...
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
void ActOnDefinedDeclarationSpecifier(Decl *D)
Called once it is known whether a tag declaration is an anonymous union or struct.
ExplicitSpecifier ActOnExplicitBoolSpecifier(Expr *E)
ActOnExplicitBoolSpecifier - Build an ExplicitSpecifier from an expression found in an explicit(bool)...
void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc, Expr *DefaultArg)
ActOnParamDefaultArgumentError - Parsing or semantic analysis of the default argument for the paramet...
Decl * ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant, SourceLocation IdLoc, IdentifierInfo *Id, const ParsedAttributesView &Attrs, SourceLocation EqualLoc, Expr *Val, SkipBodyInfo *SkipBody=nullptr)
TemplateParameterList * ActOnTemplateParameterList(unsigned Depth, SourceLocation ExportLoc, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
ActOnTemplateParameterList - Builds a TemplateParameterList, optionally constrained by RequiresClause...
void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl, SourceRange BraceRange)
ActOnTagFinishDefinition - Invoked once we have finished parsing the definition of a tag (enumeration...
Decl * ActOnParamDeclarator(Scope *S, Declarator &D, SourceLocation ExplicitThisLoc={})
ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator() to introduce parameters into fun...
TypeResult ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, const CXXScopeSpec &SS, const IdentifierInfo *Name, SourceLocation TagLoc, SourceLocation NameLoc)
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
Decl * ActOnTemplateDeclarator(Scope *S, MultiTemplateParamsArg TemplateParameterLists, Declarator &D)
TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S)
isTagName() - This method is called for error recovery purposes only to determine if the specified na...
void ActOnFinishFunctionDeclarationDeclarator(Declarator &D)
Called after parsing a function declarator belonging to a function declaration.
void ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc, Expr *defarg)
ActOnParamDefaultArgument - Check whether the default argument provided for a function parameter is w...
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
void ActOnFinishTopLevelStmtDecl(TopLevelStmtDecl *D, Stmt *Statement)
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param)
This is used to implement the constant expression evaluation part of the attribute enable_if extensio...
ASTContext & getASTContext() const
bool isCurrentClassName(const IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS=nullptr)
isCurrentClassName - Determine whether the identifier II is the name of the class type currently bein...
void ActOnStartFunctionDeclarationDeclarator(Declarator &D, unsigned TemplateParameterDepth)
Called before parsing a function declarator belonging to a function declaration.
ExprResult ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val)
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
SkipBodyInfo shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II, SourceLocation IILoc)
Determine whether the body of an anonymous enumeration should be skipped.
const LangOptions & getLangOpts() const
SemaCodeCompletion & CodeCompletion()
bool isUnexpandedParameterPackPermitted()
Determine whether an unexpanded parameter pack might be permitted in this location.
bool ActOnAlignasTypeArgument(StringRef KWName, ParsedType Ty, SourceLocation OpLoc, SourceRange R)
ActOnAlignasTypeArgument - Handle alignas(type-id) and _Alignas(type-name) .
bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, UnexpandedParameterPackContext UPPC)
If the given type contains an unexpanded parameter pack, diagnose the error.
bool ActOnDuplicateDefinition(Scope *S, Decl *Prev, SkipBodyInfo &SkipBody)
Perform ODR-like check for C/ObjC when merging tag types from modules.
bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS)
NameClassification ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, SourceLocation NameLoc, const Token &NextToken, CorrectionCandidateCallback *CCC=nullptr)
Perform name lookup on the given name, classifying it based on the results of name lookup and the fol...
StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)
bool isLibstdcxxEagerExceptionSpecHack(const Declarator &D)
Determine if we're in a case where we need to (incorrectly) eagerly parse an exception specification ...
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
bool isDeclaratorFunctionLike(Declarator &D)
Determine whether.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
void RestoreNestedNameSpecifierAnnotation(void *Annotation, SourceRange AnnotationRange, CXXScopeSpec &SS)
Given an annotation pointer for a nested-name-specifier, restore the nested-name-specifier structure.
bool CheckTypeConstraint(TemplateIdAnnotation *TypeConstraint)
void ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, Decl *EnumDecl, ArrayRef< Decl * > Elements, Scope *S, const ParsedAttributesView &Attr)
void ActOnTagStartDefinition(Scope *S, Decl *TagDecl)
ActOnTagStartDefinition - Invoked when we have entered the scope of a tag's definition (e....
void ActOnInitializerError(Decl *Dcl)
ActOnInitializerError - Given that there was an error parsing an initializer for the given declaratio...
TypeResult ActOnTypeName(Declarator &D)
TopLevelStmtDecl * ActOnStartTopLevelStmtDecl(Scope *S)
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion.
void DiagnoseUnknownAttribute(const ParsedAttr &AL)
DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, ArrayRef< Decl * > Group)
ParsedType ActOnMSVCUnknownTypeName(const IdentifierInfo &II, SourceLocation NameLoc, bool IsTemplateTypeArg)
Attempt to behave like MSVC in situations where lookup of an unqualified type name has failed in a de...
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type.
DeclResult ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc, SourceLocation TemplateLoc, unsigned TagSpec, SourceLocation KWLoc, const CXXScopeSpec &SS, TemplateTy Template, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, const ParsedAttributesView &Attr)
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
@ PotentiallyEvaluatedIfUsed
The current expression is potentially evaluated, but any declarations referenced inside that expressi...
DeclResult ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, const ParsedAttributesView &Attr, AccessSpecifier AS, SourceLocation ModulePrivateLoc, MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl, bool &IsDependent, SourceLocation ScopedEnumKWLoc, bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, bool IsTypeSpecifier, bool IsTemplateParamOrArg, OffsetOfKind OOK, SkipBodyInfo *SkipBody=nullptr)
This is invoked when we see 'struct foo' or 'struct {'.
Decl * ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, const ParsedAttributesView &DeclAttrs, RecordDecl *&AnonRecord)
ParsedFreeStandingDeclSpec - This method is invoked when a declspec with no declarator (e....
void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl, ArrayRef< Decl * > Fields, SourceLocation LBrac, SourceLocation RBrac, const ParsedAttributesView &AttrList)
SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts
A stack of expression evaluation contexts.
bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name, SourceLocation NameLoc, CXXScopeSpec &SS, ParsedTemplateTy *Template=nullptr)
Determine whether a particular identifier might be the name in a C++1z deduction-guide declaration.
OpenCLOptions & getOpenCLOptions()
void ActOnFinishDelayedAttribute(Scope *S, Decl *D, ParsedAttributes &Attrs)
ActOnFinishDelayedAttribute - Invoked when we have finished parsing an attribute for which parsing is...
void ActOnUninitializedDecl(Decl *dcl)
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
Decl * ActOnField(Scope *S, Decl *TagD, SourceLocation DeclStart, Declarator &D, Expr *BitfieldWidth)
ActOnField - Each field of a C struct/union is passed into this in order to create a FieldDecl object...
void ActOnCXXForRangeDecl(Decl *D)
Decl * ActOnDeclarator(Scope *S, Declarator &D)
ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope=nullptr)
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
void DiagnoseUnknownTypeName(IdentifierInfo *&II, SourceLocation IILoc, Scope *S, CXXScopeSpec *SS, ParsedType &SuggestedType, bool IsTemplateName=false)
ExprResult HandleExprEvaluationContextForTypeof(Expr *E)
bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS)
Determine whether the identifier II is a typo for the name of the class type currently being defined.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
A RAII object used to temporarily suppress access-like checking.
Represents the declaration of a struct/union/class/enum.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getEndLoc() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
const char * getName() const
unsigned getLength() const
void setKind(tok::TokenKind K)
SourceLocation getAnnotationEndLoc() const
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
void * getAnnotationValue() const
tok::TokenKind getKind() const
bool isRegularKeywordAttribute() const
Return true if the token is a keyword that is parsed in the same position as a standard attribute,...
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool isOneOf(Ts... Ks) const
void setEofData(const void *D)
SourceRange getAnnotationRange() const
SourceRange of the group of tokens that this annotation token represents.
void setLocation(SourceLocation L)
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
const void * getEofData() const
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
void startToken()
Reset all flags to cleared.
void setIdentifierInfo(IdentifierInfo *II)
A declaration that models statements at global scope.
void setSemiMissing(bool Missing=true)
Base wrapper for a particular "section" of type source info.
The base class of the type hierarchy.
static constexpr int FunctionTypeNumParamsLimit
The iterator over UnresolvedSets.
Declaration of a variable template.
static const char * getSpecifierName(Specifier VS)
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
bool InitScope(InterpState &S, CodePtr OpPC, uint32_t I)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isPragmaAnnotation(TokenKind K)
Return true if this is an annotation token representing a pragma.
The JSON file list parser is used to communicate input to InstallAPI.
TypeSpecifierType
Specifies the kind of type.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
@ NotAttributeSpecifier
This is not an attribute specifier.
@ AttributeSpecifier
This should be treated as an attribute-specifier.
@ InvalidAttributeSpecifier
The next tokens are '[[', but this is not an attribute-specifier.
@ ExpectedParameterOrImplicitObjectParameter
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
@ IK_TemplateId
A template-id, e.g., f<int>.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Language
The language for the input, used to select and validate the language standard and possible actions.
@ Result
The result type of a method or function.
@ Template
We are parsing a template declaration.
@ ExplicitSpecialization
We are parsing an explicit specialization.
@ ExplicitInstantiation
We are parsing an explicit instantiation.
@ NonTemplate
We are not parsing a template at all.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
@ FunctionTemplate
The name was classified as a function template name.
@ Keyword
The name has been typo-corrected to a keyword.
@ DependentNonType
The name denotes a member of a dependent type that could not be resolved.
@ UndeclaredTemplate
The name was classified as an ADL-only function template name.
@ NonType
The name was classified as a specific non-type, non-template declaration.
@ Unknown
This name is not a type or template in this context, but might be something else.
@ Error
Classification failed; an error has been produced.
@ Type
The name was classified as a type.
@ TypeTemplate
The name was classified as a template whose specializations are types.
@ Concept
The name was classified as a concept name.
@ OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ UndeclaredNonType
The name was classified as an ADL-only function name.
@ VarTemplate
The name was classified as a variable template name.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Dependent_template_name
The name refers to a dependent template name:
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &&Second)
Consumes the attributes from Second and concatenates them at the end of First.
@ Parens
New-expression has a C++98 paren-delimited initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_None
no exception specification
Represents information about a change in availability for an entity, which is part of the encoding of...
VersionTuple Version
The version number at which the change occurred.
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
SourceRange VersionRange
The source range covering the version number.
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
ParamInfo - An array of paraminfo objects is allocated whenever a function declarator is parsed.
One instance of this struct is used for each type in a declarator that is parsed.
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, ArrayRef< NamedDecl * > DeclsInPrototype, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult(), SourceLocation TrailingReturnTypeLoc=SourceLocation(), DeclSpec *MethodQualifiers=nullptr)
DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
static DeclaratorChunk getPipe(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc)
Return a DeclaratorChunk for an array.
SourceLocation Loc
Loc - The place where this type was defined.
static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, unsigned TypeQuals, SourceLocation StarLoc, SourceLocation EndLoc)
enum clang::DeclaratorChunk::@211 Kind
static DeclaratorChunk getParen(SourceLocation LParenLoc, SourceLocation RParenLoc)
Return a DeclaratorChunk for a paren.
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, SourceLocation AtomicQualLoc, SourceLocation UnalignedQualLoc)
Return a DeclaratorChunk for a pointer.
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, bool lvalue)
Return a DeclaratorChunk for a reference.
bool isStringLiteralArg(unsigned I) const
Describes how types, statements, expressions, and declarations should be printed.
bool InLifetimeExtendingContext
Whether we are currently in a context in which all temporaries must be lifetime-extended,...
ExpressionKind
Describes whether we are in an expression constext which we have to handle differently.
Information about a template-id annotation token.
bool hasInvalidName() const
const IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
TemplateNameKind Kind
The kind of template that Template refers to.
bool hasInvalidArgs() const