34 #include "llvm/ADT/SmallSet.h"
35 #include "llvm/ADT/SmallString.h"
36 #include "llvm/ADT/StringSwitch.h"
39 using namespace clang;
53 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
54 if (DSC == DeclSpecContext::DSC_normal)
55 DSC = DeclSpecContext::DSC_type_specifier;
61 ParseSpecifierQualifierList(DS, AS, DSC);
69 if (AL.isDeclspecAttribute())
70 ToBeMoved.push_back(&AL);
79 ParseDeclarator(DeclaratorInfo);
91 if (Name.size() >= 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
92 return Name.drop_front(2).drop_back(2);
99 #define CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
101 #include "clang/Parse/AttrParserStringSwitches.inc"
103 #undef CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
109 #define CLANG_ATTR_LATE_PARSED_LIST
111 #include "clang/Parse/AttrParserStringSwitches.inc"
113 #undef CLANG_ATTR_LATE_PARSED_LIST
123 if (
SM.getFileID(StartLoc) !=
SM.getFileID(EndLoc))
126 bool AttrStartIsInMacro =
128 bool AttrEndIsInMacro =
130 return AttrStartIsInMacro && AttrEndIsInMacro;
133 void Parser::ParseAttributes(
unsigned WhichAttrKinds,
ParsedAttributes &Attrs,
134 LateParsedAttrList *LateAttrs) {
140 if (WhichAttrKinds & PAKM_CXX11)
141 MoreToParse |= MaybeParseCXX11Attributes(Attrs);
142 if (WhichAttrKinds & PAKM_GNU)
143 MoreToParse |= MaybeParseGNUAttributes(Attrs, LateAttrs);
144 if (WhichAttrKinds & PAKM_Declspec)
145 MoreToParse |= MaybeParseMicrosoftDeclSpecs(Attrs);
146 }
while (MoreToParse);
191 LateParsedAttrList *LateAttrs,
Declarator *D) {
192 assert(Tok.
is(tok::kw___attribute) &&
"Not a GNU attribute list!");
197 while (Tok.
is(tok::kw___attribute)) {
199 unsigned OldNumAttrs = Attrs.
size();
200 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
202 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
207 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"(")) {
220 if (Tok.
is(tok::code_completion)) {
223 AttributeCommonInfo::Syntax::AS_GNU);
232 if (Tok.
isNot(tok::l_paren)) {
233 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
238 bool LateParse =
false;
241 else if (LateAttrs->lateAttrParseExperimentalExtOnly()) {
245 LateParse =
getLangOpts().ExperimentalLateParseAttributes &&
258 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc,
nullptr,
264 LateParsedAttribute *LA =
265 new LateParsedAttribute(
this, *AttrName, AttrNameLoc);
266 LateAttrs->push_back(LA);
270 if (!ClassStack.empty() && !LateAttrs->parseSoon())
271 getCurrentClass().LateParsedDeclarations.push_back(LA);
275 LA->Toks.push_back(Tok);
278 ConsumeAndStoreUntil(tok::r_paren, LA->Toks,
true);
283 LA->Toks.push_back(Eof);
284 }
while (Tok.
is(tok::comma));
286 if (ExpectAndConsume(tok::r_paren))
289 if (ExpectAndConsume(tok::r_paren))
296 if (!
SM.isWrittenInBuiltinFile(
SM.getSpellingLoc(AttrTokLoc)) &&
299 StringRef FoundName =
303 for (
unsigned i = OldNumAttrs; i < Attrs.
size(); ++i)
304 Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.
getBegin());
307 for (
unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
308 (*LateAttrs)[i]->MacroII = MacroII;
318 #define CLANG_ATTR_IDENTIFIER_ARG_LIST
320 #include "clang/Parse/AttrParserStringSwitches.inc"
322 #undef CLANG_ATTR_IDENTIFIER_ARG_LIST
328 #define CLANG_ATTR_STRING_LITERAL_ARG_LIST
330 #include "clang/Parse/AttrParserStringSwitches.inc"
332 #undef CLANG_ATTR_STRING_LITERAL_ARG_LIST
337 #define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
339 #include "clang/Parse/AttrParserStringSwitches.inc"
341 #undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
346 #define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
348 #include "clang/Parse/AttrParserStringSwitches.inc"
350 #undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
355 #define CLANG_ATTR_ACCEPTS_EXPR_PACK
357 #include "clang/Parse/AttrParserStringSwitches.inc"
359 #undef CLANG_ATTR_ACCEPTS_EXPR_PACK
364 #define CLANG_ATTR_TYPE_ARG_LIST
366 #include "clang/Parse/AttrParserStringSwitches.inc"
368 #undef CLANG_ATTR_TYPE_ARG_LIST
374 #define CLANG_ATTR_ARG_CONTEXT_LIST
376 #include "clang/Parse/AttrParserStringSwitches.inc"
378 #undef CLANG_ATTR_ARG_CONTEXT_LIST
382 assert(Tok.
is(tok::identifier) &&
"expected an identifier");
395 ParsedAttr::Form Form) {
400 if (Tok.
isNot(tok::r_paren))
403 if (
Parens.consumeClose())
412 ScopeName, ScopeLoc,
T.get(), Form);
415 ScopeName, ScopeLoc,
nullptr, 0, Form);
419 Parser::ParseUnevaluatedStringInAttribute(
const IdentifierInfo &AttrName) {
420 if (Tok.
is(tok::l_paren)) {
423 ExprResult Res = ParseUnevaluatedStringInAttribute(AttrName);
424 Paren.consumeClose();
427 if (!isTokenStringLiteral()) {
435 bool Parser::ParseAttributeArgumentList(
438 bool SawError =
false;
443 Expr = ParseUnevaluatedStringInAttribute(AttrName);
445 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
446 Expr = ParseBraceInitializer();
452 if (Tok.
is(tok::ellipsis))
454 else if (Tok.
is(tok::code_completion)) {
465 if (
Expr.isInvalid()) {
475 Exprs.push_back(
Expr.get());
477 if (Tok.
isNot(tok::comma))
482 checkPotentialAngleBracketDelimiter(Comma);
489 for (
auto &E : Exprs) {
498 unsigned Parser::ParseAttributeArgsCommon(
507 bool AttributeHasVariadicIdentifierArg =
511 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
515 if (Tok.
is(tok::identifier)) {
517 bool IsIdentifierArg = AttributeHasVariadicIdentifierArg ||
527 IsIdentifierArg = Next.isOneOf(tok::r_paren, tok::comma);
531 ArgExprs.push_back(ParseIdentifierLoc());
535 if (!ArgExprs.empty() ? Tok.
is(tok::comma) : Tok.
isNot(tok::r_paren)) {
537 if (!ArgExprs.empty())
540 if (AttributeIsTypeArgAttr) {
548 TheParsedType =
T.get();
549 }
else if (AttributeHasVariadicIdentifierArg) {
557 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
561 if (Tok.
is(tok::identifier)) {
562 ArgExprs.push_back(ParseIdentifierLoc());
577 ArgExprs.push_back(ArgExpr.
get());
589 ExprVector ParsedExprs;
592 if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties)) {
598 for (
size_t I = 0; I < ParsedExprs.size(); ++I) {
599 if (!isa<PackExpansionExpr>(ParsedExprs[I]))
604 diag::err_attribute_argument_parm_pack_not_supported)
611 ArgExprs.insert(ArgExprs.end(), ParsedExprs.begin(), ParsedExprs.end());
616 if (!ExpectAndConsume(tok::r_paren)) {
619 if (AttributeIsTypeArgAttr && !TheParsedType.
get().
isNull()) {
621 ScopeName, ScopeLoc, TheParsedType, Form);
624 ArgExprs.data(), ArgExprs.size(), Form);
631 return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.
get().
isNull());
636 void Parser::ParseGNUAttributeArgs(
641 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
646 if (AttrKind == ParsedAttr::AT_Availability) {
647 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
650 }
else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
651 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
652 ScopeName, ScopeLoc, Form);
654 }
else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
655 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
656 ScopeName, ScopeLoc, Form);
658 }
else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
659 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
662 }
else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
663 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
664 ScopeName, ScopeLoc, Form);
667 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName,
670 }
else if (AttrKind == ParsedAttr::AT_CountedBy) {
671 ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
674 }
else if (AttrKind == ParsedAttr::AT_CXXAssume) {
675 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc, Form);
681 std::optional<ParseScope> PrototypeScope;
688 for (
unsigned i = 0; i != FTI.
NumParams; ++i) {
694 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
698 unsigned Parser::ParseClangAttributeArgs(
702 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
709 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
710 ScopeName, ScopeLoc, Form);
711 case ParsedAttr::AT_ExternalSourceSymbol:
712 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
713 ScopeName, ScopeLoc, Form);
715 case ParsedAttr::AT_Availability:
716 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
719 case ParsedAttr::AT_ObjCBridgeRelated:
720 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
721 ScopeName, ScopeLoc, Form);
723 case ParsedAttr::AT_SwiftNewType:
724 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
727 case ParsedAttr::AT_TypeTagForDatatype:
728 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
729 ScopeName, ScopeLoc, Form);
732 case ParsedAttr::AT_CXXAssume:
733 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc, Form);
736 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
742 unsigned ExistingAttrs = Attrs.
size();
746 if (!
hasAttribute(AttributeCommonInfo::Syntax::AS_Declspec,
nullptr, AttrName,
756 if (AttrName->
getName() ==
"property") {
762 T.expectAndConsume(diag::err_expected_lparen_after,
771 bool HasInvalidAccessor =
false;
776 if (!Tok.
is(tok::identifier)) {
778 if (Tok.
is(tok::r_paren) && !HasInvalidAccessor &&
779 AccessorNames[AK_Put] ==
nullptr &&
780 AccessorNames[AK_Get] ==
nullptr) {
781 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
792 if (KindStr ==
"get") {
794 }
else if (KindStr ==
"put") {
798 }
else if (KindStr ==
"set") {
799 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
806 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
808 HasInvalidAccessor =
true;
809 goto next_property_accessor;
813 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
814 HasInvalidAccessor =
true;
833 if (!Tok.
is(tok::identifier)) {
838 if (
Kind == AK_Invalid) {
840 }
else if (AccessorNames[
Kind] !=
nullptr) {
842 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
848 next_property_accessor:
854 if (Tok.
is(tok::r_paren))
857 Diag(Tok.
getLocation(), diag::err_ms_property_expected_comma_or_rparen);
862 if (!HasInvalidAccessor)
864 AccessorNames[AK_Get], AccessorNames[AK_Put],
867 return !HasInvalidAccessor;
871 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
877 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) << AttrName;
890 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
891 assert(Tok.
is(tok::kw___declspec) &&
"Not a declspec!");
896 while (Tok.
is(tok::kw___declspec)) {
899 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
905 while (Tok.
isNot(tok::r_paren)) {
910 if (Tok.
is(tok::code_completion)) {
919 bool IsString = Tok.
getKind() == tok::string_literal;
920 if (!IsString && Tok.
getKind() != tok::identifier &&
921 Tok.
getKind() != tok::kw_restrict) {
922 Diag(Tok, diag::err_ms_declspec_type);
932 StringRef Str = PP.
getSpelling(Tok, StrBuffer, &Invalid);
938 AttrNameLoc = ConsumeStringToken();
944 bool AttrHandled =
false;
947 if (Tok.
is(tok::l_paren))
948 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
949 else if (AttrName->
getName() ==
"property")
955 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
959 EndLoc =
T.getCloseLocation();
970 case tok::kw___fastcall:
971 case tok::kw___stdcall:
972 case tok::kw___thiscall:
973 case tok::kw___regcall:
974 case tok::kw___cdecl:
975 case tok::kw___vectorcall:
976 case tok::kw___ptr64:
978 case tok::kw___ptr32:
980 case tok::kw___uptr: {
983 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
993 void Parser::ParseWebAssemblyFuncrefTypeAttribute(
ParsedAttributes &attrs) {
994 assert(Tok.
is(tok::kw___funcref));
998 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
1004 attrs.
addNew(AttrName, AttrNameLoc,
nullptr,
1009 void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
1015 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) <<
Range;
1025 case tok::kw_volatile:
1026 case tok::kw___fastcall:
1027 case tok::kw___stdcall:
1028 case tok::kw___thiscall:
1029 case tok::kw___cdecl:
1030 case tok::kw___vectorcall:
1031 case tok::kw___ptr32:
1032 case tok::kw___ptr64:
1034 case tok::kw___unaligned:
1035 case tok::kw___sptr:
1036 case tok::kw___uptr:
1047 while (Tok.
is(tok::kw___pascal)) {
1050 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1057 while (Tok.
is(tok::kw___kernel)) {
1060 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1066 while (Tok.
is(tok::kw___noinline__)) {
1069 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1070 tok::kw___noinline__);
1077 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1081 bool Parser::isHLSLQualifier(
const Token &Tok)
const {
1082 return Tok.
is(tok::kw_groupshared);
1089 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
Kind);
1097 case tok::kw__Nonnull:
1098 case tok::kw__Nullable:
1099 case tok::kw__Nullable_result:
1100 case tok::kw__Null_unspecified: {
1104 Diag(AttrNameLoc, diag::ext_nullability)
1106 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1117 return (Separator ==
'.' || Separator ==
'_');
1128 VersionTuple Parser::ParseVersionTuple(
SourceRange &Range) {
1131 if (!Tok.
is(tok::numeric_constant)) {
1132 Diag(Tok, diag::err_expected_version);
1135 return VersionTuple();
1144 const char *ThisTokBegin = &Buffer[0];
1148 unsigned ActualLength = PP.
getSpelling(Tok, ThisTokBegin, &Invalid);
1150 return VersionTuple();
1153 unsigned AfterMajor = 0;
1155 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
1156 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
1160 if (AfterMajor == 0) {
1161 Diag(Tok, diag::err_expected_version);
1164 return VersionTuple();
1167 if (AfterMajor == ActualLength) {
1172 Diag(Tok, diag::err_zero_version);
1173 return VersionTuple();
1176 return VersionTuple(Major);
1179 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1181 || (AfterMajor + 1 == ActualLength)) {
1182 Diag(Tok, diag::err_expected_version);
1185 return VersionTuple();
1189 unsigned AfterMinor = AfterMajor + 1;
1191 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
1192 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
1196 if (AfterMinor == ActualLength) {
1200 if (Major == 0 && Minor == 0) {
1201 Diag(Tok, diag::err_zero_version);
1202 return VersionTuple();
1205 return VersionTuple(Major, Minor);
1208 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1211 Diag(Tok, diag::err_expected_version);
1214 return VersionTuple();
1218 if (AfterMajorSeparator != AfterMinorSeparator)
1219 Diag(Tok, diag::warn_expected_consistent_version_separator);
1222 unsigned AfterSubminor = AfterMinor + 1;
1223 unsigned Subminor = 0;
1224 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
1225 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
1229 if (AfterSubminor != ActualLength) {
1230 Diag(Tok, diag::err_expected_version);
1233 return VersionTuple();
1236 return VersionTuple(Major, Minor, Subminor);
1264 void Parser::ParseAvailabilityAttribute(
1275 if (
T.consumeOpen()) {
1276 Diag(Tok, diag::err_expected) << tok::l_paren;
1281 if (Tok.
isNot(tok::identifier)) {
1282 Diag(Tok, diag::err_availability_expected_platform);
1289 if (Ident->getName().contains(
"xrOS") || Ident->getName().contains(
"xros"))
1290 Diag(Platform->
Loc, diag::warn_availability_unknown_platform) << Ident;
1292 else if (Ident->getName() ==
"macosx")
1296 else if (Ident->getName() ==
"macosx_app_extension")
1300 AvailabilityAttr::canonicalizePlatformName(Ident->getName()));
1304 if (ExpectAndConsume(tok::comma)) {
1311 if (!Ident_introduced) {
1326 if (Tok.
isNot(tok::identifier)) {
1327 Diag(Tok, diag::err_availability_expected_change);
1334 if (Keyword == Ident_strict) {
1336 Diag(KeywordLoc, diag::err_availability_redundant)
1339 StrictLoc = KeywordLoc;
1343 if (Keyword == Ident_unavailable) {
1344 if (UnavailableLoc.
isValid()) {
1345 Diag(KeywordLoc, diag::err_availability_redundant)
1348 UnavailableLoc = KeywordLoc;
1352 if (Keyword == Ident_deprecated && Platform->
Ident &&
1356 Diag(KeywordLoc, diag::err_availability_redundant)
1367 if (Keyword == Ident_environment) {
1368 if (EnvironmentLoc !=
nullptr) {
1369 Diag(KeywordLoc, diag::err_availability_redundant)
1374 if (Tok.
isNot(tok::equal)) {
1375 Diag(Tok, diag::err_expected_after) << Keyword << tok::equal;
1380 if (Keyword == Ident_message || Keyword == Ident_replacement) {
1381 if (!isTokenStringLiteral()) {
1382 Diag(Tok, diag::err_expected_string_literal)
1387 if (Keyword == Ident_message) {
1395 if (Keyword == Ident_environment) {
1396 if (Tok.
isNot(tok::identifier)) {
1397 Diag(Tok, diag::err_availability_expected_environment);
1401 EnvironmentLoc = ParseIdentifierLoc();
1407 if ((Keyword == Ident_introduced || Keyword == Ident_deprecated) &&
1408 Tok.
is(tok::identifier)) {
1412 if (Keyword == Ident_introduced)
1413 UnavailableLoc = KeywordLoc;
1419 VersionTuple Version = ParseVersionTuple(VersionRange);
1421 if (Version.empty()) {
1427 if (Keyword == Ident_introduced)
1429 else if (Keyword == Ident_deprecated)
1431 else if (Keyword == Ident_obsoleted)
1436 if (Index < Unknown) {
1437 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1438 Diag(KeywordLoc, diag::err_availability_redundant)
1441 Changes[Index].VersionRange.
getEnd());
1445 Changes[Index].
Version = Version;
1448 Diag(KeywordLoc, diag::err_availability_unknown_change)
1449 << Keyword << VersionRange;
1455 if (
T.consumeClose())
1459 *endLoc =
T.getCloseLocation();
1463 if (UnavailableLoc.
isValid()) {
1464 bool Complained =
false;
1465 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1466 if (Changes[Index].KeywordLoc.
isValid()) {
1468 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1470 Changes[Index].VersionRange.
getEnd());
1481 attrs.
addNew(&Availability,
1482 SourceRange(AvailabilityLoc,
T.getCloseLocation()), ScopeName,
1483 ScopeLoc, Platform, Changes[Introduced], Changes[
Deprecated],
1484 Changes[Obsoleted], UnavailableLoc, MessageExpr.
get(), Form,
1485 StrictLoc, ReplacementExpr.
get(), EnvironmentLoc);
1502 void Parser::ParseExternalSourceSymbolAttribute(
1508 if (
T.expectAndConsume())
1512 if (!Ident_language) {
1520 bool HasLanguage =
false;
1522 bool HasDefinedIn =
false;
1525 bool HasUSR =
false;
1529 if (Tok.
isNot(tok::identifier)) {
1530 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1537 if (Keyword == Ident_generated_declaration) {
1538 if (GeneratedDeclaration) {
1539 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) << Keyword;
1543 GeneratedDeclaration = ParseIdentifierLoc();
1547 if (Keyword != Ident_language && Keyword != Ident_defined_in &&
1548 Keyword != Ident_USR) {
1549 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1555 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1561 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1563 if (Keyword == Ident_language)
1565 else if (Keyword == Ident_USR)
1568 HasDefinedIn =
true;
1570 if (!isTokenStringLiteral()) {
1571 Diag(Tok, diag::err_expected_string_literal)
1574 Keyword == Ident_language
1576 : (Keyword == Ident_defined_in ? 1 : 2));
1580 if (Keyword == Ident_language) {
1582 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1588 }
else if (Keyword == Ident_USR) {
1590 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1597 assert(Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1599 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1609 if (
T.consumeClose())
1612 *EndLoc =
T.getCloseLocation();
1617 ScopeName, ScopeLoc, Args, std::size(Args), Form);
1631 void Parser::ParseObjCBridgeRelatedAttribute(
1637 if (
T.consumeOpen()) {
1638 Diag(Tok, diag::err_expected) << tok::l_paren;
1643 if (Tok.
isNot(tok::identifier)) {
1644 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1649 if (ExpectAndConsume(tok::comma)) {
1658 if (Tok.
is(tok::identifier)) {
1661 Diag(Tok, diag::err_objcbridge_related_selector_name);
1667 if (Tok.
is(tok::colon))
1668 Diag(Tok, diag::err_objcbridge_related_selector_name);
1670 Diag(Tok, diag::err_expected) << tok::comma;
1678 if (Tok.
is(tok::identifier))
1680 else if (Tok.
isNot(tok::r_paren)) {
1681 Diag(Tok, diag::err_expected) << tok::r_paren;
1687 if (
T.consumeClose())
1691 *EndLoc =
T.getCloseLocation();
1694 Attrs.
addNew(&ObjCBridgeRelated,
1695 SourceRange(ObjCBridgeRelatedLoc,
T.getCloseLocation()),
1696 ScopeName, ScopeLoc, RelatedClass, ClassMethod, InstanceMethod,
1700 void Parser::ParseSwiftNewTypeAttribute(
1707 if (
T.consumeOpen()) {
1708 Diag(Tok, diag::err_expected) << tok::l_paren;
1712 if (Tok.
is(tok::r_paren)) {
1717 if (Tok.
isNot(tok::kw_struct) && Tok.
isNot(tok::kw_enum)) {
1718 Diag(Tok, diag::warn_attribute_type_not_supported)
1720 if (!isTokenSpecial())
1731 if (
T.consumeClose())
1734 *EndLoc =
T.getCloseLocation();
1738 ScopeName, ScopeLoc, Args, std::size(Args), Form);
1741 void Parser::ParseTypeTagForDatatypeAttribute(
1745 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1750 if (Tok.
isNot(tok::identifier)) {
1751 Diag(Tok, diag::err_expected) << tok::identifier;
1757 if (ExpectAndConsume(tok::comma)) {
1769 bool LayoutCompatible =
false;
1770 bool MustBeNull =
false;
1772 if (Tok.
isNot(tok::identifier)) {
1773 Diag(Tok, diag::err_expected) << tok::identifier;
1778 if (Flag->
isStr(
"layout_compatible"))
1779 LayoutCompatible =
true;
1780 else if (Flag->
isStr(
"must_be_null"))
1783 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1790 if (!
T.consumeClose()) {
1792 ArgumentKind, MatchingCType.
get(),
1793 LayoutCompatible, MustBeNull, Form);
1797 *EndLoc =
T.getCloseLocation();
1808 bool Parser::DiagnoseProhibitedCXX11Attribute() {
1809 assert(Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square));
1811 switch (isCXX11AttributeSpecifier(
true)) {
1812 case CAK_NotAttributeSpecifier:
1816 case CAK_InvalidAttributeSpecifier:
1820 case CAK_AttributeSpecifier:
1825 assert(Tok.
is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1827 Diag(BeginLoc, diag::err_attributes_not_allowed)
1831 llvm_unreachable(
"All cases handled above.");
1840 assert((Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square)) ||
1847 ParseCXX11Attributes(Attrs);
1850 (Keyword ?
Diag(
Loc, diag::err_keyword_not_allowed) << Keyword
1851 :
Diag(
Loc, diag::err_attributes_not_allowed))
1856 void Parser::DiagnoseProhibitedAttributes(
1858 auto *FirstAttr = Attrs.
empty() ? nullptr : &Attrs.
front();
1859 if (CorrectLocation.
isValid()) {
1861 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1862 ?
Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1863 :
Diag(CorrectLocation, diag::err_attributes_misplaced))
1868 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1876 unsigned AttrDiagID,
1877 unsigned KeywordDiagID,
1878 bool DiagnoseEmptyAttrs,
1879 bool WarnOnUnknownAttrs) {
1889 if (FirstLSquare.
is(tok::l_square)) {
1890 std::optional<Token> SecondLSquare =
1893 if (SecondLSquare && SecondLSquare->is(tok::l_square)) {
1904 if (AL.isRegularKeywordAttribute()) {
1905 Diag(AL.getLoc(), KeywordDiagID) << AL;
1909 if (!AL.isStandardAttributeSyntax())
1912 if (WarnOnUnknownAttrs)
1913 Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
1914 << AL << AL.getRange();
1916 Diag(AL.getLoc(), AttrDiagID) << AL;
1924 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1925 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1926 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
1945 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1946 AL.isDeclspecAttribute()) ||
1947 AL.isMicrosoftAttribute())
1948 ToBeMoved.push_back(&AL);
1983 Decl *SingleDecl =
nullptr;
1985 case tok::kw_template:
1986 case tok::kw_export:
1987 ProhibitAttributes(DeclAttrs);
1988 ProhibitAttributes(DeclSpecAttrs);
1989 return ParseDeclarationStartingWithTemplate(Context, DeclEnd, DeclAttrs);
1990 case tok::kw_inline:
1993 ProhibitAttributes(DeclAttrs);
1994 ProhibitAttributes(DeclSpecAttrs);
1996 return ParseNamespace(Context, DeclEnd, InlineLoc);
1998 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1999 true,
nullptr, DeclSpecStart);
2001 case tok::kw_cbuffer:
2002 case tok::kw_tbuffer:
2003 SingleDecl = ParseHLSLBuffer(DeclEnd);
2005 case tok::kw_namespace:
2006 ProhibitAttributes(DeclAttrs);
2007 ProhibitAttributes(DeclSpecAttrs);
2008 return ParseNamespace(Context, DeclEnd);
2009 case tok::kw_using: {
2012 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
2015 case tok::kw_static_assert:
2016 case tok::kw__Static_assert:
2017 ProhibitAttributes(DeclAttrs);
2018 ProhibitAttributes(DeclSpecAttrs);
2019 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
2022 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
2023 true,
nullptr, DeclSpecStart);
2055 bool RequireSemi, ForRangeInit *FRI,
SourceLocation *DeclSpecStart) {
2058 OriginalDeclSpecAttrs.
addAll(DeclSpecAttrs.
begin(), DeclSpecAttrs.
end());
2059 OriginalDeclSpecAttrs.
Range = DeclSpecAttrs.
Range;
2065 ParsedTemplateInfo TemplateInfo;
2066 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
2067 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none, DSContext);
2072 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
2077 if (Tok.
is(tok::semi)) {
2078 ProhibitAttributes(DeclAttrs);
2085 DS.complete(TheDecl);
2087 Decl* decls[] = {AnonRecord, TheDecl};
2099 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
2106 case tok::annot_cxxscope:
2107 case tok::annot_template_id:
2109 case tok::code_completion:
2110 case tok::coloncolon:
2112 case tok::kw___attribute:
2113 case tok::kw_operator:
2129 case tok::identifier:
2131 case tok::code_completion:
2132 case tok::coloncolon:
2135 case tok::equalequal:
2136 case tok::kw_alignas:
2138 case tok::kw___attribute:
2156 case tok::identifier:
2179 if (Tok.
isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
2203 case tok::kw_inline:
2208 (!ParsingInObjCContainer || CurParsedObjCImpl))
2212 case tok::kw_namespace:
2217 (!ParsingInObjCContainer || CurParsedObjCImpl))
2223 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2224 ParsingInObjCContainer)
2236 case tok::annot_module_begin:
2237 case tok::annot_module_end:
2238 case tok::annot_module_include:
2239 case tok::annot_repl_input_end:
2256 ParsedTemplateInfo &TemplateInfo,
2258 ForRangeInit *FRI) {
2264 LocalAttrs.takeAllFrom(Attrs);
2266 if (TemplateInfo.TemplateParams)
2269 bool IsTemplateSpecOrInst =
2270 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
2271 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
2276 if (IsTemplateSpecOrInst)
2286 MaybeParseHLSLAnnotations(D);
2288 if (Tok.
is(tok::kw_requires))
2289 ParseTrailingRequiresClause(D);
2294 LateParsedAttrList LateParsedAttrs(
true);
2296 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2301 if (Tok.
is(tok::kw__Noreturn)) {
2303 const char *PrevSpec;
2309 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2310 Fixit &= Tok.
isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2312 Diag(
Loc, diag::err_c11_noreturn_misplaced)
2314 << (Fixit ?
FixItHint::CreateInsertion(D.getBeginLoc(),
"_Noreturn ")
2319 if (Tok.
is(tok::equal) &&
NextToken().is(tok::code_completion)) {
2330 while (
auto Specifier = isCXX11VirtSpecifier()) {
2331 Diag(Tok, diag::err_virt_specifier_outside_class)
2339 if (!isDeclarationAfterDeclarator()) {
2345 if (isStartOfFunctionDefinition(D)) {
2355 diag::err_function_declared_typedef)
2359 Decl *TheDecl =
nullptr;
2361 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
2365 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2366 TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(),
2372 diag::err_explicit_instantiation_with_definition)
2380 std::nullopt, LAngleLoc,
nullptr));
2382 TheDecl = ParseFunctionDefinition(
2384 ParsedTemplateInfo(&FakedParamLists,
2391 ParseFunctionDefinition(D, TemplateInfo, &LateParsedAttrs);
2398 Tok.
is(tok::kw_namespace)) {
2408 Diag(Tok, diag::err_expected_fn_body);
2413 if (Tok.
is(tok::l_brace)) {
2414 Diag(Tok, diag::err_function_definition_not_allowed);
2422 if (ParseAsmAttributesAfterDeclarator(D))
2431 if (FRI && (Tok.
is(tok::colon) || isTokIdentifier_in())) {
2432 bool IsForRangeLoop =
false;
2434 IsForRangeLoop =
true;
2444 LastRecord.InLifetimeExtendingContext =
true;
2449 if (Tok.
is(tok::l_brace))
2450 FRI->RangeExpr = ParseBraceInitializer();
2461 FRI->LifetimeExtendTemps = std::move(
2466 if (IsForRangeLoop) {
2470 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2471 VD->setObjCForDecl(
true);
2474 D.complete(ThisDecl);
2480 ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo, FRI);
2481 if (LateParsedAttrs.size() > 0)
2482 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2483 D.complete(FirstDecl);
2485 DeclsInGroup.push_back(FirstDecl);
2493 if (Tok.
isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2497 Diag(CommaLoc, diag::err_expected_semi_declaration)
2507 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
2509 Diag(CommaLoc, diag::err_multiple_template_declarators)
2510 << TemplateInfo.Kind;
2524 MaybeParseGNUAttributes(D);
2528 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2533 MaybeParseHLSLAnnotations(D);
2540 if (Tok.
is(tok::kw_requires))
2541 ParseTrailingRequiresClause(D);
2542 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D, TemplateInfo);
2543 D.complete(ThisDecl);
2545 DeclsInGroup.push_back(ThisDecl);
2552 if (ExpectSemi && ExpectAndConsumeSemi(
2554 ? diag::err_invalid_token_after_toplevel_declarator
2555 : diag::err_expected_semi_declaration)) {
2568 bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &D) {
2570 if (Tok.
is(tok::kw_asm)) {
2573 if (AsmLabel.isInvalid()) {
2582 MaybeParseGNUAttributes(D);
2608 Decl *Parser::ParseDeclarationAfterDeclarator(
2609 Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
2610 if (ParseAsmAttributesAfterDeclarator(D))
2613 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
2616 Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2617 Declarator &D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2619 struct InitializerScopeRAII {
2626 :
P(
P), D(D), ThisDecl(ThisDecl), Entered(
false) {
2627 if (ThisDecl &&
P.getLangOpts().CPlusPlus) {
2631 S =
P.getCurScope();
2634 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2639 ~InitializerScopeRAII() {
2640 if (ThisDecl &&
P.getLangOpts().CPlusPlus) {
2643 S =
P.getCurScope();
2646 P.Actions.ActOnCXXExitDeclInitializer(S, ThisDecl);
2655 InitKind TheInitKind;
2657 if (isTokenEqualOrEqualTypo())
2658 TheInitKind = InitKind::Equal;
2659 else if (Tok.
is(tok::l_paren))
2660 TheInitKind = InitKind::CXXDirect;
2663 TheInitKind = InitKind::CXXBraced;
2670 Decl *ThisDecl =
nullptr;
2671 Decl *OuterDecl =
nullptr;
2672 switch (TemplateInfo.Kind) {
2673 case ParsedTemplateInfo::NonTemplate:
2677 case ParsedTemplateInfo::Template:
2678 case ParsedTemplateInfo::ExplicitSpecialization: {
2680 *TemplateInfo.TemplateParams,
2682 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2685 ThisDecl = VT->getTemplatedDecl();
2690 case ParsedTemplateInfo::ExplicitInstantiation: {
2691 if (Tok.
is(tok::semi)) {
2693 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
2698 ThisDecl = ThisRes.
get();
2706 Diag(Tok, diag::err_template_defn_explicit_instantiation)
2713 diag::err_explicit_instantiation_with_definition)
2721 std::nullopt, LAngleLoc,
nullptr));
2733 switch (TheInitKind) {
2735 case InitKind::Equal: {
2738 if (Tok.
is(tok::kw_delete)) {
2744 SkipDeletedFunctionBody();
2745 }
else if (Tok.
is(tok::kw_default)) {
2753 InitializerScopeRAII InitScope(*
this, D, ThisDecl);
2755 if (Tok.
is(tok::code_completion)) {
2769 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2773 FRI->ColonLoc = EqualLoc;
2775 FRI->RangeExpr =
Init;
2778 if (
Init.isInvalid()) {
2780 StopTokens.push_back(tok::comma);
2783 StopTokens.push_back(tok::r_paren);
2792 case InitKind::CXXDirect: {
2799 InitializerScopeRAII InitScope(*
this, D, ThisDecl);
2801 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2802 auto RunSignatureHelp = [&]() {
2805 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2808 CalledSignatureHelp =
true;
2809 return PreferredType;
2811 auto SetPreferredType = [&] {
2812 PreferredType.enterFunctionArgument(Tok.
getLocation(), RunSignatureHelp);
2815 llvm::function_ref<void()> ExpressionStarts;
2821 ExpressionStarts = SetPreferredType;
2824 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2829 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2832 CalledSignatureHelp =
true;
2841 T.getCloseLocation(),
2848 case InitKind::CXXBraced: {
2850 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2852 InitializerScopeRAII InitScope(*
this, D, ThisDecl);
2854 PreferredType.enterVariableInit(Tok.
getLocation(), ThisDecl);
2857 if (
Init.isInvalid()) {
2870 return OuterDecl ? OuterDecl : ThisDecl;
2879 void Parser::ParseSpecifierQualifierList(
2882 ParsedTemplateInfo TemplateInfo;
2886 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC,
nullptr,
2887 AllowImplicitTypename);
2892 Diag(Tok, diag::err_expected_type);
2895 Diag(Tok, diag::err_typename_requires_specqual);
2906 diag::err_typename_invalid_storageclass);
2950 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2951 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2965 ParsedTemplateInfo &TemplateInfo,
2968 assert(Tok.
is(tok::identifier) &&
"should have identifier");
2990 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
3009 AnnotateScopeToken(*SS,
false);
3020 DSC == DeclSpecContext::DSC_template_type_arg)) {
3021 const char *PrevSpec;
3037 if (SS ==
nullptr) {
3038 const char *TagName =
nullptr, *FixitTagName =
nullptr;
3044 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
3046 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
3048 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
3050 TagName=
"__interface"; FixitTagName =
"__interface ";
3051 TagKind=tok::kw___interface;
break;
3053 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
3061 Diag(
Loc, diag::err_use_of_tag_name_without_tag)
3062 << TokenName << TagName <<
getLangOpts().CPlusPlus
3068 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
3069 << TokenName << TagName;
3073 if (TagKind == tok::kw_enum)
3074 ParseEnumSpecifier(
Loc, DS, TemplateInfo, AS,
3075 DeclSpecContext::DSC_normal);
3077 ParseClassSpecifier(TagKind,
Loc, DS, TemplateInfo, AS,
3079 DeclSpecContext::DSC_normal, Attrs);
3086 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
3087 DSC == DeclSpecContext::DSC_class)) {
3091 case tok::l_paren: {
3098 TentativeParsingAction PA(*
this);
3100 TPResult TPR = TryParseDeclarator(
false);
3103 if (TPR != TPResult::False) {
3111 if (DSC == DeclSpecContext::DSC_class ||
3112 (DSC == DeclSpecContext::DSC_top_level && SS)) {
3115 Diag(
Loc, diag::err_constructor_bad_name)
3136 AnnotateScopeToken(*SS,
false);
3158 const char *PrevSpec;
3179 if (IsTemplateName) {
3181 TemplateArgList Args;
3182 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3196 Parser::DeclSpecContext
3200 return DeclSpecContext::DSC_class;
3202 return DeclSpecContext::DSC_top_level;
3204 return DeclSpecContext::DSC_template_param;
3206 return DeclSpecContext::DSC_template_arg;
3208 return DeclSpecContext::DSC_template_type_arg;
3211 return DeclSpecContext::DSC_trailing;
3214 return DeclSpecContext::DSC_alias_declaration;
3216 return DeclSpecContext::DSC_association;
3218 return DeclSpecContext::DSC_type_specifier;
3220 return DeclSpecContext::DSC_condition;
3222 return DeclSpecContext::DSC_conv_operator;
3224 return DeclSpecContext::DSC_new;
3239 return DeclSpecContext::DSC_normal;
3242 llvm_unreachable(
"Missing DeclaratorContext case");
3255 if (isTypeIdInParens()) {
3284 assert(Tok.
isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3285 "Not an alignment-specifier!");
3292 if (
T.expectAndConsume())
3299 ParseAlignArgument(PP.
getSpelling(KWTok),
T.getOpenLocation(),
3308 *EndLoc =
T.getCloseLocation();
3315 ArgExprs.push_back(ArgExpr.
get());
3316 Attrs.
addNew(KWName, KWLoc,
nullptr, KWLoc, ArgExprs.data(), 1,
Kind,
3321 void Parser::DistributeCLateParsedAttrs(
Decl *Dcl,
3322 LateParsedAttrList *LateAttrs) {
3327 for (
auto *LateAttr : *LateAttrs) {
3328 if (LateAttr->Decls.empty())
3329 LateAttr->addDecl(Dcl);
3341 ParsedAttr::Form Form) {
3342 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3347 if (Tok.
is(tok::r_paren)) {
3355 using ExpressionKind =
3359 ExpressionKind::EK_BoundsAttrArgument);
3369 ArgExprs.push_back(ArgExpr.
get());
3379 ScopeName, ScopeLoc, ArgExprs.data(), ArgExprs.size(), Form);
3382 ExprResult Parser::ParseExtIntegerArgument() {
3383 assert(Tok.
isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3384 "Not an extended int type");
3388 if (
T.expectAndConsume())
3397 if(
T.consumeClose())
3411 DeclSpecContext DSContext,
3412 LateParsedAttrList *LateAttrs) {
3415 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3416 DSContext == DeclSpecContext::DSC_top_level);
3419 Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
3420 tok::annot_template_id) &&
3426 bool HasScope = Tok.
is(tok::annot_cxxscope);
3432 bool MightBeDeclarator =
true;
3433 if (Tok.
isOneOf(tok::kw_typename, tok::annot_typename)) {
3435 MightBeDeclarator =
false;
3436 }
else if (AfterScope.
is(tok::annot_template_id)) {
3442 MightBeDeclarator =
false;
3443 }
else if (AfterScope.
is(tok::identifier)) {
3444 const Token &Next = HasScope ? GetLookAheadToken(2) :
NextToken();
3448 if (Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3449 tok::annot_cxxscope, tok::coloncolon)) {
3451 MightBeDeclarator =
false;
3452 }
else if (HasScope) {
3463 switch (Classification.
getKind()) {
3469 llvm_unreachable(
"typo correction is not possible here");
3476 MightBeDeclarator =
false;
3492 if (MightBeDeclarator)
3497 diag::err_expected_after)
3508 ParsedTemplateInfo NotATemplate;
3509 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3540 void Parser::ParseDeclarationSpecifiers(
3542 DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
3554 if (DSContext == DeclSpecContext::DSC_conv_operator) {
3557 DSContext = DeclSpecContext::DSC_type_specifier;
3560 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3561 DSContext == DeclSpecContext::DSC_top_level);
3562 bool AttrsLastTime =
false;
3568 bool isStorageClass =
false;
3569 const char *PrevSpec =
nullptr;
3570 unsigned DiagID = 0;
3591 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3605 bool IsTemplateSpecOrInst =
3606 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3607 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3616 ProhibitAttributes(attrs);
3620 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3621 !PA.isRegularKeywordAttribute())
3629 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3630 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3637 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3638 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3640 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3641 << PA << PA.isRegularKeywordAttribute();
3650 DS.
Finish(Actions, Policy);
3654 case tok::kw__Alignas:
3655 diagnoseUseOfC11Keyword(Tok);
3657 case tok::kw_alignas:
3663 if (Tok.
getKind() == tok::kw_alignas)
3664 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
3670 if (!isAllowedCXX11AttributeSpecifier())
3671 goto DoneWithDeclSpec;
3674 ProhibitAttributes(attrs);
3681 ParseCXX11Attributes(attrs);
3682 AttrsLastTime =
true;
3685 case tok::code_completion: {
3689 bool AllowNonIdentifiers
3695 bool AllowNestedNameSpecifiers
3696 = DSContext == DeclSpecContext::DSC_top_level ||
3701 getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3706 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
3707 CCC = DSContext == DeclSpecContext::DSC_class
3710 else if (DSContext == DeclSpecContext::DSC_class)
3714 else if (CurParsedObjCImpl)
3722 case tok::coloncolon:
3728 goto DoneWithDeclSpec;
3730 if (Tok.
is(tok::coloncolon))
3731 goto DoneWithDeclSpec;
3734 case tok::annot_cxxscope: {
3736 goto DoneWithDeclSpec;
3739 if (TemplateInfo.TemplateParams)
3749 ? takeTemplateIdAnnotation(Next)
3755 ConsumeAnnotationToken();
3769 if ((DSContext == DeclSpecContext::DSC_top_level ||
3770 DSContext == DeclSpecContext::DSC_class) &&
3773 isConstructorDeclarator(
false,
3780 goto DoneWithDeclSpec;
3784 ConsumeAnnotationToken();
3785 assert(Tok.
is(tok::annot_template_id) &&
3786 "ParseOptionalCXXScopeSpecifier not working");
3787 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3797 ConsumeAnnotationToken();
3801 if (Next.is(tok::annot_typename)) {
3803 ConsumeAnnotationToken();
3807 PrevSpec, DiagID,
T, Policy);
3811 ConsumeAnnotationToken();
3815 Next.is(tok::annot_template_id) &&
3819 ConsumeAnnotationToken();
3820 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3824 if (Next.isNot(tok::identifier))
3825 goto DoneWithDeclSpec;
3830 if ((DSContext == DeclSpecContext::DSC_top_level ||
3831 DSContext == DeclSpecContext::DSC_class) &&
3834 isConstructorDeclarator(
false,
3838 goto DoneWithDeclSpec;
3847 *Next.getIdentifierInfo(), Next.getLocation(),
getCurScope(), &SS,
3848 false,
false,
nullptr,
3851 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3853 if (IsTemplateSpecOrInst)
3861 if (TryAnnotateTypeConstraint())
3862 goto DoneWithDeclSpec;
3863 if (Tok.
isNot(tok::annot_cxxscope) ||
3867 ConsumeAnnotationToken();
3869 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3870 if (!Attrs.
empty()) {
3871 AttrsLastTime =
true;
3872 attrs.takeAllFrom(Attrs);
3876 goto DoneWithDeclSpec;
3880 ConsumeAnnotationToken();
3883 DiagID, TypeRep, Policy);
3893 case tok::annot_typename: {
3897 goto DoneWithDeclSpec;
3906 ConsumeAnnotationToken();
3911 case tok::kw___is_signed:
3922 TryKeywordIdentFallback(
true);
3925 goto DoneWithDeclSpec;
3928 case tok::kw___super:
3929 case tok::kw_decltype:
3930 case tok::identifier:
3936 goto DoneWithDeclSpec;
3942 if (!
getLangOpts().DeclSpecKeyword && Tok.
is(tok::identifier) &&
3944 Diag(
Loc, diag::err_ms_attributes_not_enabled);
3954 if (
T.consumeOpen()) {
3955 assert(
false &&
"Not a left paren?");
3974 if (IsTemplateSpecOrInst)
3978 if (IsTemplateSpecOrInst)
3981 goto DoneWithDeclSpec;
3984 if (!Tok.
is(tok::identifier))
3989 if (TryAltiVecToken(DS,
Loc, PrevSpec, DiagID,
isInvalid))
3995 goto DoneWithDeclSpec;
3997 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3998 isObjCInstancetype()) {
4002 DiagID, TypeRep, Policy);
4015 isConstructorDeclarator(
true,
4018 goto DoneWithDeclSpec;
4022 false,
false,
nullptr,
false,
false,
4023 isClassTemplateDeductionContext(DSContext));
4028 if (TryAnnotateTypeConstraint())
4029 goto DoneWithDeclSpec;
4030 if (Tok.
isNot(tok::identifier))
4033 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
4034 if (!Attrs.
empty()) {
4035 AttrsLastTime =
true;
4036 attrs.takeAllFrom(Attrs);
4040 goto DoneWithDeclSpec;
4047 (DSContext == DeclSpecContext::DSC_class ||
4048 DSContext == DeclSpecContext::DSC_top_level) &&
4051 isConstructorDeclarator(
true,
4053 goto DoneWithDeclSpec;
4056 DiagID, TypeRep, Policy);
4068 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
4083 case tok::annot_template_id: {
4095 TemplateId =
nullptr;
4103 tok::kw_volatile, tok::kw_restrict, tok::amp,
4105 Diag(
Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
4109 TemplateId, Policy);
4113 goto DoneWithDeclSpec;
4116 TemplateId =
nullptr;
4118 ConsumeAnnotationToken();
4122 if (Tracker.consumeOpen()) {
4124 Diag(Tok, diag::err_expected) << tok::l_paren;
4128 Tracker.skipToEnd();
4129 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
4134 Tracker.consumeClose();
4142 DiagID, TemplateId, Policy);
4145 TemplateId, Policy);
4154 goto DoneWithDeclSpec;
4162 isConstructorDeclarator(
true,
4165 goto DoneWithDeclSpec;
4170 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
4175 case tok::kw___attribute:
4176 case tok::kw___declspec:
4177 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4181 case tok::kw___forceinline: {
4186 nullptr, 0, tok::kw___forceinline);
4190 case tok::kw___unaligned:
4195 case tok::kw___sptr:
4196 case tok::kw___uptr:
4197 case tok::kw___ptr64:
4198 case tok::kw___ptr32:
4200 case tok::kw___cdecl:
4201 case tok::kw___stdcall:
4202 case tok::kw___fastcall:
4203 case tok::kw___thiscall:
4204 case tok::kw___regcall:
4205 case tok::kw___vectorcall:
4209 case tok::kw___funcref:
4214 case tok::kw___pascal:
4219 case tok::kw___kernel:
4224 case tok::kw___noinline__:
4229 case tok::kw__Nonnull:
4230 case tok::kw__Nullable:
4231 case tok::kw__Nullable_result:
4232 case tok::kw__Null_unspecified:
4237 case tok::kw___kindof:
4239 nullptr, 0, tok::kw___kindof);
4244 case tok::kw_typedef:
4246 PrevSpec, DiagID, Policy);
4247 isStorageClass =
true;
4249 case tok::kw_extern:
4251 Diag(Tok, diag::ext_thread_before) <<
"extern";
4253 PrevSpec, DiagID, Policy);
4254 isStorageClass =
true;
4256 case tok::kw___private_extern__:
4258 Loc, PrevSpec, DiagID, Policy);
4259 isStorageClass =
true;
4261 case tok::kw_static:
4263 Diag(Tok, diag::ext_thread_before) <<
"static";
4265 PrevSpec, DiagID, Policy);
4266 isStorageClass =
true;
4270 if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
4272 PrevSpec, DiagID, Policy);
4274 Diag(Tok, diag::ext_auto_storage_class)
4281 PrevSpec, DiagID, Policy);
4282 isStorageClass =
true;
4284 case tok::kw___auto_type:
4285 Diag(Tok, diag::ext_auto_type);
4289 case tok::kw_register:
4291 PrevSpec, DiagID, Policy);
4292 isStorageClass =
true;
4294 case tok::kw_mutable:
4296 PrevSpec, DiagID, Policy);
4297 isStorageClass =
true;
4299 case tok::kw___thread:
4302 isStorageClass =
true;
4304 case tok::kw_thread_local:
4306 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4315 Loc, PrevSpec, DiagID);
4316 isStorageClass =
true;
4318 case tok::kw__Thread_local:
4319 diagnoseUseOfC11Keyword(Tok);
4321 Loc, PrevSpec, DiagID);
4322 isStorageClass =
true;
4326 case tok::kw_inline:
4329 case tok::kw_virtual:
4333 !
getActions().getOpenCLOptions().isAvailableOption(
4335 DiagID = diag::err_openclcxx_virtual_function;
4342 case tok::kw_explicit: {
4346 ConsumedEnd = ExplicitLoc;
4348 if (Tok.
is(tok::l_paren)) {
4351 ? diag::warn_cxx17_compat_explicit_bool
4352 : diag::ext_explicit_bool);
4356 Tracker.consumeOpen();
4363 if (ExplicitExpr.isUsable()) {
4365 Tracker.consumeClose();
4369 Tracker.skipToEnd();
4375 ExplicitSpec, CloseParenLoc);
4378 case tok::kw__Noreturn:
4379 diagnoseUseOfC11Keyword(Tok);
4384 case tok::kw_friend:
4385 if (DSContext == DeclSpecContext::DSC_class) {
4392 DiagID = diag::err_friend_invalid_in_context;
4398 case tok::kw___module_private__:
4403 case tok::kw_constexpr:
4405 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4409 case tok::kw_consteval:
4413 case tok::kw_constinit:
4429 PrevSpec, DiagID, Policy);
4431 case tok::kw___int64:
4433 PrevSpec, DiagID, Policy);
4435 case tok::kw_signed:
4439 case tok::kw_unsigned:
4443 case tok::kw__Complex:
4445 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4449 case tok::kw__Imaginary:
4451 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4467 case tok::kw__ExtInt:
4468 case tok::kw__BitInt: {
4469 DiagnoseBitIntUse(Tok);
4474 ConsumedEnd = PrevTokLocation;
4477 case tok::kw___int128:
4485 case tok::kw___bf16:
4493 case tok::kw_double:
4497 case tok::kw__Float16:
4501 case tok::kw__Accum:
4503 "This keyword is only used when fixed point types are enabled "
4504 "with `-ffixed-point`");
4508 case tok::kw__Fract:
4510 "This keyword is only used when fixed point types are enabled "
4511 "with `-ffixed-point`");
4517 "This keyword is only used when fixed point types are enabled "
4518 "with `-ffixed-point`");
4521 case tok::kw___float128:
4525 case tok::kw___ibm128:
4529 case tok::kw_wchar_t:
4533 case tok::kw_char8_t:
4537 case tok::kw_char16_t:
4541 case tok::kw_char32_t:
4547 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4551 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4553 if (Tok.
is(tok::kw_bool) &&
4557 DiagID = diag::err_bool_redeclaration;
4566 case tok::kw__Decimal32:
4570 case tok::kw__Decimal64:
4574 case tok::kw__Decimal128:
4578 case tok::kw___vector:
4581 case tok::kw___pixel:
4584 case tok::kw___bool:
4589 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4594 goto DoneWithDeclSpec;
4596 DiagID = diag::err_opencl_unknown_type_specifier;
4603 #define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4604 #define IMAGE_WRITE_TYPE(Type, Id, Ext)
4605 #define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4606 case tok::kw_##ImgType##_t: \
4607 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4608 goto DoneWithDeclSpec; \
4610 #include "clang/Basic/OpenCLImageTypes.def"
4611 case tok::kw___unknown_anytype:
4613 PrevSpec, DiagID, Policy);
4618 case tok::kw_struct:
4619 case tok::kw___interface:
4620 case tok::kw_union: {
4628 ParseClassSpecifier(
Kind,
Loc, DS, TemplateInfo, AS,
4629 EnteringContext, DSContext, Attributes);
4633 if (!Attributes.empty()) {
4634 AttrsLastTime =
true;
4635 attrs.takeAllFrom(Attributes);
4643 ParseEnumSpecifier(
Loc, DS, TemplateInfo, AS, DSContext);
4651 case tok::kw_volatile:
4655 case tok::kw_restrict:
4661 case tok::kw_typename:
4664 goto DoneWithDeclSpec;
4666 if (!Tok.
is(tok::kw_typename))
4671 case tok::kw_typeof:
4672 case tok::kw_typeof_unqual:
4673 ParseTypeofSpecifier(DS);
4676 case tok::annot_decltype:
4677 ParseDecltypeSpecifier(DS);
4680 case tok::annot_pack_indexing_type:
4681 ParsePackIndexingType(DS);
4684 case tok::annot_pragma_pack:
4688 case tok::annot_pragma_ms_pragma:
4689 HandlePragmaMSPragma();
4692 case tok::annot_pragma_ms_vtordisp:
4693 HandlePragmaMSVtorDisp();
4696 case tok::annot_pragma_ms_pointers_to_members:
4697 HandlePragmaMSPointersToMembers();
4700 #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4701 #include "clang/Basic/TransformTypeTraits.def"
4705 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4706 goto ParseIdentifier;
4709 case tok::kw__Atomic:
4714 diagnoseUseOfC11Keyword(Tok);
4716 ParseAtomicSpecifier(DS);
4724 case tok::kw___generic:
4729 if (!Actions.
getLangOpts().OpenCLGenericAddressSpace) {
4730 DiagID = diag::err_opencl_unknown_type_specifier;
4736 case tok::kw_private:
4740 goto DoneWithDeclSpec;
4742 case tok::kw___private:
4743 case tok::kw___global:
4744 case tok::kw___local:
4745 case tok::kw___constant:
4747 case tok::kw___read_only:
4748 case tok::kw___write_only:
4749 case tok::kw___read_write:
4753 case tok::kw_groupshared:
4766 goto DoneWithDeclSpec;
4771 if (
Type.isUsable()) {
4773 PrevSpec, DiagID,
Type.get(),
4775 Diag(StartLoc, DiagID) << PrevSpec;
4791 assert(PrevSpec &&
"Method did not return previous specifier!");
4794 if (DiagID == diag::ext_duplicate_declspec ||
4795 DiagID == diag::ext_warn_duplicate_declspec ||
4796 DiagID == diag::err_duplicate_declspec)
4800 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4804 Diag(
Loc, DiagID) << PrevSpec;
4807 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4811 AttrsLastTime =
false;
4823 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4826 for (
auto *I : RD->decls()) {
4827 auto *VD = dyn_cast<ValueDecl>(I);
4835 for (
const auto &DD : CAT->dependent_decls()) {
4836 if (!RD->containsDecl(DD.getDecl())) {
4837 P.Diag(VD->getBeginLoc(),
4838 diag::err_flexible_array_count_not_in_same_struct)
4840 P.Diag(DD.getDecl()->getBeginLoc(),
4841 diag::note_flexible_array_counted_by_attr_field)
4869 void Parser::ParseStructDeclaration(
4872 LateParsedAttrList *LateFieldAttrs) {
4874 if (Tok.
is(tok::kw___extension__)) {
4878 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4883 MaybeParseCXX11Attributes(Attrs);
4886 ParseSpecifierQualifierList(DS);
4890 if (Tok.
is(tok::semi)) {
4895 ProhibitAttributes(Attrs);
4899 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4905 bool FirstDeclarator =
true;
4909 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4912 if (!FirstDeclarator) {
4915 DiagnoseAndSkipCXX11Attributes();
4916 MaybeParseGNUAttributes(DeclaratorInfo.D);
4917 DiagnoseAndSkipCXX11Attributes();
4922 if (Tok.
isNot(tok::colon)) {
4925 ParseDeclarator(DeclaratorInfo.D);
4927 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.
getLocation());
4939 DeclaratorInfo.BitfieldSize = Res.
get();
4943 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
4946 Decl *
Field = FieldsCallback(DeclaratorInfo);
4948 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
4955 FirstDeclarator =
false;
4961 void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs,
bool EnterScope,
4963 assert(LAs.parseSoon() &&
4964 "Attribute list should be marked for immediate parsing.");
4965 for (
auto *LA : LAs) {
4966 ParseLexedCAttribute(*LA,
EnterScope, OutAttrs);
4977 void Parser::ParseLexedCAttribute(LateParsedAttribute &LA,
bool EnterScope,
4986 LA.Toks.push_back(AttrEnd);
4990 LA.Toks.push_back(Tok);
4991 PP.EnterTokenStream(LA.Toks,
true,
5002 assert(LA.Decls.size() <= 1 &&
5003 "late field attribute expects to have at most one declaration.");
5006 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
nullptr,
nullptr,
5009 for (
auto *D : LA.Decls)
5039 "parsing struct/union body");
5043 if (
T.consumeOpen())
5051 LateParsedAttrList LateFieldAttrs(
true,
5055 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
5060 if (Tok.
is(tok::semi)) {
5061 ConsumeExtraSemi(InsideStruct,
TagType);
5066 if (Tok.
isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
5068 ParseStaticAssertDeclaration(DeclEnd);
5072 if (Tok.
is(tok::annot_pragma_pack)) {
5077 if (Tok.
is(tok::annot_pragma_align)) {
5078 HandlePragmaAlign();
5082 if (Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
5086 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
5090 if (Tok.
is(tok::annot_pragma_openacc)) {
5099 ConsumeAnnotationToken();
5103 if (!Tok.
is(tok::at)) {
5109 FD.D, FD.BitfieldSize);
5116 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
5120 Diag(Tok, diag::err_unexpected_at);
5125 ExpectAndConsume(tok::l_paren);
5126 if (!Tok.
is(tok::identifier)) {
5127 Diag(Tok, diag::err_expected) << tok::identifier;
5135 ExpectAndConsume(tok::r_paren);
5141 if (Tok.
is(tok::r_brace)) {
5142 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
5146 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
5157 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
5160 ParseLexedCAttributeList(LateFieldAttrs,
false);
5165 T.getOpenLocation(),
T.getCloseLocation(), attrs);
5201 const ParsedTemplateInfo &TemplateInfo,
5204 if (Tok.
is(tok::code_completion)) {
5214 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5217 bool IsScopedUsingClassTag =
false;
5222 : diag::ext_scoped_enum);
5223 IsScopedUsingClassTag = Tok.
is(tok::kw_class);
5228 ProhibitAttributes(attrs);
5231 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5240 bool shouldDelayDiagsInTag =
5241 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
5242 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
5246 AllowDefiningTypeSpec AllowEnumSpecifier =
5248 bool CanBeOpaqueEnumDeclaration =
5249 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5252 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5253 CanBeOpaqueEnumDeclaration);
5261 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5266 if (Spec.
isSet() && Tok.
isNot(tok::identifier)) {
5267 Diag(Tok, diag::err_expected) << tok::identifier;
5269 if (Tok.
isNot(tok::l_brace)) {
5281 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::l_brace) &&
5282 Tok.
isNot(tok::colon)) {
5283 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5294 if (Tok.
is(tok::identifier)) {
5299 if (!Name && ScopedEnumKWLoc.
isValid()) {
5302 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5304 IsScopedUsingClassTag =
false;
5309 if (shouldDelayDiagsInTag)
5310 diagsFromTag.done();
5315 bool CanBeBitfield =
5319 if (Tok.
is(tok::colon)) {
5344 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5349 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5360 DeclSpecContext::DSC_type_specifier);
5365 BaseRange =
SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5369 Diag(ColonLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type)
5372 Diag(ColonLoc, diag::ext_cxx11_enum_fixed_underlying_type)
5375 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5378 Diag(ColonLoc, diag::ext_clang_c_enum_fixed_underlying_type)
5395 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5397 else if (Tok.
is(tok::l_brace)) {
5406 IsScopedUsingClassTag =
false;
5412 }
else if (!isTypeSpecifier(DSC) &&
5413 (Tok.
is(tok::semi) ||
5415 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5420 if (Tok.
isNot(tok::semi)) {
5422 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5430 bool IsElaboratedTypeSpecifier =
5436 diagsFromTag.redelay();
5440 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
5444 Diag(Tok, diag::err_enum_template);
5449 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
5452 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5456 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5458 TemplateInfo.TemplateParams->size());
5463 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5479 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5481 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5482 diag::err_keyword_not_allowed,
5485 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5486 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5487 else if (ScopedEnumKWLoc.
isValid())
5488 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5492 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5502 bool IsDependent =
false;
5503 const char *PrevSpec =
nullptr;
5508 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5509 IsScopedUsingClassTag,
5510 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5511 DSC == DeclSpecContext::DSC_template_param ||
5512 DSC == DeclSpecContext::DSC_template_type_arg,
5513 OffsetOfState, &SkipBody).
get();
5523 NameLoc.
isValid() ? NameLoc : StartLoc,
5524 PrevSpec, DiagID,
TagDecl, Owned,
5526 Diag(StartLoc, DiagID) << PrevSpec;
5535 Diag(Tok, diag::err_expected_type_name_after_typename);
5541 if (
Type.isInvalid()) {
5547 NameLoc.
isValid() ? NameLoc : StartLoc,
5548 PrevSpec, DiagID,
Type.get(),
5550 Diag(StartLoc, DiagID) << PrevSpec;
5569 ParseEnumBody(StartLoc, D);
5578 NameLoc.
isValid() ? NameLoc : StartLoc,
5579 PrevSpec, DiagID,
TagDecl, Owned,
5581 Diag(StartLoc, DiagID) << PrevSpec;
5604 Diag(Tok, diag::err_empty_enum);
5609 Decl *LastEnumConstDecl =
nullptr;
5612 while (Tok.
isNot(tok::r_brace)) {
5615 if (Tok.
isNot(tok::identifier)) {
5627 MaybeParseGNUAttributes(attrs);
5628 if (isAllowedCXX11AttributeSpecifier()) {
5631 ? diag::warn_cxx14_compat_ns_enum_attribute
5632 : diag::ext_ns_enum_attribute)
5634 ParseCXX11Attributes(attrs);
5639 EnumAvailabilityDiags.emplace_back(*
this);
5652 EqualLoc, AssignedVal.
get());
5653 EnumAvailabilityDiags.back().done();
5655 EnumConstantDecls.push_back(EnumConstDecl);
5656 LastEnumConstDecl = EnumConstDecl;
5658 if (Tok.
is(tok::identifier)) {
5661 Diag(
Loc, diag::err_enumerator_list_missing_comma)
5684 if (Tok.
is(tok::r_brace) && CommaLoc.
isValid()) {
5687 diag::ext_enumerator_list_comma_cxx :
5688 diag::ext_enumerator_list_comma_c)
5691 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5702 MaybeParseGNUAttributes(attrs);
5708 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5709 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5711 EnumAvailabilityDiags[i].redelay();
5712 PD.complete(EnumConstantDecls[i]);
5721 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5722 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5734 bool Parser::isKnownToBeTypeSpecifier(
const Token &Tok)
const {
5736 default:
return false;
5740 case tok::kw___int64:
5741 case tok::kw___int128:
5742 case tok::kw_signed:
5743 case tok::kw_unsigned:
5744 case tok::kw__Complex:
5745 case tok::kw__Imaginary:
5748 case tok::kw_wchar_t:
5749 case tok::kw_char8_t:
5750 case tok::kw_char16_t:
5751 case tok::kw_char32_t:
5753 case tok::kw__ExtInt:
5754 case tok::kw__BitInt:
5755 case tok::kw___bf16:
5758 case tok::kw_double:
5759 case tok::kw__Accum:
5760 case tok::kw__Fract:
5761 case tok::kw__Float16:
5762 case tok::kw___float128:
5763 case tok::kw___ibm128:
5766 case tok::kw__Decimal32:
5767 case tok::kw__Decimal64:
5768 case tok::kw__Decimal128:
5769 case tok::kw___vector:
5770 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5771 #include "clang/Basic/OpenCLImageTypes.def"
5775 case tok::kw_struct:
5776 case tok::kw___interface:
5782 case tok::annot_typename:
5789 bool Parser::isTypeSpecifierQualifier() {
5791 default:
return false;
5793 case tok::identifier:
5794 if (TryAltiVecVectorToken())
5797 case tok::kw_typename:
5802 if (Tok.
is(tok::identifier))
5804 return isTypeSpecifierQualifier();
5806 case tok::coloncolon:
5813 return isTypeSpecifierQualifier();
5816 case tok::kw___attribute:
5818 case tok::kw_typeof:
5819 case tok::kw_typeof_unqual:
5824 case tok::kw___int64:
5825 case tok::kw___int128:
5826 case tok::kw_signed:
5827 case tok::kw_unsigned:
5828 case tok::kw__Complex:
5829 case tok::kw__Imaginary:
5832 case tok::kw_wchar_t:
5833 case tok::kw_char8_t:
5834 case tok::kw_char16_t:
5835 case tok::kw_char32_t:
5837 case tok::kw__ExtInt:
5838 case tok::kw__BitInt:
5840 case tok::kw___bf16:
5842 case tok::kw_double:
5843 case tok::kw__Accum:
5844 case tok::kw__Fract:
5845 case tok::kw__Float16:
5846 case tok::kw___float128:
5847 case tok::kw___ibm128:
5850 case tok::kw__Decimal32:
5851 case tok::kw__Decimal64:
5852 case tok::kw__Decimal128:
5853 case tok::kw___vector:
5854 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5855 #include "clang/Basic/OpenCLImageTypes.def"
5859 case tok::kw_struct:
5860 case tok::kw___interface:
5867 case tok::kw_volatile:
5868 case tok::kw_restrict:
5872 case tok::kw___unknown_anytype:
5875 case tok::annot_typename:
5882 case tok::kw___cdecl:
5883 case tok::kw___stdcall:
5884 case tok::kw___fastcall:
5885 case tok::kw___thiscall:
5886 case tok::kw___regcall:
5887 case tok::kw___vectorcall:
5889 case tok::kw___ptr64:
5890 case tok::kw___ptr32:
5891 case tok::kw___pascal:
5892 case tok::kw___unaligned:
5894 case tok::kw__Nonnull:
5895 case tok::kw__Nullable:
5896 case tok::kw__Nullable_result:
5897 case tok::kw__Null_unspecified:
5899 case tok::kw___kindof:
5901 case tok::kw___private:
5902 case tok::kw___local:
5903 case tok::kw___global:
5904 case tok::kw___constant:
5905 case tok::kw___generic:
5906 case tok::kw___read_only:
5907 case tok::kw___read_write:
5908 case tok::kw___write_only:
5909 case tok::kw___funcref:
5912 case tok::kw_private:
5916 case tok::kw__Atomic:
5920 case tok::kw_groupshared:
5933 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5937 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5943 if (Tok.
is(tok::annot_repl_input_end) &&
5945 ConsumeAnnotationToken();
5950 DeclsInGroup.push_back(TLSD);
5953 for (
Stmt *S : Stmts) {
5958 DeclsInGroup.push_back(D);
5971 bool Parser::isDeclarationSpecifier(
5973 bool DisambiguatingWithExpression) {
5975 default:
return false;
5982 case tok::identifier:
5986 if (TryAltiVecVectorToken())
5989 case tok::kw_decltype:
5990 case tok::kw_typename:
5995 if (TryAnnotateTypeConstraint())
5997 if (Tok.
is(tok::identifier))
6005 if (DisambiguatingWithExpression &&
6006 isStartOfObjCClassMessageMissingOpenBracket())
6009 return isDeclarationSpecifier(AllowImplicitTypename);
6011 case tok::coloncolon:
6025 case tok::kw_typedef:
6026 case tok::kw_extern:
6027 case tok::kw___private_extern__:
6028 case tok::kw_static:
6030 case tok::kw___auto_type:
6031 case tok::kw_register:
6032 case tok::kw___thread:
6033 case tok::kw_thread_local:
6034 case tok::kw__Thread_local:
6037 case tok::kw___module_private__:
6040 case tok::kw___unknown_anytype:
6045 case tok::kw___int64:
6046 case tok::kw___int128:
6047 case tok::kw_signed:
6048 case tok::kw_unsigned:
6049 case tok::kw__Complex:
6050 case tok::kw__Imaginary:
6053 case tok::kw_wchar_t:
6054 case tok::kw_char8_t:
6055 case tok::kw_char16_t:
6056 case tok::kw_char32_t:
6059 case tok::kw__ExtInt:
6060 case tok::kw__BitInt:
6062 case tok::kw___bf16:
6064 case tok::kw_double:
6065 case tok::kw__Accum:
6066 case tok::kw__Fract:
6067 case tok::kw__Float16:
6068 case tok::kw___float128:
6069 case tok::kw___ibm128:
6072 case tok::kw__Decimal32:
6073 case tok::kw__Decimal64:
6074 case tok::kw__Decimal128:
6075 case tok::kw___vector:
6079 case tok::kw_struct:
6081 case tok::kw___interface:
6087 case tok::kw_volatile:
6088 case tok::kw_restrict:
6092 case tok::kw_inline:
6093 case tok::kw_virtual:
6094 case tok::kw_explicit:
6095 case tok::kw__Noreturn:
6098 case tok::kw__Alignas:
6101 case tok::kw_friend:
6104 case tok::kw_static_assert:
6105 case tok::kw__Static_assert:
6108 case tok::kw_typeof:
6109 case tok::kw_typeof_unqual:
6112 case tok::kw___attribute:
6115 case tok::annot_decltype:
6116 case tok::annot_pack_indexing_type:
6117 case tok::kw_constexpr:
6120 case tok::kw_consteval:
6121 case tok::kw_constinit:
6124 case tok::kw__Atomic:
6127 case tok::kw_alignas:
6137 case tok::annot_typename:
6138 return !DisambiguatingWithExpression ||
6139 !isStartOfObjCClassMessageMissingOpenBracket();
6142 case tok::annot_template_id: {
6148 return isTypeConstraintAnnotation() &&
6152 case tok::annot_cxxscope: {
6161 if (
NextToken().is(tok::identifier) && TryAnnotateTypeConstraint())
6163 return isTypeConstraintAnnotation() &&
6164 GetLookAheadToken(2).isOneOf(tok::kw_auto, tok::kw_decltype);
6167 case tok::kw___declspec:
6168 case tok::kw___cdecl:
6169 case tok::kw___stdcall:
6170 case tok::kw___fastcall:
6171 case tok::kw___thiscall:
6172 case tok::kw___regcall:
6173 case tok::kw___vectorcall:
6175 case tok::kw___sptr:
6176 case tok::kw___uptr:
6177 case tok::kw___ptr64:
6178 case tok::kw___ptr32:
6179 case tok::kw___forceinline:
6180 case tok::kw___pascal:
6181 case tok::kw___unaligned:
6183 case tok::kw__Nonnull:
6184 case tok::kw__Nullable:
6185 case tok::kw__Nullable_result:
6186 case tok::kw__Null_unspecified:
6188 case tok::kw___kindof:
6190 case tok::kw___private:
6191 case tok::kw___local:
6192 case tok::kw___global:
6193 case tok::kw___constant:
6194 case tok::kw___generic:
6195 case tok::kw___read_only:
6196 case tok::kw___read_write:
6197 case tok::kw___write_only:
6198 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
6199 #include "clang/Basic/OpenCLImageTypes.def"
6201 case tok::kw___funcref:
6202 case tok::kw_groupshared:
6205 case tok::kw_private:
6210 bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
6212 const ParsedTemplateInfo *TemplateInfo) {
6213 RevertingTentativeParsingAction TPA(*
this);
6216 if (TemplateInfo && TemplateInfo->TemplateParams)
6219 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6226 if (Tok.
is(tok::identifier)) {
6230 }
else if (Tok.
is(tok::annot_template_id)) {
6231 ConsumeAnnotationToken();
6238 SkipCXX11Attributes();
6241 if (Tok.
isNot(tok::l_paren)) {
6248 if (Tok.
is(tok::r_paren) ||
6249 (Tok.
is(tok::ellipsis) &&
NextToken().is(tok::r_paren))) {
6256 isCXX11AttributeSpecifier(
false,
6262 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6264 DeclScopeObj.EnterDeclaratorScope();
6268 MaybeParseMicrosoftAttributes(Attrs);
6277 bool IsConstructor =
false;
6283 if (Tok.
is(tok::kw_this)) {
6285 return isDeclarationSpecifier(ITC);
6288 if (isDeclarationSpecifier(ITC))
6289 IsConstructor =
true;
6290 else if (Tok.
is(tok::identifier) ||
6291 (Tok.
is(tok::annot_cxxscope) &&
NextToken().is(tok::identifier))) {
6296 if (Tok.
is(tok::annot_cxxscope))
6297 ConsumeAnnotationToken();
6309 case tok::coloncolon:
6322 SkipCXX11Attributes();
6324 if (DeductionGuide) {
6326 IsConstructor = Tok.
is(tok::arrow);
6329 if (Tok.
is(tok::colon) || Tok.
is(tok::kw_try)) {
6333 IsConstructor =
true;
6335 if (Tok.
is(tok::semi) || Tok.
is(tok::l_brace)) {
6348 IsConstructor = IsUnqualified;
6353 IsConstructor =
true;
6357 return IsConstructor;
6372 void Parser::ParseTypeQualifierListOpt(
6373 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicAllowed,
6374 bool IdentifierRequired,
6376 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6377 isAllowedCXX11AttributeSpecifier()) {
6379 ParseCXX11Attributes(Attrs);
6387 const char *PrevSpec =
nullptr;
6388 unsigned DiagID = 0;
6392 case tok::code_completion:
6395 (*CodeCompletionHandler)();
6404 case tok::kw_volatile:
6408 case tok::kw_restrict:
6412 case tok::kw__Atomic:
6414 goto DoneWithTypeQuals;
6415 diagnoseUseOfC11Keyword(Tok);
6421 case tok::kw_private:
6423 goto DoneWithTypeQuals;
6425 case tok::kw___private:
6426 case tok::kw___global:
6427 case tok::kw___local:
6428 case tok::kw___constant:
6429 case tok::kw___generic:
6430 case tok::kw___read_only:
6431 case tok::kw___write_only:
6432 case tok::kw___read_write:
6436 case tok::kw_groupshared:
6444 case tok::kw___unaligned:
6448 case tok::kw___uptr:
6453 if (TryKeywordIdentFallback(
false))
6457 case tok::kw___sptr:
6459 case tok::kw___ptr64:
6460 case tok::kw___ptr32:
6461 case tok::kw___cdecl:
6462 case tok::kw___stdcall:
6463 case tok::kw___fastcall:
6464 case tok::kw___thiscall:
6465 case tok::kw___regcall:
6466 case tok::kw___vectorcall:
6467 if (AttrReqs & AR_DeclspecAttributesParsed) {
6471 goto DoneWithTypeQuals;
6473 case tok::kw___funcref:
6476 goto DoneWithTypeQuals;
6478 case tok::kw___pascal:
6479 if (AttrReqs & AR_VendorAttributesParsed) {
6483 goto DoneWithTypeQuals;
6486 case tok::kw__Nonnull:
6487 case tok::kw__Nullable:
6488 case tok::kw__Nullable_result:
6489 case tok::kw__Null_unspecified:
6494 case tok::kw___kindof:
6496 nullptr, 0, tok::kw___kindof);
6500 case tok::kw___attribute:
6501 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6503 Diag(Tok, diag::err_attributes_not_allowed);
6507 if (AttrReqs & AR_GNUAttributesParsed ||
6508 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6526 assert(PrevSpec &&
"Method did not return previous specifier!");
6527 Diag(Tok, DiagID) << PrevSpec;
6534 void Parser::ParseDeclarator(
Declarator &D) {
6538 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6544 if (
Kind == tok::star ||
Kind == tok::caret)
6548 if (
Kind == tok::kw_pipe &&
Lang.OpenCL &&
6549 Lang.getOpenCLCompatibleVersion() >= 200)
6552 if (!
Lang.CPlusPlus)
6555 if (
Kind == tok::amp)
6563 if (
Kind == tok::ampamp)
6574 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6606 void Parser::ParseDeclaratorInternal(
Declarator &D,
6607 DirectDeclParseFunction DirectDeclParser) {
6615 (Tok.
is(tok::coloncolon) || Tok.
is(tok::kw_decltype) ||
6616 (Tok.
is(tok::identifier) &&
6618 Tok.
is(tok::annot_cxxscope))) {
6623 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6624 false, EnteringContext);
6627 if (Tok.
isNot(tok::star)) {
6632 AnnotateScopeToken(SS,
true);
6634 if (DirectDeclParser)
6635 (this->*DirectDeclParser)(D);
6640 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6641 CompoundToken::MemberPtr);
6647 ParseTypeQualifierListOpt(DS);
6652 ParseDeclaratorInternal(D, DirectDeclParser);
6669 ParseTypeQualifierListOpt(DS);
6678 if (DirectDeclParser)
6679 (this->*DirectDeclParser)(D);
6688 if (
Kind == tok::star ||
Kind == tok::caret) {
6694 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6696 ? AR_GNUAttributesParsed
6697 : AR_GNUAttributesParsedAndRejected);
6703 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6704 if (
Kind == tok::star)
6722 if (
Kind == tok::ampamp)
6724 diag::warn_cxx98_compat_rvalue_reference :
6725 diag::ext_rvalue_reference);
6728 ParseTypeQualifierListOpt(DS);
6737 diag::err_invalid_reference_qualifier_application) <<
"const";
6740 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6744 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6749 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6756 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6759 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6834 void Parser::ParseDirectDeclarator(
Declarator &D) {
6841 return ParseDecompositionDeclarator(D);
6855 ParseOptionalCXXScopeSpecifier(
6857 false, EnteringContext);
6876 DeclScopeObj.EnterDeclaratorScope();
6883 goto PastIdentifier;
6907 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6917 if (Tok.
isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6921 bool AllowConstructorName;
6922 bool AllowDeductionGuide;
6924 AllowConstructorName =
false;
6925 AllowDeductionGuide =
false;
6929 AllowDeductionGuide =
false;
6942 true, AllowConstructorName,
6943 AllowDeductionGuide, &TemplateKWLoc,
6956 DeclScopeObj.EnterDeclaratorScope();
6963 goto PastIdentifier;
6969 diag::err_expected_unqualified_id)
6972 goto PastIdentifier;
6976 "There's a C++-specific check for tok::identifier above");
6981 goto PastIdentifier;
6986 bool DiagnoseIdentifier =
false;
6990 DiagnoseIdentifier =
true;
6993 DiagnoseIdentifier =
7001 !isCXX11VirtSpecifier(Tok))
7003 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
7004 if (DiagnoseIdentifier) {
7009 goto PastIdentifier;
7013 if (Tok.
is(tok::l_paren)) {
7018 RevertingTentativeParsingAction PA(*
this);
7023 goto PastIdentifier;
7030 ParseParenDeclarator(D);
7043 DeclScopeObj.EnterDeclaratorScope();
7054 diag::ext_abstract_pack_declarator_parens);
7056 if (Tok.
getKind() == tok::annot_pragma_parser_crash)
7058 if (Tok.
is(tok::l_square))
7059 return ParseMisplacedBracketDeclarator(D);
7067 diag::err_expected_member_name_or_semi_objcxx_keyword)
7074 goto PastIdentifier;
7077 diag::err_expected_member_name_or_semi)
7081 if (Tok.
getKind() == tok::TokenKind::kw_while) {
7082 Diag(Tok, diag::err_while_loop_outside_of_a_function);
7084 if (Tok.
isOneOf(tok::period, tok::arrow))
7085 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.
is(tok::arrow);
7093 diag::err_expected_unqualified_id)
7098 diag::err_expected_either)
7099 << tok::identifier << tok::l_paren;
7108 "Haven't past the location of the identifier yet?");
7112 MaybeParseCXX11Attributes(D);
7115 if (Tok.
is(tok::l_paren)) {
7119 ParseScope PrototypeScope(
this,
7121 (IsFunctionDeclaration
7127 bool IsAmbiguous =
false;
7139 AllowImplicitTypename =
7147 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
7148 bool IsFunctionDecl =
7149 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
7150 TentativelyDeclaredIdentifiers.pop_back();
7151 if (!IsFunctionDecl)
7157 if (IsFunctionDeclaration)
7159 TemplateParameterDepth);
7160 ParseFunctionDeclarator(D, attrs,
T, IsAmbiguous);
7161 if (IsFunctionDeclaration)
7163 PrototypeScope.Exit();
7164 }
else if (Tok.
is(tok::l_square)) {
7165 ParseBracketDeclarator(D);
7173 if (!
T.consumeOpen())
7184 Diag(Tok, diag::err_requires_clause_inside_parens);
7198 void Parser::ParseDecompositionDeclarator(
Declarator &D) {
7199 assert(Tok.
is(tok::l_square));
7201 TentativeParsingAction PA(*
this);
7205 if (isCXX11AttributeSpecifier())
7206 DiagnoseAndSkipCXX11Attributes();
7210 if (!(Tok.
is(tok::identifier) &&
7213 !(Tok.
is(tok::r_square) &&
7216 return ParseMisplacedBracketDeclarator(D);
7220 while (Tok.
isNot(tok::r_square)) {
7222 if (Tok.
is(tok::comma))
7225 if (Tok.
is(tok::identifier)) {
7227 Diag(EndLoc, diag::err_expected)
7230 Diag(Tok, diag::err_expected_comma_or_rsquare);
7233 SkipUntil(tok::r_square, tok::comma, tok::identifier,
7235 if (Tok.
is(tok::comma))
7237 else if (Tok.
isNot(tok::identifier))
7242 if (isCXX11AttributeSpecifier())
7243 DiagnoseAndSkipCXX11Attributes();
7245 if (Tok.
isNot(tok::identifier)) {
7246 Diag(Tok, diag::err_expected) << tok::identifier;
7255 if (isCXX11AttributeSpecifier()) {
7257 ? diag::warn_cxx23_compat_decl_attrs_on_binding
7258 : diag::ext_decl_attrs_on_binding);
7259 MaybeParseCXX11Attributes(Attrs);
7265 if (Tok.
isNot(tok::r_square))
7280 T.getCloseLocation());
7296 void Parser::ParseParenDeclarator(
Declarator &D) {
7300 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7313 bool RequiresArg =
false;
7314 if (Tok.
is(tok::kw___attribute)) {
7315 ParseGNUAttributes(attrs);
7323 ParseMicrosoftTypeAttributes(attrs);
7326 if (Tok.
is(tok::kw___pascal))
7327 ParseBorlandTypeAttributes(attrs);
7339 }
else if (Tok.
is(tok::r_paren) ||
7342 isDeclarationSpecifier(
7344 isCXX11AttributeSpecifier()) {
7362 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7367 std::move(attrs),
T.getCloseLocation());
7373 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7386 ParseScope PrototypeScope(
this,
7390 ParseFunctionDeclarator(D, attrs,
T,
false, RequiresArg);
7391 PrototypeScope.Exit();
7394 void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7396 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7404 bool IsCXX11MemberFunction =
7412 if (!IsCXX11MemberFunction)
7432 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.
CurContext), Q,
7433 IsCXX11MemberFunction);
7456 void Parser::ParseFunctionDeclarator(
Declarator &D,
7461 assert(
getCurScope()->isFunctionPrototypeScope() &&
7462 "Should call from a Function scope");
7468 bool HasProto =
false;
7475 bool RefQualifierIsLValueRef =
true;
7493 StartLoc = LParenLoc;
7495 if (isFunctionDeclaratorIdentifierList()) {
7497 Diag(Tok, diag::err_argument_required_after_attribute);
7499 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7503 LocalEndLoc = RParenLoc;
7508 MaybeParseCXX11Attributes(FnAttrs);
7509 ProhibitAttributes(FnAttrs);
7511 if (Tok.
isNot(tok::r_paren))
7512 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7513 else if (RequiresArg)
7514 Diag(Tok, diag::err_argument_required_after_attribute);
7525 LocalEndLoc = RParenLoc;
7534 ParseTypeQualifierListOpt(
7535 DS, AR_NoAttributesParsed,
7537 false, llvm::function_ref<
void()>([&]() {
7545 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7546 EndLoc = RefQualifierLoc;
7548 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7549 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7567 GetLookAheadToken(0).is(tok::kw_noexcept) &&
7568 GetLookAheadToken(1).is(tok::l_paren) &&
7569 GetLookAheadToken(2).is(tok::kw_noexcept) &&
7570 GetLookAheadToken(3).is(tok::l_paren) &&
7571 GetLookAheadToken(4).is(tok::identifier) &&
7572 GetLookAheadToken(4).getIdentifierInfo()->isStr(
"swap")) {
7583 ESpecType = tryParseExceptionSpecification(Delayed,
7586 DynamicExceptionRanges,
7588 ExceptionSpecTokens);
7590 EndLoc = ESpecRange.
getEnd();
7594 MaybeParseCXX11Attributes(FnAttrs);
7597 LocalEndLoc = EndLoc;
7599 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7604 TrailingReturnType =
7610 MaybeParseCXX11Attributes(FnAttrs);
7622 if (!ND || isa<ParmVarDecl>(ND))
7624 DeclsInPrototype.push_back(ND);
7631 llvm::sort(DeclsInPrototype, [](
Decl *D1,
Decl *D2) {
7639 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7640 ParamInfo.size(), EllipsisLoc, RParenLoc,
7641 RefQualifierIsLValueRef, RefQualifierLoc,
7643 ESpecType, ESpecRange, DynamicExceptions.data(),
7644 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7645 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7646 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7647 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7649 std::move(FnAttrs), EndLoc);
7654 bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7656 if (Tok.
isOneOf(tok::amp, tok::ampamp)) {
7658 diag::warn_cxx98_compat_ref_qualifier :
7659 diag::ext_ref_qualifier);
7661 RefQualifierIsLValueRef = Tok.
is(tok::amp);
7673 bool Parser::isFunctionDeclaratorIdentifierList() {
7675 && Tok.
is(tok::identifier)
7676 && !TryAltiVecVectorToken()
7705 void Parser::ParseFunctionDeclaratorIdentifierList(
7709 assert(!
getLangOpts().requiresStrictPrototypes() &&
7710 "Cannot parse an identifier list in C23 or C++");
7717 Diag(Tok, diag::ext_ident_list_in_param);
7720 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
7724 if (Tok.
isNot(tok::identifier)) {
7725 Diag(Tok, diag::err_expected) << tok::identifier;
7736 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7739 if (!ParamsSoFar.insert(ParmII).second) {
7740 Diag(Tok, diag::err_param_redefinition) << ParmII;
7786 void Parser::ParseParameterDeclarationClause(
7795 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7816 IsACXXFunctionDeclaration) {
7838 ArgDeclSpecAttrs.takeAllFrom(FirstArgAttrs);
7841 MaybeParseCXX11Attributes(ArgDeclAttrs);
7844 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7865 Diag(ThisLoc, diag::err_requires_expr_explicit_object_parameter);
7868 ParsedTemplateInfo TemplateInfo;
7869 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7870 DeclSpecContext::DSC_normal,
7871 nullptr, AllowImplicitTypename);
7884 ParseDeclarator(ParmDeclarator);
7887 ParmDeclarator.SetRangeBegin(ThisLoc);
7890 MaybeParseGNUAttributes(ParmDeclarator);
7894 if (Tok.
is(tok::kw_requires)) {
7899 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7910 std::unique_ptr<CachedTokens> DefArgToks;
7914 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7915 ParmDeclarator.getNumTypeObjects() == 0) {
7917 Diag(DSStart, diag::err_missing_param);
7924 if (Tok.
is(tok::ellipsis) &&
7926 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7929 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7948 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7964 if (Tok.
is(tok::equal)) {
7975 ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument);
7991 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7992 DefArgResult = ParseBraceInitializer();
7994 if (Tok.
is(tok::l_paren) &&
NextToken().is(tok::l_brace)) {
7995 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
8012 DefArgResult.
get());
8018 ParmDeclarator.getIdentifierLoc(),
8019 Param, std::move(DefArgToks)));
8026 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
8028 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
8033 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
8034 << ParmEllipsis.
isValid() << ParmEllipsis;
8037 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
8039 Diag(ParmDeclarator.getIdentifierLoc(),
8040 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
8043 << !ParmDeclarator.hasName();
8045 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
8064 void Parser::ParseBracketDeclarator(
Declarator &D) {
8065 if (CheckProhibitedCXX11Attribute())
8073 if (Tok.
getKind() == tok::r_square) {
8076 MaybeParseCXX11Attributes(attrs);
8080 T.getOpenLocation(),
8081 T.getCloseLocation()),
8082 std::move(attrs),
T.getCloseLocation());
8084 }
else if (Tok.
getKind() == tok::numeric_constant &&
8085 GetLookAheadToken(1).is(tok::r_square)) {
8092 MaybeParseCXX11Attributes(attrs);
8096 T.getOpenLocation(),
8097 T.getCloseLocation()),
8098 std::move(attrs),
T.getCloseLocation());
8100 }
else if (Tok.
getKind() == tok::code_completion) {
8113 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
8121 bool isStar =
false;
8128 if (Tok.
is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
8132 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
8136 }
else if (Tok.
isNot(tok::r_square)) {
8154 Diag(StaticLoc, diag::err_unspecified_size_with_static);
8174 isStar, NumElements.
get(),
T.getOpenLocation(),
8175 T.getCloseLocation()),
8180 void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
8181 assert(Tok.
is(tok::l_square) &&
"Missing opening bracket");
8188 while (Tok.
is(tok::l_square)) {
8189 ParseBracketDeclarator(TempDeclarator);
8195 if (Tok.
is(tok::semi))
8201 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
8206 if (TempDeclarator.getNumTypeObjects() == 0)
8210 bool NeedParens =
false;
8235 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
8248 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
8252 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8260 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8280 void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
8281 assert(Tok.
isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
8282 "Not a typeof specifier");
8284 bool IsUnqual = Tok.
is(tok::kw_typeof_unqual);
8291 bool HasParens = Tok.
is(tok::l_paren);
8301 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange));
8317 const char *PrevSpec =
nullptr;
8325 Diag(StartLoc, DiagID) << PrevSpec;
8342 const char *PrevSpec =
nullptr;
8350 Diag(StartLoc, DiagID) << PrevSpec;
8356 void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
8357 assert(Tok.
is(tok::kw__Atomic) &&
NextToken().is(tok::l_paren) &&
8358 "Not an atomic specifier");
8362 if (
T.consumeOpen())
8366 if (Result.isInvalid()) {
8374 if (
T.getCloseLocation().isInvalid())
8380 const char *PrevSpec =
nullptr;
8383 DiagID, Result.get(),
8385 Diag(StartLoc, DiagID) << PrevSpec;
8390 bool Parser::TryAltiVecVectorTokenOutOfLine() {
8392 switch (Next.getKind()) {
8393 default:
return false;
8396 case tok::kw_signed:
8397 case tok::kw_unsigned:
8402 case tok::kw_double:
8405 case tok::kw___bool:
8406 case tok::kw___pixel:
8407 Tok.
setKind(tok::kw___vector);
8409 case tok::identifier:
8410 if (Next.getIdentifierInfo() == Ident_pixel) {
8411 Tok.
setKind(tok::kw___vector);
8414 if (Next.getIdentifierInfo() == Ident_bool ||
8415 Next.getIdentifierInfo() == Ident_Bool) {
8416 Tok.
setKind(tok::kw___vector);
8424 const char *&PrevSpec,
unsigned &DiagID,
8429 switch (Next.getKind()) {
8432 case tok::kw_signed:
8433 case tok::kw_unsigned:
8438 case tok::kw_double:
8441 case tok::kw___bool:
8442 case tok::kw___pixel:
8445 case tok::identifier:
8446 if (Next.getIdentifierInfo() == Ident_pixel) {
8450 if (Next.getIdentifierInfo() == Ident_bool ||
8451 Next.getIdentifierInfo() == Ident_Bool) {
8472 TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8479 FileID FID = SourceMgr.createFileID(
8480 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8484 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8485 L.setParsingPreprocessorDirective(
true);
8491 Tokens.push_back(Tok);
8492 }
while (Tok.
isNot(tok::eod));
8497 Token &EndToken = Tokens.back();
8504 Tokens.push_back(Tok);
8507 PP.EnterTokenStream(Tokens,
false,
8515 ParseScope LocalScope(
this, 0);
8521 if (Result.isUsable() &&
8537 void Parser::DiagnoseBitIntUse(
const Token &Tok) {
8541 assert(Tok.
isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8542 "expected either an _ExtInt or _BitInt token!");
8545 if (Tok.
is(tok::kw__ExtInt)) {
8546 Diag(
Loc, diag::warn_ext_int_deprecated)
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
static Decl::Kind getKind(const Decl *D)
Defines the C++ template declaration subclasses.
llvm::MachO::RecordLoc RecordLoc
static bool IsAttributeLateParsedExperimentalExt(const IdentifierInfo &II)
returns true iff attribute is annotated with LateAttrParseExperimentalExt in Attr....
static bool FindLocsWithCommonFileID(Preprocessor &PP, SourceLocation StartLoc, SourceLocation EndLoc)
Check if the a start and end source location expand to the same macro.
static bool IsAttributeLateParsedStandard(const IdentifierInfo &II)
returns true iff attribute is annotated with LateAttrParseStandard in Attr.td.
static bool attributeHasIdentifierArg(const IdentifierInfo &II)
Determine whether the given attribute has an identifier argument.
static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II)
Determine whether the given attribute treats kw_this as an identifier.
static StringRef normalizeAttrName(StringRef Name)
Normalizes an attribute name by dropping prefixed and suffixed __.
static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II)
Determine whether the given attribute requires parsing its arguments in an unevaluated context or not...
static bool isValidAfterIdentifierInDeclarator(const Token &T)
isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the specified token is valid after t...
static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II)
Determine whether the given attribute has a variadic identifier argument.
static bool attributeAcceptsExprPack(const IdentifierInfo &II)
Determine if an attribute accepts parameter packs.
static bool isPipeDeclarator(const Declarator &D)
static SourceLocation getMissingDeclaratorIdLoc(Declarator &D, SourceLocation Loc)
static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS, Parser &P)
static bool VersionNumberSeparator(const char Separator)
static bool attributeIsTypeArgAttr(const IdentifierInfo &II)
Determine whether the given attribute parses a type argument.
static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, DeclaratorContext TheContext)
static ParsedAttributeArgumentsProperties attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II)
Determine whether the given attribute has an identifier argument.
llvm::SmallVector< std::pair< const MemRegion *, SVal >, 4 > Bindings
constexpr static bool isOneOf()
This file declares semantic analysis for CUDA constructs.
This file declares facilities that support code completion.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenMP constructs and clauses.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the clang::TokenKind enum and support functions.
const NestedNameSpecifier * Specifier
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const clang::PrintingPolicy & getPrintingPolicy() const
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
The result of parsing/analyzing an expression, statement etc.
@ AS_Declspec
__declspec(...)
Kind getParsedKind() const
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
SourceLocation getOpenLocation() const
SourceLocation getCloseLocation() const
Represents a C++ nested-name-specifier or a global scope specifier.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
SourceLocation getEndLoc() const
bool isSet() const
Deprecated.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
void setTemplateParamLists(ArrayRef< TemplateParameterList * > L)
bool isEmpty() const
No scope specifier.
Represents a character-granular source range.
SourceLocation getBegin() const
Callback handler that receives notifications when performing code completion within the preprocessor.
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed.
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Captures information about "declaration specifiers".
bool isVirtualSpecified() const
bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, ExplicitSpecifier ExplicitSpec, SourceLocation CloseParenLoc)
bool isTypeSpecPipe() const
static const TSCS TSCS___thread
static const TST TST_typeof_unqualType
void setTypeArgumentRange(SourceRange range)
bool SetTypePipe(bool isPipe, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
SourceLocation getPipeLoc() const
static const TST TST_typename
SourceLocation getEndLoc() const LLVM_READONLY
bool hasTypeSpecifier() const
Return true if any type-specifier has been found.
bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec and return false if there was no error.
static const TST TST_char8
static const TST TST_BFloat16
void ClearStorageClassSpecs()
bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TSCS TSCS__Thread_local
bool SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec, but return true and ignore the request if ...
bool isNoreturnSpecified() const
TST getTypeSpecType() const
SourceLocation getStorageClassSpecLoc() const
SCS getStorageClassSpec() const
bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceRange getSourceRange() const LLVM_READONLY
bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void SetRangeEnd(SourceLocation Loc)
bool SetBitIntType(SourceLocation KWLoc, Expr *BitWidth, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_auto_type
static const TST TST_interface
static const TST TST_double
static const TST TST_typeofExpr
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
void SetRangeStart(SourceLocation Loc)
bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getNoreturnSpecLoc() const
static const TST TST_union
static const TST TST_char
static const TST TST_bool
static const TST TST_char16
SourceLocation getExplicitSpecLoc() const
SourceLocation getFriendSpecLoc() const
SourceLocation getModulePrivateSpecLoc() const
bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void UpdateTypeRep(ParsedType Rep)
TSCS getThreadStorageClassSpec() const
bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasAttributes() const
static const TST TST_accum
static const TST TST_half
ParsedAttributes & getAttributes()
SourceLocation getConstSpecLoc() const
static const TST TST_ibm128
void addAttributes(const ParsedAttributesView &AL)
Concatenates two attribute lists.
static const TST TST_enum
bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_float128
void Finish(Sema &S, const PrintingPolicy &Policy)
Finish - This does final analysis of the declspec, issuing diagnostics for things like "_Imaginary" (...
bool isInlineSpecified() const
SourceLocation getRestrictSpecLoc() const
static const TST TST_typeof_unqualExpr
static const TST TST_class
bool hasTagDefinition() const
static const TST TST_decimal64
unsigned getParsedSpecifiers() const
Return a bitmask of which flavors of specifiers this DeclSpec includes.
void ClearFunctionSpecs()
bool SetTypeQual(TQ T, SourceLocation Loc)
CXXScopeSpec & getTypeSpecScope()
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
static const TST TST_float16
static const TST TST_unspecified
SourceLocation getAtomicSpecLoc() const
SourceLocation getVirtualSpecLoc() const
SourceLocation getConstexprSpecLoc() const
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
Decl * getRepAsDecl() const
SourceLocation getVolatileSpecLoc() const
FriendSpecified isFriendSpecified() const
bool hasExplicitSpecifier() const
bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasConstexprSpecifier() const
void takeAttributesFrom(ParsedAttributes &attrs)
static const TST TST_typeofType
bool SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_auto
@ PQ_StorageClassSpecifier
ConstexprSpecKind getConstexprSpecifier() const
static const TST TST_struct
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
Information about one declarator, including the parsed type information and the identifier.
bool isFunctionDeclarator(unsigned &idx) const
isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
The template parameter lists that preceded the declarator.
bool isPastIdentifier() const
isPastIdentifier - Return true if we have parsed beyond the point where the name would appear.
void SetRangeBegin(SourceLocation Loc)
SetRangeBegin - Set the start of the source range to Loc, unless it's invalid.
void setCommaLoc(SourceLocation CL)
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
SourceLocation getIdentifierLoc() const
void SetIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
bool mayOmitIdentifier() const
mayOmitIdentifier - Return true if the identifier is either optional or not allowed.
SourceLocation getEndLoc() const LLVM_READONLY
bool mayBeFollowedByCXXDirectInit() const
mayBeFollowedByCXXDirectInit - Return true if the declarator can be followed by a C++ direct initiali...
bool hasGroupingParens() const
void setDecompositionBindings(SourceLocation LSquareLoc, MutableArrayRef< DecompositionDeclarator::Binding > Bindings, SourceLocation RSquareLoc)
Set the decomposition bindings for this declarator.
void setInvalidType(bool Val=true)
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
bool mayHaveIdentifier() const
mayHaveIdentifier - Return true if the identifier is either optional or required.
void setGroupingParens(bool flag)
SourceLocation getEllipsisLoc() const
DeclaratorContext getContext() const
SourceLocation getBeginLoc() const LLVM_READONLY
void setTrailingRequiresClause(Expr *TRC)
Sets a trailing requires clause for this declarator.
void setHasInitializer(bool Val=true)
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.
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
bool isFunctionDeclaratorAFunctionDeclaration() const
Return true if a function declarator at this position would be a function declaration.
void clear()
Reset the contents of this Declarator.
UnqualifiedId & getName()
Retrieve the name specified by 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.
const IdentifierInfo * getIdentifier() const
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
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.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool requiresStrictPrototypes() const
Returns true if functions without prototypes or functions with an identifier list (aka K&R C function...
std::string getOpenCLVersionString() const
Return the OpenCL C or C++ for OpenCL language name and version as a string.
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static bool isAtStartOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroBegin=nullptr)
Returns true if the given MacroID location points at the first token of the macro expansion.
static bool isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroEnd=nullptr)
Returns true if the given MacroID location points at the last token of the macro expansion.
static bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, const LangOptions &LangOpts, bool IgnoreWhiteSpace=false)
Relex the token at the specified location.
static std::optional< Token > findNextToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Finds the token that comes right after the given location.
Represents the results of name lookup.
This represents a decl that may have a name.
bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...
Represents a parameter to a function.
static constexpr unsigned getMaxFunctionScopeDepth()
ParsedAttr - Represents a syntactic attribute.
unsigned getMaxArgs() const
static const ParsedAttributesView & none()
void addAtEnd(ParsedAttr *newAttr)
void addAll(iterator B, iterator E)
void remove(ParsedAttr *ToBeRemoved)
ParsedAttributes - A collection of parsed attributes.
void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA)
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 * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Form formUsed)
Add microsoft __delspec(property) 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.
void takeAllFrom(ParsedAttributes &Other)
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.
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)
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
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.
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
Scope * getCurScope() const
Sema & getActions() const
ObjCContainerDecl * getObjCDeclContext() const
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)
const LangOptions & getLangOpts() const
SourceLocation getEndOfPreviousToken()
ExprResult ParseArrayBoundExpression()
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
friend class ObjCDeclContextSwitch
const TargetInfo & getTargetInfo() const
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
ExprResult ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast=NotTypeCast)
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()
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.
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 ...
bool isCodeCompletionReached() const
Returns true if code-completion is enabled and we have hit the code-completion point.
const LangOptions & getLangOpts() const
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
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.
static Qualifiers fromCVRUMask(unsigned CVRU)
void addAddressSpace(LangAS space, bool AllowDefaultAddrSpace=false)
Represents a struct/union/class.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isClassScope() const
isClassScope - Return true if this scope is a class/struct/union scope.
unsigned getFlags() const
getFlags - Return the flags for this scope.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ BlockScope
This is a scope that corresponds to a block/closure object.
@ FriendScope
This is a scope of friend declaration.
@ ControlScope
The controlling scope in a if/switch/while/for statement.
@ AtCatchScope
This is a scope that corresponds to the Objective-C @catch statement.
@ TemplateParamScope
This is a scope that corresponds to the template parameters of a C++ template.
@ CompoundStmtScope
This is a compound statement scope.
@ ClassScope
The scope of a struct/union/class definition.
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ EnumScope
This scope corresponds to an enum.
@ DeclScope
This is a scope that can contain a declaration.
@ CTCK_InitGlobalVar
Unknown context.
void CodeCompleteAttribute(AttributeCommonInfo::Syntax Syntax, AttributeCompletion Completion=AttributeCompletion::Attribute, const IdentifierInfo *Scope=nullptr)
ParserCompletionContext
Describes the context in which code completion occurs.
@ PCC_LocalDeclarationSpecifiers
Code completion occurs within a sequence of declaration specifiers within a function,...
@ PCC_MemberTemplate
Code completion occurs following one or more template headers within a class.
@ PCC_Class
Code completion occurs within a class, struct, or union.
@ PCC_ObjCImplementation
Code completion occurs within an Objective-C implementation or category implementation.
@ PCC_Namespace
Code completion occurs at top-level or namespace context.
@ PCC_Template
Code completion occurs following one or more template headers.
void CodeCompleteTypeQualifiers(DeclSpec &DS)
void CodeCompleteAfterFunctionEquals(Declarator &D)
QualType ProduceConstructorSignatureHelp(QualType Type, SourceLocation Loc, ArrayRef< Expr * > Args, SourceLocation OpenParLoc, bool Braced)
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
void CodeCompleteInitializer(Scope *S, Decl *D)
void CodeCompleteBracketDeclarator(Scope *S)
void CodeCompleteTag(Scope *S, unsigned TagSpec)
void CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, bool AllowNonIdentifiers, bool AllowNestedNameSpecifiers)
ParsedType ActOnObjCInstanceType(SourceLocation Loc)
The parser has parsed the context-sensitive type 'instancetype' in an Objective-C message declaration...
void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, const IdentifierInfo *ClassName, SmallVectorImpl< Decl * > &Decls)
Called whenever @defs(ClassName) is encountered in the source.
void startOpenMPCXXRangeFor()
If the current region is a range loop-based region, mark the start of the loop construct.
NameClassificationKind getKind() const
OpenCLOptions & getOpenCLOptions()
bool containsUnexpandedParameterPacks(Declarator &D)
Determine whether the given declarator contains any unexpanded parameter packs.
void ActOnParamUnparsedDefaultArgument(Decl *param, SourceLocation EqualLoc, SourceLocation ArgLoc)
ActOnParamUnparsedDefaultArgument - We've seen a default argument for a function parameter,...
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
void ActOnDefinedDeclarationSpecifier(Decl *D)
Called once it is known whether a tag declaration is an anonymous union or struct.
ExplicitSpecifier ActOnExplicitBoolSpecifier(Expr *E)
ActOnExplicitBoolSpecifier - Build an ExplicitSpecifier from an expression found in an explicit(bool)...
void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc, Expr *DefaultArg)
ActOnParamDefaultArgumentError - Parsing or semantic analysis of the default argument for the paramet...
TemplateParameterList * ActOnTemplateParameterList(unsigned Depth, SourceLocation ExportLoc, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
ActOnTemplateParameterList - Builds a TemplateParameterList, optionally constrained by RequiresClause...
void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl, SourceRange BraceRange)
ActOnTagFinishDefinition - Invoked once we have finished parsing the definition of a tag (enumeration...
Decl * ActOnParamDeclarator(Scope *S, Declarator &D, SourceLocation ExplicitThisLoc={})
ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator() to introduce parameters into fun...
TypeResult ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, const CXXScopeSpec &SS, const IdentifierInfo *Name, SourceLocation TagLoc, SourceLocation NameLoc)
Decl * ActOnTemplateDeclarator(Scope *S, MultiTemplateParamsArg TemplateParameterLists, Declarator &D)
TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S)
isTagName() - This method is called for error recovery purposes only to determine if the specified na...
void ActOnFinishFunctionDeclarationDeclarator(Declarator &D)
Called after parsing a function declarator belonging to a function declaration.
void ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc, Expr *defarg)
ActOnParamDefaultArgument - Check whether the default argument provided for a function parameter is w...
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
void ActOnFinishTopLevelStmtDecl(TopLevelStmtDecl *D, Stmt *Statement)
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param)
This is used to implement the constant expression evaluation part of the attribute enable_if extensio...
bool isCurrentClassName(const IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS=nullptr)
isCurrentClassName - Determine whether the identifier II is the name of the class type currently bein...
@ NC_Unknown
This name is not a type or template in this context, but might be something else.
@ NC_VarTemplate
The name was classified as a variable template name.
@ NC_NonType
The name was classified as a specific non-type, non-template declaration.
@ NC_TypeTemplate
The name was classified as a template whose specializations are types.
@ NC_Error
Classification failed; an error has been produced.
@ NC_FunctionTemplate
The name was classified as a function template name.
@ NC_DependentNonType
The name denotes a member of a dependent type that could not be resolved.
@ NC_UndeclaredNonType
The name was classified as an ADL-only function name.
@ NC_UndeclaredTemplate
The name was classified as an ADL-only function template name.
@ NC_Keyword
The name has been typo-corrected to a keyword.
@ NC_Type
The name was classified as a type.
@ NC_OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ NC_Concept
The name was classified as a concept name.
void ActOnStartFunctionDeclarationDeclarator(Declarator &D, unsigned TemplateParameterDepth)
Called before parsing a function declarator belonging to a function declaration.
ExprResult ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val)
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
SkipBodyInfo shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II, SourceLocation IILoc)
Determine whether the body of an anonymous enumeration should be skipped.
bool isUnexpandedParameterPackPermitted()
Determine whether an unexpanded parameter pack might be permitted in this location.
bool ActOnAlignasTypeArgument(StringRef KWName, ParsedType Ty, SourceLocation OpLoc, SourceRange R)
ActOnAlignasTypeArgument - Handle alignas(type-id) and _Alignas(type-name) .
bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, UnexpandedParameterPackContext UPPC)
If the given type contains an unexpanded parameter pack, diagnose the error.
const LangOptions & getLangOpts() const
bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS)
NameClassification ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, SourceLocation NameLoc, const Token &NextToken, CorrectionCandidateCallback *CCC=nullptr)
Perform name lookup on the given name, classifying it based on the results of name lookup and the fol...
bool isLibstdcxxEagerExceptionSpecHack(const Declarator &D)
Determine if we're in a case where we need to (incorrectly) eagerly parse an exception specification ...
Decl * ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant, SourceLocation IdLoc, IdentifierInfo *Id, const ParsedAttributesView &Attrs, SourceLocation EqualLoc, Expr *Val)
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
bool isDeclaratorFunctionLike(Declarator &D)
Determine whether.
bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody)
Perform ODR-like check for C/ObjC when merging tag types from modules.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
void RestoreNestedNameSpecifierAnnotation(void *Annotation, SourceRange AnnotationRange, CXXScopeSpec &SS)
Given an annotation pointer for a nested-name-specifier, restore the nested-name-specifier structure.
bool CheckTypeConstraint(TemplateIdAnnotation *TypeConstraint)
void ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, Decl *EnumDecl, ArrayRef< Decl * > Elements, Scope *S, const ParsedAttributesView &Attr)
void ActOnTagStartDefinition(Scope *S, Decl *TagDecl)
ActOnTagStartDefinition - Invoked when we have entered the scope of a tag's definition (e....
void ActOnInitializerError(Decl *Dcl)
ActOnInitializerError - Given that there was an error parsing an initializer for the given declaratio...
TypeResult ActOnTypeName(Declarator &D)
TopLevelStmtDecl * ActOnStartTopLevelStmtDecl(Scope *S)
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion.
DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, ArrayRef< Decl * > Group)
ParsedType ActOnMSVCUnknownTypeName(const IdentifierInfo &II, SourceLocation NameLoc, bool IsTemplateTypeArg)
Attempt to behave like MSVC in situations where lookup of an unqualified type name has failed in a de...
ASTContext & getASTContext() const
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type.
DeclResult ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc, SourceLocation TemplateLoc, unsigned TagSpec, SourceLocation KWLoc, const CXXScopeSpec &SS, TemplateTy Template, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, const ParsedAttributesView &Attr)
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
@ PotentiallyEvaluatedIfUsed
The current expression is potentially evaluated, but any declarations referenced inside that expressi...
DeclResult ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, const ParsedAttributesView &Attr, AccessSpecifier AS, SourceLocation ModulePrivateLoc, MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl, bool &IsDependent, SourceLocation ScopedEnumKWLoc, bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, bool IsTypeSpecifier, bool IsTemplateParamOrArg, OffsetOfKind OOK, SkipBodyInfo *SkipBody=nullptr)
This is invoked when we see 'struct foo' or 'struct {'.
Decl * ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, const ParsedAttributesView &DeclAttrs, RecordDecl *&AnonRecord)
ParsedFreeStandingDeclSpec - This method is invoked when a declspec with no declarator (e....
void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl, ArrayRef< Decl * > Fields, SourceLocation LBrac, SourceLocation RBrac, const ParsedAttributesView &AttrList)
SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts
A stack of expression evaluation contexts.
bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name, SourceLocation NameLoc, CXXScopeSpec &SS, ParsedTemplateTy *Template=nullptr)
Determine whether a particular identifier might be the name in a C++1z deduction-guide declaration.
void ActOnFinishDelayedAttribute(Scope *S, Decl *D, ParsedAttributes &Attrs)
ActOnFinishDelayedAttribute - Invoked when we have finished parsing an attribute for which parsing is...
void ActOnUninitializedDecl(Decl *dcl)
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
Decl * ActOnField(Scope *S, Decl *TagD, SourceLocation DeclStart, Declarator &D, Expr *BitfieldWidth)
ActOnField - Each field of a C struct/union is passed into this in order to create a FieldDecl object...
void ActOnCXXForRangeDecl(Decl *D)
Decl * ActOnDeclarator(Scope *S, Declarator &D)
ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope=nullptr)
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
void DiagnoseUnknownTypeName(IdentifierInfo *&II, SourceLocation IILoc, Scope *S, CXXScopeSpec *SS, ParsedType &SuggestedType, bool IsTemplateName=false)
ExprResult HandleExprEvaluationContextForTypeof(Expr *E)
SemaCodeCompletion & CodeCompletion()
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.
SourceLocation getEndLoc() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
unsigned getLength() const
void * getAnnotationValue() const
void setKind(tok::TokenKind K)
const char * getName() const
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)) {....
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)
IdentifierInfo * getIdentifierInfo() const
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.
bool Init(InterpState &S, CodePtr OpPC)
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.
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...
ActionResult< Stmt * > StmtResult
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Dependent_template_name
The name refers to a dependent template name:
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ Parens
New-expression has a C++98 paren-delimited initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_None
no exception specification
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Represents information about a change in availability for an entity, which is part of the encoding of...
VersionTuple Version
The version number at which the change occurred.
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
SourceRange VersionRange
The source range covering the version number.
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
ParamInfo - An array of paraminfo objects is allocated whenever a function declarator is parsed.
One instance of this struct is used for each type in a declarator that is parsed.
enum clang::DeclaratorChunk::@221 Kind
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, ArrayRef< NamedDecl * > DeclsInPrototype, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult(), SourceLocation TrailingReturnTypeLoc=SourceLocation(), DeclSpec *MethodQualifiers=nullptr)
DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
static DeclaratorChunk getPipe(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc)
Return a DeclaratorChunk for an array.
SourceLocation Loc
Loc - The place where this type was defined.
static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, unsigned TypeQuals, SourceLocation StarLoc, SourceLocation EndLoc)
static DeclaratorChunk getParen(SourceLocation LParenLoc, SourceLocation RParenLoc)
Return a DeclaratorChunk for a paren.
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, SourceLocation AtomicQualLoc, SourceLocation UnalignedQualLoc)
Return a DeclaratorChunk for a pointer.
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, bool lvalue)
Return a DeclaratorChunk for a reference.
Wraps an identifier and optional source location for the identifier.
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
bool isStringLiteralArg(unsigned I) const
Describes how types, statements, expressions, and declarations should be printed.
ExpressionKind
Describes whether we are in an expression constext which we have to handle differently.
Information about a template-id annotation token.
bool hasInvalidName() const
const IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
TemplateNameKind Kind
The kind of template that Template refers to.
bool hasInvalidArgs() const