30#include "llvm/ADT/SmallSet.h"
31#include "llvm/ADT/SmallString.h"
32#include "llvm/ADT/StringSwitch.h"
49 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
50 if (DSC == DeclSpecContext::DSC_normal)
51 DSC = DeclSpecContext::DSC_type_specifier;
57 ParseSpecifierQualifierList(DS, AS, DSC);
65 if (AL.isDeclspecAttribute())
66 ToBeMoved.push_back(&AL);
75 ParseDeclarator(DeclaratorInfo);
87 if (Name.size() >= 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
88 return Name.drop_front(2).drop_back(2);
95#define CLANG_ATTR_LATE_PARSED_LIST
97#include "clang/Parse/AttrParserStringSwitches.inc"
99#undef CLANG_ATTR_LATE_PARSED_LIST
109 if (
SM.getFileID(StartLoc) !=
SM.getFileID(EndLoc))
112 bool AttrStartIsInMacro =
114 bool AttrEndIsInMacro =
116 return AttrStartIsInMacro && AttrEndIsInMacro;
119void Parser::ParseAttributes(
unsigned WhichAttrKinds,
ParsedAttributes &Attrs,
120 LateParsedAttrList *LateAttrs) {
126 if (WhichAttrKinds & PAKM_CXX11)
127 MoreToParse |= MaybeParseCXX11Attributes(Attrs);
128 if (WhichAttrKinds & PAKM_GNU)
129 MoreToParse |= MaybeParseGNUAttributes(Attrs, LateAttrs);
130 if (WhichAttrKinds & PAKM_Declspec)
131 MoreToParse |= MaybeParseMicrosoftDeclSpecs(Attrs);
132 }
while (MoreToParse);
177 LateParsedAttrList *LateAttrs,
Declarator *D) {
178 assert(Tok.
is(tok::kw___attribute) &&
"Not a GNU attribute list!");
183 while (Tok.
is(tok::kw___attribute)) {
185 unsigned OldNumAttrs = Attrs.
size();
186 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
188 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
193 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"(")) {
206 if (Tok.
is(tok::code_completion)) {
217 if (Tok.
isNot(tok::l_paren)) {
218 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
219 ParsedAttr::Form::GNU());
225 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc,
nullptr,
231 LateParsedAttribute *LA =
232 new LateParsedAttribute(
this, *AttrName, AttrNameLoc);
233 LateAttrs->push_back(LA);
237 if (!ClassStack.empty() && !LateAttrs->parseSoon())
238 getCurrentClass().LateParsedDeclarations.push_back(LA);
242 LA->Toks.push_back(Tok);
245 ConsumeAndStoreUntil(tok::r_paren, LA->Toks,
true);
250 LA->Toks.push_back(Eof);
251 }
while (Tok.
is(tok::comma));
253 if (ExpectAndConsume(tok::r_paren))
256 if (ExpectAndConsume(tok::r_paren))
263 if (!
SM.isWrittenInBuiltinFile(
SM.getSpellingLoc(AttrTokLoc)) &&
266 StringRef FoundName =
270 for (
unsigned i = OldNumAttrs; i < Attrs.
size(); ++i)
271 Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.
getBegin());
274 for (
unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
275 (*LateAttrs)[i]->MacroII = MacroII;
285#define CLANG_ATTR_IDENTIFIER_ARG_LIST
287#include "clang/Parse/AttrParserStringSwitches.inc"
289#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
295#define CLANG_ATTR_STRING_LITERAL_ARG_LIST
297#include "clang/Parse/AttrParserStringSwitches.inc"
299#undef CLANG_ATTR_STRING_LITERAL_ARG_LIST
304#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
306#include "clang/Parse/AttrParserStringSwitches.inc"
308#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
313#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
315#include "clang/Parse/AttrParserStringSwitches.inc"
317#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
322#define CLANG_ATTR_ACCEPTS_EXPR_PACK
324#include "clang/Parse/AttrParserStringSwitches.inc"
326#undef CLANG_ATTR_ACCEPTS_EXPR_PACK
331#define CLANG_ATTR_TYPE_ARG_LIST
333#include "clang/Parse/AttrParserStringSwitches.inc"
335#undef CLANG_ATTR_TYPE_ARG_LIST
341#define CLANG_ATTR_ARG_CONTEXT_LIST
343#include "clang/Parse/AttrParserStringSwitches.inc"
345#undef CLANG_ATTR_ARG_CONTEXT_LIST
349 assert(Tok.
is(tok::identifier) &&
"expected an identifier");
367 if (Tok.
isNot(tok::r_paren))
370 if (
Parens.consumeClose())
379 ScopeName, ScopeLoc, T.
get(), Form);
382 ScopeName, ScopeLoc,
nullptr, 0, Form);
386Parser::ParseUnevaluatedStringInAttribute(
const IdentifierInfo &AttrName) {
387 if (Tok.
is(tok::l_paren)) {
390 ExprResult Res = ParseUnevaluatedStringInAttribute(AttrName);
391 Paren.consumeClose();
394 if (!isTokenStringLiteral()) {
402bool Parser::ParseAttributeArgumentList(
405 bool SawError =
false;
410 Expr = ParseUnevaluatedStringInAttribute(AttrName);
412 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
413 Expr = ParseBraceInitializer();
419 if (Tok.
is(tok::ellipsis))
421 else if (Tok.
is(tok::code_completion)) {
432 if (
Expr.isInvalid()) {
437 Exprs.push_back(
Expr.get());
439 if (Tok.
isNot(tok::comma))
444 checkPotentialAngleBracketDelimiter(Comma);
451 for (
auto &E : Exprs) {
460unsigned Parser::ParseAttributeArgsCommon(
469 bool AttributeHasVariadicIdentifierArg =
473 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
477 if (Tok.
is(tok::identifier)) {
479 bool IsIdentifierArg = AttributeHasVariadicIdentifierArg ||
489 IsIdentifierArg = Next.isOneOf(tok::r_paren, tok::comma);
493 ArgExprs.push_back(ParseIdentifierLoc());
497 if (!ArgExprs.empty() ? Tok.
is(tok::comma) : Tok.
isNot(tok::r_paren)) {
499 if (!ArgExprs.empty())
502 if (AttributeIsTypeArgAttr) {
510 TheParsedType = T.
get();
511 }
else if (AttributeHasVariadicIdentifierArg) {
519 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
523 if (Tok.
is(tok::identifier)) {
524 ArgExprs.push_back(ParseIdentifierLoc());
539 ArgExprs.push_back(ArgExpr.
get());
551 ExprVector ParsedExprs;
554 if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties)) {
560 for (
size_t I = 0; I < ParsedExprs.size(); ++I) {
561 if (!isa<PackExpansionExpr>(ParsedExprs[I]))
566 diag::err_attribute_argument_parm_pack_not_supported)
573 ArgExprs.insert(ArgExprs.end(), ParsedExprs.begin(), ParsedExprs.end());
578 if (!ExpectAndConsume(tok::r_paren)) {
581 if (AttributeIsTypeArgAttr && !TheParsedType.
get().
isNull()) {
583 ScopeName, ScopeLoc, TheParsedType, Form);
586 ArgExprs.data(), ArgExprs.size(), Form);
593 return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.
get().
isNull());
598void Parser::ParseGNUAttributeArgs(
603 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
608 if (AttrKind == ParsedAttr::AT_Availability) {
609 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
612 }
else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
613 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
614 ScopeName, ScopeLoc, Form);
616 }
else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
617 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
618 ScopeName, ScopeLoc, Form);
620 }
else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
621 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
624 }
else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
625 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
626 ScopeName, ScopeLoc, Form);
629 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName,
636 std::optional<ParseScope> PrototypeScope;
643 for (
unsigned i = 0; i != FTI.
NumParams; ++i) {
649 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
653unsigned Parser::ParseClangAttributeArgs(
657 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
664 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
665 ScopeName, ScopeLoc, Form);
666 case ParsedAttr::AT_ExternalSourceSymbol:
667 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
668 ScopeName, ScopeLoc, Form);
670 case ParsedAttr::AT_Availability:
671 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
674 case ParsedAttr::AT_ObjCBridgeRelated:
675 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
676 ScopeName, ScopeLoc, Form);
678 case ParsedAttr::AT_SwiftNewType:
679 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
682 case ParsedAttr::AT_TypeTagForDatatype:
683 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
684 ScopeName, ScopeLoc, Form);
687 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
693 unsigned ExistingAttrs = Attrs.
size();
707 if (AttrName->
getName() ==
"property") {
713 T.expectAndConsume(diag::err_expected_lparen_after,
722 bool HasInvalidAccessor =
false;
727 if (!Tok.
is(tok::identifier)) {
729 if (Tok.
is(tok::r_paren) && !HasInvalidAccessor &&
730 AccessorNames[AK_Put] ==
nullptr &&
731 AccessorNames[AK_Get] ==
nullptr) {
732 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
743 if (KindStr ==
"get") {
745 }
else if (KindStr ==
"put") {
749 }
else if (KindStr ==
"set") {
750 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
757 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
759 HasInvalidAccessor =
true;
760 goto next_property_accessor;
764 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
765 HasInvalidAccessor =
true;
784 if (!Tok.
is(tok::identifier)) {
789 if (Kind == AK_Invalid) {
791 }
else if (AccessorNames[Kind] !=
nullptr) {
793 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
799 next_property_accessor:
805 if (Tok.
is(tok::r_paren))
808 Diag(Tok.
getLocation(), diag::err_ms_property_expected_comma_or_rparen);
813 if (!HasInvalidAccessor)
815 AccessorNames[AK_Get], AccessorNames[AK_Put],
816 ParsedAttr::Form::Declspec());
818 return !HasInvalidAccessor;
822 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
828 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) << AttrName;
841 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
842 assert(Tok.
is(tok::kw___declspec) &&
"Not a declspec!");
847 while (Tok.
is(tok::kw___declspec)) {
850 if (T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
856 while (Tok.
isNot(tok::r_paren)) {
861 if (Tok.
is(tok::code_completion)) {
869 bool IsString = Tok.
getKind() == tok::string_literal;
870 if (!IsString && Tok.
getKind() != tok::identifier &&
871 Tok.
getKind() != tok::kw_restrict) {
872 Diag(Tok, diag::err_ms_declspec_type);
882 StringRef Str = PP.
getSpelling(Tok, StrBuffer, &Invalid);
888 AttrNameLoc = ConsumeStringToken();
894 bool AttrHandled =
false;
897 if (Tok.
is(tok::l_paren))
898 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
899 else if (AttrName->
getName() ==
"property")
905 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
906 ParsedAttr::Form::Declspec());
909 EndLoc = T.getCloseLocation();
920 case tok::kw___fastcall:
921 case tok::kw___stdcall:
922 case tok::kw___thiscall:
923 case tok::kw___regcall:
924 case tok::kw___cdecl:
925 case tok::kw___vectorcall:
926 case tok::kw___ptr64:
928 case tok::kw___ptr32:
930 case tok::kw___uptr: {
933 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
944 assert(Tok.
is(tok::kw___funcref));
948 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
954 attrs.
addNew(AttrName, AttrNameLoc,
nullptr,
959void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
965 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) <<
Range;
975 case tok::kw_volatile:
976 case tok::kw___fastcall:
977 case tok::kw___stdcall:
978 case tok::kw___thiscall:
979 case tok::kw___cdecl:
980 case tok::kw___vectorcall:
981 case tok::kw___ptr32:
982 case tok::kw___ptr64:
984 case tok::kw___unaligned:
997 while (Tok.
is(tok::kw___pascal)) {
1000 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1007 while (Tok.
is(tok::kw___kernel)) {
1010 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1016 while (Tok.
is(tok::kw___noinline__)) {
1019 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1020 tok::kw___noinline__);
1027 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1031bool Parser::isHLSLQualifier(
const Token &Tok)
const {
1032 return Tok.
is(tok::kw_groupshared);
1039 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0, Kind);
1047 case tok::kw__Nonnull:
1048 case tok::kw__Nullable:
1049 case tok::kw__Nullable_result:
1050 case tok::kw__Null_unspecified: {
1054 Diag(AttrNameLoc, diag::ext_nullability)
1056 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1067 return (Separator ==
'.' || Separator ==
'_');
1078VersionTuple Parser::ParseVersionTuple(
SourceRange &Range) {
1081 if (!Tok.
is(tok::numeric_constant)) {
1082 Diag(Tok, diag::err_expected_version);
1085 return VersionTuple();
1094 const char *ThisTokBegin = &Buffer[0];
1098 unsigned ActualLength = PP.
getSpelling(Tok, ThisTokBegin, &Invalid);
1100 return VersionTuple();
1103 unsigned AfterMajor = 0;
1105 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
1106 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
1110 if (AfterMajor == 0) {
1111 Diag(Tok, diag::err_expected_version);
1114 return VersionTuple();
1117 if (AfterMajor == ActualLength) {
1122 Diag(Tok, diag::err_zero_version);
1123 return VersionTuple();
1126 return VersionTuple(Major);
1129 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1131 || (AfterMajor + 1 == ActualLength)) {
1132 Diag(Tok, diag::err_expected_version);
1135 return VersionTuple();
1139 unsigned AfterMinor = AfterMajor + 1;
1141 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
1142 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
1146 if (AfterMinor == ActualLength) {
1150 if (Major == 0 && Minor == 0) {
1151 Diag(Tok, diag::err_zero_version);
1152 return VersionTuple();
1155 return VersionTuple(Major, Minor);
1158 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1161 Diag(Tok, diag::err_expected_version);
1164 return VersionTuple();
1168 if (AfterMajorSeparator != AfterMinorSeparator)
1169 Diag(Tok, diag::warn_expected_consistent_version_separator);
1172 unsigned AfterSubminor = AfterMinor + 1;
1173 unsigned Subminor = 0;
1174 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
1175 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
1179 if (AfterSubminor != ActualLength) {
1180 Diag(Tok, diag::err_expected_version);
1183 return VersionTuple();
1186 return VersionTuple(Major, Minor, Subminor);
1214void Parser::ParseAvailabilityAttribute(
1218 enum { Introduced, Deprecated, Obsoleted,
Unknown };
1224 if (T.consumeOpen()) {
1225 Diag(Tok, diag::err_expected) << tok::l_paren;
1230 if (Tok.
isNot(tok::identifier)) {
1231 Diag(Tok, diag::err_availability_expected_platform);
1238 if (Ident->getName().contains(
"xrOS") || Ident->getName().contains(
"xros"))
1239 Diag(Platform->
Loc, diag::warn_availability_unknown_platform) << Ident;
1241 else if (Ident->getName() ==
"macosx")
1245 else if (Ident->getName() ==
"macosx_app_extension")
1249 AvailabilityAttr::canonicalizePlatformName(Ident->getName()));
1253 if (ExpectAndConsume(tok::comma)) {
1260 if (!Ident_introduced) {
1274 if (Tok.
isNot(tok::identifier)) {
1275 Diag(Tok, diag::err_availability_expected_change);
1282 if (Keyword == Ident_strict) {
1284 Diag(KeywordLoc, diag::err_availability_redundant)
1287 StrictLoc = KeywordLoc;
1291 if (Keyword == Ident_unavailable) {
1292 if (UnavailableLoc.
isValid()) {
1293 Diag(KeywordLoc, diag::err_availability_redundant)
1296 UnavailableLoc = KeywordLoc;
1300 if (Keyword == Ident_deprecated && Platform->
Ident &&
1303 if (Changes[Deprecated].KeywordLoc.
isValid()) {
1304 Diag(KeywordLoc, diag::err_availability_redundant)
1311 Changes[Deprecated].
Version = VersionTuple(1);
1315 if (Tok.
isNot(tok::equal)) {
1316 Diag(Tok, diag::err_expected_after) << Keyword << tok::equal;
1321 if (Keyword == Ident_message || Keyword == Ident_replacement) {
1322 if (!isTokenStringLiteral()) {
1323 Diag(Tok, diag::err_expected_string_literal)
1328 if (Keyword == Ident_message) {
1339 if ((Keyword == Ident_introduced || Keyword == Ident_deprecated) &&
1340 Tok.
is(tok::identifier)) {
1344 if (Keyword == Ident_introduced)
1345 UnavailableLoc = KeywordLoc;
1351 VersionTuple Version = ParseVersionTuple(VersionRange);
1353 if (Version.empty()) {
1359 if (Keyword == Ident_introduced)
1361 else if (Keyword == Ident_deprecated)
1363 else if (Keyword == Ident_obsoleted)
1369 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1370 Diag(KeywordLoc, diag::err_availability_redundant)
1373 Changes[Index].VersionRange.
getEnd());
1377 Changes[Index].
Version = Version;
1380 Diag(KeywordLoc, diag::err_availability_unknown_change)
1381 << Keyword << VersionRange;
1387 if (T.consumeClose())
1391 *endLoc = T.getCloseLocation();
1395 if (UnavailableLoc.
isValid()) {
1396 bool Complained =
false;
1397 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1398 if (Changes[Index].KeywordLoc.
isValid()) {
1400 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1402 Changes[Index].VersionRange.
getEnd());
1413 attrs.
addNew(&Availability,
1414 SourceRange(AvailabilityLoc, T.getCloseLocation()), ScopeName,
1415 ScopeLoc, Platform, Changes[Introduced], Changes[Deprecated],
1416 Changes[Obsoleted], UnavailableLoc, MessageExpr.
get(), Form,
1417 StrictLoc, ReplacementExpr.
get());
1434void Parser::ParseExternalSourceSymbolAttribute(
1440 if (T.expectAndConsume())
1444 if (!Ident_language) {
1452 bool HasLanguage =
false;
1454 bool HasDefinedIn =
false;
1457 bool HasUSR =
false;
1461 if (Tok.
isNot(tok::identifier)) {
1462 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1469 if (Keyword == Ident_generated_declaration) {
1470 if (GeneratedDeclaration) {
1471 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) << Keyword;
1475 GeneratedDeclaration = ParseIdentifierLoc();
1479 if (Keyword != Ident_language && Keyword != Ident_defined_in &&
1480 Keyword != Ident_USR) {
1481 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1487 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1493 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1495 if (Keyword == Ident_language)
1497 else if (Keyword == Ident_USR)
1500 HasDefinedIn =
true;
1502 if (!isTokenStringLiteral()) {
1503 Diag(Tok, diag::err_expected_string_literal)
1506 Keyword == Ident_language
1508 : (Keyword == Ident_defined_in ? 1 : 2));
1512 if (Keyword == Ident_language) {
1514 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1520 }
else if (Keyword == Ident_USR) {
1522 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1529 assert(Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1531 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1541 if (T.consumeClose())
1544 *EndLoc = T.getCloseLocation();
1549 ScopeName, ScopeLoc, Args, std::size(Args), Form);
1563void Parser::ParseObjCBridgeRelatedAttribute(
1569 if (T.consumeOpen()) {
1570 Diag(Tok, diag::err_expected) << tok::l_paren;
1575 if (Tok.
isNot(tok::identifier)) {
1576 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1581 if (ExpectAndConsume(tok::comma)) {
1590 if (Tok.
is(tok::identifier)) {
1593 Diag(Tok, diag::err_objcbridge_related_selector_name);
1599 if (Tok.
is(tok::colon))
1600 Diag(Tok, diag::err_objcbridge_related_selector_name);
1602 Diag(Tok, diag::err_expected) << tok::comma;
1610 if (Tok.
is(tok::identifier))
1612 else if (Tok.
isNot(tok::r_paren)) {
1613 Diag(Tok, diag::err_expected) << tok::r_paren;
1619 if (T.consumeClose())
1623 *EndLoc = T.getCloseLocation();
1626 Attrs.
addNew(&ObjCBridgeRelated,
1627 SourceRange(ObjCBridgeRelatedLoc, T.getCloseLocation()),
1628 ScopeName, ScopeLoc, RelatedClass, ClassMethod, InstanceMethod,
1632void Parser::ParseSwiftNewTypeAttribute(
1639 if (T.consumeOpen()) {
1640 Diag(Tok, diag::err_expected) << tok::l_paren;
1644 if (Tok.
is(tok::r_paren)) {
1649 if (Tok.
isNot(tok::kw_struct) && Tok.
isNot(tok::kw_enum)) {
1650 Diag(Tok, diag::warn_attribute_type_not_supported)
1652 if (!isTokenSpecial())
1663 if (T.consumeClose())
1666 *EndLoc = T.getCloseLocation();
1670 ScopeName, ScopeLoc, Args, std::size(Args), Form);
1673void Parser::ParseTypeTagForDatatypeAttribute(
1677 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1682 if (Tok.
isNot(tok::identifier)) {
1683 Diag(Tok, diag::err_expected) << tok::identifier;
1689 if (ExpectAndConsume(tok::comma)) {
1701 bool LayoutCompatible =
false;
1702 bool MustBeNull =
false;
1704 if (Tok.
isNot(tok::identifier)) {
1705 Diag(Tok, diag::err_expected) << tok::identifier;
1710 if (Flag->
isStr(
"layout_compatible"))
1711 LayoutCompatible =
true;
1712 else if (Flag->
isStr(
"must_be_null"))
1715 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1722 if (!T.consumeClose()) {
1724 ArgumentKind, MatchingCType.
get(),
1725 LayoutCompatible, MustBeNull, Form);
1729 *EndLoc = T.getCloseLocation();
1740bool Parser::DiagnoseProhibitedCXX11Attribute() {
1741 assert(Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square));
1743 switch (isCXX11AttributeSpecifier(
true)) {
1744 case CAK_NotAttributeSpecifier:
1748 case CAK_InvalidAttributeSpecifier:
1752 case CAK_AttributeSpecifier:
1757 assert(Tok.
is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1759 Diag(BeginLoc, diag::err_attributes_not_allowed)
1763 llvm_unreachable(
"All cases handled above.");
1772 assert((Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square)) ||
1779 ParseCXX11Attributes(Attrs);
1782 (Keyword ?
Diag(Loc, diag::err_keyword_not_allowed) << Keyword
1783 :
Diag(Loc, diag::err_attributes_not_allowed))
1788void Parser::DiagnoseProhibitedAttributes(
1790 auto *FirstAttr = Attrs.
empty() ? nullptr : &Attrs.
front();
1791 if (CorrectLocation.
isValid()) {
1793 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1794 ?
Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1795 :
Diag(CorrectLocation, diag::err_attributes_misplaced))
1800 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1801 ?
Diag(
Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr
1802 :
Diag(
Range.getBegin(), diag::err_attributes_not_allowed))
1808 unsigned AttrDiagID,
1809 unsigned KeywordDiagID,
1810 bool DiagnoseEmptyAttrs,
1811 bool WarnOnUnknownAttrs) {
1821 if (FirstLSquare.
is(tok::l_square)) {
1822 std::optional<Token> SecondLSquare =
1825 if (SecondLSquare && SecondLSquare->is(tok::l_square)) {
1836 if (AL.isRegularKeywordAttribute()) {
1837 Diag(AL.getLoc(), KeywordDiagID) << AL;
1841 if (!AL.isStandardAttributeSyntax())
1844 if (WarnOnUnknownAttrs)
1845 Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
1846 << AL << AL.getRange();
1848 Diag(AL.getLoc(), AttrDiagID) << AL;
1856 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1857 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1858 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
1878 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1879 AL.isDeclspecAttribute()) ||
1880 AL.isMicrosoftAttribute())
1881 ToBeMoved.push_back(&AL);
1916 Decl *SingleDecl =
nullptr;
1918 case tok::kw_template:
1919 case tok::kw_export:
1920 ProhibitAttributes(DeclAttrs);
1921 ProhibitAttributes(DeclSpecAttrs);
1922 return ParseDeclarationStartingWithTemplate(Context, DeclEnd, DeclAttrs);
1923 case tok::kw_inline:
1926 ProhibitAttributes(DeclAttrs);
1927 ProhibitAttributes(DeclSpecAttrs);
1929 return ParseNamespace(Context, DeclEnd, InlineLoc);
1931 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1932 true,
nullptr, DeclSpecStart);
1934 case tok::kw_cbuffer:
1935 case tok::kw_tbuffer:
1936 SingleDecl = ParseHLSLBuffer(DeclEnd);
1938 case tok::kw_namespace:
1939 ProhibitAttributes(DeclAttrs);
1940 ProhibitAttributes(DeclSpecAttrs);
1941 return ParseNamespace(Context, DeclEnd);
1942 case tok::kw_using: {
1945 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1948 case tok::kw_static_assert:
1949 case tok::kw__Static_assert:
1950 ProhibitAttributes(DeclAttrs);
1951 ProhibitAttributes(DeclSpecAttrs);
1952 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1955 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1956 true,
nullptr, DeclSpecStart);
1988 bool RequireSemi, ForRangeInit *FRI,
SourceLocation *DeclSpecStart) {
1991 OriginalDeclSpecAttrs.
addAll(DeclSpecAttrs.
begin(), DeclSpecAttrs.
end());
1992 OriginalDeclSpecAttrs.
Range = DeclSpecAttrs.
Range;
1998 ParsedTemplateInfo TemplateInfo;
1999 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
2000 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none, DSContext);
2005 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
2010 if (Tok.
is(tok::semi)) {
2011 ProhibitAttributes(DeclAttrs);
2018 DS.complete(TheDecl);
2020 Decl* decls[] = {AnonRecord, TheDecl};
2032 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
2039 case tok::annot_cxxscope:
2040 case tok::annot_template_id:
2042 case tok::code_completion:
2043 case tok::coloncolon:
2045 case tok::kw___attribute:
2046 case tok::kw_operator:
2062 case tok::identifier:
2064 case tok::code_completion:
2065 case tok::coloncolon:
2068 case tok::equalequal:
2069 case tok::kw_alignas:
2071 case tok::kw___attribute:
2089 case tok::identifier:
2112 if (Tok.
isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
2136 case tok::kw_inline:
2141 (!ParsingInObjCContainer || CurParsedObjCImpl))
2145 case tok::kw_namespace:
2150 (!ParsingInObjCContainer || CurParsedObjCImpl))
2156 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2157 ParsingInObjCContainer)
2169 case tok::annot_module_begin:
2170 case tok::annot_module_end:
2171 case tok::annot_module_include:
2172 case tok::annot_repl_input_end:
2189 ParsedTemplateInfo &TemplateInfo,
2191 ForRangeInit *FRI) {
2197 LocalAttrs.takeAllFrom(Attrs);
2199 if (TemplateInfo.TemplateParams)
2202 bool IsTemplateSpecOrInst =
2203 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
2204 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
2209 if (IsTemplateSpecOrInst)
2219 MaybeParseHLSLSemantics(D);
2221 if (Tok.
is(tok::kw_requires))
2222 ParseTrailingRequiresClause(D);
2227 LateParsedAttrList LateParsedAttrs(
true);
2229 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2234 if (Tok.
is(tok::kw__Noreturn)) {
2236 const char *PrevSpec;
2242 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2243 Fixit &= Tok.
isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2245 Diag(Loc, diag::err_c11_noreturn_misplaced)
2247 << (Fixit ?
FixItHint::CreateInsertion(D.getBeginLoc(),
"_Noreturn ")
2252 if (Tok.
is(tok::equal) &&
NextToken().is(tok::code_completion)) {
2263 while (
auto Specifier = isCXX11VirtSpecifier()) {
2264 Diag(Tok, diag::err_virt_specifier_outside_class)
2272 if (!isDeclarationAfterDeclarator()) {
2278 if (isStartOfFunctionDefinition(D)) {
2288 diag::err_function_declared_typedef)
2292 Decl *TheDecl =
nullptr;
2294 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
2298 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2299 TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(),
2305 diag::err_explicit_instantiation_with_definition)
2313 std::nullopt, LAngleLoc,
nullptr));
2315 TheDecl = ParseFunctionDefinition(
2317 ParsedTemplateInfo(&FakedParamLists,
2324 ParseFunctionDefinition(D, TemplateInfo, &LateParsedAttrs);
2331 Tok.
is(tok::kw_namespace)) {
2341 Diag(Tok, diag::err_expected_fn_body);
2346 if (Tok.
is(tok::l_brace)) {
2347 Diag(Tok, diag::err_function_definition_not_allowed);
2355 if (ParseAsmAttributesAfterDeclarator(D))
2364 if (FRI && (Tok.
is(tok::colon) || isTokIdentifier_in())) {
2365 bool IsForRangeLoop =
false;
2367 IsForRangeLoop =
true;
2377 LastRecord.InLifetimeExtendingContext =
true;
2381 LastRecord.InMaterializeTemporaryObjectContext =
true;
2386 if (Tok.
is(tok::l_brace))
2387 FRI->RangeExpr = ParseBraceInitializer();
2398 FRI->LifetimeExtendTemps = std::move(
2403 if (IsForRangeLoop) {
2407 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2408 VD->setObjCForDecl(
true);
2411 D.complete(ThisDecl);
2417 ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo, FRI);
2418 if (LateParsedAttrs.size() > 0)
2419 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2420 D.complete(FirstDecl);
2422 DeclsInGroup.push_back(FirstDecl);
2430 if (Tok.
isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2434 Diag(CommaLoc, diag::err_expected_semi_declaration)
2444 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
2446 Diag(CommaLoc, diag::err_multiple_template_declarators)
2447 << TemplateInfo.Kind;
2461 MaybeParseGNUAttributes(D);
2465 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2470 MaybeParseHLSLSemantics(D);
2477 if (Tok.
is(tok::kw_requires))
2478 ParseTrailingRequiresClause(D);
2479 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D, TemplateInfo);
2480 D.complete(ThisDecl);
2482 DeclsInGroup.push_back(ThisDecl);
2489 if (ExpectSemi && ExpectAndConsumeSemi(
2491 ? diag::err_invalid_token_after_toplevel_declarator
2492 : diag::err_expected_semi_declaration)) {
2505bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &D) {
2507 if (Tok.
is(tok::kw_asm)) {
2509 ExprResult AsmLabel(ParseSimpleAsm(
true, &Loc));
2510 if (AsmLabel.isInvalid()) {
2519 MaybeParseGNUAttributes(D);
2545Decl *Parser::ParseDeclarationAfterDeclarator(
2546 Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
2547 if (ParseAsmAttributesAfterDeclarator(D))
2550 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
2553Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2554 Declarator &D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2556 struct InitializerScopeRAII {
2562 :
P(
P), D(D), ThisDecl(ThisDecl) {
2563 if (ThisDecl &&
P.getLangOpts().CPlusPlus) {
2567 S =
P.getCurScope();
2569 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2572 ~InitializerScopeRAII() { pop(); }
2574 if (ThisDecl &&
P.getLangOpts().CPlusPlus) {
2577 S =
P.getCurScope();
2578 P.Actions.ActOnCXXExitDeclInitializer(S, ThisDecl);
2587 InitKind TheInitKind;
2589 if (isTokenEqualOrEqualTypo())
2590 TheInitKind = InitKind::Equal;
2591 else if (Tok.
is(tok::l_paren))
2592 TheInitKind = InitKind::CXXDirect;
2595 TheInitKind = InitKind::CXXBraced;
2597 TheInitKind = InitKind::Uninitialized;
2598 if (TheInitKind != InitKind::Uninitialized)
2602 Decl *ThisDecl =
nullptr;
2603 Decl *OuterDecl =
nullptr;
2604 switch (TemplateInfo.Kind) {
2605 case ParsedTemplateInfo::NonTemplate:
2609 case ParsedTemplateInfo::Template:
2610 case ParsedTemplateInfo::ExplicitSpecialization: {
2612 *TemplateInfo.TemplateParams,
2614 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2617 ThisDecl = VT->getTemplatedDecl();
2622 case ParsedTemplateInfo::ExplicitInstantiation: {
2623 if (Tok.
is(tok::semi)) {
2625 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
2630 ThisDecl = ThisRes.
get();
2638 Diag(Tok, diag::err_template_defn_explicit_instantiation)
2645 diag::err_explicit_instantiation_with_definition)
2653 std::nullopt, LAngleLoc,
nullptr));
2664 switch (TheInitKind) {
2666 case InitKind::Equal: {
2669 if (Tok.
is(tok::kw_delete)) {
2675 }
else if (Tok.
is(tok::kw_default)) {
2683 InitializerScopeRAII InitScope(*
this, D, ThisDecl);
2685 if (Tok.
is(tok::code_completion)) {
2698 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2702 FRI->ColonLoc = EqualLoc;
2704 FRI->RangeExpr =
Init;
2709 if (
Init.isInvalid()) {
2711 StopTokens.push_back(tok::comma);
2714 StopTokens.push_back(tok::r_paren);
2723 case InitKind::CXXDirect: {
2730 InitializerScopeRAII InitScope(*
this, D, ThisDecl);
2732 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2733 auto RunSignatureHelp = [&]() {
2735 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2736 ThisDecl->
getLocation(), Exprs, T.getOpenLocation(),
2738 CalledSignatureHelp =
true;
2739 return PreferredType;
2741 auto SetPreferredType = [&] {
2742 PreferredType.enterFunctionArgument(Tok.
getLocation(), RunSignatureHelp);
2745 llvm::function_ref<void()> ExpressionStarts;
2751 ExpressionStarts = SetPreferredType;
2754 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2761 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2762 ThisDecl->
getLocation(), Exprs, T.getOpenLocation(),
2764 CalledSignatureHelp =
true;
2773 T.getCloseLocation(),
2780 case InitKind::CXXBraced: {
2782 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2784 InitializerScopeRAII InitScope(*
this, D, ThisDecl);
2786 PreferredType.enterVariableInit(Tok.
getLocation(), ThisDecl);
2791 if (
Init.isInvalid()) {
2797 case InitKind::Uninitialized: {
2804 return OuterDecl ? OuterDecl : ThisDecl;
2813void Parser::ParseSpecifierQualifierList(
2819 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC,
nullptr,
2820 AllowImplicitTypename);
2825 Diag(Tok, diag::err_expected_type);
2828 Diag(Tok, diag::err_typename_requires_specqual);
2839 diag::err_typename_invalid_storageclass);
2883 return T.
isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2884 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2898 const ParsedTemplateInfo &TemplateInfo,
2901 assert(Tok.
is(tok::identifier) &&
"should have identifier");
2923 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
2941 AnnotateScopeToken(*SS,
false);
2952 DSC == DeclSpecContext::DSC_template_type_arg)) {
2953 const char *PrevSpec;
2969 if (SS ==
nullptr) {
2970 const char *TagName =
nullptr, *FixitTagName =
nullptr;
2976 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
2978 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
2980 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
2982 TagName=
"__interface"; FixitTagName =
"__interface ";
2983 TagKind=tok::kw___interface;
break;
2985 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
2993 Diag(Loc, diag::err_use_of_tag_name_without_tag)
2994 << TokenName << TagName <<
getLangOpts().CPlusPlus
3000 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
3001 << TokenName << TagName;
3005 if (TagKind == tok::kw_enum)
3006 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,
3007 DeclSpecContext::DSC_normal);
3009 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
3011 DeclSpecContext::DSC_normal, Attrs);
3018 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
3019 DSC == DeclSpecContext::DSC_class)) {
3023 case tok::l_paren: {
3030 TentativeParsingAction PA(*
this);
3032 TPResult TPR = TryParseDeclarator(
false);
3035 if (TPR != TPResult::False) {
3043 if (DSC == DeclSpecContext::DSC_class ||
3044 (DSC == DeclSpecContext::DSC_top_level && SS)) {
3047 Diag(Loc, diag::err_constructor_bad_name)
3068 AnnotateScopeToken(*SS,
false);
3090 const char *PrevSpec;
3111 if (IsTemplateName) {
3113 TemplateArgList Args;
3114 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3128Parser::DeclSpecContext
3132 return DeclSpecContext::DSC_class;
3134 return DeclSpecContext::DSC_top_level;
3136 return DeclSpecContext::DSC_template_param;
3138 return DeclSpecContext::DSC_template_arg;
3140 return DeclSpecContext::DSC_template_type_arg;
3143 return DeclSpecContext::DSC_trailing;
3146 return DeclSpecContext::DSC_alias_declaration;
3148 return DeclSpecContext::DSC_association;
3150 return DeclSpecContext::DSC_type_specifier;
3152 return DeclSpecContext::DSC_condition;
3154 return DeclSpecContext::DSC_conv_operator;
3156 return DeclSpecContext::DSC_new;
3171 return DeclSpecContext::DSC_normal;
3174 llvm_unreachable(
"Missing DeclaratorContext case");
3187 if (isTypeIdInParens()) {
3216 assert(Tok.
isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3217 "Not an alignment-specifier!");
3224 if (T.expectAndConsume())
3231 ParseAlignArgument(PP.
getSpelling(KWTok), T.getOpenLocation(),
3240 *EndLoc = T.getCloseLocation();
3247 ArgExprs.push_back(ArgExpr.
get());
3248 Attrs.
addNew(KWName, KWLoc,
nullptr, KWLoc, ArgExprs.data(), 1, Kind,
3253ExprResult Parser::ParseExtIntegerArgument() {
3254 assert(Tok.
isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3255 "Not an extended int type");
3259 if (T.expectAndConsume())
3268 if(T.consumeClose())
3282 DeclSpecContext DSContext,
3283 LateParsedAttrList *LateAttrs) {
3286 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3287 DSContext == DeclSpecContext::DSC_top_level);
3290 Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
3291 tok::annot_template_id) &&
3297 bool HasScope = Tok.
is(tok::annot_cxxscope);
3303 bool MightBeDeclarator =
true;
3304 if (Tok.
isOneOf(tok::kw_typename, tok::annot_typename)) {
3306 MightBeDeclarator =
false;
3307 }
else if (AfterScope.
is(tok::annot_template_id)) {
3313 MightBeDeclarator =
false;
3314 }
else if (AfterScope.
is(tok::identifier)) {
3315 const Token &Next = HasScope ? GetLookAheadToken(2) :
NextToken();
3319 if (Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3320 tok::annot_cxxscope, tok::coloncolon)) {
3322 MightBeDeclarator =
false;
3323 }
else if (HasScope) {
3334 switch (Classification.
getKind()) {
3340 llvm_unreachable(
"typo correction is not possible here");
3347 MightBeDeclarator =
false;
3363 if (MightBeDeclarator)
3368 diag::err_expected_after)
3379 ParsedTemplateInfo NotATemplate;
3380 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3411void Parser::ParseDeclarationSpecifiers(
3413 DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
3425 if (DSContext == DeclSpecContext::DSC_conv_operator) {
3428 DSContext = DeclSpecContext::DSC_type_specifier;
3431 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3432 DSContext == DeclSpecContext::DSC_top_level);
3433 bool AttrsLastTime =
false;
3439 bool isStorageClass =
false;
3440 const char *PrevSpec =
nullptr;
3441 unsigned DiagID = 0;
3462 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3476 bool IsTemplateSpecOrInst =
3477 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3478 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3487 ProhibitAttributes(attrs);
3491 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3492 !PA.isRegularKeywordAttribute())
3500 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3501 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3508 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3509 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3511 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3512 << PA << PA.isRegularKeywordAttribute();
3521 DS.
Finish(Actions, Policy);
3525 case tok::kw__Alignas:
3526 diagnoseUseOfC11Keyword(Tok);
3528 case tok::kw_alignas:
3534 if (Tok.
getKind() == tok::kw_alignas)
3535 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
3541 if (!isAllowedCXX11AttributeSpecifier())
3542 goto DoneWithDeclSpec;
3545 ProhibitAttributes(attrs);
3552 ParseCXX11Attributes(attrs);
3553 AttrsLastTime =
true;
3556 case tok::code_completion: {
3559 bool AllowNonIdentifiers
3565 bool AllowNestedNameSpecifiers
3566 = DSContext == DeclSpecContext::DSC_top_level ||
3571 AllowNonIdentifiers,
3572 AllowNestedNameSpecifiers);
3577 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
3580 else if (DSContext == DeclSpecContext::DSC_class)
3584 else if (CurParsedObjCImpl)
3592 case tok::coloncolon:
3598 goto DoneWithDeclSpec;
3600 if (Tok.
is(tok::coloncolon))
3601 goto DoneWithDeclSpec;
3604 case tok::annot_cxxscope: {
3606 goto DoneWithDeclSpec;
3609 if (TemplateInfo.TemplateParams)
3619 ? takeTemplateIdAnnotation(Next)
3625 ConsumeAnnotationToken();
3639 if ((DSContext == DeclSpecContext::DSC_top_level ||
3640 DSContext == DeclSpecContext::DSC_class) &&
3643 isConstructorDeclarator(
false,
3650 goto DoneWithDeclSpec;
3654 ConsumeAnnotationToken();
3655 assert(Tok.
is(tok::annot_template_id) &&
3656 "ParseOptionalCXXScopeSpecifier not working");
3657 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3667 ConsumeAnnotationToken();
3671 if (Next.is(tok::annot_typename)) {
3673 ConsumeAnnotationToken();
3677 PrevSpec, DiagID, T, Policy);
3681 ConsumeAnnotationToken();
3685 Next.is(tok::annot_template_id) &&
3689 ConsumeAnnotationToken();
3690 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3694 if (Next.isNot(tok::identifier))
3695 goto DoneWithDeclSpec;
3700 if ((DSContext == DeclSpecContext::DSC_top_level ||
3701 DSContext == DeclSpecContext::DSC_class) &&
3704 isConstructorDeclarator(
false,
3708 goto DoneWithDeclSpec;
3717 *Next.getIdentifierInfo(), Next.getLocation(),
getCurScope(), &SS,
3718 false,
false,
nullptr,
3721 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3723 if (IsTemplateSpecOrInst)
3731 if (TryAnnotateTypeConstraint())
3732 goto DoneWithDeclSpec;
3733 if (Tok.
isNot(tok::annot_cxxscope) ||
3737 ConsumeAnnotationToken();
3739 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3740 if (!Attrs.
empty()) {
3741 AttrsLastTime =
true;
3742 attrs.takeAllFrom(Attrs);
3746 goto DoneWithDeclSpec;
3750 ConsumeAnnotationToken();
3753 DiagID, TypeRep, Policy);
3763 case tok::annot_typename: {
3767 goto DoneWithDeclSpec;
3776 ConsumeAnnotationToken();
3781 case tok::kw___is_signed:
3792 TryKeywordIdentFallback(
true);
3795 goto DoneWithDeclSpec;
3798 case tok::kw___super:
3799 case tok::kw_decltype:
3800 case tok::identifier:
3806 goto DoneWithDeclSpec;
3812 if (!
getLangOpts().DeclSpecKeyword && Tok.
is(tok::identifier) &&
3814 Diag(Loc, diag::err_ms_attributes_not_enabled);
3824 if (T.consumeOpen()) {
3825 assert(
false &&
"Not a left paren?");
3844 if (IsTemplateSpecOrInst)
3848 if (IsTemplateSpecOrInst)
3851 goto DoneWithDeclSpec;
3854 if (!Tok.
is(tok::identifier))
3859 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID,
isInvalid))
3865 goto DoneWithDeclSpec;
3867 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3868 isObjCInstancetype()) {
3872 DiagID, TypeRep, Policy);
3885 isConstructorDeclarator(
true,
3888 goto DoneWithDeclSpec;
3892 false,
false,
nullptr,
false,
false,
3893 isClassTemplateDeductionContext(DSContext));
3898 if (TryAnnotateTypeConstraint())
3899 goto DoneWithDeclSpec;
3900 if (Tok.
isNot(tok::identifier))
3903 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
3904 if (!Attrs.
empty()) {
3905 AttrsLastTime =
true;
3906 attrs.takeAllFrom(Attrs);
3910 goto DoneWithDeclSpec;
3917 (DSContext == DeclSpecContext::DSC_class ||
3918 DSContext == DeclSpecContext::DSC_top_level) &&
3921 isConstructorDeclarator(
true,
3923 goto DoneWithDeclSpec;
3926 DiagID, TypeRep, Policy);
3938 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3953 case tok::annot_template_id: {
3965 TemplateId =
nullptr;
3973 tok::kw_volatile, tok::kw_restrict, tok::amp,
3975 Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
3979 TemplateId, Policy);
3983 goto DoneWithDeclSpec;
3986 TemplateId =
nullptr;
3988 ConsumeAnnotationToken();
3992 if (Tracker.consumeOpen()) {
3994 Diag(Tok, diag::err_expected) << tok::l_paren;
3998 Tracker.skipToEnd();
3999 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
4004 Tracker.consumeClose();
4012 DiagID, TemplateId, Policy);
4015 TemplateId, Policy);
4024 goto DoneWithDeclSpec;
4032 isConstructorDeclarator(
true,
4035 goto DoneWithDeclSpec;
4040 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
4045 case tok::kw___attribute:
4046 case tok::kw___declspec:
4047 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4051 case tok::kw___forceinline: {
4056 nullptr, 0, tok::kw___forceinline);
4060 case tok::kw___unaligned:
4065 case tok::kw___sptr:
4066 case tok::kw___uptr:
4067 case tok::kw___ptr64:
4068 case tok::kw___ptr32:
4070 case tok::kw___cdecl:
4071 case tok::kw___stdcall:
4072 case tok::kw___fastcall:
4073 case tok::kw___thiscall:
4074 case tok::kw___regcall:
4075 case tok::kw___vectorcall:
4079 case tok::kw___funcref:
4084 case tok::kw___pascal:
4089 case tok::kw___kernel:
4094 case tok::kw___noinline__:
4099 case tok::kw__Nonnull:
4100 case tok::kw__Nullable:
4101 case tok::kw__Nullable_result:
4102 case tok::kw__Null_unspecified:
4107 case tok::kw___kindof:
4109 nullptr, 0, tok::kw___kindof);
4114 case tok::kw_typedef:
4116 PrevSpec, DiagID, Policy);
4117 isStorageClass =
true;
4119 case tok::kw_extern:
4121 Diag(Tok, diag::ext_thread_before) <<
"extern";
4123 PrevSpec, DiagID, Policy);
4124 isStorageClass =
true;
4126 case tok::kw___private_extern__:
4128 Loc, PrevSpec, DiagID, Policy);
4129 isStorageClass =
true;
4131 case tok::kw_static:
4133 Diag(Tok, diag::ext_thread_before) <<
"static";
4135 PrevSpec, DiagID, Policy);
4136 isStorageClass =
true;
4140 if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
4142 PrevSpec, DiagID, Policy);
4144 Diag(Tok, diag::ext_auto_storage_class)
4151 PrevSpec, DiagID, Policy);
4152 isStorageClass =
true;
4154 case tok::kw___auto_type:
4155 Diag(Tok, diag::ext_auto_type);
4159 case tok::kw_register:
4161 PrevSpec, DiagID, Policy);
4162 isStorageClass =
true;
4164 case tok::kw_mutable:
4166 PrevSpec, DiagID, Policy);
4167 isStorageClass =
true;
4169 case tok::kw___thread:
4172 isStorageClass =
true;
4174 case tok::kw_thread_local:
4176 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4185 Loc, PrevSpec, DiagID);
4186 isStorageClass =
true;
4188 case tok::kw__Thread_local:
4189 diagnoseUseOfC11Keyword(Tok);
4191 Loc, PrevSpec, DiagID);
4192 isStorageClass =
true;
4196 case tok::kw_inline:
4199 case tok::kw_virtual:
4203 !
getActions().getOpenCLOptions().isAvailableOption(
4205 DiagID = diag::err_openclcxx_virtual_function;
4212 case tok::kw_explicit: {
4216 ConsumedEnd = ExplicitLoc;
4218 if (Tok.
is(tok::l_paren)) {
4221 ? diag::warn_cxx17_compat_explicit_bool
4222 : diag::ext_explicit_bool);
4226 Tracker.consumeOpen();
4233 if (ExplicitExpr.isUsable()) {
4235 Tracker.consumeClose();
4239 Tracker.skipToEnd();
4245 ExplicitSpec, CloseParenLoc);
4248 case tok::kw__Noreturn:
4249 diagnoseUseOfC11Keyword(Tok);
4254 case tok::kw_friend:
4255 if (DSContext == DeclSpecContext::DSC_class)
4259 DiagID = diag::err_friend_invalid_in_context;
4265 case tok::kw___module_private__:
4270 case tok::kw_constexpr:
4272 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4276 case tok::kw_consteval:
4280 case tok::kw_constinit:
4296 PrevSpec, DiagID, Policy);
4298 case tok::kw___int64:
4300 PrevSpec, DiagID, Policy);
4302 case tok::kw_signed:
4306 case tok::kw_unsigned:
4310 case tok::kw__Complex:
4312 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4316 case tok::kw__Imaginary:
4318 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4334 case tok::kw__ExtInt:
4335 case tok::kw__BitInt: {
4336 DiagnoseBitIntUse(Tok);
4341 ConsumedEnd = PrevTokLocation;
4344 case tok::kw___int128:
4352 case tok::kw___bf16:
4360 case tok::kw_double:
4364 case tok::kw__Float16:
4368 case tok::kw__Accum:
4370 "This keyword is only used when fixed point types are enabled "
4371 "with `-ffixed-point`");
4375 case tok::kw__Fract:
4377 "This keyword is only used when fixed point types are enabled "
4378 "with `-ffixed-point`");
4384 "This keyword is only used when fixed point types are enabled "
4385 "with `-ffixed-point`");
4388 case tok::kw___float128:
4392 case tok::kw___ibm128:
4396 case tok::kw_wchar_t:
4400 case tok::kw_char8_t:
4404 case tok::kw_char16_t:
4408 case tok::kw_char32_t:
4414 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4418 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4420 if (Tok.
is(tok::kw_bool) &&
4424 DiagID = diag::err_bool_redeclaration;
4433 case tok::kw__Decimal32:
4437 case tok::kw__Decimal64:
4441 case tok::kw__Decimal128:
4445 case tok::kw___vector:
4448 case tok::kw___pixel:
4451 case tok::kw___bool:
4456 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4461 goto DoneWithDeclSpec;
4463 DiagID = diag::err_opencl_unknown_type_specifier;
4470#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4471#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4472#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4473 case tok::kw_##ImgType##_t: \
4474 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4475 goto DoneWithDeclSpec; \
4477#include "clang/Basic/OpenCLImageTypes.def"
4478 case tok::kw___unknown_anytype:
4480 PrevSpec, DiagID, Policy);
4485 case tok::kw_struct:
4486 case tok::kw___interface:
4487 case tok::kw_union: {
4495 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
4496 EnteringContext, DSContext, Attributes);
4500 if (!Attributes.empty()) {
4501 AttrsLastTime =
true;
4502 attrs.takeAllFrom(Attributes);
4510 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
4518 case tok::kw_volatile:
4522 case tok::kw_restrict:
4528 case tok::kw_typename:
4531 goto DoneWithDeclSpec;
4533 if (!Tok.
is(tok::kw_typename))
4538 case tok::kw_typeof:
4539 case tok::kw_typeof_unqual:
4540 ParseTypeofSpecifier(DS);
4543 case tok::annot_decltype:
4544 ParseDecltypeSpecifier(DS);
4547 case tok::annot_pack_indexing_type:
4548 ParsePackIndexingType(DS);
4551 case tok::annot_pragma_pack:
4555 case tok::annot_pragma_ms_pragma:
4556 HandlePragmaMSPragma();
4559 case tok::annot_pragma_ms_vtordisp:
4560 HandlePragmaMSVtorDisp();
4563 case tok::annot_pragma_ms_pointers_to_members:
4564 HandlePragmaMSPointersToMembers();
4567#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4568#include "clang/Basic/TransformTypeTraits.def"
4572 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4573 goto ParseIdentifier;
4576 case tok::kw__Atomic:
4581 diagnoseUseOfC11Keyword(Tok);
4583 ParseAtomicSpecifier(DS);
4591 case tok::kw___generic:
4596 if (!Actions.
getLangOpts().OpenCLGenericAddressSpace) {
4597 DiagID = diag::err_opencl_unknown_type_specifier;
4603 case tok::kw_private:
4607 goto DoneWithDeclSpec;
4609 case tok::kw___private:
4610 case tok::kw___global:
4611 case tok::kw___local:
4612 case tok::kw___constant:
4614 case tok::kw___read_only:
4615 case tok::kw___write_only:
4616 case tok::kw___read_write:
4620 case tok::kw_groupshared:
4633 goto DoneWithDeclSpec;
4638 if (
Type.isUsable()) {
4640 PrevSpec, DiagID,
Type.get(),
4642 Diag(StartLoc, DiagID) << PrevSpec;
4658 assert(PrevSpec &&
"Method did not return previous specifier!");
4661 if (DiagID == diag::ext_duplicate_declspec ||
4662 DiagID == diag::ext_warn_duplicate_declspec ||
4663 DiagID == diag::err_duplicate_declspec)
4664 Diag(Loc, DiagID) << PrevSpec
4667 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4671 Diag(Loc, DiagID) << PrevSpec;
4674 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4678 AttrsLastTime =
false;
4703void Parser::ParseStructDeclaration(
4707 if (Tok.
is(tok::kw___extension__)) {
4711 return ParseStructDeclaration(DS, FieldsCallback);
4716 MaybeParseCXX11Attributes(Attrs);
4719 ParseSpecifierQualifierList(DS);
4723 if (Tok.
is(tok::semi)) {
4728 ProhibitAttributes(Attrs);
4732 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4738 bool FirstDeclarator =
true;
4742 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4745 if (!FirstDeclarator) {
4748 DiagnoseAndSkipCXX11Attributes();
4749 MaybeParseGNUAttributes(DeclaratorInfo.D);
4750 DiagnoseAndSkipCXX11Attributes();
4755 if (Tok.
isNot(tok::colon)) {
4758 ParseDeclarator(DeclaratorInfo.D);
4760 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.
getLocation());
4767 DeclaratorInfo.BitfieldSize = Res.
get();
4771 MaybeParseGNUAttributes(DeclaratorInfo.D);
4774 FieldsCallback(DeclaratorInfo);
4781 FirstDeclarator =
false;
4798 "parsing struct/union body");
4802 if (T.consumeOpen())
4809 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
4810 Tok.
isNot(tok::eof)) {
4814 if (Tok.
is(tok::semi)) {
4815 ConsumeExtraSemi(InsideStruct,
TagType);
4820 if (Tok.
isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4822 ParseStaticAssertDeclaration(DeclEnd);
4826 if (Tok.
is(tok::annot_pragma_pack)) {
4831 if (Tok.
is(tok::annot_pragma_align)) {
4832 HandlePragmaAlign();
4836 if (Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4840 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4844 if (Tok.
is(tok::annot_pragma_openacc)) {
4853 ConsumeAnnotationToken();
4857 if (!Tok.
is(tok::at)) {
4863 FD.D, FD.BitfieldSize);
4869 ParseStructDeclaration(DS, CFieldCallback);
4873 Diag(Tok, diag::err_unexpected_at);
4878 ExpectAndConsume(tok::l_paren);
4879 if (!Tok.
is(tok::identifier)) {
4880 Diag(Tok, diag::err_expected) << tok::identifier;
4888 ExpectAndConsume(tok::r_paren);
4894 if (Tok.
is(tok::r_brace)) {
4895 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
4899 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
4910 MaybeParseGNUAttributes(attrs);
4915 T.getOpenLocation(), T.getCloseLocation(), attrs);
4951 const ParsedTemplateInfo &TemplateInfo,
4954 if (Tok.
is(tok::code_completion)) {
4964 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
4967 bool IsScopedUsingClassTag =
false;
4972 : diag::ext_scoped_enum);
4973 IsScopedUsingClassTag = Tok.
is(tok::kw_class);
4978 ProhibitAttributes(attrs);
4981 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
4990 bool shouldDelayDiagsInTag =
4991 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
4992 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
4996 AllowDefiningTypeSpec AllowEnumSpecifier =
4998 bool CanBeOpaqueEnumDeclaration =
4999 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5002 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5003 CanBeOpaqueEnumDeclaration);
5011 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5016 if (Spec.
isSet() && Tok.
isNot(tok::identifier)) {
5017 Diag(Tok, diag::err_expected) << tok::identifier;
5019 if (Tok.
isNot(tok::l_brace)) {
5031 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::l_brace) &&
5032 Tok.
isNot(tok::colon)) {
5033 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5044 if (Tok.
is(tok::identifier)) {
5049 if (!Name && ScopedEnumKWLoc.
isValid()) {
5052 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5054 IsScopedUsingClassTag =
false;
5059 if (shouldDelayDiagsInTag)
5060 diagsFromTag.done();
5065 bool CanBeBitfield =
5069 if (Tok.
is(tok::colon)) {
5094 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5099 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5110 DeclSpecContext::DSC_type_specifier);
5115 BaseRange =
SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5119 Diag(ColonLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type)
5122 Diag(ColonLoc, diag::ext_cxx11_enum_fixed_underlying_type)
5125 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5128 Diag(ColonLoc, diag::ext_clang_c_enum_fixed_underlying_type)
5145 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5147 else if (Tok.
is(tok::l_brace)) {
5156 IsScopedUsingClassTag =
false;
5162 }
else if (!isTypeSpecifier(DSC) &&
5163 (Tok.
is(tok::semi) ||
5165 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5170 if (Tok.
isNot(tok::semi)) {
5172 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5180 bool IsElaboratedTypeSpecifier =
5186 diagsFromTag.redelay();
5190 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
5194 Diag(Tok, diag::err_enum_template);
5199 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
5202 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5206 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5208 TemplateInfo.TemplateParams->size());
5213 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5229 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5231 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5232 diag::err_keyword_not_allowed,
5235 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5236 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5237 else if (ScopedEnumKWLoc.
isValid())
5238 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5242 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5252 bool IsDependent =
false;
5253 const char *PrevSpec =
nullptr;
5258 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5259 IsScopedUsingClassTag,
5260 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5261 DSC == DeclSpecContext::DSC_template_param ||
5262 DSC == DeclSpecContext::DSC_template_type_arg,
5263 OffsetOfState, &SkipBody).
get();
5273 NameLoc.
isValid() ? NameLoc : StartLoc,
5274 PrevSpec, DiagID,
TagDecl, Owned,
5276 Diag(StartLoc, DiagID) << PrevSpec;
5285 Diag(Tok, diag::err_expected_type_name_after_typename);
5291 if (
Type.isInvalid()) {
5297 NameLoc.
isValid() ? NameLoc : StartLoc,
5298 PrevSpec, DiagID,
Type.get(),
5300 Diag(StartLoc, DiagID) << PrevSpec;
5319 ParseEnumBody(StartLoc, D);
5328 NameLoc.
isValid() ? NameLoc : StartLoc,
5329 PrevSpec, DiagID,
TagDecl, Owned,
5331 Diag(StartLoc, DiagID) << PrevSpec;
5354 Diag(Tok, diag::err_empty_enum);
5359 Decl *LastEnumConstDecl =
nullptr;
5362 while (Tok.
isNot(tok::r_brace)) {
5365 if (Tok.
isNot(tok::identifier)) {
5377 MaybeParseGNUAttributes(attrs);
5378 if (isAllowedCXX11AttributeSpecifier()) {
5381 ? diag::warn_cxx14_compat_ns_enum_attribute
5382 : diag::ext_ns_enum_attribute)
5384 ParseCXX11Attributes(attrs);
5389 EnumAvailabilityDiags.emplace_back(*
this);
5402 EqualLoc, AssignedVal.
get());
5403 EnumAvailabilityDiags.back().done();
5405 EnumConstantDecls.push_back(EnumConstDecl);
5406 LastEnumConstDecl = EnumConstDecl;
5408 if (Tok.
is(tok::identifier)) {
5411 Diag(Loc, diag::err_enumerator_list_missing_comma)
5434 if (Tok.
is(tok::r_brace) && CommaLoc.
isValid()) {
5437 diag::ext_enumerator_list_comma_cxx :
5438 diag::ext_enumerator_list_comma_c)
5441 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5452 MaybeParseGNUAttributes(attrs);
5458 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5459 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5461 EnumAvailabilityDiags[i].redelay();
5462 PD.complete(EnumConstantDecls[i]);
5471 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5472 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5484bool Parser::isKnownToBeTypeSpecifier(
const Token &Tok)
const {
5486 default:
return false;
5490 case tok::kw___int64:
5491 case tok::kw___int128:
5492 case tok::kw_signed:
5493 case tok::kw_unsigned:
5494 case tok::kw__Complex:
5495 case tok::kw__Imaginary:
5498 case tok::kw_wchar_t:
5499 case tok::kw_char8_t:
5500 case tok::kw_char16_t:
5501 case tok::kw_char32_t:
5503 case tok::kw__ExtInt:
5504 case tok::kw__BitInt:
5505 case tok::kw___bf16:
5508 case tok::kw_double:
5509 case tok::kw__Accum:
5510 case tok::kw__Fract:
5511 case tok::kw__Float16:
5512 case tok::kw___float128:
5513 case tok::kw___ibm128:
5516 case tok::kw__Decimal32:
5517 case tok::kw__Decimal64:
5518 case tok::kw__Decimal128:
5519 case tok::kw___vector:
5520#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5521#include "clang/Basic/OpenCLImageTypes.def"
5525 case tok::kw_struct:
5526 case tok::kw___interface:
5532 case tok::annot_typename:
5539bool Parser::isTypeSpecifierQualifier() {
5541 default:
return false;
5543 case tok::identifier:
5544 if (TryAltiVecVectorToken())
5547 case tok::kw_typename:
5552 if (Tok.
is(tok::identifier))
5554 return isTypeSpecifierQualifier();
5556 case tok::coloncolon:
5563 return isTypeSpecifierQualifier();
5566 case tok::kw___attribute:
5568 case tok::kw_typeof:
5569 case tok::kw_typeof_unqual:
5574 case tok::kw___int64:
5575 case tok::kw___int128:
5576 case tok::kw_signed:
5577 case tok::kw_unsigned:
5578 case tok::kw__Complex:
5579 case tok::kw__Imaginary:
5582 case tok::kw_wchar_t:
5583 case tok::kw_char8_t:
5584 case tok::kw_char16_t:
5585 case tok::kw_char32_t:
5587 case tok::kw__ExtInt:
5588 case tok::kw__BitInt:
5590 case tok::kw___bf16:
5592 case tok::kw_double:
5593 case tok::kw__Accum:
5594 case tok::kw__Fract:
5595 case tok::kw__Float16:
5596 case tok::kw___float128:
5597 case tok::kw___ibm128:
5600 case tok::kw__Decimal32:
5601 case tok::kw__Decimal64:
5602 case tok::kw__Decimal128:
5603 case tok::kw___vector:
5604#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5605#include "clang/Basic/OpenCLImageTypes.def"
5609 case tok::kw_struct:
5610 case tok::kw___interface:
5617 case tok::kw_volatile:
5618 case tok::kw_restrict:
5622 case tok::kw___unknown_anytype:
5625 case tok::annot_typename:
5632 case tok::kw___cdecl:
5633 case tok::kw___stdcall:
5634 case tok::kw___fastcall:
5635 case tok::kw___thiscall:
5636 case tok::kw___regcall:
5637 case tok::kw___vectorcall:
5639 case tok::kw___ptr64:
5640 case tok::kw___ptr32:
5641 case tok::kw___pascal:
5642 case tok::kw___unaligned:
5644 case tok::kw__Nonnull:
5645 case tok::kw__Nullable:
5646 case tok::kw__Nullable_result:
5647 case tok::kw__Null_unspecified:
5649 case tok::kw___kindof:
5651 case tok::kw___private:
5652 case tok::kw___local:
5653 case tok::kw___global:
5654 case tok::kw___constant:
5655 case tok::kw___generic:
5656 case tok::kw___read_only:
5657 case tok::kw___read_write:
5658 case tok::kw___write_only:
5659 case tok::kw___funcref:
5662 case tok::kw_private:
5666 case tok::kw__Atomic:
5670 case tok::kw_groupshared:
5683 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5687 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5693 if (Tok.
is(tok::annot_repl_input_end) &&
5695 ConsumeAnnotationToken();
5700 DeclsInGroup.push_back(TLSD);
5703 for (
Stmt *S : Stmts) {
5708 DeclsInGroup.push_back(D);
5721bool Parser::isDeclarationSpecifier(
5723 bool DisambiguatingWithExpression) {
5725 default:
return false;
5732 case tok::identifier:
5736 if (TryAltiVecVectorToken())
5739 case tok::kw_decltype:
5740 case tok::kw_typename:
5745 if (TryAnnotateTypeConstraint())
5747 if (Tok.
is(tok::identifier))
5755 if (DisambiguatingWithExpression &&
5756 isStartOfObjCClassMessageMissingOpenBracket())
5759 return isDeclarationSpecifier(AllowImplicitTypename);
5761 case tok::coloncolon:
5775 case tok::kw_typedef:
5776 case tok::kw_extern:
5777 case tok::kw___private_extern__:
5778 case tok::kw_static:
5780 case tok::kw___auto_type:
5781 case tok::kw_register:
5782 case tok::kw___thread:
5783 case tok::kw_thread_local:
5784 case tok::kw__Thread_local:
5787 case tok::kw___module_private__:
5790 case tok::kw___unknown_anytype:
5795 case tok::kw___int64:
5796 case tok::kw___int128:
5797 case tok::kw_signed:
5798 case tok::kw_unsigned:
5799 case tok::kw__Complex:
5800 case tok::kw__Imaginary:
5803 case tok::kw_wchar_t:
5804 case tok::kw_char8_t:
5805 case tok::kw_char16_t:
5806 case tok::kw_char32_t:
5809 case tok::kw__ExtInt:
5810 case tok::kw__BitInt:
5812 case tok::kw___bf16:
5814 case tok::kw_double:
5815 case tok::kw__Accum:
5816 case tok::kw__Fract:
5817 case tok::kw__Float16:
5818 case tok::kw___float128:
5819 case tok::kw___ibm128:
5822 case tok::kw__Decimal32:
5823 case tok::kw__Decimal64:
5824 case tok::kw__Decimal128:
5825 case tok::kw___vector:
5829 case tok::kw_struct:
5831 case tok::kw___interface:
5837 case tok::kw_volatile:
5838 case tok::kw_restrict:
5842 case tok::kw_inline:
5843 case tok::kw_virtual:
5844 case tok::kw_explicit:
5845 case tok::kw__Noreturn:
5848 case tok::kw__Alignas:
5851 case tok::kw_friend:
5854 case tok::kw_static_assert:
5855 case tok::kw__Static_assert:
5858 case tok::kw_typeof:
5859 case tok::kw_typeof_unqual:
5862 case tok::kw___attribute:
5865 case tok::annot_decltype:
5866 case tok::annot_pack_indexing_type:
5867 case tok::kw_constexpr:
5870 case tok::kw_consteval:
5871 case tok::kw_constinit:
5874 case tok::kw__Atomic:
5877 case tok::kw_alignas:
5887 case tok::annot_typename:
5888 return !DisambiguatingWithExpression ||
5889 !isStartOfObjCClassMessageMissingOpenBracket();
5892 case tok::annot_template_id: {
5898 return isTypeConstraintAnnotation() &&
5902 case tok::annot_cxxscope: {
5911 if (
NextToken().is(tok::identifier) && TryAnnotateTypeConstraint())
5913 return isTypeConstraintAnnotation() &&
5914 GetLookAheadToken(2).isOneOf(tok::kw_auto, tok::kw_decltype);
5917 case tok::kw___declspec:
5918 case tok::kw___cdecl:
5919 case tok::kw___stdcall:
5920 case tok::kw___fastcall:
5921 case tok::kw___thiscall:
5922 case tok::kw___regcall:
5923 case tok::kw___vectorcall:
5925 case tok::kw___sptr:
5926 case tok::kw___uptr:
5927 case tok::kw___ptr64:
5928 case tok::kw___ptr32:
5929 case tok::kw___forceinline:
5930 case tok::kw___pascal:
5931 case tok::kw___unaligned:
5933 case tok::kw__Nonnull:
5934 case tok::kw__Nullable:
5935 case tok::kw__Nullable_result:
5936 case tok::kw__Null_unspecified:
5938 case tok::kw___kindof:
5940 case tok::kw___private:
5941 case tok::kw___local:
5942 case tok::kw___global:
5943 case tok::kw___constant:
5944 case tok::kw___generic:
5945 case tok::kw___read_only:
5946 case tok::kw___read_write:
5947 case tok::kw___write_only:
5948#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5949#include "clang/Basic/OpenCLImageTypes.def"
5951 case tok::kw___funcref:
5952 case tok::kw_groupshared:
5955 case tok::kw_private:
5960bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
5962 const ParsedTemplateInfo *TemplateInfo) {
5963 RevertingTentativeParsingAction TPA(*
this);
5966 if (TemplateInfo && TemplateInfo->TemplateParams)
5969 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
5976 if (Tok.
is(tok::identifier)) {
5980 }
else if (Tok.
is(tok::annot_template_id)) {
5981 ConsumeAnnotationToken();
5988 SkipCXX11Attributes();
5991 if (Tok.
isNot(tok::l_paren)) {
5998 if (Tok.
is(tok::r_paren) ||
5999 (Tok.
is(tok::ellipsis) &&
NextToken().is(tok::r_paren))) {
6006 isCXX11AttributeSpecifier(
false,
6012 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6014 DeclScopeObj.EnterDeclaratorScope();
6018 MaybeParseMicrosoftAttributes(Attrs);
6027 bool IsConstructor =
false;
6033 if (Tok.
is(tok::kw_this)) {
6035 return isDeclarationSpecifier(ITC);
6038 if (isDeclarationSpecifier(ITC))
6039 IsConstructor =
true;
6040 else if (Tok.
is(tok::identifier) ||
6041 (Tok.
is(tok::annot_cxxscope) &&
NextToken().is(tok::identifier))) {
6046 if (Tok.
is(tok::annot_cxxscope))
6047 ConsumeAnnotationToken();
6059 case tok::coloncolon:
6072 SkipCXX11Attributes();
6074 if (DeductionGuide) {
6076 IsConstructor = Tok.
is(tok::arrow);
6079 if (Tok.
is(tok::colon) || Tok.
is(tok::kw_try)) {
6083 IsConstructor =
true;
6085 if (Tok.
is(tok::semi) || Tok.
is(tok::l_brace)) {
6098 IsConstructor = IsUnqualified;
6103 IsConstructor =
true;
6107 return IsConstructor;
6122void Parser::ParseTypeQualifierListOpt(
6123 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicAllowed,
6124 bool IdentifierRequired,
6126 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6127 isAllowedCXX11AttributeSpecifier()) {
6129 ParseCXX11Attributes(Attrs);
6137 const char *PrevSpec =
nullptr;
6138 unsigned DiagID = 0;
6142 case tok::code_completion:
6145 (*CodeCompletionHandler)();
6154 case tok::kw_volatile:
6158 case tok::kw_restrict:
6162 case tok::kw__Atomic:
6164 goto DoneWithTypeQuals;
6165 diagnoseUseOfC11Keyword(Tok);
6171 case tok::kw_private:
6173 goto DoneWithTypeQuals;
6175 case tok::kw___private:
6176 case tok::kw___global:
6177 case tok::kw___local:
6178 case tok::kw___constant:
6179 case tok::kw___generic:
6180 case tok::kw___read_only:
6181 case tok::kw___write_only:
6182 case tok::kw___read_write:
6186 case tok::kw_groupshared:
6194 case tok::kw___unaligned:
6198 case tok::kw___uptr:
6203 if (TryKeywordIdentFallback(
false))
6207 case tok::kw___sptr:
6209 case tok::kw___ptr64:
6210 case tok::kw___ptr32:
6211 case tok::kw___cdecl:
6212 case tok::kw___stdcall:
6213 case tok::kw___fastcall:
6214 case tok::kw___thiscall:
6215 case tok::kw___regcall:
6216 case tok::kw___vectorcall:
6217 if (AttrReqs & AR_DeclspecAttributesParsed) {
6221 goto DoneWithTypeQuals;
6223 case tok::kw___funcref:
6226 goto DoneWithTypeQuals;
6228 case tok::kw___pascal:
6229 if (AttrReqs & AR_VendorAttributesParsed) {
6233 goto DoneWithTypeQuals;
6236 case tok::kw__Nonnull:
6237 case tok::kw__Nullable:
6238 case tok::kw__Nullable_result:
6239 case tok::kw__Null_unspecified:
6244 case tok::kw___kindof:
6246 nullptr, 0, tok::kw___kindof);
6250 case tok::kw___attribute:
6251 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6253 Diag(Tok, diag::err_attributes_not_allowed);
6257 if (AttrReqs & AR_GNUAttributesParsed ||
6258 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6276 assert(PrevSpec &&
"Method did not return previous specifier!");
6277 Diag(Tok, DiagID) << PrevSpec;
6288 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6294 if (Kind == tok::star || Kind == tok::caret)
6298 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6299 Lang.getOpenCLCompatibleVersion() >= 200)
6302 if (!Lang.CPlusPlus)
6305 if (Kind == tok::amp)
6313 if (Kind == tok::ampamp)
6324 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6356void Parser::ParseDeclaratorInternal(
Declarator &D,
6357 DirectDeclParseFunction DirectDeclParser) {
6365 (Tok.
is(tok::coloncolon) || Tok.
is(tok::kw_decltype) ||
6366 (Tok.
is(tok::identifier) &&
6368 Tok.
is(tok::annot_cxxscope))) {
6373 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6374 false, EnteringContext);
6377 if (Tok.
isNot(tok::star)) {
6382 AnnotateScopeToken(SS,
true);
6384 if (DirectDeclParser)
6385 (this->*DirectDeclParser)(D);
6390 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6391 CompoundToken::MemberPtr);
6397 ParseTypeQualifierListOpt(DS);
6402 ParseDeclaratorInternal(D, DirectDeclParser);
6419 ParseTypeQualifierListOpt(DS);
6428 if (DirectDeclParser)
6429 (this->*DirectDeclParser)(D);
6438 if (Kind == tok::star || Kind == tok::caret) {
6444 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6446 ? AR_GNUAttributesParsed
6447 : AR_GNUAttributesParsedAndRejected);
6453 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6454 if (Kind == tok::star)
6472 if (Kind == tok::ampamp)
6474 diag::warn_cxx98_compat_rvalue_reference :
6475 diag::ext_rvalue_reference);
6478 ParseTypeQualifierListOpt(DS);
6487 diag::err_invalid_reference_qualifier_application) <<
"const";
6490 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6494 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6499 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6506 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6509 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6584void Parser::ParseDirectDeclarator(
Declarator &D) {
6591 return ParseDecompositionDeclarator(D);
6605 ParseOptionalCXXScopeSpecifier(
6607 false, EnteringContext);
6626 DeclScopeObj.EnterDeclaratorScope();
6633 goto PastIdentifier;
6657 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6667 if (Tok.
isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6671 bool AllowConstructorName;
6672 bool AllowDeductionGuide;
6674 AllowConstructorName =
false;
6675 AllowDeductionGuide =
false;
6679 AllowDeductionGuide =
false;
6692 true, AllowConstructorName,
6693 AllowDeductionGuide, &TemplateKWLoc,
6706 DeclScopeObj.EnterDeclaratorScope();
6713 goto PastIdentifier;
6719 diag::err_expected_unqualified_id)
6722 goto PastIdentifier;
6726 "There's a C++-specific check for tok::identifier above");
6731 goto PastIdentifier;
6736 bool DiagnoseIdentifier =
false;
6740 DiagnoseIdentifier =
true;
6743 DiagnoseIdentifier =
6751 !isCXX11VirtSpecifier(Tok))
6753 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6754 if (DiagnoseIdentifier) {
6759 goto PastIdentifier;
6763 if (Tok.
is(tok::l_paren)) {
6768 RevertingTentativeParsingAction PA(*
this);
6773 goto PastIdentifier;
6780 ParseParenDeclarator(D);
6793 DeclScopeObj.EnterDeclaratorScope();
6804 diag::ext_abstract_pack_declarator_parens);
6806 if (Tok.
getKind() == tok::annot_pragma_parser_crash)
6808 if (Tok.
is(tok::l_square))
6809 return ParseMisplacedBracketDeclarator(D);
6817 diag::err_expected_member_name_or_semi_objcxx_keyword)
6824 goto PastIdentifier;
6827 diag::err_expected_member_name_or_semi)
6831 if (Tok.
getKind() == tok::TokenKind::kw_while) {
6832 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6834 if (Tok.
isOneOf(tok::period, tok::arrow))
6835 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.
is(tok::arrow);
6843 diag::err_expected_unqualified_id)
6848 diag::err_expected_either)
6849 << tok::identifier << tok::l_paren;
6858 "Haven't past the location of the identifier yet?");
6862 MaybeParseCXX11Attributes(D);
6865 if (Tok.
is(tok::l_paren)) {
6869 ParseScope PrototypeScope(
this,
6871 (IsFunctionDeclaration
6877 bool IsAmbiguous =
false;
6889 AllowImplicitTypename =
6897 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
6898 bool IsFunctionDecl =
6899 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
6900 TentativelyDeclaredIdentifiers.pop_back();
6901 if (!IsFunctionDecl)
6907 if (IsFunctionDeclaration)
6909 TemplateParameterDepth);
6910 ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
6911 if (IsFunctionDeclaration)
6913 PrototypeScope.Exit();
6914 }
else if (Tok.
is(tok::l_square)) {
6915 ParseBracketDeclarator(D);
6923 if (!T.consumeOpen())
6934 Diag(Tok, diag::err_requires_clause_inside_parens);
6948void Parser::ParseDecompositionDeclarator(
Declarator &D) {
6949 assert(Tok.
is(tok::l_square));
6955 if (!(
NextToken().is(tok::identifier) &&
6956 GetLookAheadToken(2).
isOneOf(tok::comma, tok::r_square)) &&
6958 GetLookAheadToken(2).
isOneOf(tok::equal, tok::l_brace)))
6959 return ParseMisplacedBracketDeclarator(D);
6965 while (Tok.
isNot(tok::r_square)) {
6967 if (Tok.
is(tok::comma))
6970 if (Tok.
is(tok::identifier)) {
6972 Diag(EndLoc, diag::err_expected)
6975 Diag(Tok, diag::err_expected_comma_or_rsquare);
6978 SkipUntil(tok::r_square, tok::comma, tok::identifier,
6980 if (Tok.
is(tok::comma))
6982 else if (Tok.
isNot(tok::identifier))
6987 if (Tok.
isNot(tok::identifier)) {
6988 Diag(Tok, diag::err_expected) << tok::identifier;
6996 if (Tok.
isNot(tok::r_square))
7009 T.getCloseLocation());
7025void Parser::ParseParenDeclarator(
Declarator &D) {
7029 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7042 bool RequiresArg =
false;
7043 if (Tok.
is(tok::kw___attribute)) {
7044 ParseGNUAttributes(attrs);
7052 ParseMicrosoftTypeAttributes(attrs);
7055 if (Tok.
is(tok::kw___pascal))
7056 ParseBorlandTypeAttributes(attrs);
7068 }
else if (Tok.
is(tok::r_paren) ||
7071 isDeclarationSpecifier(
7073 isCXX11AttributeSpecifier()) {
7091 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7096 std::move(attrs), T.getCloseLocation());
7102 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7115 ParseScope PrototypeScope(
this,
7119 ParseFunctionDeclarator(D, attrs, T,
false, RequiresArg);
7120 PrototypeScope.Exit();
7123void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7125 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7133 bool IsCXX11MemberFunction =
7141 if (!IsCXX11MemberFunction)
7161 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.
CurContext), Q,
7162 IsCXX11MemberFunction);
7185void Parser::ParseFunctionDeclarator(
Declarator &D,
7190 assert(
getCurScope()->isFunctionPrototypeScope() &&
7191 "Should call from a Function scope");
7197 bool HasProto =
false;
7204 bool RefQualifierIsLValueRef =
true;
7222 StartLoc = LParenLoc;
7224 if (isFunctionDeclaratorIdentifierList()) {
7226 Diag(Tok, diag::err_argument_required_after_attribute);
7228 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7232 LocalEndLoc = RParenLoc;
7237 MaybeParseCXX11Attributes(FnAttrs);
7238 ProhibitAttributes(FnAttrs);
7240 if (Tok.
isNot(tok::r_paren))
7241 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7242 else if (RequiresArg)
7243 Diag(Tok, diag::err_argument_required_after_attribute);
7254 LocalEndLoc = RParenLoc;
7263 ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed,
7266 llvm::function_ref<
void()>([&]() {
7274 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7275 EndLoc = RefQualifierLoc;
7277 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7278 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7288 GetLookAheadToken(0).is(tok::kw_noexcept) &&
7289 GetLookAheadToken(1).is(tok::l_paren) &&
7290 GetLookAheadToken(2).is(tok::kw_noexcept) &&
7291 GetLookAheadToken(3).is(tok::l_paren) &&
7292 GetLookAheadToken(4).is(tok::identifier) &&
7293 GetLookAheadToken(4).getIdentifierInfo()->isStr(
"swap")) {
7304 ESpecType = tryParseExceptionSpecification(Delayed,
7307 DynamicExceptionRanges,
7309 ExceptionSpecTokens);
7311 EndLoc = ESpecRange.
getEnd();
7315 MaybeParseCXX11Attributes(FnAttrs);
7318 LocalEndLoc = EndLoc;
7320 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7325 TrailingReturnType =
7327 TrailingReturnTypeLoc =
Range.getBegin();
7328 EndLoc =
Range.getEnd();
7331 MaybeParseCXX11Attributes(FnAttrs);
7343 if (!ND || isa<ParmVarDecl>(ND))
7345 DeclsInPrototype.push_back(ND);
7352 llvm::sort(DeclsInPrototype, [](
Decl *D1,
Decl *D2) {
7360 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7361 ParamInfo.size(), EllipsisLoc, RParenLoc,
7362 RefQualifierIsLValueRef, RefQualifierLoc,
7364 ESpecType, ESpecRange, DynamicExceptions.data(),
7365 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7366 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7367 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7368 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7370 std::move(FnAttrs), EndLoc);
7375bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7377 if (Tok.
isOneOf(tok::amp, tok::ampamp)) {
7379 diag::warn_cxx98_compat_ref_qualifier :
7380 diag::ext_ref_qualifier);
7382 RefQualifierIsLValueRef = Tok.
is(tok::amp);
7394bool Parser::isFunctionDeclaratorIdentifierList() {
7396 && Tok.
is(tok::identifier)
7397 && !TryAltiVecVectorToken()
7413 && (!Tok.
is(tok::eof) &&
7426void Parser::ParseFunctionDeclaratorIdentifierList(
7430 assert(!
getLangOpts().requiresStrictPrototypes() &&
7431 "Cannot parse an identifier list in C23 or C++");
7438 Diag(Tok, diag::ext_ident_list_in_param);
7441 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
7445 if (Tok.
isNot(tok::identifier)) {
7446 Diag(Tok, diag::err_expected) << tok::identifier;
7457 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7460 if (!ParamsSoFar.insert(ParmII).second) {
7461 Diag(Tok, diag::err_param_redefinition) << ParmII;
7507void Parser::ParseParameterDeclarationClause(
7516 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7537 IsACXXFunctionDeclaration) {
7559 ArgDeclSpecAttrs.takeAllFrom(FirstArgAttrs);
7562 MaybeParseCXX11Attributes(ArgDeclAttrs);
7565 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7576 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(),
7577 AS_none, DeclSpecContext::DSC_normal,
7578 nullptr, AllowImplicitTypename);
7591 ParseDeclarator(ParmDeclarator);
7594 ParmDeclarator.SetRangeBegin(ThisLoc);
7597 MaybeParseGNUAttributes(ParmDeclarator);
7601 if (Tok.
is(tok::kw_requires)) {
7606 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7617 std::unique_ptr<CachedTokens> DefArgToks;
7621 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7622 ParmDeclarator.getNumTypeObjects() == 0) {
7624 Diag(DSStart, diag::err_missing_param);
7631 if (Tok.
is(tok::ellipsis) &&
7633 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7636 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7655 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7671 if (Tok.
is(tok::equal)) {
7682 ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument);
7698 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7699 DefArgResult = ParseBraceInitializer();
7701 if (Tok.
is(tok::l_paren) &&
NextToken().is(tok::l_brace)) {
7702 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7719 DefArgResult.
get());
7725 ParmDeclarator.getIdentifierLoc(),
7726 Param, std::move(DefArgToks)));
7733 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7735 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7740 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7741 << ParmEllipsis.
isValid() << ParmEllipsis;
7744 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7746 Diag(ParmDeclarator.getIdentifierLoc(),
7747 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7750 << !ParmDeclarator.hasName();
7752 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7771void Parser::ParseBracketDeclarator(
Declarator &D) {
7772 if (CheckProhibitedCXX11Attribute())
7780 if (Tok.
getKind() == tok::r_square) {
7783 MaybeParseCXX11Attributes(attrs);
7787 T.getOpenLocation(),
7788 T.getCloseLocation()),
7789 std::move(attrs), T.getCloseLocation());
7791 }
else if (Tok.
getKind() == tok::numeric_constant &&
7792 GetLookAheadToken(1).is(tok::r_square)) {
7799 MaybeParseCXX11Attributes(attrs);
7803 T.getOpenLocation(),
7804 T.getCloseLocation()),
7805 std::move(attrs), T.getCloseLocation());
7807 }
else if (Tok.
getKind() == tok::code_completion) {
7820 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
7828 bool isStar =
false;
7835 if (Tok.
is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
7839 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7843 }
else if (Tok.
isNot(tok::r_square)) {
7861 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7881 isStar, NumElements.
get(), T.getOpenLocation(),
7882 T.getCloseLocation()),
7887void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
7888 assert(Tok.
is(tok::l_square) &&
"Missing opening bracket");
7895 while (Tok.
is(tok::l_square)) {
7896 ParseBracketDeclarator(TempDeclarator);
7902 if (Tok.
is(tok::semi))
7908 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7913 if (TempDeclarator.getNumTypeObjects() == 0)
7917 bool NeedParens =
false;
7942 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
7955 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
7959 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7967 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7987void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
7988 assert(Tok.
isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
7989 "Not a typeof specifier");
7991 bool IsUnqual = Tok.
is(tok::kw_typeof_unqual);
7998 bool HasParens = Tok.
is(tok::l_paren);
8008 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange));
8024 const char *PrevSpec =
nullptr;
8032 Diag(StartLoc, DiagID) << PrevSpec;
8049 const char *PrevSpec =
nullptr;
8057 Diag(StartLoc, DiagID) << PrevSpec;
8063void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
8064 assert(Tok.
is(tok::kw__Atomic) &&
NextToken().is(tok::l_paren) &&
8065 "Not an atomic specifier");
8069 if (T.consumeOpen())
8073 if (
Result.isInvalid()) {
8087 const char *PrevSpec =
nullptr;
8092 Diag(StartLoc, DiagID) << PrevSpec;
8097bool Parser::TryAltiVecVectorTokenOutOfLine() {
8099 switch (Next.getKind()) {
8100 default:
return false;
8103 case tok::kw_signed:
8104 case tok::kw_unsigned:
8109 case tok::kw_double:
8112 case tok::kw___bool:
8113 case tok::kw___pixel:
8114 Tok.
setKind(tok::kw___vector);
8116 case tok::identifier:
8117 if (Next.getIdentifierInfo() == Ident_pixel) {
8118 Tok.
setKind(tok::kw___vector);
8121 if (Next.getIdentifierInfo() == Ident_bool ||
8122 Next.getIdentifierInfo() == Ident_Bool) {
8123 Tok.
setKind(tok::kw___vector);
8131 const char *&PrevSpec,
unsigned &DiagID,
8136 switch (Next.getKind()) {
8139 case tok::kw_signed:
8140 case tok::kw_unsigned:
8145 case tok::kw_double:
8148 case tok::kw___bool:
8149 case tok::kw___pixel:
8152 case tok::identifier:
8153 if (Next.getIdentifierInfo() == Ident_pixel) {
8157 if (Next.getIdentifierInfo() == Ident_bool ||
8158 Next.getIdentifierInfo() == Ident_Bool) {
8179TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8186 FileID FID = SourceMgr.createFileID(
8187 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8191 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8192 L.setParsingPreprocessorDirective(
true);
8198 Tokens.push_back(Tok);
8199 }
while (Tok.
isNot(tok::eod));
8204 Token &EndToken = Tokens.back();
8211 Tokens.push_back(Tok);
8214 PP.EnterTokenStream(Tokens,
false,
8222 ParseScope LocalScope(
this, 0);
8235 while (Tok.
isNot(tok::eof))
8239 if (Tok.
is(tok::eof) && Tok.
getEofData() == TypeStr.data())
8244void Parser::DiagnoseBitIntUse(
const Token &Tok) {
8248 assert(Tok.
isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8249 "expected either an _ExtInt or _BitInt token!");
8252 if (Tok.
is(tok::kw__ExtInt)) {
8253 Diag(Loc, diag::warn_ext_int_deprecated)
8259 Diag(Loc, diag::warn_c23_compat_keyword) << Tok.
getName();
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.
static bool isAttributeLateParsed(const IdentifierInfo &II)
isAttributeLateParsed - Return true if the attribute has arguments that require late parsing.
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 attributeHasIdentifierArg(const IdentifierInfo &II)
Determine whether the given attribute has an identifier argument.
static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II)
Determine whether the given attribute treats kw_this as an identifier.
static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II)
Determine whether the given attribute requires parsing its arguments in an unevaluated context or not...
static bool isValidAfterIdentifierInDeclarator(const Token &T)
isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the specified token is valid after t...
static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II)
Determine whether the given attribute has a variadic identifier argument.
static bool attributeAcceptsExprPack(const IdentifierInfo &II)
Determine if an attribute accepts parameter packs.
static bool isPipeDeclarator(const Declarator &D)
static SourceLocation getMissingDeclaratorIdLoc(Declarator &D, SourceLocation Loc)
static 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()
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the clang::TokenKind enum and support functions.
const clang::PrintingPolicy & getPrintingPolicy() const
The result of parsing/analyzing an expression, statement etc.
@ AS_Declspec
__declspec(...)
Kind getParsedKind() const
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
SourceLocation getOpenLocation() const
SourceLocation getCloseLocation() const
Represents a C++ nested-name-specifier or a global scope specifier.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
SourceLocation getEndLoc() const
bool isSet() const
Deprecated.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
void setTemplateParamLists(ArrayRef< TemplateParameterList * > L)
bool isEmpty() const
No scope specifier.
Represents a character-granular source range.
SourceLocation getBegin() const
Callback handler that receives notifications when performing code completion within the preprocessor.
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed.
Captures information about "declaration specifiers".
bool isVirtualSpecified() const
bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, ExplicitSpecifier ExplicitSpec, SourceLocation CloseParenLoc)
bool isTypeSpecPipe() const
static const TSCS TSCS___thread
static const TST TST_typeof_unqualType
void setTypeArgumentRange(SourceRange range)
bool SetTypePipe(bool isPipe, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
SourceLocation getPipeLoc() const
static const TST TST_typename
SourceLocation getEndLoc() const LLVM_READONLY
bool hasTypeSpecifier() const
Return true if any type-specifier has been found.
bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec and return false if there was no error.
static const TST TST_char8
static const TST TST_BFloat16
void ClearStorageClassSpecs()
bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TSCS TSCS__Thread_local
bool SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec, but return true and ignore the request if ...
bool isNoreturnSpecified() const
TST getTypeSpecType() const
SourceLocation getStorageClassSpecLoc() const
SCS getStorageClassSpec() const
bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceRange getSourceRange() const LLVM_READONLY
bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void SetRangeEnd(SourceLocation Loc)
bool SetBitIntType(SourceLocation KWLoc, Expr *BitWidth, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_auto_type
static const TST TST_interface
static const TST TST_double
static const TST TST_typeofExpr
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
void SetRangeStart(SourceLocation Loc)
bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getNoreturnSpecLoc() const
static const TST TST_union
static const TST TST_char
static const TST TST_bool
static const TST TST_char16
SourceLocation getExplicitSpecLoc() const
SourceLocation getFriendSpecLoc() const
SourceLocation getModulePrivateSpecLoc() const
bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void UpdateTypeRep(ParsedType Rep)
TSCS getThreadStorageClassSpec() const
bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasAttributes() const
static const TST TST_accum
static const TST TST_half
ParsedAttributes & getAttributes()
SourceLocation getConstSpecLoc() const
static const TST TST_ibm128
void addAttributes(const ParsedAttributesView &AL)
Concatenates two attribute lists.
static const TST TST_enum
bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_float128
void Finish(Sema &S, const PrintingPolicy &Policy)
Finish - This does final analysis of the declspec, issuing diagnostics for things like "_Imaginary" (...
bool isInlineSpecified() const
SourceLocation getRestrictSpecLoc() const
static const TST TST_typeof_unqualExpr
static const TST TST_class
bool hasTagDefinition() const
static const TST TST_decimal64
unsigned getParsedSpecifiers() const
Return a bitmask of which flavors of specifiers this DeclSpec includes.
void ClearFunctionSpecs()
bool SetTypeQual(TQ T, SourceLocation Loc)
static const TST TST_wchar
static const TST TST_void
bool isTypeAltiVecVector() const
void ClearConstexprSpec()
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
static const TST TST_float
static const TST TST_atomic
static const TST TST_fract
SourceLocation getThreadStorageClassSpecLoc() const
Decl * getRepAsDecl() const
static const TST TST_float16
static const TST TST_unspecified
SourceLocation getAtomicSpecLoc() const
SourceLocation getVirtualSpecLoc() const
SourceLocation getConstexprSpecLoc() const
CXXScopeSpec & getTypeSpecScope()
bool isEmpty() const
isEmpty - Return true if this declaration specifier is completely empty: no tokens were parsed in the...
SourceLocation getTypeSpecTypeLoc() const
static const TSCS TSCS_thread_local
bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal32
bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
TypeSpecifierWidth getTypeSpecWidth() const
static const TST TST_char32
bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal128
bool isTypeSpecOwned() const
SourceLocation getInlineSpecLoc() const
SourceLocation getUnalignedSpecLoc() const
static const TST TST_int128
SourceLocation getVolatileSpecLoc() const
FriendSpecified isFriendSpecified() const
bool hasExplicitSpecifier() const
bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasConstexprSpecifier() const
void takeAttributesFrom(ParsedAttributes &attrs)
static const TST TST_typeofType
bool SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_auto
@ PQ_StorageClassSpecifier
ConstexprSpecKind getConstexprSpecifier() const
static const TST TST_struct
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getLocation() const
Information about one declarator, including the parsed type information and the identifier.
bool isFunctionDeclarator(unsigned &idx) const
isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...
bool isPastIdentifier() const
isPastIdentifier - Return true if we have parsed beyond the point where the name would appear.
void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
void SetRangeBegin(SourceLocation Loc)
SetRangeBegin - Set the start of the source range to Loc, unless it's invalid.
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
void setCommaLoc(SourceLocation CL)
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
SourceLocation getIdentifierLoc() const
bool mayOmitIdentifier() const
mayOmitIdentifier - Return true if the identifier is either optional or not allowed.
SourceLocation getEndLoc() const LLVM_READONLY
bool mayBeFollowedByCXXDirectInit() const
mayBeFollowedByCXXDirectInit - Return true if the declarator can be followed by a C++ direct initiali...
bool hasGroupingParens() const
void setInvalidType(bool Val=true)
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
bool mayHaveIdentifier() const
mayHaveIdentifier - Return true if the identifier is either optional or required.
void setGroupingParens(bool flag)
SourceLocation getEllipsisLoc() const
DeclaratorContext getContext() const
SourceLocation getBeginLoc() const LLVM_READONLY
void setTrailingRequiresClause(Expr *TRC)
Sets a trailing requires clause for this declarator.
void setHasInitializer(bool Val=true)
UnqualifiedId & getName()
Retrieve the name specified by this declarator.
void setTemplateParameterLists(ArrayRef< TemplateParameterList * > TPLs)
Sets the template parameter lists that preceded the declarator.
bool isFirstDeclarator() const
bool hasTrailingRequiresClause() const
Determine whether a trailing requires clause was written in this declarator.
void setDecompositionBindings(SourceLocation LSquareLoc, ArrayRef< DecompositionDeclarator::Binding > Bindings, SourceLocation RSquareLoc)
Set the decomposition bindings for this declarator.
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
The template parameter lists that preceded the declarator.
bool isFunctionDeclaratorAFunctionDeclaration() const
Return true if a function declarator at this position would be a function declaration.
IdentifierInfo * getIdentifier() const
void clear()
Reset the contents of this Declarator.
void setAsmLabel(Expr *E)
void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &&attrs, SourceLocation EndLoc)
AddTypeInfo - Add a chunk to this declarator.
void ExtendWithDeclSpec(const DeclSpec &DS)
ExtendWithDeclSpec - Extend the declarator source range to include the given declspec,...
void SetRangeEnd(SourceLocation Loc)
SetRangeEnd - Set the end of the source range to Loc, unless it's invalid.
void setExtension(bool Val=true)
bool isInvalidType() const
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
bool isFirstDeclarationOfMember()
Returns true if this declares a real member and not a friend.
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
void setEllipsisLoc(SourceLocation EL)
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.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool requiresStrictPrototypes() const
Returns true if functions without prototypes or functions with an identifier list (aka K&R C function...
std::string getOpenCLVersionString() const
Return the OpenCL C or C++ for OpenCL language name and version as a string.
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static bool isAtStartOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroBegin=nullptr)
Returns true if the given MacroID location points at the first token of the macro expansion.
static bool isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroEnd=nullptr)
Returns true if the given MacroID location points at the last token of the macro expansion.
static bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, const LangOptions &LangOpts, bool IgnoreWhiteSpace=false)
Relex the token at the specified location.
static std::optional< Token > findNextToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Finds the token that comes right after the given location.
Represents the results of name lookup.
This represents a decl that may have a name.
bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...
Represents a parameter to a function.
static constexpr unsigned getMaxFunctionScopeDepth()
ParsedAttr - Represents a syntactic attribute.
unsigned getMaxArgs() const
static const ParsedAttributesView & none()
void addAtEnd(ParsedAttr *newAttr)
void addAll(iterator B, iterator E)
void remove(ParsedAttr *ToBeRemoved)
ParsedAttributes - A collection of parsed attributes.
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA)
ParsedAttr * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Form formUsed)
Add microsoft __delspec(property) attribute.
ParsedAttr * addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, ParsedAttr::Form form)
Add type_tag_for_datatype attribute.
ParsedAttr * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ParsedType typeArg, ParsedAttr::Form formUsed, SourceLocation ellipsisLoc=SourceLocation())
Add an attribute with a single type argument.
Parser - This implements a parser for the C family of languages.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
DeclGroupPtrTy ParseOpenACCDirectiveDecl()
Placeholder for now, should just ignore the directives after emitting a diagnostic.
Sema & getActions() const
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
Scope * getCurScope() const
SourceLocation getEndOfPreviousToken()
ExprResult ParseArrayBoundExpression()
const TargetInfo & getTargetInfo() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
friend class ObjCDeclContextSwitch
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
ExprResult ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast=NotTypeCast)
const LangOptions & getLangOpts() const
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtCodeCompletion
Stop at code completion.
@ StopAtSemi
Stop skipping at semicolon.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
ExprResult ParseUnevaluatedStringLiteralExpression()
ObjCContainerDecl * getObjCDeclContext() const
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
SmallVector< TemplateParameterList *, 4 > TemplateParameterLists
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
RAII object used to inform the actions that we're currently parsing a declaration.
A class for parsing a DeclSpec.
A class for parsing a declarator.
A class for parsing a field declarator.
void enterVariableInit(SourceLocation Tok, Decl *D)
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool isIncrementalProcessingEnabled() const
Returns true if incremental processing is enabled.
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
const LangOptions & getLangOpts() const
bool isCodeCompletionReached() const
Returns true if code-completion is enabled and we have hit the code-completion point.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
PrettyDeclStackTraceEntry - If a crash occurs in the parser while parsing something related to a decl...
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
The collection of all-type qualifiers we support.
void addAddressSpace(LangAS space)
static Qualifiers fromCVRUMask(unsigned CVRU)
Represents a struct/union/class.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isClassScope() const
isClassScope - Return true if this scope is a class/struct/union scope.
unsigned getFlags() const
getFlags - Return the flags for this scope.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ BlockScope
This is a scope that corresponds to a block/closure object.
@ 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.
NameClassificationKind getKind() const
void CodeCompleteTag(Scope *S, unsigned TagSpec)
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 CodeCompleteInitializer(Scope *S, Decl *D)
QualType ProduceConstructorSignatureHelp(QualType Type, SourceLocation Loc, ArrayRef< Expr * > Args, SourceLocation OpenParLoc, bool Braced)
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...
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...
@ CTCK_InitGlobalVar
Unknown context.
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...
TypeResult ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, const CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation TagLoc, SourceLocation NameLoc)
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)
void CodeCompleteTypeQualifiers(DeclSpec &DS)
ParsedType ActOnObjCInstanceType(SourceLocation Loc)
The parser has parsed the context-sensitive type 'instancetype' in an Objective-C message declaration...
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
const LangOptions & getLangOpts() const
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) .
void CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D, const VirtSpecifiers *VS=nullptr)
void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, IdentifierInfo *ClassName, SmallVectorImpl< Decl * > &Decls)
Called whenever @defs(ClassName) is encountered in the source.
bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS)
void startOpenMPCXXRangeFor()
If the current region is a range loop-based region, mark the start of the loop construct.
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 LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
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.
void CodeCompleteAttribute(AttributeCommonInfo::Syntax Syntax, AttributeCompletion Completion=AttributeCompletion::Attribute, const IdentifierInfo *Scope=nullptr)
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.
ParserCompletionContext
Describes the context in which code completion occurs.
@ PCC_LocalDeclarationSpecifiers
Code completion occurs within a sequence of declaration specifiers within a function,...
@ PCC_Template
Code completion occurs following one or more template headers.
@ 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.
SkipBodyInfo shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II, SourceLocation IILoc)
Determine whether the body of an anonymous enumeration should be skipped.
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 CodeCompleteBracketDeclarator(Scope *S)
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 CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
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.
void CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, bool AllowNonIdentifiers, bool AllowNestedNameSpecifiers)
OpenCLOptions & getOpenCLOptions()
void CodeCompleteAfterFunctionEquals(Declarator &D)
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)
void DiagnoseUnknownTypeName(IdentifierInfo *&II, SourceLocation IILoc, Scope *S, CXXScopeSpec *SS, ParsedType &SuggestedType, bool IsTemplateName=false)
ExprResult HandleExprEvaluationContextForTypeof(Expr *E)
bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS)
Determine whether the identifier II is a typo for the name of the class type currently being defined.
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
A RAII object used to temporarily suppress access-like checking.
Represents the declaration of a struct/union/class/enum.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getEndLoc() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
const char * getName() const
unsigned getLength() const
void setKind(tok::TokenKind K)
SourceLocation getAnnotationEndLoc() const
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
void * getAnnotationValue() const
tok::TokenKind getKind() const
bool isRegularKeywordAttribute() const
Return true if the token is a keyword that is parsed in the same position as a standard attribute,...
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
void setEofData(const void *D)
SourceRange getAnnotationRange() const
SourceRange of the group of tokens that this annotation token represents.
void setLocation(SourceLocation L)
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
const void * getEofData() const
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
void startToken()
Reset all flags to cleared.
void setIdentifierInfo(IdentifierInfo *II)
A declaration that models statements at global scope.
void setSemiMissing(bool Missing=true)
Base wrapper for a particular "section" of type source info.
The base class of the type hierarchy.
SourceLocation EndLocation
The location of the last token that describes this unqualified-id.
SourceRange getSourceRange() const LLVM_READONLY
Return the source range that covers this unqualified-id.
SourceLocation StartLocation
The location of the first token that describes this unqualified-id, which will be the location of the...
UnqualifiedIdKind getKind() const
Determine what kind of name we have.
The iterator over UnresolvedSets.
Declaration of a variable template.
static const char * getSpecifierName(Specifier VS)
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isPragmaAnnotation(TokenKind K)
Return true if this is an annotation token representing a pragma.
The JSON file list parser is used to communicate input to InstallAPI.
TypeSpecifierType
Specifies the kind of type.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
@ IK_TemplateId
A template-id, e.g., f<int>.
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &Second, ParsedAttributes &Result)
Consumes the attributes from First and Second and concatenates them into Result.
Language
The language for the input, used to select and validate the language standard and possible actions.
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
LangAS
Defines the address space values used by the address space qualifier of QualType.
int hasAttribute(AttributeCommonInfo::Syntax Syntax, const IdentifierInfo *Scope, const IdentifierInfo *Attr, const TargetInfo &Target, const LangOptions &LangOpts)
Return the version number associated with the attribute if we recognize and implement the attribute s...
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Dependent_template_name
The name refers to a dependent template name:
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
ActionResult< ParsedType > TypeResult
@ Parens
New-expression has a C++98 paren-delimited initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_None
no exception specification
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Represents information about a change in availability for an entity, which is part of the encoding of...
VersionTuple Version
The version number at which the change occurred.
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
SourceRange VersionRange
The source range covering the version number.
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
ParamInfo - An array of paraminfo objects is allocated whenever a function declarator is parsed.
One instance of this struct is used for each type in a declarator that is parsed.
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
enum clang::DeclaratorChunk::@216 Kind
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, ArrayRef< NamedDecl * > DeclsInPrototype, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult(), SourceLocation TrailingReturnTypeLoc=SourceLocation(), DeclSpec *MethodQualifiers=nullptr)
DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
static DeclaratorChunk getPipe(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc)
Return a DeclaratorChunk for an array.
SourceLocation Loc
Loc - The place where this type was defined.
static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, unsigned TypeQuals, SourceLocation StarLoc, SourceLocation EndLoc)
static DeclaratorChunk getParen(SourceLocation LParenLoc, SourceLocation RParenLoc)
Return a DeclaratorChunk for a paren.
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, SourceLocation AtomicQualLoc, SourceLocation UnalignedQualLoc)
Return a DeclaratorChunk for a pointer.
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, bool lvalue)
Return a DeclaratorChunk for a reference.
Wraps an identifier and optional source location for the identifier.
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
bool isStringLiteralArg(unsigned I) const
Describes how types, statements, expressions, and declarations should be printed.
Information about a template-id annotation token.
bool hasInvalidName() const
TemplateNameKind Kind
The kind of template that Template refers to.
bool hasInvalidArgs() const
IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.