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);
192 assert(Tok.
is(tok::kw___attribute) &&
"Not a GNU attribute list!");
197 while (Tok.
is(tok::kw___attribute)) {
199 unsigned OldNumAttrs = Attrs.
size();
200 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
202 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
207 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"(")) {
220 if (Tok.
is(tok::code_completion)) {
232 if (Tok.
isNot(tok::l_paren)) {
233 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
234 ParsedAttr::Form::GNU());
238 bool LateParse =
false;
241 else if (LateAttrs->lateAttrParseExperimentalExtOnly()) {
245 LateParse =
getLangOpts().ExperimentalLateParseAttributes &&
258 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc,
nullptr,
264 LateParsedAttribute *LA =
265 new LateParsedAttribute(
this, *AttrName, AttrNameLoc);
266 LateAttrs->push_back(LA);
270 if (!ClassStack.empty() && !LateAttrs->parseSoon())
271 getCurrentClass().LateParsedDeclarations.push_back(LA);
275 LA->Toks.push_back(Tok);
278 ConsumeAndStoreUntil(tok::r_paren, LA->Toks,
true);
283 LA->Toks.push_back(Eof);
284 }
while (Tok.
is(tok::comma));
286 if (ExpectAndConsume(tok::r_paren))
289 if (ExpectAndConsume(tok::r_paren))
296 if (!
SM.isWrittenInBuiltinFile(
SM.getSpellingLoc(AttrTokLoc)) &&
299 StringRef FoundName =
303 for (
unsigned i = OldNumAttrs; i < Attrs.
size(); ++i)
304 Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.
getBegin());
307 for (
unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
308 (*LateAttrs)[i]->MacroII = MacroII;
318#define CLANG_ATTR_IDENTIFIER_ARG_LIST
320#include "clang/Parse/AttrParserStringSwitches.inc"
322#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
328#define CLANG_ATTR_STRING_LITERAL_ARG_LIST
330#include "clang/Parse/AttrParserStringSwitches.inc"
332#undef CLANG_ATTR_STRING_LITERAL_ARG_LIST
337#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
339#include "clang/Parse/AttrParserStringSwitches.inc"
341#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
346#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
348#include "clang/Parse/AttrParserStringSwitches.inc"
350#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
355#define CLANG_ATTR_ACCEPTS_EXPR_PACK
357#include "clang/Parse/AttrParserStringSwitches.inc"
359#undef CLANG_ATTR_ACCEPTS_EXPR_PACK
364#define CLANG_ATTR_TYPE_ARG_LIST
366#include "clang/Parse/AttrParserStringSwitches.inc"
368#undef CLANG_ATTR_TYPE_ARG_LIST
373#define CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST
375#include
"clang/Parse/AttrParserStringSwitches.inc"
377#undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST
384#define CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST
386#include
"clang/Parse/AttrParserStringSwitches.inc"
389#undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_AT_INDEX_LIST
395#define CLANG_ATTR_ARG_CONTEXT_LIST
397#include "clang/Parse/AttrParserStringSwitches.inc"
399#undef CLANG_ATTR_ARG_CONTEXT_LIST
403 assert(Tok.
is(tok::identifier) &&
"expected an identifier");
421 if (Tok.
isNot(tok::r_paren))
424 if (
Parens.consumeClose())
433 ScopeName, ScopeLoc,
T.get(), Form);
436 ScopeName, ScopeLoc,
nullptr, 0, Form);
440Parser::ParseUnevaluatedStringInAttribute(
const IdentifierInfo &AttrName) {
441 if (Tok.
is(tok::l_paren)) {
444 ExprResult Res = ParseUnevaluatedStringInAttribute(AttrName);
445 Paren.consumeClose();
448 if (!isTokenStringLiteral()) {
456bool Parser::ParseAttributeArgumentList(
459 bool SawError =
false;
464 Expr = ParseUnevaluatedStringInAttribute(AttrName);
466 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
467 Expr = ParseBraceInitializer();
473 if (Tok.
is(tok::ellipsis))
475 else if (Tok.
is(tok::code_completion)) {
486 if (
Expr.isInvalid()) {
496 Exprs.push_back(
Expr.get());
498 if (Tok.
isNot(tok::comma))
503 checkPotentialAngleBracketDelimiter(Comma);
510 for (
auto &
E : Exprs) {
519unsigned Parser::ParseAttributeArgsCommon(
528 bool AttributeHasVariadicIdentifierArg =
532 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
536 if (Tok.
is(tok::identifier)) {
538 bool IsIdentifierArg = AttributeHasVariadicIdentifierArg ||
548 IsIdentifierArg = Next.isOneOf(tok::r_paren, tok::comma);
552 ArgExprs.push_back(ParseIdentifierLoc());
556 if (!ArgExprs.empty() ? Tok.
is(tok::comma) : Tok.
isNot(tok::r_paren)) {
558 if (!ArgExprs.empty())
561 if (AttributeIsTypeArgAttr) {
569 TheParsedType =
T.get();
570 }
else if (AttributeHasVariadicIdentifierArg ||
579 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
583 *AttrName, ArgExprs.size())) {
584 ArgExprs.push_back(ParseIdentifierLoc());
589 if (Tok.
is(tok::identifier)) {
590 ArgExprs.push_back(ParseIdentifierLoc());
607 ArgExprs.push_back(ArgExpr.
get());
622 ExprVector ParsedExprs;
625 if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties)) {
631 for (
size_t I = 0; I < ParsedExprs.size(); ++I) {
632 if (!isa<PackExpansionExpr>(ParsedExprs[I]))
637 diag::err_attribute_argument_parm_pack_not_supported)
644 ArgExprs.insert(ArgExprs.end(), ParsedExprs.begin(), ParsedExprs.end());
649 if (!ExpectAndConsume(tok::r_paren)) {
652 if (AttributeIsTypeArgAttr && !TheParsedType.
get().
isNull()) {
654 ScopeName, ScopeLoc, TheParsedType, Form);
657 ArgExprs.data(), ArgExprs.size(), Form);
664 return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.
get().
isNull());
669void Parser::ParseGNUAttributeArgs(
674 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
679 if (AttrKind == ParsedAttr::AT_Availability) {
680 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
683 }
else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
684 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
685 ScopeName, ScopeLoc, Form);
687 }
else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
688 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
689 ScopeName, ScopeLoc, Form);
691 }
else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
692 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
695 }
else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
696 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
697 ScopeName, ScopeLoc, Form);
700 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName,
703 }
else if (AttrKind == ParsedAttr::AT_CountedBy ||
704 AttrKind == ParsedAttr::AT_CountedByOrNull ||
705 AttrKind == ParsedAttr::AT_SizedBy ||
706 AttrKind == ParsedAttr::AT_SizedByOrNull) {
707 ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
710 }
else if (AttrKind == ParsedAttr::AT_CXXAssume) {
711 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc, Form);
717 std::optional<ParseScope> PrototypeScope;
719 D &&
D->isFunctionDeclarator()) {
724 for (
unsigned i = 0; i != FTI.
NumParams; ++i) {
730 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
734unsigned Parser::ParseClangAttributeArgs(
738 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
745 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
746 ScopeName, ScopeLoc, Form);
747 case ParsedAttr::AT_ExternalSourceSymbol:
748 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
749 ScopeName, ScopeLoc, Form);
751 case ParsedAttr::AT_Availability:
752 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
755 case ParsedAttr::AT_ObjCBridgeRelated:
756 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
757 ScopeName, ScopeLoc, Form);
759 case ParsedAttr::AT_SwiftNewType:
760 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
763 case ParsedAttr::AT_TypeTagForDatatype:
764 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
765 ScopeName, ScopeLoc, Form);
768 case ParsedAttr::AT_CXXAssume:
769 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc, Form);
772 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
778 unsigned ExistingAttrs = Attrs.
size();
792 if (AttrName->
getName() ==
"property") {
798 T.expectAndConsume(diag::err_expected_lparen_after,
807 bool HasInvalidAccessor =
false;
812 if (!Tok.
is(tok::identifier)) {
814 if (Tok.
is(tok::r_paren) && !HasInvalidAccessor &&
815 AccessorNames[AK_Put] ==
nullptr &&
816 AccessorNames[AK_Get] ==
nullptr) {
817 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
828 if (KindStr ==
"get") {
830 }
else if (KindStr ==
"put") {
834 }
else if (KindStr ==
"set") {
835 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
842 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
844 HasInvalidAccessor =
true;
845 goto next_property_accessor;
849 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
850 HasInvalidAccessor =
true;
869 if (!Tok.
is(tok::identifier)) {
874 if (Kind == AK_Invalid) {
876 }
else if (AccessorNames[Kind] !=
nullptr) {
878 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
884 next_property_accessor:
890 if (Tok.
is(tok::r_paren))
893 Diag(Tok.
getLocation(), diag::err_ms_property_expected_comma_or_rparen);
898 if (!HasInvalidAccessor)
900 AccessorNames[AK_Get], AccessorNames[AK_Put],
901 ParsedAttr::Form::Declspec());
903 return !HasInvalidAccessor;
907 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
913 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) << AttrName;
926 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
927 assert(Tok.
is(tok::kw___declspec) &&
"Not a declspec!");
932 while (Tok.
is(tok::kw___declspec)) {
935 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
941 while (Tok.
isNot(tok::r_paren)) {
946 if (Tok.
is(tok::code_completion)) {
955 bool IsString = Tok.
getKind() == tok::string_literal;
956 if (!IsString && Tok.
getKind() != tok::identifier &&
957 Tok.
getKind() != tok::kw_restrict) {
958 Diag(Tok, diag::err_ms_declspec_type);
968 StringRef Str = PP.
getSpelling(Tok, StrBuffer, &Invalid);
974 AttrNameLoc = ConsumeStringToken();
980 bool AttrHandled =
false;
983 if (Tok.
is(tok::l_paren))
984 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
985 else if (AttrName->
getName() ==
"property")
991 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
992 ParsedAttr::Form::Declspec());
995 EndLoc =
T.getCloseLocation();
1006 case tok::kw___fastcall:
1007 case tok::kw___stdcall:
1008 case tok::kw___thiscall:
1009 case tok::kw___regcall:
1010 case tok::kw___cdecl:
1011 case tok::kw___vectorcall:
1012 case tok::kw___ptr64:
1014 case tok::kw___ptr32:
1015 case tok::kw___sptr:
1016 case tok::kw___uptr: {
1019 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1029void Parser::ParseWebAssemblyFuncrefTypeAttribute(
ParsedAttributes &attrs) {
1030 assert(Tok.
is(tok::kw___funcref));
1034 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
1040 attrs.
addNew(AttrName, AttrNameLoc,
nullptr,
1045void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
1051 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) <<
Range;
1061 case tok::kw_volatile:
1062 case tok::kw___fastcall:
1063 case tok::kw___stdcall:
1064 case tok::kw___thiscall:
1065 case tok::kw___cdecl:
1066 case tok::kw___vectorcall:
1067 case tok::kw___ptr32:
1068 case tok::kw___ptr64:
1070 case tok::kw___unaligned:
1071 case tok::kw___sptr:
1072 case tok::kw___uptr:
1083 while (Tok.
is(tok::kw___pascal)) {
1086 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1093 while (Tok.
is(tok::kw___kernel)) {
1096 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1102 while (Tok.
is(tok::kw___noinline__)) {
1105 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1106 tok::kw___noinline__);
1113 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1117bool Parser::isHLSLQualifier(
const Token &Tok)
const {
1118 return Tok.
is(tok::kw_groupshared);
1125 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0, Kind);
1133 case tok::kw__Nonnull:
1134 case tok::kw__Nullable:
1135 case tok::kw__Nullable_result:
1136 case tok::kw__Null_unspecified: {
1140 Diag(AttrNameLoc, diag::ext_nullability)
1142 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1153 return (Separator ==
'.' || Separator ==
'_');
1167 if (!Tok.
is(tok::numeric_constant)) {
1168 Diag(Tok, diag::err_expected_version);
1171 return VersionTuple();
1180 const char *ThisTokBegin = &Buffer[0];
1184 unsigned ActualLength = PP.
getSpelling(Tok, ThisTokBegin, &Invalid);
1186 return VersionTuple();
1189 unsigned AfterMajor = 0;
1191 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
1192 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
1196 if (AfterMajor == 0) {
1197 Diag(Tok, diag::err_expected_version);
1200 return VersionTuple();
1203 if (AfterMajor == ActualLength) {
1208 Diag(Tok, diag::err_zero_version);
1209 return VersionTuple();
1212 return VersionTuple(Major);
1215 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1217 || (AfterMajor + 1 == ActualLength)) {
1218 Diag(Tok, diag::err_expected_version);
1221 return VersionTuple();
1225 unsigned AfterMinor = AfterMajor + 1;
1227 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
1228 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
1232 if (AfterMinor == ActualLength) {
1236 if (Major == 0 && Minor == 0) {
1237 Diag(Tok, diag::err_zero_version);
1238 return VersionTuple();
1241 return VersionTuple(Major, Minor);
1244 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1247 Diag(Tok, diag::err_expected_version);
1250 return VersionTuple();
1254 if (AfterMajorSeparator != AfterMinorSeparator)
1255 Diag(Tok, diag::warn_expected_consistent_version_separator);
1258 unsigned AfterSubminor = AfterMinor + 1;
1259 unsigned Subminor = 0;
1260 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
1261 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
1265 if (AfterSubminor != ActualLength) {
1266 Diag(Tok, diag::err_expected_version);
1269 return VersionTuple();
1272 return VersionTuple(Major, Minor, Subminor);
1300void Parser::ParseAvailabilityAttribute(
1304 enum { Introduced, Deprecated, Obsoleted,
Unknown };
1311 if (
T.consumeOpen()) {
1312 Diag(Tok, diag::err_expected) << tok::l_paren;
1317 if (Tok.
isNot(tok::identifier)) {
1318 Diag(Tok, diag::err_availability_expected_platform);
1325 if (Ident->getName().contains(
"xrOS") || Ident->getName().contains(
"xros"))
1326 Diag(Platform->
Loc, diag::warn_availability_unknown_platform) << Ident;
1328 else if (Ident->getName() ==
"macosx")
1332 else if (Ident->getName() ==
"macosx_app_extension")
1336 AvailabilityAttr::canonicalizePlatformName(Ident->getName()));
1340 if (ExpectAndConsume(tok::comma)) {
1347 if (!Ident_introduced) {
1362 if (Tok.
isNot(tok::identifier)) {
1363 Diag(Tok, diag::err_availability_expected_change);
1370 if (Keyword == Ident_strict) {
1372 Diag(KeywordLoc, diag::err_availability_redundant)
1375 StrictLoc = KeywordLoc;
1379 if (Keyword == Ident_unavailable) {
1380 if (UnavailableLoc.
isValid()) {
1381 Diag(KeywordLoc, diag::err_availability_redundant)
1384 UnavailableLoc = KeywordLoc;
1388 if (Keyword == Ident_deprecated && Platform->
Ident &&
1391 if (Changes[Deprecated].KeywordLoc.
isValid()) {
1392 Diag(KeywordLoc, diag::err_availability_redundant)
1399 Changes[Deprecated].
Version = VersionTuple(1);
1403 if (Keyword == Ident_environment) {
1404 if (EnvironmentLoc !=
nullptr) {
1405 Diag(KeywordLoc, diag::err_availability_redundant)
1410 if (Tok.
isNot(tok::equal)) {
1411 Diag(Tok, diag::err_expected_after) << Keyword << tok::equal;
1416 if (Keyword == Ident_message || Keyword == Ident_replacement) {
1417 if (!isTokenStringLiteral()) {
1418 Diag(Tok, diag::err_expected_string_literal)
1423 if (Keyword == Ident_message) {
1431 if (Keyword == Ident_environment) {
1432 if (Tok.
isNot(tok::identifier)) {
1433 Diag(Tok, diag::err_availability_expected_environment);
1437 EnvironmentLoc = ParseIdentifierLoc();
1443 if ((Keyword == Ident_introduced || Keyword == Ident_deprecated) &&
1444 Tok.
is(tok::identifier)) {
1448 if (Keyword == Ident_introduced)
1449 UnavailableLoc = KeywordLoc;
1455 VersionTuple Version = ParseVersionTuple(VersionRange);
1457 if (Version.empty()) {
1463 if (Keyword == Ident_introduced)
1465 else if (Keyword == Ident_deprecated)
1467 else if (Keyword == Ident_obsoleted)
1473 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1474 Diag(KeywordLoc, diag::err_availability_redundant)
1477 Changes[Index].VersionRange.
getEnd());
1481 Changes[Index].
Version = Version;
1484 Diag(KeywordLoc, diag::err_availability_unknown_change)
1485 << Keyword << VersionRange;
1491 if (
T.consumeClose())
1495 *endLoc =
T.getCloseLocation();
1499 if (UnavailableLoc.
isValid()) {
1500 bool Complained =
false;
1501 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1502 if (Changes[Index].KeywordLoc.
isValid()) {
1504 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1506 Changes[Index].VersionRange.
getEnd());
1517 attrs.
addNew(&Availability,
1518 SourceRange(AvailabilityLoc,
T.getCloseLocation()), ScopeName,
1519 ScopeLoc, Platform, Changes[Introduced], Changes[Deprecated],
1520 Changes[Obsoleted], UnavailableLoc, MessageExpr.
get(), Form,
1521 StrictLoc, ReplacementExpr.
get(), EnvironmentLoc);
1538void Parser::ParseExternalSourceSymbolAttribute(
1544 if (
T.expectAndConsume())
1548 if (!Ident_language) {
1556 bool HasLanguage =
false;
1558 bool HasDefinedIn =
false;
1561 bool HasUSR =
false;
1565 if (Tok.
isNot(tok::identifier)) {
1566 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1573 if (Keyword == Ident_generated_declaration) {
1574 if (GeneratedDeclaration) {
1575 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) << Keyword;
1579 GeneratedDeclaration = ParseIdentifierLoc();
1583 if (Keyword != Ident_language && Keyword != Ident_defined_in &&
1584 Keyword != Ident_USR) {
1585 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1591 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1597 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1599 if (Keyword == Ident_language)
1601 else if (Keyword == Ident_USR)
1604 HasDefinedIn =
true;
1606 if (!isTokenStringLiteral()) {
1607 Diag(Tok, diag::err_expected_string_literal)
1610 Keyword == Ident_language
1612 : (Keyword == Ident_defined_in ? 1 : 2));
1616 if (Keyword == Ident_language) {
1618 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1624 }
else if (Keyword == Ident_USR) {
1626 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1633 assert(Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1635 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1645 if (
T.consumeClose())
1648 *EndLoc =
T.getCloseLocation();
1653 ScopeName, ScopeLoc, Args, std::size(Args), Form);
1667void Parser::ParseObjCBridgeRelatedAttribute(
1673 if (
T.consumeOpen()) {
1674 Diag(Tok, diag::err_expected) << tok::l_paren;
1679 if (Tok.
isNot(tok::identifier)) {
1680 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1685 if (ExpectAndConsume(tok::comma)) {
1694 if (Tok.
is(tok::identifier)) {
1697 Diag(Tok, diag::err_objcbridge_related_selector_name);
1703 if (Tok.
is(tok::colon))
1704 Diag(Tok, diag::err_objcbridge_related_selector_name);
1706 Diag(Tok, diag::err_expected) << tok::comma;
1714 if (Tok.
is(tok::identifier))
1716 else if (Tok.
isNot(tok::r_paren)) {
1717 Diag(Tok, diag::err_expected) << tok::r_paren;
1723 if (
T.consumeClose())
1727 *EndLoc =
T.getCloseLocation();
1730 Attrs.
addNew(&ObjCBridgeRelated,
1731 SourceRange(ObjCBridgeRelatedLoc,
T.getCloseLocation()),
1732 ScopeName, ScopeLoc, RelatedClass, ClassMethod, InstanceMethod,
1736void Parser::ParseSwiftNewTypeAttribute(
1743 if (
T.consumeOpen()) {
1744 Diag(Tok, diag::err_expected) << tok::l_paren;
1748 if (Tok.
is(tok::r_paren)) {
1753 if (Tok.
isNot(tok::kw_struct) && Tok.
isNot(tok::kw_enum)) {
1754 Diag(Tok, diag::warn_attribute_type_not_supported)
1756 if (!isTokenSpecial())
1767 if (
T.consumeClose())
1770 *EndLoc =
T.getCloseLocation();
1774 ScopeName, ScopeLoc, Args, std::size(Args), Form);
1777void Parser::ParseTypeTagForDatatypeAttribute(
1781 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1786 if (Tok.
isNot(tok::identifier)) {
1787 Diag(Tok, diag::err_expected) << tok::identifier;
1793 if (ExpectAndConsume(tok::comma)) {
1805 bool LayoutCompatible =
false;
1806 bool MustBeNull =
false;
1808 if (Tok.
isNot(tok::identifier)) {
1809 Diag(Tok, diag::err_expected) << tok::identifier;
1814 if (Flag->
isStr(
"layout_compatible"))
1815 LayoutCompatible =
true;
1816 else if (Flag->
isStr(
"must_be_null"))
1819 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1826 if (!
T.consumeClose()) {
1828 ArgumentKind, MatchingCType.
get(),
1829 LayoutCompatible, MustBeNull, Form);
1833 *EndLoc =
T.getCloseLocation();
1844bool Parser::DiagnoseProhibitedCXX11Attribute() {
1845 assert(Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square));
1847 switch (isCXX11AttributeSpecifier(
true)) {
1848 case CAK_NotAttributeSpecifier:
1852 case CAK_InvalidAttributeSpecifier:
1856 case CAK_AttributeSpecifier:
1861 assert(Tok.
is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1863 Diag(BeginLoc, diag::err_attributes_not_allowed)
1867 llvm_unreachable(
"All cases handled above.");
1876 assert((Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square)) ||
1883 ParseCXX11Attributes(Attrs);
1886 (Keyword ?
Diag(
Loc, diag::err_keyword_not_allowed) << Keyword
1887 :
Diag(
Loc, diag::err_attributes_not_allowed))
1892void Parser::DiagnoseProhibitedAttributes(
1894 auto *FirstAttr = Attrs.
empty() ? nullptr : &Attrs.
front();
1895 if (CorrectLocation.
isValid()) {
1897 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1898 ?
Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1899 :
Diag(CorrectLocation, diag::err_attributes_misplaced))
1904 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1912 unsigned AttrDiagID,
1913 unsigned KeywordDiagID,
1914 bool DiagnoseEmptyAttrs,
1915 bool WarnOnUnknownAttrs) {
1925 if (FirstLSquare.
is(tok::l_square)) {
1926 std::optional<Token> SecondLSquare =
1929 if (SecondLSquare && SecondLSquare->is(tok::l_square)) {
1940 if (AL.isRegularKeywordAttribute()) {
1941 Diag(AL.getLoc(), KeywordDiagID) << AL;
1945 if (!AL.isStandardAttributeSyntax())
1948 if (WarnOnUnknownAttrs)
1949 Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
1950 << AL << AL.getRange();
1952 Diag(AL.getLoc(), AttrDiagID) << AL;
1960 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1961 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1962 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
1981 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1982 AL.isDeclspecAttribute()) ||
1983 AL.isMicrosoftAttribute())
1984 ToBeMoved.push_back(&AL);
2019 Decl *SingleDecl =
nullptr;
2021 case tok::kw_template:
2022 case tok::kw_export:
2023 ProhibitAttributes(DeclAttrs);
2024 ProhibitAttributes(DeclSpecAttrs);
2025 return ParseDeclarationStartingWithTemplate(Context, DeclEnd, DeclAttrs);
2026 case tok::kw_inline:
2029 ProhibitAttributes(DeclAttrs);
2030 ProhibitAttributes(DeclSpecAttrs);
2032 return ParseNamespace(Context, DeclEnd, InlineLoc);
2034 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
2035 true,
nullptr, DeclSpecStart);
2037 case tok::kw_cbuffer:
2038 case tok::kw_tbuffer:
2039 SingleDecl = ParseHLSLBuffer(DeclEnd);
2041 case tok::kw_namespace:
2042 ProhibitAttributes(DeclAttrs);
2043 ProhibitAttributes(DeclSpecAttrs);
2044 return ParseNamespace(Context, DeclEnd);
2045 case tok::kw_using: {
2048 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
2051 case tok::kw_static_assert:
2052 case tok::kw__Static_assert:
2053 ProhibitAttributes(DeclAttrs);
2054 ProhibitAttributes(DeclSpecAttrs);
2055 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
2058 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
2059 true,
nullptr, DeclSpecStart);
2091 bool RequireSemi, ForRangeInit *FRI,
SourceLocation *DeclSpecStart) {
2094 OriginalDeclSpecAttrs.
addAll(DeclSpecAttrs.
begin(), DeclSpecAttrs.
end());
2095 OriginalDeclSpecAttrs.
Range = DeclSpecAttrs.
Range;
2101 ParsedTemplateInfo TemplateInfo;
2102 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
2103 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none, DSContext);
2108 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
2113 if (Tok.
is(tok::semi)) {
2114 ProhibitAttributes(DeclAttrs);
2121 DS.complete(TheDecl);
2123 Decl* decls[] = {AnonRecord, TheDecl};
2135 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
2142 case tok::annot_cxxscope:
2143 case tok::annot_template_id:
2145 case tok::code_completion:
2146 case tok::coloncolon:
2148 case tok::kw___attribute:
2149 case tok::kw_operator:
2165 case tok::identifier:
2167 case tok::code_completion:
2168 case tok::coloncolon:
2171 case tok::equalequal:
2172 case tok::kw_alignas:
2174 case tok::kw___attribute:
2192 case tok::identifier:
2215 if (Tok.
isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
2239 case tok::kw_inline:
2244 (!ParsingInObjCContainer || CurParsedObjCImpl))
2248 case tok::kw_namespace:
2253 (!ParsingInObjCContainer || CurParsedObjCImpl))
2259 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2260 ParsingInObjCContainer)
2272 case tok::annot_module_begin:
2273 case tok::annot_module_end:
2274 case tok::annot_module_include:
2275 case tok::annot_repl_input_end:
2292 ParsedTemplateInfo &TemplateInfo,
2294 ForRangeInit *FRI) {
2300 LocalAttrs.takeAllFrom(Attrs);
2302 if (TemplateInfo.TemplateParams)
2303 D.setTemplateParameterLists(*TemplateInfo.TemplateParams);
2305 bool IsTemplateSpecOrInst =
2306 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
2307 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
2312 if (IsTemplateSpecOrInst)
2316 if (!
D.hasName() && !
D.mayOmitIdentifier()) {
2322 MaybeParseHLSLAnnotations(
D);
2324 if (Tok.
is(tok::kw_requires))
2325 ParseTrailingRequiresClause(
D);
2330 LateParsedAttrList LateParsedAttrs(
true);
2331 if (
D.isFunctionDeclarator()) {
2332 MaybeParseGNUAttributes(
D, &LateParsedAttrs);
2337 if (Tok.
is(tok::kw__Noreturn)) {
2339 const char *PrevSpec;
2345 MaybeParseGNUAttributes(
D, &LateParsedAttrs);
2346 Fixit &= Tok.
isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2348 Diag(
Loc, diag::err_c11_noreturn_misplaced)
2350 << (Fixit ?
FixItHint::CreateInsertion(
D.getBeginLoc(),
"_Noreturn ")
2355 if (Tok.
is(tok::equal) &&
NextToken().is(tok::code_completion)) {
2366 while (
auto Specifier = isCXX11VirtSpecifier()) {
2367 Diag(Tok, diag::err_virt_specifier_outside_class)
2375 if (!isDeclarationAfterDeclarator()) {
2381 if (isStartOfFunctionDefinition(
D)) {
2391 diag::err_function_declared_typedef)
2395 Decl *TheDecl =
nullptr;
2397 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
2401 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2402 TheDecl = ParseFunctionDefinition(
D, ParsedTemplateInfo(),
2407 Diag(
D.getIdentifierLoc(),
2408 diag::err_explicit_instantiation_with_definition)
2416 std::nullopt, LAngleLoc,
nullptr));
2418 TheDecl = ParseFunctionDefinition(
2420 ParsedTemplateInfo(&FakedParamLists,
2427 ParseFunctionDefinition(
D, TemplateInfo, &LateParsedAttrs);
2434 Tok.
is(tok::kw_namespace)) {
2444 Diag(Tok, diag::err_expected_fn_body);
2449 if (Tok.
is(tok::l_brace)) {
2450 Diag(Tok, diag::err_function_definition_not_allowed);
2458 if (ParseAsmAttributesAfterDeclarator(
D))
2467 if (FRI && (Tok.
is(tok::colon) || isTokIdentifier_in())) {
2468 bool IsForRangeLoop =
false;
2470 IsForRangeLoop =
true;
2480 LastRecord.InLifetimeExtendingContext =
true;
2485 if (Tok.
is(tok::l_brace))
2486 FRI->RangeExpr = ParseBraceInitializer();
2497 FRI->LifetimeExtendTemps = std::move(
2502 if (IsForRangeLoop) {
2506 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2507 VD->setObjCForDecl(
true);
2510 D.complete(ThisDecl);
2516 ParseDeclarationAfterDeclaratorAndAttributes(
D, TemplateInfo, FRI);
2517 if (LateParsedAttrs.size() > 0)
2518 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2519 D.complete(FirstDecl);
2521 DeclsInGroup.push_back(FirstDecl);
2529 if (Tok.
isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2533 Diag(CommaLoc, diag::err_expected_semi_declaration)
2543 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
2544 D.isFirstDeclarator()) {
2545 Diag(CommaLoc, diag::err_multiple_template_declarators)
2546 << TemplateInfo.Kind;
2551 D.setCommaLoc(CommaLoc);
2560 MaybeParseGNUAttributes(
D);
2564 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2569 MaybeParseHLSLAnnotations(
D);
2571 if (!
D.isInvalidType()) {
2576 if (Tok.
is(tok::kw_requires))
2577 ParseTrailingRequiresClause(
D);
2578 Decl *ThisDecl = ParseDeclarationAfterDeclarator(
D, TemplateInfo);
2579 D.complete(ThisDecl);
2581 DeclsInGroup.push_back(ThisDecl);
2588 if (ExpectSemi && ExpectAndConsumeSemi(
2590 ? diag::err_invalid_token_after_toplevel_declarator
2591 : diag::err_expected_semi_declaration)) {
2604bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &
D) {
2606 if (Tok.
is(tok::kw_asm)) {
2609 if (AsmLabel.isInvalid()) {
2614 D.setAsmLabel(AsmLabel.get());
2618 MaybeParseGNUAttributes(
D);
2644Decl *Parser::ParseDeclarationAfterDeclarator(
2645 Declarator &
D,
const ParsedTemplateInfo &TemplateInfo) {
2646 if (ParseAsmAttributesAfterDeclarator(
D))
2649 return ParseDeclarationAfterDeclaratorAndAttributes(
D, TemplateInfo);
2652Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2653 Declarator &
D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2655 struct InitializerScopeRAII {
2662 :
P(
P),
D(
D), ThisDecl(ThisDecl), Entered(
false) {
2663 if (ThisDecl &&
P.getLangOpts().CPlusPlus) {
2665 if (
D.getCXXScopeSpec().isSet()) {
2667 S =
P.getCurScope();
2670 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2675 ~InitializerScopeRAII() {
2676 if (ThisDecl &&
P.getLangOpts().CPlusPlus) {
2678 if (
D.getCXXScopeSpec().isSet())
2679 S =
P.getCurScope();
2682 P.Actions.ActOnCXXExitDeclInitializer(S, ThisDecl);
2691 InitKind TheInitKind;
2693 if (isTokenEqualOrEqualTypo())
2694 TheInitKind = InitKind::Equal;
2695 else if (Tok.
is(tok::l_paren))
2696 TheInitKind = InitKind::CXXDirect;
2698 (!CurParsedObjCImpl || !
D.isFunctionDeclarator()))
2699 TheInitKind = InitKind::CXXBraced;
2701 TheInitKind = InitKind::Uninitialized;
2702 if (TheInitKind != InitKind::Uninitialized)
2703 D.setHasInitializer();
2706 Decl *ThisDecl =
nullptr;
2707 Decl *OuterDecl =
nullptr;
2708 switch (TemplateInfo.Kind) {
2709 case ParsedTemplateInfo::NonTemplate:
2713 case ParsedTemplateInfo::Template:
2714 case ParsedTemplateInfo::ExplicitSpecialization: {
2716 *TemplateInfo.TemplateParams,
2718 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2721 ThisDecl = VT->getTemplatedDecl();
2726 case ParsedTemplateInfo::ExplicitInstantiation: {
2727 if (Tok.
is(tok::semi)) {
2729 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
D);
2734 ThisDecl = ThisRes.
get();
2742 Diag(Tok, diag::err_template_defn_explicit_instantiation)
2748 Diag(
D.getIdentifierLoc(),
2749 diag::err_explicit_instantiation_with_definition)
2757 std::nullopt, LAngleLoc,
nullptr));
2769 switch (TheInitKind) {
2771 case InitKind::Equal: {
2774 if (Tok.
is(tok::kw_delete)) {
2775 if (
D.isFunctionDeclarator())
2780 SkipDeletedFunctionBody();
2781 }
else if (Tok.
is(tok::kw_default)) {
2782 if (
D.isFunctionDeclarator())
2789 InitializerScopeRAII InitScope(*
this,
D, ThisDecl);
2791 if (Tok.
is(tok::code_completion)) {
2804 if (Tok.
is(tok::r_paren) && FRI &&
D.isFirstDeclarator()) {
2805 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2809 FRI->ColonLoc = EqualLoc;
2811 FRI->RangeExpr =
Init;
2814 if (
Init.isInvalid()) {
2816 StopTokens.push_back(tok::comma);
2819 StopTokens.push_back(tok::r_paren);
2828 case InitKind::CXXDirect: {
2835 InitializerScopeRAII InitScope(*
this,
D, ThisDecl);
2837 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2838 auto RunSignatureHelp = [&]() {
2841 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2844 CalledSignatureHelp =
true;
2845 return PreferredType;
2847 auto SetPreferredType = [&] {
2848 PreferredType.enterFunctionArgument(Tok.
getLocation(), RunSignatureHelp);
2851 llvm::function_ref<void()> ExpressionStarts;
2857 ExpressionStarts = SetPreferredType;
2860 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2865 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2868 CalledSignatureHelp =
true;
2877 T.getCloseLocation(),
2884 case InitKind::CXXBraced: {
2886 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2888 InitializerScopeRAII InitScope(*
this,
D, ThisDecl);
2890 PreferredType.enterVariableInit(Tok.
getLocation(), ThisDecl);
2893 if (
Init.isInvalid()) {
2899 case InitKind::Uninitialized: {
2906 return OuterDecl ? OuterDecl : ThisDecl;
2915void Parser::ParseSpecifierQualifierList(
2918 ParsedTemplateInfo TemplateInfo;
2922 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC,
nullptr,
2923 AllowImplicitTypename);
2928 Diag(Tok, diag::err_expected_type);
2931 Diag(Tok, diag::err_typename_requires_specqual);
2942 diag::err_typename_invalid_storageclass);
2986 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2987 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
3001 ParsedTemplateInfo &TemplateInfo,
3004 assert(Tok.
is(tok::identifier) &&
"should have identifier");
3026 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
3044 AnnotateScopeToken(*SS,
false);
3055 DSC == DeclSpecContext::DSC_template_type_arg)) {
3056 const char *PrevSpec;
3072 if (SS ==
nullptr) {
3073 const char *TagName =
nullptr, *FixitTagName =
nullptr;
3079 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
3081 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
3083 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
3085 TagName=
"__interface"; FixitTagName =
"__interface ";
3086 TagKind=tok::kw___interface;
break;
3088 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
3096 Diag(
Loc, diag::err_use_of_tag_name_without_tag)
3097 << TokenName << TagName <<
getLangOpts().CPlusPlus
3103 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
3104 << TokenName << TagName;
3108 if (TagKind == tok::kw_enum)
3109 ParseEnumSpecifier(
Loc, DS, TemplateInfo, AS,
3110 DeclSpecContext::DSC_normal);
3112 ParseClassSpecifier(TagKind,
Loc, DS, TemplateInfo, AS,
3114 DeclSpecContext::DSC_normal, Attrs);
3121 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
3122 DSC == DeclSpecContext::DSC_class)) {
3126 case tok::l_paren: {
3133 TentativeParsingAction PA(*
this);
3135 TPResult TPR = TryParseDeclarator(
false);
3138 if (TPR != TPResult::False) {
3146 if (DSC == DeclSpecContext::DSC_class ||
3147 (DSC == DeclSpecContext::DSC_top_level && SS)) {
3150 Diag(
Loc, diag::err_constructor_bad_name)
3171 AnnotateScopeToken(*SS,
false);
3193 const char *PrevSpec;
3214 if (IsTemplateName) {
3216 TemplateArgList Args;
3217 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3231Parser::DeclSpecContext
3235 return DeclSpecContext::DSC_class;
3237 return DeclSpecContext::DSC_top_level;
3239 return DeclSpecContext::DSC_template_param;
3241 return DeclSpecContext::DSC_template_arg;
3243 return DeclSpecContext::DSC_template_type_arg;
3246 return DeclSpecContext::DSC_trailing;
3249 return DeclSpecContext::DSC_alias_declaration;
3251 return DeclSpecContext::DSC_association;
3253 return DeclSpecContext::DSC_type_specifier;
3255 return DeclSpecContext::DSC_condition;
3257 return DeclSpecContext::DSC_conv_operator;
3259 return DeclSpecContext::DSC_new;
3274 return DeclSpecContext::DSC_normal;
3277 llvm_unreachable(
"Missing DeclaratorContext case");
3290 if (isTypeIdInParens()) {
3319 assert(Tok.
isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3320 "Not an alignment-specifier!");
3327 if (
T.expectAndConsume())
3334 ParseAlignArgument(PP.
getSpelling(KWTok),
T.getOpenLocation(),
3343 *EndLoc =
T.getCloseLocation();
3350 ArgExprs.push_back(ArgExpr.
get());
3351 Attrs.
addNew(KWName, KWLoc,
nullptr, KWLoc, ArgExprs.data(), 1, Kind,
3356void Parser::DistributeCLateParsedAttrs(
Decl *Dcl,
3357 LateParsedAttrList *LateAttrs) {
3362 for (
auto *LateAttr : *LateAttrs) {
3363 if (LateAttr->Decls.empty())
3364 LateAttr->addDecl(Dcl);
3377 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3382 if (Tok.
is(tok::r_paren)) {
3390 using ExpressionKind =
3394 ExpressionKind::EK_AttrArgument);
3404 ArgExprs.push_back(ArgExpr.
get());
3414 ScopeName, ScopeLoc, ArgExprs.data(), ArgExprs.size(), Form);
3417ExprResult Parser::ParseExtIntegerArgument() {
3418 assert(Tok.
isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3419 "Not an extended int type");
3423 if (
T.expectAndConsume())
3432 if(
T.consumeClose())
3446 DeclSpecContext DSContext,
3447 LateParsedAttrList *LateAttrs) {
3450 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3451 DSContext == DeclSpecContext::DSC_top_level);
3454 Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
3455 tok::annot_template_id) &&
3461 bool HasScope = Tok.
is(tok::annot_cxxscope);
3467 bool MightBeDeclarator =
true;
3468 if (Tok.
isOneOf(tok::kw_typename, tok::annot_typename)) {
3470 MightBeDeclarator =
false;
3471 }
else if (AfterScope.
is(tok::annot_template_id)) {
3477 MightBeDeclarator =
false;
3478 }
else if (AfterScope.
is(tok::identifier)) {
3479 const Token &Next = HasScope ? GetLookAheadToken(2) :
NextToken();
3483 if (Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3484 tok::annot_cxxscope, tok::coloncolon)) {
3486 MightBeDeclarator =
false;
3487 }
else if (HasScope) {
3498 switch (Classification.
getKind()) {
3504 llvm_unreachable(
"typo correction is not possible here");
3511 MightBeDeclarator =
false;
3527 if (MightBeDeclarator)
3532 diag::err_expected_after)
3543 ParsedTemplateInfo NotATemplate;
3544 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3575void Parser::ParseDeclarationSpecifiers(
3577 DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
3589 if (DSContext == DeclSpecContext::DSC_conv_operator) {
3592 DSContext = DeclSpecContext::DSC_type_specifier;
3595 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3596 DSContext == DeclSpecContext::DSC_top_level);
3597 bool AttrsLastTime =
false;
3603 bool isStorageClass =
false;
3604 const char *PrevSpec =
nullptr;
3605 unsigned DiagID = 0;
3626 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3640 bool IsTemplateSpecOrInst =
3641 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3642 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3651 ProhibitAttributes(attrs);
3655 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3656 !PA.isRegularKeywordAttribute())
3664 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3665 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3672 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3673 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3675 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3676 << PA << PA.isRegularKeywordAttribute();
3685 DS.
Finish(Actions, Policy);
3689 case tok::kw__Alignas:
3690 diagnoseUseOfC11Keyword(Tok);
3692 case tok::kw_alignas:
3698 if (Tok.
getKind() == tok::kw_alignas)
3699 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
3705 if (!isAllowedCXX11AttributeSpecifier())
3706 goto DoneWithDeclSpec;
3709 ProhibitAttributes(attrs);
3716 ParseCXX11Attributes(attrs);
3717 AttrsLastTime =
true;
3720 case tok::code_completion: {
3724 bool AllowNonIdentifiers
3730 bool AllowNestedNameSpecifiers
3731 = DSContext == DeclSpecContext::DSC_top_level ||
3736 getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3741 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
3742 CCC = DSContext == DeclSpecContext::DSC_class
3745 else if (DSContext == DeclSpecContext::DSC_class)
3749 else if (CurParsedObjCImpl)
3757 case tok::coloncolon:
3763 goto DoneWithDeclSpec;
3765 if (Tok.
is(tok::coloncolon))
3766 goto DoneWithDeclSpec;
3769 case tok::annot_cxxscope: {
3771 goto DoneWithDeclSpec;
3774 if (TemplateInfo.TemplateParams)
3784 ? takeTemplateIdAnnotation(Next)
3790 ConsumeAnnotationToken();
3804 if ((DSContext == DeclSpecContext::DSC_top_level ||
3805 DSContext == DeclSpecContext::DSC_class) &&
3808 isConstructorDeclarator(
false,
3815 goto DoneWithDeclSpec;
3819 ConsumeAnnotationToken();
3820 assert(Tok.
is(tok::annot_template_id) &&
3821 "ParseOptionalCXXScopeSpecifier not working");
3822 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3832 ConsumeAnnotationToken();
3836 if (Next.is(tok::annot_typename)) {
3838 ConsumeAnnotationToken();
3842 PrevSpec, DiagID,
T, Policy);
3846 ConsumeAnnotationToken();
3850 Next.is(tok::annot_template_id) &&
3854 ConsumeAnnotationToken();
3855 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3859 if (Next.isNot(tok::identifier))
3860 goto DoneWithDeclSpec;
3865 if ((DSContext == DeclSpecContext::DSC_top_level ||
3866 DSContext == DeclSpecContext::DSC_class) &&
3869 isConstructorDeclarator(
false,
3873 goto DoneWithDeclSpec;
3882 *Next.getIdentifierInfo(), Next.getLocation(),
getCurScope(), &SS,
3883 false,
false,
nullptr,
3886 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3888 if (IsTemplateSpecOrInst)
3896 if (TryAnnotateTypeConstraint())
3897 goto DoneWithDeclSpec;
3898 if (Tok.
isNot(tok::annot_cxxscope) ||
3902 ConsumeAnnotationToken();
3904 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3905 if (!Attrs.
empty()) {
3906 AttrsLastTime =
true;
3907 attrs.takeAllFrom(Attrs);
3911 goto DoneWithDeclSpec;
3915 ConsumeAnnotationToken();
3918 DiagID, TypeRep, Policy);
3928 case tok::annot_typename: {
3932 goto DoneWithDeclSpec;
3941 ConsumeAnnotationToken();
3946 case tok::kw___is_signed:
3957 TryKeywordIdentFallback(
true);
3960 goto DoneWithDeclSpec;
3963 case tok::kw___super:
3964 case tok::kw_decltype:
3965 case tok::identifier:
3971 goto DoneWithDeclSpec;
3977 if (!
getLangOpts().DeclSpecKeyword && Tok.
is(tok::identifier) &&
3979 Diag(
Loc, diag::err_ms_attributes_not_enabled);
3989 if (
T.consumeOpen()) {
3990 assert(
false &&
"Not a left paren?");
4009 if (IsTemplateSpecOrInst)
4013 if (IsTemplateSpecOrInst)
4016 goto DoneWithDeclSpec;
4019 if (!Tok.
is(tok::identifier))
4024 if (TryAltiVecToken(DS,
Loc, PrevSpec, DiagID,
isInvalid))
4030 goto DoneWithDeclSpec;
4032 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
4033 isObjCInstancetype()) {
4037 DiagID, TypeRep, Policy);
4050 isConstructorDeclarator(
true,
4053 goto DoneWithDeclSpec;
4057 false,
false,
nullptr,
false,
false,
4058 isClassTemplateDeductionContext(DSContext));
4063 if (TryAnnotateTypeConstraint())
4064 goto DoneWithDeclSpec;
4065 if (Tok.
isNot(tok::identifier))
4068 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
4069 if (!Attrs.
empty()) {
4070 AttrsLastTime =
true;
4071 attrs.takeAllFrom(Attrs);
4075 goto DoneWithDeclSpec;
4082 (DSContext == DeclSpecContext::DSC_class ||
4083 DSContext == DeclSpecContext::DSC_top_level) &&
4086 isConstructorDeclarator(
true,
4088 goto DoneWithDeclSpec;
4091 DiagID, TypeRep, Policy);
4103 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
4118 case tok::annot_template_id: {
4130 TemplateId =
nullptr;
4138 tok::kw_volatile, tok::kw_restrict, tok::amp,
4140 Diag(
Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
4144 TemplateId, Policy);
4148 goto DoneWithDeclSpec;
4151 TemplateId =
nullptr;
4153 ConsumeAnnotationToken();
4157 if (Tracker.consumeOpen()) {
4159 Diag(Tok, diag::err_expected) << tok::l_paren;
4163 Tracker.skipToEnd();
4164 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
4169 Tracker.consumeClose();
4177 DiagID, TemplateId, Policy);
4180 TemplateId, Policy);
4189 goto DoneWithDeclSpec;
4197 isConstructorDeclarator(
true,
4200 goto DoneWithDeclSpec;
4205 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
4210 case tok::kw___attribute:
4211 case tok::kw___declspec:
4212 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4216 case tok::kw___forceinline: {
4221 nullptr, 0, tok::kw___forceinline);
4225 case tok::kw___unaligned:
4230 case tok::kw___sptr:
4231 case tok::kw___uptr:
4232 case tok::kw___ptr64:
4233 case tok::kw___ptr32:
4235 case tok::kw___cdecl:
4236 case tok::kw___stdcall:
4237 case tok::kw___fastcall:
4238 case tok::kw___thiscall:
4239 case tok::kw___regcall:
4240 case tok::kw___vectorcall:
4244 case tok::kw___funcref:
4249 case tok::kw___pascal:
4254 case tok::kw___kernel:
4259 case tok::kw___noinline__:
4264 case tok::kw__Nonnull:
4265 case tok::kw__Nullable:
4266 case tok::kw__Nullable_result:
4267 case tok::kw__Null_unspecified:
4272 case tok::kw___kindof:
4274 nullptr, 0, tok::kw___kindof);
4279 case tok::kw_typedef:
4281 PrevSpec, DiagID, Policy);
4282 isStorageClass =
true;
4284 case tok::kw_extern:
4286 Diag(Tok, diag::ext_thread_before) <<
"extern";
4288 PrevSpec, DiagID, Policy);
4289 isStorageClass =
true;
4291 case tok::kw___private_extern__:
4293 Loc, PrevSpec, DiagID, Policy);
4294 isStorageClass =
true;
4296 case tok::kw_static:
4298 Diag(Tok, diag::ext_thread_before) <<
"static";
4300 PrevSpec, DiagID, Policy);
4301 isStorageClass =
true;
4305 if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
4307 PrevSpec, DiagID, Policy);
4309 Diag(Tok, diag::ext_auto_storage_class)
4316 PrevSpec, DiagID, Policy);
4317 isStorageClass =
true;
4319 case tok::kw___auto_type:
4320 Diag(Tok, diag::ext_auto_type);
4324 case tok::kw_register:
4326 PrevSpec, DiagID, Policy);
4327 isStorageClass =
true;
4329 case tok::kw_mutable:
4331 PrevSpec, DiagID, Policy);
4332 isStorageClass =
true;
4334 case tok::kw___thread:
4337 isStorageClass =
true;
4339 case tok::kw_thread_local:
4341 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4350 Loc, PrevSpec, DiagID);
4351 isStorageClass =
true;
4353 case tok::kw__Thread_local:
4354 diagnoseUseOfC11Keyword(Tok);
4356 Loc, PrevSpec, DiagID);
4357 isStorageClass =
true;
4361 case tok::kw_inline:
4364 case tok::kw_virtual:
4368 !
getActions().getOpenCLOptions().isAvailableOption(
4370 DiagID = diag::err_openclcxx_virtual_function;
4377 case tok::kw_explicit: {
4381 ConsumedEnd = ExplicitLoc;
4383 if (Tok.
is(tok::l_paren)) {
4386 ? diag::warn_cxx17_compat_explicit_bool
4387 : diag::ext_explicit_bool);
4391 Tracker.consumeOpen();
4398 if (ExplicitExpr.isUsable()) {
4400 Tracker.consumeClose();
4404 Tracker.skipToEnd();
4410 ExplicitSpec, CloseParenLoc);
4413 case tok::kw__Noreturn:
4414 diagnoseUseOfC11Keyword(Tok);
4419 case tok::kw_friend:
4420 if (DSContext == DeclSpecContext::DSC_class) {
4427 DiagID = diag::err_friend_invalid_in_context;
4433 case tok::kw___module_private__:
4438 case tok::kw_constexpr:
4440 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4444 case tok::kw_consteval:
4448 case tok::kw_constinit:
4464 PrevSpec, DiagID, Policy);
4466 case tok::kw___int64:
4468 PrevSpec, DiagID, Policy);
4470 case tok::kw_signed:
4474 case tok::kw_unsigned:
4478 case tok::kw__Complex:
4480 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4484 case tok::kw__Imaginary:
4486 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4502 case tok::kw__ExtInt:
4503 case tok::kw__BitInt: {
4504 DiagnoseBitIntUse(Tok);
4509 ConsumedEnd = PrevTokLocation;
4512 case tok::kw___int128:
4520 case tok::kw___bf16:
4528 case tok::kw_double:
4532 case tok::kw__Float16:
4536 case tok::kw__Accum:
4538 "This keyword is only used when fixed point types are enabled "
4539 "with `-ffixed-point`");
4543 case tok::kw__Fract:
4545 "This keyword is only used when fixed point types are enabled "
4546 "with `-ffixed-point`");
4552 "This keyword is only used when fixed point types are enabled "
4553 "with `-ffixed-point`");
4556 case tok::kw___float128:
4560 case tok::kw___ibm128:
4564 case tok::kw_wchar_t:
4568 case tok::kw_char8_t:
4572 case tok::kw_char16_t:
4576 case tok::kw_char32_t:
4582 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4586 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4588 if (Tok.
is(tok::kw_bool) &&
4592 DiagID = diag::err_bool_redeclaration;
4601 case tok::kw__Decimal32:
4605 case tok::kw__Decimal64:
4609 case tok::kw__Decimal128:
4613 case tok::kw___vector:
4616 case tok::kw___pixel:
4619 case tok::kw___bool:
4624 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4629 goto DoneWithDeclSpec;
4631 DiagID = diag::err_opencl_unknown_type_specifier;
4638#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4639#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4640#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4641 case tok::kw_##ImgType##_t: \
4642 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4643 goto DoneWithDeclSpec; \
4645#include "clang/Basic/OpenCLImageTypes.def"
4646 case tok::kw___unknown_anytype:
4648 PrevSpec, DiagID, Policy);
4653 case tok::kw_struct:
4654 case tok::kw___interface:
4655 case tok::kw_union: {
4663 ParseClassSpecifier(Kind,
Loc, DS, TemplateInfo, AS,
4664 EnteringContext, DSContext, Attributes);
4668 if (!Attributes.empty()) {
4669 AttrsLastTime =
true;
4670 attrs.takeAllFrom(Attributes);
4678 ParseEnumSpecifier(
Loc, DS, TemplateInfo, AS, DSContext);
4686 case tok::kw_volatile:
4690 case tok::kw_restrict:
4696 case tok::kw_typename:
4699 goto DoneWithDeclSpec;
4701 if (!Tok.
is(tok::kw_typename))
4706 case tok::kw_typeof:
4707 case tok::kw_typeof_unqual:
4708 ParseTypeofSpecifier(DS);
4711 case tok::annot_decltype:
4712 ParseDecltypeSpecifier(DS);
4715 case tok::annot_pack_indexing_type:
4716 ParsePackIndexingType(DS);
4719 case tok::annot_pragma_pack:
4723 case tok::annot_pragma_ms_pragma:
4724 HandlePragmaMSPragma();
4727 case tok::annot_pragma_ms_vtordisp:
4728 HandlePragmaMSVtorDisp();
4731 case tok::annot_pragma_ms_pointers_to_members:
4732 HandlePragmaMSPointersToMembers();
4735#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4736#include "clang/Basic/TransformTypeTraits.def"
4740 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4741 goto ParseIdentifier;
4744 case tok::kw__Atomic:
4749 diagnoseUseOfC11Keyword(Tok);
4751 ParseAtomicSpecifier(DS);
4759 case tok::kw___generic:
4764 if (!Actions.
getLangOpts().OpenCLGenericAddressSpace) {
4765 DiagID = diag::err_opencl_unknown_type_specifier;
4771 case tok::kw_private:
4775 goto DoneWithDeclSpec;
4777 case tok::kw___private:
4778 case tok::kw___global:
4779 case tok::kw___local:
4780 case tok::kw___constant:
4782 case tok::kw___read_only:
4783 case tok::kw___write_only:
4784 case tok::kw___read_write:
4788 case tok::kw_groupshared:
4801 goto DoneWithDeclSpec;
4806 if (
Type.isUsable()) {
4808 PrevSpec, DiagID,
Type.get(),
4810 Diag(StartLoc, DiagID) << PrevSpec;
4826 assert(PrevSpec &&
"Method did not return previous specifier!");
4829 if (DiagID == diag::ext_duplicate_declspec ||
4830 DiagID == diag::ext_warn_duplicate_declspec ||
4831 DiagID == diag::err_duplicate_declspec)
4835 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4839 Diag(
Loc, DiagID) << PrevSpec;
4842 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4846 AttrsLastTime =
false;
4858 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4861 for (
auto *I : RD->decls()) {
4862 auto *VD = dyn_cast<ValueDecl>(I);
4870 for (
const auto &DD : CAT->dependent_decls()) {
4871 if (!RD->containsDecl(DD.getDecl())) {
4872 P.Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4873 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4874 P.Diag(DD.getDecl()->getBeginLoc(),
4875 diag::note_flexible_array_counted_by_attr_field)
4903void Parser::ParseStructDeclaration(
4906 LateParsedAttrList *LateFieldAttrs) {
4908 if (Tok.
is(tok::kw___extension__)) {
4912 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4917 MaybeParseCXX11Attributes(Attrs);
4920 ParseSpecifierQualifierList(DS);
4924 if (Tok.
is(tok::semi)) {
4929 ProhibitAttributes(Attrs);
4933 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4939 bool FirstDeclarator =
true;
4943 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4946 if (!FirstDeclarator) {
4949 DiagnoseAndSkipCXX11Attributes();
4950 MaybeParseGNUAttributes(DeclaratorInfo.D);
4951 DiagnoseAndSkipCXX11Attributes();
4956 if (Tok.
isNot(tok::colon)) {
4959 ParseDeclarator(DeclaratorInfo.D);
4961 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.
getLocation());
4973 DeclaratorInfo.BitfieldSize = Res.
get();
4977 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
4980 Decl *
Field = FieldsCallback(DeclaratorInfo);
4982 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
4989 FirstDeclarator =
false;
4995void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs,
bool EnterScope,
4997 assert(LAs.parseSoon() &&
4998 "Attribute list should be marked for immediate parsing.");
4999 for (
auto *LA : LAs) {
5000 ParseLexedCAttribute(*LA,
EnterScope, OutAttrs);
5011void Parser::ParseLexedCAttribute(LateParsedAttribute &LA,
bool EnterScope,
5020 LA.Toks.push_back(AttrEnd);
5024 LA.Toks.push_back(Tok);
5025 PP.EnterTokenStream(LA.Toks,
true,
5036 assert(LA.Decls.size() <= 1 &&
5037 "late field attribute expects to have at most one declaration.");
5040 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
nullptr,
nullptr,
5043 for (
auto *
D : LA.Decls)
5048 while (Tok.
isNot(tok::eof))
5073 "parsing struct/union body");
5077 if (
T.consumeOpen())
5085 LateParsedAttrList LateFieldAttrs(
true,
5089 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
5090 Tok.
isNot(tok::eof)) {
5094 if (Tok.
is(tok::semi)) {
5095 ConsumeExtraSemi(InsideStruct,
TagType);
5100 if (Tok.
isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
5102 ParseStaticAssertDeclaration(DeclEnd);
5106 if (Tok.
is(tok::annot_pragma_pack)) {
5111 if (Tok.
is(tok::annot_pragma_align)) {
5112 HandlePragmaAlign();
5116 if (Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
5120 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
5124 if (Tok.
is(tok::annot_pragma_openacc)) {
5133 ConsumeAnnotationToken();
5137 if (!Tok.
is(tok::at)) {
5143 FD.D, FD.BitfieldSize);
5150 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
5154 Diag(Tok, diag::err_unexpected_at);
5159 ExpectAndConsume(tok::l_paren);
5160 if (!Tok.
is(tok::identifier)) {
5161 Diag(Tok, diag::err_expected) << tok::identifier;
5169 ExpectAndConsume(tok::r_paren);
5175 if (Tok.
is(tok::r_brace)) {
5176 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
5180 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
5191 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
5194 ParseLexedCAttributeList(LateFieldAttrs,
false);
5199 T.getOpenLocation(),
T.getCloseLocation(), attrs);
5235 const ParsedTemplateInfo &TemplateInfo,
5238 if (Tok.
is(tok::code_completion)) {
5248 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5251 bool IsScopedUsingClassTag =
false;
5256 : diag::ext_scoped_enum);
5257 IsScopedUsingClassTag = Tok.
is(tok::kw_class);
5262 ProhibitAttributes(attrs);
5265 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5274 bool shouldDelayDiagsInTag =
5275 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
5276 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
5280 AllowDefiningTypeSpec AllowEnumSpecifier =
5282 bool CanBeOpaqueEnumDeclaration =
5283 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5286 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5287 CanBeOpaqueEnumDeclaration);
5295 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5300 if (Spec.
isSet() && Tok.
isNot(tok::identifier)) {
5301 Diag(Tok, diag::err_expected) << tok::identifier;
5303 if (Tok.
isNot(tok::l_brace)) {
5315 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::l_brace) &&
5316 Tok.
isNot(tok::colon)) {
5317 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5328 if (Tok.
is(tok::identifier)) {
5333 if (!Name && ScopedEnumKWLoc.
isValid()) {
5336 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5338 IsScopedUsingClassTag =
false;
5343 if (shouldDelayDiagsInTag)
5344 diagsFromTag.done();
5349 bool CanBeBitfield =
5353 if (Tok.
is(tok::colon)) {
5378 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5383 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5394 DeclSpecContext::DSC_type_specifier);
5399 BaseRange =
SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5403 Diag(ColonLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type)
5406 Diag(ColonLoc, diag::ext_cxx11_enum_fixed_underlying_type)
5409 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5412 Diag(ColonLoc, diag::ext_clang_c_enum_fixed_underlying_type)
5429 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5431 else if (Tok.
is(tok::l_brace)) {
5440 IsScopedUsingClassTag =
false;
5446 }
else if (!isTypeSpecifier(DSC) &&
5447 (Tok.
is(tok::semi) ||
5449 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5454 if (Tok.
isNot(tok::semi)) {
5456 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5464 bool IsElaboratedTypeSpecifier =
5470 diagsFromTag.redelay();
5474 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
5478 Diag(Tok, diag::err_enum_template);
5483 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
5486 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5490 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5492 TemplateInfo.TemplateParams->size());
5497 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5513 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5515 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5516 diag::err_keyword_not_allowed,
5519 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5520 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5521 else if (ScopedEnumKWLoc.
isValid())
5522 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5526 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5536 bool IsDependent =
false;
5537 const char *PrevSpec =
nullptr;
5542 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5543 IsScopedUsingClassTag,
5544 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5545 DSC == DeclSpecContext::DSC_template_param ||
5546 DSC == DeclSpecContext::DSC_template_type_arg,
5547 OffsetOfState, &SkipBody).
get();
5557 NameLoc.
isValid() ? NameLoc : StartLoc,
5558 PrevSpec, DiagID,
TagDecl, Owned,
5560 Diag(StartLoc, DiagID) << PrevSpec;
5569 Diag(Tok, diag::err_expected_type_name_after_typename);
5575 if (
Type.isInvalid()) {
5581 NameLoc.
isValid() ? NameLoc : StartLoc,
5582 PrevSpec, DiagID,
Type.get(),
5584 Diag(StartLoc, DiagID) << PrevSpec;
5603 ParseEnumBody(StartLoc,
D);
5612 NameLoc.
isValid() ? NameLoc : StartLoc,
5613 PrevSpec, DiagID,
TagDecl, Owned,
5615 Diag(StartLoc, DiagID) << PrevSpec;
5638 Diag(Tok, diag::err_empty_enum);
5643 Decl *LastEnumConstDecl =
nullptr;
5646 while (Tok.
isNot(tok::r_brace)) {
5649 if (Tok.
isNot(tok::identifier)) {
5661 MaybeParseGNUAttributes(attrs);
5662 if (isAllowedCXX11AttributeSpecifier()) {
5665 ? diag::warn_cxx14_compat_ns_enum_attribute
5666 : diag::ext_ns_enum_attribute)
5668 ParseCXX11Attributes(attrs);
5673 EnumAvailabilityDiags.emplace_back(*
this);
5686 EqualLoc, AssignedVal.
get());
5687 EnumAvailabilityDiags.back().done();
5689 EnumConstantDecls.push_back(EnumConstDecl);
5690 LastEnumConstDecl = EnumConstDecl;
5692 if (Tok.
is(tok::identifier)) {
5695 Diag(
Loc, diag::err_enumerator_list_missing_comma)
5718 if (Tok.
is(tok::r_brace) && CommaLoc.
isValid()) {
5721 diag::ext_enumerator_list_comma_cxx :
5722 diag::ext_enumerator_list_comma_c)
5725 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5736 MaybeParseGNUAttributes(attrs);
5742 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5743 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5745 EnumAvailabilityDiags[i].redelay();
5746 PD.complete(EnumConstantDecls[i]);
5755 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5756 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5768bool Parser::isKnownToBeTypeSpecifier(
const Token &Tok)
const {
5770 default:
return false;
5774 case tok::kw___int64:
5775 case tok::kw___int128:
5776 case tok::kw_signed:
5777 case tok::kw_unsigned:
5778 case tok::kw__Complex:
5779 case tok::kw__Imaginary:
5782 case tok::kw_wchar_t:
5783 case tok::kw_char8_t:
5784 case tok::kw_char16_t:
5785 case tok::kw_char32_t:
5787 case tok::kw__ExtInt:
5788 case tok::kw__BitInt:
5789 case tok::kw___bf16:
5792 case tok::kw_double:
5793 case tok::kw__Accum:
5794 case tok::kw__Fract:
5795 case tok::kw__Float16:
5796 case tok::kw___float128:
5797 case tok::kw___ibm128:
5800 case tok::kw__Decimal32:
5801 case tok::kw__Decimal64:
5802 case tok::kw__Decimal128:
5803 case tok::kw___vector:
5804#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5805#include "clang/Basic/OpenCLImageTypes.def"
5809 case tok::kw_struct:
5810 case tok::kw___interface:
5816 case tok::annot_typename:
5823bool Parser::isTypeSpecifierQualifier() {
5825 default:
return false;
5827 case tok::identifier:
5828 if (TryAltiVecVectorToken())
5831 case tok::kw_typename:
5836 if (Tok.
is(tok::identifier))
5838 return isTypeSpecifierQualifier();
5840 case tok::coloncolon:
5847 return isTypeSpecifierQualifier();
5850 case tok::kw___attribute:
5852 case tok::kw_typeof:
5853 case tok::kw_typeof_unqual:
5858 case tok::kw___int64:
5859 case tok::kw___int128:
5860 case tok::kw_signed:
5861 case tok::kw_unsigned:
5862 case tok::kw__Complex:
5863 case tok::kw__Imaginary:
5866 case tok::kw_wchar_t:
5867 case tok::kw_char8_t:
5868 case tok::kw_char16_t:
5869 case tok::kw_char32_t:
5871 case tok::kw__ExtInt:
5872 case tok::kw__BitInt:
5874 case tok::kw___bf16:
5876 case tok::kw_double:
5877 case tok::kw__Accum:
5878 case tok::kw__Fract:
5879 case tok::kw__Float16:
5880 case tok::kw___float128:
5881 case tok::kw___ibm128:
5884 case tok::kw__Decimal32:
5885 case tok::kw__Decimal64:
5886 case tok::kw__Decimal128:
5887 case tok::kw___vector:
5888#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5889#include "clang/Basic/OpenCLImageTypes.def"
5893 case tok::kw_struct:
5894 case tok::kw___interface:
5901 case tok::kw_volatile:
5902 case tok::kw_restrict:
5906 case tok::kw___unknown_anytype:
5909 case tok::annot_typename:
5916 case tok::kw___cdecl:
5917 case tok::kw___stdcall:
5918 case tok::kw___fastcall:
5919 case tok::kw___thiscall:
5920 case tok::kw___regcall:
5921 case tok::kw___vectorcall:
5923 case tok::kw___ptr64:
5924 case tok::kw___ptr32:
5925 case tok::kw___pascal:
5926 case tok::kw___unaligned:
5928 case tok::kw__Nonnull:
5929 case tok::kw__Nullable:
5930 case tok::kw__Nullable_result:
5931 case tok::kw__Null_unspecified:
5933 case tok::kw___kindof:
5935 case tok::kw___private:
5936 case tok::kw___local:
5937 case tok::kw___global:
5938 case tok::kw___constant:
5939 case tok::kw___generic:
5940 case tok::kw___read_only:
5941 case tok::kw___read_write:
5942 case tok::kw___write_only:
5943 case tok::kw___funcref:
5946 case tok::kw_private:
5950 case tok::kw__Atomic:
5954 case tok::kw_groupshared:
5967 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5971 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5977 if (Tok.
is(tok::annot_repl_input_end) &&
5979 ConsumeAnnotationToken();
5984 DeclsInGroup.push_back(TLSD);
5987 for (
Stmt *S : Stmts) {
5992 DeclsInGroup.push_back(
D);
6005bool Parser::isDeclarationSpecifier(
6007 bool DisambiguatingWithExpression) {
6009 default:
return false;
6016 case tok::identifier:
6020 if (TryAltiVecVectorToken())
6023 case tok::kw_decltype:
6024 case tok::kw_typename:
6029 if (TryAnnotateTypeConstraint())
6031 if (Tok.
is(tok::identifier))
6039 if (DisambiguatingWithExpression &&
6040 isStartOfObjCClassMessageMissingOpenBracket())
6043 return isDeclarationSpecifier(AllowImplicitTypename);
6045 case tok::coloncolon:
6059 case tok::kw_typedef:
6060 case tok::kw_extern:
6061 case tok::kw___private_extern__:
6062 case tok::kw_static:
6064 case tok::kw___auto_type:
6065 case tok::kw_register:
6066 case tok::kw___thread:
6067 case tok::kw_thread_local:
6068 case tok::kw__Thread_local:
6071 case tok::kw___module_private__:
6074 case tok::kw___unknown_anytype:
6079 case tok::kw___int64:
6080 case tok::kw___int128:
6081 case tok::kw_signed:
6082 case tok::kw_unsigned:
6083 case tok::kw__Complex:
6084 case tok::kw__Imaginary:
6087 case tok::kw_wchar_t:
6088 case tok::kw_char8_t:
6089 case tok::kw_char16_t:
6090 case tok::kw_char32_t:
6093 case tok::kw__ExtInt:
6094 case tok::kw__BitInt:
6096 case tok::kw___bf16:
6098 case tok::kw_double:
6099 case tok::kw__Accum:
6100 case tok::kw__Fract:
6101 case tok::kw__Float16:
6102 case tok::kw___float128:
6103 case tok::kw___ibm128:
6106 case tok::kw__Decimal32:
6107 case tok::kw__Decimal64:
6108 case tok::kw__Decimal128:
6109 case tok::kw___vector:
6113 case tok::kw_struct:
6115 case tok::kw___interface:
6121 case tok::kw_volatile:
6122 case tok::kw_restrict:
6126 case tok::kw_inline:
6127 case tok::kw_virtual:
6128 case tok::kw_explicit:
6129 case tok::kw__Noreturn:
6132 case tok::kw__Alignas:
6135 case tok::kw_friend:
6138 case tok::kw_static_assert:
6139 case tok::kw__Static_assert:
6142 case tok::kw_typeof:
6143 case tok::kw_typeof_unqual:
6146 case tok::kw___attribute:
6149 case tok::annot_decltype:
6150 case tok::annot_pack_indexing_type:
6151 case tok::kw_constexpr:
6154 case tok::kw_consteval:
6155 case tok::kw_constinit:
6158 case tok::kw__Atomic:
6161 case tok::kw_alignas:
6171 case tok::annot_typename:
6172 return !DisambiguatingWithExpression ||
6173 !isStartOfObjCClassMessageMissingOpenBracket();
6176 case tok::annot_template_id: {
6182 return isTypeConstraintAnnotation() &&
6186 case tok::annot_cxxscope: {
6195 if (
NextToken().is(tok::identifier) && TryAnnotateTypeConstraint())
6197 return isTypeConstraintAnnotation() &&
6198 GetLookAheadToken(2).isOneOf(tok::kw_auto, tok::kw_decltype);
6201 case tok::kw___declspec:
6202 case tok::kw___cdecl:
6203 case tok::kw___stdcall:
6204 case tok::kw___fastcall:
6205 case tok::kw___thiscall:
6206 case tok::kw___regcall:
6207 case tok::kw___vectorcall:
6209 case tok::kw___sptr:
6210 case tok::kw___uptr:
6211 case tok::kw___ptr64:
6212 case tok::kw___ptr32:
6213 case tok::kw___forceinline:
6214 case tok::kw___pascal:
6215 case tok::kw___unaligned:
6217 case tok::kw__Nonnull:
6218 case tok::kw__Nullable:
6219 case tok::kw__Nullable_result:
6220 case tok::kw__Null_unspecified:
6222 case tok::kw___kindof:
6224 case tok::kw___private:
6225 case tok::kw___local:
6226 case tok::kw___global:
6227 case tok::kw___constant:
6228 case tok::kw___generic:
6229 case tok::kw___read_only:
6230 case tok::kw___read_write:
6231 case tok::kw___write_only:
6232#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
6233#include "clang/Basic/OpenCLImageTypes.def"
6235 case tok::kw___funcref:
6236 case tok::kw_groupshared:
6239 case tok::kw_private:
6244bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
6246 const ParsedTemplateInfo *TemplateInfo) {
6247 RevertingTentativeParsingAction TPA(*
this);
6250 if (TemplateInfo && TemplateInfo->TemplateParams)
6253 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6260 if (Tok.
is(tok::identifier)) {
6264 }
else if (Tok.
is(tok::annot_template_id)) {
6265 ConsumeAnnotationToken();
6272 SkipCXX11Attributes();
6275 if (Tok.
isNot(tok::l_paren)) {
6282 if (Tok.
is(tok::r_paren) ||
6283 (Tok.
is(tok::ellipsis) &&
NextToken().is(tok::r_paren))) {
6290 isCXX11AttributeSpecifier(
false,
6296 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6298 DeclScopeObj.EnterDeclaratorScope();
6302 MaybeParseMicrosoftAttributes(Attrs);
6311 bool IsConstructor =
false;
6317 if (Tok.
is(tok::kw_this)) {
6319 return isDeclarationSpecifier(ITC);
6322 if (isDeclarationSpecifier(ITC))
6323 IsConstructor =
true;
6324 else if (Tok.
is(tok::identifier) ||
6325 (Tok.
is(tok::annot_cxxscope) &&
NextToken().is(tok::identifier))) {
6330 if (Tok.
is(tok::annot_cxxscope))
6331 ConsumeAnnotationToken();
6343 case tok::coloncolon:
6356 SkipCXX11Attributes();
6358 if (DeductionGuide) {
6360 IsConstructor = Tok.
is(tok::arrow);
6363 if (Tok.
is(tok::colon) || Tok.
is(tok::kw_try)) {
6367 IsConstructor =
true;
6369 if (Tok.
is(tok::semi) || Tok.
is(tok::l_brace)) {
6382 IsConstructor = IsUnqualified;
6387 IsConstructor =
true;
6391 return IsConstructor;
6406void Parser::ParseTypeQualifierListOpt(
6407 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicAllowed,
6408 bool IdentifierRequired,
6410 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6411 isAllowedCXX11AttributeSpecifier()) {
6413 ParseCXX11Attributes(Attrs);
6421 const char *PrevSpec =
nullptr;
6422 unsigned DiagID = 0;
6426 case tok::code_completion:
6429 (*CodeCompletionHandler)();
6438 case tok::kw_volatile:
6442 case tok::kw_restrict:
6446 case tok::kw__Atomic:
6448 goto DoneWithTypeQuals;
6449 diagnoseUseOfC11Keyword(Tok);
6455 case tok::kw_private:
6457 goto DoneWithTypeQuals;
6459 case tok::kw___private:
6460 case tok::kw___global:
6461 case tok::kw___local:
6462 case tok::kw___constant:
6463 case tok::kw___generic:
6464 case tok::kw___read_only:
6465 case tok::kw___write_only:
6466 case tok::kw___read_write:
6470 case tok::kw_groupshared:
6478 case tok::kw___unaligned:
6482 case tok::kw___uptr:
6487 if (TryKeywordIdentFallback(
false))
6491 case tok::kw___sptr:
6493 case tok::kw___ptr64:
6494 case tok::kw___ptr32:
6495 case tok::kw___cdecl:
6496 case tok::kw___stdcall:
6497 case tok::kw___fastcall:
6498 case tok::kw___thiscall:
6499 case tok::kw___regcall:
6500 case tok::kw___vectorcall:
6501 if (AttrReqs & AR_DeclspecAttributesParsed) {
6505 goto DoneWithTypeQuals;
6507 case tok::kw___funcref:
6510 goto DoneWithTypeQuals;
6512 case tok::kw___pascal:
6513 if (AttrReqs & AR_VendorAttributesParsed) {
6517 goto DoneWithTypeQuals;
6520 case tok::kw__Nonnull:
6521 case tok::kw__Nullable:
6522 case tok::kw__Nullable_result:
6523 case tok::kw__Null_unspecified:
6528 case tok::kw___kindof:
6530 nullptr, 0, tok::kw___kindof);
6534 case tok::kw___attribute:
6535 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6537 Diag(Tok, diag::err_attributes_not_allowed);
6541 if (AttrReqs & AR_GNUAttributesParsed ||
6542 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6560 assert(PrevSpec &&
"Method did not return previous specifier!");
6561 Diag(Tok, DiagID) << PrevSpec;
6572 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6578 if (Kind == tok::star || Kind == tok::caret)
6582 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6583 Lang.getOpenCLCompatibleVersion() >= 200)
6586 if (!Lang.CPlusPlus)
6589 if (Kind == tok::amp)
6597 if (Kind == tok::ampamp)
6606 const unsigned NumTypes =
D.getNumTypeObjects();
6608 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6640void Parser::ParseDeclaratorInternal(
Declarator &
D,
6641 DirectDeclParseFunction DirectDeclParser) {
6649 (Tok.
is(tok::coloncolon) || Tok.
is(tok::kw_decltype) ||
6650 (Tok.
is(tok::identifier) &&
6652 Tok.
is(tok::annot_cxxscope))) {
6657 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6658 false, EnteringContext);
6661 if (Tok.
isNot(tok::star)) {
6663 if (
D.mayHaveIdentifier())
6664 D.getCXXScopeSpec() = SS;
6666 AnnotateScopeToken(SS,
true);
6668 if (DirectDeclParser)
6669 (this->*DirectDeclParser)(
D);
6674 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6675 CompoundToken::MemberPtr);
6679 D.SetRangeEnd(StarLoc);
6681 ParseTypeQualifierListOpt(DS);
6682 D.ExtendWithDeclSpec(DS);
6686 ParseDeclaratorInternal(D, DirectDeclParser);
6703 ParseTypeQualifierListOpt(DS);
6712 if (DirectDeclParser)
6713 (this->*DirectDeclParser)(
D);
6722 if (Kind == tok::star || Kind == tok::caret) {
6728 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6730 ? AR_GNUAttributesParsed
6731 : AR_GNUAttributesParsedAndRejected);
6732 ParseTypeQualifierListOpt(DS, Reqs,
true, !
D.mayOmitIdentifier());
6733 D.ExtendWithDeclSpec(DS);
6737 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6738 if (Kind == tok::star)
6756 if (Kind == tok::ampamp)
6758 diag::warn_cxx98_compat_rvalue_reference :
6759 diag::ext_rvalue_reference);
6762 ParseTypeQualifierListOpt(DS);
6763 D.ExtendWithDeclSpec(DS);
6771 diag::err_invalid_reference_qualifier_application) <<
"const";
6774 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6778 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6783 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6785 if (
D.getNumTypeObjects() > 0) {
6790 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6793 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6815 if (
D.getName().StartLocation.isInvalid() &&
6816 D.getName().EndLocation.isValid())
6817 return D.getName().EndLocation;
6868void Parser::ParseDirectDeclarator(
Declarator &
D) {
6869 DeclaratorScopeObj DeclScopeObj(*
this,
D.getCXXScopeSpec());
6873 if (Tok.
is(tok::l_square) && !
D.mayOmitIdentifier() &&
6874 D.getCXXScopeSpec().isEmpty())
6875 return ParseDecompositionDeclarator(
D);
6886 if (
D.getCXXScopeSpec().isEmpty()) {
6889 ParseOptionalCXXScopeSpecifier(
6890 D.getCXXScopeSpec(),
nullptr,
6891 false, EnteringContext);
6905 if (
D.getCXXScopeSpec().isValid()) {
6907 D.getCXXScopeSpec()))
6910 DeclScopeObj.EnterDeclaratorScope();
6915 D.setInvalidType(
true);
6917 goto PastIdentifier;
6928 if (Tok.
is(tok::ellipsis) &&
D.getCXXScopeSpec().isEmpty() &&
6932 NextToken().is(tok::r_paren) && !
D.hasGroupingParens() &&
6934 D.getDeclSpec().getTypeSpecType() !=
TST_auto)) {
6941 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc,
D);
6944 D.setEllipsisLoc(EllipsisLoc);
6951 if (Tok.
isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6955 bool AllowConstructorName;
6956 bool AllowDeductionGuide;
6957 if (
D.getDeclSpec().hasTypeSpecifier()) {
6958 AllowConstructorName =
false;
6959 AllowDeductionGuide =
false;
6960 }
else if (
D.getCXXScopeSpec().isSet()) {
6963 AllowDeductionGuide =
false;
6970 bool HadScope =
D.getCXXScopeSpec().isValid();
6976 true, AllowConstructorName,
6977 AllowDeductionGuide, &TemplateKWLoc,
6981 D.getCXXScopeSpec().isInvalid()) {
6983 D.setInvalidType(
true);
6987 if (!HadScope &&
D.getCXXScopeSpec().isValid() &&
6989 D.getCXXScopeSpec()))
6990 DeclScopeObj.EnterDeclaratorScope();
6997 goto PastIdentifier;
7000 if (
D.getCXXScopeSpec().isNotEmpty()) {
7003 diag::err_expected_unqualified_id)
7006 goto PastIdentifier;
7008 }
else if (Tok.
is(tok::identifier) &&
D.mayHaveIdentifier()) {
7010 "There's a C++-specific check for tok::identifier above");
7015 goto PastIdentifier;
7016 }
else if (Tok.
is(tok::identifier) && !
D.mayHaveIdentifier()) {
7020 bool DiagnoseIdentifier =
false;
7021 if (
D.hasGroupingParens())
7024 DiagnoseIdentifier =
true;
7027 DiagnoseIdentifier =
7035 !isCXX11VirtSpecifier(Tok))
7037 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
7038 if (DiagnoseIdentifier) {
7043 goto PastIdentifier;
7047 if (Tok.
is(tok::l_paren)) {
7051 if (
D.mayOmitIdentifier() &&
D.mayBeFollowedByCXXDirectInit()) {
7052 RevertingTentativeParsingAction PA(*
this);
7053 if (TryParseDeclarator(
true,
D.mayHaveIdentifier(),
true,
7054 D.getDeclSpec().getTypeSpecType() ==
TST_auto) ==
7057 goto PastIdentifier;
7064 ParseParenDeclarator(
D);
7069 if (
D.getCXXScopeSpec().isSet()) {
7072 if (!
D.isInvalidType() &&
7074 D.getCXXScopeSpec()))
7077 DeclScopeObj.EnterDeclaratorScope();
7079 }
else if (
D.mayOmitIdentifier()) {
7086 if (
D.hasEllipsis() &&
D.hasGroupingParens())
7088 diag::ext_abstract_pack_declarator_parens);
7090 if (Tok.
getKind() == tok::annot_pragma_parser_crash)
7092 if (Tok.
is(tok::l_square))
7093 return ParseMisplacedBracketDeclarator(
D);
7101 diag::err_expected_member_name_or_semi_objcxx_keyword)
7108 goto PastIdentifier;
7111 diag::err_expected_member_name_or_semi)
7115 if (Tok.
getKind() == tok::TokenKind::kw_while) {
7116 Diag(Tok, diag::err_while_loop_outside_of_a_function);
7118 if (Tok.
isOneOf(tok::period, tok::arrow))
7119 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.
is(tok::arrow);
7127 diag::err_expected_unqualified_id)
7132 diag::err_expected_either)
7133 << tok::identifier << tok::l_paren;
7137 D.setInvalidType(
true);
7141 assert(
D.isPastIdentifier() &&
7142 "Haven't past the location of the identifier yet?");
7145 if (
D.hasName() && !
D.getNumTypeObjects())
7146 MaybeParseCXX11Attributes(
D);
7149 if (Tok.
is(tok::l_paren)) {
7150 bool IsFunctionDeclaration =
D.isFunctionDeclaratorAFunctionDeclaration();
7153 ParseScope PrototypeScope(
this,
7155 (IsFunctionDeclaration
7161 bool IsAmbiguous =
false;
7172 if (
D.getCXXScopeSpec().isSet())
7173 AllowImplicitTypename =
7181 TentativelyDeclaredIdentifiers.push_back(
D.getIdentifier());
7182 bool IsFunctionDecl =
7183 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
7184 TentativelyDeclaredIdentifiers.pop_back();
7185 if (!IsFunctionDecl)
7191 if (IsFunctionDeclaration)
7193 TemplateParameterDepth);
7194 ParseFunctionDeclarator(
D, attrs,
T, IsAmbiguous);
7195 if (IsFunctionDeclaration)
7197 PrototypeScope.Exit();
7198 }
else if (Tok.
is(tok::l_square)) {
7199 ParseBracketDeclarator(
D);
7207 if (!
T.consumeOpen())
7210 }
else if (Tok.
is(tok::kw_requires) &&
D.hasGroupingParens()) {
7218 Diag(Tok, diag::err_requires_clause_inside_parens);
7222 if (TrailingRequiresClause.
isUsable() &&
D.isFunctionDeclarator() &&
7223 !
D.hasTrailingRequiresClause())
7225 D.setTrailingRequiresClause(TrailingRequiresClause.
get());
7232void Parser::ParseDecompositionDeclarator(
Declarator &
D) {
7233 assert(Tok.
is(tok::l_square));
7235 TentativeParsingAction PA(*
this);
7239 if (isCXX11AttributeSpecifier())
7240 DiagnoseAndSkipCXX11Attributes();
7244 if (!(Tok.
is(tok::identifier) &&
7247 !(Tok.
is(tok::r_square) &&
7250 return ParseMisplacedBracketDeclarator(
D);
7254 while (Tok.
isNot(tok::r_square)) {
7256 if (Tok.
is(tok::comma))
7259 if (Tok.
is(tok::identifier)) {
7261 Diag(EndLoc, diag::err_expected)
7264 Diag(Tok, diag::err_expected_comma_or_rsquare);
7267 SkipUntil(tok::r_square, tok::comma, tok::identifier,
7269 if (Tok.
is(tok::comma))
7271 else if (Tok.
isNot(tok::identifier))
7276 if (isCXX11AttributeSpecifier())
7277 DiagnoseAndSkipCXX11Attributes();
7279 if (Tok.
isNot(tok::identifier)) {
7280 Diag(Tok, diag::err_expected) << tok::identifier;
7289 if (isCXX11AttributeSpecifier()) {
7291 ? diag::warn_cxx23_compat_decl_attrs_on_binding
7292 : diag::ext_decl_attrs_on_binding);
7293 MaybeParseCXX11Attributes(Attrs);
7299 if (Tok.
isNot(tok::r_square))
7313 return D.setDecompositionBindings(
T.getOpenLocation(),
Bindings,
7314 T.getCloseLocation());
7334 assert(!
D.isPastIdentifier() &&
"Should be called before passing identifier");
7347 bool RequiresArg =
false;
7348 if (Tok.
is(tok::kw___attribute)) {
7349 ParseGNUAttributes(attrs);
7357 ParseMicrosoftTypeAttributes(attrs);
7360 if (Tok.
is(tok::kw___pascal))
7361 ParseBorlandTypeAttributes(attrs);
7369 if (!
D.mayOmitIdentifier()) {
7373 }
else if (Tok.
is(tok::r_paren) ||
7376 isDeclarationSpecifier(
7378 isCXX11AttributeSpecifier()) {
7394 bool hadGroupingParens =
D.hasGroupingParens();
7395 D.setGroupingParens(
true);
7396 ParseDeclaratorInternal(
D, &Parser::ParseDirectDeclarator);
7401 std::move(attrs),
T.getCloseLocation());
7403 D.setGroupingParens(hadGroupingParens);
7407 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc,
D);
7420 ParseScope PrototypeScope(
this,
7422 (
D.isFunctionDeclaratorAFunctionDeclaration()
7424 ParseFunctionDeclarator(
D, attrs,
T,
false, RequiresArg);
7425 PrototypeScope.Exit();
7428void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7430 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7438 bool IsCXX11MemberFunction =
7442 ? !
D.getDeclSpec().isFriendSpecified()
7444 D.getCXXScopeSpec().isValid() &&
7446 if (!IsCXX11MemberFunction)
7466 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.
CurContext), Q,
7467 IsCXX11MemberFunction);
7490void Parser::ParseFunctionDeclarator(
Declarator &
D,
7495 assert(
getCurScope()->isFunctionPrototypeScope() &&
7496 "Should call from a Function scope");
7498 assert(
D.isPastIdentifier() &&
"Should not call before identifier!");
7502 bool HasProto =
false;
7509 bool RefQualifierIsLValueRef =
true;
7527 StartLoc = LParenLoc;
7529 if (isFunctionDeclaratorIdentifierList()) {
7531 Diag(Tok, diag::err_argument_required_after_attribute);
7533 ParseFunctionDeclaratorIdentifierList(
D, ParamInfo);
7537 LocalEndLoc = RParenLoc;
7542 MaybeParseCXX11Attributes(FnAttrs);
7543 ProhibitAttributes(FnAttrs);
7545 if (Tok.
isNot(tok::r_paren))
7546 ParseParameterDeclarationClause(
D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7547 else if (RequiresArg)
7548 Diag(Tok, diag::err_argument_required_after_attribute);
7559 LocalEndLoc = RParenLoc;
7568 ParseTypeQualifierListOpt(
7569 DS, AR_NoAttributesParsed,
7571 false, llvm::function_ref<
void()>([&]() {
7579 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7580 EndLoc = RefQualifierLoc;
7582 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7583 InitCXXThisScopeForDeclaratorIfRelevant(
D, DS, ThisScope);
7599 D.isFunctionDeclaratorAFunctionDeclaration();
7601 GetLookAheadToken(0).is(tok::kw_noexcept) &&
7602 GetLookAheadToken(1).is(tok::l_paren) &&
7603 GetLookAheadToken(2).is(tok::kw_noexcept) &&
7604 GetLookAheadToken(3).is(tok::l_paren) &&
7605 GetLookAheadToken(4).is(tok::identifier) &&
7606 GetLookAheadToken(4).getIdentifierInfo()->isStr(
"swap")) {
7617 ESpecType = tryParseExceptionSpecification(Delayed,
7620 DynamicExceptionRanges,
7622 ExceptionSpecTokens);
7624 EndLoc = ESpecRange.
getEnd();
7628 MaybeParseCXX11Attributes(FnAttrs);
7631 LocalEndLoc = EndLoc;
7633 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7634 if (
D.getDeclSpec().getTypeSpecType() ==
TST_auto)
7635 StartLoc =
D.getDeclSpec().getTypeSpecTypeLoc();
7638 TrailingReturnType =
7639 ParseTrailingReturnType(
Range,
D.mayBeFollowedByCXXDirectInit());
7644 MaybeParseCXX11Attributes(FnAttrs);
7656 if (!ND || isa<ParmVarDecl>(ND))
7658 DeclsInPrototype.push_back(ND);
7665 llvm::sort(DeclsInPrototype, [](
Decl *D1,
Decl *D2) {
7673 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7674 ParamInfo.size(), EllipsisLoc, RParenLoc,
7675 RefQualifierIsLValueRef, RefQualifierLoc,
7677 ESpecType, ESpecRange, DynamicExceptions.data(),
7678 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7679 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7680 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7681 LocalEndLoc,
D, TrailingReturnType, TrailingReturnTypeLoc,
7683 std::move(FnAttrs), EndLoc);
7688bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7690 if (Tok.
isOneOf(tok::amp, tok::ampamp)) {
7692 diag::warn_cxx98_compat_ref_qualifier :
7693 diag::ext_ref_qualifier);
7695 RefQualifierIsLValueRef = Tok.
is(tok::amp);
7707bool Parser::isFunctionDeclaratorIdentifierList() {
7709 && Tok.
is(tok::identifier)
7710 && !TryAltiVecVectorToken()
7726 && (!Tok.
is(tok::eof) &&
7739void Parser::ParseFunctionDeclaratorIdentifierList(
7743 assert(!
getLangOpts().requiresStrictPrototypes() &&
7744 "Cannot parse an identifier list in C23 or C++");
7750 if (!
D.getIdentifier())
7751 Diag(Tok, diag::ext_ident_list_in_param);
7754 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
7758 if (Tok.
isNot(tok::identifier)) {
7759 Diag(Tok, diag::err_expected) << tok::identifier;
7770 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7773 if (!ParamsSoFar.insert(ParmII).second) {
7774 Diag(Tok, diag::err_param_redefinition) << ParmII;
7820void Parser::ParseParameterDeclarationClause(
7829 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7850 IsACXXFunctionDeclaration) {
7872 ArgDeclSpecAttrs.takeAllFrom(FirstArgAttrs);
7875 MaybeParseCXX11Attributes(ArgDeclAttrs);
7878 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7899 Diag(ThisLoc, diag::err_requires_expr_explicit_object_parameter);
7902 ParsedTemplateInfo TemplateInfo;
7903 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7904 DeclSpecContext::DSC_normal,
7905 nullptr, AllowImplicitTypename);
7918 ParseDeclarator(ParmDeclarator);
7921 ParmDeclarator.SetRangeBegin(ThisLoc);
7924 MaybeParseGNUAttributes(ParmDeclarator);
7928 if (Tok.
is(tok::kw_requires)) {
7933 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7944 std::unique_ptr<CachedTokens> DefArgToks;
7948 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7949 ParmDeclarator.getNumTypeObjects() == 0) {
7951 Diag(DSStart, diag::err_missing_param);
7958 if (Tok.
is(tok::ellipsis) &&
7960 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7963 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7982 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7998 if (Tok.
is(tok::equal)) {
8009 ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument);
8025 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
8026 DefArgResult = ParseBraceInitializer();
8028 if (Tok.
is(tok::l_paren) &&
NextToken().is(tok::l_brace)) {
8029 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
8046 DefArgResult.
get());
8052 ParmDeclarator.getIdentifierLoc(),
8053 Param, std::move(DefArgToks)));
8060 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
8062 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
8067 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
8068 << ParmEllipsis.
isValid() << ParmEllipsis;
8071 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
8073 Diag(ParmDeclarator.getIdentifierLoc(),
8074 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
8077 << !ParmDeclarator.hasName();
8079 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
8098void Parser::ParseBracketDeclarator(
Declarator &
D) {
8099 if (CheckProhibitedCXX11Attribute())
8107 if (Tok.
getKind() == tok::r_square) {
8110 MaybeParseCXX11Attributes(attrs);
8114 T.getOpenLocation(),
8115 T.getCloseLocation()),
8116 std::move(attrs),
T.getCloseLocation());
8118 }
else if (Tok.
getKind() == tok::numeric_constant &&
8119 GetLookAheadToken(1).is(tok::r_square)) {
8126 MaybeParseCXX11Attributes(attrs);
8130 T.getOpenLocation(),
8131 T.getCloseLocation()),
8132 std::move(attrs),
T.getCloseLocation());
8134 }
else if (Tok.
getKind() == tok::code_completion) {
8147 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
8155 bool isStar =
false;
8162 if (Tok.
is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
8166 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
8170 }
else if (Tok.
isNot(tok::r_square)) {
8188 Diag(StaticLoc, diag::err_unspecified_size_with_static);
8195 D.setInvalidType(
true);
8208 isStar, NumElements.
get(),
T.getOpenLocation(),
8209 T.getCloseLocation()),
8214void Parser::ParseMisplacedBracketDeclarator(
Declarator &
D) {
8215 assert(Tok.
is(tok::l_square) &&
"Missing opening bracket");
8216 assert(!
D.mayOmitIdentifier() &&
"Declarator cannot omit identifier");
8222 while (Tok.
is(tok::l_square)) {
8223 ParseBracketDeclarator(TempDeclarator);
8229 if (Tok.
is(tok::semi))
8230 D.getName().EndLocation = StartBracketLoc;
8235 ParseDeclaratorInternal(
D, &Parser::ParseDirectDeclarator);
8240 if (TempDeclarator.getNumTypeObjects() == 0)
8244 bool NeedParens =
false;
8245 if (
D.getNumTypeObjects() != 0) {
8246 switch (
D.getTypeObject(
D.getNumTypeObjects() - 1).
Kind) {
8269 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
8271 D.AddTypeInfo(Chunk, TempDeclarator.getAttributePool(),
SourceLocation());
8276 if (!
D.getIdentifier() && !NeedParens)
8282 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
8286 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8294 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8314void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
8315 assert(Tok.
isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
8316 "Not a typeof specifier");
8318 bool IsUnqual = Tok.
is(tok::kw_typeof_unqual);
8325 bool HasParens = Tok.
is(tok::l_paren);
8335 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange));
8351 const char *PrevSpec =
nullptr;
8359 Diag(StartLoc, DiagID) << PrevSpec;
8376 const char *PrevSpec =
nullptr;
8384 Diag(StartLoc, DiagID) << PrevSpec;
8390void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
8391 assert(Tok.
is(tok::kw__Atomic) &&
NextToken().is(tok::l_paren) &&
8392 "Not an atomic specifier");
8396 if (
T.consumeOpen())
8400 if (
Result.isInvalid()) {
8408 if (
T.getCloseLocation().isInvalid())
8414 const char *PrevSpec =
nullptr;
8419 Diag(StartLoc, DiagID) << PrevSpec;
8424bool Parser::TryAltiVecVectorTokenOutOfLine() {
8426 switch (Next.getKind()) {
8427 default:
return false;
8430 case tok::kw_signed:
8431 case tok::kw_unsigned:
8436 case tok::kw_double:
8439 case tok::kw___bool:
8440 case tok::kw___pixel:
8441 Tok.
setKind(tok::kw___vector);
8443 case tok::identifier:
8444 if (Next.getIdentifierInfo() == Ident_pixel) {
8445 Tok.
setKind(tok::kw___vector);
8448 if (Next.getIdentifierInfo() == Ident_bool ||
8449 Next.getIdentifierInfo() == Ident_Bool) {
8450 Tok.
setKind(tok::kw___vector);
8458 const char *&PrevSpec,
unsigned &DiagID,
8463 switch (Next.getKind()) {
8466 case tok::kw_signed:
8467 case tok::kw_unsigned:
8472 case tok::kw_double:
8475 case tok::kw___bool:
8476 case tok::kw___pixel:
8479 case tok::identifier:
8480 if (Next.getIdentifierInfo() == Ident_pixel) {
8484 if (Next.getIdentifierInfo() == Ident_bool ||
8485 Next.getIdentifierInfo() == Ident_Bool) {
8506TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8513 FileID FID = SourceMgr.createFileID(
8514 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8518 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8519 L.setParsingPreprocessorDirective(
true);
8525 Tokens.push_back(Tok);
8526 }
while (Tok.
isNot(tok::eod));
8531 Token &EndToken = Tokens.back();
8538 Tokens.push_back(Tok);
8541 PP.EnterTokenStream(Tokens,
false,
8549 ParseScope LocalScope(
this, 0);
8562 while (Tok.
isNot(tok::eof))
8566 if (Tok.
is(tok::eof) && Tok.
getEofData() == TypeStr.data())
8571void Parser::DiagnoseBitIntUse(
const Token &Tok) {
8575 assert(Tok.
isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8576 "expected either an _ExtInt or _BitInt token!");
8579 if (Tok.
is(tok::kw__ExtInt)) {
8580 Diag(
Loc, diag::warn_ext_int_deprecated)
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
static StringRef normalizeAttrName(const IdentifierInfo *Name, StringRef NormalizedScopeName, AttributeCommonInfo::Syntax SyntaxUsed)
static Decl::Kind getKind(const Decl *D)
Defines the C++ template declaration subclasses.
llvm::MachO::RecordLoc RecordLoc
static bool IsAttributeLateParsedExperimentalExt(const IdentifierInfo &II)
returns true iff attribute is annotated with LateAttrParseExperimentalExt in Attr....
static bool FindLocsWithCommonFileID(Preprocessor &PP, SourceLocation StartLoc, SourceLocation EndLoc)
Check if the a start and end source location expand to the same macro.
static bool IsAttributeLateParsedStandard(const IdentifierInfo &II)
returns true iff attribute is annotated with LateAttrParseStandard in Attr.td.
static bool attributeHasIdentifierArg(const IdentifierInfo &II)
Determine whether the given attribute has an identifier argument.
static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II)
Determine whether the given attribute treats kw_this as an identifier.
static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II)
Determine whether the given attribute takes identifier arguments.
static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II)
Determine whether the given attribute requires parsing its arguments in an unevaluated context or not...
static bool isValidAfterIdentifierInDeclarator(const Token &T)
isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the specified token is valid after t...
static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II)
Determine whether the given attribute has a variadic identifier argument.
static bool attributeAcceptsExprPack(const IdentifierInfo &II)
Determine if an attribute accepts parameter packs.
static bool isPipeDeclarator(const Declarator &D)
static bool attributeHasStrictIdentifierArgAtIndex(const IdentifierInfo &II, size_t argIndex)
Determine whether the given attribute takes an identifier argument at a specific index.
static SourceLocation getMissingDeclaratorIdLoc(Declarator &D, SourceLocation Loc)
static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS, Parser &P)
static bool VersionNumberSeparator(const char Separator)
static bool attributeIsTypeArgAttr(const IdentifierInfo &II)
Determine whether the given attribute parses a type argument.
static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, DeclaratorContext TheContext)
static ParsedAttributeArgumentsProperties attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II)
Determine whether the given attribute has an identifier argument.
llvm::SmallVector< std::pair< const MemRegion *, SVal >, 4 > Bindings
static constexpr bool isOneOf()
This file declares semantic analysis for CUDA constructs.
This file declares facilities that support code completion.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenMP constructs and clauses.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the clang::TokenKind enum and support functions.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
const clang::PrintingPolicy & getPrintingPolicy() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
The result of parsing/analyzing an expression, statement etc.
@ AS_Declspec
__declspec(...)
Kind getParsedKind() const
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
SourceLocation getOpenLocation() const
SourceLocation getCloseLocation() const
Represents a C++ nested-name-specifier or a global scope specifier.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
SourceLocation getEndLoc() const
bool isSet() const
Deprecated.
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)
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.
The iterator over UnresolvedSets.
Declaration of a variable template.
static const char * getSpecifierName(Specifier VS)
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isPragmaAnnotation(TokenKind K)
Return true if this is an annotation token representing a pragma.
The JSON file list parser is used to communicate input to InstallAPI.
TypeSpecifierType
Specifies the kind of type.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
@ IK_TemplateId
A template-id, e.g., f<int>.
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &Second, ParsedAttributes &Result)
Consumes the attributes from First and Second and concatenates them into Result.
Language
The language for the input, used to select and validate the language standard and possible actions.
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
LangAS
Defines the address space values used by the address space qualifier of QualType.
int hasAttribute(AttributeCommonInfo::Syntax Syntax, const IdentifierInfo *Scope, const IdentifierInfo *Attr, const TargetInfo &Target, const LangOptions &LangOpts)
Return the version number associated with the attribute if we recognize and implement the attribute s...
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Dependent_template_name
The name refers to a dependent template name:
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ Parens
New-expression has a C++98 paren-delimited initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_None
no exception specification
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Represents information about a change in availability for an entity, which is part of the encoding of...
VersionTuple Version
The version number at which the change occurred.
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
SourceRange VersionRange
The source range covering the version number.
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
ParamInfo - An array of paraminfo objects is allocated whenever a function declarator is parsed.
One instance of this struct is used for each type in a declarator that is parsed.
enum clang::DeclaratorChunk::@225 Kind
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, ArrayRef< NamedDecl * > DeclsInPrototype, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult(), SourceLocation TrailingReturnTypeLoc=SourceLocation(), DeclSpec *MethodQualifiers=nullptr)
DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
static DeclaratorChunk getPipe(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc)
Return a DeclaratorChunk for an array.
SourceLocation Loc
Loc - The place where this type was defined.
static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, unsigned TypeQuals, SourceLocation StarLoc, SourceLocation EndLoc)
static DeclaratorChunk getParen(SourceLocation LParenLoc, SourceLocation RParenLoc)
Return a DeclaratorChunk for a paren.
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, SourceLocation AtomicQualLoc, SourceLocation UnalignedQualLoc)
Return a DeclaratorChunk for a pointer.
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, bool lvalue)
Return a DeclaratorChunk for a reference.
Wraps an identifier and optional source location for the identifier.
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
bool isStringLiteralArg(unsigned I) const
Describes how types, statements, expressions, and declarations should be printed.
ExpressionKind
Describes whether we are in an expression constext which we have to handle differently.
Information about a template-id annotation token.
bool hasInvalidName() const
const IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
TemplateNameKind Kind
The kind of template that Template refers to.
bool hasInvalidArgs() const