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);
165 LateParsedAttrList *LateAttrs,
173 if (Tok.
isNot(tok::l_paren)) {
174 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
175 ParsedAttr::Form::GNU());
179 bool LateParse =
false;
182 else if (LateAttrs->lateAttrParseExperimentalExtOnly()) {
186 LateParse =
getLangOpts().ExperimentalLateParseAttributes &&
199 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc,
nullptr,
205 LateParsedAttribute *LA =
206 new LateParsedAttribute(
this, *AttrName, AttrNameLoc);
207 LateAttrs->push_back(LA);
211 if (!ClassStack.empty() && !LateAttrs->parseSoon())
212 getCurrentClass().LateParsedDeclarations.push_back(LA);
216 LA->Toks.push_back(Tok);
219 ConsumeAndStoreUntil(tok::r_paren, LA->Toks,
true);
224 LA->Toks.push_back(Eof);
272 assert(Tok.
is(tok::kw___attribute) &&
"Not a GNU attribute list!");
277 while (Tok.
is(tok::kw___attribute)) {
279 unsigned OldNumAttrs = Attrs.
size();
280 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
282 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
287 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"(")) {
300 if (Tok.
is(tok::code_completion)) {
307 if (ParseSingleGNUAttribute(Attrs, EndLoc, LateAttrs,
D))
309 }
while (Tok.
is(tok::comma));
311 if (ExpectAndConsume(tok::r_paren))
314 if (ExpectAndConsume(tok::r_paren))
321 if (!
SM.isWrittenInBuiltinFile(
SM.getSpellingLoc(AttrTokLoc)) &&
324 StringRef FoundName =
328 for (
unsigned i = OldNumAttrs; i < Attrs.
size(); ++i)
329 Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.
getBegin());
332 for (
unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
333 (*LateAttrs)[i]->MacroII = MacroII;
346#define CLANG_ATTR_IDENTIFIER_ARG_LIST
348#include "clang/Parse/AttrParserStringSwitches.inc"
350#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
358#define CLANG_ATTR_STRING_LITERAL_ARG_LIST
360#include "clang/Parse/AttrParserStringSwitches.inc"
362#undef CLANG_ATTR_STRING_LITERAL_ARG_LIST
369#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
371#include "clang/Parse/AttrParserStringSwitches.inc"
373#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
380#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
382#include "clang/Parse/AttrParserStringSwitches.inc"
384#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
391#define CLANG_ATTR_ACCEPTS_EXPR_PACK
393#include "clang/Parse/AttrParserStringSwitches.inc"
395#undef CLANG_ATTR_ACCEPTS_EXPR_PACK
402#define CLANG_ATTR_TYPE_ARG_LIST
404#include "clang/Parse/AttrParserStringSwitches.inc"
406#undef CLANG_ATTR_TYPE_ARG_LIST
413#define CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
415#include "clang/Parse/AttrParserStringSwitches.inc"
417#undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
425#define CLANG_ATTR_ARG_CONTEXT_LIST
427#include "clang/Parse/AttrParserStringSwitches.inc"
429#undef CLANG_ATTR_ARG_CONTEXT_LIST
433 assert(Tok.
is(tok::identifier) &&
"expected an identifier");
451 if (Tok.
isNot(tok::r_paren))
454 if (
Parens.consumeClose())
463 ScopeName, ScopeLoc,
T.get(), Form);
466 ScopeName, ScopeLoc,
nullptr, 0, Form);
470Parser::ParseUnevaluatedStringInAttribute(
const IdentifierInfo &AttrName) {
471 if (Tok.
is(tok::l_paren)) {
474 ExprResult Res = ParseUnevaluatedStringInAttribute(AttrName);
475 Paren.consumeClose();
478 if (!isTokenStringLiteral()) {
486bool Parser::ParseAttributeArgumentList(
489 bool SawError =
false;
494 Expr = ParseUnevaluatedStringInAttribute(AttrName);
496 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
497 Expr = ParseBraceInitializer();
503 if (Tok.
is(tok::ellipsis))
505 else if (Tok.
is(tok::code_completion)) {
516 if (
Expr.isInvalid()) {
526 Exprs.push_back(
Expr.get());
528 if (Tok.
isNot(tok::comma))
533 checkPotentialAngleBracketDelimiter(Comma);
540 for (
auto &
E : Exprs) {
549unsigned Parser::ParseAttributeArgsCommon(
558 bool AttributeIsTypeArgAttr =
560 bool AttributeHasVariadicIdentifierArg =
564 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
568 if (Tok.
is(tok::identifier)) {
570 bool IsIdentifierArg =
571 AttributeHasVariadicIdentifierArg ||
582 IsIdentifierArg = Next.isOneOf(tok::r_paren, tok::comma);
586 ArgExprs.push_back(ParseIdentifierLoc());
590 if (!ArgExprs.empty() ? Tok.
is(tok::comma) : Tok.
isNot(tok::r_paren)) {
592 if (!ArgExprs.empty())
595 if (AttributeIsTypeArgAttr) {
603 TheParsedType =
T.get();
604 }
else if (AttributeHasVariadicIdentifierArg ||
614 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
618 if (Tok.
is(tok::identifier)) {
619 ArgExprs.push_back(ParseIdentifierLoc());
637 ArgExprs.push_back(ArgExpr.
get());
653 ExprVector ParsedExprs;
657 if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties)) {
663 for (
size_t I = 0; I < ParsedExprs.size(); ++I) {
664 if (!isa<PackExpansionExpr>(ParsedExprs[I]))
669 diag::err_attribute_argument_parm_pack_not_supported)
676 ArgExprs.insert(ArgExprs.end(), ParsedExprs.begin(), ParsedExprs.end());
681 if (!ExpectAndConsume(tok::r_paren)) {
684 if (AttributeIsTypeArgAttr && !TheParsedType.
get().
isNull()) {
686 ScopeName, ScopeLoc, TheParsedType, Form);
689 ArgExprs.data(), ArgExprs.size(), Form);
696 return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.
get().
isNull());
701void Parser::ParseGNUAttributeArgs(
706 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
711 if (AttrKind == ParsedAttr::AT_Availability) {
712 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
715 }
else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
716 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
717 ScopeName, ScopeLoc, Form);
719 }
else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
720 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
721 ScopeName, ScopeLoc, Form);
723 }
else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
724 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
727 }
else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
728 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
729 ScopeName, ScopeLoc, Form);
732 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName,
735 }
else if (AttrKind == ParsedAttr::AT_CountedBy ||
736 AttrKind == ParsedAttr::AT_CountedByOrNull ||
737 AttrKind == ParsedAttr::AT_SizedBy ||
738 AttrKind == ParsedAttr::AT_SizedByOrNull) {
739 ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
742 }
else if (AttrKind == ParsedAttr::AT_CXXAssume) {
743 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc, Form);
749 std::optional<ParseScope> PrototypeScope;
751 D &&
D->isFunctionDeclarator()) {
756 for (
unsigned i = 0; i != FTI.
NumParams; ++i) {
762 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
766unsigned Parser::ParseClangAttributeArgs(
770 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
777 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
778 ScopeName, ScopeLoc, Form);
779 case ParsedAttr::AT_ExternalSourceSymbol:
780 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
781 ScopeName, ScopeLoc, Form);
783 case ParsedAttr::AT_Availability:
784 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
787 case ParsedAttr::AT_ObjCBridgeRelated:
788 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
789 ScopeName, ScopeLoc, Form);
791 case ParsedAttr::AT_SwiftNewType:
792 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
795 case ParsedAttr::AT_TypeTagForDatatype:
796 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
797 ScopeName, ScopeLoc, Form);
800 case ParsedAttr::AT_CXXAssume:
801 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc, Form);
804 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
810 unsigned ExistingAttrs = Attrs.
size();
824 if (AttrName->
getName() ==
"property") {
830 T.expectAndConsume(diag::err_expected_lparen_after,
839 bool HasInvalidAccessor =
false;
844 if (!Tok.
is(tok::identifier)) {
846 if (Tok.
is(tok::r_paren) && !HasInvalidAccessor &&
847 AccessorNames[AK_Put] ==
nullptr &&
848 AccessorNames[AK_Get] ==
nullptr) {
849 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
860 if (KindStr ==
"get") {
862 }
else if (KindStr ==
"put") {
866 }
else if (KindStr ==
"set") {
867 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
874 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
876 HasInvalidAccessor =
true;
877 goto next_property_accessor;
881 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
882 HasInvalidAccessor =
true;
901 if (!Tok.
is(tok::identifier)) {
906 if (Kind == AK_Invalid) {
908 }
else if (AccessorNames[Kind] !=
nullptr) {
910 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
916 next_property_accessor:
922 if (Tok.
is(tok::r_paren))
925 Diag(Tok.
getLocation(), diag::err_ms_property_expected_comma_or_rparen);
930 if (!HasInvalidAccessor)
932 AccessorNames[AK_Get], AccessorNames[AK_Put],
933 ParsedAttr::Form::Declspec());
935 return !HasInvalidAccessor;
939 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
945 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) << AttrName;
958 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
959 assert(Tok.
is(tok::kw___declspec) &&
"Not a declspec!");
964 while (Tok.
is(tok::kw___declspec)) {
967 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
973 while (Tok.
isNot(tok::r_paren)) {
978 if (Tok.
is(tok::code_completion)) {
987 bool IsString = Tok.
getKind() == tok::string_literal;
988 if (!IsString && Tok.
getKind() != tok::identifier &&
989 Tok.
getKind() != tok::kw_restrict) {
990 Diag(Tok, diag::err_ms_declspec_type);
1000 StringRef Str = PP.
getSpelling(Tok, StrBuffer, &Invalid);
1006 AttrNameLoc = ConsumeStringToken();
1012 bool AttrHandled =
false;
1015 if (Tok.
is(tok::l_paren))
1016 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
1017 else if (AttrName->
getName() ==
"property")
1023 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1024 ParsedAttr::Form::Declspec());
1027 EndLoc =
T.getCloseLocation();
1038 case tok::kw___fastcall:
1039 case tok::kw___stdcall:
1040 case tok::kw___thiscall:
1041 case tok::kw___regcall:
1042 case tok::kw___cdecl:
1043 case tok::kw___vectorcall:
1044 case tok::kw___ptr64:
1046 case tok::kw___ptr32:
1047 case tok::kw___sptr:
1048 case tok::kw___uptr: {
1051 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1061void Parser::ParseWebAssemblyFuncrefTypeAttribute(
ParsedAttributes &attrs) {
1062 assert(Tok.
is(tok::kw___funcref));
1066 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
1072 attrs.
addNew(AttrName, AttrNameLoc,
nullptr,
1077void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
1083 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) <<
Range;
1093 case tok::kw_volatile:
1094 case tok::kw___fastcall:
1095 case tok::kw___stdcall:
1096 case tok::kw___thiscall:
1097 case tok::kw___cdecl:
1098 case tok::kw___vectorcall:
1099 case tok::kw___ptr32:
1100 case tok::kw___ptr64:
1102 case tok::kw___unaligned:
1103 case tok::kw___sptr:
1104 case tok::kw___uptr:
1115 while (Tok.
is(tok::kw___pascal)) {
1118 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1125 while (Tok.
is(tok::kw___kernel)) {
1128 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1134 while (Tok.
is(tok::kw___noinline__)) {
1137 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1138 tok::kw___noinline__);
1145 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1149bool Parser::isHLSLQualifier(
const Token &Tok)
const {
1150 return Tok.
is(tok::kw_groupshared);
1157 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0, Kind);
1165 case tok::kw__Nonnull:
1166 case tok::kw__Nullable:
1167 case tok::kw__Nullable_result:
1168 case tok::kw__Null_unspecified: {
1172 Diag(AttrNameLoc, diag::ext_nullability)
1174 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1185 return (Separator ==
'.' || Separator ==
'_');
1199 if (!Tok.
is(tok::numeric_constant)) {
1200 Diag(Tok, diag::err_expected_version);
1203 return VersionTuple();
1212 const char *ThisTokBegin = &Buffer[0];
1216 unsigned ActualLength = PP.
getSpelling(Tok, ThisTokBegin, &Invalid);
1218 return VersionTuple();
1221 unsigned AfterMajor = 0;
1223 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
1224 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
1228 if (AfterMajor == 0) {
1229 Diag(Tok, diag::err_expected_version);
1232 return VersionTuple();
1235 if (AfterMajor == ActualLength) {
1240 Diag(Tok, diag::err_zero_version);
1241 return VersionTuple();
1244 return VersionTuple(Major);
1247 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1249 || (AfterMajor + 1 == ActualLength)) {
1250 Diag(Tok, diag::err_expected_version);
1253 return VersionTuple();
1257 unsigned AfterMinor = AfterMajor + 1;
1259 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
1260 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
1264 if (AfterMinor == ActualLength) {
1268 if (Major == 0 && Minor == 0) {
1269 Diag(Tok, diag::err_zero_version);
1270 return VersionTuple();
1273 return VersionTuple(Major, Minor);
1276 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1279 Diag(Tok, diag::err_expected_version);
1282 return VersionTuple();
1286 if (AfterMajorSeparator != AfterMinorSeparator)
1287 Diag(Tok, diag::warn_expected_consistent_version_separator);
1290 unsigned AfterSubminor = AfterMinor + 1;
1291 unsigned Subminor = 0;
1292 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
1293 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
1297 if (AfterSubminor != ActualLength) {
1298 Diag(Tok, diag::err_expected_version);
1301 return VersionTuple();
1304 return VersionTuple(Major, Minor, Subminor);
1332void Parser::ParseAvailabilityAttribute(
1336 enum { Introduced, Deprecated, Obsoleted,
Unknown };
1343 if (
T.consumeOpen()) {
1344 Diag(Tok, diag::err_expected) << tok::l_paren;
1349 if (Tok.
isNot(tok::identifier)) {
1350 Diag(Tok, diag::err_availability_expected_platform);
1357 if (Ident->getName().contains(
"xrOS") || Ident->getName().contains(
"xros"))
1358 Diag(Platform->
Loc, diag::warn_availability_unknown_platform) << Ident;
1360 else if (Ident->getName() ==
"macosx")
1364 else if (Ident->getName() ==
"macosx_app_extension")
1368 AvailabilityAttr::canonicalizePlatformName(Ident->getName()));
1372 if (ExpectAndConsume(tok::comma)) {
1379 if (!Ident_introduced) {
1394 if (Tok.
isNot(tok::identifier)) {
1395 Diag(Tok, diag::err_availability_expected_change);
1402 if (Keyword == Ident_strict) {
1404 Diag(KeywordLoc, diag::err_availability_redundant)
1407 StrictLoc = KeywordLoc;
1411 if (Keyword == Ident_unavailable) {
1412 if (UnavailableLoc.
isValid()) {
1413 Diag(KeywordLoc, diag::err_availability_redundant)
1416 UnavailableLoc = KeywordLoc;
1420 if (Keyword == Ident_deprecated && Platform->
Ident &&
1423 if (Changes[Deprecated].KeywordLoc.
isValid()) {
1424 Diag(KeywordLoc, diag::err_availability_redundant)
1431 Changes[Deprecated].
Version = VersionTuple(1);
1435 if (Keyword == Ident_environment) {
1436 if (EnvironmentLoc !=
nullptr) {
1437 Diag(KeywordLoc, diag::err_availability_redundant)
1442 if (Tok.
isNot(tok::equal)) {
1443 Diag(Tok, diag::err_expected_after) << Keyword << tok::equal;
1448 if (Keyword == Ident_message || Keyword == Ident_replacement) {
1449 if (!isTokenStringLiteral()) {
1450 Diag(Tok, diag::err_expected_string_literal)
1455 if (Keyword == Ident_message) {
1463 if (Keyword == Ident_environment) {
1464 if (Tok.
isNot(tok::identifier)) {
1465 Diag(Tok, diag::err_availability_expected_environment);
1469 EnvironmentLoc = ParseIdentifierLoc();
1475 if ((Keyword == Ident_introduced || Keyword == Ident_deprecated) &&
1476 Tok.
is(tok::identifier)) {
1480 if (Keyword == Ident_introduced)
1481 UnavailableLoc = KeywordLoc;
1487 VersionTuple Version = ParseVersionTuple(VersionRange);
1489 if (Version.empty()) {
1495 if (Keyword == Ident_introduced)
1497 else if (Keyword == Ident_deprecated)
1499 else if (Keyword == Ident_obsoleted)
1505 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1506 Diag(KeywordLoc, diag::err_availability_redundant)
1509 Changes[Index].VersionRange.
getEnd());
1513 Changes[Index].
Version = Version;
1516 Diag(KeywordLoc, diag::err_availability_unknown_change)
1517 << Keyword << VersionRange;
1523 if (
T.consumeClose())
1527 *endLoc =
T.getCloseLocation();
1531 if (UnavailableLoc.
isValid()) {
1532 bool Complained =
false;
1533 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1534 if (Changes[Index].KeywordLoc.
isValid()) {
1536 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1538 Changes[Index].VersionRange.
getEnd());
1549 attrs.
addNew(&Availability,
1550 SourceRange(AvailabilityLoc,
T.getCloseLocation()), ScopeName,
1551 ScopeLoc, Platform, Changes[Introduced], Changes[Deprecated],
1552 Changes[Obsoleted], UnavailableLoc, MessageExpr.
get(), Form,
1553 StrictLoc, ReplacementExpr.
get(), EnvironmentLoc);
1570void Parser::ParseExternalSourceSymbolAttribute(
1576 if (
T.expectAndConsume())
1580 if (!Ident_language) {
1588 bool HasLanguage =
false;
1590 bool HasDefinedIn =
false;
1593 bool HasUSR =
false;
1597 if (Tok.
isNot(tok::identifier)) {
1598 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1605 if (Keyword == Ident_generated_declaration) {
1606 if (GeneratedDeclaration) {
1607 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) << Keyword;
1611 GeneratedDeclaration = ParseIdentifierLoc();
1615 if (Keyword != Ident_language && Keyword != Ident_defined_in &&
1616 Keyword != Ident_USR) {
1617 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1623 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1629 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1631 if (Keyword == Ident_language)
1633 else if (Keyword == Ident_USR)
1636 HasDefinedIn =
true;
1638 if (!isTokenStringLiteral()) {
1639 Diag(Tok, diag::err_expected_string_literal)
1642 Keyword == Ident_language
1644 : (Keyword == Ident_defined_in ? 1 : 2));
1648 if (Keyword == Ident_language) {
1650 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1656 }
else if (Keyword == Ident_USR) {
1658 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1665 assert(Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1667 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1677 if (
T.consumeClose())
1680 *EndLoc =
T.getCloseLocation();
1685 ScopeName, ScopeLoc, Args, std::size(Args), Form);
1699void Parser::ParseObjCBridgeRelatedAttribute(
1705 if (
T.consumeOpen()) {
1706 Diag(Tok, diag::err_expected) << tok::l_paren;
1711 if (Tok.
isNot(tok::identifier)) {
1712 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1717 if (ExpectAndConsume(tok::comma)) {
1726 if (Tok.
is(tok::identifier)) {
1729 Diag(Tok, diag::err_objcbridge_related_selector_name);
1735 if (Tok.
is(tok::colon))
1736 Diag(Tok, diag::err_objcbridge_related_selector_name);
1738 Diag(Tok, diag::err_expected) << tok::comma;
1746 if (Tok.
is(tok::identifier))
1748 else if (Tok.
isNot(tok::r_paren)) {
1749 Diag(Tok, diag::err_expected) << tok::r_paren;
1755 if (
T.consumeClose())
1759 *EndLoc =
T.getCloseLocation();
1762 Attrs.
addNew(&ObjCBridgeRelated,
1763 SourceRange(ObjCBridgeRelatedLoc,
T.getCloseLocation()),
1764 ScopeName, ScopeLoc, RelatedClass, ClassMethod, InstanceMethod,
1768void Parser::ParseSwiftNewTypeAttribute(
1775 if (
T.consumeOpen()) {
1776 Diag(Tok, diag::err_expected) << tok::l_paren;
1780 if (Tok.
is(tok::r_paren)) {
1785 if (Tok.
isNot(tok::kw_struct) && Tok.
isNot(tok::kw_enum)) {
1786 Diag(Tok, diag::warn_attribute_type_not_supported)
1788 if (!isTokenSpecial())
1799 if (
T.consumeClose())
1802 *EndLoc =
T.getCloseLocation();
1806 ScopeName, ScopeLoc, Args, std::size(Args), Form);
1809void Parser::ParseTypeTagForDatatypeAttribute(
1813 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1818 if (Tok.
isNot(tok::identifier)) {
1819 Diag(Tok, diag::err_expected) << tok::identifier;
1825 if (ExpectAndConsume(tok::comma)) {
1837 bool LayoutCompatible =
false;
1838 bool MustBeNull =
false;
1840 if (Tok.
isNot(tok::identifier)) {
1841 Diag(Tok, diag::err_expected) << tok::identifier;
1846 if (Flag->
isStr(
"layout_compatible"))
1847 LayoutCompatible =
true;
1848 else if (Flag->
isStr(
"must_be_null"))
1851 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1858 if (!
T.consumeClose()) {
1860 ArgumentKind, MatchingCType.
get(),
1861 LayoutCompatible, MustBeNull, Form);
1865 *EndLoc =
T.getCloseLocation();
1876bool Parser::DiagnoseProhibitedCXX11Attribute() {
1877 assert(Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square));
1879 switch (isCXX11AttributeSpecifier(
true)) {
1880 case CAK_NotAttributeSpecifier:
1884 case CAK_InvalidAttributeSpecifier:
1888 case CAK_AttributeSpecifier:
1893 assert(Tok.
is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1895 Diag(BeginLoc, diag::err_attributes_not_allowed)
1899 llvm_unreachable(
"All cases handled above.");
1908 assert((Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square)) ||
1915 ParseCXX11Attributes(Attrs);
1918 (Keyword ?
Diag(
Loc, diag::err_keyword_not_allowed) << Keyword
1919 :
Diag(
Loc, diag::err_attributes_not_allowed))
1924void Parser::DiagnoseProhibitedAttributes(
1926 auto *FirstAttr = Attrs.
empty() ? nullptr : &Attrs.
front();
1927 if (CorrectLocation.
isValid()) {
1929 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1930 ?
Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1931 :
Diag(CorrectLocation, diag::err_attributes_misplaced))
1936 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1944 unsigned AttrDiagID,
1945 unsigned KeywordDiagID,
1946 bool DiagnoseEmptyAttrs,
1947 bool WarnOnUnknownAttrs) {
1957 if (FirstLSquare.
is(tok::l_square)) {
1958 std::optional<Token> SecondLSquare =
1961 if (SecondLSquare && SecondLSquare->is(tok::l_square)) {
1972 if (AL.isRegularKeywordAttribute()) {
1973 Diag(AL.getLoc(), KeywordDiagID) << AL;
1977 if (!AL.isStandardAttributeSyntax())
1980 if (WarnOnUnknownAttrs)
1981 Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
1982 << AL << AL.getRange();
1984 Diag(AL.getLoc(), AttrDiagID) << AL;
1992 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1993 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1994 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
2013 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
2014 AL.isDeclspecAttribute()) ||
2015 AL.isMicrosoftAttribute())
2016 ToBeMoved.push_back(&AL);
2051 Decl *SingleDecl =
nullptr;
2053 case tok::kw_template:
2054 case tok::kw_export:
2055 ProhibitAttributes(DeclAttrs);
2056 ProhibitAttributes(DeclSpecAttrs);
2057 return ParseDeclarationStartingWithTemplate(Context, DeclEnd, DeclAttrs);
2058 case tok::kw_inline:
2061 ProhibitAttributes(DeclAttrs);
2062 ProhibitAttributes(DeclSpecAttrs);
2064 return ParseNamespace(Context, DeclEnd, InlineLoc);
2066 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
2067 true,
nullptr, DeclSpecStart);
2069 case tok::kw_cbuffer:
2070 case tok::kw_tbuffer:
2071 SingleDecl = ParseHLSLBuffer(DeclEnd);
2073 case tok::kw_namespace:
2074 ProhibitAttributes(DeclAttrs);
2075 ProhibitAttributes(DeclSpecAttrs);
2076 return ParseNamespace(Context, DeclEnd);
2077 case tok::kw_using: {
2080 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
2083 case tok::kw_static_assert:
2084 case tok::kw__Static_assert:
2085 ProhibitAttributes(DeclAttrs);
2086 ProhibitAttributes(DeclSpecAttrs);
2087 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
2090 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
2091 true,
nullptr, DeclSpecStart);
2123 bool RequireSemi, ForRangeInit *FRI,
SourceLocation *DeclSpecStart) {
2126 OriginalDeclSpecAttrs.
addAll(DeclSpecAttrs.
begin(), DeclSpecAttrs.
end());
2127 OriginalDeclSpecAttrs.
Range = DeclSpecAttrs.
Range;
2133 ParsedTemplateInfo TemplateInfo;
2134 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
2135 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none, DSContext);
2140 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
2145 if (Tok.
is(tok::semi)) {
2146 ProhibitAttributes(DeclAttrs);
2153 DS.complete(TheDecl);
2155 Decl* decls[] = {AnonRecord, TheDecl};
2167 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
2174 case tok::annot_cxxscope:
2175 case tok::annot_template_id:
2177 case tok::code_completion:
2178 case tok::coloncolon:
2180 case tok::kw___attribute:
2181 case tok::kw_operator:
2197 case tok::identifier:
2199 case tok::code_completion:
2200 case tok::coloncolon:
2203 case tok::equalequal:
2204 case tok::kw_alignas:
2206 case tok::kw___attribute:
2224 case tok::identifier:
2247 if (Tok.
isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
2271 case tok::kw_inline:
2276 (!ParsingInObjCContainer || CurParsedObjCImpl))
2280 case tok::kw_namespace:
2285 (!ParsingInObjCContainer || CurParsedObjCImpl))
2291 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2292 ParsingInObjCContainer)
2304 case tok::annot_module_begin:
2305 case tok::annot_module_end:
2306 case tok::annot_module_include:
2307 case tok::annot_repl_input_end:
2324 ParsedTemplateInfo &TemplateInfo,
2326 ForRangeInit *FRI) {
2332 LocalAttrs.takeAllFrom(Attrs);
2334 if (TemplateInfo.TemplateParams)
2335 D.setTemplateParameterLists(*TemplateInfo.TemplateParams);
2337 bool IsTemplateSpecOrInst =
2338 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
2339 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
2344 if (IsTemplateSpecOrInst)
2348 if (!
D.hasName() && !
D.mayOmitIdentifier()) {
2354 while (MaybeParseHLSLAnnotations(
D))
2357 if (Tok.
is(tok::kw_requires))
2358 ParseTrailingRequiresClause(
D);
2363 LateParsedAttrList LateParsedAttrs(
true);
2364 if (
D.isFunctionDeclarator()) {
2365 MaybeParseGNUAttributes(
D, &LateParsedAttrs);
2370 if (Tok.
is(tok::kw__Noreturn)) {
2372 const char *PrevSpec;
2378 MaybeParseGNUAttributes(
D, &LateParsedAttrs);
2379 Fixit &= Tok.
isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2381 Diag(
Loc, diag::err_c11_noreturn_misplaced)
2383 << (Fixit ?
FixItHint::CreateInsertion(
D.getBeginLoc(),
"_Noreturn ")
2388 if (Tok.
is(tok::equal) &&
NextToken().is(tok::code_completion)) {
2399 while (
auto Specifier = isCXX11VirtSpecifier()) {
2400 Diag(Tok, diag::err_virt_specifier_outside_class)
2408 if (!isDeclarationAfterDeclarator()) {
2414 if (isStartOfFunctionDefinition(
D)) {
2424 diag::err_function_declared_typedef)
2428 Decl *TheDecl =
nullptr;
2430 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
2434 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2435 TheDecl = ParseFunctionDefinition(
D, ParsedTemplateInfo(),
2440 Diag(
D.getIdentifierLoc(),
2441 diag::err_explicit_instantiation_with_definition)
2449 LAngleLoc,
nullptr));
2451 TheDecl = ParseFunctionDefinition(
2453 ParsedTemplateInfo(&FakedParamLists,
2460 ParseFunctionDefinition(
D, TemplateInfo, &LateParsedAttrs);
2467 Tok.
is(tok::kw_namespace)) {
2477 Diag(Tok, diag::err_expected_fn_body);
2482 if (Tok.
is(tok::l_brace)) {
2483 Diag(Tok, diag::err_function_definition_not_allowed);
2491 if (ParseAsmAttributesAfterDeclarator(
D))
2500 if (FRI && (Tok.
is(tok::colon) || isTokIdentifier_in())) {
2501 bool IsForRangeLoop =
false;
2503 IsForRangeLoop =
true;
2514 LastRecord.RebuildDefaultArgOrDefaultInit =
true;
2519 if (Tok.
is(tok::l_brace))
2520 FRI->RangeExpr = ParseBraceInitializer();
2531 FRI->LifetimeExtendTemps = std::move(
2536 if (IsForRangeLoop) {
2540 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2541 VD->setObjCForDecl(
true);
2544 D.complete(ThisDecl);
2550 ParseDeclarationAfterDeclaratorAndAttributes(
D, TemplateInfo, FRI);
2551 if (LateParsedAttrs.size() > 0)
2552 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2553 D.complete(FirstDecl);
2555 DeclsInGroup.push_back(FirstDecl);
2563 if (Tok.
isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2567 Diag(CommaLoc, diag::err_expected_semi_declaration)
2577 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
2578 D.isFirstDeclarator()) {
2579 Diag(CommaLoc, diag::err_multiple_template_declarators)
2580 << TemplateInfo.Kind;
2585 D.setCommaLoc(CommaLoc);
2594 MaybeParseGNUAttributes(
D);
2598 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2603 MaybeParseHLSLAnnotations(
D);
2605 if (!
D.isInvalidType()) {
2610 if (Tok.
is(tok::kw_requires))
2611 ParseTrailingRequiresClause(
D);
2612 Decl *ThisDecl = ParseDeclarationAfterDeclarator(
D, TemplateInfo);
2613 D.complete(ThisDecl);
2615 DeclsInGroup.push_back(ThisDecl);
2622 if (ExpectSemi && ExpectAndConsumeSemi(
2624 ? diag::err_invalid_token_after_toplevel_declarator
2625 : diag::err_expected_semi_declaration)) {
2638bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &
D) {
2640 if (Tok.
is(tok::kw_asm)) {
2643 if (AsmLabel.isInvalid()) {
2648 D.setAsmLabel(AsmLabel.get());
2652 MaybeParseGNUAttributes(
D);
2678Decl *Parser::ParseDeclarationAfterDeclarator(
2679 Declarator &
D,
const ParsedTemplateInfo &TemplateInfo) {
2680 if (ParseAsmAttributesAfterDeclarator(
D))
2683 return ParseDeclarationAfterDeclaratorAndAttributes(
D, TemplateInfo);
2686Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2687 Declarator &
D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2689 struct InitializerScopeRAII {
2696 :
P(
P),
D(
D), ThisDecl(ThisDecl), Entered(
false) {
2697 if (ThisDecl &&
P.getLangOpts().CPlusPlus) {
2699 if (
D.getCXXScopeSpec().isSet()) {
2701 S =
P.getCurScope();
2704 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2709 ~InitializerScopeRAII() {
2710 if (ThisDecl &&
P.getLangOpts().CPlusPlus) {
2712 if (
D.getCXXScopeSpec().isSet())
2713 S =
P.getCurScope();
2716 P.Actions.ActOnCXXExitDeclInitializer(S, ThisDecl);
2725 InitKind TheInitKind;
2727 if (isTokenEqualOrEqualTypo())
2728 TheInitKind = InitKind::Equal;
2729 else if (Tok.
is(tok::l_paren))
2730 TheInitKind = InitKind::CXXDirect;
2732 (!CurParsedObjCImpl || !
D.isFunctionDeclarator()))
2733 TheInitKind = InitKind::CXXBraced;
2735 TheInitKind = InitKind::Uninitialized;
2736 if (TheInitKind != InitKind::Uninitialized)
2737 D.setHasInitializer();
2740 Decl *ThisDecl =
nullptr;
2741 Decl *OuterDecl =
nullptr;
2742 switch (TemplateInfo.Kind) {
2743 case ParsedTemplateInfo::NonTemplate:
2747 case ParsedTemplateInfo::Template:
2748 case ParsedTemplateInfo::ExplicitSpecialization: {
2750 *TemplateInfo.TemplateParams,
2752 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2755 ThisDecl = VT->getTemplatedDecl();
2760 case ParsedTemplateInfo::ExplicitInstantiation: {
2761 if (Tok.
is(tok::semi)) {
2763 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
D);
2768 ThisDecl = ThisRes.
get();
2776 Diag(Tok, diag::err_template_defn_explicit_instantiation)
2782 Diag(
D.getIdentifierLoc(),
2783 diag::err_explicit_instantiation_with_definition)
2791 LAngleLoc,
nullptr));
2803 switch (TheInitKind) {
2805 case InitKind::Equal: {
2808 if (Tok.
is(tok::kw_delete)) {
2809 if (
D.isFunctionDeclarator())
2814 SkipDeletedFunctionBody();
2815 }
else if (Tok.
is(tok::kw_default)) {
2816 if (
D.isFunctionDeclarator())
2823 InitializerScopeRAII
InitScope(*
this,
D, ThisDecl);
2825 if (Tok.
is(tok::code_completion)) {
2838 if (Tok.
is(tok::r_paren) && FRI &&
D.isFirstDeclarator()) {
2839 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2843 FRI->ColonLoc = EqualLoc;
2845 FRI->RangeExpr =
Init;
2848 if (
Init.isInvalid()) {
2850 StopTokens.push_back(tok::comma);
2853 StopTokens.push_back(tok::r_paren);
2862 case InitKind::CXXDirect: {
2869 InitializerScopeRAII
InitScope(*
this,
D, ThisDecl);
2871 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2872 auto RunSignatureHelp = [&]() {
2875 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2878 CalledSignatureHelp =
true;
2879 return PreferredType;
2881 auto SetPreferredType = [&] {
2882 PreferredType.enterFunctionArgument(Tok.
getLocation(), RunSignatureHelp);
2885 llvm::function_ref<void()> ExpressionStarts;
2891 ExpressionStarts = SetPreferredType;
2894 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2899 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2902 CalledSignatureHelp =
true;
2911 T.getCloseLocation(),
2918 case InitKind::CXXBraced: {
2920 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2922 InitializerScopeRAII
InitScope(*
this,
D, ThisDecl);
2924 PreferredType.enterVariableInit(Tok.
getLocation(), ThisDecl);
2927 if (
Init.isInvalid()) {
2933 case InitKind::Uninitialized: {
2940 return OuterDecl ? OuterDecl : ThisDecl;
2949void Parser::ParseSpecifierQualifierList(
2952 ParsedTemplateInfo TemplateInfo;
2956 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC,
nullptr,
2957 AllowImplicitTypename);
2962 Diag(Tok, diag::err_expected_type);
2965 Diag(Tok, diag::err_typename_requires_specqual);
2976 diag::err_typename_invalid_storageclass);
3020 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
3021 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
3035 ParsedTemplateInfo &TemplateInfo,
3038 assert(Tok.
is(tok::identifier) &&
"should have identifier");
3060 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
3078 AnnotateScopeToken(*SS,
false);
3089 DSC == DeclSpecContext::DSC_template_type_arg)) {
3090 const char *PrevSpec;
3106 if (SS ==
nullptr) {
3107 const char *TagName =
nullptr, *FixitTagName =
nullptr;
3113 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
3115 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
3117 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
3119 TagName=
"__interface"; FixitTagName =
"__interface ";
3120 TagKind=tok::kw___interface;
break;
3122 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
3130 Diag(
Loc, diag::err_use_of_tag_name_without_tag)
3131 << TokenName << TagName <<
getLangOpts().CPlusPlus
3137 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
3138 << TokenName << TagName;
3142 if (TagKind == tok::kw_enum)
3143 ParseEnumSpecifier(
Loc, DS, TemplateInfo, AS,
3144 DeclSpecContext::DSC_normal);
3146 ParseClassSpecifier(TagKind,
Loc, DS, TemplateInfo, AS,
3148 DeclSpecContext::DSC_normal, Attrs);
3155 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
3156 DSC == DeclSpecContext::DSC_class)) {
3160 case tok::l_paren: {
3167 TentativeParsingAction PA(*
this);
3169 TPResult TPR = TryParseDeclarator(
false);
3172 if (TPR != TPResult::False) {
3180 if (DSC == DeclSpecContext::DSC_class ||
3181 (DSC == DeclSpecContext::DSC_top_level && SS)) {
3184 Diag(
Loc, diag::err_constructor_bad_name)
3205 AnnotateScopeToken(*SS,
false);
3227 const char *PrevSpec;
3248 if (IsTemplateName) {
3250 TemplateArgList Args;
3251 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3265Parser::DeclSpecContext
3269 return DeclSpecContext::DSC_class;
3271 return DeclSpecContext::DSC_top_level;
3273 return DeclSpecContext::DSC_template_param;
3275 return DeclSpecContext::DSC_template_arg;
3277 return DeclSpecContext::DSC_template_type_arg;
3280 return DeclSpecContext::DSC_trailing;
3283 return DeclSpecContext::DSC_alias_declaration;
3285 return DeclSpecContext::DSC_association;
3287 return DeclSpecContext::DSC_type_specifier;
3289 return DeclSpecContext::DSC_condition;
3291 return DeclSpecContext::DSC_conv_operator;
3293 return DeclSpecContext::DSC_new;
3308 return DeclSpecContext::DSC_normal;
3311 llvm_unreachable(
"Missing DeclaratorContext case");
3324 if (isTypeIdInParens()) {
3353 assert(Tok.
isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3354 "Not an alignment-specifier!");
3361 if (
T.expectAndConsume())
3368 ParseAlignArgument(PP.
getSpelling(KWTok),
T.getOpenLocation(),
3377 *EndLoc =
T.getCloseLocation();
3384 ArgExprs.push_back(ArgExpr.
get());
3385 Attrs.
addNew(KWName, KWLoc,
nullptr, KWLoc, ArgExprs.data(), 1, Kind,
3390void Parser::DistributeCLateParsedAttrs(
Decl *Dcl,
3391 LateParsedAttrList *LateAttrs) {
3396 for (
auto *LateAttr : *LateAttrs) {
3397 if (LateAttr->Decls.empty())
3398 LateAttr->addDecl(Dcl);
3411 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3416 if (Tok.
is(tok::r_paren)) {
3424 using ExpressionKind =
3428 ExpressionKind::EK_AttrArgument);
3438 ArgExprs.push_back(ArgExpr.
get());
3448 ScopeName, ScopeLoc, ArgExprs.data(), ArgExprs.size(), Form);
3451ExprResult Parser::ParseExtIntegerArgument() {
3452 assert(Tok.
isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3453 "Not an extended int type");
3457 if (
T.expectAndConsume())
3466 if(
T.consumeClose())
3480 DeclSpecContext DSContext,
3481 LateParsedAttrList *LateAttrs) {
3484 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3485 DSContext == DeclSpecContext::DSC_top_level);
3488 Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
3489 tok::annot_template_id) &&
3495 bool HasScope = Tok.
is(tok::annot_cxxscope);
3501 bool MightBeDeclarator =
true;
3502 if (Tok.
isOneOf(tok::kw_typename, tok::annot_typename)) {
3504 MightBeDeclarator =
false;
3505 }
else if (AfterScope.
is(tok::annot_template_id)) {
3511 MightBeDeclarator =
false;
3512 }
else if (AfterScope.
is(tok::identifier)) {
3513 const Token &Next = HasScope ? GetLookAheadToken(2) :
NextToken();
3517 if (Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3518 tok::annot_cxxscope, tok::coloncolon)) {
3520 MightBeDeclarator =
false;
3521 }
else if (HasScope) {
3532 switch (Classification.
getKind()) {
3538 llvm_unreachable(
"typo correction is not possible here");
3545 MightBeDeclarator =
false;
3561 if (MightBeDeclarator)
3566 diag::err_expected_after)
3577 ParsedTemplateInfo NotATemplate;
3578 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3609void Parser::ParseDeclarationSpecifiers(
3611 DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
3623 if (DSContext == DeclSpecContext::DSC_conv_operator) {
3626 DSContext = DeclSpecContext::DSC_type_specifier;
3629 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3630 DSContext == DeclSpecContext::DSC_top_level);
3631 bool AttrsLastTime =
false;
3637 bool isStorageClass =
false;
3638 const char *PrevSpec =
nullptr;
3639 unsigned DiagID = 0;
3660 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3674 bool IsTemplateSpecOrInst =
3675 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3676 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3685 ProhibitAttributes(attrs);
3689 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3690 !PA.isRegularKeywordAttribute())
3698 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3699 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3706 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3707 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3709 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3710 << PA << PA.isRegularKeywordAttribute();
3719 DS.
Finish(Actions, Policy);
3723 case tok::kw__Alignas:
3724 diagnoseUseOfC11Keyword(Tok);
3726 case tok::kw_alignas:
3732 if (Tok.
getKind() == tok::kw_alignas)
3733 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
3739 if (!isAllowedCXX11AttributeSpecifier())
3740 goto DoneWithDeclSpec;
3743 ProhibitAttributes(attrs);
3750 ParseCXX11Attributes(attrs);
3751 AttrsLastTime =
true;
3754 case tok::code_completion: {
3758 bool AllowNonIdentifiers
3764 bool AllowNestedNameSpecifiers
3765 = DSContext == DeclSpecContext::DSC_top_level ||
3770 getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3775 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
3776 CCC = DSContext == DeclSpecContext::DSC_class
3779 else if (DSContext == DeclSpecContext::DSC_class)
3783 else if (CurParsedObjCImpl)
3791 case tok::coloncolon:
3797 goto DoneWithDeclSpec;
3799 if (Tok.
is(tok::coloncolon))
3800 goto DoneWithDeclSpec;
3803 case tok::annot_cxxscope: {
3805 goto DoneWithDeclSpec;
3808 if (TemplateInfo.TemplateParams)
3818 ? takeTemplateIdAnnotation(Next)
3824 ConsumeAnnotationToken();
3838 if ((DSContext == DeclSpecContext::DSC_top_level ||
3839 DSContext == DeclSpecContext::DSC_class) &&
3842 isConstructorDeclarator(
false,
3849 goto DoneWithDeclSpec;
3853 ConsumeAnnotationToken();
3854 assert(Tok.
is(tok::annot_template_id) &&
3855 "ParseOptionalCXXScopeSpecifier not working");
3856 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3866 ConsumeAnnotationToken();
3870 if (Next.is(tok::annot_typename)) {
3872 ConsumeAnnotationToken();
3876 PrevSpec, DiagID,
T, Policy);
3880 ConsumeAnnotationToken();
3884 Next.is(tok::annot_template_id) &&
3888 ConsumeAnnotationToken();
3889 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3893 if (Next.isNot(tok::identifier))
3894 goto DoneWithDeclSpec;
3899 if ((DSContext == DeclSpecContext::DSC_top_level ||
3900 DSContext == DeclSpecContext::DSC_class) &&
3903 isConstructorDeclarator(
false,
3907 goto DoneWithDeclSpec;
3916 *Next.getIdentifierInfo(), Next.getLocation(),
getCurScope(), &SS,
3917 false,
false,
nullptr,
3920 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3922 if (IsTemplateSpecOrInst)
3930 if (TryAnnotateTypeConstraint())
3931 goto DoneWithDeclSpec;
3932 if (Tok.
isNot(tok::annot_cxxscope) ||
3936 ConsumeAnnotationToken();
3938 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3939 if (!Attrs.
empty()) {
3940 AttrsLastTime =
true;
3941 attrs.takeAllFrom(Attrs);
3945 goto DoneWithDeclSpec;
3949 ConsumeAnnotationToken();
3952 DiagID, TypeRep, Policy);
3962 case tok::annot_typename: {
3966 goto DoneWithDeclSpec;
3975 ConsumeAnnotationToken();
3980 case tok::kw___is_signed:
3991 TryKeywordIdentFallback(
true);
3994 goto DoneWithDeclSpec;
3997 case tok::kw___super:
3998 case tok::kw_decltype:
3999 case tok::identifier:
4005 goto DoneWithDeclSpec;
4011 if (!
getLangOpts().DeclSpecKeyword && Tok.
is(tok::identifier) &&
4013 Diag(
Loc, diag::err_ms_attributes_not_enabled);
4023 if (
T.consumeOpen()) {
4024 assert(
false &&
"Not a left paren?");
4043 if (IsTemplateSpecOrInst)
4047 if (IsTemplateSpecOrInst)
4050 goto DoneWithDeclSpec;
4053 if (!Tok.
is(tok::identifier))
4058 if (TryAltiVecToken(DS,
Loc, PrevSpec, DiagID,
isInvalid))
4064 goto DoneWithDeclSpec;
4066 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
4067 isObjCInstancetype()) {
4071 DiagID, TypeRep, Policy);
4084 isConstructorDeclarator(
true,
4087 goto DoneWithDeclSpec;
4091 false,
false,
nullptr,
false,
false,
4092 isClassTemplateDeductionContext(DSContext));
4097 if (TryAnnotateTypeConstraint())
4098 goto DoneWithDeclSpec;
4099 if (Tok.
isNot(tok::identifier))
4102 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
4103 if (!Attrs.
empty()) {
4104 AttrsLastTime =
true;
4105 attrs.takeAllFrom(Attrs);
4109 goto DoneWithDeclSpec;
4116 (DSContext == DeclSpecContext::DSC_class ||
4117 DSContext == DeclSpecContext::DSC_top_level) &&
4120 isConstructorDeclarator(
true,
4122 goto DoneWithDeclSpec;
4125 DiagID, TypeRep, Policy);
4137 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
4152 case tok::annot_template_id: {
4164 TemplateId =
nullptr;
4172 tok::kw_volatile, tok::kw_restrict, tok::amp,
4174 Diag(
Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
4178 TemplateId, Policy);
4182 goto DoneWithDeclSpec;
4185 TemplateId =
nullptr;
4187 ConsumeAnnotationToken();
4191 if (Tracker.consumeOpen()) {
4193 Diag(Tok, diag::err_expected) << tok::l_paren;
4197 Tracker.skipToEnd();
4198 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
4203 Tracker.consumeClose();
4211 DiagID, TemplateId, Policy);
4214 TemplateId, Policy);
4223 goto DoneWithDeclSpec;
4231 isConstructorDeclarator(
true,
4234 goto DoneWithDeclSpec;
4239 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
4244 case tok::kw___attribute:
4245 case tok::kw___declspec:
4246 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4250 case tok::kw___forceinline: {
4255 nullptr, 0, tok::kw___forceinline);
4259 case tok::kw___unaligned:
4264 case tok::kw___sptr:
4265 case tok::kw___uptr:
4266 case tok::kw___ptr64:
4267 case tok::kw___ptr32:
4269 case tok::kw___cdecl:
4270 case tok::kw___stdcall:
4271 case tok::kw___fastcall:
4272 case tok::kw___thiscall:
4273 case tok::kw___regcall:
4274 case tok::kw___vectorcall:
4278 case tok::kw___funcref:
4283 case tok::kw___pascal:
4288 case tok::kw___kernel:
4293 case tok::kw___noinline__:
4298 case tok::kw__Nonnull:
4299 case tok::kw__Nullable:
4300 case tok::kw__Nullable_result:
4301 case tok::kw__Null_unspecified:
4306 case tok::kw___kindof:
4308 nullptr, 0, tok::kw___kindof);
4313 case tok::kw_typedef:
4315 PrevSpec, DiagID, Policy);
4316 isStorageClass =
true;
4318 case tok::kw_extern:
4320 Diag(Tok, diag::ext_thread_before) <<
"extern";
4322 PrevSpec, DiagID, Policy);
4323 isStorageClass =
true;
4325 case tok::kw___private_extern__:
4327 Loc, PrevSpec, DiagID, Policy);
4328 isStorageClass =
true;
4330 case tok::kw_static:
4332 Diag(Tok, diag::ext_thread_before) <<
"static";
4334 PrevSpec, DiagID, Policy);
4335 isStorageClass =
true;
4339 if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
4341 PrevSpec, DiagID, Policy);
4343 Diag(Tok, diag::ext_auto_storage_class)
4350 PrevSpec, DiagID, Policy);
4351 isStorageClass =
true;
4353 case tok::kw___auto_type:
4354 Diag(Tok, diag::ext_auto_type);
4358 case tok::kw_register:
4360 PrevSpec, DiagID, Policy);
4361 isStorageClass =
true;
4363 case tok::kw_mutable:
4365 PrevSpec, DiagID, Policy);
4366 isStorageClass =
true;
4368 case tok::kw___thread:
4371 isStorageClass =
true;
4373 case tok::kw_thread_local:
4375 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4384 Loc, PrevSpec, DiagID);
4385 isStorageClass =
true;
4387 case tok::kw__Thread_local:
4388 diagnoseUseOfC11Keyword(Tok);
4390 Loc, PrevSpec, DiagID);
4391 isStorageClass =
true;
4395 case tok::kw_inline:
4398 case tok::kw_virtual:
4402 !
getActions().getOpenCLOptions().isAvailableOption(
4404 DiagID = diag::err_openclcxx_virtual_function;
4411 case tok::kw_explicit: {
4415 ConsumedEnd = ExplicitLoc;
4417 if (Tok.
is(tok::l_paren)) {
4420 ? diag::warn_cxx17_compat_explicit_bool
4421 : diag::ext_explicit_bool);
4425 Tracker.consumeOpen();
4432 if (ExplicitExpr.isUsable()) {
4434 Tracker.consumeClose();
4438 Tracker.skipToEnd();
4444 ExplicitSpec, CloseParenLoc);
4447 case tok::kw__Noreturn:
4448 diagnoseUseOfC11Keyword(Tok);
4453 case tok::kw_friend:
4454 if (DSContext == DeclSpecContext::DSC_class) {
4461 DiagID = diag::err_friend_invalid_in_context;
4467 case tok::kw___module_private__:
4472 case tok::kw_constexpr:
4474 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4478 case tok::kw_consteval:
4482 case tok::kw_constinit:
4498 PrevSpec, DiagID, Policy);
4500 case tok::kw___int64:
4502 PrevSpec, DiagID, Policy);
4504 case tok::kw_signed:
4508 case tok::kw_unsigned:
4512 case tok::kw__Complex:
4514 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4518 case tok::kw__Imaginary:
4520 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4536 case tok::kw__ExtInt:
4537 case tok::kw__BitInt: {
4538 DiagnoseBitIntUse(Tok);
4543 ConsumedEnd = PrevTokLocation;
4546 case tok::kw___int128:
4554 case tok::kw___bf16:
4562 case tok::kw_double:
4566 case tok::kw__Float16:
4570 case tok::kw__Accum:
4572 "This keyword is only used when fixed point types are enabled "
4573 "with `-ffixed-point`");
4577 case tok::kw__Fract:
4579 "This keyword is only used when fixed point types are enabled "
4580 "with `-ffixed-point`");
4586 "This keyword is only used when fixed point types are enabled "
4587 "with `-ffixed-point`");
4590 case tok::kw___float128:
4594 case tok::kw___ibm128:
4598 case tok::kw_wchar_t:
4602 case tok::kw_char8_t:
4606 case tok::kw_char16_t:
4610 case tok::kw_char32_t:
4616 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4620 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4622 if (Tok.
is(tok::kw_bool) &&
4626 DiagID = diag::err_bool_redeclaration;
4635 case tok::kw__Decimal32:
4639 case tok::kw__Decimal64:
4643 case tok::kw__Decimal128:
4647 case tok::kw___vector:
4650 case tok::kw___pixel:
4653 case tok::kw___bool:
4658 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4663 goto DoneWithDeclSpec;
4665 DiagID = diag::err_opencl_unknown_type_specifier;
4672#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4673#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4674#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4675 case tok::kw_##ImgType##_t: \
4676 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4677 goto DoneWithDeclSpec; \
4679#include "clang/Basic/OpenCLImageTypes.def"
4680 case tok::kw___unknown_anytype:
4682 PrevSpec, DiagID, Policy);
4687 case tok::kw_struct:
4688 case tok::kw___interface:
4689 case tok::kw_union: {
4697 ParseClassSpecifier(Kind,
Loc, DS, TemplateInfo, AS,
4698 EnteringContext, DSContext, Attributes);
4702 if (!Attributes.empty()) {
4703 AttrsLastTime =
true;
4704 attrs.takeAllFrom(Attributes);
4712 ParseEnumSpecifier(
Loc, DS, TemplateInfo, AS, DSContext);
4720 case tok::kw_volatile:
4724 case tok::kw_restrict:
4730 case tok::kw_typename:
4733 goto DoneWithDeclSpec;
4735 if (!Tok.
is(tok::kw_typename))
4740 case tok::kw_typeof:
4741 case tok::kw_typeof_unqual:
4742 ParseTypeofSpecifier(DS);
4745 case tok::annot_decltype:
4746 ParseDecltypeSpecifier(DS);
4749 case tok::annot_pack_indexing_type:
4750 ParsePackIndexingType(DS);
4753 case tok::annot_pragma_pack:
4757 case tok::annot_pragma_ms_pragma:
4758 HandlePragmaMSPragma();
4761 case tok::annot_pragma_ms_vtordisp:
4762 HandlePragmaMSVtorDisp();
4765 case tok::annot_pragma_ms_pointers_to_members:
4766 HandlePragmaMSPointersToMembers();
4769#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4770#include "clang/Basic/TransformTypeTraits.def"
4774 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4775 goto ParseIdentifier;
4778 case tok::kw__Atomic:
4783 diagnoseUseOfC11Keyword(Tok);
4785 ParseAtomicSpecifier(DS);
4793 case tok::kw___generic:
4798 if (!Actions.
getLangOpts().OpenCLGenericAddressSpace) {
4799 DiagID = diag::err_opencl_unknown_type_specifier;
4805 case tok::kw_private:
4809 goto DoneWithDeclSpec;
4811 case tok::kw___private:
4812 case tok::kw___global:
4813 case tok::kw___local:
4814 case tok::kw___constant:
4816 case tok::kw___read_only:
4817 case tok::kw___write_only:
4818 case tok::kw___read_write:
4822 case tok::kw_groupshared:
4830#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
4831 case tok::kw_##Name: \
4832 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4835#include "clang/Basic/HLSLIntangibleTypes.def"
4842 goto DoneWithDeclSpec;
4847 if (
Type.isUsable()) {
4849 PrevSpec, DiagID,
Type.get(),
4851 Diag(StartLoc, DiagID) << PrevSpec;
4867 assert(PrevSpec &&
"Method did not return previous specifier!");
4870 if (DiagID == diag::ext_duplicate_declspec ||
4871 DiagID == diag::ext_warn_duplicate_declspec ||
4872 DiagID == diag::err_duplicate_declspec)
4876 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4880 Diag(
Loc, DiagID) << PrevSpec;
4883 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4887 AttrsLastTime =
false;
4899 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4902 for (
auto *I : RD->decls()) {
4903 auto *VD = dyn_cast<ValueDecl>(I);
4911 for (
const auto &DD : CAT->dependent_decls()) {
4912 if (!RD->containsDecl(DD.getDecl())) {
4913 P.Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4914 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4915 P.Diag(DD.getDecl()->getBeginLoc(),
4916 diag::note_flexible_array_counted_by_attr_field)
4944void Parser::ParseStructDeclaration(
4947 LateParsedAttrList *LateFieldAttrs) {
4949 if (Tok.
is(tok::kw___extension__)) {
4953 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4958 MaybeParseCXX11Attributes(Attrs);
4961 ParseSpecifierQualifierList(DS);
4965 if (Tok.
is(tok::semi)) {
4970 ProhibitAttributes(Attrs);
4974 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4980 bool FirstDeclarator =
true;
4984 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4987 if (!FirstDeclarator) {
4990 DiagnoseAndSkipCXX11Attributes();
4991 MaybeParseGNUAttributes(DeclaratorInfo.D);
4992 DiagnoseAndSkipCXX11Attributes();
4997 if (Tok.
isNot(tok::colon)) {
5000 ParseDeclarator(DeclaratorInfo.D);
5002 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.
getLocation());
5014 DeclaratorInfo.BitfieldSize = Res.
get();
5018 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
5021 Decl *
Field = FieldsCallback(DeclaratorInfo);
5023 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
5030 FirstDeclarator =
false;
5036void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs,
bool EnterScope,
5038 assert(LAs.parseSoon() &&
5039 "Attribute list should be marked for immediate parsing.");
5040 for (
auto *LA : LAs) {
5041 ParseLexedCAttribute(*LA,
EnterScope, OutAttrs);
5052void Parser::ParseLexedCAttribute(LateParsedAttribute &LA,
bool EnterScope,
5061 LA.Toks.push_back(AttrEnd);
5065 LA.Toks.push_back(Tok);
5066 PP.EnterTokenStream(LA.Toks,
true,
5077 assert(LA.Decls.size() <= 1 &&
5078 "late field attribute expects to have at most one declaration.");
5081 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
nullptr,
nullptr,
5084 for (
auto *
D : LA.Decls)
5089 while (Tok.
isNot(tok::eof))
5114 "parsing struct/union body");
5118 if (
T.consumeOpen())
5126 LateParsedAttrList LateFieldAttrs(
true,
5130 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
5131 Tok.
isNot(tok::eof)) {
5135 if (Tok.
is(tok::semi)) {
5136 ConsumeExtraSemi(InsideStruct,
TagType);
5141 if (Tok.
isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
5143 ParseStaticAssertDeclaration(DeclEnd);
5147 if (Tok.
is(tok::annot_pragma_pack)) {
5152 if (Tok.
is(tok::annot_pragma_align)) {
5153 HandlePragmaAlign();
5157 if (Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
5161 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
5165 if (Tok.
is(tok::annot_pragma_openacc)) {
5174 ConsumeAnnotationToken();
5178 if (!Tok.
is(tok::at)) {
5184 FD.D, FD.BitfieldSize);
5191 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
5195 Diag(Tok, diag::err_unexpected_at);
5200 ExpectAndConsume(tok::l_paren);
5201 if (!Tok.
is(tok::identifier)) {
5202 Diag(Tok, diag::err_expected) << tok::identifier;
5210 ExpectAndConsume(tok::r_paren);
5216 if (Tok.
is(tok::r_brace)) {
5217 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
5221 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
5232 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
5235 ParseLexedCAttributeList(LateFieldAttrs,
false);
5240 T.getOpenLocation(),
T.getCloseLocation(), attrs);
5276 const ParsedTemplateInfo &TemplateInfo,
5279 if (Tok.
is(tok::code_completion)) {
5289 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5292 bool IsScopedUsingClassTag =
false;
5297 : diag::ext_scoped_enum);
5298 IsScopedUsingClassTag = Tok.
is(tok::kw_class);
5303 ProhibitAttributes(attrs);
5306 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5315 bool shouldDelayDiagsInTag =
5316 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
5317 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
5321 AllowDefiningTypeSpec AllowEnumSpecifier =
5323 bool CanBeOpaqueEnumDeclaration =
5324 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5327 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5328 CanBeOpaqueEnumDeclaration);
5336 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5341 if (Spec.
isSet() && Tok.
isNot(tok::identifier)) {
5342 Diag(Tok, diag::err_expected) << tok::identifier;
5344 if (Tok.
isNot(tok::l_brace)) {
5356 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::l_brace) &&
5357 Tok.
isNot(tok::colon)) {
5358 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5369 if (Tok.
is(tok::identifier)) {
5374 if (!Name && ScopedEnumKWLoc.
isValid()) {
5377 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5379 IsScopedUsingClassTag =
false;
5384 if (shouldDelayDiagsInTag)
5385 diagsFromTag.done();
5390 bool CanBeBitfield =
5394 if (Tok.
is(tok::colon)) {
5419 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5424 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5435 DeclSpecContext::DSC_type_specifier);
5440 BaseRange =
SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5444 Diag(ColonLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type)
5447 Diag(ColonLoc, diag::ext_cxx11_enum_fixed_underlying_type)
5450 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5454 ? diag::warn_c17_compat_enum_fixed_underlying_type
5455 : diag::ext_c23_enum_fixed_underlying_type)
5472 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5474 else if (Tok.
is(tok::l_brace)) {
5483 IsScopedUsingClassTag =
false;
5489 }
else if (!isTypeSpecifier(DSC) &&
5490 (Tok.
is(tok::semi) ||
5492 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5497 if (Tok.
isNot(tok::semi)) {
5499 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5507 bool IsElaboratedTypeSpecifier =
5513 diagsFromTag.redelay();
5517 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
5521 Diag(Tok, diag::err_enum_template);
5526 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
5529 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5533 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5535 TemplateInfo.TemplateParams->size());
5540 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5556 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5558 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5559 diag::err_keyword_not_allowed,
5562 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5563 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5564 else if (ScopedEnumKWLoc.
isValid())
5565 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5569 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5579 bool IsDependent =
false;
5580 const char *PrevSpec =
nullptr;
5585 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5586 IsScopedUsingClassTag,
5587 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5588 DSC == DeclSpecContext::DSC_template_param ||
5589 DSC == DeclSpecContext::DSC_template_type_arg,
5590 OffsetOfState, &SkipBody).
get();
5600 NameLoc.
isValid() ? NameLoc : StartLoc,
5601 PrevSpec, DiagID,
TagDecl, Owned,
5603 Diag(StartLoc, DiagID) << PrevSpec;
5612 Diag(Tok, diag::err_expected_type_name_after_typename);
5618 if (
Type.isInvalid()) {
5624 NameLoc.
isValid() ? NameLoc : StartLoc,
5625 PrevSpec, DiagID,
Type.get(),
5627 Diag(StartLoc, DiagID) << PrevSpec;
5646 ParseEnumBody(StartLoc,
D);
5655 NameLoc.
isValid() ? NameLoc : StartLoc,
5656 PrevSpec, DiagID,
TagDecl, Owned,
5658 Diag(StartLoc, DiagID) << PrevSpec;
5681 Diag(Tok, diag::err_empty_enum);
5686 Decl *LastEnumConstDecl =
nullptr;
5689 while (Tok.
isNot(tok::r_brace)) {
5692 if (Tok.
isNot(tok::identifier)) {
5704 MaybeParseGNUAttributes(attrs);
5705 if (isAllowedCXX11AttributeSpecifier()) {
5708 ? diag::warn_cxx14_compat_ns_enum_attribute
5709 : diag::ext_ns_enum_attribute)
5711 ParseCXX11Attributes(attrs);
5716 EnumAvailabilityDiags.emplace_back(*
this);
5729 EqualLoc, AssignedVal.
get());
5730 EnumAvailabilityDiags.back().done();
5732 EnumConstantDecls.push_back(EnumConstDecl);
5733 LastEnumConstDecl = EnumConstDecl;
5735 if (Tok.
is(tok::identifier)) {
5738 Diag(
Loc, diag::err_enumerator_list_missing_comma)
5761 if (Tok.
is(tok::r_brace) && CommaLoc.
isValid()) {
5764 diag::ext_enumerator_list_comma_cxx :
5765 diag::ext_enumerator_list_comma_c)
5768 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5779 MaybeParseGNUAttributes(attrs);
5785 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5786 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5788 EnumAvailabilityDiags[i].redelay();
5789 PD.complete(EnumConstantDecls[i]);
5798 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5799 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5811bool Parser::isKnownToBeTypeSpecifier(
const Token &Tok)
const {
5813 default:
return false;
5817 case tok::kw___int64:
5818 case tok::kw___int128:
5819 case tok::kw_signed:
5820 case tok::kw_unsigned:
5821 case tok::kw__Complex:
5822 case tok::kw__Imaginary:
5825 case tok::kw_wchar_t:
5826 case tok::kw_char8_t:
5827 case tok::kw_char16_t:
5828 case tok::kw_char32_t:
5830 case tok::kw__ExtInt:
5831 case tok::kw__BitInt:
5832 case tok::kw___bf16:
5835 case tok::kw_double:
5836 case tok::kw__Accum:
5837 case tok::kw__Fract:
5838 case tok::kw__Float16:
5839 case tok::kw___float128:
5840 case tok::kw___ibm128:
5843 case tok::kw__Decimal32:
5844 case tok::kw__Decimal64:
5845 case tok::kw__Decimal128:
5846 case tok::kw___vector:
5847#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5848#include "clang/Basic/OpenCLImageTypes.def"
5849#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5850#include "clang/Basic/HLSLIntangibleTypes.def"
5854 case tok::kw_struct:
5855 case tok::kw___interface:
5861 case tok::annot_typename:
5868bool Parser::isTypeSpecifierQualifier() {
5870 default:
return false;
5872 case tok::identifier:
5873 if (TryAltiVecVectorToken())
5876 case tok::kw_typename:
5881 if (Tok.
is(tok::identifier))
5883 return isTypeSpecifierQualifier();
5885 case tok::coloncolon:
5892 return isTypeSpecifierQualifier();
5895 case tok::kw___attribute:
5897 case tok::kw_typeof:
5898 case tok::kw_typeof_unqual:
5903 case tok::kw___int64:
5904 case tok::kw___int128:
5905 case tok::kw_signed:
5906 case tok::kw_unsigned:
5907 case tok::kw__Complex:
5908 case tok::kw__Imaginary:
5911 case tok::kw_wchar_t:
5912 case tok::kw_char8_t:
5913 case tok::kw_char16_t:
5914 case tok::kw_char32_t:
5916 case tok::kw__ExtInt:
5917 case tok::kw__BitInt:
5919 case tok::kw___bf16:
5921 case tok::kw_double:
5922 case tok::kw__Accum:
5923 case tok::kw__Fract:
5924 case tok::kw__Float16:
5925 case tok::kw___float128:
5926 case tok::kw___ibm128:
5929 case tok::kw__Decimal32:
5930 case tok::kw__Decimal64:
5931 case tok::kw__Decimal128:
5932 case tok::kw___vector:
5933#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5934#include "clang/Basic/OpenCLImageTypes.def"
5935#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5936#include "clang/Basic/HLSLIntangibleTypes.def"
5940 case tok::kw_struct:
5941 case tok::kw___interface:
5948 case tok::kw_volatile:
5949 case tok::kw_restrict:
5953 case tok::kw___unknown_anytype:
5956 case tok::annot_typename:
5963 case tok::kw___cdecl:
5964 case tok::kw___stdcall:
5965 case tok::kw___fastcall:
5966 case tok::kw___thiscall:
5967 case tok::kw___regcall:
5968 case tok::kw___vectorcall:
5970 case tok::kw___ptr64:
5971 case tok::kw___ptr32:
5972 case tok::kw___pascal:
5973 case tok::kw___unaligned:
5975 case tok::kw__Nonnull:
5976 case tok::kw__Nullable:
5977 case tok::kw__Nullable_result:
5978 case tok::kw__Null_unspecified:
5980 case tok::kw___kindof:
5982 case tok::kw___private:
5983 case tok::kw___local:
5984 case tok::kw___global:
5985 case tok::kw___constant:
5986 case tok::kw___generic:
5987 case tok::kw___read_only:
5988 case tok::kw___read_write:
5989 case tok::kw___write_only:
5990 case tok::kw___funcref:
5993 case tok::kw_private:
5997 case tok::kw__Atomic:
6001 case tok::kw_groupshared:
6014 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
6018 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
6024 if (Tok.
is(tok::annot_repl_input_end) &&
6026 ConsumeAnnotationToken();
6031 DeclsInGroup.push_back(TLSD);
6034 for (
Stmt *S : Stmts) {
6039 DeclsInGroup.push_back(
D);
6052bool Parser::isDeclarationSpecifier(
6054 bool DisambiguatingWithExpression) {
6056 default:
return false;
6063 case tok::identifier:
6067 if (TryAltiVecVectorToken())
6070 case tok::kw_decltype:
6071 case tok::kw_typename:
6076 if (TryAnnotateTypeConstraint())
6078 if (Tok.
is(tok::identifier))
6086 if (DisambiguatingWithExpression &&
6087 isStartOfObjCClassMessageMissingOpenBracket())
6090 return isDeclarationSpecifier(AllowImplicitTypename);
6092 case tok::coloncolon:
6106 case tok::kw_typedef:
6107 case tok::kw_extern:
6108 case tok::kw___private_extern__:
6109 case tok::kw_static:
6111 case tok::kw___auto_type:
6112 case tok::kw_register:
6113 case tok::kw___thread:
6114 case tok::kw_thread_local:
6115 case tok::kw__Thread_local:
6118 case tok::kw___module_private__:
6121 case tok::kw___unknown_anytype:
6126 case tok::kw___int64:
6127 case tok::kw___int128:
6128 case tok::kw_signed:
6129 case tok::kw_unsigned:
6130 case tok::kw__Complex:
6131 case tok::kw__Imaginary:
6134 case tok::kw_wchar_t:
6135 case tok::kw_char8_t:
6136 case tok::kw_char16_t:
6137 case tok::kw_char32_t:
6140 case tok::kw__ExtInt:
6141 case tok::kw__BitInt:
6143 case tok::kw___bf16:
6145 case tok::kw_double:
6146 case tok::kw__Accum:
6147 case tok::kw__Fract:
6148 case tok::kw__Float16:
6149 case tok::kw___float128:
6150 case tok::kw___ibm128:
6153 case tok::kw__Decimal32:
6154 case tok::kw__Decimal64:
6155 case tok::kw__Decimal128:
6156 case tok::kw___vector:
6160 case tok::kw_struct:
6162 case tok::kw___interface:
6168 case tok::kw_volatile:
6169 case tok::kw_restrict:
6173 case tok::kw_inline:
6174 case tok::kw_virtual:
6175 case tok::kw_explicit:
6176 case tok::kw__Noreturn:
6179 case tok::kw__Alignas:
6182 case tok::kw_friend:
6185 case tok::kw_static_assert:
6186 case tok::kw__Static_assert:
6189 case tok::kw_typeof:
6190 case tok::kw_typeof_unqual:
6193 case tok::kw___attribute:
6196 case tok::annot_decltype:
6197 case tok::annot_pack_indexing_type:
6198 case tok::kw_constexpr:
6201 case tok::kw_consteval:
6202 case tok::kw_constinit:
6205 case tok::kw__Atomic:
6208 case tok::kw_alignas:
6218 case tok::annot_typename:
6219 return !DisambiguatingWithExpression ||
6220 !isStartOfObjCClassMessageMissingOpenBracket();
6223 case tok::annot_template_id: {
6229 return isTypeConstraintAnnotation() &&
6233 case tok::annot_cxxscope: {
6242 if (
NextToken().is(tok::identifier) && TryAnnotateTypeConstraint())
6244 return isTypeConstraintAnnotation() &&
6245 GetLookAheadToken(2).isOneOf(tok::kw_auto, tok::kw_decltype);
6248 case tok::kw___declspec:
6249 case tok::kw___cdecl:
6250 case tok::kw___stdcall:
6251 case tok::kw___fastcall:
6252 case tok::kw___thiscall:
6253 case tok::kw___regcall:
6254 case tok::kw___vectorcall:
6256 case tok::kw___sptr:
6257 case tok::kw___uptr:
6258 case tok::kw___ptr64:
6259 case tok::kw___ptr32:
6260 case tok::kw___forceinline:
6261 case tok::kw___pascal:
6262 case tok::kw___unaligned:
6264 case tok::kw__Nonnull:
6265 case tok::kw__Nullable:
6266 case tok::kw__Nullable_result:
6267 case tok::kw__Null_unspecified:
6269 case tok::kw___kindof:
6271 case tok::kw___private:
6272 case tok::kw___local:
6273 case tok::kw___global:
6274 case tok::kw___constant:
6275 case tok::kw___generic:
6276 case tok::kw___read_only:
6277 case tok::kw___read_write:
6278 case tok::kw___write_only:
6279#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
6280#include "clang/Basic/OpenCLImageTypes.def"
6281#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
6282#include "clang/Basic/HLSLIntangibleTypes.def"
6284 case tok::kw___funcref:
6285 case tok::kw_groupshared:
6288 case tok::kw_private:
6293bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
6295 const ParsedTemplateInfo *TemplateInfo) {
6296 RevertingTentativeParsingAction TPA(*
this);
6299 if (TemplateInfo && TemplateInfo->TemplateParams)
6302 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6309 if (Tok.
is(tok::identifier)) {
6313 }
else if (Tok.
is(tok::annot_template_id)) {
6314 ConsumeAnnotationToken();
6321 SkipCXX11Attributes();
6324 if (Tok.
isNot(tok::l_paren)) {
6331 if (Tok.
is(tok::r_paren) ||
6332 (Tok.
is(tok::ellipsis) &&
NextToken().is(tok::r_paren))) {
6339 isCXX11AttributeSpecifier(
false,
6345 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6347 DeclScopeObj.EnterDeclaratorScope();
6351 MaybeParseMicrosoftAttributes(Attrs);
6360 bool IsConstructor =
false;
6366 if (Tok.
is(tok::kw_this)) {
6368 return isDeclarationSpecifier(ITC);
6371 if (isDeclarationSpecifier(ITC))
6372 IsConstructor =
true;
6373 else if (Tok.
is(tok::identifier) ||
6374 (Tok.
is(tok::annot_cxxscope) &&
NextToken().is(tok::identifier))) {
6379 if (Tok.
is(tok::annot_cxxscope))
6380 ConsumeAnnotationToken();
6392 case tok::coloncolon:
6405 SkipCXX11Attributes();
6407 if (DeductionGuide) {
6409 IsConstructor = Tok.
is(tok::arrow);
6412 if (Tok.
is(tok::colon) || Tok.
is(tok::kw_try)) {
6416 IsConstructor =
true;
6418 if (Tok.
is(tok::semi) || Tok.
is(tok::l_brace)) {
6431 IsConstructor = IsUnqualified;
6436 IsConstructor =
true;
6440 return IsConstructor;
6455void Parser::ParseTypeQualifierListOpt(
6456 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicAllowed,
6457 bool IdentifierRequired,
6459 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6460 isAllowedCXX11AttributeSpecifier()) {
6462 ParseCXX11Attributes(Attrs);
6470 const char *PrevSpec =
nullptr;
6471 unsigned DiagID = 0;
6475 case tok::code_completion:
6478 (*CodeCompletionHandler)();
6487 case tok::kw_volatile:
6491 case tok::kw_restrict:
6495 case tok::kw__Atomic:
6497 goto DoneWithTypeQuals;
6498 diagnoseUseOfC11Keyword(Tok);
6504 case tok::kw_private:
6506 goto DoneWithTypeQuals;
6508 case tok::kw___private:
6509 case tok::kw___global:
6510 case tok::kw___local:
6511 case tok::kw___constant:
6512 case tok::kw___generic:
6513 case tok::kw___read_only:
6514 case tok::kw___write_only:
6515 case tok::kw___read_write:
6519 case tok::kw_groupshared:
6527 case tok::kw___unaligned:
6531 case tok::kw___uptr:
6536 if (TryKeywordIdentFallback(
false))
6540 case tok::kw___sptr:
6542 case tok::kw___ptr64:
6543 case tok::kw___ptr32:
6544 case tok::kw___cdecl:
6545 case tok::kw___stdcall:
6546 case tok::kw___fastcall:
6547 case tok::kw___thiscall:
6548 case tok::kw___regcall:
6549 case tok::kw___vectorcall:
6550 if (AttrReqs & AR_DeclspecAttributesParsed) {
6554 goto DoneWithTypeQuals;
6556 case tok::kw___funcref:
6559 goto DoneWithTypeQuals;
6561 case tok::kw___pascal:
6562 if (AttrReqs & AR_VendorAttributesParsed) {
6566 goto DoneWithTypeQuals;
6569 case tok::kw__Nonnull:
6570 case tok::kw__Nullable:
6571 case tok::kw__Nullable_result:
6572 case tok::kw__Null_unspecified:
6577 case tok::kw___kindof:
6579 nullptr, 0, tok::kw___kindof);
6583 case tok::kw___attribute:
6584 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6586 Diag(Tok, diag::err_attributes_not_allowed);
6590 if (AttrReqs & AR_GNUAttributesParsed ||
6591 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6609 assert(PrevSpec &&
"Method did not return previous specifier!");
6610 Diag(Tok, DiagID) << PrevSpec;
6621 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6627 if (Kind == tok::star || Kind == tok::caret)
6631 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6632 Lang.getOpenCLCompatibleVersion() >= 200)
6635 if (!Lang.CPlusPlus)
6638 if (Kind == tok::amp)
6646 if (Kind == tok::ampamp)
6655 const unsigned NumTypes =
D.getNumTypeObjects();
6657 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6689void Parser::ParseDeclaratorInternal(
Declarator &
D,
6690 DirectDeclParseFunction DirectDeclParser) {
6698 (Tok.
is(tok::coloncolon) || Tok.
is(tok::kw_decltype) ||
6699 (Tok.
is(tok::identifier) &&
6701 Tok.
is(tok::annot_cxxscope))) {
6702 TentativeParsingAction TPA(*
this,
true);
6708 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6718 Tok.
is(tok::star)) {
6722 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6723 CompoundToken::MemberPtr);
6727 D.SetRangeEnd(StarLoc);
6729 ParseTypeQualifierListOpt(DS);
6730 D.ExtendWithDeclSpec(DS);
6734 ParseDeclaratorInternal(D, DirectDeclParser);
6748 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6755 if (
D.mayHaveIdentifier())
6756 D.getCXXScopeSpec() = SS;
6758 AnnotateScopeToken(SS,
true);
6760 if (DirectDeclParser)
6761 (this->*DirectDeclParser)(
D);
6770 ParseTypeQualifierListOpt(DS);
6779 if (DirectDeclParser)
6780 (this->*DirectDeclParser)(
D);
6789 if (Kind == tok::star || Kind == tok::caret) {
6795 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6797 ? AR_GNUAttributesParsed
6798 : AR_GNUAttributesParsedAndRejected);
6799 ParseTypeQualifierListOpt(DS, Reqs,
true, !
D.mayOmitIdentifier());
6800 D.ExtendWithDeclSpec(DS);
6804 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6805 if (Kind == tok::star)
6823 if (Kind == tok::ampamp)
6825 diag::warn_cxx98_compat_rvalue_reference :
6826 diag::ext_rvalue_reference);
6829 ParseTypeQualifierListOpt(DS);
6830 D.ExtendWithDeclSpec(DS);
6838 diag::err_invalid_reference_qualifier_application) <<
"const";
6841 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6845 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6850 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6852 if (
D.getNumTypeObjects() > 0) {
6857 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6860 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6882 if (
D.getName().StartLocation.isInvalid() &&
6883 D.getName().EndLocation.isValid())
6884 return D.getName().EndLocation;
6935void Parser::ParseDirectDeclarator(
Declarator &
D) {
6936 DeclaratorScopeObj DeclScopeObj(*
this,
D.getCXXScopeSpec());
6940 if (Tok.
is(tok::l_square) && !
D.mayOmitIdentifier() &&
6941 D.getCXXScopeSpec().isEmpty())
6942 return ParseDecompositionDeclarator(
D);
6953 if (
D.getCXXScopeSpec().isEmpty()) {
6956 ParseOptionalCXXScopeSpecifier(
6957 D.getCXXScopeSpec(),
nullptr,
6958 false, EnteringContext);
6972 if (
D.getCXXScopeSpec().isValid()) {
6974 D.getCXXScopeSpec()))
6977 DeclScopeObj.EnterDeclaratorScope();
6982 D.setInvalidType(
true);
6984 goto PastIdentifier;
6995 if (Tok.
is(tok::ellipsis) &&
D.getCXXScopeSpec().isEmpty() &&
6999 NextToken().is(tok::r_paren) && !
D.hasGroupingParens() &&
7001 D.getDeclSpec().getTypeSpecType() !=
TST_auto)) {
7008 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc,
D);
7011 D.setEllipsisLoc(EllipsisLoc);
7018 if (Tok.
isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
7022 bool AllowConstructorName;
7023 bool AllowDeductionGuide;
7024 if (
D.getDeclSpec().hasTypeSpecifier()) {
7025 AllowConstructorName =
false;
7026 AllowDeductionGuide =
false;
7027 }
else if (
D.getCXXScopeSpec().isSet()) {
7030 AllowDeductionGuide =
false;
7037 bool HadScope =
D.getCXXScopeSpec().isValid();
7043 true, AllowConstructorName,
7044 AllowDeductionGuide, &TemplateKWLoc,
7048 D.getCXXScopeSpec().isInvalid()) {
7050 D.setInvalidType(
true);
7054 if (!HadScope &&
D.getCXXScopeSpec().isValid() &&
7056 D.getCXXScopeSpec()))
7057 DeclScopeObj.EnterDeclaratorScope();
7064 goto PastIdentifier;
7067 if (
D.getCXXScopeSpec().isNotEmpty()) {
7070 diag::err_expected_unqualified_id)
7073 goto PastIdentifier;
7075 }
else if (Tok.
is(tok::identifier) &&
D.mayHaveIdentifier()) {
7077 "There's a C++-specific check for tok::identifier above");
7082 goto PastIdentifier;
7083 }
else if (Tok.
is(tok::identifier) && !
D.mayHaveIdentifier()) {
7087 bool DiagnoseIdentifier =
false;
7088 if (
D.hasGroupingParens())
7091 DiagnoseIdentifier =
true;
7094 DiagnoseIdentifier =
7102 !isCXX11VirtSpecifier(Tok))
7104 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
7105 if (DiagnoseIdentifier) {
7110 goto PastIdentifier;
7114 if (Tok.
is(tok::l_paren)) {
7118 if (
D.mayOmitIdentifier() &&
D.mayBeFollowedByCXXDirectInit()) {
7119 RevertingTentativeParsingAction PA(*
this);
7120 if (TryParseDeclarator(
true,
D.mayHaveIdentifier(),
true,
7121 D.getDeclSpec().getTypeSpecType() ==
TST_auto) ==
7124 goto PastIdentifier;
7131 ParseParenDeclarator(
D);
7136 if (
D.getCXXScopeSpec().isSet()) {
7139 if (!
D.isInvalidType() &&
7141 D.getCXXScopeSpec()))
7144 DeclScopeObj.EnterDeclaratorScope();
7146 }
else if (
D.mayOmitIdentifier()) {
7153 if (
D.hasEllipsis() &&
D.hasGroupingParens())
7155 diag::ext_abstract_pack_declarator_parens);
7157 if (Tok.
getKind() == tok::annot_pragma_parser_crash)
7159 if (Tok.
is(tok::l_square))
7160 return ParseMisplacedBracketDeclarator(
D);
7168 diag::err_expected_member_name_or_semi_objcxx_keyword)
7175 goto PastIdentifier;
7178 diag::err_expected_member_name_or_semi)
7182 if (Tok.
getKind() == tok::TokenKind::kw_while) {
7183 Diag(Tok, diag::err_while_loop_outside_of_a_function);
7185 if (Tok.
isOneOf(tok::period, tok::arrow))
7186 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.
is(tok::arrow);
7194 diag::err_expected_unqualified_id)
7199 diag::err_expected_either)
7200 << tok::identifier << tok::l_paren;
7204 D.setInvalidType(
true);
7208 assert(
D.isPastIdentifier() &&
7209 "Haven't past the location of the identifier yet?");
7212 if (
D.hasName() && !
D.getNumTypeObjects())
7213 MaybeParseCXX11Attributes(
D);
7216 if (Tok.
is(tok::l_paren)) {
7217 bool IsFunctionDeclaration =
D.isFunctionDeclaratorAFunctionDeclaration();
7220 ParseScope PrototypeScope(
this,
7222 (IsFunctionDeclaration
7228 bool IsAmbiguous =
false;
7239 if (
D.getCXXScopeSpec().isSet())
7240 AllowImplicitTypename =
7248 TentativelyDeclaredIdentifiers.push_back(
D.getIdentifier());
7249 bool IsFunctionDecl =
7250 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
7251 TentativelyDeclaredIdentifiers.pop_back();
7252 if (!IsFunctionDecl)
7258 if (IsFunctionDeclaration)
7260 TemplateParameterDepth);
7261 ParseFunctionDeclarator(
D, attrs,
T, IsAmbiguous);
7262 if (IsFunctionDeclaration)
7264 PrototypeScope.Exit();
7265 }
else if (Tok.
is(tok::l_square)) {
7266 ParseBracketDeclarator(
D);
7274 if (!
T.consumeOpen())
7277 }
else if (Tok.
is(tok::kw_requires) &&
D.hasGroupingParens()) {
7285 Diag(Tok, diag::err_requires_clause_inside_parens);
7289 if (TrailingRequiresClause.
isUsable() &&
D.isFunctionDeclarator() &&
7290 !
D.hasTrailingRequiresClause())
7292 D.setTrailingRequiresClause(TrailingRequiresClause.
get());
7299void Parser::ParseDecompositionDeclarator(
Declarator &
D) {
7300 assert(Tok.
is(tok::l_square));
7302 TentativeParsingAction PA(*
this);
7306 if (isCXX11AttributeSpecifier())
7307 DiagnoseAndSkipCXX11Attributes();
7311 if (!(Tok.
is(tok::identifier) &&
7314 !(Tok.
is(tok::r_square) &&
7317 return ParseMisplacedBracketDeclarator(
D);
7321 while (Tok.
isNot(tok::r_square)) {
7323 if (Tok.
is(tok::comma))
7326 if (Tok.
is(tok::identifier)) {
7328 Diag(EndLoc, diag::err_expected)
7331 Diag(Tok, diag::err_expected_comma_or_rsquare);
7334 SkipUntil(tok::r_square, tok::comma, tok::identifier,
7336 if (Tok.
is(tok::comma))
7338 else if (Tok.
isNot(tok::identifier))
7343 if (isCXX11AttributeSpecifier())
7344 DiagnoseAndSkipCXX11Attributes();
7346 if (Tok.
isNot(tok::identifier)) {
7347 Diag(Tok, diag::err_expected) << tok::identifier;
7356 if (isCXX11AttributeSpecifier()) {
7358 ? diag::warn_cxx23_compat_decl_attrs_on_binding
7359 : diag::ext_decl_attrs_on_binding);
7360 MaybeParseCXX11Attributes(Attrs);
7366 if (Tok.
isNot(tok::r_square))
7380 return D.setDecompositionBindings(
T.getOpenLocation(),
Bindings,
7381 T.getCloseLocation());
7401 assert(!
D.isPastIdentifier() &&
"Should be called before passing identifier");
7414 bool RequiresArg =
false;
7415 if (Tok.
is(tok::kw___attribute)) {
7416 ParseGNUAttributes(attrs);
7424 ParseMicrosoftTypeAttributes(attrs);
7427 if (Tok.
is(tok::kw___pascal))
7428 ParseBorlandTypeAttributes(attrs);
7436 if (!
D.mayOmitIdentifier()) {
7440 }
else if (Tok.
is(tok::r_paren) ||
7443 isDeclarationSpecifier(
7445 isCXX11AttributeSpecifier()) {
7461 bool hadGroupingParens =
D.hasGroupingParens();
7462 D.setGroupingParens(
true);
7463 ParseDeclaratorInternal(
D, &Parser::ParseDirectDeclarator);
7468 std::move(attrs),
T.getCloseLocation());
7470 D.setGroupingParens(hadGroupingParens);
7474 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc,
D);
7487 ParseScope PrototypeScope(
this,
7489 (
D.isFunctionDeclaratorAFunctionDeclaration()
7491 ParseFunctionDeclarator(
D, attrs,
T,
false, RequiresArg);
7492 PrototypeScope.Exit();
7495void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7497 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7505 bool IsCXX11MemberFunction =
7509 ? !
D.getDeclSpec().isFriendSpecified()
7511 D.getCXXScopeSpec().isValid() &&
7513 if (!IsCXX11MemberFunction)
7533 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.
CurContext), Q,
7534 IsCXX11MemberFunction);
7557void Parser::ParseFunctionDeclarator(
Declarator &
D,
7562 assert(
getCurScope()->isFunctionPrototypeScope() &&
7563 "Should call from a Function scope");
7565 assert(
D.isPastIdentifier() &&
"Should not call before identifier!");
7569 bool HasProto =
false;
7576 bool RefQualifierIsLValueRef =
true;
7594 StartLoc = LParenLoc;
7596 if (isFunctionDeclaratorIdentifierList()) {
7598 Diag(Tok, diag::err_argument_required_after_attribute);
7600 ParseFunctionDeclaratorIdentifierList(
D, ParamInfo);
7604 LocalEndLoc = RParenLoc;
7609 MaybeParseCXX11Attributes(FnAttrs);
7610 ProhibitAttributes(FnAttrs);
7612 if (Tok.
isNot(tok::r_paren))
7613 ParseParameterDeclarationClause(
D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7614 else if (RequiresArg)
7615 Diag(Tok, diag::err_argument_required_after_attribute);
7626 LocalEndLoc = RParenLoc;
7635 ParseTypeQualifierListOpt(
7636 DS, AR_NoAttributesParsed,
7638 false, llvm::function_ref<
void()>([&]() {
7646 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7647 EndLoc = RefQualifierLoc;
7649 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7650 InitCXXThisScopeForDeclaratorIfRelevant(
D, DS, ThisScope);
7666 D.isFunctionDeclaratorAFunctionDeclaration();
7668 GetLookAheadToken(0).is(tok::kw_noexcept) &&
7669 GetLookAheadToken(1).is(tok::l_paren) &&
7670 GetLookAheadToken(2).is(tok::kw_noexcept) &&
7671 GetLookAheadToken(3).is(tok::l_paren) &&
7672 GetLookAheadToken(4).is(tok::identifier) &&
7673 GetLookAheadToken(4).getIdentifierInfo()->isStr(
"swap")) {
7684 ESpecType = tryParseExceptionSpecification(Delayed,
7687 DynamicExceptionRanges,
7689 ExceptionSpecTokens);
7691 EndLoc = ESpecRange.
getEnd();
7695 MaybeParseCXX11Attributes(FnAttrs);
7698 LocalEndLoc = EndLoc;
7700 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7701 if (
D.getDeclSpec().getTypeSpecType() ==
TST_auto)
7702 StartLoc =
D.getDeclSpec().getTypeSpecTypeLoc();
7705 TrailingReturnType =
7706 ParseTrailingReturnType(
Range,
D.mayBeFollowedByCXXDirectInit());
7711 MaybeParseCXX11Attributes(FnAttrs);
7723 if (!ND || isa<ParmVarDecl>(ND))
7725 DeclsInPrototype.push_back(ND);
7732 llvm::sort(DeclsInPrototype, [](
Decl *D1,
Decl *D2) {
7740 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7741 ParamInfo.size(), EllipsisLoc, RParenLoc,
7742 RefQualifierIsLValueRef, RefQualifierLoc,
7744 ESpecType, ESpecRange, DynamicExceptions.data(),
7745 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7746 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7747 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7748 LocalEndLoc,
D, TrailingReturnType, TrailingReturnTypeLoc,
7750 std::move(FnAttrs), EndLoc);
7755bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7757 if (Tok.
isOneOf(tok::amp, tok::ampamp)) {
7759 diag::warn_cxx98_compat_ref_qualifier :
7760 diag::ext_ref_qualifier);
7762 RefQualifierIsLValueRef = Tok.
is(tok::amp);
7774bool Parser::isFunctionDeclaratorIdentifierList() {
7776 && Tok.
is(tok::identifier)
7777 && !TryAltiVecVectorToken()
7793 && (!Tok.
is(tok::eof) &&
7806void Parser::ParseFunctionDeclaratorIdentifierList(
7810 assert(!
getLangOpts().requiresStrictPrototypes() &&
7811 "Cannot parse an identifier list in C23 or C++");
7817 if (!
D.getIdentifier())
7818 Diag(Tok, diag::ext_ident_list_in_param);
7821 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
7825 if (Tok.
isNot(tok::identifier)) {
7826 Diag(Tok, diag::err_expected) << tok::identifier;
7837 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7840 if (!ParamsSoFar.insert(ParmII).second) {
7841 Diag(Tok, diag::err_param_redefinition) << ParmII;
7887void Parser::ParseParameterDeclarationClause(
7896 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7917 IsACXXFunctionDeclaration) {
7939 ArgDeclSpecAttrs.takeAllFrom(FirstArgAttrs);
7942 MaybeParseCXX11Attributes(ArgDeclAttrs);
7945 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7956 ParsedTemplateInfo TemplateInfo;
7957 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7958 DeclSpecContext::DSC_normal,
7959 nullptr, AllowImplicitTypename);
7972 ParseDeclarator(ParmDeclarator);
7975 ParmDeclarator.SetRangeBegin(ThisLoc);
7978 MaybeParseGNUAttributes(ParmDeclarator);
7982 if (Tok.
is(tok::kw_requires)) {
7987 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7998 std::unique_ptr<CachedTokens> DefArgToks;
8002 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
8003 ParmDeclarator.getNumTypeObjects() == 0) {
8005 Diag(DSStart, diag::err_missing_param);
8012 if (Tok.
is(tok::ellipsis) &&
8014 (!ParmDeclarator.getEllipsisLoc().isValid() &&
8017 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
8036 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
8049 Diag(ParmDeclarator.getBeginLoc(),
8050 diag::err_function_parameter_limit_exceeded);
8063 if (Tok.
is(tok::equal)) {
8074 ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument);
8090 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
8091 DefArgResult = ParseBraceInitializer();
8093 if (Tok.
is(tok::l_paren) &&
NextToken().is(tok::l_brace)) {
8094 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
8111 DefArgResult.
get());
8117 ParmDeclarator.getIdentifierLoc(),
8118 Param, std::move(DefArgToks)));
8126 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
8133 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
8135 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
8140 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
8141 << ParmEllipsis.
isValid() << ParmEllipsis;
8144 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
8146 Diag(ParmDeclarator.getIdentifierLoc(),
8147 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
8150 << !ParmDeclarator.hasName();
8152 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
8171void Parser::ParseBracketDeclarator(
Declarator &
D) {
8172 if (CheckProhibitedCXX11Attribute())
8180 if (Tok.
getKind() == tok::r_square) {
8183 MaybeParseCXX11Attributes(attrs);
8187 T.getOpenLocation(),
8188 T.getCloseLocation()),
8189 std::move(attrs),
T.getCloseLocation());
8191 }
else if (Tok.
getKind() == tok::numeric_constant &&
8192 GetLookAheadToken(1).is(tok::r_square)) {
8199 MaybeParseCXX11Attributes(attrs);
8203 T.getOpenLocation(),
8204 T.getCloseLocation()),
8205 std::move(attrs),
T.getCloseLocation());
8207 }
else if (Tok.
getKind() == tok::code_completion) {
8220 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
8228 bool isStar =
false;
8235 if (Tok.
is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
8239 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
8243 }
else if (Tok.
isNot(tok::r_square)) {
8261 Diag(StaticLoc, diag::err_unspecified_size_with_static);
8268 D.setInvalidType(
true);
8281 isStar, NumElements.
get(),
T.getOpenLocation(),
8282 T.getCloseLocation()),
8287void Parser::ParseMisplacedBracketDeclarator(
Declarator &
D) {
8288 assert(Tok.
is(tok::l_square) &&
"Missing opening bracket");
8289 assert(!
D.mayOmitIdentifier() &&
"Declarator cannot omit identifier");
8295 while (Tok.
is(tok::l_square)) {
8296 ParseBracketDeclarator(TempDeclarator);
8302 if (Tok.
is(tok::semi))
8303 D.getName().EndLocation = StartBracketLoc;
8308 ParseDeclaratorInternal(
D, &Parser::ParseDirectDeclarator);
8313 if (TempDeclarator.getNumTypeObjects() == 0)
8317 bool NeedParens =
false;
8318 if (
D.getNumTypeObjects() != 0) {
8319 switch (
D.getTypeObject(
D.getNumTypeObjects() - 1).
Kind) {
8342 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
8344 D.AddTypeInfo(Chunk, TempDeclarator.getAttributePool(),
SourceLocation());
8349 if (!
D.getIdentifier() && !NeedParens)
8355 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
8359 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8367 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8387void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
8388 assert(Tok.
isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
8389 "Not a typeof specifier");
8391 bool IsUnqual = Tok.
is(tok::kw_typeof_unqual);
8398 bool HasParens = Tok.
is(tok::l_paren);
8408 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange));
8424 const char *PrevSpec =
nullptr;
8432 Diag(StartLoc, DiagID) << PrevSpec;
8449 const char *PrevSpec =
nullptr;
8457 Diag(StartLoc, DiagID) << PrevSpec;
8463void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
8464 assert(Tok.
is(tok::kw__Atomic) &&
NextToken().is(tok::l_paren) &&
8465 "Not an atomic specifier");
8469 if (
T.consumeOpen())
8473 if (
Result.isInvalid()) {
8481 if (
T.getCloseLocation().isInvalid())
8487 const char *PrevSpec =
nullptr;
8492 Diag(StartLoc, DiagID) << PrevSpec;
8497bool Parser::TryAltiVecVectorTokenOutOfLine() {
8499 switch (Next.getKind()) {
8500 default:
return false;
8503 case tok::kw_signed:
8504 case tok::kw_unsigned:
8509 case tok::kw_double:
8512 case tok::kw___bool:
8513 case tok::kw___pixel:
8514 Tok.
setKind(tok::kw___vector);
8516 case tok::identifier:
8517 if (Next.getIdentifierInfo() == Ident_pixel) {
8518 Tok.
setKind(tok::kw___vector);
8521 if (Next.getIdentifierInfo() == Ident_bool ||
8522 Next.getIdentifierInfo() == Ident_Bool) {
8523 Tok.
setKind(tok::kw___vector);
8531 const char *&PrevSpec,
unsigned &DiagID,
8536 switch (Next.getKind()) {
8539 case tok::kw_signed:
8540 case tok::kw_unsigned:
8545 case tok::kw_double:
8548 case tok::kw___bool:
8549 case tok::kw___pixel:
8552 case tok::identifier:
8553 if (Next.getIdentifierInfo() == Ident_pixel) {
8557 if (Next.getIdentifierInfo() == Ident_bool ||
8558 Next.getIdentifierInfo() == Ident_Bool) {
8579TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8586 FileID FID = SourceMgr.createFileID(
8587 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8591 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8592 L.setParsingPreprocessorDirective(
true);
8598 Tokens.push_back(Tok);
8599 }
while (Tok.
isNot(tok::eod));
8604 Token &EndToken = Tokens.back();
8611 Tokens.push_back(Tok);
8614 PP.EnterTokenStream(Tokens,
false,
8622 ParseScope LocalScope(
this, 0);
8635 while (Tok.
isNot(tok::eof))
8639 if (Tok.
is(tok::eof) && Tok.
getEofData() == TypeStr.data())
8644void Parser::DiagnoseBitIntUse(
const Token &Tok) {
8648 assert(Tok.
isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8649 "expected either an _ExtInt or _BitInt token!");
8652 if (Tok.
is(tok::kw__ExtInt)) {
8653 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 ParsedAttributeArgumentsProperties attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has string arguments.
static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute takes a strict identifier argument.
static bool attributeIsTypeArgAttr(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute parses a type argument.
static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute treats kw_this as an identifier.
static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute requires parsing its arguments in an unevaluated context or not...
static bool attributeHasIdentifierArg(const llvm::Triple &T, const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has an identifier argument.
static bool isValidAfterIdentifierInDeclarator(const Token &T)
isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the specified token is valid after t...
static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has a variadic identifier argument.
static bool isPipeDeclarator(const Declarator &D)
static SourceLocation getMissingDeclaratorIdLoc(Declarator &D, SourceLocation Loc)
static bool attributeAcceptsExprPack(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine if an attribute accepts parameter packs.
static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS, Parser &P)
static bool VersionNumberSeparator(const char Separator)
static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, DeclaratorContext TheContext)
llvm::SmallVector< std::pair< const MemRegion *, SVal >, 4 > Bindings
static constexpr bool isOneOf()
This file declares semantic analysis for CUDA constructs.
This file declares facilities that support code completion.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenMP constructs and clauses.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the clang::TokenKind enum and support functions.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
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.
Syntax
The style used to specify an attribute.
@ AS_Declspec
__declspec(...)
Kind getParsedKind() const
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
SourceLocation getOpenLocation() const
SourceLocation getCloseLocation() const
Represents a C++ nested-name-specifier or a global scope specifier.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
SourceLocation getEndLoc() const
bool isSet() const
Deprecated.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
void setTemplateParamLists(ArrayRef< TemplateParameterList * > L)
bool isEmpty() const
No scope specifier.
Represents a character-granular source range.
SourceLocation getBegin() const
Callback handler that receives notifications when performing code completion within the preprocessor.
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed.
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Captures information about "declaration specifiers".
bool isVirtualSpecified() const
bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, ExplicitSpecifier ExplicitSpec, SourceLocation CloseParenLoc)
bool isTypeSpecPipe() const
static const TSCS TSCS___thread
static const TST TST_typeof_unqualType
void setTypeArgumentRange(SourceRange range)
bool SetTypePipe(bool isPipe, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
SourceLocation getPipeLoc() const
static const TST TST_typename
SourceLocation getEndLoc() const LLVM_READONLY
bool hasTypeSpecifier() const
Return true if any type-specifier has been found.
bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec and return false if there was no error.
static const TST TST_char8
static const TST TST_BFloat16
void ClearStorageClassSpecs()
bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TSCS TSCS__Thread_local
bool SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec, but return true and ignore the request if ...
bool isNoreturnSpecified() const
TST getTypeSpecType() const
SourceLocation getStorageClassSpecLoc() const
SCS getStorageClassSpec() const
bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceRange getSourceRange() const LLVM_READONLY
bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void SetRangeEnd(SourceLocation Loc)
bool SetBitIntType(SourceLocation KWLoc, Expr *BitWidth, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_auto_type
static const TST TST_interface
static const TST TST_double
static const TST TST_typeofExpr
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
void SetRangeStart(SourceLocation Loc)
bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getNoreturnSpecLoc() const
static const TST TST_union
static const TST TST_char
static const TST TST_bool
static const TST TST_char16
SourceLocation getExplicitSpecLoc() const
SourceLocation getFriendSpecLoc() const
SourceLocation getModulePrivateSpecLoc() const
bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void UpdateTypeRep(ParsedType Rep)
TSCS getThreadStorageClassSpec() const
bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasAttributes() const
static const TST TST_accum
static const TST TST_half
ParsedAttributes & getAttributes()
SourceLocation getConstSpecLoc() const
static const TST TST_ibm128
void addAttributes(const ParsedAttributesView &AL)
Concatenates two attribute lists.
static const TST TST_enum
bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_float128
void Finish(Sema &S, const PrintingPolicy &Policy)
Finish - This does final analysis of the declspec, issuing diagnostics for things like "_Complex" (la...
bool isInlineSpecified() const
SourceLocation getRestrictSpecLoc() const
static const TST TST_typeof_unqualExpr
static const TST TST_class
bool hasTagDefinition() const
static const TST TST_decimal64
unsigned getParsedSpecifiers() const
Return a bitmask of which flavors of specifiers this DeclSpec includes.
void ClearFunctionSpecs()
bool SetTypeQual(TQ T, SourceLocation Loc)
static const TST TST_wchar
static const TST TST_void
bool isTypeAltiVecVector() const
void ClearConstexprSpec()
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
static const TST TST_float
static const TST TST_atomic
static const TST TST_fract
SourceLocation getThreadStorageClassSpecLoc() const
Decl * getRepAsDecl() const
static const TST TST_float16
static const TST TST_unspecified
SourceLocation getAtomicSpecLoc() const
SourceLocation getVirtualSpecLoc() const
SourceLocation getConstexprSpecLoc() const
CXXScopeSpec & getTypeSpecScope()
bool isEmpty() const
isEmpty - Return true if this declaration specifier is completely empty: no tokens were parsed in the...
static const TSCS TSCS_thread_local
bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal32
bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
TypeSpecifierWidth getTypeSpecWidth() const
static const TST TST_char32
bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal128
bool isTypeSpecOwned() const
SourceLocation getInlineSpecLoc() const
SourceLocation getUnalignedSpecLoc() const
static const TST TST_int128
SourceLocation getVolatileSpecLoc() const
FriendSpecified isFriendSpecified() const
bool hasExplicitSpecifier() const
bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasConstexprSpecifier() const
void takeAttributesFrom(ParsedAttributes &attrs)
static const TST TST_typeofType
bool SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_auto
@ PQ_StorageClassSpecifier
ConstexprSpecKind getConstexprSpecifier() const
static const TST TST_struct
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
Kind
Lists the kind of concrete classes of Decl.
bool isInvalidDecl() const
SourceLocation getLocation() const
SourceLocation getBeginLoc() const LLVM_READONLY
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Information about one declarator, including the parsed type information and the identifier.
bool isInvalidType() const
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
bool hasAllExtensionsSilenced()
RAII object that enters a new expression evaluation context.
Store information needed for an explicit specifier.
This represents one expression.
ExtensionRAIIObject - This saves the state of extension warnings when constructed and disables them.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code from FromRange at a specific location.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
bool isCPlusPlusKeyword(const LangOptions &LangOpts) const
Return true if this token is a C++ keyword in the specified language.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
void revertTokenIDToIdentifier()
Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2 compatibility.
StringRef getName() const
Return the actual identifier string.
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.
void takeAllFrom(ParsedAttributes &Other)
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.
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
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)
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
Decl * ActOnTemplateDeclarator(Scope *S, MultiTemplateParamsArg TemplateParameterLists, Declarator &D)
TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S)
isTagName() - This method is called for error recovery purposes only to determine if the specified na...
void ActOnFinishFunctionDeclarationDeclarator(Declarator &D)
Called after parsing a function declarator belonging to a function declaration.
void ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc, Expr *defarg)
ActOnParamDefaultArgument - Check whether the default argument provided for a function parameter is w...
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
void ActOnFinishTopLevelStmtDecl(TopLevelStmtDecl *D, Stmt *Statement)
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param)
This is used to implement the constant expression evaluation part of the attribute enable_if extensio...
ASTContext & getASTContext() const
bool isCurrentClassName(const IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS=nullptr)
isCurrentClassName - Determine whether the identifier II is the name of the class type currently bein...
@ 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 DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, UnexpandedParameterPackContext UPPC)
If the given type contains an unexpanded parameter pack, diagnose the error.
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 ActOnFinishDelayedAttribute(Scope *S, Decl *D, ParsedAttributes &Attrs)
ActOnFinishDelayedAttribute - Invoked when we have finished parsing an attribute for which parsing is...
void ActOnUninitializedDecl(Decl *dcl)
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
Decl * ActOnField(Scope *S, Decl *TagD, SourceLocation DeclStart, Declarator &D, Expr *BitfieldWidth)
ActOnField - Each field of a C struct/union is passed into this in order to create a FieldDecl object...
void ActOnCXXForRangeDecl(Decl *D)
Decl * ActOnDeclarator(Scope *S, Declarator &D)
ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope=nullptr)
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
void DiagnoseUnknownTypeName(IdentifierInfo *&II, SourceLocation IILoc, Scope *S, CXXScopeSpec *SS, ParsedType &SuggestedType, bool IsTemplateName=false)
ExprResult HandleExprEvaluationContextForTypeof(Expr *E)
bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS)
Determine whether the identifier II is a typo for the name of the class type currently being defined.
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.
static constexpr int FunctionTypeNumParamsLimit
The iterator over UnresolvedSets.
Declaration of a variable template.
static const char * getSpecifierName(Specifier VS)
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
bool InitScope(InterpState &S, CodePtr OpPC, uint32_t I)
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isPragmaAnnotation(TokenKind K)
Return true if this is an annotation token representing a pragma.
The JSON file list parser is used to communicate input to InstallAPI.
TypeSpecifierType
Specifies the kind of type.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
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.
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
enum clang::DeclaratorChunk::@222 Kind
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.
bool InLifetimeExtendingContext
Whether we are currently in a context in which all temporaries must be lifetime-extended,...
ExpressionKind
Describes whether we are in an expression constext which we have to handle differently.
Information about a template-id annotation token.
bool hasInvalidName() const
const IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
TemplateNameKind Kind
The kind of template that Template refers to.
bool hasInvalidArgs() const