34#include "llvm/ADT/SmallSet.h"
35#include "llvm/ADT/SmallString.h"
36#include "llvm/ADT/StringSwitch.h"
53 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
54 if (DSC == DeclSpecContext::DSC_normal)
55 DSC = DeclSpecContext::DSC_type_specifier;
61 ParseSpecifierQualifierList(DS, AS, DSC);
69 if (AL.isDeclspecAttribute())
70 ToBeMoved.push_back(&AL);
79 ParseDeclarator(DeclaratorInfo);
91 if (Name.size() >= 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
92 return Name.drop_front(2).drop_back(2);
99#define CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
101#include "clang/Parse/AttrParserStringSwitches.inc"
103#undef CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
109#define CLANG_ATTR_LATE_PARSED_LIST
111#include "clang/Parse/AttrParserStringSwitches.inc"
113#undef CLANG_ATTR_LATE_PARSED_LIST
123 if (
SM.getFileID(StartLoc) !=
SM.getFileID(EndLoc))
126 bool AttrStartIsInMacro =
128 bool AttrEndIsInMacro =
130 return AttrStartIsInMacro && AttrEndIsInMacro;
133void Parser::ParseAttributes(
unsigned WhichAttrKinds,
ParsedAttributes &Attrs,
134 LateParsedAttrList *LateAttrs) {
140 if (WhichAttrKinds & PAKM_CXX11)
141 MoreToParse |= MaybeParseCXX11Attributes(Attrs);
142 if (WhichAttrKinds & PAKM_GNU)
143 MoreToParse |= MaybeParseGNUAttributes(Attrs, LateAttrs);
144 if (WhichAttrKinds & PAKM_Declspec)
145 MoreToParse |= MaybeParseMicrosoftDeclSpecs(Attrs);
146 }
while (MoreToParse);
191 LateParsedAttrList *LateAttrs,
Declarator *D) {
192 assert(Tok.
is(tok::kw___attribute) &&
"Not a GNU attribute list!");
197 while (Tok.
is(tok::kw___attribute)) {
199 unsigned OldNumAttrs = Attrs.
size();
200 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
202 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
207 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"(")) {
220 if (Tok.
is(tok::code_completion)) {
232 if (Tok.
isNot(tok::l_paren)) {
233 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
234 ParsedAttr::Form::GNU());
238 bool LateParse =
false;
241 else if (LateAttrs->lateAttrParseExperimentalExtOnly()) {
245 LateParse =
getLangOpts().ExperimentalLateParseAttributes &&
258 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc,
nullptr,
264 LateParsedAttribute *LA =
265 new LateParsedAttribute(
this, *AttrName, AttrNameLoc);
266 LateAttrs->push_back(LA);
270 if (!ClassStack.empty() && !LateAttrs->parseSoon())
271 getCurrentClass().LateParsedDeclarations.push_back(LA);
275 LA->Toks.push_back(Tok);
278 ConsumeAndStoreUntil(tok::r_paren, LA->Toks,
true);
283 LA->Toks.push_back(Eof);
284 }
while (Tok.
is(tok::comma));
286 if (ExpectAndConsume(tok::r_paren))
289 if (ExpectAndConsume(tok::r_paren))
296 if (!
SM.isWrittenInBuiltinFile(
SM.getSpellingLoc(AttrTokLoc)) &&
299 StringRef FoundName =
303 for (
unsigned i = OldNumAttrs; i < Attrs.
size(); ++i)
304 Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.
getBegin());
307 for (
unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
308 (*LateAttrs)[i]->MacroII = MacroII;
318#define CLANG_ATTR_IDENTIFIER_ARG_LIST
320#include "clang/Parse/AttrParserStringSwitches.inc"
322#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
328#define CLANG_ATTR_STRING_LITERAL_ARG_LIST
330#include "clang/Parse/AttrParserStringSwitches.inc"
332#undef CLANG_ATTR_STRING_LITERAL_ARG_LIST
337#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
339#include "clang/Parse/AttrParserStringSwitches.inc"
341#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
346#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
348#include "clang/Parse/AttrParserStringSwitches.inc"
350#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
355#define CLANG_ATTR_ACCEPTS_EXPR_PACK
357#include "clang/Parse/AttrParserStringSwitches.inc"
359#undef CLANG_ATTR_ACCEPTS_EXPR_PACK
364#define CLANG_ATTR_TYPE_ARG_LIST
366#include "clang/Parse/AttrParserStringSwitches.inc"
368#undef CLANG_ATTR_TYPE_ARG_LIST
374#define CLANG_ATTR_ARG_CONTEXT_LIST
376#include "clang/Parse/AttrParserStringSwitches.inc"
378#undef CLANG_ATTR_ARG_CONTEXT_LIST
382 assert(Tok.
is(tok::identifier) &&
"expected an identifier");
400 if (Tok.
isNot(tok::r_paren))
403 if (
Parens.consumeClose())
412 ScopeName, ScopeLoc,
T.get(), Form);
415 ScopeName, ScopeLoc,
nullptr, 0, Form);
419Parser::ParseUnevaluatedStringInAttribute(
const IdentifierInfo &AttrName) {
420 if (Tok.
is(tok::l_paren)) {
423 ExprResult Res = ParseUnevaluatedStringInAttribute(AttrName);
424 Paren.consumeClose();
427 if (!isTokenStringLiteral()) {
435bool Parser::ParseAttributeArgumentList(
438 bool SawError =
false;
443 Expr = ParseUnevaluatedStringInAttribute(AttrName);
445 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
446 Expr = ParseBraceInitializer();
452 if (Tok.
is(tok::ellipsis))
454 else if (Tok.
is(tok::code_completion)) {
465 if (
Expr.isInvalid()) {
470 Exprs.push_back(
Expr.get());
472 if (Tok.
isNot(tok::comma))
477 checkPotentialAngleBracketDelimiter(Comma);
484 for (
auto &E : Exprs) {
493unsigned Parser::ParseAttributeArgsCommon(
502 bool AttributeHasVariadicIdentifierArg =
506 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
510 if (Tok.
is(tok::identifier)) {
512 bool IsIdentifierArg = AttributeHasVariadicIdentifierArg ||
522 IsIdentifierArg = Next.isOneOf(tok::r_paren, tok::comma);
526 ArgExprs.push_back(ParseIdentifierLoc());
530 if (!ArgExprs.empty() ? Tok.
is(tok::comma) : Tok.
isNot(tok::r_paren)) {
532 if (!ArgExprs.empty())
535 if (AttributeIsTypeArgAttr) {
543 TheParsedType =
T.get();
544 }
else if (AttributeHasVariadicIdentifierArg) {
552 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
556 if (Tok.
is(tok::identifier)) {
557 ArgExprs.push_back(ParseIdentifierLoc());
572 ArgExprs.push_back(ArgExpr.
get());
584 ExprVector ParsedExprs;
587 if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties)) {
593 for (
size_t I = 0; I < ParsedExprs.size(); ++I) {
594 if (!isa<PackExpansionExpr>(ParsedExprs[I]))
599 diag::err_attribute_argument_parm_pack_not_supported)
606 ArgExprs.insert(ArgExprs.end(), ParsedExprs.begin(), ParsedExprs.end());
611 if (!ExpectAndConsume(tok::r_paren)) {
614 if (AttributeIsTypeArgAttr && !TheParsedType.
get().
isNull()) {
616 ScopeName, ScopeLoc, TheParsedType, Form);
619 ArgExprs.data(), ArgExprs.size(), Form);
626 return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.
get().
isNull());
631void Parser::ParseGNUAttributeArgs(
636 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
641 if (AttrKind == ParsedAttr::AT_Availability) {
642 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
645 }
else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
646 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
647 ScopeName, ScopeLoc, Form);
649 }
else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
650 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
651 ScopeName, ScopeLoc, Form);
653 }
else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
654 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
657 }
else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
658 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
659 ScopeName, ScopeLoc, Form);
662 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName,
665 }
else if (AttrKind == ParsedAttr::AT_CountedBy) {
666 ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
673 std::optional<ParseScope> PrototypeScope;
680 for (
unsigned i = 0; i != FTI.
NumParams; ++i) {
686 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
690unsigned Parser::ParseClangAttributeArgs(
694 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
701 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
702 ScopeName, ScopeLoc, Form);
703 case ParsedAttr::AT_ExternalSourceSymbol:
704 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
705 ScopeName, ScopeLoc, Form);
707 case ParsedAttr::AT_Availability:
708 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
711 case ParsedAttr::AT_ObjCBridgeRelated:
712 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
713 ScopeName, ScopeLoc, Form);
715 case ParsedAttr::AT_SwiftNewType:
716 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
719 case ParsedAttr::AT_TypeTagForDatatype:
720 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
721 ScopeName, ScopeLoc, Form);
724 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
730 unsigned ExistingAttrs = Attrs.
size();
744 if (AttrName->
getName() ==
"property") {
750 T.expectAndConsume(diag::err_expected_lparen_after,
759 bool HasInvalidAccessor =
false;
764 if (!Tok.
is(tok::identifier)) {
766 if (Tok.
is(tok::r_paren) && !HasInvalidAccessor &&
767 AccessorNames[AK_Put] ==
nullptr &&
768 AccessorNames[AK_Get] ==
nullptr) {
769 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
780 if (KindStr ==
"get") {
782 }
else if (KindStr ==
"put") {
786 }
else if (KindStr ==
"set") {
787 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
794 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
796 HasInvalidAccessor =
true;
797 goto next_property_accessor;
801 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
802 HasInvalidAccessor =
true;
821 if (!Tok.
is(tok::identifier)) {
826 if (Kind == AK_Invalid) {
828 }
else if (AccessorNames[Kind] !=
nullptr) {
830 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
836 next_property_accessor:
842 if (Tok.
is(tok::r_paren))
845 Diag(Tok.
getLocation(), diag::err_ms_property_expected_comma_or_rparen);
850 if (!HasInvalidAccessor)
852 AccessorNames[AK_Get], AccessorNames[AK_Put],
853 ParsedAttr::Form::Declspec());
855 return !HasInvalidAccessor;
859 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
865 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) << AttrName;
878 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
879 assert(Tok.
is(tok::kw___declspec) &&
"Not a declspec!");
884 while (Tok.
is(tok::kw___declspec)) {
887 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
893 while (Tok.
isNot(tok::r_paren)) {
898 if (Tok.
is(tok::code_completion)) {
907 bool IsString = Tok.
getKind() == tok::string_literal;
908 if (!IsString && Tok.
getKind() != tok::identifier &&
909 Tok.
getKind() != tok::kw_restrict) {
910 Diag(Tok, diag::err_ms_declspec_type);
920 StringRef Str = PP.
getSpelling(Tok, StrBuffer, &Invalid);
926 AttrNameLoc = ConsumeStringToken();
932 bool AttrHandled =
false;
935 if (Tok.
is(tok::l_paren))
936 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
937 else if (AttrName->
getName() ==
"property")
943 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
944 ParsedAttr::Form::Declspec());
947 EndLoc =
T.getCloseLocation();
958 case tok::kw___fastcall:
959 case tok::kw___stdcall:
960 case tok::kw___thiscall:
961 case tok::kw___regcall:
962 case tok::kw___cdecl:
963 case tok::kw___vectorcall:
964 case tok::kw___ptr64:
966 case tok::kw___ptr32:
968 case tok::kw___uptr: {
971 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
982 assert(Tok.
is(tok::kw___funcref));
986 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
992 attrs.
addNew(AttrName, AttrNameLoc,
nullptr,
997void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
1003 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) <<
Range;
1013 case tok::kw_volatile:
1014 case tok::kw___fastcall:
1015 case tok::kw___stdcall:
1016 case tok::kw___thiscall:
1017 case tok::kw___cdecl:
1018 case tok::kw___vectorcall:
1019 case tok::kw___ptr32:
1020 case tok::kw___ptr64:
1022 case tok::kw___unaligned:
1023 case tok::kw___sptr:
1024 case tok::kw___uptr:
1035 while (Tok.
is(tok::kw___pascal)) {
1038 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1045 while (Tok.
is(tok::kw___kernel)) {
1048 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1054 while (Tok.
is(tok::kw___noinline__)) {
1057 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1058 tok::kw___noinline__);
1065 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1069bool Parser::isHLSLQualifier(
const Token &Tok)
const {
1070 return Tok.
is(tok::kw_groupshared);
1077 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0, Kind);
1085 case tok::kw__Nonnull:
1086 case tok::kw__Nullable:
1087 case tok::kw__Nullable_result:
1088 case tok::kw__Null_unspecified: {
1092 Diag(AttrNameLoc, diag::ext_nullability)
1094 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1105 return (Separator ==
'.' || Separator ==
'_');
1119 if (!Tok.
is(tok::numeric_constant)) {
1120 Diag(Tok, diag::err_expected_version);
1123 return VersionTuple();
1132 const char *ThisTokBegin = &Buffer[0];
1136 unsigned ActualLength = PP.
getSpelling(Tok, ThisTokBegin, &Invalid);
1138 return VersionTuple();
1141 unsigned AfterMajor = 0;
1143 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
1144 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
1148 if (AfterMajor == 0) {
1149 Diag(Tok, diag::err_expected_version);
1152 return VersionTuple();
1155 if (AfterMajor == ActualLength) {
1160 Diag(Tok, diag::err_zero_version);
1161 return VersionTuple();
1164 return VersionTuple(Major);
1167 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1169 || (AfterMajor + 1 == ActualLength)) {
1170 Diag(Tok, diag::err_expected_version);
1173 return VersionTuple();
1177 unsigned AfterMinor = AfterMajor + 1;
1179 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
1180 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
1184 if (AfterMinor == ActualLength) {
1188 if (Major == 0 && Minor == 0) {
1189 Diag(Tok, diag::err_zero_version);
1190 return VersionTuple();
1193 return VersionTuple(Major, Minor);
1196 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1199 Diag(Tok, diag::err_expected_version);
1202 return VersionTuple();
1206 if (AfterMajorSeparator != AfterMinorSeparator)
1207 Diag(Tok, diag::warn_expected_consistent_version_separator);
1210 unsigned AfterSubminor = AfterMinor + 1;
1211 unsigned Subminor = 0;
1212 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
1213 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
1217 if (AfterSubminor != ActualLength) {
1218 Diag(Tok, diag::err_expected_version);
1221 return VersionTuple();
1224 return VersionTuple(Major, Minor, Subminor);
1252void Parser::ParseAvailabilityAttribute(
1256 enum { Introduced, Deprecated, Obsoleted,
Unknown };
1263 if (
T.consumeOpen()) {
1264 Diag(Tok, diag::err_expected) << tok::l_paren;
1269 if (Tok.
isNot(tok::identifier)) {
1270 Diag(Tok, diag::err_availability_expected_platform);
1277 if (Ident->getName().contains(
"xrOS") || Ident->getName().contains(
"xros"))
1278 Diag(Platform->
Loc, diag::warn_availability_unknown_platform) << Ident;
1280 else if (Ident->getName() ==
"macosx")
1284 else if (Ident->getName() ==
"macosx_app_extension")
1288 AvailabilityAttr::canonicalizePlatformName(Ident->getName()));
1292 if (ExpectAndConsume(tok::comma)) {
1299 if (!Ident_introduced) {
1314 if (Tok.
isNot(tok::identifier)) {
1315 Diag(Tok, diag::err_availability_expected_change);
1322 if (Keyword == Ident_strict) {
1324 Diag(KeywordLoc, diag::err_availability_redundant)
1327 StrictLoc = KeywordLoc;
1331 if (Keyword == Ident_unavailable) {
1332 if (UnavailableLoc.
isValid()) {
1333 Diag(KeywordLoc, diag::err_availability_redundant)
1336 UnavailableLoc = KeywordLoc;
1340 if (Keyword == Ident_deprecated && Platform->
Ident &&
1343 if (Changes[Deprecated].KeywordLoc.
isValid()) {
1344 Diag(KeywordLoc, diag::err_availability_redundant)
1351 Changes[Deprecated].
Version = VersionTuple(1);
1355 if (Keyword == Ident_environment) {
1356 if (EnvironmentLoc !=
nullptr) {
1357 Diag(KeywordLoc, diag::err_availability_redundant)
1362 if (Tok.
isNot(tok::equal)) {
1363 Diag(Tok, diag::err_expected_after) << Keyword << tok::equal;
1368 if (Keyword == Ident_message || Keyword == Ident_replacement) {
1369 if (!isTokenStringLiteral()) {
1370 Diag(Tok, diag::err_expected_string_literal)
1375 if (Keyword == Ident_message) {
1383 if (Keyword == Ident_environment) {
1384 if (Tok.
isNot(tok::identifier)) {
1385 Diag(Tok, diag::err_availability_expected_environment);
1389 EnvironmentLoc = ParseIdentifierLoc();
1395 if ((Keyword == Ident_introduced || Keyword == Ident_deprecated) &&
1396 Tok.
is(tok::identifier)) {
1400 if (Keyword == Ident_introduced)
1401 UnavailableLoc = KeywordLoc;
1407 VersionTuple Version = ParseVersionTuple(VersionRange);
1409 if (Version.empty()) {
1415 if (Keyword == Ident_introduced)
1417 else if (Keyword == Ident_deprecated)
1419 else if (Keyword == Ident_obsoleted)
1425 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1426 Diag(KeywordLoc, diag::err_availability_redundant)
1429 Changes[Index].VersionRange.
getEnd());
1433 Changes[Index].
Version = Version;
1436 Diag(KeywordLoc, diag::err_availability_unknown_change)
1437 << Keyword << VersionRange;
1443 if (
T.consumeClose())
1447 *endLoc =
T.getCloseLocation();
1451 if (UnavailableLoc.
isValid()) {
1452 bool Complained =
false;
1453 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1454 if (Changes[Index].KeywordLoc.
isValid()) {
1456 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1458 Changes[Index].VersionRange.
getEnd());
1469 attrs.
addNew(&Availability,
1470 SourceRange(AvailabilityLoc,
T.getCloseLocation()), ScopeName,
1471 ScopeLoc, Platform, Changes[Introduced], Changes[Deprecated],
1472 Changes[Obsoleted], UnavailableLoc, MessageExpr.
get(), Form,
1473 StrictLoc, ReplacementExpr.
get(), EnvironmentLoc);
1490void Parser::ParseExternalSourceSymbolAttribute(
1496 if (
T.expectAndConsume())
1500 if (!Ident_language) {
1508 bool HasLanguage =
false;
1510 bool HasDefinedIn =
false;
1513 bool HasUSR =
false;
1517 if (Tok.
isNot(tok::identifier)) {
1518 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1525 if (Keyword == Ident_generated_declaration) {
1526 if (GeneratedDeclaration) {
1527 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) << Keyword;
1531 GeneratedDeclaration = ParseIdentifierLoc();
1535 if (Keyword != Ident_language && Keyword != Ident_defined_in &&
1536 Keyword != Ident_USR) {
1537 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1543 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1549 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1551 if (Keyword == Ident_language)
1553 else if (Keyword == Ident_USR)
1556 HasDefinedIn =
true;
1558 if (!isTokenStringLiteral()) {
1559 Diag(Tok, diag::err_expected_string_literal)
1562 Keyword == Ident_language
1564 : (Keyword == Ident_defined_in ? 1 : 2));
1568 if (Keyword == Ident_language) {
1570 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1576 }
else if (Keyword == Ident_USR) {
1578 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1585 assert(Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1587 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1597 if (
T.consumeClose())
1600 *EndLoc =
T.getCloseLocation();
1605 ScopeName, ScopeLoc, Args, std::size(Args), Form);
1619void Parser::ParseObjCBridgeRelatedAttribute(
1625 if (
T.consumeOpen()) {
1626 Diag(Tok, diag::err_expected) << tok::l_paren;
1631 if (Tok.
isNot(tok::identifier)) {
1632 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1637 if (ExpectAndConsume(tok::comma)) {
1646 if (Tok.
is(tok::identifier)) {
1649 Diag(Tok, diag::err_objcbridge_related_selector_name);
1655 if (Tok.
is(tok::colon))
1656 Diag(Tok, diag::err_objcbridge_related_selector_name);
1658 Diag(Tok, diag::err_expected) << tok::comma;
1666 if (Tok.
is(tok::identifier))
1668 else if (Tok.
isNot(tok::r_paren)) {
1669 Diag(Tok, diag::err_expected) << tok::r_paren;
1675 if (
T.consumeClose())
1679 *EndLoc =
T.getCloseLocation();
1682 Attrs.
addNew(&ObjCBridgeRelated,
1683 SourceRange(ObjCBridgeRelatedLoc,
T.getCloseLocation()),
1684 ScopeName, ScopeLoc, RelatedClass, ClassMethod, InstanceMethod,
1688void Parser::ParseSwiftNewTypeAttribute(
1695 if (
T.consumeOpen()) {
1696 Diag(Tok, diag::err_expected) << tok::l_paren;
1700 if (Tok.
is(tok::r_paren)) {
1705 if (Tok.
isNot(tok::kw_struct) && Tok.
isNot(tok::kw_enum)) {
1706 Diag(Tok, diag::warn_attribute_type_not_supported)
1708 if (!isTokenSpecial())
1719 if (
T.consumeClose())
1722 *EndLoc =
T.getCloseLocation();
1726 ScopeName, ScopeLoc, Args, std::size(Args), Form);
1729void Parser::ParseTypeTagForDatatypeAttribute(
1733 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1738 if (Tok.
isNot(tok::identifier)) {
1739 Diag(Tok, diag::err_expected) << tok::identifier;
1745 if (ExpectAndConsume(tok::comma)) {
1757 bool LayoutCompatible =
false;
1758 bool MustBeNull =
false;
1760 if (Tok.
isNot(tok::identifier)) {
1761 Diag(Tok, diag::err_expected) << tok::identifier;
1766 if (Flag->
isStr(
"layout_compatible"))
1767 LayoutCompatible =
true;
1768 else if (Flag->
isStr(
"must_be_null"))
1771 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1778 if (!
T.consumeClose()) {
1780 ArgumentKind, MatchingCType.
get(),
1781 LayoutCompatible, MustBeNull, Form);
1785 *EndLoc =
T.getCloseLocation();
1796bool Parser::DiagnoseProhibitedCXX11Attribute() {
1797 assert(Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square));
1799 switch (isCXX11AttributeSpecifier(
true)) {
1800 case CAK_NotAttributeSpecifier:
1804 case CAK_InvalidAttributeSpecifier:
1808 case CAK_AttributeSpecifier:
1813 assert(Tok.
is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1815 Diag(BeginLoc, diag::err_attributes_not_allowed)
1819 llvm_unreachable(
"All cases handled above.");
1828 assert((Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square)) ||
1835 ParseCXX11Attributes(Attrs);
1838 (Keyword ?
Diag(
Loc, diag::err_keyword_not_allowed) << Keyword
1839 :
Diag(
Loc, diag::err_attributes_not_allowed))
1844void Parser::DiagnoseProhibitedAttributes(
1846 auto *FirstAttr = Attrs.
empty() ? nullptr : &Attrs.
front();
1847 if (CorrectLocation.
isValid()) {
1849 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1850 ?
Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1851 :
Diag(CorrectLocation, diag::err_attributes_misplaced))
1856 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1864 unsigned AttrDiagID,
1865 unsigned KeywordDiagID,
1866 bool DiagnoseEmptyAttrs,
1867 bool WarnOnUnknownAttrs) {
1877 if (FirstLSquare.
is(tok::l_square)) {
1878 std::optional<Token> SecondLSquare =
1881 if (SecondLSquare && SecondLSquare->is(tok::l_square)) {
1892 if (AL.isRegularKeywordAttribute()) {
1893 Diag(AL.getLoc(), KeywordDiagID) << AL;
1897 if (!AL.isStandardAttributeSyntax())
1900 if (WarnOnUnknownAttrs)
1901 Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
1902 << AL << AL.getRange();
1904 Diag(AL.getLoc(), AttrDiagID) << AL;
1912 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1913 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1914 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
1934 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1935 AL.isDeclspecAttribute()) ||
1936 AL.isMicrosoftAttribute())
1937 ToBeMoved.push_back(&AL);
1972 Decl *SingleDecl =
nullptr;
1974 case tok::kw_template:
1975 case tok::kw_export:
1976 ProhibitAttributes(DeclAttrs);
1977 ProhibitAttributes(DeclSpecAttrs);
1978 return ParseDeclarationStartingWithTemplate(Context, DeclEnd, DeclAttrs);
1979 case tok::kw_inline:
1982 ProhibitAttributes(DeclAttrs);
1983 ProhibitAttributes(DeclSpecAttrs);
1985 return ParseNamespace(Context, DeclEnd, InlineLoc);
1987 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1988 true,
nullptr, DeclSpecStart);
1990 case tok::kw_cbuffer:
1991 case tok::kw_tbuffer:
1992 SingleDecl = ParseHLSLBuffer(DeclEnd);
1994 case tok::kw_namespace:
1995 ProhibitAttributes(DeclAttrs);
1996 ProhibitAttributes(DeclSpecAttrs);
1997 return ParseNamespace(Context, DeclEnd);
1998 case tok::kw_using: {
2001 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
2004 case tok::kw_static_assert:
2005 case tok::kw__Static_assert:
2006 ProhibitAttributes(DeclAttrs);
2007 ProhibitAttributes(DeclSpecAttrs);
2008 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
2011 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
2012 true,
nullptr, DeclSpecStart);
2044 bool RequireSemi, ForRangeInit *FRI,
SourceLocation *DeclSpecStart) {
2047 OriginalDeclSpecAttrs.
addAll(DeclSpecAttrs.
begin(), DeclSpecAttrs.
end());
2048 OriginalDeclSpecAttrs.
Range = DeclSpecAttrs.
Range;
2054 ParsedTemplateInfo TemplateInfo;
2055 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
2056 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none, DSContext);
2061 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
2066 if (Tok.
is(tok::semi)) {
2067 ProhibitAttributes(DeclAttrs);
2074 DS.complete(TheDecl);
2076 Decl* decls[] = {AnonRecord, TheDecl};
2088 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
2095 case tok::annot_cxxscope:
2096 case tok::annot_template_id:
2098 case tok::code_completion:
2099 case tok::coloncolon:
2101 case tok::kw___attribute:
2102 case tok::kw_operator:
2118 case tok::identifier:
2120 case tok::code_completion:
2121 case tok::coloncolon:
2124 case tok::equalequal:
2125 case tok::kw_alignas:
2127 case tok::kw___attribute:
2145 case tok::identifier:
2168 if (Tok.
isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
2192 case tok::kw_inline:
2197 (!ParsingInObjCContainer || CurParsedObjCImpl))
2201 case tok::kw_namespace:
2206 (!ParsingInObjCContainer || CurParsedObjCImpl))
2212 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2213 ParsingInObjCContainer)
2225 case tok::annot_module_begin:
2226 case tok::annot_module_end:
2227 case tok::annot_module_include:
2228 case tok::annot_repl_input_end:
2245 ParsedTemplateInfo &TemplateInfo,
2247 ForRangeInit *FRI) {
2253 LocalAttrs.takeAllFrom(Attrs);
2255 if (TemplateInfo.TemplateParams)
2258 bool IsTemplateSpecOrInst =
2259 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
2260 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
2265 if (IsTemplateSpecOrInst)
2275 MaybeParseHLSLAnnotations(D);
2277 if (Tok.
is(tok::kw_requires))
2278 ParseTrailingRequiresClause(D);
2283 LateParsedAttrList LateParsedAttrs(
true);
2285 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2290 if (Tok.
is(tok::kw__Noreturn)) {
2292 const char *PrevSpec;
2298 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2299 Fixit &= Tok.
isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2301 Diag(
Loc, diag::err_c11_noreturn_misplaced)
2303 << (Fixit ?
FixItHint::CreateInsertion(D.getBeginLoc(),
"_Noreturn ")
2308 if (Tok.
is(tok::equal) &&
NextToken().is(tok::code_completion)) {
2319 while (
auto Specifier = isCXX11VirtSpecifier()) {
2320 Diag(Tok, diag::err_virt_specifier_outside_class)
2328 if (!isDeclarationAfterDeclarator()) {
2334 if (isStartOfFunctionDefinition(D)) {
2344 diag::err_function_declared_typedef)
2348 Decl *TheDecl =
nullptr;
2350 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
2354 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2355 TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(),
2361 diag::err_explicit_instantiation_with_definition)
2369 std::nullopt, LAngleLoc,
nullptr));
2371 TheDecl = ParseFunctionDefinition(
2373 ParsedTemplateInfo(&FakedParamLists,
2380 ParseFunctionDefinition(D, TemplateInfo, &LateParsedAttrs);
2387 Tok.
is(tok::kw_namespace)) {
2397 Diag(Tok, diag::err_expected_fn_body);
2402 if (Tok.
is(tok::l_brace)) {
2403 Diag(Tok, diag::err_function_definition_not_allowed);
2411 if (ParseAsmAttributesAfterDeclarator(D))
2420 if (FRI && (Tok.
is(tok::colon) || isTokIdentifier_in())) {
2421 bool IsForRangeLoop =
false;
2423 IsForRangeLoop =
true;
2433 LastRecord.InLifetimeExtendingContext =
true;
2438 if (Tok.
is(tok::l_brace))
2439 FRI->RangeExpr = ParseBraceInitializer();
2450 FRI->LifetimeExtendTemps = std::move(
2455 if (IsForRangeLoop) {
2459 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2460 VD->setObjCForDecl(
true);
2463 D.complete(ThisDecl);
2469 ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo, FRI);
2470 if (LateParsedAttrs.size() > 0)
2471 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2472 D.complete(FirstDecl);
2474 DeclsInGroup.push_back(FirstDecl);
2482 if (Tok.
isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2486 Diag(CommaLoc, diag::err_expected_semi_declaration)
2496 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
2498 Diag(CommaLoc, diag::err_multiple_template_declarators)
2499 << TemplateInfo.Kind;
2513 MaybeParseGNUAttributes(D);
2517 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2522 MaybeParseHLSLAnnotations(D);
2529 if (Tok.
is(tok::kw_requires))
2530 ParseTrailingRequiresClause(D);
2531 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D, TemplateInfo);
2532 D.complete(ThisDecl);
2534 DeclsInGroup.push_back(ThisDecl);
2541 if (ExpectSemi && ExpectAndConsumeSemi(
2543 ? diag::err_invalid_token_after_toplevel_declarator
2544 : diag::err_expected_semi_declaration)) {
2557bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &D) {
2559 if (Tok.
is(tok::kw_asm)) {
2562 if (AsmLabel.isInvalid()) {
2571 MaybeParseGNUAttributes(D);
2597Decl *Parser::ParseDeclarationAfterDeclarator(
2598 Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
2599 if (ParseAsmAttributesAfterDeclarator(D))
2602 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
2605Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2606 Declarator &D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2608 struct InitializerScopeRAII {
2615 :
P(
P), D(D), ThisDecl(ThisDecl), Entered(
false) {
2616 if (ThisDecl &&
P.getLangOpts().CPlusPlus) {
2620 S =
P.getCurScope();
2623 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2628 ~InitializerScopeRAII() {
2629 if (ThisDecl &&
P.getLangOpts().CPlusPlus) {
2632 S =
P.getCurScope();
2635 P.Actions.ActOnCXXExitDeclInitializer(S, ThisDecl);
2644 InitKind TheInitKind;
2646 if (isTokenEqualOrEqualTypo())
2647 TheInitKind = InitKind::Equal;
2648 else if (Tok.
is(tok::l_paren))
2649 TheInitKind = InitKind::CXXDirect;
2652 TheInitKind = InitKind::CXXBraced;
2654 TheInitKind = InitKind::Uninitialized;
2655 if (TheInitKind != InitKind::Uninitialized)
2659 Decl *ThisDecl =
nullptr;
2660 Decl *OuterDecl =
nullptr;
2661 switch (TemplateInfo.Kind) {
2662 case ParsedTemplateInfo::NonTemplate:
2666 case ParsedTemplateInfo::Template:
2667 case ParsedTemplateInfo::ExplicitSpecialization: {
2669 *TemplateInfo.TemplateParams,
2671 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2674 ThisDecl = VT->getTemplatedDecl();
2679 case ParsedTemplateInfo::ExplicitInstantiation: {
2680 if (Tok.
is(tok::semi)) {
2682 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
2687 ThisDecl = ThisRes.
get();
2695 Diag(Tok, diag::err_template_defn_explicit_instantiation)
2702 diag::err_explicit_instantiation_with_definition)
2710 std::nullopt, LAngleLoc,
nullptr));
2722 switch (TheInitKind) {
2724 case InitKind::Equal: {
2727 if (Tok.
is(tok::kw_delete)) {
2733 SkipDeletedFunctionBody();
2734 }
else if (Tok.
is(tok::kw_default)) {
2742 InitializerScopeRAII InitScope(*
this, D, ThisDecl);
2744 if (Tok.
is(tok::code_completion)) {
2758 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2762 FRI->ColonLoc = EqualLoc;
2764 FRI->RangeExpr =
Init;
2767 if (
Init.isInvalid()) {
2769 StopTokens.push_back(tok::comma);
2772 StopTokens.push_back(tok::r_paren);
2781 case InitKind::CXXDirect: {
2788 InitializerScopeRAII InitScope(*
this, D, ThisDecl);
2790 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2791 auto RunSignatureHelp = [&]() {
2794 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2797 CalledSignatureHelp =
true;
2798 return PreferredType;
2800 auto SetPreferredType = [&] {
2801 PreferredType.enterFunctionArgument(Tok.
getLocation(), RunSignatureHelp);
2804 llvm::function_ref<void()> ExpressionStarts;
2810 ExpressionStarts = SetPreferredType;
2813 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2818 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2821 CalledSignatureHelp =
true;
2830 T.getCloseLocation(),
2837 case InitKind::CXXBraced: {
2839 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2841 InitializerScopeRAII InitScope(*
this, D, ThisDecl);
2843 PreferredType.enterVariableInit(Tok.
getLocation(), ThisDecl);
2846 if (
Init.isInvalid()) {
2852 case InitKind::Uninitialized: {
2859 return OuterDecl ? OuterDecl : ThisDecl;
2868void Parser::ParseSpecifierQualifierList(
2871 ParsedTemplateInfo TemplateInfo;
2875 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC,
nullptr,
2876 AllowImplicitTypename);
2881 Diag(Tok, diag::err_expected_type);
2884 Diag(Tok, diag::err_typename_requires_specqual);
2895 diag::err_typename_invalid_storageclass);
2939 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2940 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2954 ParsedTemplateInfo &TemplateInfo,
2957 assert(Tok.
is(tok::identifier) &&
"should have identifier");
2979 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
2997 AnnotateScopeToken(*SS,
false);
3008 DSC == DeclSpecContext::DSC_template_type_arg)) {
3009 const char *PrevSpec;
3025 if (SS ==
nullptr) {
3026 const char *TagName =
nullptr, *FixitTagName =
nullptr;
3032 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
3034 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
3036 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
3038 TagName=
"__interface"; FixitTagName =
"__interface ";
3039 TagKind=tok::kw___interface;
break;
3041 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
3049 Diag(
Loc, diag::err_use_of_tag_name_without_tag)
3050 << TokenName << TagName <<
getLangOpts().CPlusPlus
3056 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
3057 << TokenName << TagName;
3061 if (TagKind == tok::kw_enum)
3062 ParseEnumSpecifier(
Loc, DS, TemplateInfo, AS,
3063 DeclSpecContext::DSC_normal);
3065 ParseClassSpecifier(TagKind,
Loc, DS, TemplateInfo, AS,
3067 DeclSpecContext::DSC_normal, Attrs);
3074 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
3075 DSC == DeclSpecContext::DSC_class)) {
3079 case tok::l_paren: {
3086 TentativeParsingAction PA(*
this);
3088 TPResult TPR = TryParseDeclarator(
false);
3091 if (TPR != TPResult::False) {
3099 if (DSC == DeclSpecContext::DSC_class ||
3100 (DSC == DeclSpecContext::DSC_top_level && SS)) {
3103 Diag(
Loc, diag::err_constructor_bad_name)
3124 AnnotateScopeToken(*SS,
false);
3146 const char *PrevSpec;
3167 if (IsTemplateName) {
3169 TemplateArgList Args;
3170 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3184Parser::DeclSpecContext
3188 return DeclSpecContext::DSC_class;
3190 return DeclSpecContext::DSC_top_level;
3192 return DeclSpecContext::DSC_template_param;
3194 return DeclSpecContext::DSC_template_arg;
3196 return DeclSpecContext::DSC_template_type_arg;
3199 return DeclSpecContext::DSC_trailing;
3202 return DeclSpecContext::DSC_alias_declaration;
3204 return DeclSpecContext::DSC_association;
3206 return DeclSpecContext::DSC_type_specifier;
3208 return DeclSpecContext::DSC_condition;
3210 return DeclSpecContext::DSC_conv_operator;
3212 return DeclSpecContext::DSC_new;
3227 return DeclSpecContext::DSC_normal;
3230 llvm_unreachable(
"Missing DeclaratorContext case");
3243 if (isTypeIdInParens()) {
3272 assert(Tok.
isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3273 "Not an alignment-specifier!");
3280 if (
T.expectAndConsume())
3287 ParseAlignArgument(PP.
getSpelling(KWTok),
T.getOpenLocation(),
3296 *EndLoc =
T.getCloseLocation();
3303 ArgExprs.push_back(ArgExpr.
get());
3304 Attrs.
addNew(KWName, KWLoc,
nullptr, KWLoc, ArgExprs.data(), 1, Kind,
3317 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3322 if (Tok.
is(tok::r_paren)) {
3330 using ExpressionKind =
3334 ExpressionKind::EK_BoundsAttrArgument);
3344 ArgExprs.push_back(ArgExpr.
get());
3354 ScopeName, ScopeLoc, ArgExprs.data(), ArgExprs.size(), Form);
3357ExprResult Parser::ParseExtIntegerArgument() {
3358 assert(Tok.
isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3359 "Not an extended int type");
3363 if (
T.expectAndConsume())
3372 if(
T.consumeClose())
3386 DeclSpecContext DSContext,
3387 LateParsedAttrList *LateAttrs) {
3390 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3391 DSContext == DeclSpecContext::DSC_top_level);
3394 Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
3395 tok::annot_template_id) &&
3401 bool HasScope = Tok.
is(tok::annot_cxxscope);
3407 bool MightBeDeclarator =
true;
3408 if (Tok.
isOneOf(tok::kw_typename, tok::annot_typename)) {
3410 MightBeDeclarator =
false;
3411 }
else if (AfterScope.
is(tok::annot_template_id)) {
3417 MightBeDeclarator =
false;
3418 }
else if (AfterScope.
is(tok::identifier)) {
3419 const Token &Next = HasScope ? GetLookAheadToken(2) :
NextToken();
3423 if (Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3424 tok::annot_cxxscope, tok::coloncolon)) {
3426 MightBeDeclarator =
false;
3427 }
else if (HasScope) {
3438 switch (Classification.
getKind()) {
3444 llvm_unreachable(
"typo correction is not possible here");
3451 MightBeDeclarator =
false;
3467 if (MightBeDeclarator)
3472 diag::err_expected_after)
3483 ParsedTemplateInfo NotATemplate;
3484 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3515void Parser::ParseDeclarationSpecifiers(
3517 DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
3529 if (DSContext == DeclSpecContext::DSC_conv_operator) {
3532 DSContext = DeclSpecContext::DSC_type_specifier;
3535 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3536 DSContext == DeclSpecContext::DSC_top_level);
3537 bool AttrsLastTime =
false;
3543 bool isStorageClass =
false;
3544 const char *PrevSpec =
nullptr;
3545 unsigned DiagID = 0;
3566 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3580 bool IsTemplateSpecOrInst =
3581 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3582 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3591 ProhibitAttributes(attrs);
3595 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3596 !PA.isRegularKeywordAttribute())
3604 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3605 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3612 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3613 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3615 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3616 << PA << PA.isRegularKeywordAttribute();
3625 DS.
Finish(Actions, Policy);
3629 case tok::kw__Alignas:
3630 diagnoseUseOfC11Keyword(Tok);
3632 case tok::kw_alignas:
3638 if (Tok.
getKind() == tok::kw_alignas)
3639 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
3645 if (!isAllowedCXX11AttributeSpecifier())
3646 goto DoneWithDeclSpec;
3649 ProhibitAttributes(attrs);
3656 ParseCXX11Attributes(attrs);
3657 AttrsLastTime =
true;
3660 case tok::code_completion: {
3664 bool AllowNonIdentifiers
3670 bool AllowNestedNameSpecifiers
3671 = DSContext == DeclSpecContext::DSC_top_level ||
3676 getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3681 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
3682 CCC = DSContext == DeclSpecContext::DSC_class
3685 else if (DSContext == DeclSpecContext::DSC_class)
3689 else if (CurParsedObjCImpl)
3697 case tok::coloncolon:
3703 goto DoneWithDeclSpec;
3705 if (Tok.
is(tok::coloncolon))
3706 goto DoneWithDeclSpec;
3709 case tok::annot_cxxscope: {
3711 goto DoneWithDeclSpec;
3714 if (TemplateInfo.TemplateParams)
3724 ? takeTemplateIdAnnotation(Next)
3730 ConsumeAnnotationToken();
3744 if ((DSContext == DeclSpecContext::DSC_top_level ||
3745 DSContext == DeclSpecContext::DSC_class) &&
3748 isConstructorDeclarator(
false,
3755 goto DoneWithDeclSpec;
3759 ConsumeAnnotationToken();
3760 assert(Tok.
is(tok::annot_template_id) &&
3761 "ParseOptionalCXXScopeSpecifier not working");
3762 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3772 ConsumeAnnotationToken();
3776 if (Next.is(tok::annot_typename)) {
3778 ConsumeAnnotationToken();
3782 PrevSpec, DiagID,
T, Policy);
3786 ConsumeAnnotationToken();
3790 Next.is(tok::annot_template_id) &&
3794 ConsumeAnnotationToken();
3795 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3799 if (Next.isNot(tok::identifier))
3800 goto DoneWithDeclSpec;
3805 if ((DSContext == DeclSpecContext::DSC_top_level ||
3806 DSContext == DeclSpecContext::DSC_class) &&
3809 isConstructorDeclarator(
false,
3813 goto DoneWithDeclSpec;
3822 *Next.getIdentifierInfo(), Next.getLocation(),
getCurScope(), &SS,
3823 false,
false,
nullptr,
3826 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3828 if (IsTemplateSpecOrInst)
3836 if (TryAnnotateTypeConstraint())
3837 goto DoneWithDeclSpec;
3838 if (Tok.
isNot(tok::annot_cxxscope) ||
3842 ConsumeAnnotationToken();
3844 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3845 if (!Attrs.
empty()) {
3846 AttrsLastTime =
true;
3847 attrs.takeAllFrom(Attrs);
3851 goto DoneWithDeclSpec;
3855 ConsumeAnnotationToken();
3858 DiagID, TypeRep, Policy);
3868 case tok::annot_typename: {
3872 goto DoneWithDeclSpec;
3881 ConsumeAnnotationToken();
3886 case tok::kw___is_signed:
3897 TryKeywordIdentFallback(
true);
3900 goto DoneWithDeclSpec;
3903 case tok::kw___super:
3904 case tok::kw_decltype:
3905 case tok::identifier:
3911 goto DoneWithDeclSpec;
3917 if (!
getLangOpts().DeclSpecKeyword && Tok.
is(tok::identifier) &&
3919 Diag(
Loc, diag::err_ms_attributes_not_enabled);
3929 if (
T.consumeOpen()) {
3930 assert(
false &&
"Not a left paren?");
3949 if (IsTemplateSpecOrInst)
3953 if (IsTemplateSpecOrInst)
3956 goto DoneWithDeclSpec;
3959 if (!Tok.
is(tok::identifier))
3964 if (TryAltiVecToken(DS,
Loc, PrevSpec, DiagID,
isInvalid))
3970 goto DoneWithDeclSpec;
3972 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3973 isObjCInstancetype()) {
3977 DiagID, TypeRep, Policy);
3990 isConstructorDeclarator(
true,
3993 goto DoneWithDeclSpec;
3997 false,
false,
nullptr,
false,
false,
3998 isClassTemplateDeductionContext(DSContext));
4003 if (TryAnnotateTypeConstraint())
4004 goto DoneWithDeclSpec;
4005 if (Tok.
isNot(tok::identifier))
4008 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
4009 if (!Attrs.
empty()) {
4010 AttrsLastTime =
true;
4011 attrs.takeAllFrom(Attrs);
4015 goto DoneWithDeclSpec;
4022 (DSContext == DeclSpecContext::DSC_class ||
4023 DSContext == DeclSpecContext::DSC_top_level) &&
4026 isConstructorDeclarator(
true,
4028 goto DoneWithDeclSpec;
4031 DiagID, TypeRep, Policy);
4043 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
4058 case tok::annot_template_id: {
4070 TemplateId =
nullptr;
4078 tok::kw_volatile, tok::kw_restrict, tok::amp,
4080 Diag(
Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
4084 TemplateId, Policy);
4088 goto DoneWithDeclSpec;
4091 TemplateId =
nullptr;
4093 ConsumeAnnotationToken();
4097 if (Tracker.consumeOpen()) {
4099 Diag(Tok, diag::err_expected) << tok::l_paren;
4103 Tracker.skipToEnd();
4104 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
4109 Tracker.consumeClose();
4117 DiagID, TemplateId, Policy);
4120 TemplateId, Policy);
4129 goto DoneWithDeclSpec;
4137 isConstructorDeclarator(
true,
4140 goto DoneWithDeclSpec;
4145 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
4150 case tok::kw___attribute:
4151 case tok::kw___declspec:
4152 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4156 case tok::kw___forceinline: {
4161 nullptr, 0, tok::kw___forceinline);
4165 case tok::kw___unaligned:
4170 case tok::kw___sptr:
4171 case tok::kw___uptr:
4172 case tok::kw___ptr64:
4173 case tok::kw___ptr32:
4175 case tok::kw___cdecl:
4176 case tok::kw___stdcall:
4177 case tok::kw___fastcall:
4178 case tok::kw___thiscall:
4179 case tok::kw___regcall:
4180 case tok::kw___vectorcall:
4184 case tok::kw___funcref:
4189 case tok::kw___pascal:
4194 case tok::kw___kernel:
4199 case tok::kw___noinline__:
4204 case tok::kw__Nonnull:
4205 case tok::kw__Nullable:
4206 case tok::kw__Nullable_result:
4207 case tok::kw__Null_unspecified:
4212 case tok::kw___kindof:
4214 nullptr, 0, tok::kw___kindof);
4219 case tok::kw_typedef:
4221 PrevSpec, DiagID, Policy);
4222 isStorageClass =
true;
4224 case tok::kw_extern:
4226 Diag(Tok, diag::ext_thread_before) <<
"extern";
4228 PrevSpec, DiagID, Policy);
4229 isStorageClass =
true;
4231 case tok::kw___private_extern__:
4233 Loc, PrevSpec, DiagID, Policy);
4234 isStorageClass =
true;
4236 case tok::kw_static:
4238 Diag(Tok, diag::ext_thread_before) <<
"static";
4240 PrevSpec, DiagID, Policy);
4241 isStorageClass =
true;
4245 if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
4247 PrevSpec, DiagID, Policy);
4249 Diag(Tok, diag::ext_auto_storage_class)
4256 PrevSpec, DiagID, Policy);
4257 isStorageClass =
true;
4259 case tok::kw___auto_type:
4260 Diag(Tok, diag::ext_auto_type);
4264 case tok::kw_register:
4266 PrevSpec, DiagID, Policy);
4267 isStorageClass =
true;
4269 case tok::kw_mutable:
4271 PrevSpec, DiagID, Policy);
4272 isStorageClass =
true;
4274 case tok::kw___thread:
4277 isStorageClass =
true;
4279 case tok::kw_thread_local:
4281 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4290 Loc, PrevSpec, DiagID);
4291 isStorageClass =
true;
4293 case tok::kw__Thread_local:
4294 diagnoseUseOfC11Keyword(Tok);
4296 Loc, PrevSpec, DiagID);
4297 isStorageClass =
true;
4301 case tok::kw_inline:
4304 case tok::kw_virtual:
4308 !
getActions().getOpenCLOptions().isAvailableOption(
4310 DiagID = diag::err_openclcxx_virtual_function;
4317 case tok::kw_explicit: {
4321 ConsumedEnd = ExplicitLoc;
4323 if (Tok.
is(tok::l_paren)) {
4326 ? diag::warn_cxx17_compat_explicit_bool
4327 : diag::ext_explicit_bool);
4331 Tracker.consumeOpen();
4338 if (ExplicitExpr.isUsable()) {
4340 Tracker.consumeClose();
4344 Tracker.skipToEnd();
4350 ExplicitSpec, CloseParenLoc);
4353 case tok::kw__Noreturn:
4354 diagnoseUseOfC11Keyword(Tok);
4359 case tok::kw_friend:
4360 if (DSContext == DeclSpecContext::DSC_class) {
4367 DiagID = diag::err_friend_invalid_in_context;
4373 case tok::kw___module_private__:
4378 case tok::kw_constexpr:
4380 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4384 case tok::kw_consteval:
4388 case tok::kw_constinit:
4404 PrevSpec, DiagID, Policy);
4406 case tok::kw___int64:
4408 PrevSpec, DiagID, Policy);
4410 case tok::kw_signed:
4414 case tok::kw_unsigned:
4418 case tok::kw__Complex:
4420 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4424 case tok::kw__Imaginary:
4426 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4442 case tok::kw__ExtInt:
4443 case tok::kw__BitInt: {
4444 DiagnoseBitIntUse(Tok);
4449 ConsumedEnd = PrevTokLocation;
4452 case tok::kw___int128:
4460 case tok::kw___bf16:
4468 case tok::kw_double:
4472 case tok::kw__Float16:
4476 case tok::kw__Accum:
4478 "This keyword is only used when fixed point types are enabled "
4479 "with `-ffixed-point`");
4483 case tok::kw__Fract:
4485 "This keyword is only used when fixed point types are enabled "
4486 "with `-ffixed-point`");
4492 "This keyword is only used when fixed point types are enabled "
4493 "with `-ffixed-point`");
4496 case tok::kw___float128:
4500 case tok::kw___ibm128:
4504 case tok::kw_wchar_t:
4508 case tok::kw_char8_t:
4512 case tok::kw_char16_t:
4516 case tok::kw_char32_t:
4522 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4526 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4528 if (Tok.
is(tok::kw_bool) &&
4532 DiagID = diag::err_bool_redeclaration;
4541 case tok::kw__Decimal32:
4545 case tok::kw__Decimal64:
4549 case tok::kw__Decimal128:
4553 case tok::kw___vector:
4556 case tok::kw___pixel:
4559 case tok::kw___bool:
4564 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4569 goto DoneWithDeclSpec;
4571 DiagID = diag::err_opencl_unknown_type_specifier;
4578#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4579#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4580#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4581 case tok::kw_##ImgType##_t: \
4582 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4583 goto DoneWithDeclSpec; \
4585#include "clang/Basic/OpenCLImageTypes.def"
4586 case tok::kw___unknown_anytype:
4588 PrevSpec, DiagID, Policy);
4593 case tok::kw_struct:
4594 case tok::kw___interface:
4595 case tok::kw_union: {
4603 ParseClassSpecifier(Kind,
Loc, DS, TemplateInfo, AS,
4604 EnteringContext, DSContext, Attributes);
4608 if (!Attributes.empty()) {
4609 AttrsLastTime =
true;
4610 attrs.takeAllFrom(Attributes);
4618 ParseEnumSpecifier(
Loc, DS, TemplateInfo, AS, DSContext);
4626 case tok::kw_volatile:
4630 case tok::kw_restrict:
4636 case tok::kw_typename:
4639 goto DoneWithDeclSpec;
4641 if (!Tok.
is(tok::kw_typename))
4646 case tok::kw_typeof:
4647 case tok::kw_typeof_unqual:
4648 ParseTypeofSpecifier(DS);
4651 case tok::annot_decltype:
4652 ParseDecltypeSpecifier(DS);
4655 case tok::annot_pack_indexing_type:
4656 ParsePackIndexingType(DS);
4659 case tok::annot_pragma_pack:
4663 case tok::annot_pragma_ms_pragma:
4664 HandlePragmaMSPragma();
4667 case tok::annot_pragma_ms_vtordisp:
4668 HandlePragmaMSVtorDisp();
4671 case tok::annot_pragma_ms_pointers_to_members:
4672 HandlePragmaMSPointersToMembers();
4675#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4676#include "clang/Basic/TransformTypeTraits.def"
4680 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4681 goto ParseIdentifier;
4684 case tok::kw__Atomic:
4689 diagnoseUseOfC11Keyword(Tok);
4691 ParseAtomicSpecifier(DS);
4699 case tok::kw___generic:
4704 if (!Actions.
getLangOpts().OpenCLGenericAddressSpace) {
4705 DiagID = diag::err_opencl_unknown_type_specifier;
4711 case tok::kw_private:
4715 goto DoneWithDeclSpec;
4717 case tok::kw___private:
4718 case tok::kw___global:
4719 case tok::kw___local:
4720 case tok::kw___constant:
4722 case tok::kw___read_only:
4723 case tok::kw___write_only:
4724 case tok::kw___read_write:
4728 case tok::kw_groupshared:
4741 goto DoneWithDeclSpec;
4746 if (
Type.isUsable()) {
4748 PrevSpec, DiagID,
Type.get(),
4750 Diag(StartLoc, DiagID) << PrevSpec;
4766 assert(PrevSpec &&
"Method did not return previous specifier!");
4769 if (DiagID == diag::ext_duplicate_declspec ||
4770 DiagID == diag::ext_warn_duplicate_declspec ||
4771 DiagID == diag::err_duplicate_declspec)
4775 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4779 Diag(
Loc, DiagID) << PrevSpec;
4782 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4786 AttrsLastTime =
false;
4798 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4801 for (
auto *I : RD->decls()) {
4802 auto *VD = dyn_cast<ValueDecl>(I);
4810 for (
const auto &DD : CAT->dependent_decls()) {
4811 if (!RD->containsDecl(DD.getDecl())) {
4812 P.Diag(VD->getBeginLoc(),
4813 diag::err_flexible_array_count_not_in_same_struct)
4815 P.Diag(DD.getDecl()->getBeginLoc(),
4816 diag::note_flexible_array_counted_by_attr_field)
4844void Parser::ParseStructDeclaration(
4848 if (Tok.
is(tok::kw___extension__)) {
4852 return ParseStructDeclaration(DS, FieldsCallback);
4857 MaybeParseCXX11Attributes(Attrs);
4860 ParseSpecifierQualifierList(DS);
4864 if (Tok.
is(tok::semi)) {
4869 ProhibitAttributes(Attrs);
4873 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4879 bool FirstDeclarator =
true;
4883 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4886 if (!FirstDeclarator) {
4889 DiagnoseAndSkipCXX11Attributes();
4890 MaybeParseGNUAttributes(DeclaratorInfo.D);
4891 DiagnoseAndSkipCXX11Attributes();
4896 if (Tok.
isNot(tok::colon)) {
4899 ParseDeclarator(DeclaratorInfo.D);
4901 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.
getLocation());
4913 DeclaratorInfo.BitfieldSize = Res.
get();
4917 MaybeParseGNUAttributes(DeclaratorInfo.D);
4920 FieldsCallback(DeclaratorInfo);
4927 FirstDeclarator =
false;
4944 "parsing struct/union body");
4948 if (
T.consumeOpen())
4955 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
4956 Tok.
isNot(tok::eof)) {
4960 if (Tok.
is(tok::semi)) {
4961 ConsumeExtraSemi(InsideStruct,
TagType);
4966 if (Tok.
isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4968 ParseStaticAssertDeclaration(DeclEnd);
4972 if (Tok.
is(tok::annot_pragma_pack)) {
4977 if (Tok.
is(tok::annot_pragma_align)) {
4978 HandlePragmaAlign();
4982 if (Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4986 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4990 if (Tok.
is(tok::annot_pragma_openacc)) {
4999 ConsumeAnnotationToken();
5003 if (!Tok.
is(tok::at)) {
5009 FD.D, FD.BitfieldSize);
5015 ParseStructDeclaration(DS, CFieldCallback);
5019 Diag(Tok, diag::err_unexpected_at);
5024 ExpectAndConsume(tok::l_paren);
5025 if (!Tok.
is(tok::identifier)) {
5026 Diag(Tok, diag::err_expected) << tok::identifier;
5034 ExpectAndConsume(tok::r_paren);
5040 if (Tok.
is(tok::r_brace)) {
5041 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
5045 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
5056 MaybeParseGNUAttributes(attrs);
5061 T.getOpenLocation(),
T.getCloseLocation(), attrs);
5097 const ParsedTemplateInfo &TemplateInfo,
5100 if (Tok.
is(tok::code_completion)) {
5110 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5113 bool IsScopedUsingClassTag =
false;
5118 : diag::ext_scoped_enum);
5119 IsScopedUsingClassTag = Tok.
is(tok::kw_class);
5124 ProhibitAttributes(attrs);
5127 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5136 bool shouldDelayDiagsInTag =
5137 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
5138 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
5142 AllowDefiningTypeSpec AllowEnumSpecifier =
5144 bool CanBeOpaqueEnumDeclaration =
5145 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5148 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5149 CanBeOpaqueEnumDeclaration);
5157 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5162 if (Spec.
isSet() && Tok.
isNot(tok::identifier)) {
5163 Diag(Tok, diag::err_expected) << tok::identifier;
5165 if (Tok.
isNot(tok::l_brace)) {
5177 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::l_brace) &&
5178 Tok.
isNot(tok::colon)) {
5179 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5190 if (Tok.
is(tok::identifier)) {
5195 if (!Name && ScopedEnumKWLoc.
isValid()) {
5198 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5200 IsScopedUsingClassTag =
false;
5205 if (shouldDelayDiagsInTag)
5206 diagsFromTag.done();
5211 bool CanBeBitfield =
5215 if (Tok.
is(tok::colon)) {
5240 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5245 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5256 DeclSpecContext::DSC_type_specifier);
5261 BaseRange =
SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5265 Diag(ColonLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type)
5268 Diag(ColonLoc, diag::ext_cxx11_enum_fixed_underlying_type)
5271 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5274 Diag(ColonLoc, diag::ext_clang_c_enum_fixed_underlying_type)
5291 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5293 else if (Tok.
is(tok::l_brace)) {
5302 IsScopedUsingClassTag =
false;
5308 }
else if (!isTypeSpecifier(DSC) &&
5309 (Tok.
is(tok::semi) ||
5311 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5316 if (Tok.
isNot(tok::semi)) {
5318 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5326 bool IsElaboratedTypeSpecifier =
5332 diagsFromTag.redelay();
5336 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
5340 Diag(Tok, diag::err_enum_template);
5345 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
5348 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5352 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5354 TemplateInfo.TemplateParams->size());
5359 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5375 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5377 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5378 diag::err_keyword_not_allowed,
5381 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5382 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5383 else if (ScopedEnumKWLoc.
isValid())
5384 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5388 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5398 bool IsDependent =
false;
5399 const char *PrevSpec =
nullptr;
5404 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5405 IsScopedUsingClassTag,
5406 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5407 DSC == DeclSpecContext::DSC_template_param ||
5408 DSC == DeclSpecContext::DSC_template_type_arg,
5409 OffsetOfState, &SkipBody).
get();
5419 NameLoc.
isValid() ? NameLoc : StartLoc,
5420 PrevSpec, DiagID,
TagDecl, Owned,
5422 Diag(StartLoc, DiagID) << PrevSpec;
5431 Diag(Tok, diag::err_expected_type_name_after_typename);
5437 if (
Type.isInvalid()) {
5443 NameLoc.
isValid() ? NameLoc : StartLoc,
5444 PrevSpec, DiagID,
Type.get(),
5446 Diag(StartLoc, DiagID) << PrevSpec;
5465 ParseEnumBody(StartLoc, D);
5474 NameLoc.
isValid() ? NameLoc : StartLoc,
5475 PrevSpec, DiagID,
TagDecl, Owned,
5477 Diag(StartLoc, DiagID) << PrevSpec;
5500 Diag(Tok, diag::err_empty_enum);
5505 Decl *LastEnumConstDecl =
nullptr;
5508 while (Tok.
isNot(tok::r_brace)) {
5511 if (Tok.
isNot(tok::identifier)) {
5523 MaybeParseGNUAttributes(attrs);
5524 if (isAllowedCXX11AttributeSpecifier()) {
5527 ? diag::warn_cxx14_compat_ns_enum_attribute
5528 : diag::ext_ns_enum_attribute)
5530 ParseCXX11Attributes(attrs);
5535 EnumAvailabilityDiags.emplace_back(*
this);
5548 EqualLoc, AssignedVal.
get());
5549 EnumAvailabilityDiags.back().done();
5551 EnumConstantDecls.push_back(EnumConstDecl);
5552 LastEnumConstDecl = EnumConstDecl;
5554 if (Tok.
is(tok::identifier)) {
5557 Diag(
Loc, diag::err_enumerator_list_missing_comma)
5580 if (Tok.
is(tok::r_brace) && CommaLoc.
isValid()) {
5583 diag::ext_enumerator_list_comma_cxx :
5584 diag::ext_enumerator_list_comma_c)
5587 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5598 MaybeParseGNUAttributes(attrs);
5604 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5605 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5607 EnumAvailabilityDiags[i].redelay();
5608 PD.complete(EnumConstantDecls[i]);
5617 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5618 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5630bool Parser::isKnownToBeTypeSpecifier(
const Token &Tok)
const {
5632 default:
return false;
5636 case tok::kw___int64:
5637 case tok::kw___int128:
5638 case tok::kw_signed:
5639 case tok::kw_unsigned:
5640 case tok::kw__Complex:
5641 case tok::kw__Imaginary:
5644 case tok::kw_wchar_t:
5645 case tok::kw_char8_t:
5646 case tok::kw_char16_t:
5647 case tok::kw_char32_t:
5649 case tok::kw__ExtInt:
5650 case tok::kw__BitInt:
5651 case tok::kw___bf16:
5654 case tok::kw_double:
5655 case tok::kw__Accum:
5656 case tok::kw__Fract:
5657 case tok::kw__Float16:
5658 case tok::kw___float128:
5659 case tok::kw___ibm128:
5662 case tok::kw__Decimal32:
5663 case tok::kw__Decimal64:
5664 case tok::kw__Decimal128:
5665 case tok::kw___vector:
5666#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5667#include "clang/Basic/OpenCLImageTypes.def"
5671 case tok::kw_struct:
5672 case tok::kw___interface:
5678 case tok::annot_typename:
5685bool Parser::isTypeSpecifierQualifier() {
5687 default:
return false;
5689 case tok::identifier:
5690 if (TryAltiVecVectorToken())
5693 case tok::kw_typename:
5698 if (Tok.
is(tok::identifier))
5700 return isTypeSpecifierQualifier();
5702 case tok::coloncolon:
5709 return isTypeSpecifierQualifier();
5712 case tok::kw___attribute:
5714 case tok::kw_typeof:
5715 case tok::kw_typeof_unqual:
5720 case tok::kw___int64:
5721 case tok::kw___int128:
5722 case tok::kw_signed:
5723 case tok::kw_unsigned:
5724 case tok::kw__Complex:
5725 case tok::kw__Imaginary:
5728 case tok::kw_wchar_t:
5729 case tok::kw_char8_t:
5730 case tok::kw_char16_t:
5731 case tok::kw_char32_t:
5733 case tok::kw__ExtInt:
5734 case tok::kw__BitInt:
5736 case tok::kw___bf16:
5738 case tok::kw_double:
5739 case tok::kw__Accum:
5740 case tok::kw__Fract:
5741 case tok::kw__Float16:
5742 case tok::kw___float128:
5743 case tok::kw___ibm128:
5746 case tok::kw__Decimal32:
5747 case tok::kw__Decimal64:
5748 case tok::kw__Decimal128:
5749 case tok::kw___vector:
5750#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5751#include "clang/Basic/OpenCLImageTypes.def"
5755 case tok::kw_struct:
5756 case tok::kw___interface:
5763 case tok::kw_volatile:
5764 case tok::kw_restrict:
5768 case tok::kw___unknown_anytype:
5771 case tok::annot_typename:
5778 case tok::kw___cdecl:
5779 case tok::kw___stdcall:
5780 case tok::kw___fastcall:
5781 case tok::kw___thiscall:
5782 case tok::kw___regcall:
5783 case tok::kw___vectorcall:
5785 case tok::kw___ptr64:
5786 case tok::kw___ptr32:
5787 case tok::kw___pascal:
5788 case tok::kw___unaligned:
5790 case tok::kw__Nonnull:
5791 case tok::kw__Nullable:
5792 case tok::kw__Nullable_result:
5793 case tok::kw__Null_unspecified:
5795 case tok::kw___kindof:
5797 case tok::kw___private:
5798 case tok::kw___local:
5799 case tok::kw___global:
5800 case tok::kw___constant:
5801 case tok::kw___generic:
5802 case tok::kw___read_only:
5803 case tok::kw___read_write:
5804 case tok::kw___write_only:
5805 case tok::kw___funcref:
5808 case tok::kw_private:
5812 case tok::kw__Atomic:
5816 case tok::kw_groupshared:
5829 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5833 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5839 if (Tok.
is(tok::annot_repl_input_end) &&
5841 ConsumeAnnotationToken();
5846 DeclsInGroup.push_back(TLSD);
5849 for (
Stmt *S : Stmts) {
5854 DeclsInGroup.push_back(D);
5867bool Parser::isDeclarationSpecifier(
5869 bool DisambiguatingWithExpression) {
5871 default:
return false;
5878 case tok::identifier:
5882 if (TryAltiVecVectorToken())
5885 case tok::kw_decltype:
5886 case tok::kw_typename:
5891 if (TryAnnotateTypeConstraint())
5893 if (Tok.
is(tok::identifier))
5901 if (DisambiguatingWithExpression &&
5902 isStartOfObjCClassMessageMissingOpenBracket())
5905 return isDeclarationSpecifier(AllowImplicitTypename);
5907 case tok::coloncolon:
5921 case tok::kw_typedef:
5922 case tok::kw_extern:
5923 case tok::kw___private_extern__:
5924 case tok::kw_static:
5926 case tok::kw___auto_type:
5927 case tok::kw_register:
5928 case tok::kw___thread:
5929 case tok::kw_thread_local:
5930 case tok::kw__Thread_local:
5933 case tok::kw___module_private__:
5936 case tok::kw___unknown_anytype:
5941 case tok::kw___int64:
5942 case tok::kw___int128:
5943 case tok::kw_signed:
5944 case tok::kw_unsigned:
5945 case tok::kw__Complex:
5946 case tok::kw__Imaginary:
5949 case tok::kw_wchar_t:
5950 case tok::kw_char8_t:
5951 case tok::kw_char16_t:
5952 case tok::kw_char32_t:
5955 case tok::kw__ExtInt:
5956 case tok::kw__BitInt:
5958 case tok::kw___bf16:
5960 case tok::kw_double:
5961 case tok::kw__Accum:
5962 case tok::kw__Fract:
5963 case tok::kw__Float16:
5964 case tok::kw___float128:
5965 case tok::kw___ibm128:
5968 case tok::kw__Decimal32:
5969 case tok::kw__Decimal64:
5970 case tok::kw__Decimal128:
5971 case tok::kw___vector:
5975 case tok::kw_struct:
5977 case tok::kw___interface:
5983 case tok::kw_volatile:
5984 case tok::kw_restrict:
5988 case tok::kw_inline:
5989 case tok::kw_virtual:
5990 case tok::kw_explicit:
5991 case tok::kw__Noreturn:
5994 case tok::kw__Alignas:
5997 case tok::kw_friend:
6000 case tok::kw_static_assert:
6001 case tok::kw__Static_assert:
6004 case tok::kw_typeof:
6005 case tok::kw_typeof_unqual:
6008 case tok::kw___attribute:
6011 case tok::annot_decltype:
6012 case tok::annot_pack_indexing_type:
6013 case tok::kw_constexpr:
6016 case tok::kw_consteval:
6017 case tok::kw_constinit:
6020 case tok::kw__Atomic:
6023 case tok::kw_alignas:
6033 case tok::annot_typename:
6034 return !DisambiguatingWithExpression ||
6035 !isStartOfObjCClassMessageMissingOpenBracket();
6038 case tok::annot_template_id: {
6044 return isTypeConstraintAnnotation() &&
6048 case tok::annot_cxxscope: {
6057 if (
NextToken().is(tok::identifier) && TryAnnotateTypeConstraint())
6059 return isTypeConstraintAnnotation() &&
6060 GetLookAheadToken(2).isOneOf(tok::kw_auto, tok::kw_decltype);
6063 case tok::kw___declspec:
6064 case tok::kw___cdecl:
6065 case tok::kw___stdcall:
6066 case tok::kw___fastcall:
6067 case tok::kw___thiscall:
6068 case tok::kw___regcall:
6069 case tok::kw___vectorcall:
6071 case tok::kw___sptr:
6072 case tok::kw___uptr:
6073 case tok::kw___ptr64:
6074 case tok::kw___ptr32:
6075 case tok::kw___forceinline:
6076 case tok::kw___pascal:
6077 case tok::kw___unaligned:
6079 case tok::kw__Nonnull:
6080 case tok::kw__Nullable:
6081 case tok::kw__Nullable_result:
6082 case tok::kw__Null_unspecified:
6084 case tok::kw___kindof:
6086 case tok::kw___private:
6087 case tok::kw___local:
6088 case tok::kw___global:
6089 case tok::kw___constant:
6090 case tok::kw___generic:
6091 case tok::kw___read_only:
6092 case tok::kw___read_write:
6093 case tok::kw___write_only:
6094#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
6095#include "clang/Basic/OpenCLImageTypes.def"
6097 case tok::kw___funcref:
6098 case tok::kw_groupshared:
6101 case tok::kw_private:
6106bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
6108 const ParsedTemplateInfo *TemplateInfo) {
6109 RevertingTentativeParsingAction TPA(*
this);
6112 if (TemplateInfo && TemplateInfo->TemplateParams)
6115 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6122 if (Tok.
is(tok::identifier)) {
6126 }
else if (Tok.
is(tok::annot_template_id)) {
6127 ConsumeAnnotationToken();
6134 SkipCXX11Attributes();
6137 if (Tok.
isNot(tok::l_paren)) {
6144 if (Tok.
is(tok::r_paren) ||
6145 (Tok.
is(tok::ellipsis) &&
NextToken().is(tok::r_paren))) {
6152 isCXX11AttributeSpecifier(
false,
6158 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6160 DeclScopeObj.EnterDeclaratorScope();
6164 MaybeParseMicrosoftAttributes(Attrs);
6173 bool IsConstructor =
false;
6179 if (Tok.
is(tok::kw_this)) {
6181 return isDeclarationSpecifier(ITC);
6184 if (isDeclarationSpecifier(ITC))
6185 IsConstructor =
true;
6186 else if (Tok.
is(tok::identifier) ||
6187 (Tok.
is(tok::annot_cxxscope) &&
NextToken().is(tok::identifier))) {
6192 if (Tok.
is(tok::annot_cxxscope))
6193 ConsumeAnnotationToken();
6205 case tok::coloncolon:
6218 SkipCXX11Attributes();
6220 if (DeductionGuide) {
6222 IsConstructor = Tok.
is(tok::arrow);
6225 if (Tok.
is(tok::colon) || Tok.
is(tok::kw_try)) {
6229 IsConstructor =
true;
6231 if (Tok.
is(tok::semi) || Tok.
is(tok::l_brace)) {
6244 IsConstructor = IsUnqualified;
6249 IsConstructor =
true;
6253 return IsConstructor;
6268void Parser::ParseTypeQualifierListOpt(
6269 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicAllowed,
6270 bool IdentifierRequired,
6272 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6273 isAllowedCXX11AttributeSpecifier()) {
6275 ParseCXX11Attributes(Attrs);
6283 const char *PrevSpec =
nullptr;
6284 unsigned DiagID = 0;
6288 case tok::code_completion:
6291 (*CodeCompletionHandler)();
6300 case tok::kw_volatile:
6304 case tok::kw_restrict:
6308 case tok::kw__Atomic:
6310 goto DoneWithTypeQuals;
6311 diagnoseUseOfC11Keyword(Tok);
6317 case tok::kw_private:
6319 goto DoneWithTypeQuals;
6321 case tok::kw___private:
6322 case tok::kw___global:
6323 case tok::kw___local:
6324 case tok::kw___constant:
6325 case tok::kw___generic:
6326 case tok::kw___read_only:
6327 case tok::kw___write_only:
6328 case tok::kw___read_write:
6332 case tok::kw_groupshared:
6340 case tok::kw___unaligned:
6344 case tok::kw___uptr:
6349 if (TryKeywordIdentFallback(
false))
6353 case tok::kw___sptr:
6355 case tok::kw___ptr64:
6356 case tok::kw___ptr32:
6357 case tok::kw___cdecl:
6358 case tok::kw___stdcall:
6359 case tok::kw___fastcall:
6360 case tok::kw___thiscall:
6361 case tok::kw___regcall:
6362 case tok::kw___vectorcall:
6363 if (AttrReqs & AR_DeclspecAttributesParsed) {
6367 goto DoneWithTypeQuals;
6369 case tok::kw___funcref:
6372 goto DoneWithTypeQuals;
6374 case tok::kw___pascal:
6375 if (AttrReqs & AR_VendorAttributesParsed) {
6379 goto DoneWithTypeQuals;
6382 case tok::kw__Nonnull:
6383 case tok::kw__Nullable:
6384 case tok::kw__Nullable_result:
6385 case tok::kw__Null_unspecified:
6390 case tok::kw___kindof:
6392 nullptr, 0, tok::kw___kindof);
6396 case tok::kw___attribute:
6397 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6399 Diag(Tok, diag::err_attributes_not_allowed);
6403 if (AttrReqs & AR_GNUAttributesParsed ||
6404 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6422 assert(PrevSpec &&
"Method did not return previous specifier!");
6423 Diag(Tok, DiagID) << PrevSpec;
6434 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6440 if (Kind == tok::star || Kind == tok::caret)
6444 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6445 Lang.getOpenCLCompatibleVersion() >= 200)
6448 if (!Lang.CPlusPlus)
6451 if (Kind == tok::amp)
6459 if (Kind == tok::ampamp)
6470 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6502void Parser::ParseDeclaratorInternal(
Declarator &D,
6503 DirectDeclParseFunction DirectDeclParser) {
6511 (Tok.
is(tok::coloncolon) || Tok.
is(tok::kw_decltype) ||
6512 (Tok.
is(tok::identifier) &&
6514 Tok.
is(tok::annot_cxxscope))) {
6519 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6520 false, EnteringContext);
6523 if (Tok.
isNot(tok::star)) {
6528 AnnotateScopeToken(SS,
true);
6530 if (DirectDeclParser)
6531 (this->*DirectDeclParser)(D);
6536 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6537 CompoundToken::MemberPtr);
6543 ParseTypeQualifierListOpt(DS);
6548 ParseDeclaratorInternal(D, DirectDeclParser);
6565 ParseTypeQualifierListOpt(DS);
6574 if (DirectDeclParser)
6575 (this->*DirectDeclParser)(D);
6584 if (Kind == tok::star || Kind == tok::caret) {
6590 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6592 ? AR_GNUAttributesParsed
6593 : AR_GNUAttributesParsedAndRejected);
6599 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6600 if (Kind == tok::star)
6618 if (Kind == tok::ampamp)
6620 diag::warn_cxx98_compat_rvalue_reference :
6621 diag::ext_rvalue_reference);
6624 ParseTypeQualifierListOpt(DS);
6633 diag::err_invalid_reference_qualifier_application) <<
"const";
6636 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6640 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6645 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6652 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6655 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6730void Parser::ParseDirectDeclarator(
Declarator &D) {
6737 return ParseDecompositionDeclarator(D);
6751 ParseOptionalCXXScopeSpecifier(
6753 false, EnteringContext);
6772 DeclScopeObj.EnterDeclaratorScope();
6779 goto PastIdentifier;
6803 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6813 if (Tok.
isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6817 bool AllowConstructorName;
6818 bool AllowDeductionGuide;
6820 AllowConstructorName =
false;
6821 AllowDeductionGuide =
false;
6825 AllowDeductionGuide =
false;
6838 true, AllowConstructorName,
6839 AllowDeductionGuide, &TemplateKWLoc,
6852 DeclScopeObj.EnterDeclaratorScope();
6859 goto PastIdentifier;
6865 diag::err_expected_unqualified_id)
6868 goto PastIdentifier;
6872 "There's a C++-specific check for tok::identifier above");
6877 goto PastIdentifier;
6882 bool DiagnoseIdentifier =
false;
6886 DiagnoseIdentifier =
true;
6889 DiagnoseIdentifier =
6897 !isCXX11VirtSpecifier(Tok))
6899 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6900 if (DiagnoseIdentifier) {
6905 goto PastIdentifier;
6909 if (Tok.
is(tok::l_paren)) {
6914 RevertingTentativeParsingAction PA(*
this);
6919 goto PastIdentifier;
6926 ParseParenDeclarator(D);
6939 DeclScopeObj.EnterDeclaratorScope();
6950 diag::ext_abstract_pack_declarator_parens);
6952 if (Tok.
getKind() == tok::annot_pragma_parser_crash)
6954 if (Tok.
is(tok::l_square))
6955 return ParseMisplacedBracketDeclarator(D);
6963 diag::err_expected_member_name_or_semi_objcxx_keyword)
6970 goto PastIdentifier;
6973 diag::err_expected_member_name_or_semi)
6977 if (Tok.
getKind() == tok::TokenKind::kw_while) {
6978 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6980 if (Tok.
isOneOf(tok::period, tok::arrow))
6981 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.
is(tok::arrow);
6989 diag::err_expected_unqualified_id)
6994 diag::err_expected_either)
6995 << tok::identifier << tok::l_paren;
7004 "Haven't past the location of the identifier yet?");
7008 MaybeParseCXX11Attributes(D);
7011 if (Tok.
is(tok::l_paren)) {
7015 ParseScope PrototypeScope(
this,
7017 (IsFunctionDeclaration
7023 bool IsAmbiguous =
false;
7035 AllowImplicitTypename =
7043 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
7044 bool IsFunctionDecl =
7045 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
7046 TentativelyDeclaredIdentifiers.pop_back();
7047 if (!IsFunctionDecl)
7053 if (IsFunctionDeclaration)
7055 TemplateParameterDepth);
7056 ParseFunctionDeclarator(D, attrs,
T, IsAmbiguous);
7057 if (IsFunctionDeclaration)
7059 PrototypeScope.Exit();
7060 }
else if (Tok.
is(tok::l_square)) {
7061 ParseBracketDeclarator(D);
7069 if (!
T.consumeOpen())
7080 Diag(Tok, diag::err_requires_clause_inside_parens);
7094void Parser::ParseDecompositionDeclarator(
Declarator &D) {
7095 assert(Tok.
is(tok::l_square));
7097 TentativeParsingAction PA(*
this);
7101 if (isCXX11AttributeSpecifier())
7102 DiagnoseAndSkipCXX11Attributes();
7106 if (!(Tok.
is(tok::identifier) &&
7109 !(Tok.
is(tok::r_square) &&
7112 return ParseMisplacedBracketDeclarator(D);
7116 while (Tok.
isNot(tok::r_square)) {
7118 if (Tok.
is(tok::comma))
7121 if (Tok.
is(tok::identifier)) {
7123 Diag(EndLoc, diag::err_expected)
7126 Diag(Tok, diag::err_expected_comma_or_rsquare);
7129 SkipUntil(tok::r_square, tok::comma, tok::identifier,
7131 if (Tok.
is(tok::comma))
7133 else if (Tok.
isNot(tok::identifier))
7138 if (isCXX11AttributeSpecifier())
7139 DiagnoseAndSkipCXX11Attributes();
7141 if (Tok.
isNot(tok::identifier)) {
7142 Diag(Tok, diag::err_expected) << tok::identifier;
7151 if (isCXX11AttributeSpecifier()) {
7153 ? diag::warn_cxx23_compat_decl_attrs_on_binding
7154 : diag::ext_decl_attrs_on_binding);
7155 MaybeParseCXX11Attributes(Attrs);
7161 if (Tok.
isNot(tok::r_square))
7176 T.getCloseLocation());
7192void Parser::ParseParenDeclarator(
Declarator &D) {
7196 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7209 bool RequiresArg =
false;
7210 if (Tok.
is(tok::kw___attribute)) {
7211 ParseGNUAttributes(attrs);
7219 ParseMicrosoftTypeAttributes(attrs);
7222 if (Tok.
is(tok::kw___pascal))
7223 ParseBorlandTypeAttributes(attrs);
7235 }
else if (Tok.
is(tok::r_paren) ||
7238 isDeclarationSpecifier(
7240 isCXX11AttributeSpecifier()) {
7258 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7263 std::move(attrs),
T.getCloseLocation());
7269 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7282 ParseScope PrototypeScope(
this,
7286 ParseFunctionDeclarator(D, attrs,
T,
false, RequiresArg);
7287 PrototypeScope.Exit();
7290void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7292 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7300 bool IsCXX11MemberFunction =
7308 if (!IsCXX11MemberFunction)
7328 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.
CurContext), Q,
7329 IsCXX11MemberFunction);
7352void Parser::ParseFunctionDeclarator(
Declarator &D,
7357 assert(
getCurScope()->isFunctionPrototypeScope() &&
7358 "Should call from a Function scope");
7364 bool HasProto =
false;
7371 bool RefQualifierIsLValueRef =
true;
7389 StartLoc = LParenLoc;
7391 if (isFunctionDeclaratorIdentifierList()) {
7393 Diag(Tok, diag::err_argument_required_after_attribute);
7395 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7399 LocalEndLoc = RParenLoc;
7404 MaybeParseCXX11Attributes(FnAttrs);
7405 ProhibitAttributes(FnAttrs);
7407 if (Tok.
isNot(tok::r_paren))
7408 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7409 else if (RequiresArg)
7410 Diag(Tok, diag::err_argument_required_after_attribute);
7421 LocalEndLoc = RParenLoc;
7430 ParseTypeQualifierListOpt(
7431 DS, AR_NoAttributesParsed,
7433 false, llvm::function_ref<
void()>([&]() {
7441 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7442 EndLoc = RefQualifierLoc;
7444 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7445 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7463 GetLookAheadToken(0).is(tok::kw_noexcept) &&
7464 GetLookAheadToken(1).is(tok::l_paren) &&
7465 GetLookAheadToken(2).is(tok::kw_noexcept) &&
7466 GetLookAheadToken(3).is(tok::l_paren) &&
7467 GetLookAheadToken(4).is(tok::identifier) &&
7468 GetLookAheadToken(4).getIdentifierInfo()->isStr(
"swap")) {
7479 ESpecType = tryParseExceptionSpecification(Delayed,
7482 DynamicExceptionRanges,
7484 ExceptionSpecTokens);
7486 EndLoc = ESpecRange.
getEnd();
7490 MaybeParseCXX11Attributes(FnAttrs);
7493 LocalEndLoc = EndLoc;
7495 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7500 TrailingReturnType =
7506 MaybeParseCXX11Attributes(FnAttrs);
7518 if (!ND || isa<ParmVarDecl>(ND))
7520 DeclsInPrototype.push_back(ND);
7527 llvm::sort(DeclsInPrototype, [](
Decl *D1,
Decl *D2) {
7535 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7536 ParamInfo.size(), EllipsisLoc, RParenLoc,
7537 RefQualifierIsLValueRef, RefQualifierLoc,
7539 ESpecType, ESpecRange, DynamicExceptions.data(),
7540 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7541 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7542 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7543 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7545 std::move(FnAttrs), EndLoc);
7550bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7552 if (Tok.
isOneOf(tok::amp, tok::ampamp)) {
7554 diag::warn_cxx98_compat_ref_qualifier :
7555 diag::ext_ref_qualifier);
7557 RefQualifierIsLValueRef = Tok.
is(tok::amp);
7569bool Parser::isFunctionDeclaratorIdentifierList() {
7571 && Tok.
is(tok::identifier)
7572 && !TryAltiVecVectorToken()
7588 && (!Tok.
is(tok::eof) &&
7601void Parser::ParseFunctionDeclaratorIdentifierList(
7605 assert(!
getLangOpts().requiresStrictPrototypes() &&
7606 "Cannot parse an identifier list in C23 or C++");
7613 Diag(Tok, diag::ext_ident_list_in_param);
7616 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
7620 if (Tok.
isNot(tok::identifier)) {
7621 Diag(Tok, diag::err_expected) << tok::identifier;
7632 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7635 if (!ParamsSoFar.insert(ParmII).second) {
7636 Diag(Tok, diag::err_param_redefinition) << ParmII;
7682void Parser::ParseParameterDeclarationClause(
7691 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7712 IsACXXFunctionDeclaration) {
7734 ArgDeclSpecAttrs.takeAllFrom(FirstArgAttrs);
7737 MaybeParseCXX11Attributes(ArgDeclAttrs);
7740 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7761 Diag(ThisLoc, diag::err_requires_expr_explicit_object_parameter);
7764 ParsedTemplateInfo TemplateInfo;
7765 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7766 DeclSpecContext::DSC_normal,
7767 nullptr, AllowImplicitTypename);
7780 ParseDeclarator(ParmDeclarator);
7783 ParmDeclarator.SetRangeBegin(ThisLoc);
7786 MaybeParseGNUAttributes(ParmDeclarator);
7790 if (Tok.
is(tok::kw_requires)) {
7795 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7806 std::unique_ptr<CachedTokens> DefArgToks;
7810 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7811 ParmDeclarator.getNumTypeObjects() == 0) {
7813 Diag(DSStart, diag::err_missing_param);
7820 if (Tok.
is(tok::ellipsis) &&
7822 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7825 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7844 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7860 if (Tok.
is(tok::equal)) {
7871 ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument);
7887 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7888 DefArgResult = ParseBraceInitializer();
7890 if (Tok.
is(tok::l_paren) &&
NextToken().is(tok::l_brace)) {
7891 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7908 DefArgResult.
get());
7914 ParmDeclarator.getIdentifierLoc(),
7915 Param, std::move(DefArgToks)));
7922 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7924 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7929 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7930 << ParmEllipsis.
isValid() << ParmEllipsis;
7933 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7935 Diag(ParmDeclarator.getIdentifierLoc(),
7936 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7939 << !ParmDeclarator.hasName();
7941 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7960void Parser::ParseBracketDeclarator(
Declarator &D) {
7961 if (CheckProhibitedCXX11Attribute())
7969 if (Tok.
getKind() == tok::r_square) {
7972 MaybeParseCXX11Attributes(attrs);
7976 T.getOpenLocation(),
7977 T.getCloseLocation()),
7978 std::move(attrs),
T.getCloseLocation());
7980 }
else if (Tok.
getKind() == tok::numeric_constant &&
7981 GetLookAheadToken(1).is(tok::r_square)) {
7988 MaybeParseCXX11Attributes(attrs);
7992 T.getOpenLocation(),
7993 T.getCloseLocation()),
7994 std::move(attrs),
T.getCloseLocation());
7996 }
else if (Tok.
getKind() == tok::code_completion) {
8009 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
8017 bool isStar =
false;
8024 if (Tok.
is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
8028 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
8032 }
else if (Tok.
isNot(tok::r_square)) {
8050 Diag(StaticLoc, diag::err_unspecified_size_with_static);
8070 isStar, NumElements.
get(),
T.getOpenLocation(),
8071 T.getCloseLocation()),
8076void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
8077 assert(Tok.
is(tok::l_square) &&
"Missing opening bracket");
8084 while (Tok.
is(tok::l_square)) {
8085 ParseBracketDeclarator(TempDeclarator);
8091 if (Tok.
is(tok::semi))
8097 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
8102 if (TempDeclarator.getNumTypeObjects() == 0)
8106 bool NeedParens =
false;
8131 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
8144 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
8148 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8156 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8176void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
8177 assert(Tok.
isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
8178 "Not a typeof specifier");
8180 bool IsUnqual = Tok.
is(tok::kw_typeof_unqual);
8187 bool HasParens = Tok.
is(tok::l_paren);
8197 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange));
8213 const char *PrevSpec =
nullptr;
8221 Diag(StartLoc, DiagID) << PrevSpec;
8238 const char *PrevSpec =
nullptr;
8246 Diag(StartLoc, DiagID) << PrevSpec;
8252void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
8253 assert(Tok.
is(tok::kw__Atomic) &&
NextToken().is(tok::l_paren) &&
8254 "Not an atomic specifier");
8258 if (
T.consumeOpen())
8262 if (
Result.isInvalid()) {
8270 if (
T.getCloseLocation().isInvalid())
8276 const char *PrevSpec =
nullptr;
8281 Diag(StartLoc, DiagID) << PrevSpec;
8286bool Parser::TryAltiVecVectorTokenOutOfLine() {
8288 switch (Next.getKind()) {
8289 default:
return false;
8292 case tok::kw_signed:
8293 case tok::kw_unsigned:
8298 case tok::kw_double:
8301 case tok::kw___bool:
8302 case tok::kw___pixel:
8303 Tok.
setKind(tok::kw___vector);
8305 case tok::identifier:
8306 if (Next.getIdentifierInfo() == Ident_pixel) {
8307 Tok.
setKind(tok::kw___vector);
8310 if (Next.getIdentifierInfo() == Ident_bool ||
8311 Next.getIdentifierInfo() == Ident_Bool) {
8312 Tok.
setKind(tok::kw___vector);
8320 const char *&PrevSpec,
unsigned &DiagID,
8325 switch (Next.getKind()) {
8328 case tok::kw_signed:
8329 case tok::kw_unsigned:
8334 case tok::kw_double:
8337 case tok::kw___bool:
8338 case tok::kw___pixel:
8341 case tok::identifier:
8342 if (Next.getIdentifierInfo() == Ident_pixel) {
8346 if (Next.getIdentifierInfo() == Ident_bool ||
8347 Next.getIdentifierInfo() == Ident_Bool) {
8368TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8375 FileID FID = SourceMgr.createFileID(
8376 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8380 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8381 L.setParsingPreprocessorDirective(
true);
8387 Tokens.push_back(Tok);
8388 }
while (Tok.
isNot(tok::eod));
8393 Token &EndToken = Tokens.back();
8400 Tokens.push_back(Tok);
8403 PP.EnterTokenStream(Tokens,
false,
8411 ParseScope LocalScope(
this, 0);
8424 while (Tok.
isNot(tok::eof))
8428 if (Tok.
is(tok::eof) && Tok.
getEofData() == TypeStr.data())
8433void Parser::DiagnoseBitIntUse(
const Token &Tok) {
8437 assert(Tok.
isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8438 "expected either an _ExtInt or _BitInt token!");
8441 if (Tok.
is(tok::kw__ExtInt)) {
8442 Diag(
Loc, diag::warn_ext_int_deprecated)
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
static StringRef normalizeAttrName(const IdentifierInfo *Name, 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 bool attributeHasIdentifierArg(const IdentifierInfo &II)
Determine whether the given attribute has an identifier argument.
static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II)
Determine whether the given attribute treats kw_this as an identifier.
static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II)
Determine whether the given attribute requires parsing its arguments in an unevaluated context or not...
static bool isValidAfterIdentifierInDeclarator(const Token &T)
isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the specified token is valid after t...
static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II)
Determine whether the given attribute has a variadic identifier argument.
static bool attributeAcceptsExprPack(const IdentifierInfo &II)
Determine if an attribute accepts parameter packs.
static bool isPipeDeclarator(const Declarator &D)
static SourceLocation getMissingDeclaratorIdLoc(Declarator &D, SourceLocation Loc)
static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS, Parser &P)
static bool VersionNumberSeparator(const char Separator)
static bool attributeIsTypeArgAttr(const IdentifierInfo &II)
Determine whether the given attribute parses a type argument.
static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, DeclaratorContext TheContext)
static ParsedAttributeArgumentsProperties attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II)
Determine whether the given attribute has an identifier argument.
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 ...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
const clang::PrintingPolicy & getPrintingPolicy() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
The result of parsing/analyzing an expression, statement etc.
@ 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 "_Imaginary" (...
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...
SourceLocation getTypeSpecTypeLoc() const
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
bool isInvalidDecl() const
SourceLocation getLocation() const
Information about one declarator, including the parsed type information and the identifier.
bool isFunctionDeclarator(unsigned &idx) const
isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...
bool isPastIdentifier() const
isPastIdentifier - Return true if we have parsed beyond the point where the name would appear.
void SetRangeBegin(SourceLocation Loc)
SetRangeBegin - Set the start of the source range to Loc, unless it's invalid.
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
void setCommaLoc(SourceLocation CL)
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
SourceLocation getIdentifierLoc() const
void SetIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
bool mayOmitIdentifier() const
mayOmitIdentifier - Return true if the identifier is either optional or not allowed.
SourceLocation getEndLoc() const LLVM_READONLY
bool mayBeFollowedByCXXDirectInit() const
mayBeFollowedByCXXDirectInit - Return true if the declarator can be followed by a C++ direct initiali...
bool hasGroupingParens() const
void setDecompositionBindings(SourceLocation LSquareLoc, MutableArrayRef< DecompositionDeclarator::Binding > Bindings, SourceLocation RSquareLoc)
Set the decomposition bindings for this declarator.
void setInvalidType(bool Val=true)
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
bool mayHaveIdentifier() const
mayHaveIdentifier - Return true if the identifier is either optional or required.
void setGroupingParens(bool flag)
SourceLocation getEllipsisLoc() const
DeclaratorContext getContext() const
SourceLocation getBeginLoc() const LLVM_READONLY
void setTrailingRequiresClause(Expr *TRC)
Sets a trailing requires clause for this declarator.
void setHasInitializer(bool Val=true)
UnqualifiedId & getName()
Retrieve the name specified by this declarator.
void setTemplateParameterLists(ArrayRef< TemplateParameterList * > TPLs)
Sets the template parameter lists that preceded the declarator.
bool isFirstDeclarator() const
bool hasTrailingRequiresClause() const
Determine whether a trailing requires clause was written in this declarator.
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
The template parameter lists that preceded the declarator.
bool isFunctionDeclaratorAFunctionDeclaration() const
Return true if a function declarator at this position would be a function declaration.
void clear()
Reset the contents of this Declarator.
void setAsmLabel(Expr *E)
void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &&attrs, SourceLocation EndLoc)
AddTypeInfo - Add a chunk to this declarator.
void ExtendWithDeclSpec(const DeclSpec &DS)
ExtendWithDeclSpec - Extend the declarator source range to include the given declspec,...
void SetRangeEnd(SourceLocation Loc)
SetRangeEnd - Set the end of the source range to Loc, unless it's invalid.
void setExtension(bool Val=true)
bool isInvalidType() const
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
void setEllipsisLoc(SourceLocation EL)
const IdentifierInfo * getIdentifier() const
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.
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 bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, const LangOptions &LangOpts, bool IgnoreWhiteSpace=false)
Relex the token at the specified location.
static std::optional< Token > findNextToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Finds the token that comes right after the given 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.
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA)
ParsedAttr * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Form formUsed)
Add microsoft __delspec(property) attribute.
ParsedAttr * addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, ParsedAttr::Form form)
Add type_tag_for_datatype attribute.
ParsedAttr * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ParsedType typeArg, ParsedAttr::Form formUsed, SourceLocation ellipsisLoc=SourceLocation())
Add an attribute with a single type argument.
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 type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
DeclGroupPtrTy ParseOpenACCDirectiveDecl()
Placeholder for now, should just ignore the directives after emitting a diagnostic.
Sema & getActions() const
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
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.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
Scope * getCurScope() const
SourceLocation getEndOfPreviousToken()
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
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
ExprResult ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast=NotTypeCast)
const LangOptions & getLangOpts() const
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
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.
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...
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)
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...
@ NC_Unknown
This name is not a type or template in this context, but might be something else.
@ NC_VarTemplate
The name was classified as a variable template name.
@ NC_NonType
The name was classified as a specific non-type, non-template declaration.
@ NC_TypeTemplate
The name was classified as a template whose specializations are types.
@ NC_Error
Classification failed; an error has been produced.
@ NC_FunctionTemplate
The name was classified as a function template name.
@ NC_DependentNonType
The name denotes a member of a dependent type that could not be resolved.
@ NC_UndeclaredNonType
The name was classified as an ADL-only function name.
@ NC_UndeclaredTemplate
The name was classified as an ADL-only function template name.
@ NC_Keyword
The name has been typo-corrected to a keyword.
@ NC_Type
The name was classified as a type.
@ NC_OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ NC_Concept
The name was classified as a concept name.
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 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...
bool isLibstdcxxEagerExceptionSpecHack(const Declarator &D)
Determine if we're in a case where we need to (incorrectly) eagerly parse an exception specification ...
Decl * ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant, SourceLocation IdLoc, IdentifierInfo *Id, const ParsedAttributesView &Attrs, SourceLocation EqualLoc, Expr *Val)
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
bool isDeclaratorFunctionLike(Declarator &D)
Determine whether.
bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody)
Perform ODR-like check for C/ObjC when merging tag types from modules.
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.
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 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.
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
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.
void setEofData(const void *D)
SourceRange getAnnotationRange() const
SourceRange of the group of tokens that this annotation token represents.
void setLocation(SourceLocation L)
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
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.
SourceLocation EndLocation
The location of the last token that describes this unqualified-id.
SourceRange getSourceRange() const LLVM_READONLY
Return the source range that covers this unqualified-id.
SourceLocation StartLocation
The location of the first token that describes this unqualified-id, which will be the location of the...
UnqualifiedIdKind getKind() const
Determine what kind of name we have.
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.
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)
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>.
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &Second, ParsedAttributes &Result)
Consumes the attributes from First and Second and concatenates them into Result.
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.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
LangAS
Defines the address space values used by the address space qualifier of QualType.
int hasAttribute(AttributeCommonInfo::Syntax Syntax, const IdentifierInfo *Scope, const IdentifierInfo *Attr, const TargetInfo &Target, const LangOptions &LangOpts)
Return the version number associated with the attribute if we recognize and implement the attribute s...
@ 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
@ 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
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
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.
enum clang::DeclaratorChunk::@221 Kind
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)
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.
Wraps an identifier and optional source location for the identifier.
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
bool isStringLiteralArg(unsigned I) const
Describes how types, statements, expressions, and declarations should be printed.
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