32#include "llvm/ADT/SmallSet.h"
33#include "llvm/ADT/SmallString.h"
34#include "llvm/ADT/StringSwitch.h"
51 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
52 if (DSC == DeclSpecContext::DSC_normal)
53 DSC = DeclSpecContext::DSC_type_specifier;
59 ParseSpecifierQualifierList(DS, AS, DSC);
67 if (AL.isDeclspecAttribute())
68 ToBeMoved.push_back(&AL);
77 ParseDeclarator(DeclaratorInfo);
89 if (Name.size() >= 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
90 return Name.drop_front(2).drop_back(2);
97#define CLANG_ATTR_LATE_PARSED_LIST
99#include "clang/Parse/AttrParserStringSwitches.inc"
101#undef CLANG_ATTR_LATE_PARSED_LIST
111 if (
SM.getFileID(StartLoc) !=
SM.getFileID(EndLoc))
114 bool AttrStartIsInMacro =
116 bool AttrEndIsInMacro =
118 return AttrStartIsInMacro && AttrEndIsInMacro;
121void Parser::ParseAttributes(
unsigned WhichAttrKinds,
ParsedAttributes &Attrs,
122 LateParsedAttrList *LateAttrs) {
128 if (WhichAttrKinds & PAKM_CXX11)
129 MoreToParse |= MaybeParseCXX11Attributes(Attrs);
130 if (WhichAttrKinds & PAKM_GNU)
131 MoreToParse |= MaybeParseGNUAttributes(Attrs, LateAttrs);
132 if (WhichAttrKinds & PAKM_Declspec)
133 MoreToParse |= MaybeParseMicrosoftDeclSpecs(Attrs);
134 }
while (MoreToParse);
179 LateParsedAttrList *LateAttrs,
Declarator *D) {
180 assert(Tok.
is(tok::kw___attribute) &&
"Not a GNU attribute list!");
185 while (Tok.
is(tok::kw___attribute)) {
187 unsigned OldNumAttrs = Attrs.
size();
188 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
190 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
195 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"(")) {
208 if (Tok.
is(tok::code_completion)) {
219 if (Tok.
isNot(tok::l_paren)) {
220 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
221 ParsedAttr::Form::GNU());
227 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc,
nullptr,
233 LateParsedAttribute *LA =
234 new LateParsedAttribute(
this, *AttrName, AttrNameLoc);
235 LateAttrs->push_back(LA);
239 if (!ClassStack.empty() && !LateAttrs->parseSoon())
240 getCurrentClass().LateParsedDeclarations.push_back(LA);
244 LA->Toks.push_back(Tok);
247 ConsumeAndStoreUntil(tok::r_paren, LA->Toks,
true);
252 LA->Toks.push_back(Eof);
253 }
while (Tok.
is(tok::comma));
255 if (ExpectAndConsume(tok::r_paren))
258 if (ExpectAndConsume(tok::r_paren))
265 if (!
SM.isWrittenInBuiltinFile(
SM.getSpellingLoc(AttrTokLoc)) &&
268 StringRef FoundName =
272 for (
unsigned i = OldNumAttrs; i < Attrs.
size(); ++i)
273 Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.
getBegin());
276 for (
unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
277 (*LateAttrs)[i]->MacroII = MacroII;
287#define CLANG_ATTR_IDENTIFIER_ARG_LIST
289#include "clang/Parse/AttrParserStringSwitches.inc"
291#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
297#define CLANG_ATTR_STRING_LITERAL_ARG_LIST
299#include "clang/Parse/AttrParserStringSwitches.inc"
301#undef CLANG_ATTR_STRING_LITERAL_ARG_LIST
306#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
308#include "clang/Parse/AttrParserStringSwitches.inc"
310#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
315#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
317#include "clang/Parse/AttrParserStringSwitches.inc"
319#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
324#define CLANG_ATTR_ACCEPTS_EXPR_PACK
326#include "clang/Parse/AttrParserStringSwitches.inc"
328#undef CLANG_ATTR_ACCEPTS_EXPR_PACK
333#define CLANG_ATTR_TYPE_ARG_LIST
335#include "clang/Parse/AttrParserStringSwitches.inc"
337#undef CLANG_ATTR_TYPE_ARG_LIST
343#define CLANG_ATTR_ARG_CONTEXT_LIST
345#include "clang/Parse/AttrParserStringSwitches.inc"
347#undef CLANG_ATTR_ARG_CONTEXT_LIST
351 assert(Tok.
is(tok::identifier) &&
"expected an identifier");
369 if (Tok.
isNot(tok::r_paren))
372 if (
Parens.consumeClose())
381 ScopeName, ScopeLoc,
T.get(), Form);
384 ScopeName, ScopeLoc,
nullptr, 0, Form);
388Parser::ParseUnevaluatedStringInAttribute(
const IdentifierInfo &AttrName) {
389 if (Tok.
is(tok::l_paren)) {
392 ExprResult Res = ParseUnevaluatedStringInAttribute(AttrName);
393 Paren.consumeClose();
396 if (!isTokenStringLiteral()) {
404bool Parser::ParseAttributeArgumentList(
407 bool SawError =
false;
412 Expr = ParseUnevaluatedStringInAttribute(AttrName);
414 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
415 Expr = ParseBraceInitializer();
421 if (Tok.
is(tok::ellipsis))
423 else if (Tok.
is(tok::code_completion)) {
434 if (
Expr.isInvalid()) {
439 Exprs.push_back(
Expr.get());
441 if (Tok.
isNot(tok::comma))
446 checkPotentialAngleBracketDelimiter(Comma);
453 for (
auto &E : Exprs) {
462unsigned Parser::ParseAttributeArgsCommon(
471 bool AttributeHasVariadicIdentifierArg =
475 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
479 if (Tok.
is(tok::identifier)) {
481 bool IsIdentifierArg = AttributeHasVariadicIdentifierArg ||
491 IsIdentifierArg = Next.isOneOf(tok::r_paren, tok::comma);
495 ArgExprs.push_back(ParseIdentifierLoc());
499 if (!ArgExprs.empty() ? Tok.
is(tok::comma) : Tok.
isNot(tok::r_paren)) {
501 if (!ArgExprs.empty())
504 if (AttributeIsTypeArgAttr) {
512 TheParsedType =
T.get();
513 }
else if (AttributeHasVariadicIdentifierArg) {
521 if (ChangeKWThisToIdent && Tok.
is(tok::kw_this))
525 if (Tok.
is(tok::identifier)) {
526 ArgExprs.push_back(ParseIdentifierLoc());
541 ArgExprs.push_back(ArgExpr.
get());
553 ExprVector ParsedExprs;
556 if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties)) {
562 for (
size_t I = 0; I < ParsedExprs.size(); ++I) {
563 if (!isa<PackExpansionExpr>(ParsedExprs[I]))
568 diag::err_attribute_argument_parm_pack_not_supported)
575 ArgExprs.insert(ArgExprs.end(), ParsedExprs.begin(), ParsedExprs.end());
580 if (!ExpectAndConsume(tok::r_paren)) {
583 if (AttributeIsTypeArgAttr && !TheParsedType.
get().
isNull()) {
585 ScopeName, ScopeLoc, TheParsedType, Form);
588 ArgExprs.data(), ArgExprs.size(), Form);
595 return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.
get().
isNull());
600void Parser::ParseGNUAttributeArgs(
605 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
610 if (AttrKind == ParsedAttr::AT_Availability) {
611 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
614 }
else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
615 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
616 ScopeName, ScopeLoc, Form);
618 }
else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
619 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
620 ScopeName, ScopeLoc, Form);
622 }
else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
623 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
626 }
else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
627 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
628 ScopeName, ScopeLoc, Form);
631 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName,
634 }
else if (AttrKind == ParsedAttr::AT_CountedBy) {
635 ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
642 std::optional<ParseScope> PrototypeScope;
649 for (
unsigned i = 0; i != FTI.
NumParams; ++i) {
655 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
659unsigned Parser::ParseClangAttributeArgs(
663 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
670 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
671 ScopeName, ScopeLoc, Form);
672 case ParsedAttr::AT_ExternalSourceSymbol:
673 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
674 ScopeName, ScopeLoc, Form);
676 case ParsedAttr::AT_Availability:
677 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
680 case ParsedAttr::AT_ObjCBridgeRelated:
681 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
682 ScopeName, ScopeLoc, Form);
684 case ParsedAttr::AT_SwiftNewType:
685 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
688 case ParsedAttr::AT_TypeTagForDatatype:
689 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
690 ScopeName, ScopeLoc, Form);
693 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
699 unsigned ExistingAttrs = Attrs.
size();
713 if (AttrName->
getName() ==
"property") {
719 T.expectAndConsume(diag::err_expected_lparen_after,
728 bool HasInvalidAccessor =
false;
733 if (!Tok.
is(tok::identifier)) {
735 if (Tok.
is(tok::r_paren) && !HasInvalidAccessor &&
736 AccessorNames[AK_Put] ==
nullptr &&
737 AccessorNames[AK_Get] ==
nullptr) {
738 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
749 if (KindStr ==
"get") {
751 }
else if (KindStr ==
"put") {
755 }
else if (KindStr ==
"set") {
756 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
763 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
765 HasInvalidAccessor =
true;
766 goto next_property_accessor;
770 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
771 HasInvalidAccessor =
true;
790 if (!Tok.
is(tok::identifier)) {
795 if (Kind == AK_Invalid) {
797 }
else if (AccessorNames[Kind] !=
nullptr) {
799 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
805 next_property_accessor:
811 if (Tok.
is(tok::r_paren))
814 Diag(Tok.
getLocation(), diag::err_ms_property_expected_comma_or_rparen);
819 if (!HasInvalidAccessor)
821 AccessorNames[AK_Get], AccessorNames[AK_Put],
822 ParsedAttr::Form::Declspec());
824 return !HasInvalidAccessor;
828 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
834 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) << AttrName;
847 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
848 assert(Tok.
is(tok::kw___declspec) &&
"Not a declspec!");
853 while (Tok.
is(tok::kw___declspec)) {
856 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
862 while (Tok.
isNot(tok::r_paren)) {
867 if (Tok.
is(tok::code_completion)) {
875 bool IsString = Tok.
getKind() == tok::string_literal;
876 if (!IsString && Tok.
getKind() != tok::identifier &&
877 Tok.
getKind() != tok::kw_restrict) {
878 Diag(Tok, diag::err_ms_declspec_type);
888 StringRef Str = PP.
getSpelling(Tok, StrBuffer, &Invalid);
894 AttrNameLoc = ConsumeStringToken();
900 bool AttrHandled =
false;
903 if (Tok.
is(tok::l_paren))
904 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
905 else if (AttrName->
getName() ==
"property")
911 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
912 ParsedAttr::Form::Declspec());
915 EndLoc =
T.getCloseLocation();
926 case tok::kw___fastcall:
927 case tok::kw___stdcall:
928 case tok::kw___thiscall:
929 case tok::kw___regcall:
930 case tok::kw___cdecl:
931 case tok::kw___vectorcall:
932 case tok::kw___ptr64:
934 case tok::kw___ptr32:
936 case tok::kw___uptr: {
939 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
950 assert(Tok.
is(tok::kw___funcref));
954 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
960 attrs.
addNew(AttrName, AttrNameLoc,
nullptr,
965void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
971 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) <<
Range;
981 case tok::kw_volatile:
982 case tok::kw___fastcall:
983 case tok::kw___stdcall:
984 case tok::kw___thiscall:
985 case tok::kw___cdecl:
986 case tok::kw___vectorcall:
987 case tok::kw___ptr32:
988 case tok::kw___ptr64:
990 case tok::kw___unaligned:
1003 while (Tok.
is(tok::kw___pascal)) {
1006 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1013 while (Tok.
is(tok::kw___kernel)) {
1016 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1022 while (Tok.
is(tok::kw___noinline__)) {
1025 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1026 tok::kw___noinline__);
1033 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1037bool Parser::isHLSLQualifier(
const Token &Tok)
const {
1038 return Tok.
is(tok::kw_groupshared);
1045 Attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0, Kind);
1053 case tok::kw__Nonnull:
1054 case tok::kw__Nullable:
1055 case tok::kw__Nullable_result:
1056 case tok::kw__Null_unspecified: {
1060 Diag(AttrNameLoc, diag::ext_nullability)
1062 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1073 return (Separator ==
'.' || Separator ==
'_');
1084VersionTuple Parser::ParseVersionTuple(
SourceRange &Range) {
1087 if (!Tok.
is(tok::numeric_constant)) {
1088 Diag(Tok, diag::err_expected_version);
1091 return VersionTuple();
1100 const char *ThisTokBegin = &Buffer[0];
1104 unsigned ActualLength = PP.
getSpelling(Tok, ThisTokBegin, &Invalid);
1106 return VersionTuple();
1109 unsigned AfterMajor = 0;
1111 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
1112 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
1116 if (AfterMajor == 0) {
1117 Diag(Tok, diag::err_expected_version);
1120 return VersionTuple();
1123 if (AfterMajor == ActualLength) {
1128 Diag(Tok, diag::err_zero_version);
1129 return VersionTuple();
1132 return VersionTuple(Major);
1135 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1137 || (AfterMajor + 1 == ActualLength)) {
1138 Diag(Tok, diag::err_expected_version);
1141 return VersionTuple();
1145 unsigned AfterMinor = AfterMajor + 1;
1147 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
1148 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
1152 if (AfterMinor == ActualLength) {
1156 if (Major == 0 && Minor == 0) {
1157 Diag(Tok, diag::err_zero_version);
1158 return VersionTuple();
1161 return VersionTuple(Major, Minor);
1164 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1167 Diag(Tok, diag::err_expected_version);
1170 return VersionTuple();
1174 if (AfterMajorSeparator != AfterMinorSeparator)
1175 Diag(Tok, diag::warn_expected_consistent_version_separator);
1178 unsigned AfterSubminor = AfterMinor + 1;
1179 unsigned Subminor = 0;
1180 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
1181 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
1185 if (AfterSubminor != ActualLength) {
1186 Diag(Tok, diag::err_expected_version);
1189 return VersionTuple();
1192 return VersionTuple(Major, Minor, Subminor);
1220void Parser::ParseAvailabilityAttribute(
1224 enum { Introduced, Deprecated, Obsoleted,
Unknown };
1230 if (
T.consumeOpen()) {
1231 Diag(Tok, diag::err_expected) << tok::l_paren;
1236 if (Tok.
isNot(tok::identifier)) {
1237 Diag(Tok, diag::err_availability_expected_platform);
1244 if (Ident->getName().contains(
"xrOS") || Ident->getName().contains(
"xros"))
1245 Diag(Platform->
Loc, diag::warn_availability_unknown_platform) << Ident;
1247 else if (Ident->getName() ==
"macosx")
1251 else if (Ident->getName() ==
"macosx_app_extension")
1255 AvailabilityAttr::canonicalizePlatformName(Ident->getName()));
1259 if (ExpectAndConsume(tok::comma)) {
1266 if (!Ident_introduced) {
1280 if (Tok.
isNot(tok::identifier)) {
1281 Diag(Tok, diag::err_availability_expected_change);
1288 if (Keyword == Ident_strict) {
1290 Diag(KeywordLoc, diag::err_availability_redundant)
1293 StrictLoc = KeywordLoc;
1297 if (Keyword == Ident_unavailable) {
1298 if (UnavailableLoc.
isValid()) {
1299 Diag(KeywordLoc, diag::err_availability_redundant)
1302 UnavailableLoc = KeywordLoc;
1306 if (Keyword == Ident_deprecated && Platform->
Ident &&
1309 if (Changes[Deprecated].KeywordLoc.
isValid()) {
1310 Diag(KeywordLoc, diag::err_availability_redundant)
1317 Changes[Deprecated].
Version = VersionTuple(1);
1321 if (Tok.
isNot(tok::equal)) {
1322 Diag(Tok, diag::err_expected_after) << Keyword << tok::equal;
1327 if (Keyword == Ident_message || Keyword == Ident_replacement) {
1328 if (!isTokenStringLiteral()) {
1329 Diag(Tok, diag::err_expected_string_literal)
1334 if (Keyword == Ident_message) {
1345 if ((Keyword == Ident_introduced || Keyword == Ident_deprecated) &&
1346 Tok.
is(tok::identifier)) {
1350 if (Keyword == Ident_introduced)
1351 UnavailableLoc = KeywordLoc;
1357 VersionTuple Version = ParseVersionTuple(VersionRange);
1359 if (Version.empty()) {
1365 if (Keyword == Ident_introduced)
1367 else if (Keyword == Ident_deprecated)
1369 else if (Keyword == Ident_obsoleted)
1375 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1376 Diag(KeywordLoc, diag::err_availability_redundant)
1379 Changes[Index].VersionRange.
getEnd());
1383 Changes[Index].
Version = Version;
1386 Diag(KeywordLoc, diag::err_availability_unknown_change)
1387 << Keyword << VersionRange;
1393 if (
T.consumeClose())
1397 *endLoc =
T.getCloseLocation();
1401 if (UnavailableLoc.
isValid()) {
1402 bool Complained =
false;
1403 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1404 if (Changes[Index].KeywordLoc.
isValid()) {
1406 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1408 Changes[Index].VersionRange.
getEnd());
1419 attrs.
addNew(&Availability,
1420 SourceRange(AvailabilityLoc,
T.getCloseLocation()), ScopeName,
1421 ScopeLoc, Platform, Changes[Introduced], Changes[Deprecated],
1422 Changes[Obsoleted], UnavailableLoc, MessageExpr.
get(), Form,
1423 StrictLoc, ReplacementExpr.
get());
1440void Parser::ParseExternalSourceSymbolAttribute(
1446 if (
T.expectAndConsume())
1450 if (!Ident_language) {
1458 bool HasLanguage =
false;
1460 bool HasDefinedIn =
false;
1463 bool HasUSR =
false;
1467 if (Tok.
isNot(tok::identifier)) {
1468 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1475 if (Keyword == Ident_generated_declaration) {
1476 if (GeneratedDeclaration) {
1477 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) << Keyword;
1481 GeneratedDeclaration = ParseIdentifierLoc();
1485 if (Keyword != Ident_language && Keyword != Ident_defined_in &&
1486 Keyword != Ident_USR) {
1487 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1493 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1499 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1501 if (Keyword == Ident_language)
1503 else if (Keyword == Ident_USR)
1506 HasDefinedIn =
true;
1508 if (!isTokenStringLiteral()) {
1509 Diag(Tok, diag::err_expected_string_literal)
1512 Keyword == Ident_language
1514 : (Keyword == Ident_defined_in ? 1 : 2));
1518 if (Keyword == Ident_language) {
1520 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1526 }
else if (Keyword == Ident_USR) {
1528 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1535 assert(Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1537 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1547 if (
T.consumeClose())
1550 *EndLoc =
T.getCloseLocation();
1555 ScopeName, ScopeLoc, Args, std::size(Args), Form);
1569void Parser::ParseObjCBridgeRelatedAttribute(
1575 if (
T.consumeOpen()) {
1576 Diag(Tok, diag::err_expected) << tok::l_paren;
1581 if (Tok.
isNot(tok::identifier)) {
1582 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1587 if (ExpectAndConsume(tok::comma)) {
1596 if (Tok.
is(tok::identifier)) {
1599 Diag(Tok, diag::err_objcbridge_related_selector_name);
1605 if (Tok.
is(tok::colon))
1606 Diag(Tok, diag::err_objcbridge_related_selector_name);
1608 Diag(Tok, diag::err_expected) << tok::comma;
1616 if (Tok.
is(tok::identifier))
1618 else if (Tok.
isNot(tok::r_paren)) {
1619 Diag(Tok, diag::err_expected) << tok::r_paren;
1625 if (
T.consumeClose())
1629 *EndLoc =
T.getCloseLocation();
1632 Attrs.
addNew(&ObjCBridgeRelated,
1633 SourceRange(ObjCBridgeRelatedLoc,
T.getCloseLocation()),
1634 ScopeName, ScopeLoc, RelatedClass, ClassMethod, InstanceMethod,
1638void Parser::ParseSwiftNewTypeAttribute(
1645 if (
T.consumeOpen()) {
1646 Diag(Tok, diag::err_expected) << tok::l_paren;
1650 if (Tok.
is(tok::r_paren)) {
1655 if (Tok.
isNot(tok::kw_struct) && Tok.
isNot(tok::kw_enum)) {
1656 Diag(Tok, diag::warn_attribute_type_not_supported)
1658 if (!isTokenSpecial())
1669 if (
T.consumeClose())
1672 *EndLoc =
T.getCloseLocation();
1676 ScopeName, ScopeLoc, Args, std::size(Args), Form);
1679void Parser::ParseTypeTagForDatatypeAttribute(
1683 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1688 if (Tok.
isNot(tok::identifier)) {
1689 Diag(Tok, diag::err_expected) << tok::identifier;
1695 if (ExpectAndConsume(tok::comma)) {
1707 bool LayoutCompatible =
false;
1708 bool MustBeNull =
false;
1710 if (Tok.
isNot(tok::identifier)) {
1711 Diag(Tok, diag::err_expected) << tok::identifier;
1716 if (Flag->
isStr(
"layout_compatible"))
1717 LayoutCompatible =
true;
1718 else if (Flag->
isStr(
"must_be_null"))
1721 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1728 if (!
T.consumeClose()) {
1730 ArgumentKind, MatchingCType.
get(),
1731 LayoutCompatible, MustBeNull, Form);
1735 *EndLoc =
T.getCloseLocation();
1746bool Parser::DiagnoseProhibitedCXX11Attribute() {
1747 assert(Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square));
1749 switch (isCXX11AttributeSpecifier(
true)) {
1750 case CAK_NotAttributeSpecifier:
1754 case CAK_InvalidAttributeSpecifier:
1758 case CAK_AttributeSpecifier:
1763 assert(Tok.
is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1765 Diag(BeginLoc, diag::err_attributes_not_allowed)
1769 llvm_unreachable(
"All cases handled above.");
1778 assert((Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square)) ||
1785 ParseCXX11Attributes(Attrs);
1788 (Keyword ?
Diag(Loc, diag::err_keyword_not_allowed) << Keyword
1789 :
Diag(Loc, diag::err_attributes_not_allowed))
1794void Parser::DiagnoseProhibitedAttributes(
1796 auto *FirstAttr = Attrs.
empty() ? nullptr : &Attrs.
front();
1797 if (CorrectLocation.
isValid()) {
1799 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1800 ?
Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1801 :
Diag(CorrectLocation, diag::err_attributes_misplaced))
1806 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1807 ?
Diag(
Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr
1808 :
Diag(
Range.getBegin(), diag::err_attributes_not_allowed))
1814 unsigned AttrDiagID,
1815 unsigned KeywordDiagID,
1816 bool DiagnoseEmptyAttrs,
1817 bool WarnOnUnknownAttrs) {
1827 if (FirstLSquare.
is(tok::l_square)) {
1828 std::optional<Token> SecondLSquare =
1831 if (SecondLSquare && SecondLSquare->is(tok::l_square)) {
1842 if (AL.isRegularKeywordAttribute()) {
1843 Diag(AL.getLoc(), KeywordDiagID) << AL;
1847 if (!AL.isStandardAttributeSyntax())
1850 if (WarnOnUnknownAttrs)
1851 Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
1852 << AL << AL.getRange();
1854 Diag(AL.getLoc(), AttrDiagID) << AL;
1862 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1863 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1864 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
1884 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1885 AL.isDeclspecAttribute()) ||
1886 AL.isMicrosoftAttribute())
1887 ToBeMoved.push_back(&AL);
1922 Decl *SingleDecl =
nullptr;
1924 case tok::kw_template:
1925 case tok::kw_export:
1926 ProhibitAttributes(DeclAttrs);
1927 ProhibitAttributes(DeclSpecAttrs);
1928 return ParseDeclarationStartingWithTemplate(Context, DeclEnd, DeclAttrs);
1929 case tok::kw_inline:
1932 ProhibitAttributes(DeclAttrs);
1933 ProhibitAttributes(DeclSpecAttrs);
1935 return ParseNamespace(Context, DeclEnd, InlineLoc);
1937 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1938 true,
nullptr, DeclSpecStart);
1940 case tok::kw_cbuffer:
1941 case tok::kw_tbuffer:
1942 SingleDecl = ParseHLSLBuffer(DeclEnd);
1944 case tok::kw_namespace:
1945 ProhibitAttributes(DeclAttrs);
1946 ProhibitAttributes(DeclSpecAttrs);
1947 return ParseNamespace(Context, DeclEnd);
1948 case tok::kw_using: {
1951 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1954 case tok::kw_static_assert:
1955 case tok::kw__Static_assert:
1956 ProhibitAttributes(DeclAttrs);
1957 ProhibitAttributes(DeclSpecAttrs);
1958 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1961 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1962 true,
nullptr, DeclSpecStart);
1994 bool RequireSemi, ForRangeInit *FRI,
SourceLocation *DeclSpecStart) {
1997 OriginalDeclSpecAttrs.
addAll(DeclSpecAttrs.
begin(), DeclSpecAttrs.
end());
1998 OriginalDeclSpecAttrs.
Range = DeclSpecAttrs.
Range;
2004 ParsedTemplateInfo TemplateInfo;
2005 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
2006 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none, DSContext);
2011 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
2016 if (Tok.
is(tok::semi)) {
2017 ProhibitAttributes(DeclAttrs);
2024 DS.complete(TheDecl);
2026 Decl* decls[] = {AnonRecord, TheDecl};
2038 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
2045 case tok::annot_cxxscope:
2046 case tok::annot_template_id:
2048 case tok::code_completion:
2049 case tok::coloncolon:
2051 case tok::kw___attribute:
2052 case tok::kw_operator:
2068 case tok::identifier:
2070 case tok::code_completion:
2071 case tok::coloncolon:
2074 case tok::equalequal:
2075 case tok::kw_alignas:
2077 case tok::kw___attribute:
2095 case tok::identifier:
2118 if (Tok.
isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
2142 case tok::kw_inline:
2147 (!ParsingInObjCContainer || CurParsedObjCImpl))
2151 case tok::kw_namespace:
2156 (!ParsingInObjCContainer || CurParsedObjCImpl))
2162 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2163 ParsingInObjCContainer)
2175 case tok::annot_module_begin:
2176 case tok::annot_module_end:
2177 case tok::annot_module_include:
2178 case tok::annot_repl_input_end:
2195 ParsedTemplateInfo &TemplateInfo,
2197 ForRangeInit *FRI) {
2203 LocalAttrs.takeAllFrom(Attrs);
2205 if (TemplateInfo.TemplateParams)
2208 bool IsTemplateSpecOrInst =
2209 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
2210 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
2215 if (IsTemplateSpecOrInst)
2225 MaybeParseHLSLSemantics(D);
2227 if (Tok.
is(tok::kw_requires))
2228 ParseTrailingRequiresClause(D);
2233 LateParsedAttrList LateParsedAttrs(
true);
2235 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2240 if (Tok.
is(tok::kw__Noreturn)) {
2242 const char *PrevSpec;
2248 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2249 Fixit &= Tok.
isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2251 Diag(Loc, diag::err_c11_noreturn_misplaced)
2253 << (Fixit ?
FixItHint::CreateInsertion(D.getBeginLoc(),
"_Noreturn ")
2258 if (Tok.
is(tok::equal) &&
NextToken().is(tok::code_completion)) {
2269 while (
auto Specifier = isCXX11VirtSpecifier()) {
2270 Diag(Tok, diag::err_virt_specifier_outside_class)
2278 if (!isDeclarationAfterDeclarator()) {
2284 if (isStartOfFunctionDefinition(D)) {
2294 diag::err_function_declared_typedef)
2298 Decl *TheDecl =
nullptr;
2300 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
2304 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2305 TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(),
2311 diag::err_explicit_instantiation_with_definition)
2319 std::nullopt, LAngleLoc,
nullptr));
2321 TheDecl = ParseFunctionDefinition(
2323 ParsedTemplateInfo(&FakedParamLists,
2330 ParseFunctionDefinition(D, TemplateInfo, &LateParsedAttrs);
2337 Tok.
is(tok::kw_namespace)) {
2347 Diag(Tok, diag::err_expected_fn_body);
2352 if (Tok.
is(tok::l_brace)) {
2353 Diag(Tok, diag::err_function_definition_not_allowed);
2361 if (ParseAsmAttributesAfterDeclarator(D))
2370 if (FRI && (Tok.
is(tok::colon) || isTokIdentifier_in())) {
2371 bool IsForRangeLoop =
false;
2373 IsForRangeLoop =
true;
2383 LastRecord.InLifetimeExtendingContext =
true;
2388 if (Tok.
is(tok::l_brace))
2389 FRI->RangeExpr = ParseBraceInitializer();
2400 FRI->LifetimeExtendTemps = std::move(
2405 if (IsForRangeLoop) {
2409 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2410 VD->setObjCForDecl(
true);
2413 D.complete(ThisDecl);
2419 ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo, FRI);
2420 if (LateParsedAttrs.size() > 0)
2421 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2422 D.complete(FirstDecl);
2424 DeclsInGroup.push_back(FirstDecl);
2432 if (Tok.
isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2436 Diag(CommaLoc, diag::err_expected_semi_declaration)
2446 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
2448 Diag(CommaLoc, diag::err_multiple_template_declarators)
2449 << TemplateInfo.Kind;
2463 MaybeParseGNUAttributes(D);
2467 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2472 MaybeParseHLSLSemantics(D);
2479 if (Tok.
is(tok::kw_requires))
2480 ParseTrailingRequiresClause(D);
2481 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D, TemplateInfo);
2482 D.complete(ThisDecl);
2484 DeclsInGroup.push_back(ThisDecl);
2491 if (ExpectSemi && ExpectAndConsumeSemi(
2493 ? diag::err_invalid_token_after_toplevel_declarator
2494 : diag::err_expected_semi_declaration)) {
2507bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &D) {
2509 if (Tok.
is(tok::kw_asm)) {
2511 ExprResult AsmLabel(ParseSimpleAsm(
true, &Loc));
2512 if (AsmLabel.isInvalid()) {
2521 MaybeParseGNUAttributes(D);
2547Decl *Parser::ParseDeclarationAfterDeclarator(
2548 Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
2549 if (ParseAsmAttributesAfterDeclarator(D))
2552 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
2555Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2556 Declarator &D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2558 struct InitializerScopeRAII {
2564 :
P(
P), D(D), ThisDecl(ThisDecl) {
2565 if (ThisDecl &&
P.getLangOpts().CPlusPlus) {
2569 S =
P.getCurScope();
2571 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2574 ~InitializerScopeRAII() { pop(); }
2576 if (ThisDecl &&
P.getLangOpts().CPlusPlus) {
2579 S =
P.getCurScope();
2580 P.Actions.ActOnCXXExitDeclInitializer(S, ThisDecl);
2589 InitKind TheInitKind;
2591 if (isTokenEqualOrEqualTypo())
2592 TheInitKind = InitKind::Equal;
2593 else if (Tok.
is(tok::l_paren))
2594 TheInitKind = InitKind::CXXDirect;
2597 TheInitKind = InitKind::CXXBraced;
2599 TheInitKind = InitKind::Uninitialized;
2600 if (TheInitKind != InitKind::Uninitialized)
2604 Decl *ThisDecl =
nullptr;
2605 Decl *OuterDecl =
nullptr;
2606 switch (TemplateInfo.Kind) {
2607 case ParsedTemplateInfo::NonTemplate:
2611 case ParsedTemplateInfo::Template:
2612 case ParsedTemplateInfo::ExplicitSpecialization: {
2614 *TemplateInfo.TemplateParams,
2616 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2619 ThisDecl = VT->getTemplatedDecl();
2624 case ParsedTemplateInfo::ExplicitInstantiation: {
2625 if (Tok.
is(tok::semi)) {
2627 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
2632 ThisDecl = ThisRes.
get();
2640 Diag(Tok, diag::err_template_defn_explicit_instantiation)
2647 diag::err_explicit_instantiation_with_definition)
2655 std::nullopt, LAngleLoc,
nullptr));
2667 switch (TheInitKind) {
2669 case InitKind::Equal: {
2672 if (Tok.
is(tok::kw_delete)) {
2678 SkipDeletedFunctionBody();
2679 }
else if (Tok.
is(tok::kw_default)) {
2687 InitializerScopeRAII InitScope(*
this, D, ThisDecl);
2689 if (Tok.
is(tok::code_completion)) {
2702 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2706 FRI->ColonLoc = EqualLoc;
2708 FRI->RangeExpr =
Init;
2713 if (
Init.isInvalid()) {
2715 StopTokens.push_back(tok::comma);
2718 StopTokens.push_back(tok::r_paren);
2727 case InitKind::CXXDirect: {
2734 InitializerScopeRAII InitScope(*
this, D, ThisDecl);
2736 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2737 auto RunSignatureHelp = [&]() {
2739 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2742 CalledSignatureHelp =
true;
2743 return PreferredType;
2745 auto SetPreferredType = [&] {
2746 PreferredType.enterFunctionArgument(Tok.
getLocation(), RunSignatureHelp);
2749 llvm::function_ref<void()> ExpressionStarts;
2755 ExpressionStarts = SetPreferredType;
2758 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2765 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2768 CalledSignatureHelp =
true;
2777 T.getCloseLocation(),
2784 case InitKind::CXXBraced: {
2786 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2788 InitializerScopeRAII InitScope(*
this, D, ThisDecl);
2790 PreferredType.enterVariableInit(Tok.
getLocation(), ThisDecl);
2795 if (
Init.isInvalid()) {
2801 case InitKind::Uninitialized: {
2808 return OuterDecl ? OuterDecl : ThisDecl;
2817void Parser::ParseSpecifierQualifierList(
2823 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC,
nullptr,
2824 AllowImplicitTypename);
2829 Diag(Tok, diag::err_expected_type);
2832 Diag(Tok, diag::err_typename_requires_specqual);
2843 diag::err_typename_invalid_storageclass);
2887 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2888 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2902 const ParsedTemplateInfo &TemplateInfo,
2905 assert(Tok.
is(tok::identifier) &&
"should have identifier");
2927 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
2945 AnnotateScopeToken(*SS,
false);
2956 DSC == DeclSpecContext::DSC_template_type_arg)) {
2957 const char *PrevSpec;
2973 if (SS ==
nullptr) {
2974 const char *TagName =
nullptr, *FixitTagName =
nullptr;
2980 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
2982 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
2984 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
2986 TagName=
"__interface"; FixitTagName =
"__interface ";
2987 TagKind=tok::kw___interface;
break;
2989 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
2997 Diag(Loc, diag::err_use_of_tag_name_without_tag)
2998 << TokenName << TagName <<
getLangOpts().CPlusPlus
3004 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
3005 << TokenName << TagName;
3009 if (TagKind == tok::kw_enum)
3010 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,
3011 DeclSpecContext::DSC_normal);
3013 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
3015 DeclSpecContext::DSC_normal, Attrs);
3022 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
3023 DSC == DeclSpecContext::DSC_class)) {
3027 case tok::l_paren: {
3034 TentativeParsingAction PA(*
this);
3036 TPResult TPR = TryParseDeclarator(
false);
3039 if (TPR != TPResult::False) {
3047 if (DSC == DeclSpecContext::DSC_class ||
3048 (DSC == DeclSpecContext::DSC_top_level && SS)) {
3051 Diag(Loc, diag::err_constructor_bad_name)
3072 AnnotateScopeToken(*SS,
false);
3094 const char *PrevSpec;
3115 if (IsTemplateName) {
3117 TemplateArgList Args;
3118 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3132Parser::DeclSpecContext
3136 return DeclSpecContext::DSC_class;
3138 return DeclSpecContext::DSC_top_level;
3140 return DeclSpecContext::DSC_template_param;
3142 return DeclSpecContext::DSC_template_arg;
3144 return DeclSpecContext::DSC_template_type_arg;
3147 return DeclSpecContext::DSC_trailing;
3150 return DeclSpecContext::DSC_alias_declaration;
3152 return DeclSpecContext::DSC_association;
3154 return DeclSpecContext::DSC_type_specifier;
3156 return DeclSpecContext::DSC_condition;
3158 return DeclSpecContext::DSC_conv_operator;
3160 return DeclSpecContext::DSC_new;
3175 return DeclSpecContext::DSC_normal;
3178 llvm_unreachable(
"Missing DeclaratorContext case");
3191 if (isTypeIdInParens()) {
3220 assert(Tok.
isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3221 "Not an alignment-specifier!");
3228 if (
T.expectAndConsume())
3235 ParseAlignArgument(PP.
getSpelling(KWTok),
T.getOpenLocation(),
3244 *EndLoc =
T.getCloseLocation();
3251 ArgExprs.push_back(ArgExpr.
get());
3252 Attrs.
addNew(KWName, KWLoc,
nullptr, KWLoc, ArgExprs.data(), 1, Kind,
3265 assert(Tok.
is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3270 if (Tok.
is(tok::r_paren)) {
3278 using ExpressionKind =
3282 ExpressionKind::EK_BoundsAttrArgument);
3292 ArgExprs.push_back(ArgExpr.
get());
3302 ScopeName, ScopeLoc, ArgExprs.data(), ArgExprs.size(), Form);
3305ExprResult Parser::ParseExtIntegerArgument() {
3306 assert(Tok.
isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3307 "Not an extended int type");
3311 if (
T.expectAndConsume())
3320 if(
T.consumeClose())
3334 DeclSpecContext DSContext,
3335 LateParsedAttrList *LateAttrs) {
3338 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3339 DSContext == DeclSpecContext::DSC_top_level);
3342 Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
3343 tok::annot_template_id) &&
3349 bool HasScope = Tok.
is(tok::annot_cxxscope);
3355 bool MightBeDeclarator =
true;
3356 if (Tok.
isOneOf(tok::kw_typename, tok::annot_typename)) {
3358 MightBeDeclarator =
false;
3359 }
else if (AfterScope.
is(tok::annot_template_id)) {
3365 MightBeDeclarator =
false;
3366 }
else if (AfterScope.
is(tok::identifier)) {
3367 const Token &Next = HasScope ? GetLookAheadToken(2) :
NextToken();
3371 if (Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3372 tok::annot_cxxscope, tok::coloncolon)) {
3374 MightBeDeclarator =
false;
3375 }
else if (HasScope) {
3386 switch (Classification.
getKind()) {
3392 llvm_unreachable(
"typo correction is not possible here");
3399 MightBeDeclarator =
false;
3415 if (MightBeDeclarator)
3420 diag::err_expected_after)
3431 ParsedTemplateInfo NotATemplate;
3432 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3463void Parser::ParseDeclarationSpecifiers(
3465 DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
3477 if (DSContext == DeclSpecContext::DSC_conv_operator) {
3480 DSContext = DeclSpecContext::DSC_type_specifier;
3483 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3484 DSContext == DeclSpecContext::DSC_top_level);
3485 bool AttrsLastTime =
false;
3491 bool isStorageClass =
false;
3492 const char *PrevSpec =
nullptr;
3493 unsigned DiagID = 0;
3514 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3528 bool IsTemplateSpecOrInst =
3529 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
3530 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
3539 ProhibitAttributes(attrs);
3543 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3544 !PA.isRegularKeywordAttribute())
3552 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3553 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3560 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3561 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3563 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3564 << PA << PA.isRegularKeywordAttribute();
3573 DS.
Finish(Actions, Policy);
3577 case tok::kw__Alignas:
3578 diagnoseUseOfC11Keyword(Tok);
3580 case tok::kw_alignas:
3586 if (Tok.
getKind() == tok::kw_alignas)
3587 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
3593 if (!isAllowedCXX11AttributeSpecifier())
3594 goto DoneWithDeclSpec;
3597 ProhibitAttributes(attrs);
3604 ParseCXX11Attributes(attrs);
3605 AttrsLastTime =
true;
3608 case tok::code_completion: {
3611 bool AllowNonIdentifiers
3617 bool AllowNestedNameSpecifiers
3618 = DSContext == DeclSpecContext::DSC_top_level ||
3623 AllowNonIdentifiers,
3624 AllowNestedNameSpecifiers);
3629 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
3632 else if (DSContext == DeclSpecContext::DSC_class)
3636 else if (CurParsedObjCImpl)
3644 case tok::coloncolon:
3650 goto DoneWithDeclSpec;
3652 if (Tok.
is(tok::coloncolon))
3653 goto DoneWithDeclSpec;
3656 case tok::annot_cxxscope: {
3658 goto DoneWithDeclSpec;
3661 if (TemplateInfo.TemplateParams)
3671 ? takeTemplateIdAnnotation(Next)
3677 ConsumeAnnotationToken();
3691 if ((DSContext == DeclSpecContext::DSC_top_level ||
3692 DSContext == DeclSpecContext::DSC_class) &&
3695 isConstructorDeclarator(
false,
3702 goto DoneWithDeclSpec;
3706 ConsumeAnnotationToken();
3707 assert(Tok.
is(tok::annot_template_id) &&
3708 "ParseOptionalCXXScopeSpecifier not working");
3709 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3719 ConsumeAnnotationToken();
3723 if (Next.is(tok::annot_typename)) {
3725 ConsumeAnnotationToken();
3729 PrevSpec, DiagID,
T, Policy);
3733 ConsumeAnnotationToken();
3737 Next.is(tok::annot_template_id) &&
3741 ConsumeAnnotationToken();
3742 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3746 if (Next.isNot(tok::identifier))
3747 goto DoneWithDeclSpec;
3752 if ((DSContext == DeclSpecContext::DSC_top_level ||
3753 DSContext == DeclSpecContext::DSC_class) &&
3756 isConstructorDeclarator(
false,
3760 goto DoneWithDeclSpec;
3769 *Next.getIdentifierInfo(), Next.getLocation(),
getCurScope(), &SS,
3770 false,
false,
nullptr,
3773 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3775 if (IsTemplateSpecOrInst)
3783 if (TryAnnotateTypeConstraint())
3784 goto DoneWithDeclSpec;
3785 if (Tok.
isNot(tok::annot_cxxscope) ||
3789 ConsumeAnnotationToken();
3791 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3792 if (!Attrs.
empty()) {
3793 AttrsLastTime =
true;
3794 attrs.takeAllFrom(Attrs);
3798 goto DoneWithDeclSpec;
3802 ConsumeAnnotationToken();
3805 DiagID, TypeRep, Policy);
3815 case tok::annot_typename: {
3819 goto DoneWithDeclSpec;
3828 ConsumeAnnotationToken();
3833 case tok::kw___is_signed:
3844 TryKeywordIdentFallback(
true);
3847 goto DoneWithDeclSpec;
3850 case tok::kw___super:
3851 case tok::kw_decltype:
3852 case tok::identifier:
3858 goto DoneWithDeclSpec;
3864 if (!
getLangOpts().DeclSpecKeyword && Tok.
is(tok::identifier) &&
3866 Diag(Loc, diag::err_ms_attributes_not_enabled);
3876 if (
T.consumeOpen()) {
3877 assert(
false &&
"Not a left paren?");
3896 if (IsTemplateSpecOrInst)
3900 if (IsTemplateSpecOrInst)
3903 goto DoneWithDeclSpec;
3906 if (!Tok.
is(tok::identifier))
3911 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID,
isInvalid))
3917 goto DoneWithDeclSpec;
3919 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3920 isObjCInstancetype()) {
3924 DiagID, TypeRep, Policy);
3937 isConstructorDeclarator(
true,
3940 goto DoneWithDeclSpec;
3944 false,
false,
nullptr,
false,
false,
3945 isClassTemplateDeductionContext(DSContext));
3950 if (TryAnnotateTypeConstraint())
3951 goto DoneWithDeclSpec;
3952 if (Tok.
isNot(tok::identifier))
3955 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
3956 if (!Attrs.
empty()) {
3957 AttrsLastTime =
true;
3958 attrs.takeAllFrom(Attrs);
3962 goto DoneWithDeclSpec;
3969 (DSContext == DeclSpecContext::DSC_class ||
3970 DSContext == DeclSpecContext::DSC_top_level) &&
3973 isConstructorDeclarator(
true,
3975 goto DoneWithDeclSpec;
3978 DiagID, TypeRep, Policy);
3990 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
4005 case tok::annot_template_id: {
4017 TemplateId =
nullptr;
4025 tok::kw_volatile, tok::kw_restrict, tok::amp,
4027 Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
4031 TemplateId, Policy);
4035 goto DoneWithDeclSpec;
4038 TemplateId =
nullptr;
4040 ConsumeAnnotationToken();
4044 if (Tracker.consumeOpen()) {
4046 Diag(Tok, diag::err_expected) << tok::l_paren;
4050 Tracker.skipToEnd();
4051 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
4056 Tracker.consumeClose();
4064 DiagID, TemplateId, Policy);
4067 TemplateId, Policy);
4076 goto DoneWithDeclSpec;
4084 isConstructorDeclarator(
true,
4087 goto DoneWithDeclSpec;
4092 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
4097 case tok::kw___attribute:
4098 case tok::kw___declspec:
4099 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4103 case tok::kw___forceinline: {
4108 nullptr, 0, tok::kw___forceinline);
4112 case tok::kw___unaligned:
4117 case tok::kw___sptr:
4118 case tok::kw___uptr:
4119 case tok::kw___ptr64:
4120 case tok::kw___ptr32:
4122 case tok::kw___cdecl:
4123 case tok::kw___stdcall:
4124 case tok::kw___fastcall:
4125 case tok::kw___thiscall:
4126 case tok::kw___regcall:
4127 case tok::kw___vectorcall:
4131 case tok::kw___funcref:
4136 case tok::kw___pascal:
4141 case tok::kw___kernel:
4146 case tok::kw___noinline__:
4151 case tok::kw__Nonnull:
4152 case tok::kw__Nullable:
4153 case tok::kw__Nullable_result:
4154 case tok::kw__Null_unspecified:
4159 case tok::kw___kindof:
4161 nullptr, 0, tok::kw___kindof);
4166 case tok::kw_typedef:
4168 PrevSpec, DiagID, Policy);
4169 isStorageClass =
true;
4171 case tok::kw_extern:
4173 Diag(Tok, diag::ext_thread_before) <<
"extern";
4175 PrevSpec, DiagID, Policy);
4176 isStorageClass =
true;
4178 case tok::kw___private_extern__:
4180 Loc, PrevSpec, DiagID, Policy);
4181 isStorageClass =
true;
4183 case tok::kw_static:
4185 Diag(Tok, diag::ext_thread_before) <<
"static";
4187 PrevSpec, DiagID, Policy);
4188 isStorageClass =
true;
4192 if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
4194 PrevSpec, DiagID, Policy);
4196 Diag(Tok, diag::ext_auto_storage_class)
4203 PrevSpec, DiagID, Policy);
4204 isStorageClass =
true;
4206 case tok::kw___auto_type:
4207 Diag(Tok, diag::ext_auto_type);
4211 case tok::kw_register:
4213 PrevSpec, DiagID, Policy);
4214 isStorageClass =
true;
4216 case tok::kw_mutable:
4218 PrevSpec, DiagID, Policy);
4219 isStorageClass =
true;
4221 case tok::kw___thread:
4224 isStorageClass =
true;
4226 case tok::kw_thread_local:
4228 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4237 Loc, PrevSpec, DiagID);
4238 isStorageClass =
true;
4240 case tok::kw__Thread_local:
4241 diagnoseUseOfC11Keyword(Tok);
4243 Loc, PrevSpec, DiagID);
4244 isStorageClass =
true;
4248 case tok::kw_inline:
4251 case tok::kw_virtual:
4255 !
getActions().getOpenCLOptions().isAvailableOption(
4257 DiagID = diag::err_openclcxx_virtual_function;
4264 case tok::kw_explicit: {
4268 ConsumedEnd = ExplicitLoc;
4270 if (Tok.
is(tok::l_paren)) {
4273 ? diag::warn_cxx17_compat_explicit_bool
4274 : diag::ext_explicit_bool);
4278 Tracker.consumeOpen();
4285 if (ExplicitExpr.isUsable()) {
4287 Tracker.consumeClose();
4291 Tracker.skipToEnd();
4297 ExplicitSpec, CloseParenLoc);
4300 case tok::kw__Noreturn:
4301 diagnoseUseOfC11Keyword(Tok);
4306 case tok::kw_friend:
4307 if (DSContext == DeclSpecContext::DSC_class)
4311 DiagID = diag::err_friend_invalid_in_context;
4317 case tok::kw___module_private__:
4322 case tok::kw_constexpr:
4324 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4328 case tok::kw_consteval:
4332 case tok::kw_constinit:
4348 PrevSpec, DiagID, Policy);
4350 case tok::kw___int64:
4352 PrevSpec, DiagID, Policy);
4354 case tok::kw_signed:
4358 case tok::kw_unsigned:
4362 case tok::kw__Complex:
4364 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4368 case tok::kw__Imaginary:
4370 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4386 case tok::kw__ExtInt:
4387 case tok::kw__BitInt: {
4388 DiagnoseBitIntUse(Tok);
4393 ConsumedEnd = PrevTokLocation;
4396 case tok::kw___int128:
4404 case tok::kw___bf16:
4412 case tok::kw_double:
4416 case tok::kw__Float16:
4420 case tok::kw__Accum:
4422 "This keyword is only used when fixed point types are enabled "
4423 "with `-ffixed-point`");
4427 case tok::kw__Fract:
4429 "This keyword is only used when fixed point types are enabled "
4430 "with `-ffixed-point`");
4436 "This keyword is only used when fixed point types are enabled "
4437 "with `-ffixed-point`");
4440 case tok::kw___float128:
4444 case tok::kw___ibm128:
4448 case tok::kw_wchar_t:
4452 case tok::kw_char8_t:
4456 case tok::kw_char16_t:
4460 case tok::kw_char32_t:
4466 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4470 Diag(Tok, diag::ext_c99_feature) << Tok.
getName();
4472 if (Tok.
is(tok::kw_bool) &&
4476 DiagID = diag::err_bool_redeclaration;
4485 case tok::kw__Decimal32:
4489 case tok::kw__Decimal64:
4493 case tok::kw__Decimal128:
4497 case tok::kw___vector:
4500 case tok::kw___pixel:
4503 case tok::kw___bool:
4508 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4513 goto DoneWithDeclSpec;
4515 DiagID = diag::err_opencl_unknown_type_specifier;
4522#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4523#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4524#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4525 case tok::kw_##ImgType##_t: \
4526 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4527 goto DoneWithDeclSpec; \
4529#include "clang/Basic/OpenCLImageTypes.def"
4530 case tok::kw___unknown_anytype:
4532 PrevSpec, DiagID, Policy);
4537 case tok::kw_struct:
4538 case tok::kw___interface:
4539 case tok::kw_union: {
4547 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
4548 EnteringContext, DSContext, Attributes);
4552 if (!Attributes.empty()) {
4553 AttrsLastTime =
true;
4554 attrs.takeAllFrom(Attributes);
4562 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
4570 case tok::kw_volatile:
4574 case tok::kw_restrict:
4580 case tok::kw_typename:
4583 goto DoneWithDeclSpec;
4585 if (!Tok.
is(tok::kw_typename))
4590 case tok::kw_typeof:
4591 case tok::kw_typeof_unqual:
4592 ParseTypeofSpecifier(DS);
4595 case tok::annot_decltype:
4596 ParseDecltypeSpecifier(DS);
4599 case tok::annot_pack_indexing_type:
4600 ParsePackIndexingType(DS);
4603 case tok::annot_pragma_pack:
4607 case tok::annot_pragma_ms_pragma:
4608 HandlePragmaMSPragma();
4611 case tok::annot_pragma_ms_vtordisp:
4612 HandlePragmaMSVtorDisp();
4615 case tok::annot_pragma_ms_pointers_to_members:
4616 HandlePragmaMSPointersToMembers();
4619#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4620#include "clang/Basic/TransformTypeTraits.def"
4624 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4625 goto ParseIdentifier;
4628 case tok::kw__Atomic:
4633 diagnoseUseOfC11Keyword(Tok);
4635 ParseAtomicSpecifier(DS);
4643 case tok::kw___generic:
4648 if (!Actions.
getLangOpts().OpenCLGenericAddressSpace) {
4649 DiagID = diag::err_opencl_unknown_type_specifier;
4655 case tok::kw_private:
4659 goto DoneWithDeclSpec;
4661 case tok::kw___private:
4662 case tok::kw___global:
4663 case tok::kw___local:
4664 case tok::kw___constant:
4666 case tok::kw___read_only:
4667 case tok::kw___write_only:
4668 case tok::kw___read_write:
4672 case tok::kw_groupshared:
4685 goto DoneWithDeclSpec;
4690 if (
Type.isUsable()) {
4692 PrevSpec, DiagID,
Type.get(),
4694 Diag(StartLoc, DiagID) << PrevSpec;
4710 assert(PrevSpec &&
"Method did not return previous specifier!");
4713 if (DiagID == diag::ext_duplicate_declspec ||
4714 DiagID == diag::ext_warn_duplicate_declspec ||
4715 DiagID == diag::err_duplicate_declspec)
4716 Diag(Loc, DiagID) << PrevSpec
4719 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4723 Diag(Loc, DiagID) << PrevSpec;
4726 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4730 AttrsLastTime =
false;
4742 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4745 for (
auto *I : RD->decls()) {
4746 auto *VD = dyn_cast<ValueDecl>(I);
4754 for (
const auto &DD : CAT->dependent_decls()) {
4755 if (!RD->containsDecl(DD.getDecl())) {
4756 P.Diag(VD->getBeginLoc(),
4757 diag::err_flexible_array_count_not_in_same_struct)
4759 P.Diag(DD.getDecl()->getBeginLoc(),
4760 diag::note_flexible_array_counted_by_attr_field)
4788void Parser::ParseStructDeclaration(
4792 if (Tok.
is(tok::kw___extension__)) {
4796 return ParseStructDeclaration(DS, FieldsCallback);
4801 MaybeParseCXX11Attributes(Attrs);
4804 ParseSpecifierQualifierList(DS);
4808 if (Tok.
is(tok::semi)) {
4813 ProhibitAttributes(Attrs);
4817 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4823 bool FirstDeclarator =
true;
4827 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4830 if (!FirstDeclarator) {
4833 DiagnoseAndSkipCXX11Attributes();
4834 MaybeParseGNUAttributes(DeclaratorInfo.D);
4835 DiagnoseAndSkipCXX11Attributes();
4840 if (Tok.
isNot(tok::colon)) {
4843 ParseDeclarator(DeclaratorInfo.D);
4845 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.
getLocation());
4857 DeclaratorInfo.BitfieldSize = Res.
get();
4861 MaybeParseGNUAttributes(DeclaratorInfo.D);
4864 FieldsCallback(DeclaratorInfo);
4871 FirstDeclarator =
false;
4888 "parsing struct/union body");
4892 if (
T.consumeOpen())
4899 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
4900 Tok.
isNot(tok::eof)) {
4904 if (Tok.
is(tok::semi)) {
4905 ConsumeExtraSemi(InsideStruct,
TagType);
4910 if (Tok.
isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4912 ParseStaticAssertDeclaration(DeclEnd);
4916 if (Tok.
is(tok::annot_pragma_pack)) {
4921 if (Tok.
is(tok::annot_pragma_align)) {
4922 HandlePragmaAlign();
4926 if (Tok.
isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4930 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4934 if (Tok.
is(tok::annot_pragma_openacc)) {
4943 ConsumeAnnotationToken();
4947 if (!Tok.
is(tok::at)) {
4953 FD.D, FD.BitfieldSize);
4959 ParseStructDeclaration(DS, CFieldCallback);
4963 Diag(Tok, diag::err_unexpected_at);
4968 ExpectAndConsume(tok::l_paren);
4969 if (!Tok.
is(tok::identifier)) {
4970 Diag(Tok, diag::err_expected) << tok::identifier;
4978 ExpectAndConsume(tok::r_paren);
4984 if (Tok.
is(tok::r_brace)) {
4985 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
4989 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
5000 MaybeParseGNUAttributes(attrs);
5005 T.getOpenLocation(),
T.getCloseLocation(), attrs);
5041 const ParsedTemplateInfo &TemplateInfo,
5044 if (Tok.
is(tok::code_completion)) {
5054 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5057 bool IsScopedUsingClassTag =
false;
5062 : diag::ext_scoped_enum);
5063 IsScopedUsingClassTag = Tok.
is(tok::kw_class);
5068 ProhibitAttributes(attrs);
5071 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5080 bool shouldDelayDiagsInTag =
5081 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
5082 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
5086 AllowDefiningTypeSpec AllowEnumSpecifier =
5088 bool CanBeOpaqueEnumDeclaration =
5089 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5092 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5093 CanBeOpaqueEnumDeclaration);
5101 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5106 if (Spec.
isSet() && Tok.
isNot(tok::identifier)) {
5107 Diag(Tok, diag::err_expected) << tok::identifier;
5109 if (Tok.
isNot(tok::l_brace)) {
5121 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::l_brace) &&
5122 Tok.
isNot(tok::colon)) {
5123 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5134 if (Tok.
is(tok::identifier)) {
5139 if (!Name && ScopedEnumKWLoc.
isValid()) {
5142 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5144 IsScopedUsingClassTag =
false;
5149 if (shouldDelayDiagsInTag)
5150 diagsFromTag.done();
5155 bool CanBeBitfield =
5159 if (Tok.
is(tok::colon)) {
5184 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5189 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5200 DeclSpecContext::DSC_type_specifier);
5205 BaseRange =
SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5209 Diag(ColonLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type)
5212 Diag(ColonLoc, diag::ext_cxx11_enum_fixed_underlying_type)
5215 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5218 Diag(ColonLoc, diag::ext_clang_c_enum_fixed_underlying_type)
5235 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5237 else if (Tok.
is(tok::l_brace)) {
5246 IsScopedUsingClassTag =
false;
5252 }
else if (!isTypeSpecifier(DSC) &&
5253 (Tok.
is(tok::semi) ||
5255 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5260 if (Tok.
isNot(tok::semi)) {
5262 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5270 bool IsElaboratedTypeSpecifier =
5276 diagsFromTag.redelay();
5280 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
5284 Diag(Tok, diag::err_enum_template);
5289 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
5292 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5296 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5298 TemplateInfo.TemplateParams->size());
5303 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5319 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5321 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5322 diag::err_keyword_not_allowed,
5325 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5326 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5327 else if (ScopedEnumKWLoc.
isValid())
5328 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5332 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5342 bool IsDependent =
false;
5343 const char *PrevSpec =
nullptr;
5348 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5349 IsScopedUsingClassTag,
5350 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5351 DSC == DeclSpecContext::DSC_template_param ||
5352 DSC == DeclSpecContext::DSC_template_type_arg,
5353 OffsetOfState, &SkipBody).
get();
5363 NameLoc.
isValid() ? NameLoc : StartLoc,
5364 PrevSpec, DiagID,
TagDecl, Owned,
5366 Diag(StartLoc, DiagID) << PrevSpec;
5375 Diag(Tok, diag::err_expected_type_name_after_typename);
5381 if (
Type.isInvalid()) {
5387 NameLoc.
isValid() ? NameLoc : StartLoc,
5388 PrevSpec, DiagID,
Type.get(),
5390 Diag(StartLoc, DiagID) << PrevSpec;
5409 ParseEnumBody(StartLoc, D);
5418 NameLoc.
isValid() ? NameLoc : StartLoc,
5419 PrevSpec, DiagID,
TagDecl, Owned,
5421 Diag(StartLoc, DiagID) << PrevSpec;
5444 Diag(Tok, diag::err_empty_enum);
5449 Decl *LastEnumConstDecl =
nullptr;
5452 while (Tok.
isNot(tok::r_brace)) {
5455 if (Tok.
isNot(tok::identifier)) {
5467 MaybeParseGNUAttributes(attrs);
5468 if (isAllowedCXX11AttributeSpecifier()) {
5471 ? diag::warn_cxx14_compat_ns_enum_attribute
5472 : diag::ext_ns_enum_attribute)
5474 ParseCXX11Attributes(attrs);
5479 EnumAvailabilityDiags.emplace_back(*
this);
5492 EqualLoc, AssignedVal.
get());
5493 EnumAvailabilityDiags.back().done();
5495 EnumConstantDecls.push_back(EnumConstDecl);
5496 LastEnumConstDecl = EnumConstDecl;
5498 if (Tok.
is(tok::identifier)) {
5501 Diag(Loc, diag::err_enumerator_list_missing_comma)
5524 if (Tok.
is(tok::r_brace) && CommaLoc.
isValid()) {
5527 diag::ext_enumerator_list_comma_cxx :
5528 diag::ext_enumerator_list_comma_c)
5531 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5542 MaybeParseGNUAttributes(attrs);
5548 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5549 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5551 EnumAvailabilityDiags[i].redelay();
5552 PD.complete(EnumConstantDecls[i]);
5561 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5562 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5574bool Parser::isKnownToBeTypeSpecifier(
const Token &Tok)
const {
5576 default:
return false;
5580 case tok::kw___int64:
5581 case tok::kw___int128:
5582 case tok::kw_signed:
5583 case tok::kw_unsigned:
5584 case tok::kw__Complex:
5585 case tok::kw__Imaginary:
5588 case tok::kw_wchar_t:
5589 case tok::kw_char8_t:
5590 case tok::kw_char16_t:
5591 case tok::kw_char32_t:
5593 case tok::kw__ExtInt:
5594 case tok::kw__BitInt:
5595 case tok::kw___bf16:
5598 case tok::kw_double:
5599 case tok::kw__Accum:
5600 case tok::kw__Fract:
5601 case tok::kw__Float16:
5602 case tok::kw___float128:
5603 case tok::kw___ibm128:
5606 case tok::kw__Decimal32:
5607 case tok::kw__Decimal64:
5608 case tok::kw__Decimal128:
5609 case tok::kw___vector:
5610#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5611#include "clang/Basic/OpenCLImageTypes.def"
5615 case tok::kw_struct:
5616 case tok::kw___interface:
5622 case tok::annot_typename:
5629bool Parser::isTypeSpecifierQualifier() {
5631 default:
return false;
5633 case tok::identifier:
5634 if (TryAltiVecVectorToken())
5637 case tok::kw_typename:
5642 if (Tok.
is(tok::identifier))
5644 return isTypeSpecifierQualifier();
5646 case tok::coloncolon:
5653 return isTypeSpecifierQualifier();
5656 case tok::kw___attribute:
5658 case tok::kw_typeof:
5659 case tok::kw_typeof_unqual:
5664 case tok::kw___int64:
5665 case tok::kw___int128:
5666 case tok::kw_signed:
5667 case tok::kw_unsigned:
5668 case tok::kw__Complex:
5669 case tok::kw__Imaginary:
5672 case tok::kw_wchar_t:
5673 case tok::kw_char8_t:
5674 case tok::kw_char16_t:
5675 case tok::kw_char32_t:
5677 case tok::kw__ExtInt:
5678 case tok::kw__BitInt:
5680 case tok::kw___bf16:
5682 case tok::kw_double:
5683 case tok::kw__Accum:
5684 case tok::kw__Fract:
5685 case tok::kw__Float16:
5686 case tok::kw___float128:
5687 case tok::kw___ibm128:
5690 case tok::kw__Decimal32:
5691 case tok::kw__Decimal64:
5692 case tok::kw__Decimal128:
5693 case tok::kw___vector:
5694#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5695#include "clang/Basic/OpenCLImageTypes.def"
5699 case tok::kw_struct:
5700 case tok::kw___interface:
5707 case tok::kw_volatile:
5708 case tok::kw_restrict:
5712 case tok::kw___unknown_anytype:
5715 case tok::annot_typename:
5722 case tok::kw___cdecl:
5723 case tok::kw___stdcall:
5724 case tok::kw___fastcall:
5725 case tok::kw___thiscall:
5726 case tok::kw___regcall:
5727 case tok::kw___vectorcall:
5729 case tok::kw___ptr64:
5730 case tok::kw___ptr32:
5731 case tok::kw___pascal:
5732 case tok::kw___unaligned:
5734 case tok::kw__Nonnull:
5735 case tok::kw__Nullable:
5736 case tok::kw__Nullable_result:
5737 case tok::kw__Null_unspecified:
5739 case tok::kw___kindof:
5741 case tok::kw___private:
5742 case tok::kw___local:
5743 case tok::kw___global:
5744 case tok::kw___constant:
5745 case tok::kw___generic:
5746 case tok::kw___read_only:
5747 case tok::kw___read_write:
5748 case tok::kw___write_only:
5749 case tok::kw___funcref:
5752 case tok::kw_private:
5756 case tok::kw__Atomic:
5760 case tok::kw_groupshared:
5773 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5777 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5783 if (Tok.
is(tok::annot_repl_input_end) &&
5785 ConsumeAnnotationToken();
5790 DeclsInGroup.push_back(TLSD);
5793 for (
Stmt *S : Stmts) {
5798 DeclsInGroup.push_back(D);
5811bool Parser::isDeclarationSpecifier(
5813 bool DisambiguatingWithExpression) {
5815 default:
return false;
5822 case tok::identifier:
5826 if (TryAltiVecVectorToken())
5829 case tok::kw_decltype:
5830 case tok::kw_typename:
5835 if (TryAnnotateTypeConstraint())
5837 if (Tok.
is(tok::identifier))
5845 if (DisambiguatingWithExpression &&
5846 isStartOfObjCClassMessageMissingOpenBracket())
5849 return isDeclarationSpecifier(AllowImplicitTypename);
5851 case tok::coloncolon:
5865 case tok::kw_typedef:
5866 case tok::kw_extern:
5867 case tok::kw___private_extern__:
5868 case tok::kw_static:
5870 case tok::kw___auto_type:
5871 case tok::kw_register:
5872 case tok::kw___thread:
5873 case tok::kw_thread_local:
5874 case tok::kw__Thread_local:
5877 case tok::kw___module_private__:
5880 case tok::kw___unknown_anytype:
5885 case tok::kw___int64:
5886 case tok::kw___int128:
5887 case tok::kw_signed:
5888 case tok::kw_unsigned:
5889 case tok::kw__Complex:
5890 case tok::kw__Imaginary:
5893 case tok::kw_wchar_t:
5894 case tok::kw_char8_t:
5895 case tok::kw_char16_t:
5896 case tok::kw_char32_t:
5899 case tok::kw__ExtInt:
5900 case tok::kw__BitInt:
5902 case tok::kw___bf16:
5904 case tok::kw_double:
5905 case tok::kw__Accum:
5906 case tok::kw__Fract:
5907 case tok::kw__Float16:
5908 case tok::kw___float128:
5909 case tok::kw___ibm128:
5912 case tok::kw__Decimal32:
5913 case tok::kw__Decimal64:
5914 case tok::kw__Decimal128:
5915 case tok::kw___vector:
5919 case tok::kw_struct:
5921 case tok::kw___interface:
5927 case tok::kw_volatile:
5928 case tok::kw_restrict:
5932 case tok::kw_inline:
5933 case tok::kw_virtual:
5934 case tok::kw_explicit:
5935 case tok::kw__Noreturn:
5938 case tok::kw__Alignas:
5941 case tok::kw_friend:
5944 case tok::kw_static_assert:
5945 case tok::kw__Static_assert:
5948 case tok::kw_typeof:
5949 case tok::kw_typeof_unqual:
5952 case tok::kw___attribute:
5955 case tok::annot_decltype:
5956 case tok::annot_pack_indexing_type:
5957 case tok::kw_constexpr:
5960 case tok::kw_consteval:
5961 case tok::kw_constinit:
5964 case tok::kw__Atomic:
5967 case tok::kw_alignas:
5977 case tok::annot_typename:
5978 return !DisambiguatingWithExpression ||
5979 !isStartOfObjCClassMessageMissingOpenBracket();
5982 case tok::annot_template_id: {
5988 return isTypeConstraintAnnotation() &&
5992 case tok::annot_cxxscope: {
6001 if (
NextToken().is(tok::identifier) && TryAnnotateTypeConstraint())
6003 return isTypeConstraintAnnotation() &&
6004 GetLookAheadToken(2).isOneOf(tok::kw_auto, tok::kw_decltype);
6007 case tok::kw___declspec:
6008 case tok::kw___cdecl:
6009 case tok::kw___stdcall:
6010 case tok::kw___fastcall:
6011 case tok::kw___thiscall:
6012 case tok::kw___regcall:
6013 case tok::kw___vectorcall:
6015 case tok::kw___sptr:
6016 case tok::kw___uptr:
6017 case tok::kw___ptr64:
6018 case tok::kw___ptr32:
6019 case tok::kw___forceinline:
6020 case tok::kw___pascal:
6021 case tok::kw___unaligned:
6023 case tok::kw__Nonnull:
6024 case tok::kw__Nullable:
6025 case tok::kw__Nullable_result:
6026 case tok::kw__Null_unspecified:
6028 case tok::kw___kindof:
6030 case tok::kw___private:
6031 case tok::kw___local:
6032 case tok::kw___global:
6033 case tok::kw___constant:
6034 case tok::kw___generic:
6035 case tok::kw___read_only:
6036 case tok::kw___read_write:
6037 case tok::kw___write_only:
6038#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
6039#include "clang/Basic/OpenCLImageTypes.def"
6041 case tok::kw___funcref:
6042 case tok::kw_groupshared:
6045 case tok::kw_private:
6050bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
6052 const ParsedTemplateInfo *TemplateInfo) {
6053 RevertingTentativeParsingAction TPA(*
this);
6056 if (TemplateInfo && TemplateInfo->TemplateParams)
6059 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6066 if (Tok.
is(tok::identifier)) {
6070 }
else if (Tok.
is(tok::annot_template_id)) {
6071 ConsumeAnnotationToken();
6078 SkipCXX11Attributes();
6081 if (Tok.
isNot(tok::l_paren)) {
6088 if (Tok.
is(tok::r_paren) ||
6089 (Tok.
is(tok::ellipsis) &&
NextToken().is(tok::r_paren))) {
6096 isCXX11AttributeSpecifier(
false,
6102 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6104 DeclScopeObj.EnterDeclaratorScope();
6108 MaybeParseMicrosoftAttributes(Attrs);
6117 bool IsConstructor =
false;
6123 if (Tok.
is(tok::kw_this)) {
6125 return isDeclarationSpecifier(ITC);
6128 if (isDeclarationSpecifier(ITC))
6129 IsConstructor =
true;
6130 else if (Tok.
is(tok::identifier) ||
6131 (Tok.
is(tok::annot_cxxscope) &&
NextToken().is(tok::identifier))) {
6136 if (Tok.
is(tok::annot_cxxscope))
6137 ConsumeAnnotationToken();
6149 case tok::coloncolon:
6162 SkipCXX11Attributes();
6164 if (DeductionGuide) {
6166 IsConstructor = Tok.
is(tok::arrow);
6169 if (Tok.
is(tok::colon) || Tok.
is(tok::kw_try)) {
6173 IsConstructor =
true;
6175 if (Tok.
is(tok::semi) || Tok.
is(tok::l_brace)) {
6188 IsConstructor = IsUnqualified;
6193 IsConstructor =
true;
6197 return IsConstructor;
6212void Parser::ParseTypeQualifierListOpt(
6213 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicAllowed,
6214 bool IdentifierRequired,
6216 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6217 isAllowedCXX11AttributeSpecifier()) {
6219 ParseCXX11Attributes(Attrs);
6227 const char *PrevSpec =
nullptr;
6228 unsigned DiagID = 0;
6232 case tok::code_completion:
6235 (*CodeCompletionHandler)();
6244 case tok::kw_volatile:
6248 case tok::kw_restrict:
6252 case tok::kw__Atomic:
6254 goto DoneWithTypeQuals;
6255 diagnoseUseOfC11Keyword(Tok);
6261 case tok::kw_private:
6263 goto DoneWithTypeQuals;
6265 case tok::kw___private:
6266 case tok::kw___global:
6267 case tok::kw___local:
6268 case tok::kw___constant:
6269 case tok::kw___generic:
6270 case tok::kw___read_only:
6271 case tok::kw___write_only:
6272 case tok::kw___read_write:
6276 case tok::kw_groupshared:
6284 case tok::kw___unaligned:
6288 case tok::kw___uptr:
6293 if (TryKeywordIdentFallback(
false))
6297 case tok::kw___sptr:
6299 case tok::kw___ptr64:
6300 case tok::kw___ptr32:
6301 case tok::kw___cdecl:
6302 case tok::kw___stdcall:
6303 case tok::kw___fastcall:
6304 case tok::kw___thiscall:
6305 case tok::kw___regcall:
6306 case tok::kw___vectorcall:
6307 if (AttrReqs & AR_DeclspecAttributesParsed) {
6311 goto DoneWithTypeQuals;
6313 case tok::kw___funcref:
6316 goto DoneWithTypeQuals;
6318 case tok::kw___pascal:
6319 if (AttrReqs & AR_VendorAttributesParsed) {
6323 goto DoneWithTypeQuals;
6326 case tok::kw__Nonnull:
6327 case tok::kw__Nullable:
6328 case tok::kw__Nullable_result:
6329 case tok::kw__Null_unspecified:
6334 case tok::kw___kindof:
6336 nullptr, 0, tok::kw___kindof);
6340 case tok::kw___attribute:
6341 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6343 Diag(Tok, diag::err_attributes_not_allowed);
6347 if (AttrReqs & AR_GNUAttributesParsed ||
6348 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6366 assert(PrevSpec &&
"Method did not return previous specifier!");
6367 Diag(Tok, DiagID) << PrevSpec;
6378 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6384 if (Kind == tok::star || Kind == tok::caret)
6388 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6389 Lang.getOpenCLCompatibleVersion() >= 200)
6392 if (!Lang.CPlusPlus)
6395 if (Kind == tok::amp)
6403 if (Kind == tok::ampamp)
6414 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6446void Parser::ParseDeclaratorInternal(
Declarator &D,
6447 DirectDeclParseFunction DirectDeclParser) {
6455 (Tok.
is(tok::coloncolon) || Tok.
is(tok::kw_decltype) ||
6456 (Tok.
is(tok::identifier) &&
6458 Tok.
is(tok::annot_cxxscope))) {
6463 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6464 false, EnteringContext);
6467 if (Tok.
isNot(tok::star)) {
6472 AnnotateScopeToken(SS,
true);
6474 if (DirectDeclParser)
6475 (this->*DirectDeclParser)(D);
6480 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6481 CompoundToken::MemberPtr);
6487 ParseTypeQualifierListOpt(DS);
6492 ParseDeclaratorInternal(D, DirectDeclParser);
6509 ParseTypeQualifierListOpt(DS);
6518 if (DirectDeclParser)
6519 (this->*DirectDeclParser)(D);
6528 if (Kind == tok::star || Kind == tok::caret) {
6534 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6536 ? AR_GNUAttributesParsed
6537 : AR_GNUAttributesParsedAndRejected);
6543 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6544 if (Kind == tok::star)
6562 if (Kind == tok::ampamp)
6564 diag::warn_cxx98_compat_rvalue_reference :
6565 diag::ext_rvalue_reference);
6568 ParseTypeQualifierListOpt(DS);
6577 diag::err_invalid_reference_qualifier_application) <<
"const";
6580 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6584 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6589 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6596 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6599 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6674void Parser::ParseDirectDeclarator(
Declarator &D) {
6681 return ParseDecompositionDeclarator(D);
6695 ParseOptionalCXXScopeSpecifier(
6697 false, EnteringContext);
6716 DeclScopeObj.EnterDeclaratorScope();
6723 goto PastIdentifier;
6747 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6757 if (Tok.
isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6761 bool AllowConstructorName;
6762 bool AllowDeductionGuide;
6764 AllowConstructorName =
false;
6765 AllowDeductionGuide =
false;
6769 AllowDeductionGuide =
false;
6782 true, AllowConstructorName,
6783 AllowDeductionGuide, &TemplateKWLoc,
6796 DeclScopeObj.EnterDeclaratorScope();
6803 goto PastIdentifier;
6809 diag::err_expected_unqualified_id)
6812 goto PastIdentifier;
6816 "There's a C++-specific check for tok::identifier above");
6821 goto PastIdentifier;
6826 bool DiagnoseIdentifier =
false;
6830 DiagnoseIdentifier =
true;
6833 DiagnoseIdentifier =
6841 !isCXX11VirtSpecifier(Tok))
6843 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6844 if (DiagnoseIdentifier) {
6849 goto PastIdentifier;
6853 if (Tok.
is(tok::l_paren)) {
6858 RevertingTentativeParsingAction PA(*
this);
6863 goto PastIdentifier;
6870 ParseParenDeclarator(D);
6883 DeclScopeObj.EnterDeclaratorScope();
6894 diag::ext_abstract_pack_declarator_parens);
6896 if (Tok.
getKind() == tok::annot_pragma_parser_crash)
6898 if (Tok.
is(tok::l_square))
6899 return ParseMisplacedBracketDeclarator(D);
6907 diag::err_expected_member_name_or_semi_objcxx_keyword)
6914 goto PastIdentifier;
6917 diag::err_expected_member_name_or_semi)
6921 if (Tok.
getKind() == tok::TokenKind::kw_while) {
6922 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6924 if (Tok.
isOneOf(tok::period, tok::arrow))
6925 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.
is(tok::arrow);
6933 diag::err_expected_unqualified_id)
6938 diag::err_expected_either)
6939 << tok::identifier << tok::l_paren;
6948 "Haven't past the location of the identifier yet?");
6952 MaybeParseCXX11Attributes(D);
6955 if (Tok.
is(tok::l_paren)) {
6959 ParseScope PrototypeScope(
this,
6961 (IsFunctionDeclaration
6967 bool IsAmbiguous =
false;
6979 AllowImplicitTypename =
6987 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
6988 bool IsFunctionDecl =
6989 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
6990 TentativelyDeclaredIdentifiers.pop_back();
6991 if (!IsFunctionDecl)
6997 if (IsFunctionDeclaration)
6999 TemplateParameterDepth);
7000 ParseFunctionDeclarator(D, attrs,
T, IsAmbiguous);
7001 if (IsFunctionDeclaration)
7003 PrototypeScope.Exit();
7004 }
else if (Tok.
is(tok::l_square)) {
7005 ParseBracketDeclarator(D);
7013 if (!
T.consumeOpen())
7024 Diag(Tok, diag::err_requires_clause_inside_parens);
7038void Parser::ParseDecompositionDeclarator(
Declarator &D) {
7039 assert(Tok.
is(tok::l_square));
7045 if (!(
NextToken().is(tok::identifier) &&
7046 GetLookAheadToken(2).
isOneOf(tok::comma, tok::r_square)) &&
7048 GetLookAheadToken(2).
isOneOf(tok::equal, tok::l_brace)))
7049 return ParseMisplacedBracketDeclarator(D);
7055 while (Tok.
isNot(tok::r_square)) {
7057 if (Tok.
is(tok::comma))
7060 if (Tok.
is(tok::identifier)) {
7062 Diag(EndLoc, diag::err_expected)
7065 Diag(Tok, diag::err_expected_comma_or_rsquare);
7068 SkipUntil(tok::r_square, tok::comma, tok::identifier,
7070 if (Tok.
is(tok::comma))
7072 else if (Tok.
isNot(tok::identifier))
7077 if (Tok.
isNot(tok::identifier)) {
7078 Diag(Tok, diag::err_expected) << tok::identifier;
7086 if (Tok.
isNot(tok::r_square))
7099 T.getCloseLocation());
7115void Parser::ParseParenDeclarator(
Declarator &D) {
7119 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7132 bool RequiresArg =
false;
7133 if (Tok.
is(tok::kw___attribute)) {
7134 ParseGNUAttributes(attrs);
7142 ParseMicrosoftTypeAttributes(attrs);
7145 if (Tok.
is(tok::kw___pascal))
7146 ParseBorlandTypeAttributes(attrs);
7158 }
else if (Tok.
is(tok::r_paren) ||
7161 isDeclarationSpecifier(
7163 isCXX11AttributeSpecifier()) {
7181 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7186 std::move(attrs),
T.getCloseLocation());
7192 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7205 ParseScope PrototypeScope(
this,
7209 ParseFunctionDeclarator(D, attrs,
T,
false, RequiresArg);
7210 PrototypeScope.Exit();
7213void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7215 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7223 bool IsCXX11MemberFunction =
7231 if (!IsCXX11MemberFunction)
7251 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.
CurContext), Q,
7252 IsCXX11MemberFunction);
7275void Parser::ParseFunctionDeclarator(
Declarator &D,
7280 assert(
getCurScope()->isFunctionPrototypeScope() &&
7281 "Should call from a Function scope");
7287 bool HasProto =
false;
7294 bool RefQualifierIsLValueRef =
true;
7312 StartLoc = LParenLoc;
7314 if (isFunctionDeclaratorIdentifierList()) {
7316 Diag(Tok, diag::err_argument_required_after_attribute);
7318 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7322 LocalEndLoc = RParenLoc;
7327 MaybeParseCXX11Attributes(FnAttrs);
7328 ProhibitAttributes(FnAttrs);
7330 if (Tok.
isNot(tok::r_paren))
7331 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7332 else if (RequiresArg)
7333 Diag(Tok, diag::err_argument_required_after_attribute);
7344 LocalEndLoc = RParenLoc;
7353 ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed,
7356 llvm::function_ref<
void()>([&]() {
7364 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7365 EndLoc = RefQualifierLoc;
7367 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7368 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7378 GetLookAheadToken(0).is(tok::kw_noexcept) &&
7379 GetLookAheadToken(1).is(tok::l_paren) &&
7380 GetLookAheadToken(2).is(tok::kw_noexcept) &&
7381 GetLookAheadToken(3).is(tok::l_paren) &&
7382 GetLookAheadToken(4).is(tok::identifier) &&
7383 GetLookAheadToken(4).getIdentifierInfo()->isStr(
"swap")) {
7394 ESpecType = tryParseExceptionSpecification(Delayed,
7397 DynamicExceptionRanges,
7399 ExceptionSpecTokens);
7401 EndLoc = ESpecRange.
getEnd();
7405 MaybeParseCXX11Attributes(FnAttrs);
7408 LocalEndLoc = EndLoc;
7410 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7415 TrailingReturnType =
7417 TrailingReturnTypeLoc =
Range.getBegin();
7418 EndLoc =
Range.getEnd();
7421 MaybeParseCXX11Attributes(FnAttrs);
7433 if (!ND || isa<ParmVarDecl>(ND))
7435 DeclsInPrototype.push_back(ND);
7442 llvm::sort(DeclsInPrototype, [](
Decl *D1,
Decl *D2) {
7450 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7451 ParamInfo.size(), EllipsisLoc, RParenLoc,
7452 RefQualifierIsLValueRef, RefQualifierLoc,
7454 ESpecType, ESpecRange, DynamicExceptions.data(),
7455 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7456 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7457 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7458 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7460 std::move(FnAttrs), EndLoc);
7465bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7467 if (Tok.
isOneOf(tok::amp, tok::ampamp)) {
7469 diag::warn_cxx98_compat_ref_qualifier :
7470 diag::ext_ref_qualifier);
7472 RefQualifierIsLValueRef = Tok.
is(tok::amp);
7484bool Parser::isFunctionDeclaratorIdentifierList() {
7486 && Tok.
is(tok::identifier)
7487 && !TryAltiVecVectorToken()
7503 && (!Tok.
is(tok::eof) &&
7516void Parser::ParseFunctionDeclaratorIdentifierList(
7520 assert(!
getLangOpts().requiresStrictPrototypes() &&
7521 "Cannot parse an identifier list in C23 or C++");
7528 Diag(Tok, diag::ext_ident_list_in_param);
7531 llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
7535 if (Tok.
isNot(tok::identifier)) {
7536 Diag(Tok, diag::err_expected) << tok::identifier;
7547 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7550 if (!ParamsSoFar.insert(ParmII).second) {
7551 Diag(Tok, diag::err_param_redefinition) << ParmII;
7597void Parser::ParseParameterDeclarationClause(
7606 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7627 IsACXXFunctionDeclaration) {
7649 ArgDeclSpecAttrs.takeAllFrom(FirstArgAttrs);
7652 MaybeParseCXX11Attributes(ArgDeclAttrs);
7655 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7666 ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(),
7667 AS_none, DeclSpecContext::DSC_normal,
7668 nullptr, AllowImplicitTypename);
7681 ParseDeclarator(ParmDeclarator);
7684 ParmDeclarator.SetRangeBegin(ThisLoc);
7687 MaybeParseGNUAttributes(ParmDeclarator);
7691 if (Tok.
is(tok::kw_requires)) {
7696 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7707 std::unique_ptr<CachedTokens> DefArgToks;
7711 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7712 ParmDeclarator.getNumTypeObjects() == 0) {
7714 Diag(DSStart, diag::err_missing_param);
7721 if (Tok.
is(tok::ellipsis) &&
7723 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7726 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7745 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7761 if (Tok.
is(tok::equal)) {
7772 ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument);
7788 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7789 DefArgResult = ParseBraceInitializer();
7791 if (Tok.
is(tok::l_paren) &&
NextToken().is(tok::l_brace)) {
7792 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7809 DefArgResult.
get());
7815 ParmDeclarator.getIdentifierLoc(),
7816 Param, std::move(DefArgToks)));
7823 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7825 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7830 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7831 << ParmEllipsis.
isValid() << ParmEllipsis;
7834 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7836 Diag(ParmDeclarator.getIdentifierLoc(),
7837 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7840 << !ParmDeclarator.hasName();
7842 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7861void Parser::ParseBracketDeclarator(
Declarator &D) {
7862 if (CheckProhibitedCXX11Attribute())
7870 if (Tok.
getKind() == tok::r_square) {
7873 MaybeParseCXX11Attributes(attrs);
7877 T.getOpenLocation(),
7878 T.getCloseLocation()),
7879 std::move(attrs),
T.getCloseLocation());
7881 }
else if (Tok.
getKind() == tok::numeric_constant &&
7882 GetLookAheadToken(1).is(tok::r_square)) {
7889 MaybeParseCXX11Attributes(attrs);
7893 T.getOpenLocation(),
7894 T.getCloseLocation()),
7895 std::move(attrs),
T.getCloseLocation());
7897 }
else if (Tok.
getKind() == tok::code_completion) {
7910 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
7918 bool isStar =
false;
7925 if (Tok.
is(tok::star) && GetLookAheadToken(1).is(tok::r_square)) {
7929 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7933 }
else if (Tok.
isNot(tok::r_square)) {
7951 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7971 isStar, NumElements.
get(),
T.getOpenLocation(),
7972 T.getCloseLocation()),
7977void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
7978 assert(Tok.
is(tok::l_square) &&
"Missing opening bracket");
7985 while (Tok.
is(tok::l_square)) {
7986 ParseBracketDeclarator(TempDeclarator);
7992 if (Tok.
is(tok::semi))
7998 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
8003 if (TempDeclarator.getNumTypeObjects() == 0)
8007 bool NeedParens =
false;
8032 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
8045 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
8049 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8057 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8077void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
8078 assert(Tok.
isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
8079 "Not a typeof specifier");
8081 bool IsUnqual = Tok.
is(tok::kw_typeof_unqual);
8088 bool HasParens = Tok.
is(tok::l_paren);
8098 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange));
8114 const char *PrevSpec =
nullptr;
8122 Diag(StartLoc, DiagID) << PrevSpec;
8139 const char *PrevSpec =
nullptr;
8147 Diag(StartLoc, DiagID) << PrevSpec;
8153void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
8154 assert(Tok.
is(tok::kw__Atomic) &&
NextToken().is(tok::l_paren) &&
8155 "Not an atomic specifier");
8159 if (
T.consumeOpen())
8163 if (
Result.isInvalid()) {
8171 if (
T.getCloseLocation().isInvalid())
8177 const char *PrevSpec =
nullptr;
8182 Diag(StartLoc, DiagID) << PrevSpec;
8187bool Parser::TryAltiVecVectorTokenOutOfLine() {
8189 switch (Next.getKind()) {
8190 default:
return false;
8193 case tok::kw_signed:
8194 case tok::kw_unsigned:
8199 case tok::kw_double:
8202 case tok::kw___bool:
8203 case tok::kw___pixel:
8204 Tok.
setKind(tok::kw___vector);
8206 case tok::identifier:
8207 if (Next.getIdentifierInfo() == Ident_pixel) {
8208 Tok.
setKind(tok::kw___vector);
8211 if (Next.getIdentifierInfo() == Ident_bool ||
8212 Next.getIdentifierInfo() == Ident_Bool) {
8213 Tok.
setKind(tok::kw___vector);
8221 const char *&PrevSpec,
unsigned &DiagID,
8226 switch (Next.getKind()) {
8229 case tok::kw_signed:
8230 case tok::kw_unsigned:
8235 case tok::kw_double:
8238 case tok::kw___bool:
8239 case tok::kw___pixel:
8242 case tok::identifier:
8243 if (Next.getIdentifierInfo() == Ident_pixel) {
8247 if (Next.getIdentifierInfo() == Ident_bool ||
8248 Next.getIdentifierInfo() == Ident_Bool) {
8269TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8276 FileID FID = SourceMgr.createFileID(
8277 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8281 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8282 L.setParsingPreprocessorDirective(
true);
8288 Tokens.push_back(Tok);
8289 }
while (Tok.
isNot(tok::eod));
8294 Token &EndToken = Tokens.back();
8301 Tokens.push_back(Tok);
8304 PP.EnterTokenStream(Tokens,
false,
8312 ParseScope LocalScope(
this, 0);
8325 while (Tok.
isNot(tok::eof))
8329 if (Tok.
is(tok::eof) && Tok.
getEofData() == TypeStr.data())
8334void Parser::DiagnoseBitIntUse(
const Token &Tok) {
8338 assert(Tok.
isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8339 "expected either an _ExtInt or _BitInt token!");
8342 if (Tok.
is(tok::kw__ExtInt)) {
8343 Diag(Loc, diag::warn_ext_int_deprecated)
8349 Diag(Loc, diag::warn_c23_compat_keyword) << Tok.
getName();
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
static StringRef normalizeAttrName(const IdentifierInfo *Name, StringRef NormalizedScopeName, AttributeCommonInfo::Syntax SyntaxUsed)
static Decl::Kind getKind(const Decl *D)
Defines the C++ template declaration subclasses.
llvm::MachO::RecordLoc RecordLoc
static bool isAttributeLateParsed(const IdentifierInfo &II)
isAttributeLateParsed - Return true if the attribute has arguments that require late parsing.
static bool FindLocsWithCommonFileID(Preprocessor &PP, SourceLocation StartLoc, SourceLocation EndLoc)
Check if the a start and end source location expand to the same macro.
static bool attributeHasIdentifierArg(const IdentifierInfo &II)
Determine whether the given attribute has an identifier argument.
static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II)
Determine whether the given attribute treats kw_this as an identifier.
static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II)
Determine whether the given attribute requires parsing its arguments in an unevaluated context or not...
static bool isValidAfterIdentifierInDeclarator(const Token &T)
isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the specified token is valid after t...
static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II)
Determine whether the given attribute has a variadic identifier argument.
static bool attributeAcceptsExprPack(const IdentifierInfo &II)
Determine if an attribute accepts parameter packs.
static bool isPipeDeclarator(const Declarator &D)
static SourceLocation getMissingDeclaratorIdLoc(Declarator &D, SourceLocation Loc)
static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS, Parser &P)
static bool VersionNumberSeparator(const char Separator)
static bool attributeIsTypeArgAttr(const IdentifierInfo &II)
Determine whether the given attribute parses a type argument.
static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, DeclaratorContext TheContext)
static ParsedAttributeArgumentsProperties attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II)
Determine whether the given attribute has an identifier argument.
llvm::SmallVector< std::pair< const MemRegion *, SVal >, 4 > Bindings
static constexpr bool isOneOf()
This file declares semantic analysis for CUDA constructs.
This file declares semantic analysis for OpenMP constructs and clauses.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the clang::TokenKind enum and support functions.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
const clang::PrintingPolicy & getPrintingPolicy() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
The result of parsing/analyzing an expression, statement etc.
@ AS_Declspec
__declspec(...)
Kind getParsedKind() const
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
SourceLocation getOpenLocation() const
SourceLocation getCloseLocation() const
Represents a C++ nested-name-specifier or a global scope specifier.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
SourceLocation getEndLoc() const
bool isSet() const
Deprecated.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
void setTemplateParamLists(ArrayRef< TemplateParameterList * > L)
bool isEmpty() const
No scope specifier.
Represents a character-granular source range.
SourceLocation getBegin() const
Callback handler that receives notifications when performing code completion within the preprocessor.
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed.
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Captures information about "declaration specifiers".
bool isVirtualSpecified() const
bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, ExplicitSpecifier ExplicitSpec, SourceLocation CloseParenLoc)
bool isTypeSpecPipe() const
static const TSCS TSCS___thread
static const TST TST_typeof_unqualType
void setTypeArgumentRange(SourceRange range)
bool SetTypePipe(bool isPipe, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
SourceLocation getPipeLoc() const
static const TST TST_typename
SourceLocation getEndLoc() const LLVM_READONLY
bool hasTypeSpecifier() const
Return true if any type-specifier has been found.
bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec and return false if there was no error.
static const TST TST_char8
static const TST TST_BFloat16
void ClearStorageClassSpecs()
bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TSCS TSCS__Thread_local
bool SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec, but return true and ignore the request if ...
bool isNoreturnSpecified() const
TST getTypeSpecType() const
SourceLocation getStorageClassSpecLoc() const
SCS getStorageClassSpec() const
bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceRange getSourceRange() const LLVM_READONLY
bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void SetRangeEnd(SourceLocation Loc)
bool SetBitIntType(SourceLocation KWLoc, Expr *BitWidth, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_auto_type
static const TST TST_interface
static const TST TST_double
static const TST TST_typeofExpr
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
void SetRangeStart(SourceLocation Loc)
bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getNoreturnSpecLoc() const
static const TST TST_union
static const TST TST_char
static const TST TST_bool
static const TST TST_char16
SourceLocation getExplicitSpecLoc() const
SourceLocation getFriendSpecLoc() const
SourceLocation getModulePrivateSpecLoc() const
bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void UpdateTypeRep(ParsedType Rep)
TSCS getThreadStorageClassSpec() const
bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasAttributes() const
static const TST TST_accum
static const TST TST_half
ParsedAttributes & getAttributes()
SourceLocation getConstSpecLoc() const
static const TST TST_ibm128
void addAttributes(const ParsedAttributesView &AL)
Concatenates two attribute lists.
static const TST TST_enum
bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_float128
void Finish(Sema &S, const PrintingPolicy &Policy)
Finish - This does final analysis of the declspec, issuing diagnostics for things like "_Imaginary" (...
bool isInlineSpecified() const
SourceLocation getRestrictSpecLoc() const
static const TST TST_typeof_unqualExpr
static const TST TST_class
bool hasTagDefinition() const
static const TST TST_decimal64
unsigned getParsedSpecifiers() const
Return a bitmask of which flavors of specifiers this DeclSpec includes.
void ClearFunctionSpecs()
bool SetTypeQual(TQ T, SourceLocation Loc)
static const TST TST_wchar
static const TST TST_void
bool isTypeAltiVecVector() const
void ClearConstexprSpec()
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
static const TST TST_float
static const TST TST_atomic
static const TST TST_fract
SourceLocation getThreadStorageClassSpecLoc() const
Decl * getRepAsDecl() const
static const TST TST_float16
static const TST TST_unspecified
SourceLocation getAtomicSpecLoc() const
SourceLocation getVirtualSpecLoc() const
SourceLocation getConstexprSpecLoc() const
CXXScopeSpec & getTypeSpecScope()
bool isEmpty() const
isEmpty - Return true if this declaration specifier is completely empty: no tokens were parsed in the...
SourceLocation getTypeSpecTypeLoc() const
static const TSCS TSCS_thread_local
bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal32
bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
TypeSpecifierWidth getTypeSpecWidth() const
static const TST TST_char32
bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal128
bool isTypeSpecOwned() const
SourceLocation getInlineSpecLoc() const
SourceLocation getUnalignedSpecLoc() const
static const TST TST_int128
SourceLocation getVolatileSpecLoc() const
FriendSpecified isFriendSpecified() const
bool hasExplicitSpecifier() const
bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasConstexprSpecifier() const
void takeAttributesFrom(ParsedAttributes &attrs)
static const TST TST_typeofType
bool SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_auto
@ PQ_StorageClassSpecifier
ConstexprSpecKind getConstexprSpecifier() const
static const TST TST_struct
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getLocation() const
Information about one declarator, including the parsed type information and the identifier.
bool isFunctionDeclarator(unsigned &idx) const
isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...
bool isPastIdentifier() const
isPastIdentifier - Return true if we have parsed beyond the point where the name would appear.
void SetRangeBegin(SourceLocation Loc)
SetRangeBegin - Set the start of the source range to Loc, unless it's invalid.
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
void setCommaLoc(SourceLocation CL)
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
SourceLocation getIdentifierLoc() const
void SetIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
bool mayOmitIdentifier() const
mayOmitIdentifier - Return true if the identifier is either optional or not allowed.
SourceLocation getEndLoc() const LLVM_READONLY
bool mayBeFollowedByCXXDirectInit() const
mayBeFollowedByCXXDirectInit - Return true if the declarator can be followed by a C++ direct initiali...
bool hasGroupingParens() const
void setInvalidType(bool Val=true)
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
bool mayHaveIdentifier() const
mayHaveIdentifier - Return true if the identifier is either optional or required.
void setGroupingParens(bool flag)
SourceLocation getEllipsisLoc() const
DeclaratorContext getContext() const
SourceLocation getBeginLoc() const LLVM_READONLY
void setTrailingRequiresClause(Expr *TRC)
Sets a trailing requires clause for this declarator.
void setHasInitializer(bool Val=true)
UnqualifiedId & getName()
Retrieve the name specified by this declarator.
void setTemplateParameterLists(ArrayRef< TemplateParameterList * > TPLs)
Sets the template parameter lists that preceded the declarator.
bool isFirstDeclarator() const
bool hasTrailingRequiresClause() const
Determine whether a trailing requires clause was written in this declarator.
void setDecompositionBindings(SourceLocation LSquareLoc, ArrayRef< DecompositionDeclarator::Binding > Bindings, SourceLocation RSquareLoc)
Set the decomposition bindings for this declarator.
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
The template parameter lists that preceded the declarator.
bool isFunctionDeclaratorAFunctionDeclaration() const
Return true if a function declarator at this position would be a function declaration.
void clear()
Reset the contents of this Declarator.
void setAsmLabel(Expr *E)
void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &&attrs, SourceLocation EndLoc)
AddTypeInfo - Add a chunk to this declarator.
void ExtendWithDeclSpec(const DeclSpec &DS)
ExtendWithDeclSpec - Extend the declarator source range to include the given declspec,...
void SetRangeEnd(SourceLocation Loc)
SetRangeEnd - Set the end of the source range to Loc, unless it's invalid.
void setExtension(bool Val=true)
bool isInvalidType() const
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
bool isFirstDeclarationOfMember()
Returns true if this declares a real member and not a friend.
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
void setEllipsisLoc(SourceLocation EL)
const IdentifierInfo * getIdentifier() const
bool hasAllExtensionsSilenced()
RAII object that enters a new expression evaluation context.
Store information needed for an explicit specifier.
This represents one expression.
ExtensionRAIIObject - This saves the state of extension warnings when constructed and disables them.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code from FromRange at a specific location.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
bool isCPlusPlusKeyword(const LangOptions &LangOpts) const
Return true if this token is a C++ keyword in the specified language.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
const char * getNameStart() const
Return the beginning of the actual null-terminated string for this identifier.
bool isKeyword(const LangOptions &LangOpts) const
Return true if this token is a keyword in the specified language.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
void revertTokenIDToIdentifier()
Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2 compatibility.
StringRef getName() const
Return the actual identifier string.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool requiresStrictPrototypes() const
Returns true if functions without prototypes or functions with an identifier list (aka K&R C function...
std::string getOpenCLVersionString() const
Return the OpenCL C or C++ for OpenCL language name and version as a string.
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static bool isAtStartOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroBegin=nullptr)
Returns true if the given MacroID location points at the first token of the macro expansion.
static bool isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroEnd=nullptr)
Returns true if the given MacroID location points at the last token of the macro expansion.
static bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, const LangOptions &LangOpts, bool IgnoreWhiteSpace=false)
Relex the token at the specified location.
static std::optional< Token > findNextToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Finds the token that comes right after the given location.
Represents the results of name lookup.
This represents a decl that may have a name.
bool isSupported(llvm::StringRef Ext, const LangOptions &LO) const
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...
Represents a parameter to a function.
static constexpr unsigned getMaxFunctionScopeDepth()
ParsedAttr - Represents a syntactic attribute.
unsigned getMaxArgs() const
static const ParsedAttributesView & none()
void addAtEnd(ParsedAttr *newAttr)
void addAll(iterator B, iterator E)
void remove(ParsedAttr *ToBeRemoved)
ParsedAttributes - A collection of parsed attributes.
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA)
ParsedAttr * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Form formUsed)
Add microsoft __delspec(property) attribute.
ParsedAttr * addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, ParsedAttr::Form form)
Add type_tag_for_datatype attribute.
ParsedAttr * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ParsedType typeArg, ParsedAttr::Form formUsed, SourceLocation ellipsisLoc=SourceLocation())
Add an attribute with a single type argument.
Parser - This implements a parser for the C family of languages.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
DeclGroupPtrTy ParseOpenACCDirectiveDecl()
Placeholder for now, should just ignore the directives after emitting a diagnostic.
Sema & getActions() const
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
Scope * getCurScope() const
SourceLocation getEndOfPreviousToken()
ExprResult ParseArrayBoundExpression()
const TargetInfo & getTargetInfo() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
friend class ObjCDeclContextSwitch
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
ExprResult ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast=NotTypeCast)
const LangOptions & getLangOpts() const
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtCodeCompletion
Stop at code completion.
@ StopAtSemi
Stop skipping at semicolon.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
ExprResult ParseUnevaluatedStringLiteralExpression()
ObjCContainerDecl * getObjCDeclContext() const
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
SmallVector< TemplateParameterList *, 4 > TemplateParameterLists
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
RAII object used to inform the actions that we're currently parsing a declaration.
A class for parsing a DeclSpec.
A class for parsing a declarator.
A class for parsing a field declarator.
void enterVariableInit(SourceLocation Tok, Decl *D)
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool isIncrementalProcessingEnabled() const
Returns true if incremental processing is enabled.
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
SourceManager & getSourceManager() const
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
const LangOptions & getLangOpts() const
bool isCodeCompletionReached() const
Returns true if code-completion is enabled and we have hit the code-completion point.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
PrettyDeclStackTraceEntry - If a crash occurs in the parser while parsing something related to a decl...
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
The collection of all-type qualifiers we support.
void addAddressSpace(LangAS space)
static Qualifiers fromCVRUMask(unsigned CVRU)
Represents a struct/union/class.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isClassScope() const
isClassScope - Return true if this scope is a class/struct/union scope.
unsigned getFlags() const
getFlags - Return the flags for this scope.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ BlockScope
This is a scope that corresponds to a block/closure object.
@ 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 startOpenMPCXXRangeFor()
If the current region is a range loop-based region, mark the start of the loop construct.
NameClassificationKind getKind() const
void CodeCompleteTag(Scope *S, unsigned TagSpec)
bool containsUnexpandedParameterPacks(Declarator &D)
Determine whether the given declarator contains any unexpanded parameter packs.
void ActOnParamUnparsedDefaultArgument(Decl *param, SourceLocation EqualLoc, SourceLocation ArgLoc)
ActOnParamUnparsedDefaultArgument - We've seen a default argument for a function parameter,...
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
void ActOnDefinedDeclarationSpecifier(Decl *D)
Called once it is known whether a tag declaration is an anonymous union or struct.
ExplicitSpecifier ActOnExplicitBoolSpecifier(Expr *E)
ActOnExplicitBoolSpecifier - Build an ExplicitSpecifier from an expression found in an explicit(bool)...
void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc, Expr *DefaultArg)
ActOnParamDefaultArgumentError - Parsing or semantic analysis of the default argument for the paramet...
TemplateParameterList * ActOnTemplateParameterList(unsigned Depth, SourceLocation ExportLoc, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
ActOnTemplateParameterList - Builds a TemplateParameterList, optionally constrained by RequiresClause...
void CodeCompleteInitializer(Scope *S, Decl *D)
QualType ProduceConstructorSignatureHelp(QualType Type, SourceLocation Loc, ArrayRef< Expr * > Args, SourceLocation OpenParLoc, bool Braced)
void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl, SourceRange BraceRange)
ActOnTagFinishDefinition - Invoked once we have finished parsing the definition of a tag (enumeration...
Decl * ActOnParamDeclarator(Scope *S, Declarator &D, SourceLocation ExplicitThisLoc={})
ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator() to introduce parameters into fun...
TypeResult ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, const CXXScopeSpec &SS, const IdentifierInfo *Name, SourceLocation TagLoc, SourceLocation NameLoc)
Decl * ActOnTemplateDeclarator(Scope *S, MultiTemplateParamsArg TemplateParameterLists, Declarator &D)
TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S)
isTagName() - This method is called for error recovery purposes only to determine if the specified na...
void ActOnFinishFunctionDeclarationDeclarator(Declarator &D)
Called after parsing a function declarator belonging to a function declaration.
void ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc, Expr *defarg)
ActOnParamDefaultArgument - Check whether the default argument provided for a function parameter is w...
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
void ActOnFinishTopLevelStmtDecl(TopLevelStmtDecl *D, Stmt *Statement)
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param)
This is used to implement the constant expression evaluation part of the attribute enable_if extensio...
ASTContext & getASTContext() const
bool isCurrentClassName(const IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS=nullptr)
isCurrentClassName - Determine whether the identifier II is the name of the class type currently bein...
@ NC_Unknown
This name is not a type or template in this context, but might be something else.
@ NC_VarTemplate
The name was classified as a variable template name.
@ NC_NonType
The name was classified as a specific non-type, non-template declaration.
@ NC_TypeTemplate
The name was classified as a template whose specializations are types.
@ NC_Error
Classification failed; an error has been produced.
@ NC_FunctionTemplate
The name was classified as a function template name.
@ NC_DependentNonType
The name denotes a member of a dependent type that could not be resolved.
@ NC_UndeclaredNonType
The name was classified as an ADL-only function name.
@ NC_UndeclaredTemplate
The name was classified as an ADL-only function template name.
@ NC_Keyword
The name has been typo-corrected to a keyword.
@ NC_Type
The name was classified as a type.
@ NC_OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ NC_Concept
The name was classified as a concept name.
void ActOnStartFunctionDeclarationDeclarator(Declarator &D, unsigned TemplateParameterDepth)
Called before parsing a function declarator belonging to a function declaration.
ExprResult ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val)
void CodeCompleteTypeQualifiers(DeclSpec &DS)
ParsedType ActOnObjCInstanceType(SourceLocation Loc)
The parser has parsed the context-sensitive type 'instancetype' in an Objective-C message declaration...
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
void ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart, const IdentifierInfo *ClassName, SmallVectorImpl< Decl * > &Decls)
Called whenever @defs(ClassName) is encountered in the source.
const LangOptions & getLangOpts() const
bool isUnexpandedParameterPackPermitted()
Determine whether an unexpanded parameter pack might be permitted in this location.
bool ActOnAlignasTypeArgument(StringRef KWName, ParsedType Ty, SourceLocation OpLoc, SourceRange R)
ActOnAlignasTypeArgument - Handle alignas(type-id) and _Alignas(type-name) .
void CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D, const VirtSpecifiers *VS=nullptr)
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 LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
bool isLibstdcxxEagerExceptionSpecHack(const Declarator &D)
Determine if we're in a case where we need to (incorrectly) eagerly parse an exception specification ...
Decl * ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant, SourceLocation IdLoc, IdentifierInfo *Id, const ParsedAttributesView &Attrs, SourceLocation EqualLoc, Expr *Val)
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
bool isDeclaratorFunctionLike(Declarator &D)
Determine whether.
void CodeCompleteAttribute(AttributeCommonInfo::Syntax Syntax, AttributeCompletion Completion=AttributeCompletion::Attribute, const IdentifierInfo *Scope=nullptr)
bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody)
Perform ODR-like check for C/ObjC when merging tag types from modules.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
ParserCompletionContext
Describes the context in which code completion occurs.
@ PCC_LocalDeclarationSpecifiers
Code completion occurs within a sequence of declaration specifiers within a function,...
@ PCC_Template
Code completion occurs following one or more template headers.
@ PCC_MemberTemplate
Code completion occurs following one or more template headers within a class.
@ PCC_Class
Code completion occurs within a class, struct, or union.
@ PCC_ObjCImplementation
Code completion occurs within an Objective-C implementation or category implementation.
@ PCC_Namespace
Code completion occurs at top-level or namespace context.
SkipBodyInfo shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II, SourceLocation IILoc)
Determine whether the body of an anonymous enumeration should be skipped.
void RestoreNestedNameSpecifierAnnotation(void *Annotation, SourceRange AnnotationRange, CXXScopeSpec &SS)
Given an annotation pointer for a nested-name-specifier, restore the nested-name-specifier structure.
bool CheckTypeConstraint(TemplateIdAnnotation *TypeConstraint)
void CodeCompleteBracketDeclarator(Scope *S)
void ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, Decl *EnumDecl, ArrayRef< Decl * > Elements, Scope *S, const ParsedAttributesView &Attr)
void ActOnTagStartDefinition(Scope *S, Decl *TagDecl)
ActOnTagStartDefinition - Invoked when we have entered the scope of a tag's definition (e....
void ActOnInitializerError(Decl *Dcl)
ActOnInitializerError - Given that there was an error parsing an initializer for the given declaratio...
TypeResult ActOnTypeName(Declarator &D)
TopLevelStmtDecl * ActOnStartTopLevelStmtDecl(Scope *S)
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion.
DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, ArrayRef< Decl * > Group)
ParsedType ActOnMSVCUnknownTypeName(const IdentifierInfo &II, SourceLocation NameLoc, bool IsTemplateTypeArg)
Attempt to behave like MSVC in situations where lookup of an unqualified type name has failed in a de...
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type.
DeclResult ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc, SourceLocation TemplateLoc, unsigned TagSpec, SourceLocation KWLoc, const CXXScopeSpec &SS, TemplateTy Template, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, const ParsedAttributesView &Attr)
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
@ PotentiallyEvaluatedIfUsed
The current expression is potentially evaluated, but any declarations referenced inside that expressi...
DeclResult ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, const ParsedAttributesView &Attr, AccessSpecifier AS, SourceLocation ModulePrivateLoc, MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl, bool &IsDependent, SourceLocation ScopedEnumKWLoc, bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, bool IsTypeSpecifier, bool IsTemplateParamOrArg, OffsetOfKind OOK, SkipBodyInfo *SkipBody=nullptr)
This is invoked when we see 'struct foo' or 'struct {'.
Decl * ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, const ParsedAttributesView &DeclAttrs, RecordDecl *&AnonRecord)
ParsedFreeStandingDeclSpec - This method is invoked when a declspec with no declarator (e....
void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)
void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl, ArrayRef< Decl * > Fields, SourceLocation LBrac, SourceLocation RBrac, const ParsedAttributesView &AttrList)
SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts
A stack of expression evaluation contexts.
bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name, SourceLocation NameLoc, CXXScopeSpec &SS, ParsedTemplateTy *Template=nullptr)
Determine whether a particular identifier might be the name in a C++1z deduction-guide declaration.
void CodeCompleteDeclSpec(Scope *S, DeclSpec &DS, bool AllowNonIdentifiers, bool AllowNestedNameSpecifiers)
OpenCLOptions & getOpenCLOptions()
void CodeCompleteAfterFunctionEquals(Declarator &D)
void ActOnUninitializedDecl(Decl *dcl)
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
Decl * ActOnField(Scope *S, Decl *TagD, SourceLocation DeclStart, Declarator &D, Expr *BitfieldWidth)
ActOnField - Each field of a C struct/union is passed into this in order to create a FieldDecl object...
void ActOnCXXForRangeDecl(Decl *D)
Decl * ActOnDeclarator(Scope *S, Declarator &D)
ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope=nullptr)
void DiagnoseUnknownTypeName(IdentifierInfo *&II, SourceLocation IILoc, Scope *S, CXXScopeSpec *SS, ParsedType &SuggestedType, bool IsTemplateName=false)
ExprResult HandleExprEvaluationContextForTypeof(Expr *E)
bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS)
Determine whether the identifier II is a typo for the name of the class type currently being defined.
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
A RAII object used to temporarily suppress access-like checking.
Represents the declaration of a struct/union/class/enum.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getEndLoc() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
const char * getName() const
unsigned getLength() const
void setKind(tok::TokenKind K)
SourceLocation getAnnotationEndLoc() const
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
void * getAnnotationValue() const
tok::TokenKind getKind() const
bool isRegularKeywordAttribute() const
Return true if the token is a keyword that is parsed in the same position as a standard attribute,...
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
void setEofData(const void *D)
SourceRange getAnnotationRange() const
SourceRange of the group of tokens that this annotation token represents.
void setLocation(SourceLocation L)
bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const
bool isNot(tok::TokenKind K) const
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
const void * getEofData() const
bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const
Return true if we have an ObjC keyword identifier.
void startToken()
Reset all flags to cleared.
void setIdentifierInfo(IdentifierInfo *II)
A declaration that models statements at global scope.
void setSemiMissing(bool Missing=true)
Base wrapper for a particular "section" of type source info.
The base class of the type hierarchy.
SourceLocation EndLocation
The location of the last token that describes this unqualified-id.
SourceRange getSourceRange() const LLVM_READONLY
Return the source range that covers this unqualified-id.
SourceLocation StartLocation
The location of the first token that describes this unqualified-id, which will be the location of the...
UnqualifiedIdKind getKind() const
Determine what kind of name we have.
The iterator over UnresolvedSets.
Declaration of a variable template.
static const char * getSpecifierName(Specifier VS)
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isPragmaAnnotation(TokenKind K)
Return true if this is an annotation token representing a pragma.
The JSON file list parser is used to communicate input to InstallAPI.
TypeSpecifierType
Specifies the kind of type.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
@ IK_TemplateId
A template-id, e.g., f<int>.
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &Second, ParsedAttributes &Result)
Consumes the attributes from First and Second and concatenates them into Result.
Language
The language for the input, used to select and validate the language standard and possible actions.
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
LangAS
Defines the address space values used by the address space qualifier of QualType.
int hasAttribute(AttributeCommonInfo::Syntax Syntax, const IdentifierInfo *Scope, const IdentifierInfo *Attr, const TargetInfo &Target, const LangOptions &LangOpts)
Return the version number associated with the attribute if we recognize and implement the attribute s...
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Dependent_template_name
The name refers to a dependent template name:
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ Parens
New-expression has a C++98 paren-delimited initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_None
no exception specification
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Represents information about a change in availability for an entity, which is part of the encoding of...
VersionTuple Version
The version number at which the change occurred.
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
SourceRange VersionRange
The source range covering the version number.
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
ParamInfo - An array of paraminfo objects is allocated whenever a function declarator is parsed.
One instance of this struct is used for each type in a declarator that is parsed.
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
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.
enum clang::DeclaratorChunk::@219 Kind
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