34#include "llvm/ADT/ScopeExit.h"
35#include "llvm/ADT/SmallSet.h"
36#include "llvm/ADT/StringSwitch.h"
48 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
49 if (DSC == DeclSpecContext::DSC_normal)
50 DSC = DeclSpecContext::DSC_type_specifier;
56 ParseSpecifierQualifierList(DS, AS, DSC);
64 if (AL.isDeclspecAttribute())
65 ToBeMoved.push_back(&AL);
74 ParseDeclarator(DeclaratorInfo);
81 return Actions.ActOnTypeName(DeclaratorInfo);
86 if (Name.size() >= 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
87 return Name.drop_front(2).drop_back(2);
94#define CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
96#include "clang/Parse/AttrParserStringSwitches.inc"
98#undef CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
104#define CLANG_ATTR_LATE_PARSED_LIST
106#include "clang/Parse/AttrParserStringSwitches.inc"
108#undef CLANG_ATTR_LATE_PARSED_LIST
114#define CLANG_ATTR_PARSE_ARGS_IN_FUNCTION_SCOPE_LIST
116#include "clang/Parse/AttrParserStringSwitches.inc"
118#undef CLANG_ATTR_PARSE_ARGS_IN_FUNCTION_SCOPE_LIST
131 bool AttrStartIsInMacro =
133 bool AttrEndIsInMacro =
135 return AttrStartIsInMacro && AttrEndIsInMacro;
138void Parser::ParseAttributes(
unsigned WhichAttrKinds,
ParsedAttributes &Attrs,
145 if (WhichAttrKinds & PAKM_CXX11)
146 MoreToParse |= MaybeParseCXX11Attributes(Attrs);
147 if (WhichAttrKinds & PAKM_GNU)
148 MoreToParse |= MaybeParseGNUAttributes(Attrs, LateAttrs);
149 if (WhichAttrKinds & PAKM_Declspec)
150 MoreToParse |= MaybeParseMicrosoftDeclSpecs(Attrs);
151 }
while (MoreToParse);
158 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
164 if (Tok.isNot(tok::l_paren)) {
165 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
166 ParsedAttr::Form::GNU());
170 bool LateParse =
false;
177 LateParse =
getLangOpts().ExperimentalLateParseAttributes &&
190 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc,
nullptr,
191 SourceLocation(), ParsedAttr::Form::GNU(), D);
198 LateAttrs->push_back(LA);
202 if (!ClassStack.empty() && !LateAttrs->
parseSoon())
203 getCurrentClass().LateParsedDeclarations.push_back(LA);
207 LA->
Toks.push_back(Tok);
210 ConsumeAndStoreUntil(tok::r_paren, LA->
Toks,
true);
215 LA->
Toks.push_back(Eof);
222 assert(Tok.is(tok::kw___attribute) &&
"Not a GNU attribute list!");
224 SourceLocation StartLoc = Tok.getLocation();
225 SourceLocation EndLoc = StartLoc;
227 while (Tok.is(tok::kw___attribute)) {
229 unsigned OldNumAttrs = Attrs.
size();
230 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
232 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
237 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"(")) {
248 if (Tok.isAnnotation())
250 if (Tok.is(tok::code_completion)) {
252 Actions.CodeCompletion().CodeCompleteAttribute(
257 if (ParseSingleGNUAttribute(Attrs, EndLoc, LateAttrs, D))
259 }
while (Tok.is(tok::comma));
261 if (ExpectAndConsume(tok::r_paren))
263 SourceLocation Loc = Tok.getLocation();
264 if (ExpectAndConsume(tok::r_paren))
270 auto &SM = PP.getSourceManager();
271 if (!SM.isWrittenInBuiltinFile(SM.getSpellingLoc(AttrTokLoc)) &&
273 CharSourceRange ExpansionRange = SM.getExpansionRange(AttrTokLoc);
274 StringRef FoundName =
276 IdentifierInfo *MacroII = PP.getIdentifierInfo(FoundName);
278 for (
unsigned i = OldNumAttrs; i < Attrs.
size(); ++i)
279 Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.
getBegin());
282 for (
unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
283 (*LateAttrs)[i]->MacroII = MacroII;
288 Attrs.
Range = SourceRange(StartLoc, EndLoc);
296#define CLANG_ATTR_IDENTIFIER_ARG_LIST
298#include "clang/Parse/AttrParserStringSwitches.inc"
300#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
308#define CLANG_ATTR_STRING_LITERAL_ARG_LIST
310#include "clang/Parse/AttrParserStringSwitches.inc"
312#undef CLANG_ATTR_STRING_LITERAL_ARG_LIST
319#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
321#include "clang/Parse/AttrParserStringSwitches.inc"
323#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
330#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
332#include "clang/Parse/AttrParserStringSwitches.inc"
334#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
341#define CLANG_ATTR_ACCEPTS_EXPR_PACK
343#include "clang/Parse/AttrParserStringSwitches.inc"
345#undef CLANG_ATTR_ACCEPTS_EXPR_PACK
352#define CLANG_ATTR_TYPE_ARG_LIST
354#include "clang/Parse/AttrParserStringSwitches.inc"
356#undef CLANG_ATTR_TYPE_ARG_LIST
363#define CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
365#include "clang/Parse/AttrParserStringSwitches.inc"
367#undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
375#define CLANG_ATTR_ARG_CONTEXT_LIST
377#include "clang/Parse/AttrParserStringSwitches.inc"
379#undef CLANG_ATTR_ARG_CONTEXT_LIST
383 assert(Tok.is(tok::identifier) &&
"expected an identifier");
384 IdentifierLoc *IL =
new (Actions.Context)
385 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
400 if (Tok.isNot(tok::r_paren))
403 if (
Parens.consumeClose())
411 &AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
412 AttributeScopeInfo(ScopeName, ScopeLoc),
T.get(), Form);
414 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
415 AttributeScopeInfo(ScopeName, ScopeLoc),
nullptr, 0, Form);
419Parser::ParseUnevaluatedStringInAttribute(
const IdentifierInfo &AttrName) {
420 if (Tok.is(tok::l_paren)) {
423 ExprResult Res = ParseUnevaluatedStringInAttribute(AttrName);
424 Paren.consumeClose();
427 if (!isTokenStringLiteral()) {
428 Diag(Tok.getLocation(), diag::err_expected_string_literal)
435bool Parser::ParseAttributeArgumentList(
438 bool SawError =
false;
442 Expr = ParseUnevaluatedStringInAttribute(AttrName);
444 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
445 Expr = ParseBraceInitializer();
450 if (Tok.is(tok::ellipsis))
452 else if (Tok.is(tok::code_completion)) {
468 if (Actions.DiagnoseUnexpandedParameterPack(Expr.
get())) {
473 Exprs.push_back(Expr.
get());
475 if (Tok.isNot(tok::comma))
480 checkPotentialAngleBracketDelimiter(Comma);
487unsigned Parser::ParseAttributeArgsCommon(
496 bool AttributeIsTypeArgAttr =
498 bool AttributeHasVariadicIdentifierArg =
502 if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
503 Tok.setKind(tok::identifier);
506 if (Tok.is(tok::identifier)) {
508 bool IsIdentifierArg =
509 AttributeHasVariadicIdentifierArg ||
520 IsIdentifierArg =
Next.isOneOf(tok::r_paren, tok::comma);
524 ArgExprs.push_back(ParseIdentifierLoc());
528 if (!ArgExprs.empty() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren)) {
530 if (!ArgExprs.empty())
533 if (AttributeIsTypeArgAttr) {
541 TheParsedType =
T.get();
542 }
else if (AttributeHasVariadicIdentifierArg ||
552 if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
553 Tok.setKind(tok::identifier);
556 if (Tok.is(tok::identifier)) {
557 ArgExprs.push_back(ParseIdentifierLoc());
573 ArgExprs.push_back(ArgExpr.
get());
589 ExprVector ParsedExprs;
590 ParsedAttributeArgumentsProperties ArgProperties =
593 if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties,
600 for (
size_t I = 0; I < ParsedExprs.size(); ++I) {
605 Diag(Tok.getLocation(),
606 diag::err_attribute_argument_parm_pack_not_supported)
613 llvm::append_range(ArgExprs, ParsedExprs);
617 SourceLocation RParen = Tok.getLocation();
618 if (!ExpectAndConsume(tok::r_paren)) {
619 SourceLocation AttrLoc = ScopeLoc.
isValid() ? ScopeLoc : AttrNameLoc;
621 if (AttributeIsTypeArgAttr && !TheParsedType.
get().
isNull()) {
623 AttributeScopeInfo(ScopeName, ScopeLoc),
624 TheParsedType, Form);
626 Attrs.
addNew(AttrName, SourceRange(AttrLoc, RParen),
627 AttributeScopeInfo(ScopeName, ScopeLoc), ArgExprs.data(),
628 ArgExprs.size(), Form);
635 return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.
get().
isNull());
638void Parser::ParseGNUAttributeArgs(
643 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
648 if (AttrKind == ParsedAttr::AT_Availability) {
649 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
652 }
else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
653 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
654 ScopeName, ScopeLoc, Form);
656 }
else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
657 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
658 ScopeName, ScopeLoc, Form);
660 }
else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
661 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
664 }
else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
665 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
666 ScopeName, ScopeLoc, Form);
669 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName,
672 }
else if (AttrKind == ParsedAttr::AT_CountedBy ||
673 AttrKind == ParsedAttr::AT_CountedByOrNull ||
674 AttrKind == ParsedAttr::AT_SizedBy ||
675 AttrKind == ParsedAttr::AT_SizedByOrNull) {
676 ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
679 }
else if (AttrKind == ParsedAttr::AT_CXXAssume) {
680 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
681 ScopeLoc, EndLoc, Form);
687 std::optional<ParseScope> PrototypeScope;
692 const DeclaratorChunk::FunctionTypeInfo *FTI =
nullptr;
704 PrototypeScope.emplace(
708 for (
unsigned i = 0; i < FTI->
NumParams; ++i)
709 Actions.ActOnReenterCXXMethodParameter(
714 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
718unsigned Parser::ParseClangAttributeArgs(
722 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
729 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
730 ScopeName, ScopeLoc, Form);
731 case ParsedAttr::AT_ExternalSourceSymbol:
732 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
733 ScopeName, ScopeLoc, Form);
735 case ParsedAttr::AT_Availability:
736 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
739 case ParsedAttr::AT_ObjCBridgeRelated:
740 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
741 ScopeName, ScopeLoc, Form);
743 case ParsedAttr::AT_SwiftNewType:
744 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
747 case ParsedAttr::AT_TypeTagForDatatype:
748 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
749 ScopeName, ScopeLoc, Form);
752 case ParsedAttr::AT_CXXAssume:
753 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
754 ScopeLoc, EndLoc, Form);
757 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
763 unsigned ExistingAttrs = Attrs.
size();
775 SourceLocation OpenParenLoc = Tok.getLocation();
777 if (
AttrName->getName() ==
"property") {
783 T.expectAndConsume(diag::err_expected_lparen_after,
784 AttrName->getNameStart(), tok::r_paren);
791 IdentifierInfo *AccessorNames[] = {
nullptr,
nullptr};
792 bool HasInvalidAccessor =
false;
797 if (!Tok.is(tok::identifier)) {
799 if (Tok.is(tok::r_paren) && !HasInvalidAccessor &&
800 AccessorNames[AK_Put] ==
nullptr &&
801 AccessorNames[AK_Get] ==
nullptr) {
802 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
806 Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor);
811 SourceLocation KindLoc = Tok.getLocation();
812 StringRef KindStr = Tok.getIdentifierInfo()->getName();
813 if (KindStr ==
"get") {
815 }
else if (KindStr ==
"put") {
819 }
else if (KindStr ==
"set") {
820 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
827 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
829 HasInvalidAccessor =
true;
830 goto next_property_accessor;
834 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
835 HasInvalidAccessor =
true;
848 Diag(Tok.getLocation(), diag::err_ms_property_expected_equal)
854 if (!Tok.is(tok::identifier)) {
855 Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name);
859 if (Kind == AK_Invalid) {
861 }
else if (AccessorNames[Kind] !=
nullptr) {
863 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
865 AccessorNames[
Kind] = Tok.getIdentifierInfo();
869 next_property_accessor:
875 if (Tok.is(tok::r_paren))
878 Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen);
883 if (!HasInvalidAccessor)
885 AccessorNames[AK_Get], AccessorNames[AK_Put],
886 ParsedAttr::Form::Declspec());
888 return !HasInvalidAccessor;
892 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
893 SourceLocation(), ParsedAttr::Form::Declspec());
898 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) <<
AttrName;
905 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
906 assert(Tok.is(tok::kw___declspec) &&
"Not a declspec!");
908 SourceLocation StartLoc = Tok.getLocation();
909 SourceLocation EndLoc = StartLoc;
911 while (Tok.is(tok::kw___declspec)) {
914 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
920 while (Tok.isNot(tok::r_paren)) {
925 if (Tok.is(tok::code_completion)) {
927 Actions.CodeCompletion().CodeCompleteAttribute(
934 bool IsString = Tok.getKind() == tok::string_literal;
935 if (!IsString && Tok.getKind() != tok::identifier &&
936 Tok.getKind() != tok::kw_restrict) {
937 Diag(Tok, diag::err_ms_declspec_type);
943 SourceLocation AttrNameLoc;
945 SmallString<8> StrBuffer;
946 bool Invalid =
false;
947 StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
952 AttrName = PP.getIdentifierInfo(Str);
953 AttrNameLoc = ConsumeStringToken();
959 bool AttrHandled =
false;
962 if (Tok.is(tok::l_paren))
963 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
964 else if (
AttrName->getName() ==
"property")
966 Diag(Tok.getLocation(), diag::err_expected_lparen_after)
970 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
971 ParsedAttr::Form::Declspec());
974 EndLoc =
T.getCloseLocation();
977 Attrs.
Range = SourceRange(StartLoc, EndLoc);
983 auto Kind = Tok.getKind();
985 case tok::kw___fastcall:
986 case tok::kw___stdcall:
987 case tok::kw___thiscall:
988 case tok::kw___regcall:
989 case tok::kw___cdecl:
990 case tok::kw___vectorcall:
991 case tok::kw___ptr64:
993 case tok::kw___ptr32:
995 case tok::kw___uptr: {
996 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
998 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1008void Parser::ParseWebAssemblyFuncrefTypeAttribute(
ParsedAttributes &attrs) {
1009 assert(Tok.is(tok::kw___funcref));
1010 SourceLocation StartLoc = Tok.getLocation();
1013 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
1017 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1019 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr,
1020 0, tok::kw___funcref);
1023void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
1024 SourceLocation StartLoc = Tok.getLocation();
1025 SourceLocation EndLoc = SkipExtendedMicrosoftTypeAttributes();
1028 SourceRange
Range(StartLoc, EndLoc);
1029 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) <<
Range;
1034 SourceLocation EndLoc;
1037 switch (Tok.getKind()) {
1039 case tok::kw_volatile:
1040 case tok::kw___fastcall:
1041 case tok::kw___stdcall:
1042 case tok::kw___thiscall:
1043 case tok::kw___cdecl:
1044 case tok::kw___vectorcall:
1045 case tok::kw___ptr32:
1046 case tok::kw___ptr64:
1048 case tok::kw___unaligned:
1049 case tok::kw___sptr:
1050 case tok::kw___uptr:
1061 while (Tok.is(tok::kw___pascal)) {
1062 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1064 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1071 while (Tok.is(tok::kw___kernel)) {
1072 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1074 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1080 while (Tok.is(tok::kw___noinline__)) {
1081 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1083 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1084 tok::kw___noinline__);
1089 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1090 SourceLocation AttrNameLoc = Tok.getLocation();
1091 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1095bool Parser::isHLSLQualifier(
const Token &
Tok)
const {
1096 return Tok.is(tok::kw_groupshared) || Tok.is(tok::kw_row_major) ||
1097 Tok.is(tok::kw_column_major);
1101 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1102 auto Kind = Tok.getKind();
1104 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0, Kind);
1110 auto Kind = Tok.getKind();
1112 case tok::kw__Nonnull:
1113 case tok::kw__Nullable:
1114 case tok::kw__Nullable_result:
1115 case tok::kw__Null_unspecified: {
1116 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1119 Diag(AttrNameLoc, diag::ext_nullability)
1121 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1132 return (Separator ==
'.' || Separator ==
'_');
1135VersionTuple Parser::ParseVersionTuple(
SourceRange &Range) {
1136 Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());
1138 if (!Tok.is(tok::numeric_constant)) {
1139 Diag(Tok, diag::err_expected_version);
1142 return VersionTuple();
1149 SmallString<512> Buffer;
1150 Buffer.resize(Tok.getLength()+1);
1151 const char *ThisTokBegin = &Buffer[0];
1154 bool Invalid =
false;
1155 unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);
1157 return VersionTuple();
1160 unsigned AfterMajor = 0;
1162 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
1163 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
1167 if (AfterMajor == 0) {
1168 Diag(Tok, diag::err_expected_version);
1171 return VersionTuple();
1174 if (AfterMajor == ActualLength) {
1179 Diag(Tok, diag::err_zero_version);
1180 return VersionTuple();
1183 return VersionTuple(Major);
1186 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1188 || (AfterMajor + 1 == ActualLength)) {
1189 Diag(Tok, diag::err_expected_version);
1192 return VersionTuple();
1196 unsigned AfterMinor = AfterMajor + 1;
1198 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
1199 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
1203 if (AfterMinor == ActualLength) {
1207 if (Major == 0 && Minor == 0) {
1208 Diag(Tok, diag::err_zero_version);
1209 return VersionTuple();
1212 return VersionTuple(Major, Minor);
1215 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1218 Diag(Tok, diag::err_expected_version);
1221 return VersionTuple();
1225 if (AfterMajorSeparator != AfterMinorSeparator)
1226 Diag(Tok, diag::warn_expected_consistent_version_separator);
1229 unsigned AfterSubminor = AfterMinor + 1;
1230 unsigned Subminor = 0;
1231 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
1232 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
1236 if (AfterSubminor != ActualLength) {
1237 Diag(Tok, diag::err_expected_version);
1240 return VersionTuple();
1243 return VersionTuple(Major, Minor, Subminor);
1246void Parser::ParseAvailabilityAttribute(
1250 enum { Introduced, Deprecated, Obsoleted,
Unknown };
1251 AvailabilityChange Changes[
Unknown];
1253 IdentifierLoc *EnvironmentLoc =
nullptr;
1257 if (
T.consumeOpen()) {
1258 Diag(Tok, diag::err_expected) << tok::l_paren;
1263 if (Tok.isNot(tok::identifier)) {
1264 Diag(Tok, diag::err_availability_expected_platform);
1268 IdentifierLoc *Platform = ParseIdentifierLoc();
1271 if (Ident->getName().contains(
"xrOS") || Ident->getName().contains(
"xros"))
1272 Diag(Platform->
getLoc(), diag::warn_availability_unknown_platform)
1275 else if (Ident->getName() ==
"macosx")
1279 else if (Ident->getName() ==
"macosx_app_extension")
1283 AvailabilityAttr::canonicalizePlatformName(Ident->getName())));
1287 if (ExpectAndConsume(tok::comma)) {
1294 if (!Ident_introduced) {
1295 Ident_introduced = PP.getIdentifierInfo(
"introduced");
1296 Ident_deprecated = PP.getIdentifierInfo(
"deprecated");
1297 Ident_obsoleted = PP.getIdentifierInfo(
"obsoleted");
1298 Ident_unavailable = PP.getIdentifierInfo(
"unavailable");
1299 Ident_message = PP.getIdentifierInfo(
"message");
1300 Ident_strict = PP.getIdentifierInfo(
"strict");
1301 Ident_replacement = PP.getIdentifierInfo(
"replacement");
1302 Ident_environment = PP.getIdentifierInfo(
"environment");
1307 SourceLocation UnavailableLoc, StrictLoc;
1309 if (Tok.isNot(tok::identifier)) {
1310 Diag(Tok, diag::err_availability_expected_change);
1314 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1317 if (
Keyword == Ident_strict) {
1319 Diag(KeywordLoc, diag::err_availability_redundant)
1320 <<
Keyword << SourceRange(StrictLoc);
1322 StrictLoc = KeywordLoc;
1326 if (
Keyword == Ident_unavailable) {
1327 if (UnavailableLoc.
isValid()) {
1328 Diag(KeywordLoc, diag::err_availability_redundant)
1329 <<
Keyword << SourceRange(UnavailableLoc);
1331 UnavailableLoc = KeywordLoc;
1338 if (Changes[Deprecated].KeywordLoc.
isValid()) {
1339 Diag(KeywordLoc, diag::err_availability_redundant)
1341 << SourceRange(Changes[Deprecated].KeywordLoc);
1346 Changes[Deprecated].
Version = VersionTuple(1);
1350 if (
Keyword == Ident_environment) {
1351 if (EnvironmentLoc !=
nullptr) {
1352 Diag(KeywordLoc, diag::err_availability_redundant)
1357 if (Tok.isNot(tok::equal)) {
1358 Diag(Tok, diag::err_expected_after) <<
Keyword << tok::equal;
1364 if (!isTokenStringLiteral()) {
1365 Diag(Tok, diag::err_expected_string_literal)
1370 if (
Keyword == Ident_message) {
1378 if (
Keyword == Ident_environment) {
1379 if (Tok.isNot(tok::identifier)) {
1380 Diag(Tok, diag::err_availability_expected_environment);
1384 EnvironmentLoc = ParseIdentifierLoc();
1390 if ((
Keyword == Ident_introduced ||
Keyword == Ident_deprecated) &&
1391 Tok.is(tok::identifier)) {
1392 IdentifierInfo *NA = Tok.getIdentifierInfo();
1395 if (
Keyword == Ident_introduced)
1396 UnavailableLoc = KeywordLoc;
1401 SourceRange VersionRange;
1402 VersionTuple Version = ParseVersionTuple(VersionRange);
1404 if (Version.empty()) {
1410 if (
Keyword == Ident_introduced)
1412 else if (
Keyword == Ident_deprecated)
1414 else if (
Keyword == Ident_obsoleted)
1420 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1421 Diag(KeywordLoc, diag::err_availability_redundant)
1423 << SourceRange(Changes[Index].KeywordLoc,
1424 Changes[Index].VersionRange.
getEnd());
1428 Changes[Index].
Version = Version;
1431 Diag(KeywordLoc, diag::err_availability_unknown_change)
1438 if (
T.consumeClose())
1442 *endLoc =
T.getCloseLocation();
1446 if (UnavailableLoc.
isValid()) {
1447 bool Complained =
false;
1448 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1449 if (Changes[Index].KeywordLoc.
isValid()) {
1451 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1452 << SourceRange(Changes[Index].KeywordLoc,
1453 Changes[Index].VersionRange.
getEnd());
1458 Changes[Index] = AvailabilityChange();
1464 attrs.
addNew(&Availability,
1465 SourceRange(AvailabilityLoc,
T.getCloseLocation()),
1466 AttributeScopeInfo(ScopeName, ScopeLoc), Platform,
1467 Changes[Introduced], Changes[Deprecated], Changes[Obsoleted],
1468 UnavailableLoc, MessageExpr.
get(), Form, StrictLoc,
1469 ReplacementExpr.
get(), EnvironmentLoc);
1472void Parser::ParseExternalSourceSymbolAttribute(
1478 if (
T.expectAndConsume())
1482 if (!Ident_language) {
1483 Ident_language = PP.getIdentifierInfo(
"language");
1484 Ident_defined_in = PP.getIdentifierInfo(
"defined_in");
1485 Ident_generated_declaration = PP.getIdentifierInfo(
"generated_declaration");
1486 Ident_USR = PP.getIdentifierInfo(
"USR");
1490 bool HasLanguage =
false;
1492 bool HasDefinedIn =
false;
1493 IdentifierLoc *GeneratedDeclaration =
nullptr;
1495 bool HasUSR =
false;
1499 if (Tok.isNot(tok::identifier)) {
1500 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1505 SourceLocation KeywordLoc = Tok.getLocation();
1506 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1507 if (
Keyword == Ident_generated_declaration) {
1508 if (GeneratedDeclaration) {
1509 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) <<
Keyword;
1513 GeneratedDeclaration = ParseIdentifierLoc();
1519 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1525 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1531 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1533 if (
Keyword == Ident_language)
1535 else if (
Keyword == Ident_USR)
1538 HasDefinedIn =
true;
1540 if (!isTokenStringLiteral()) {
1541 Diag(Tok, diag::err_expected_string_literal)
1546 : (
Keyword == Ident_defined_in ? 1 : 2));
1550 if (
Keyword == Ident_language) {
1552 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1558 }
else if (
Keyword == Ident_USR) {
1560 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1567 assert(
Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1569 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1579 if (
T.consumeClose())
1582 *EndLoc =
T.getCloseLocation();
1586 Attrs.
addNew(&ExternalSourceSymbol, SourceRange(Loc,
T.getCloseLocation()),
1587 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1591void Parser::ParseObjCBridgeRelatedAttribute(
1597 if (
T.consumeOpen()) {
1598 Diag(Tok, diag::err_expected) << tok::l_paren;
1603 if (Tok.isNot(tok::identifier)) {
1604 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1608 IdentifierLoc *RelatedClass = ParseIdentifierLoc();
1609 if (ExpectAndConsume(tok::comma)) {
1618 if (Tok.is(tok::identifier)) {
1621 Diag(Tok, diag::err_objcbridge_related_selector_name);
1627 if (Tok.is(tok::colon))
1628 Diag(Tok, diag::err_objcbridge_related_selector_name);
1630 Diag(Tok, diag::err_expected) << tok::comma;
1638 if (Tok.is(tok::identifier))
1640 else if (Tok.isNot(tok::r_paren)) {
1641 Diag(Tok, diag::err_expected) << tok::r_paren;
1647 if (
T.consumeClose())
1651 *EndLoc =
T.getCloseLocation();
1654 Attrs.
addNew(&ObjCBridgeRelated,
1655 SourceRange(ObjCBridgeRelatedLoc,
T.getCloseLocation()),
1656 AttributeScopeInfo(ScopeName, ScopeLoc), RelatedClass,
1657 ClassMethod, InstanceMethod, Form);
1660void Parser::ParseSwiftNewTypeAttribute(
1667 if (
T.consumeOpen()) {
1668 Diag(Tok, diag::err_expected) << tok::l_paren;
1672 if (Tok.is(tok::r_paren)) {
1673 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
1677 if (Tok.isNot(tok::kw_struct) && Tok.isNot(tok::kw_enum)) {
1678 Diag(Tok, diag::warn_attribute_type_not_supported)
1679 << &
AttrName << Tok.getIdentifierInfo();
1680 if (!isTokenSpecial())
1686 auto *SwiftType =
new (Actions.Context)
1687 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
1691 if (
T.consumeClose())
1694 *EndLoc =
T.getCloseLocation();
1697 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
T.getCloseLocation()),
1698 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1702void Parser::ParseTypeTagForDatatypeAttribute(
1706 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1711 if (Tok.isNot(tok::identifier)) {
1712 Diag(Tok, diag::err_expected) << tok::identifier;
1716 IdentifierLoc *ArgumentKind = ParseIdentifierLoc();
1718 if (ExpectAndConsume(tok::comma)) {
1723 SourceRange MatchingCTypeRange;
1730 bool LayoutCompatible =
false;
1731 bool MustBeNull =
false;
1733 if (Tok.isNot(tok::identifier)) {
1734 Diag(Tok, diag::err_expected) << tok::identifier;
1738 IdentifierInfo *Flag = Tok.getIdentifierInfo();
1739 if (Flag->
isStr(
"layout_compatible"))
1740 LayoutCompatible =
true;
1741 else if (Flag->
isStr(
"must_be_null"))
1744 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1751 if (!
T.consumeClose()) {
1753 &AttrName, AttrNameLoc, AttributeScopeInfo(ScopeName, ScopeLoc),
1754 ArgumentKind, MatchingCType.
get(), LayoutCompatible, MustBeNull, Form);
1758 *EndLoc =
T.getCloseLocation();
1761bool Parser::DiagnoseProhibitedCXX11Attribute() {
1762 assert(Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square));
1764 switch (isCXX11AttributeSpecifier(
true)) {
1770 Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1775 SourceLocation BeginLoc = ConsumeBracket();
1778 assert(Tok.is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1779 SourceLocation EndLoc = ConsumeBracket();
1780 Diag(BeginLoc, diag::err_attributes_not_allowed)
1781 << SourceRange(BeginLoc, EndLoc);
1784 llvm_unreachable(
"All cases handled above.");
1789 assert((Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square)) ||
1790 Tok.is(tok::kw_alignas) || Tok.isRegularKeywordAttribute());
1794 Tok.isRegularKeywordAttribute() ? Tok.getIdentifierInfo() :
nullptr;
1795 SourceLocation Loc = Tok.getLocation();
1796 ParseCXX11Attributes(Attrs);
1797 CharSourceRange AttrRange(SourceRange(Loc, Attrs.
Range.
getEnd()),
true);
1800 :
Diag(Loc, diag::err_attributes_not_allowed))
1805void Parser::DiagnoseProhibitedAttributes(
1808 if (CorrectLocation.
isValid()) {
1809 CharSourceRange AttrRange(Attrs.
Range,
true);
1810 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1811 ?
Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1812 :
Diag(CorrectLocation, diag::err_attributes_misplaced))
1817 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1818 ?
Diag(
Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr
1819 :
Diag(
Range.getBegin(), diag::err_attributes_not_allowed))
1825 unsigned AttrDiagID,
1826 unsigned KeywordDiagID,
1827 bool DiagnoseEmptyAttrs,
1828 bool WarnOnUnknownAttrs) {
1834 auto &SM = PP.getSourceManager();
1838 if (FirstLSquare.
is(tok::l_square)) {
1839 std::optional<Token> SecondLSquare =
1842 if (SecondLSquare && SecondLSquare->is(tok::l_square)) {
1852 for (
const ParsedAttr &AL : Attrs) {
1853 if (AL.isRegularKeywordAttribute()) {
1854 Diag(AL.getLoc(), KeywordDiagID) << AL;
1858 if (!AL.isStandardAttributeSyntax())
1861 if (WarnOnUnknownAttrs) {
1862 Actions.DiagnoseUnknownAttribute(AL);
1866 Diag(AL.getLoc(), AttrDiagID) << AL;
1873 for (
const ParsedAttr &PA : Attrs) {
1874 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1875 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1876 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
1885 llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;
1888 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1889 AL.isDeclspecAttribute()) ||
1890 AL.isMicrosoftAttribute())
1891 ToBeMoved.push_back(&AL);
1894 for (ParsedAttr *AL : ToBeMoved) {
1908 ObjCDeclContextSwitch ObjCDC(*
this);
1910 Decl *SingleDecl =
nullptr;
1911 switch (Tok.getKind()) {
1912 case tok::kw_template:
1913 case tok::kw_export:
1914 ProhibitAttributes(DeclAttrs);
1915 ProhibitAttributes(DeclSpecAttrs);
1916 return ParseDeclarationStartingWithTemplate(Context, DeclEnd, DeclAttrs);
1917 case tok::kw_inline:
1920 ProhibitAttributes(DeclAttrs);
1921 ProhibitAttributes(DeclSpecAttrs);
1923 return ParseNamespace(Context, DeclEnd, InlineLoc);
1925 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1926 true,
nullptr, DeclSpecStart);
1928 case tok::kw_cbuffer:
1929 case tok::kw_tbuffer:
1930 SingleDecl = ParseHLSLBuffer(DeclEnd, DeclAttrs);
1932 case tok::kw_namespace:
1933 ProhibitAttributes(DeclAttrs);
1934 ProhibitAttributes(DeclSpecAttrs);
1935 return ParseNamespace(Context, DeclEnd);
1936 case tok::kw_using: {
1938 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1939 DeclEnd, DeclAttrs);
1941 case tok::kw_static_assert:
1942 case tok::kw__Static_assert:
1943 ProhibitAttributes(DeclAttrs);
1944 ProhibitAttributes(DeclSpecAttrs);
1945 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1948 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1949 true,
nullptr, DeclSpecStart);
1954 return Actions.ConvertDeclToDeclGroup(SingleDecl);
1960 bool RequireSemi, ForRangeInit *FRI,
SourceLocation *DeclSpecStart) {
1962 ParsedAttributesView OriginalDeclSpecAttrs;
1963 OriginalDeclSpecAttrs.
prepend(DeclSpecAttrs.
begin(), DeclSpecAttrs.
end());
1964 OriginalDeclSpecAttrs.
Range = DeclSpecAttrs.
Range;
1967 ParsingDeclSpec DS(*
this);
1970 ParsedTemplateInfo TemplateInfo;
1971 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
1972 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none, DSContext);
1977 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
1982 if (Tok.is(tok::semi)) {
1983 ProhibitAttributes(DeclAttrs);
1984 DeclEnd = Tok.getLocation();
1986 RecordDecl *AnonRecord =
nullptr;
1987 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
1989 Actions.ActOnDefinedDeclarationSpecifier(TheDecl);
1990 DS.complete(TheDecl);
1992 Decl* decls[] = {AnonRecord, TheDecl};
1993 return Actions.BuildDeclaratorGroup(decls);
1995 return Actions.ConvertDeclToDeclGroup(TheDecl);
1999 Actions.ActOnDefinedDeclarationSpecifier(DS.
getRepAsDecl());
2004 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
2008 switch (Tok.getKind()) {
2009 case tok::annot_cxxscope:
2010 case tok::annot_template_id:
2012 case tok::code_completion:
2013 case tok::coloncolon:
2015 case tok::kw___attribute:
2016 case tok::kw_operator:
2032 case tok::identifier:
2034 case tok::code_completion:
2035 case tok::coloncolon:
2038 case tok::equalequal:
2039 case tok::kw_alignas:
2041 case tok::kw___attribute:
2059 case tok::identifier:
2063 return Tok.isRegularKeywordAttribute();
2067 return Tok.isRegularKeywordAttribute();
2073 switch (Tok.getKind()) {
2079 if (Tok.isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
2103 case tok::kw_inline:
2107 if (Tok.isAtStartOfLine() &&
NextToken().
is(tok::kw_namespace) &&
2108 (!ParsingInObjCContainer || CurParsedObjCImpl))
2112 case tok::kw_extern:
2115 case tok::kw_namespace:
2119 if (Tok.isAtStartOfLine() &&
2120 (!ParsingInObjCContainer || CurParsedObjCImpl))
2126 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2127 ParsingInObjCContainer)
2134 if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
2139 case tok::annot_module_begin:
2140 case tok::annot_module_end:
2141 case tok::annot_module_include:
2142 case tok::annot_repl_input_end:
2156 ParsedTemplateInfo &TemplateInfo,
2158 ForRangeInit *FRI) {
2164 LocalAttrs.takeAllPrependingFrom(Attrs);
2166 if (TemplateInfo.TemplateParams)
2169 bool IsTemplateSpecOrInst =
2176 if (IsTemplateSpecOrInst)
2186 while (MaybeParseHLSLAnnotations(D))
2189 if (
Tok.is(tok::kw_requires)) {
2190 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
2194 ++CurTemplateDepthTracker;
2195 ParseTrailingRequiresClauseWithScope(D);
2201 LateParsedAttrList LateParsedAttrs(
true);
2203 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2208 if (Tok.is(tok::kw__Noreturn)) {
2210 const char *PrevSpec;
2216 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2217 Fixit &= Tok.isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2219 Diag(Loc, diag::err_c11_noreturn_misplaced)
2221 << (Fixit ? FixItHint::CreateInsertion(D.getBeginLoc(),
"_Noreturn ")
2226 if (Tok.is(tok::equal) &&
NextToken().
is(tok::code_completion)) {
2228 Actions.CodeCompletion().CodeCompleteAfterFunctionEquals(D);
2237 while (
auto Specifier = isCXX11VirtSpecifier()) {
2238 Diag(Tok, diag::err_virt_specifier_outside_class)
2246 if (!isDeclarationAfterDeclarator()) {
2252 if (isStartOfFunctionDefinition(D)) {
2262 diag::err_function_declared_typedef)
2266 Decl *TheDecl =
nullptr;
2272 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2273 TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(),
2276 SourceLocation LAngleLoc =
2277 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2279 diag::err_explicit_instantiation_with_definition)
2280 << SourceRange(TemplateInfo.TemplateLoc)
2285 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2286 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
2287 LAngleLoc,
nullptr));
2289 TheDecl = ParseFunctionDefinition(
2291 ParsedTemplateInfo(&FakedParamLists,
2298 ParseFunctionDefinition(D, TemplateInfo, &LateParsedAttrs);
2301 return Actions.ConvertDeclToDeclGroup(TheDecl);
2305 Tok.is(tok::kw_namespace)) {
2315 Diag(Tok, diag::err_expected_fn_body);
2320 if (Tok.is(tok::l_brace)) {
2321 Diag(Tok, diag::err_function_definition_not_allowed);
2329 if (ParseAsmAttributesAfterDeclarator(D))
2338 if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
2351 bool EnterContext = FRI->ExpansionStmt &&
2352 Actions.CurContext == FRI->ExpansionStmt->getParent();
2354 Actions.PushDeclContext(
nullptr, FRI->ExpansionStmt);
2355 llvm::scope_exit RestoreDeclContext{[&] {
2357 Actions.PopDeclContext();
2360 bool IsForRangeLoopOrExpansionStmt =
false;
2362 IsForRangeLoopOrExpansionStmt =
true;
2364 Actions.OpenMP().startOpenMPCXXRangeFor();
2366 ParseForRangeInitializerAfterColon(*FRI, &DS);
2370 if (IsForRangeLoopOrExpansionStmt) {
2371 Actions.ActOnCXXForRangeDecl(ThisDecl, FRI->ExpansionStmt);
2374 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2375 VD->setObjCForDecl(
true);
2377 Actions.FinalizeDeclaration(ThisDecl);
2378 D.complete(ThisDecl);
2379 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, ThisDecl);
2382 SmallVector<Decl *, 8> DeclsInGroup;
2384 ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo, FRI);
2385 if (LateParsedAttrs.size() > 0)
2386 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2387 D.complete(FirstDecl);
2389 DeclsInGroup.push_back(FirstDecl);
2395 SourceLocation CommaLoc;
2397 if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2401 Diag(CommaLoc, diag::err_expected_semi_declaration)
2413 Diag(CommaLoc, diag::err_multiple_template_declarators)
2414 << TemplateInfo.Kind;
2428 MaybeParseGNUAttributes(D);
2432 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2437 MaybeParseHLSLAnnotations(D);
2444 if (Tok.is(tok::kw_requires))
2445 ParseTrailingRequiresClauseWithScope(D);
2446 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D, TemplateInfo);
2447 D.complete(ThisDecl);
2449 DeclsInGroup.push_back(ThisDecl);
2454 *DeclEnd = Tok.getLocation();
2456 if (ExpectSemi && ExpectAndConsumeSemi(
2458 ? diag::err_invalid_token_after_toplevel_declarator
2459 : diag::err_expected_semi_declaration)) {
2467 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
2470bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &D) {
2472 if (Tok.is(tok::kw_asm)) {
2474 ExprResult AsmLabel(ParseSimpleAsm(
true, &Loc));
2475 if (AsmLabel.isInvalid()) {
2484 MaybeParseGNUAttributes(D);
2488Decl *Parser::ParseDeclarationAfterDeclarator(
2489 Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
2490 if (ParseAsmAttributesAfterDeclarator(D))
2493 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
2496Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2497 Declarator &D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2499 struct InitializerScopeRAII {
2505 InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl)
2506 : P(P), D(D), ThisDecl(ThisDecl), Entered(
false) {
2509 if (D.getCXXScopeSpec().isSet()) {
2511 S = P.getCurScope();
2514 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2519 ~InitializerScopeRAII() {
2535 InitKind TheInitKind;
2537 if (isTokenEqualOrEqualTypo())
2538 TheInitKind = InitKind::Equal;
2539 else if (
Tok.
is(tok::l_paren))
2540 TheInitKind = InitKind::CXXDirect;
2543 TheInitKind = InitKind::CXXBraced;
2545 TheInitKind = InitKind::Uninitialized;
2546 if (TheInitKind != InitKind::Uninitialized)
2550 Decl *ThisDecl =
nullptr;
2551 Decl *OuterDecl =
nullptr;
2552 switch (TemplateInfo.Kind) {
2554 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2559 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
2560 *TemplateInfo.TemplateParams,
2562 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2565 ThisDecl = VT->getTemplatedDecl();
2571 if (
Tok.
is(tok::semi)) {
2572 DeclResult ThisRes = Actions.ActOnExplicitInstantiation(
2573 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
2575 SkipUntil(tok::semi, StopBeforeMatch);
2578 ThisDecl = ThisRes.
get();
2586 Diag(
Tok, diag::err_template_defn_explicit_instantiation)
2588 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2591 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2593 diag::err_explicit_instantiation_with_definition)
2598 TemplateParameterLists FakedParamLists;
2599 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2601 LAngleLoc,
nullptr));
2604 Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D);
2613 switch (TheInitKind) {
2615 case InitKind::Equal: {
2618 if (
Tok.
is(tok::kw_delete)) {
2620 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2623 Diag(ConsumeToken(), diag::err_deleted_non_function);
2624 SkipDeletedFunctionBody();
2625 }
else if (
Tok.
is(tok::kw_default)) {
2627 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2630 Diag(ConsumeToken(), diag::err_default_special_members)
2631 << getLangOpts().CPlusPlus20;
2633 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2635 if (
Tok.
is(tok::code_completion)) {
2637 Actions.CodeCompletion().CodeCompleteInitializer(getCurScope(),
2639 Actions.FinalizeDeclaration(ThisDecl);
2649 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2653 FRI->ColonLoc = EqualLoc;
2655 FRI->RangeExpr =
Init;
2658 if (
Init.isInvalid()) {
2660 StopTokens.push_back(tok::comma);
2663 StopTokens.push_back(tok::r_paren);
2664 SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch);
2665 Actions.ActOnInitializerError(ThisDecl);
2667 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
2672 case InitKind::CXXDirect: {
2679 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2681 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2682 auto RunSignatureHelp = [&]() {
2684 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2685 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2688 CalledSignatureHelp =
true;
2689 return PreferredType;
2691 auto SetPreferredType = [&] {
2692 PreferredType.enterFunctionArgument(
Tok.
getLocation(), RunSignatureHelp);
2695 llvm::function_ref<void()> ExpressionStarts;
2701 ExpressionStarts = SetPreferredType;
2704 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2707 if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
2708 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2709 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2712 CalledSignatureHelp =
true;
2714 Actions.ActOnInitializerError(ThisDecl);
2715 SkipUntil(tok::r_paren, StopAtSemi);
2721 T.getCloseLocation(),
2723 Actions.AddInitializerToDecl(ThisDecl,
Initializer.get(),
2728 case InitKind::CXXBraced: {
2730 Diag(
Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2732 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2737 if (
Init.isInvalid()) {
2738 Actions.ActOnInitializerError(ThisDecl);
2740 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
true);
2743 case InitKind::Uninitialized: {
2744 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2745 Actions.ActOnUninitializedDecl(ThisDecl);
2750 Actions.FinalizeDeclaration(ThisDecl);
2751 return OuterDecl ? OuterDecl : ThisDecl;
2754void Parser::ParseSpecifierQualifierList(
2757 ParsedTemplateInfo TemplateInfo;
2761 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC,
nullptr,
2762 AllowImplicitTypename);
2767 Diag(Tok, diag::err_expected_type);
2770 Diag(Tok, diag::err_typename_requires_specqual);
2781 diag::err_typename_invalid_storageclass);
2825 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2826 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2831 ParsedTemplateInfo &TemplateInfo,
2834 assert(Tok.is(tok::identifier) &&
"should have identifier");
2836 SourceLocation Loc = Tok.getLocation();
2856 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
2874 AnnotateScopeToken(*SS,
false);
2883 if (
ParsedType T = Actions.ActOnMSVCUnknownTypeName(
2884 *Tok.getIdentifierInfo(), Tok.getLocation(),
2885 DSC == DeclSpecContext::DSC_template_type_arg)) {
2886 const char *PrevSpec;
2889 Actions.getASTContext().getPrintingPolicy());
2902 if (SS ==
nullptr) {
2903 const char *TagName =
nullptr, *FixitTagName =
nullptr;
2906 switch (Actions.isTagName(*Tok.getIdentifierInfo(),
getCurScope())) {
2909 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
2911 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
2913 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
2915 TagName=
"__interface"; FixitTagName =
"__interface ";
2916 TagKind=tok::kw___interface;
break;
2918 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
2922 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
2923 LookupResult
R(Actions, TokenName, SourceLocation(),
2926 Diag(Loc, diag::err_use_of_tag_name_without_tag)
2927 << TokenName << TagName <<
getLangOpts().CPlusPlus
2933 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2934 << TokenName << TagName;
2938 if (TagKind == tok::kw_enum)
2939 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,
2940 DeclSpecContext::DSC_normal);
2942 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
2944 DeclSpecContext::DSC_normal, Attrs);
2951 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
2952 DSC == DeclSpecContext::DSC_class)) {
2956 case tok::l_paren: {
2963 TentativeParsingAction PA(*
this);
2965 TPResult TPR = TryParseDeclarator(
false);
2968 if (TPR != TPResult::False) {
2976 if (DSC == DeclSpecContext::DSC_class ||
2977 (DSC == DeclSpecContext::DSC_top_level && SS)) {
2978 IdentifierInfo *II = Tok.getIdentifierInfo();
2979 if (Actions.isCurrentClassNameTypo(II, SS)) {
2980 Diag(Loc, diag::err_constructor_bad_name)
2981 << Tok.getIdentifierInfo() << II
2983 Tok.setIdentifierInfo(II);
3001 AnnotateScopeToken(*SS,
false);
3015 IdentifierInfo *II = Tok.getIdentifierInfo();
3017 Actions.DiagnoseUnknownTypeName(II, Loc,
getCurScope(), SS,
T,
3023 const char *PrevSpec;
3026 Actions.getASTContext().getPrintingPolicy());
3031 }
else if (II != Tok.getIdentifierInfo()) {
3044 if (IsTemplateName) {
3045 SourceLocation LAngle, RAngle;
3046 TemplateArgList Args;
3047 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3056Parser::DeclSpecContext
3060 return DeclSpecContext::DSC_class;
3062 return DeclSpecContext::DSC_top_level;
3064 return DeclSpecContext::DSC_template_param;
3066 return DeclSpecContext::DSC_template_arg;
3068 return DeclSpecContext::DSC_template_type_arg;
3071 return DeclSpecContext::DSC_trailing;
3074 return DeclSpecContext::DSC_alias_declaration;
3076 return DeclSpecContext::DSC_association;
3078 return DeclSpecContext::DSC_type_specifier;
3080 return DeclSpecContext::DSC_condition;
3082 return DeclSpecContext::DSC_conv_operator;
3084 return DeclSpecContext::DSC_new;
3099 return DeclSpecContext::DSC_normal;
3102 llvm_unreachable(
"Missing DeclaratorContext case");
3109 if (isTypeIdInParens()) {
3110 SourceLocation TypeLoc = Tok.getLocation();
3112 SourceRange TypeRange(Start, Tok.getLocation());
3113 if (Actions.ActOnAlignasTypeArgument(KWName, Ty, TypeLoc, TypeRange))
3130 assert(Tok.isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3131 "Not an alignment-specifier!");
3138 if (
T.expectAndConsume())
3143 SourceLocation EllipsisLoc;
3145 ParseAlignArgument(PP.getSpelling(KWTok),
T.getOpenLocation(),
3154 *EndLoc =
T.getCloseLocation();
3161 ArgExprs.push_back(ArgExpr.
get());
3162 Attrs.
addNew(KWName, KWLoc, AttributeScopeInfo(), ArgExprs.data(), 1, Kind,
3167void Parser::DistributeCLateParsedAttrs(
Decl *Dcl,
3173 for (
auto *LateAttr : *LateAttrs) {
3174 if (LateAttr->Decls.empty())
3175 LateAttr->addDecl(Dcl);
3181 assert(Tok.is(tok::kw___ptrauth));
3183 IdentifierInfo *KwName = Tok.getIdentifierInfo();
3187 if (
T.expectAndConsume())
3197 ArgExprs.push_back(ER.
get());
3201 SourceLocation EndLoc =
T.getCloseLocation();
3203 if (ArgExprs.empty() || ArgExprs.size() > 3) {
3204 Diag(KwLoc, diag::err_ptrauth_qualifier_bad_arg_count);
3208 Attrs.
addNew(KwName, SourceRange(KwLoc, EndLoc), AttributeScopeInfo(),
3209 ArgExprs.data(), ArgExprs.size(),
3210 ParsedAttr::Form::Keyword(
false,
3220 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3225 if (Tok.is(tok::r_paren)) {
3226 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
3233 using ExpressionKind =
3235 EnterExpressionEvaluationContext EC(
3237 ExpressionKind::EK_AttrArgument);
3245 ArgExprs.push_back(ArgExpr.
get());
3248 ASTContext &Ctx = Actions.getASTContext();
3254 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
3255 AttributeScopeInfo(), ArgExprs.data(), ArgExprs.size(), Form);
3258ExprResult Parser::ParseExtIntegerArgument() {
3259 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3260 "Not an extended int type");
3264 if (
T.expectAndConsume())
3273 if(
T.consumeClose())
3280 DeclSpecContext DSContext,
3284 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3285 DSContext == DeclSpecContext::DSC_top_level);
3288 (Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype) ||
3289 (Tok.is(tok::annot_template_id) &&
NextToken().
is(tok::coloncolon))) &&
3295 bool HasScope = Tok.is(tok::annot_cxxscope);
3297 Token AfterScope = HasScope ?
NextToken() : Tok;
3301 bool MightBeDeclarator =
true;
3302 if (Tok.isOneOf(tok::kw_typename, tok::annot_typename)) {
3304 MightBeDeclarator =
false;
3305 }
else if (AfterScope.
is(tok::annot_template_id)) {
3308 TemplateIdAnnotation *Annot =
3311 MightBeDeclarator =
false;
3312 }
else if (AfterScope.
is(tok::identifier)) {
3317 if (
Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3318 tok::annot_cxxscope, tok::coloncolon)) {
3320 MightBeDeclarator = false;
3321 }
else if (HasScope) {
3326 Actions.RestoreNestedNameSpecifierAnnotation(
3327 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
3329 Sema::NameClassification Classification = Actions.ClassifyName(
3332 switch (Classification.
getKind()) {
3338 llvm_unreachable(
"typo correction is not possible here");
3346 MightBeDeclarator =
false;
3361 if (MightBeDeclarator)
3364 const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
3366 diag::err_expected_after)
3377 ParsedTemplateInfo NotATemplate;
3378 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3382void Parser::ParseDeclarationSpecifiers(
3396 if (DSContext == DeclSpecContext::DSC_conv_operator)
3397 DSContext = DeclSpecContext::DSC_type_specifier;
3399 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3400 DSContext == DeclSpecContext::DSC_top_level);
3401 bool AttrsLastTime =
false;
3402 ParsedAttributes attrs(AttrFactory);
3404 PrintingPolicy Policy = Actions.getPrintingPolicy();
3407 bool isStorageClass =
false;
3408 const char *PrevSpec =
nullptr;
3409 unsigned DiagID = 0;
3413 SourceLocation ConsumedEnd;
3422 if (
getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&
3425 Tok.setKind(tok::identifier);
3427 SourceLocation Loc = Tok.getLocation();
3430 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3434 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
3435 Tok.setKind(tok::identifier);
3444 bool IsTemplateSpecOrInst =
3448 switch (Tok.getKind()) {
3450 if (Tok.isRegularKeywordAttribute())
3455 ProhibitAttributes(attrs);
3458 for (
const ParsedAttr &PA : attrs) {
3459 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3460 !PA.isRegularKeywordAttribute())
3468 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3469 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3476 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3477 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3480 if (PA.getKind() == ParsedAttr::AT_LifetimeBound)
3481 Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type)
3482 << PA << PA.isRegularKeywordAttribute()
3485 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3486 << PA << PA.isRegularKeywordAttribute();
3495 DS.
Finish(Actions, Policy);
3499 case tok::kw__Alignas:
3500 diagnoseUseOfC11Keyword(Tok);
3502 case tok::kw_alignas:
3508 if (Tok.getKind() == tok::kw_alignas)
3509 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
3515 if (!isAllowedCXX11AttributeSpecifier())
3516 goto DoneWithDeclSpec;
3519 ProhibitAttributes(attrs);
3524 attrs.Range = SourceRange();
3526 ParseCXX11Attributes(attrs);
3527 AttrsLastTime =
true;
3530 case tok::code_completion: {
3534 bool AllowNonIdentifiers
3540 bool AllowNestedNameSpecifiers
3541 = DSContext == DeclSpecContext::DSC_top_level ||
3545 Actions.CodeCompletion().CodeCompleteDeclSpec(
3546 getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3552 CCC = DSContext == DeclSpecContext::DSC_class
3555 else if (DSContext == DeclSpecContext::DSC_class)
3559 else if (CurParsedObjCImpl)
3563 Actions.CodeCompletion().CodeCompleteOrdinaryName(
getCurScope(), CCC);
3567 case tok::coloncolon:
3573 goto DoneWithDeclSpec;
3575 if (Tok.is(tok::coloncolon))
3576 goto DoneWithDeclSpec;
3579 case tok::annot_cxxscope: {
3581 goto DoneWithDeclSpec;
3584 if (TemplateInfo.TemplateParams)
3586 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
3587 Tok.getAnnotationRange(),
3593 TemplateIdAnnotation *TemplateId =
Next.is(tok::annot_template_id)
3594 ? takeTemplateIdAnnotation(
Next)
3600 ConsumeAnnotationToken();
3614 if ((DSContext == DeclSpecContext::DSC_top_level ||
3615 DSContext == DeclSpecContext::DSC_class) &&
3618 isConstructorDeclarator(
false,
3625 goto DoneWithDeclSpec;
3629 ConsumeAnnotationToken();
3630 assert(Tok.is(tok::annot_template_id) &&
3631 "ParseOptionalCXXScopeSpecifier not working");
3632 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3642 ConsumeAnnotationToken();
3646 if (
Next.is(tok::annot_typename)) {
3648 ConsumeAnnotationToken();
3651 Tok.getAnnotationEndLoc(),
3652 PrevSpec, DiagID,
T, Policy);
3656 ConsumeAnnotationToken();
3660 Next.is(tok::annot_template_id) &&
3661 static_cast<TemplateIdAnnotation *
>(
Next.getAnnotationValue())
3664 ConsumeAnnotationToken();
3665 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3669 if (
Next.isNot(tok::identifier))
3670 goto DoneWithDeclSpec;
3675 if ((DSContext == DeclSpecContext::DSC_top_level ||
3676 DSContext == DeclSpecContext::DSC_class) &&
3679 isConstructorDeclarator(
false,
3683 goto DoneWithDeclSpec;
3689 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3693 false,
false,
nullptr,
3696 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3698 if (IsTemplateSpecOrInst)
3706 if (TryAnnotateTypeConstraint())
3707 goto DoneWithDeclSpec;
3708 if (Tok.isNot(tok::annot_cxxscope) ||
3712 ConsumeAnnotationToken();
3713 ParsedAttributes Attrs(AttrFactory);
3714 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3715 if (!Attrs.
empty()) {
3716 AttrsLastTime =
true;
3717 attrs.takeAllAppendingFrom(Attrs);
3721 goto DoneWithDeclSpec;
3725 ConsumeAnnotationToken();
3728 DiagID, TypeRep, Policy);
3738 case tok::annot_typename: {
3742 goto DoneWithDeclSpec;
3751 ConsumeAnnotationToken();
3756 case tok::kw___is_signed:
3768 TryKeywordIdentFallback(
true);
3771 goto DoneWithDeclSpec;
3774 case tok::kw___super:
3775 case tok::kw_decltype:
3776 case tok::identifier:
3782 goto DoneWithDeclSpec;
3788 if (!
getLangOpts().DeclSpecKeyword && Tok.is(tok::identifier) &&
3789 Tok.getIdentifierInfo()->getName() ==
"__declspec") {
3790 Diag(Loc, diag::err_ms_attributes_not_enabled);
3800 if (
T.consumeOpen()) {
3801 assert(
false &&
"Not a left paren?");
3816 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3820 if (IsTemplateSpecOrInst)
3824 if (IsTemplateSpecOrInst)
3827 goto DoneWithDeclSpec;
3830 if (!Tok.is(tok::identifier))
3835 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID,
isInvalid))
3841 goto DoneWithDeclSpec;
3843 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3844 isObjCInstancetype()) {
3845 ParsedType TypeRep = Actions.ObjC().ActOnObjCInstanceType(Loc);
3848 DiagID, TypeRep, Policy);
3860 Actions.isCurrentClassName(*Tok.getIdentifierInfo(),
getCurScope()) &&
3861 isConstructorDeclarator(
true,
3864 goto DoneWithDeclSpec;
3867 *Tok.getIdentifierInfo(), Tok.getLocation(),
getCurScope(),
nullptr,
3868 false,
false,
nullptr,
false,
false,
3869 isClassTemplateDeductionContext(DSContext));
3874 if (TryAnnotateTypeConstraint())
3875 goto DoneWithDeclSpec;
3876 if (Tok.isNot(tok::identifier))
3878 ParsedAttributes Attrs(AttrFactory);
3879 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
3880 if (!Attrs.
empty()) {
3881 AttrsLastTime =
true;
3882 attrs.takeAllAppendingFrom(Attrs);
3886 goto DoneWithDeclSpec;
3893 (DSContext == DeclSpecContext::DSC_class ||
3894 DSContext == DeclSpecContext::DSC_top_level) &&
3895 Actions.isDeductionGuideName(
getCurScope(), *Tok.getIdentifierInfo(),
3896 Tok.getLocation(), SS) &&
3897 isConstructorDeclarator(
true,
3899 goto DoneWithDeclSpec;
3902 DiagID, TypeRep, Policy);
3913 SourceLocation NewEndLoc;
3914 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3929 case tok::annot_template_id: {
3930 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
3941 TemplateId =
nullptr;
3949 tok::kw_volatile, tok::kw_restrict, tok::amp,
3951 Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
3955 TemplateId, Policy);
3959 goto DoneWithDeclSpec;
3961 if (TemplateId && !
isInvalid && Actions.CheckTypeConstraint(TemplateId))
3962 TemplateId =
nullptr;
3964 ConsumeAnnotationToken();
3965 SourceLocation AutoLoc = Tok.getLocation();
3968 if (Tracker.consumeOpen()) {
3970 Diag(Tok, diag::err_expected) << tok::l_paren;
3974 Tracker.skipToEnd();
3975 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
3980 Tracker.consumeClose();
3983 ConsumedEnd = Tok.getLocation();
3988 DiagID, TemplateId, Policy);
3991 TemplateId, Policy);
4000 goto DoneWithDeclSpec;
4008 isConstructorDeclarator(
true,
4011 goto DoneWithDeclSpec;
4016 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
4021 case tok::kw___attribute:
4022 case tok::kw___declspec:
4023 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4027 case tok::kw___forceinline: {
4029 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
4030 SourceLocation AttrNameLoc = Tok.getLocation();
4032 nullptr, 0, tok::kw___forceinline);
4036 case tok::kw___unaligned:
4042 case tok::kw___ptrauth:
4046 case tok::kw___sptr:
4047 case tok::kw___uptr:
4048 case tok::kw___ptr64:
4049 case tok::kw___ptr32:
4051 case tok::kw___cdecl:
4052 case tok::kw___stdcall:
4053 case tok::kw___fastcall:
4054 case tok::kw___thiscall:
4055 case tok::kw___regcall:
4056 case tok::kw___vectorcall:
4060 case tok::kw___funcref:
4065 case tok::kw___pascal:
4070 case tok::kw___kernel:
4075 case tok::kw___noinline__:
4080 case tok::kw__Nonnull:
4081 case tok::kw__Nullable:
4082 case tok::kw__Nullable_result:
4083 case tok::kw__Null_unspecified:
4088 case tok::kw___kindof:
4090 AttributeScopeInfo(),
nullptr, 0,
4096 case tok::kw_typedef:
4098 PrevSpec, DiagID, Policy);
4099 isStorageClass =
true;
4101 case tok::kw_extern:
4103 Diag(Tok, diag::ext_thread_before) <<
"extern";
4105 PrevSpec, DiagID, Policy);
4106 isStorageClass =
true;
4108 case tok::kw___private_extern__:
4110 Loc, PrevSpec, DiagID, Policy);
4111 isStorageClass =
true;
4113 case tok::kw_static:
4115 Diag(Tok, diag::ext_thread_before) <<
"static";
4117 PrevSpec, DiagID, Policy);
4118 isStorageClass =
true;
4122 auto MayBeTypeSpecifier = [&]() {
4133 if (isKnownToBeTypeSpecifier(
T))
4143 if (MayBeTypeSpecifier()) {
4145 PrevSpec, DiagID, Policy);
4147 Diag(Tok, diag::ext_auto_storage_class)
4154 PrevSpec, DiagID, Policy);
4155 isStorageClass =
true;
4157 case tok::kw___auto_type:
4158 Diag(Tok, diag::ext_auto_type);
4162 case tok::kw_register:
4164 PrevSpec, DiagID, Policy);
4165 isStorageClass =
true;
4167 case tok::kw_mutable:
4169 PrevSpec, DiagID, Policy);
4170 isStorageClass =
true;
4172 case tok::kw___thread:
4175 isStorageClass =
true;
4177 case tok::kw_thread_local:
4179 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4188 Loc, PrevSpec, DiagID);
4189 isStorageClass =
true;
4191 case tok::kw__Thread_local:
4192 diagnoseUseOfC11Keyword(Tok);
4194 Loc, PrevSpec, DiagID);
4195 isStorageClass =
true;
4199 case tok::kw_inline:
4202 case tok::kw_virtual:
4206 !
getActions().getOpenCLOptions().isAvailableOption(
4208 DiagID = diag::err_openclcxx_virtual_function;
4209 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4212 DiagID = diag::err_hlsl_virtual_function;
4213 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4219 case tok::kw_explicit: {
4220 SourceLocation ExplicitLoc = Loc;
4221 SourceLocation CloseParenLoc;
4223 ConsumedEnd = ExplicitLoc;
4225 if (Tok.is(tok::l_paren)) {
4228 ? diag::warn_cxx17_compat_explicit_bool
4229 : diag::ext_explicit_bool);
4231 ExprResult ExplicitExpr(
static_cast<Expr *
>(
nullptr));
4233 Tracker.consumeOpen();
4235 EnterExpressionEvaluationContext ConstantEvaluated(
4239 ConsumedEnd = Tok.getLocation();
4240 if (ExplicitExpr.isUsable()) {
4241 CloseParenLoc = Tok.getLocation();
4242 Tracker.consumeClose();
4244 Actions.ActOnExplicitBoolSpecifier(ExplicitExpr.get());
4246 Tracker.skipToEnd();
4248 Diag(Tok.getLocation(), diag::warn_cxx20_compat_explicit_bool);
4252 ExplicitSpec, CloseParenLoc);
4255 case tok::kw__Noreturn:
4256 diagnoseUseOfC11Keyword(Tok);
4261 case tok::kw_friend:
4262 if (DSContext == DeclSpecContext::DSC_class) {
4269 DiagID = diag::err_friend_invalid_in_context;
4275 case tok::kw___module_private__:
4280 case tok::kw_constexpr:
4282 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4286 case tok::kw_consteval:
4290 case tok::kw_constinit:
4298 Diag(Tok, diag::err_unknown_typename) << Tok.getName();
4302 goto DoneWithDeclSpec;
4313 PrevSpec, DiagID, Policy);
4315 case tok::kw___int64:
4317 PrevSpec, DiagID, Policy);
4319 case tok::kw_signed:
4323 case tok::kw_unsigned:
4327 case tok::kw__Complex:
4329 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4333 case tok::kw__Imaginary:
4335 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4351 case tok::kw__ExtInt:
4352 case tok::kw__BitInt: {
4353 DiagnoseBitIntUse(Tok);
4358 ConsumedEnd = PrevTokLocation;
4361 case tok::kw___int128:
4369 case tok::kw___bf16:
4377 case tok::kw_double:
4381 case tok::kw__Float16:
4385 case tok::kw__Accum:
4387 "This keyword is only used when fixed point types are enabled "
4388 "with `-ffixed-point`");
4392 case tok::kw__Fract:
4394 "This keyword is only used when fixed point types are enabled "
4395 "with `-ffixed-point`");
4401 "This keyword is only used when fixed point types are enabled "
4402 "with `-ffixed-point`");
4405 case tok::kw___float128:
4409 case tok::kw___ibm128:
4413 case tok::kw_wchar_t:
4417 case tok::kw_char8_t:
4421 case tok::kw_char16_t:
4425 case tok::kw_char32_t:
4431 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4435 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4437 if (Tok.is(tok::kw_bool) &&
4441 DiagID = diag::err_bool_redeclaration;
4443 Tok.setKind(tok::identifier);
4450 case tok::kw__Decimal32:
4454 case tok::kw__Decimal64:
4458 case tok::kw__Decimal128:
4462 case tok::kw___vector:
4465 case tok::kw___pixel:
4468 case tok::kw___bool:
4473 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4476 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
4477 Tok.setKind(tok::identifier);
4478 goto DoneWithDeclSpec;
4480 DiagID = diag::err_opencl_unknown_type_specifier;
4481 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4487#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4488#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4489#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4490 case tok::kw_##ImgType##_t: \
4491 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4492 goto DoneWithDeclSpec; \
4494#include "clang/Basic/OpenCLImageTypes.def"
4495 case tok::kw___unknown_anytype:
4497 PrevSpec, DiagID, Policy);
4502 case tok::kw_struct:
4503 case tok::kw___interface:
4504 case tok::kw_union: {
4511 ParsedAttributes Attributes(AttrFactory);
4512 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
4513 EnteringContext, DSContext, Attributes);
4517 if (!Attributes.empty()) {
4518 AttrsLastTime =
true;
4519 attrs.takeAllAppendingFrom(Attributes);
4527 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
4535 case tok::kw_volatile:
4539 case tok::kw_restrict:
4543 case tok::kw___ob_wrap:
4545 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
4550 OverflowBehaviorType::OverflowBehaviorKind::Wrap, Loc, PrevSpec,
4553 case tok::kw___ob_trap:
4555 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
4560 OverflowBehaviorType::OverflowBehaviorKind::Trap, Loc, PrevSpec,
4565 case tok::kw_typename:
4568 goto DoneWithDeclSpec;
4570 if (!Tok.is(tok::kw_typename))
4575 case tok::kw_typeof:
4576 case tok::kw_typeof_unqual:
4577 ParseTypeofSpecifier(DS);
4580 case tok::annot_decltype:
4581 ParseDecltypeSpecifier(DS);
4584 case tok::annot_pack_indexing_type:
4585 ParsePackIndexingType(DS);
4588 case tok::annot_pragma_pack:
4592 case tok::annot_pragma_ms_pragma:
4593 HandlePragmaMSPragma();
4596 case tok::annot_pragma_ms_vtordisp:
4597 HandlePragmaMSVtorDisp();
4600 case tok::annot_pragma_ms_pointers_to_members:
4601 HandlePragmaMSPointersToMembers();
4604 case tok::annot_pragma_export:
4605 HandlePragmaExport();
4608#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4609#include "clang/Basic/BuiltinTraits.inc"
4613 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4614 goto ParseIdentifier;
4617 case tok::kw__Atomic:
4622 diagnoseUseOfC11Keyword(Tok);
4624 ParseAtomicSpecifier(DS);
4632 case tok::kw___generic:
4637 if (!Actions.getLangOpts().OpenCLGenericAddressSpace) {
4638 DiagID = diag::err_opencl_unknown_type_specifier;
4639 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4644 case tok::kw_private:
4648 goto DoneWithDeclSpec;
4650 case tok::kw___private:
4651 case tok::kw___global:
4652 case tok::kw___local:
4653 case tok::kw___constant:
4655 case tok::kw___read_only:
4656 case tok::kw___write_only:
4657 case tok::kw___read_write:
4660 case tok::kw_row_major:
4661 case tok::kw_column_major:
4662 case tok::kw_groupshared:
4670#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
4671 case tok::kw_##Name: \
4672 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4675#include "clang/Basic/HLSLIntangibleTypes.def"
4682 goto DoneWithDeclSpec;
4684 SourceLocation StartLoc = Tok.getLocation();
4685 SourceLocation EndLoc;
4687 if (
Type.isUsable()) {
4689 PrevSpec, DiagID,
Type.get(),
4690 Actions.getASTContext().getPrintingPolicy()))
4691 Diag(StartLoc, DiagID) << PrevSpec;
4707 assert(PrevSpec &&
"Method did not return previous specifier!");
4710 if (DiagID == diag::ext_duplicate_declspec ||
4711 DiagID == diag::ext_warn_duplicate_declspec ||
4712 DiagID == diag::err_duplicate_declspec)
4713 Diag(Loc, DiagID) << PrevSpec
4716 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4720 Diag(Loc, DiagID) << PrevSpec;
4723 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4727 AttrsLastTime =
false;
4739 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4742 for (
auto *I : RD->decls()) {
4743 auto *VD = dyn_cast<ValueDecl>(I);
4751 for (
const auto &DD : CAT->dependent_decls()) {
4752 if (!RD->containsDecl(DD.getDecl())) {
4753 P.
Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4754 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4755 P.
Diag(DD.getDecl()->getBeginLoc(),
4756 diag::note_flexible_array_counted_by_attr_field)
4763void Parser::ParseStructDeclaration(
4768 if (Tok.is(tok::kw___extension__)) {
4770 ExtensionRAIIObject O(Diags);
4772 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4776 ParsedAttributes Attrs(AttrFactory);
4777 MaybeParseCXX11Attributes(Attrs);
4780 ParseSpecifierQualifierList(DS);
4784 if (Tok.is(tok::semi)) {
4789 ProhibitAttributes(Attrs);
4790 RecordDecl *AnonRecord =
nullptr;
4791 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
4793 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4799 bool FirstDeclarator =
true;
4800 SourceLocation CommaLoc;
4802 ParsingFieldDeclarator DeclaratorInfo(*
this, DS, Attrs);
4803 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4806 if (!FirstDeclarator) {
4809 DiagnoseAndSkipCXX11Attributes();
4810 MaybeParseGNUAttributes(DeclaratorInfo.D);
4811 DiagnoseAndSkipCXX11Attributes();
4816 if (Tok.isNot(tok::colon)) {
4819 ParseDeclarator(DeclaratorInfo.D);
4821 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.getLocation());
4833 DeclaratorInfo.BitfieldSize = Res.
get();
4837 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
4840 Decl *
Field = FieldsCallback(DeclaratorInfo);
4842 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
4849 FirstDeclarator =
false;
4857 AttrEnd.startToken();
4858 AttrEnd.setKind(tok::eof);
4859 AttrEnd.setLocation(Tok.getLocation());
4860 AttrEnd.setEofData(LA.
Toks.data());
4861 LA.
Toks.push_back(AttrEnd);
4865 LA.
Toks.push_back(Tok);
4866 PP.EnterTokenStream(LA.
Toks,
true,
4872 ParsedAttributes Attrs(AttrFactory);
4874 assert(LA.
Decls.size() <= 1 &&
4875 "late field attribute expects to have at most one declaration.");
4879 SourceLocation(), ParsedAttr::Form::GNU(),
nullptr);
4883 while (Tok.isNot(tok::eof))
4887 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
4895 ParsedAttributes Attrs = ParseLexedCAttributeTokens(LA);
4901 Self->ParseLexedTypeAttribute(*
this, OutAttrs);
4906 LateParsedAttrList::iterator It =
4914 From.erase(It, From.end());
4919 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl,
RecordLoc,
4920 "parsing struct/union body");
4924 if (
T.consumeOpen())
4928 Actions.ActOnTagStartDefinition(
getCurScope(), TagDecl);
4932 LateParsedAttrList LateFieldAttrs(
true,
4936 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
4937 Tok.isNot(tok::eof)) {
4941 if (Tok.is(tok::semi)) {
4947 if (Tok.isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4948 SourceLocation DeclEnd;
4949 ParseStaticAssertDeclaration(DeclEnd);
4953 if (Tok.is(tok::annot_pragma_pack)) {
4958 if (Tok.is(tok::annot_pragma_align)) {
4959 HandlePragmaAlign();
4963 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4966 ParsedAttributes Attrs(AttrFactory);
4967 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4971 if (Tok.is(tok::annot_pragma_openacc)) {
4973 ParsedAttributes Attrs(AttrFactory);
4979 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
4981 TagType, Actions.getASTContext().getPrintingPolicy());
4982 ConsumeAnnotationToken();
4986 if (!Tok.is(tok::at)) {
4987 auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
4991 FD.D.getDeclSpec().getSourceRange().getBegin(),
4992 FD.D, FD.BitfieldSize);
4998 ParsingDeclSpec DS(*
this);
4999 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
5002 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
5003 Diag(Tok, diag::err_unexpected_at);
5008 ExpectAndConsume(tok::l_paren);
5009 if (!Tok.is(tok::identifier)) {
5010 Diag(Tok, diag::err_expected) << tok::identifier;
5014 SmallVector<Decl *, 16> Fields;
5015 Actions.ObjC().ActOnDefs(
getCurScope(), TagDecl, Tok.getLocation(),
5016 Tok.getIdentifierInfo(), Fields);
5018 ExpectAndConsume(tok::r_paren);
5024 if (Tok.is(tok::r_brace)) {
5025 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
5029 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
5038 ParsedAttributes attrs(AttrFactory);
5040 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
5042 SmallVector<Decl *, 32> FieldDecls(TagDecl->
fields());
5045 T.getOpenLocation(),
T.getCloseLocation(), attrs);
5048 ParseLexedAttributeList(LateFieldAttrs,
nullptr,
false,
5051 Actions.ActOnTagFinishDefinition(
getCurScope(), TagDecl,
T.getRange());
5055 const ParsedTemplateInfo &TemplateInfo,
5058 if (Tok.is(tok::code_completion)) {
5067 ParsedAttributes attrs(AttrFactory);
5068 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5070 SourceLocation ScopedEnumKWLoc;
5071 bool IsScopedUsingClassTag =
false;
5076 : diag::ext_scoped_enum);
5077 IsScopedUsingClassTag = Tok.is(tok::kw_class);
5082 ProhibitAttributes(attrs);
5085 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5094 bool shouldDelayDiagsInTag =
5097 SuppressAccessChecks diagsFromTag(*
this, shouldDelayDiagsInTag);
5100 AllowDefiningTypeSpec AllowEnumSpecifier =
5102 bool CanBeOpaqueEnumDeclaration =
5103 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5106 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5107 CanBeOpaqueEnumDeclaration);
5111 CXXScopeSpec InvalidDeclScope;
5119 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5124 if (Spec.
isSet() && Tok.isNot(tok::identifier)) {
5125 Diag(Tok, diag::err_expected) << tok::identifier;
5127 if (Tok.isNot(tok::l_brace)) {
5135 SS = std::move(Spec);
5139 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
5140 Tok.isNot(tok::colon)) {
5141 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5150 IdentifierInfo *Name =
nullptr;
5151 SourceLocation NameLoc;
5152 if (Tok.is(tok::identifier)) {
5153 Name = Tok.getIdentifierInfo();
5157 if (!Name && ScopedEnumKWLoc.
isValid()) {
5160 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5161 ScopedEnumKWLoc = SourceLocation();
5162 IsScopedUsingClassTag =
false;
5167 if (shouldDelayDiagsInTag)
5168 diagsFromTag.done();
5171 SourceRange BaseRange;
5173 bool CanBeBitfield =
5177 if (Tok.is(tok::colon)) {
5202 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5206 Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
5207 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5214 DeclSpec DS(AttrFactory);
5218 DeclSpecContext::DSC_type_specifier);
5221 BaseType = Actions.ActOnTypeName(DeclaratorInfo);
5223 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5227 DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)
5230 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5234 ? diag::warn_c17_compat_enum_fixed_underlying_type
5235 : diag::ext_c23_enum_fixed_underlying_type)
5252 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5254 else if (Tok.is(tok::l_brace)) {
5256 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
5262 ScopedEnumKWLoc = SourceLocation();
5263 IsScopedUsingClassTag =
false;
5269 }
else if (!isTypeSpecifier(DSC) &&
5270 (Tok.is(tok::semi) ||
5271 (Tok.isAtStartOfLine() &&
5272 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5277 if (Tok.isNot(tok::semi)) {
5279 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5280 PP.EnterToken(Tok,
true);
5281 Tok.setKind(tok::semi);
5287 bool IsElaboratedTypeSpecifier =
5293 diagsFromTag.redelay();
5301 Diag(Tok, diag::err_enum_template);
5309 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5313 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5315 TemplateInfo.TemplateParams->size());
5320 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5336 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5338 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5339 diag::err_keyword_not_allowed,
5342 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5343 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5344 else if (ScopedEnumKWLoc.
isValid())
5345 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5349 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5351 SkipBodyInfo SkipBody;
5354 SkipBody = Actions.shouldSkipAnonEnumBody(
getCurScope(),
5359 bool IsDependent =
false;
5360 const char *PrevSpec =
nullptr;
5365 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5366 IsScopedUsingClassTag,
5367 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5368 DSC == DeclSpecContext::DSC_template_param ||
5369 DSC == DeclSpecContext::DSC_template_type_arg,
5370 OffsetOfState, &SkipBody).get();
5380 NameLoc.
isValid() ? NameLoc : StartLoc,
5381 PrevSpec, DiagID, TagDecl, Owned,
5382 Actions.getASTContext().getPrintingPolicy()))
5383 Diag(StartLoc, DiagID) << PrevSpec;
5392 Diag(Tok, diag::err_expected_type_name_after_typename);
5398 if (
Type.isInvalid()) {
5404 NameLoc.
isValid() ? NameLoc : StartLoc,
5405 PrevSpec, DiagID,
Type.get(),
5406 Actions.getASTContext().getPrintingPolicy()))
5407 Diag(StartLoc, DiagID) << PrevSpec;
5426 ParseEnumBody(StartLoc, D, &SkipBody);
5428 !Actions.ActOnDuplicateDefinition(
getCurScope(), TagDecl, SkipBody)) {
5435 NameLoc.
isValid() ? NameLoc : StartLoc,
5436 PrevSpec, DiagID, TagDecl, Owned,
5437 Actions.getASTContext().getPrintingPolicy()))
5438 Diag(StartLoc, DiagID) << PrevSpec;
5445 Actions.ActOnTagStartDefinition(
getCurScope(), EnumDecl);
5453 Diag(
T.getOpenLocation(), diag::ext_ms_c_empty_enum_type)
5454 << SourceRange(
T.getOpenLocation(), Tok.getLocation());
5456 Diag(Tok, diag::err_empty_enum);
5459 SmallVector<Decl *, 32> EnumConstantDecls;
5460 SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
5462 Decl *LastEnumConstDecl =
nullptr;
5465 while (Tok.isNot(tok::r_brace)) {
5468 if (Tok.isNot(tok::identifier)) {
5469 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
5475 IdentifierInfo *Ident = Tok.getIdentifierInfo();
5479 ParsedAttributes attrs(AttrFactory);
5480 MaybeParseGNUAttributes(attrs);
5481 if (isAllowedCXX11AttributeSpecifier()) {
5484 ? diag::warn_cxx14_compat_ns_enum_attribute
5485 : diag::ext_ns_enum_attribute)
5487 ParseCXX11Attributes(attrs);
5490 SourceLocation EqualLoc;
5492 EnumAvailabilityDiags.emplace_back(*
this);
5494 EnterExpressionEvaluationContext ConstantEvaluated(
5503 Decl *EnumConstDecl = Actions.ActOnEnumConstant(
5504 getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
5505 EqualLoc, AssignedVal.
get(), SkipBody);
5506 EnumAvailabilityDiags.back().done();
5508 EnumConstantDecls.push_back(EnumConstDecl);
5509 LastEnumConstDecl = EnumConstDecl;
5511 if (Tok.is(tok::identifier)) {
5514 Diag(Loc, diag::err_enumerator_list_missing_comma)
5521 SourceLocation CommaLoc;
5522 if (Tok.isNot(tok::r_brace) && !
TryConsumeToken(tok::comma, CommaLoc)) {
5524 Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
5527 Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
5537 if (Tok.is(tok::r_brace) && CommaLoc.
isValid()) {
5540 diag::ext_enumerator_list_comma_cxx :
5541 diag::ext_enumerator_list_comma_c)
5544 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5554 ParsedAttributes attrs(AttrFactory);
5555 MaybeParseGNUAttributes(attrs);
5557 Actions.ActOnEnumBody(StartLoc,
T.getRange(), EnumDecl, EnumConstantDecls,
5561 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5562 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5564 EnumAvailabilityDiags[i].redelay();
5565 PD.complete(EnumConstantDecls[i]);
5569 Actions.ActOnTagFinishDefinition(
getCurScope(), EnumDecl,
T.getRange());
5574 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5575 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5579 PP.EnterToken(Tok,
true);
5580 Tok.setKind(tok::semi);
5584bool Parser::isKnownToBeTypeSpecifier(
const Token &
Tok)
const {
5585 switch (Tok.getKind()) {
5586 default:
return false;
5590 case tok::kw___int64:
5591 case tok::kw___int128:
5592 case tok::kw_signed:
5593 case tok::kw_unsigned:
5594 case tok::kw__Complex:
5595 case tok::kw__Imaginary:
5598 case tok::kw_wchar_t:
5599 case tok::kw_char8_t:
5600 case tok::kw_char16_t:
5601 case tok::kw_char32_t:
5603 case tok::kw__ExtInt:
5604 case tok::kw__BitInt:
5605 case tok::kw___bf16:
5608 case tok::kw_double:
5609 case tok::kw__Accum:
5610 case tok::kw__Fract:
5611 case tok::kw__Float16:
5612 case tok::kw___float128:
5613 case tok::kw___ibm128:
5616 case tok::kw__Decimal32:
5617 case tok::kw__Decimal64:
5618 case tok::kw__Decimal128:
5619 case tok::kw___vector:
5620#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5621#include "clang/Basic/OpenCLImageTypes.def"
5622#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5623#include "clang/Basic/HLSLIntangibleTypes.def"
5627 case tok::kw_struct:
5628 case tok::kw___interface:
5633 case tok::kw_typeof:
5634 case tok::kw_typeof_unqual:
5637 case tok::kw__Atomic:
5640 case tok::annot_typename:
5645bool Parser::isTypeSpecifierQualifier(
const Token &
Tok) {
5646 switch (Tok.getKind()) {
5647 default:
return false;
5649 case tok::identifier:
5650 if (TryAltiVecVectorToken())
5653 case tok::kw_typename:
5662 case tok::coloncolon:
5672 case tok::kw___attribute:
5674 case tok::kw_typeof:
5675 case tok::kw_typeof_unqual:
5680 case tok::kw___int64:
5681 case tok::kw___int128:
5682 case tok::kw_signed:
5683 case tok::kw_unsigned:
5684 case tok::kw__Complex:
5685 case tok::kw__Imaginary:
5688 case tok::kw_wchar_t:
5689 case tok::kw_char8_t:
5690 case tok::kw_char16_t:
5691 case tok::kw_char32_t:
5693 case tok::kw__ExtInt:
5694 case tok::kw__BitInt:
5696 case tok::kw___bf16:
5698 case tok::kw_double:
5699 case tok::kw__Accum:
5700 case tok::kw__Fract:
5701 case tok::kw__Float16:
5702 case tok::kw___float128:
5703 case tok::kw___ibm128:
5706 case tok::kw__Decimal32:
5707 case tok::kw__Decimal64:
5708 case tok::kw__Decimal128:
5709 case tok::kw___vector:
5710#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5711#include "clang/Basic/OpenCLImageTypes.def"
5712#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5713#include "clang/Basic/HLSLIntangibleTypes.def"
5717 case tok::kw_struct:
5718 case tok::kw___interface:
5725 case tok::kw_volatile:
5726 case tok::kw_restrict:
5727 case tok::kw___ob_wrap:
5728 case tok::kw___ob_trap:
5732 case tok::kw___unknown_anytype:
5735 case tok::annot_typename:
5742 case tok::kw___cdecl:
5743 case tok::kw___stdcall:
5744 case tok::kw___fastcall:
5745 case tok::kw___thiscall:
5746 case tok::kw___regcall:
5747 case tok::kw___vectorcall:
5749 case tok::kw___ptr64:
5750 case tok::kw___ptr32:
5751 case tok::kw___pascal:
5752 case tok::kw___unaligned:
5753 case tok::kw___ptrauth:
5755 case tok::kw__Nonnull:
5756 case tok::kw__Nullable:
5757 case tok::kw__Nullable_result:
5758 case tok::kw__Null_unspecified:
5760 case tok::kw___kindof:
5762 case tok::kw___private:
5763 case tok::kw___local:
5764 case tok::kw___global:
5765 case tok::kw___constant:
5766 case tok::kw___generic:
5767 case tok::kw___read_only:
5768 case tok::kw___read_write:
5769 case tok::kw___write_only:
5770 case tok::kw___funcref:
5773 case tok::kw_private:
5777 case tok::kw__Atomic:
5781 case tok::kw_groupshared:
5785 case tok::kw_row_major:
5786 case tok::kw_column_major:
5792 assert(PP.isIncrementalProcessingEnabled() &&
"Not in incremental mode");
5796 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5799 TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5800 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5801 Actions.ActOnFinishTopLevelStmtDecl(TLSD,
R.get());
5803 R = Actions.ActOnNullStmt(Tok.getLocation());
5805 if (Tok.is(tok::annot_repl_input_end) &&
5806 Tok.getAnnotationValue() !=
nullptr) {
5807 ConsumeAnnotationToken();
5811 SmallVector<Decl *, 2> DeclsInGroup;
5812 DeclsInGroup.push_back(TLSD);
5815 for (Stmt *S : Stmts) {
5818 TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5819 Actions.ActOnFinishTopLevelStmtDecl(D, S);
5820 DeclsInGroup.push_back(D);
5823 return Actions.BuildDeclaratorGroup(DeclsInGroup);
5826bool Parser::isDeclarationSpecifier(
5828 bool DisambiguatingWithExpression) {
5829 switch (Tok.getKind()) {
5830 default:
return false;
5837 case tok::identifier:
5841 if (TryAltiVecVectorToken())
5844 case tok::kw_decltype:
5845 case tok::kw_typename:
5850 if (TryAnnotateTypeConstraint())
5852 if (Tok.is(tok::identifier))
5860 if (DisambiguatingWithExpression &&
5861 isStartOfObjCClassMessageMissingOpenBracket())
5864 return isDeclarationSpecifier(AllowImplicitTypename);
5866 case tok::coloncolon:
5880 case tok::kw_typedef:
5881 case tok::kw_extern:
5882 case tok::kw___private_extern__:
5883 case tok::kw_static:
5885 case tok::kw___auto_type:
5886 case tok::kw_register:
5887 case tok::kw___thread:
5888 case tok::kw_thread_local:
5889 case tok::kw__Thread_local:
5892 case tok::kw___module_private__:
5895 case tok::kw___unknown_anytype:
5900 case tok::kw___int64:
5901 case tok::kw___int128:
5902 case tok::kw_signed:
5903 case tok::kw_unsigned:
5904 case tok::kw__Complex:
5905 case tok::kw__Imaginary:
5908 case tok::kw_wchar_t:
5909 case tok::kw_char8_t:
5910 case tok::kw_char16_t:
5911 case tok::kw_char32_t:
5914 case tok::kw__ExtInt:
5915 case tok::kw__BitInt:
5917 case tok::kw___bf16:
5919 case tok::kw_double:
5920 case tok::kw__Accum:
5921 case tok::kw__Fract:
5922 case tok::kw__Float16:
5923 case tok::kw___float128:
5924 case tok::kw___ibm128:
5927 case tok::kw__Decimal32:
5928 case tok::kw__Decimal64:
5929 case tok::kw__Decimal128:
5930 case tok::kw___vector:
5934 case tok::kw_struct:
5936 case tok::kw___interface:
5942 case tok::kw_volatile:
5943 case tok::kw_restrict:
5944 case tok::kw___ob_wrap:
5945 case tok::kw___ob_trap:
5949 case tok::kw_inline:
5950 case tok::kw_virtual:
5951 case tok::kw_explicit:
5952 case tok::kw__Noreturn:
5955 case tok::kw__Alignas:
5958 case tok::kw_friend:
5961 case tok::kw_static_assert:
5962 case tok::kw__Static_assert:
5965 case tok::kw_typeof:
5966 case tok::kw_typeof_unqual:
5969 case tok::kw___attribute:
5972 case tok::annot_decltype:
5973 case tok::annot_pack_indexing_type:
5974 case tok::kw_constexpr:
5977 case tok::kw_consteval:
5978 case tok::kw_constinit:
5981 case tok::kw__Atomic:
5984 case tok::kw_alignas:
5994 case tok::annot_typename:
5995 return !DisambiguatingWithExpression ||
5996 !isStartOfObjCClassMessageMissingOpenBracket();
5999 case tok::annot_template_id: {
6000 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
6005 return isTypeConstraintAnnotation() &&
6009 case tok::annot_cxxscope: {
6010 TemplateIdAnnotation *TemplateId =
6018 if (
NextToken().
is(tok::identifier) && TryAnnotateTypeConstraint())
6020 return isTypeConstraintAnnotation() &&
6024 case tok::kw___declspec:
6025 case tok::kw___cdecl:
6026 case tok::kw___stdcall:
6027 case tok::kw___fastcall:
6028 case tok::kw___thiscall:
6029 case tok::kw___regcall:
6030 case tok::kw___vectorcall:
6032 case tok::kw___sptr:
6033 case tok::kw___uptr:
6034 case tok::kw___ptr64:
6035 case tok::kw___ptr32:
6036 case tok::kw___forceinline:
6037 case tok::kw___pascal:
6038 case tok::kw___unaligned:
6039 case tok::kw___ptrauth:
6041 case tok::kw__Nonnull:
6042 case tok::kw__Nullable:
6043 case tok::kw__Nullable_result:
6044 case tok::kw__Null_unspecified:
6046 case tok::kw___kindof:
6048 case tok::kw___private:
6049 case tok::kw___local:
6050 case tok::kw___global:
6051 case tok::kw___constant:
6052 case tok::kw___generic:
6053 case tok::kw___read_only:
6054 case tok::kw___read_write:
6055 case tok::kw___write_only:
6056#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
6057#include "clang/Basic/OpenCLImageTypes.def"
6058#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
6059#include "clang/Basic/HLSLIntangibleTypes.def"
6061 case tok::kw___funcref:
6062 case tok::kw_groupshared:
6065 case tok::kw_row_major:
6066 case tok::kw_column_major:
6069 case tok::kw_private:
6074bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
6076 const ParsedTemplateInfo *TemplateInfo) {
6077 RevertingTentativeParsingAction TPA(*
this);
6080 if (TemplateInfo && TemplateInfo->TemplateParams)
6083 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6090 if (Tok.is(tok::identifier)) {
6094 }
else if (Tok.is(tok::annot_template_id)) {
6095 ConsumeAnnotationToken();
6102 SkipCXX11Attributes();
6105 if (Tok.isNot(tok::l_paren)) {
6112 if (Tok.is(tok::r_paren) ||
6113 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren))) {
6119 if (isCXX11AttributeSpecifier(
false,
6126 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6128 DeclScopeObj.EnterDeclaratorScope();
6131 ParsedAttributes Attrs(AttrFactory);
6132 MaybeParseMicrosoftAttributes(Attrs);
6141 bool IsConstructor =
false;
6147 if (Tok.is(tok::kw_this)) {
6149 return isDeclarationSpecifier(ITC);
6152 if (isDeclarationSpecifier(ITC))
6153 IsConstructor =
true;
6154 else if (Tok.is(tok::identifier) ||
6155 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier))) {
6160 if (Tok.is(tok::annot_cxxscope))
6161 ConsumeAnnotationToken();
6167 switch (Tok.getKind()) {
6173 case tok::coloncolon:
6186 SkipCXX11Attributes();
6188 if (DeductionGuide) {
6190 IsConstructor = Tok.is(tok::arrow);
6193 if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
6197 IsConstructor =
true;
6199 if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {
6212 IsConstructor = IsUnqualified;
6217 IsConstructor =
true;
6221 return IsConstructor;
6224void Parser::ParseTypeQualifierListOpt(
6225 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicOrPtrauthAllowed,
6227 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6228 isAllowedCXX11AttributeSpecifier()) {
6229 ParsedAttributes Attrs(AttrFactory);
6230 ParseCXX11Attributes(Attrs);
6234 SourceLocation EndLoc;
6238 const char *PrevSpec =
nullptr;
6239 unsigned DiagID = 0;
6240 SourceLocation Loc = Tok.getLocation();
6242 switch (Tok.getKind()) {
6243 case tok::code_completion:
6245 if (CodeCompletionHandler)
6246 CodeCompletionHandler();
6248 Actions.CodeCompletion().CodeCompleteTypeQualifiers(DS);
6255 case tok::kw_volatile:
6259 case tok::kw_restrict:
6263 case tok::kw___ob_wrap:
6265 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6270 OverflowBehaviorType::OverflowBehaviorKind::Wrap, Loc, PrevSpec,
6273 case tok::kw___ob_trap:
6275 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6280 OverflowBehaviorType::OverflowBehaviorKind::Trap, Loc, PrevSpec,
6283 case tok::kw__Atomic:
6284 if (!AtomicOrPtrauthAllowed)
6285 goto DoneWithTypeQuals;
6286 diagnoseUseOfC11Keyword(Tok);
6292 case tok::kw_private:
6294 goto DoneWithTypeQuals;
6296 case tok::kw___private:
6297 case tok::kw___global:
6298 case tok::kw___local:
6299 case tok::kw___constant:
6300 case tok::kw___generic:
6301 case tok::kw___read_only:
6302 case tok::kw___write_only:
6303 case tok::kw___read_write:
6307 case tok::kw_groupshared:
6316 case tok::kw___ptrauth:
6317 if (!AtomicOrPtrauthAllowed)
6318 goto DoneWithTypeQuals;
6320 EndLoc = PrevTokLocation;
6323 case tok::kw___unaligned:
6327 case tok::kw___uptr:
6332 if (TryKeywordIdentFallback(
false))
6336 case tok::kw___sptr:
6338 case tok::kw___ptr64:
6339 case tok::kw___ptr32:
6340 case tok::kw___cdecl:
6341 case tok::kw___stdcall:
6342 case tok::kw___fastcall:
6343 case tok::kw___thiscall:
6344 case tok::kw___regcall:
6345 case tok::kw___vectorcall:
6346 if (AttrReqs & AR_DeclspecAttributesParsed) {
6350 goto DoneWithTypeQuals;
6352 case tok::kw___funcref:
6356 case tok::kw___pascal:
6357 if (AttrReqs & AR_VendorAttributesParsed) {
6361 goto DoneWithTypeQuals;
6364 case tok::kw__Nonnull:
6365 case tok::kw__Nullable:
6366 case tok::kw__Nullable_result:
6367 case tok::kw__Null_unspecified:
6372 case tok::kw___kindof:
6374 AttributeScopeInfo(),
nullptr, 0,
6379 case tok::kw___attribute:
6380 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6382 Diag(Tok, diag::err_attributes_not_allowed);
6386 if (AttrReqs & AR_GNUAttributesParsed ||
6387 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6397 DS.
Finish(Actions, Actions.getASTContext().getPrintingPolicy());
6405 assert(PrevSpec &&
"Method did not return previous specifier!");
6406 Diag(Tok, DiagID) << PrevSpec;
6415 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6416 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6422 if (Kind == tok::star || Kind == tok::caret)
6426 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6427 Lang.getOpenCLCompatibleVersion() >= 200)
6430 if (!Lang.CPlusPlus)
6433 if (Kind == tok::amp)
6441 if (Kind == tok::ampamp)
6452 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6459void Parser::ParseDeclaratorInternal(
Declarator &D,
6460 DirectDeclParseFunction DirectDeclParser) {
6461 if (Diags.hasAllExtensionsSilenced())
6471 (Tok.is(tok::coloncolon) ||
6472 (Tok.is(tok::kw_decltype) &&
NextToken().
is(tok::l_paren)) ||
6473 (Tok.is(tok::identifier) &&
6475 Tok.is(tok::annot_cxxscope))) {
6476 TentativeParsingAction TPA(*
this,
true);
6482 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6494 Tok.is(tok::star)) {
6498 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6499 CompoundToken::MemberPtr);
6504 DeclSpec DS(AttrFactory);
6505 ParseTypeQualifierListOpt(DS);
6509 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6510 ParseDeclaratorInternal(D, DirectDeclParser);
6524 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6534 AnnotateScopeToken(SS,
true);
6536 if (DirectDeclParser)
6537 (this->*DirectDeclParser)(D);
6545 DeclSpec DS(AttrFactory);
6546 ParseTypeQualifierListOpt(DS);
6555 if (DirectDeclParser)
6556 (this->*DirectDeclParser)(D);
6565 if (Kind == tok::star || Kind == tok::caret) {
6567 DeclSpec DS(AttrFactory);
6571 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6573 ? AR_GNUAttributesParsed
6574 : AR_GNUAttributesParsedAndRejected);
6575 ParseTypeQualifierListOpt(DS, Reqs,
true,
6580 Actions.runWithSufficientStackSpace(
6581 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6582 if (Kind == tok::star)
6597 DeclSpec DS(AttrFactory);
6601 if (Kind == tok::ampamp)
6603 diag::warn_cxx98_compat_rvalue_reference :
6604 diag::ext_rvalue_reference);
6607 ParseTypeQualifierListOpt(DS);
6616 diag::err_invalid_reference_qualifier_application) <<
"const";
6619 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6623 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6627 Actions.runWithSufficientStackSpace(
6628 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6635 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6638 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6667void Parser::ParseDirectDeclarator(
Declarator &D) {
6674 return ParseDecompositionDeclarator(D);
6688 ParseOptionalCXXScopeSpecifier(
6690 false, EnteringContext);
6705 if (Actions.ShouldEnterDeclaratorScope(
getCurScope(),
6709 DeclScopeObj.EnterDeclaratorScope();
6716 goto PastIdentifier;
6732 !Actions.containsUnexpandedParameterPacks(D) &&
6740 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6750 if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6754 bool AllowConstructorName;
6755 bool AllowDeductionGuide;
6757 AllowConstructorName =
false;
6758 AllowDeductionGuide =
false;
6762 AllowDeductionGuide =
false;
6770 SourceLocation TemplateKWLoc;
6775 true, AllowConstructorName,
6776 AllowDeductionGuide, &TemplateKWLoc,
6789 DeclScopeObj.EnterDeclaratorScope();
6796 goto PastIdentifier;
6802 diag::err_expected_unqualified_id)
6805 goto PastIdentifier;
6809 "There's a C++-specific check for tok::identifier above");
6810 assert(Tok.getIdentifierInfo() &&
"Not an identifier?");
6811 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6814 goto PastIdentifier;
6819 bool DiagnoseIdentifier =
false;
6823 DiagnoseIdentifier =
true;
6826 DiagnoseIdentifier =
6834 !isCXX11VirtSpecifier(Tok))
6836 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6837 if (DiagnoseIdentifier) {
6838 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
6842 goto PastIdentifier;
6846 if (Tok.is(tok::l_paren)) {
6851 RevertingTentativeParsingAction PA(*
this);
6856 goto PastIdentifier;
6863 ParseParenDeclarator(D);
6876 DeclScopeObj.EnterDeclaratorScope();
6887 diag::ext_abstract_pack_declarator_parens);
6889 if (Tok.getKind() == tok::annot_pragma_parser_crash)
6891 if (Tok.is(tok::l_square))
6892 return ParseMisplacedBracketDeclarator(D);
6897 !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
6898 Tok.getIdentifierInfo()->isCPlusPlusKeyword(
getLangOpts())) {
6900 diag::err_expected_member_name_or_semi_objcxx_keyword)
6901 << Tok.getIdentifierInfo()
6904 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6907 goto PastIdentifier;
6910 diag::err_expected_member_name_or_semi)
6914 if (Tok.getKind() == tok::TokenKind::kw_while) {
6915 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6917 if (Tok.isOneOf(tok::period, tok::arrow))
6918 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
6921 if (Tok.isAtStartOfLine() && Loc.
isValid())
6922 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
6926 diag::err_expected_unqualified_id)
6931 diag::err_expected_either)
6932 << tok::identifier << tok::l_paren;
6941 "Haven't past the location of the identifier yet?");
6945 MaybeParseCXX11Attributes(D);
6948 if (Tok.is(tok::l_paren)) {
6960 bool IsAmbiguous =
false;
6972 AllowImplicitTypename =
6980 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
6981 bool IsFunctionDecl =
6982 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
6983 TentativelyDeclaredIdentifiers.pop_back();
6984 if (!IsFunctionDecl)
6987 ParsedAttributes attrs(AttrFactory);
6990 if (IsFunctionDeclaration)
6991 Actions.ActOnStartFunctionDeclarationDeclarator(D,
6992 TemplateParameterDepth);
6993 ParseFunctionDeclarator(D, attrs,
T, IsAmbiguous);
6994 if (IsFunctionDeclaration)
6995 Actions.ActOnFinishFunctionDeclarationDeclarator(D);
6996 PrototypeScope.Exit();
6997 }
else if (Tok.is(tok::l_square)) {
6998 ParseBracketDeclarator(D);
6999 }
else if (Tok.isRegularKeywordAttribute()) {
7001 Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();
7006 if (!
T.consumeOpen())
7017 Diag(Tok, diag::err_requires_clause_inside_parens);
7031void Parser::ParseDecompositionDeclarator(
Declarator &D) {
7032 assert(Tok.is(tok::l_square));
7034 TentativeParsingAction PA(*
this);
7039 DiagnoseAndSkipCXX11Attributes();
7043 if (!(Tok.isOneOf(tok::identifier, tok::ellipsis) &&
7045 tok::identifier, tok::l_square, tok::ellipsis)) &&
7046 !(Tok.is(tok::r_square) &&
7049 return ParseMisplacedBracketDeclarator(D);
7052 SourceLocation PrevEllipsisLoc;
7053 SmallVector<DecompositionDeclarator::Binding, 32>
Bindings;
7054 while (Tok.isNot(tok::r_square)) {
7056 if (Tok.is(tok::comma))
7059 if (Tok.is(tok::identifier)) {
7061 Diag(EndLoc, diag::err_expected)
7064 Diag(Tok, diag::err_expected_comma_or_rsquare);
7067 SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis},
7069 if (Tok.is(tok::comma))
7071 else if (Tok.is(tok::r_square))
7076 if (isCXX11AttributeSpecifier() !=
7078 DiagnoseAndSkipCXX11Attributes();
7080 SourceLocation EllipsisLoc;
7082 if (Tok.is(tok::ellipsis)) {
7084 : diag::ext_cxx_binding_pack);
7085 if (PrevEllipsisLoc.
isValid()) {
7086 Diag(Tok, diag::err_binding_multiple_ellipses);
7087 Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
7090 EllipsisLoc = Tok.getLocation();
7091 PrevEllipsisLoc = EllipsisLoc;
7095 if (Tok.isNot(tok::identifier)) {
7096 Diag(Tok, diag::err_expected) << tok::identifier;
7100 IdentifierInfo *II = Tok.getIdentifierInfo();
7101 SourceLocation Loc = Tok.getLocation();
7104 if (Tok.is(tok::ellipsis) && !PrevEllipsisLoc.
isValid()) {
7105 DiagnoseMisplacedEllipsis(Tok.getLocation(), Loc, EllipsisLoc.
isValid(),
7107 EllipsisLoc = Tok.getLocation();
7111 ParsedAttributes Attrs(AttrFactory);
7112 if (isCXX11AttributeSpecifier() !=
7115 ? diag::warn_cxx23_compat_decl_attrs_on_binding
7116 : diag::ext_decl_attrs_on_binding);
7117 MaybeParseCXX11Attributes(Attrs);
7120 Bindings.push_back({II, Loc, std::move(Attrs), EllipsisLoc});
7123 if (Tok.isNot(tok::r_square))
7130 Diag(Tok.getLocation(), diag::ext_decomp_decl_empty);
7138 T.getCloseLocation());
7141void Parser::ParseParenDeclarator(
Declarator &D) {
7145 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7157 ParsedAttributes attrs(AttrFactory);
7158 bool RequiresArg =
false;
7159 if (Tok.is(tok::kw___attribute)) {
7160 ParseGNUAttributes(attrs);
7168 ParseMicrosoftTypeAttributes(attrs);
7171 if (Tok.is(tok::kw___pascal))
7172 ParseBorlandTypeAttributes(attrs);
7184 }
else if (Tok.is(tok::r_paren) ||
7186 Tok.is(tok::ellipsis) &&
7188 isDeclarationSpecifier(
7190 isCXX11AttributeSpecifier() !=
7210 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7215 std::move(attrs),
T.getCloseLocation());
7221 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7239 ParseFunctionDeclarator(D, attrs,
T,
false, RequiresArg);
7240 PrototypeScope.Exit();
7243void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7245 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7253 bool IsCXX11MemberFunction =
7260 Actions.CurContext->isRecord());
7261 if (!IsCXX11MemberFunction)
7281 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,
7282 IsCXX11MemberFunction);
7285void Parser::ParseFunctionDeclarator(
Declarator &D,
7290 assert(
getCurScope()->isFunctionPrototypeScope() &&
7291 "Should call from a Function scope");
7297 bool HasProto =
false;
7299 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
7301 SourceLocation EllipsisLoc;
7303 DeclSpec DS(AttrFactory);
7304 bool RefQualifierIsLValueRef =
true;
7305 SourceLocation RefQualifierLoc;
7307 SourceRange ESpecRange;
7308 SmallVector<ParsedType, 2> DynamicExceptions;
7309 SmallVector<SourceRange, 2> DynamicExceptionRanges;
7312 ParsedAttributes FnAttrs(AttrFactory);
7314 SourceLocation TrailingReturnTypeLoc;
7319 SourceLocation StartLoc, LocalEndLoc, EndLoc;
7320 SourceLocation LParenLoc, RParenLoc;
7322 StartLoc = LParenLoc;
7324 if (isFunctionDeclaratorIdentifierList()) {
7326 Diag(Tok, diag::err_argument_required_after_attribute);
7328 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7332 LocalEndLoc = RParenLoc;
7337 MaybeParseCXX11Attributes(FnAttrs);
7338 ProhibitAttributes(FnAttrs);
7340 if (Tok.isNot(tok::r_paren))
7341 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7342 else if (RequiresArg)
7343 Diag(Tok, diag::err_argument_required_after_attribute);
7354 LocalEndLoc = RParenLoc;
7363 ParseTypeQualifierListOpt(
7364 DS, AR_NoAttributesParsed,
7367 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);
7374 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7375 EndLoc = RefQualifierLoc;
7377 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7378 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7395 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
7412 ESpecType = tryParseExceptionSpecification(Delayed,
7415 DynamicExceptionRanges,
7417 ExceptionSpecTokens);
7419 EndLoc = ESpecRange.
getEnd();
7423 MaybeParseCXX11Attributes(FnAttrs);
7426 LocalEndLoc = EndLoc;
7428 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7431 LocalEndLoc = Tok.getLocation();
7433 TrailingReturnType =
7435 TrailingReturnTypeLoc =
Range.getBegin();
7436 EndLoc =
Range.getEnd();
7439 MaybeParseCXX11Attributes(FnAttrs);
7447 SmallVector<NamedDecl *, 0> DeclsInPrototype;
7450 NamedDecl *ND = dyn_cast<NamedDecl>(D);
7453 DeclsInPrototype.push_back(ND);
7460 llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) {
7468 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7469 ParamInfo.size(), EllipsisLoc, RParenLoc,
7470 RefQualifierIsLValueRef, RefQualifierLoc,
7472 ESpecType, ESpecRange, DynamicExceptions.data(),
7473 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7474 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7475 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7476 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7478 std::move(FnAttrs), EndLoc);
7481bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7483 if (Tok.isOneOf(tok::amp, tok::ampamp)) {
7485 diag::warn_cxx98_compat_ref_qualifier :
7486 diag::ext_ref_qualifier);
7488 RefQualifierIsLValueRef = Tok.is(tok::amp);
7495bool Parser::isFunctionDeclaratorIdentifierList() {
7497 && Tok.is(tok::identifier)
7498 && !TryAltiVecVectorToken()
7514 && (!Tok.is(tok::eof) &&
7518void Parser::ParseFunctionDeclaratorIdentifierList(
7522 assert(!
getLangOpts().requiresStrictPrototypes() &&
7523 "Cannot parse an identifier list in C23 or C++");
7530 Diag(Tok, diag::ext_ident_list_in_param);
7533 llvm::SmallPtrSet<const IdentifierInfo *, 16> ParamsSoFar;
7537 if (Tok.isNot(tok::identifier)) {
7538 Diag(Tok, diag::err_expected) << tok::identifier;
7545 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
7548 if (Actions.getTypeName(*ParmII, Tok.getLocation(),
getCurScope()))
7549 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7552 if (!ParamsSoFar.insert(ParmII).second) {
7553 Diag(Tok, diag::err_param_redefinition) << ParmII;
7556 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7567void Parser::ParseParameterDeclarationClause(
7576 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7578 Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)
7597 IsACXXFunctionDeclaration) {
7609 DeclSpec DS(AttrFactory);
7611 ParsedAttributes ArgDeclAttrs(AttrFactory);
7612 ParsedAttributes ArgDeclSpecAttrs(AttrFactory);
7619 ArgDeclSpecAttrs.takeAllPrependingFrom(FirstArgAttrs);
7622 MaybeParseCXX11Attributes(ArgDeclAttrs);
7625 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7628 SourceLocation DSStart = Tok.getLocation();
7632 SourceLocation ThisLoc;
7636 ParsedTemplateInfo TemplateInfo;
7637 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7638 DeclSpecContext::DSC_normal,
7639 nullptr, AllowImplicitTypename);
7652 ParseDeclarator(ParmDeclarator);
7655 ParmDeclarator.SetRangeBegin(ThisLoc);
7658 MaybeParseGNUAttributes(ParmDeclarator);
7662 if (Tok.is(tok::kw_requires)) {
7667 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7673 const IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
7677 std::unique_ptr<CachedTokens> DefArgToks;
7681 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7682 ParmDeclarator.getNumTypeObjects() == 0) {
7684 Diag(DSStart, diag::err_missing_param);
7691 if (Tok.is(tok::ellipsis) &&
7693 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7694 !Actions.isUnexpandedParameterPackPermitted())) &&
7695 Actions.containsUnexpandedParameterPacks(ParmDeclarator))
7696 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7715 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7716 Tok.isNot(tok::raw_identifier) && !Tok.isAnnotation() &&
7717 Tok.getIdentifierInfo() &&
7718 Tok.getIdentifierInfo()->isKeyword(
getLangOpts())) {
7719 Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok);
7728 Diag(ParmDeclarator.getBeginLoc(),
7729 diag::err_function_parameter_limit_exceeded);
7737 Actions.ActOnParamDeclarator(
getCurScope(), ParmDeclarator, ThisLoc);
7742 if (Tok.is(tok::equal)) {
7743 SourceLocation EqualLoc = Tok.getLocation();
7753 ConsumeAndStoreInitializer(*DefArgToks,
7755 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
7766 DelayTemplateIdDestructionRAII DontDestructTemplateIds(
7771 EnterExpressionEvaluationContext Eval(
7778 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7779 DefArgResult = ParseBraceInitializer();
7781 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
7782 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7783 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7793 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7798 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
7799 DefArgResult.
get());
7804 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7805 ParmDeclarator.getIdentifierLoc(),
7806 Param, std::move(DefArgToks)));
7814 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
7821 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7823 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7824 Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {
7827 SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();
7828 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7829 << ParmEllipsis.
isValid() << ParmEllipsis;
7832 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7834 Diag(ParmDeclarator.getIdentifierLoc(),
7835 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7838 << !ParmDeclarator.hasName();
7840 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7852void Parser::ParseBracketDeclarator(
Declarator &D) {
7853 if (CheckProhibitedCXX11Attribute())
7861 if (Tok.getKind() == tok::r_square) {
7863 ParsedAttributes attrs(AttrFactory);
7864 MaybeParseCXX11Attributes(attrs);
7868 T.getOpenLocation(),
7869 T.getCloseLocation()),
7870 std::move(attrs),
T.getCloseLocation());
7872 }
else if (Tok.getKind() == tok::numeric_constant &&
7879 ParsedAttributes attrs(AttrFactory);
7880 MaybeParseCXX11Attributes(attrs);
7884 T.getOpenLocation(),
7885 T.getCloseLocation()),
7886 std::move(attrs),
T.getCloseLocation());
7888 }
else if (Tok.getKind() == tok::code_completion) {
7890 Actions.CodeCompletion().CodeCompleteBracketDeclarator(
getCurScope());
7895 SourceLocation StaticLoc;
7900 DeclSpec DS(AttrFactory);
7901 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
7909 bool isStar =
false;
7920 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7921 StaticLoc = SourceLocation();
7924 }
else if (Tok.isNot(tok::r_square)) {
7941 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7942 StaticLoc = SourceLocation();
7961 isStar, NumElements.
get(),
T.getOpenLocation(),
7962 T.getCloseLocation()),
7966void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
7967 assert(Tok.is(tok::l_square) &&
"Missing opening bracket");
7970 SourceLocation StartBracketLoc = Tok.getLocation();
7974 while (Tok.is(tok::l_square)) {
7975 ParseBracketDeclarator(TempDeclarator);
7981 if (Tok.is(tok::semi))
7984 SourceLocation SuggestParenLoc = Tok.getLocation();
7987 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7992 if (TempDeclarator.getNumTypeObjects() == 0)
7996 bool NeedParens =
false;
8015 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
8021 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
8022 const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
8023 D.
AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());
8028 if (!D.
hasName() && !NeedParens)
8031 SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();
8034 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
8035 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
8038 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8043 EndLoc, CharSourceRange(BracketRange,
true))
8046 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8049 EndLoc, CharSourceRange(BracketRange,
true))
8054void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
8055 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
8056 "Not a typeof specifier");
8058 bool IsUnqual = Tok.is(tok::kw_typeof_unqual);
8059 const IdentifierInfo *II = Tok.getIdentifierInfo();
8061 Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName();
8065 bool HasParens = Tok.is(tok::l_paren);
8073 SourceRange CastRange;
8075 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);
8091 const char *PrevSpec =
nullptr;
8098 Actions.getASTContext().getPrintingPolicy()))
8099 Diag(StartLoc, DiagID) << PrevSpec;
8110 Operand = Actions.HandleExprEvaluationContextForTypeof(
Operand.get());
8116 const char *PrevSpec =
nullptr;
8123 Actions.getASTContext().getPrintingPolicy()))
8124 Diag(StartLoc, DiagID) << PrevSpec;
8127void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
8128 assert(Tok.is(tok::kw__Atomic) &&
NextToken().
is(tok::l_paren) &&
8129 "Not an atomic specifier");
8133 if (
T.consumeOpen())
8137 if (
Result.isInvalid()) {
8145 if (
T.getCloseLocation().isInvalid())
8151 const char *PrevSpec =
nullptr;
8155 Actions.getASTContext().getPrintingPolicy()))
8156 Diag(StartLoc, DiagID) << PrevSpec;
8159bool Parser::TryAltiVecVectorTokenOutOfLine() {
8161 switch (
Next.getKind()) {
8162 default:
return false;
8165 case tok::kw_signed:
8166 case tok::kw_unsigned:
8171 case tok::kw_double:
8174 case tok::kw___bool:
8175 case tok::kw___pixel:
8176 Tok.setKind(tok::kw___vector);
8178 case tok::identifier:
8179 if (
Next.getIdentifierInfo() == Ident_pixel) {
8180 Tok.setKind(tok::kw___vector);
8183 if (
Next.getIdentifierInfo() == Ident_bool ||
8184 Next.getIdentifierInfo() == Ident_Bool) {
8185 Tok.setKind(tok::kw___vector);
8193 const char *&PrevSpec,
unsigned &DiagID,
8195 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
8196 if (Tok.getIdentifierInfo() == Ident_vector) {
8198 switch (
Next.getKind()) {
8201 case tok::kw_signed:
8202 case tok::kw_unsigned:
8207 case tok::kw_double:
8210 case tok::kw___bool:
8211 case tok::kw___pixel:
8214 case tok::identifier:
8215 if (
Next.getIdentifierInfo() == Ident_pixel) {
8219 if (
Next.getIdentifierInfo() == Ident_bool ||
8220 Next.getIdentifierInfo() == Ident_Bool) {
8229 }
else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
8233 }
else if ((Tok.getIdentifierInfo() == Ident_bool) &&
8241TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8244 SmallVector<Token, 4> Tokens;
8247 auto &SourceMgr = PP.getSourceManager();
8248 FileID FID = SourceMgr.createFileID(
8249 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8253 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8254 L.setParsingPreprocessorDirective(
true);
8260 Tokens.push_back(Tok);
8261 }
while (Tok.isNot(tok::eod));
8266 Token &EndToken = Tokens.back();
8273 Tokens.push_back(Tok);
8276 PP.EnterTokenStream(Tokens,
false,
8291 (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {
8292 Diag(Tok.getLocation(), diag::err_type_unparsed);
8297 while (Tok.isNot(tok::eof))
8301 if (Tok.is(tok::eof) && Tok.getEofData() == TypeStr.data())
8306void Parser::DiagnoseBitIntUse(
const Token &
Tok) {
8310 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8311 "expected either an _ExtInt or _BitInt token!");
8313 SourceLocation Loc = Tok.getLocation();
8314 if (Tok.is(tok::kw__ExtInt)) {
8315 Diag(Loc, diag::warn_ext_int_deprecated)
8321 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(StringRef AttrName, StringRef NormalizedScopeName, AttributeCommonInfo::Syntax SyntaxUsed)
static Decl::Kind getKind(const Decl *D)
Defines the C++ template declaration subclasses.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::RecordLoc RecordLoc
static StringRef getTriple(const Command &Job)
static bool IsAttributeLateParsedExperimentalExt(const IdentifierInfo &II)
returns true iff attribute is annotated with LateAttrParseExperimentalExt in Attr....
static bool FindLocsWithCommonFileID(Preprocessor &PP, SourceLocation StartLoc, SourceLocation EndLoc)
Check if the a start and end source location expand to the same macro.
static bool IsAttributeArgsParsedInFunctionScope(const IdentifierInfo &II)
Such attributes need their arguments parsed inside a function prototype scope so the arguments can re...
static bool IsAttributeLateParsedStandard(const IdentifierInfo &II)
returns true iff attribute is annotated with LateAttrParseStandard in Attr.td.
static ParsedAttributeArgumentsProperties attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has string arguments.
static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute takes a strict identifier argument.
static bool attributeIsTypeArgAttr(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute parses a type argument.
static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute treats kw_this as an identifier.
static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute requires parsing its arguments in an unevaluated context or not...
static bool attributeHasIdentifierArg(const llvm::Triple &T, const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has an identifier argument.
static bool isValidAfterIdentifierInDeclarator(const Token &T)
isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the specified token is valid after t...
static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has a variadic identifier argument.
static bool isPipeDeclarator(const Declarator &D)
static SourceLocation getMissingDeclaratorIdLoc(Declarator &D, SourceLocation Loc)
static bool attributeAcceptsExprPack(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine if an attribute accepts parameter packs.
static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS, Parser &P)
static bool VersionNumberSeparator(const char Separator)
static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, DeclaratorContext TheContext)
llvm::SmallVector< std::pair< const MemRegion *, SVal >, 4 > Bindings
static constexpr bool isOneOf()
This file declares semantic analysis for CUDA constructs.
This file declares facilities that support code completion.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenMP constructs and clauses.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the clang::TokenKind enum and support functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Syntax
The style used to specify an attribute.
@ AS_Declspec
__declspec(...)
Kind getParsedKind() const
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
SourceLocation getOpenLocation() const
SourceLocation getCloseLocation() const
Represents a C++ nested-name-specifier or a global scope specifier.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
SourceLocation getEndLoc() const
bool isSet() const
Deprecated.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
void setTemplateParamLists(ArrayRef< TemplateParameterList * > L)
bool isEmpty() const
No scope specifier.
SourceLocation getBegin() const
Callback handler that receives notifications when performing code completion within the preprocessor.
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)
SourceLocation getOverflowBehaviorLoc() const
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()
bool SetOverflowBehavior(OverflowBehaviorType::OverflowBehaviorKind Kind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
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)
bool isWrapSpecified() const
static const TST TST_float128
void takeAttributesAppendingingFrom(ParsedAttributes &attrs)
void Finish(Sema &S, const PrintingPolicy &Policy)
Finish - This does final analysis of the declspec, issuing diagnostics for things like "_Complex" (la...
bool isInlineSpecified() const
SourceLocation getRestrictSpecLoc() const
static const TST TST_typeof_unqualExpr
static const TST TST_class
bool hasTagDefinition() const
static const TST TST_decimal64
unsigned getParsedSpecifiers() const
Return a bitmask of which flavors of specifiers this DeclSpec includes.
void ClearFunctionSpecs()
bool SetTypeQual(TQ T, SourceLocation Loc)
static const TST TST_wchar
static const TST TST_void
bool isTypeAltiVecVector() const
void ClearConstexprSpec()
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
static const TST TST_float
static const TST TST_atomic
static const TST TST_fract
SourceLocation getThreadStorageClassSpecLoc() const
Decl * getRepAsDecl() const
static const TST TST_float16
static const TST TST_unspecified
SourceLocation getAtomicSpecLoc() const
SourceLocation getVirtualSpecLoc() const
SourceLocation getConstexprSpecLoc() const
CXXScopeSpec & getTypeSpecScope()
bool isEmpty() const
isEmpty - Return true if this declaration specifier is completely empty: no tokens were parsed in the...
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
static const TST TST_typeofType
bool SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_auto
@ PQ_StorageClassSpecifier
ConstexprSpecKind getConstexprSpecifier() const
static const TST TST_struct
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
Information about one declarator, including the parsed type information and the identifier.
bool isFunctionDeclarator(unsigned &idx) const
isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...
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 setDecompositionBindings(SourceLocation LSquareLoc, MutableArrayRef< DecompositionDeclarator::Binding > Bindings, SourceLocation RSquareLoc)
Set the decomposition bindings for this declarator.
void setInvalidType(bool Val=true)
TemplateParameterList * getInventedTemplateParameterList() const
The template parameter list generated from the explicit template parameters along with any invented t...
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.
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.
void setEllipsisLoc(SourceLocation EL)
const IdentifierInfo * getIdentifier() const
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.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
SourceLocation getLoc() const
void setIdentifierInfo(IdentifierInfo *Ident)
IdentifierInfo * getIdentifierInfo() const
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.
bool lateAttrParseExperimentalExtOnly() const
returns true iff the attribute to be parsed should only be late parsed if it is annotated with LateAt...
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 std::optional< Token > findNextToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeComments=false)
Finds the token that comes right after the given location.
static bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, const LangOptions &LangOpts, bool IgnoreWhiteSpace=false)
Relex the token at the specified location.
UnresolvedSetImpl::iterator iterator
static constexpr unsigned getMaxFunctionScopeDepth()
ParsedAttr - Represents a syntactic attribute.
unsigned getMaxArgs() const
static const ParsedAttributesView & none()
void prepend(iterator B, iterator E)
void addAtEnd(ParsedAttr *newAttr)
void remove(ParsedAttr *ToBeRemoved)
ParsedAttributes - A collection of parsed attributes.
void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA)
ParsedAttr * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Form formUsed)
Add microsoft __delspec(property) attribute.
ParsedAttr * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ParsedType typeArg, ParsedAttr::Form formUsed, SourceLocation ellipsisLoc=SourceLocation())
Add an attribute with a single type argument.
ParsedAttr * addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, ParsedAttr::Form form)
Add type_tag_for_datatype attribute.
void takeAllAppendingFrom(ParsedAttributes &Other)
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
ParseScope - Introduces a new scope for parsing.
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.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, bool IsAddressOfOperand=false)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation getEndOfPreviousToken() const
DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagId)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
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.
ExprResult ParseConstantExpressionInExprEvalContext(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
SmallVector< Stmt *, 24 > StmtVector
A SmallVector of statements.
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.
friend class ColonProtectionRAIIObject
DeclGroupPtrTy ParseOpenACCDirectiveDecl(AccessSpecifier &AS, ParsedAttributes &Attrs, DeclSpec::TST TagType, Decl *TagDecl)
Parse OpenACC directive on a declaration.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
const Token & GetLookAheadToken(unsigned N)
GetLookAheadToken - This peeks ahead N tokens and returns that token without consuming any tokens.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
ExprResult ParseArrayBoundExpression()
friend struct LateParsedAttribute
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...
const Token & getCurToken() const
void ExitScope()
ExitScope - Pop a scope off the scope stack.
const LangOptions & getLangOpts() const
friend class ParenBraceBracketBalancer
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtCodeCompletion
Stop at code completion.
@ StopAtSemi
Stop skipping at semicolon.
ExprResult ParseUnevaluatedStringLiteralExpression()
ObjCContainerDecl * getObjCDeclContext() const
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
friend class BalancedDelimiterTracker
SmallVector< TemplateParameterList *, 4 > TemplateParameterLists
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
A class for parsing a DeclSpec.
A class for parsing a declarator.
A class for parsing a field declarator.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
SourceManager & getSourceManager() const
const LangOptions & getLangOpts() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
void addAddressSpace(LangAS space)
static Qualifiers fromCVRUMask(unsigned CVRU)
Represents a struct/union/class.
field_range fields() const
bool isClassScope() const
isClassScope - Return true if this scope is a class/struct/union scope.
unsigned getFlags() const
getFlags - Return the flags for this scope.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ BlockScope
This is a scope that corresponds to a block/closure object.
@ FriendScope
This is a scope of friend declaration.
@ ControlScope
The controlling scope in a if/switch/while/for statement.
@ AtCatchScope
This is a scope that corresponds to the Objective-C @catch statement.
@ TemplateParamScope
This is a scope that corresponds to the template parameters of a C++ template.
@ CompoundStmtScope
This is a compound statement scope.
@ ClassScope
The scope of a struct/union/class definition.
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ EnumScope
This scope corresponds to an enum.
@ DeclScope
This is a scope that can contain a declaration.
@ CTCK_InitGlobalVar
Unknown context.
ParserCompletionContext
Describes the context in which code completion occurs.
@ PCC_LocalDeclarationSpecifiers
Code completion occurs within a sequence of declaration specifiers within a function,...
@ PCC_MemberTemplate
Code completion occurs following one or more template headers within a class.
@ PCC_Class
Code completion occurs within a class, struct, or union.
@ PCC_ObjCImplementation
Code completion occurs within an Objective-C implementation or category implementation.
@ PCC_Namespace
Code completion occurs at top-level or namespace context.
@ PCC_Template
Code completion occurs following one or more template headers.
NameClassificationKind getKind() const
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ 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...
void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl)
ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an initializer for the declaratio...
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.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
A RAII object used to temporarily suppress access-like checking.
Represents the declaration of a struct/union/class/enum.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
void setKind(tok::TokenKind K)
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 isOneOf(Ts... Ks) const
void setEofData(const void *D)
void setLocation(SourceLocation L)
void startToken()
Reset all flags to cleared.
void setSemiMissing(bool Missing=true)
static constexpr int FunctionTypeNumParamsLimit
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.
Declaration of a variable template.
static const char * getSpecifierName(Specifier VS)
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
bool InitScope(InterpState &S, uint32_t I)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
const char * getKeywordSpelling(TokenKind Kind) LLVM_READNONE
Determines the spelling of simple keyword and contextual keyword tokens like 'int' and 'dynamic_cast'...
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.
Top level wrappers for InstallAPI frontend operations.
TypeSpecifierType
Specifies the kind of type.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
bool isa(CodeGen::Address addr)
@ NotAttributeSpecifier
This is not an attribute specifier.
@ AttributeSpecifier
This should be treated as an attribute-specifier.
@ InvalidAttributeSpecifier
The next tokens are '[[', but this is not an attribute-specifier.
@ ExpectedParameterOrImplicitObjectParameter
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
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>.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
ActionResult< Decl * > DeclResult
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
llvm::SmallVector< ArgsUnion, 12U > ArgsVector
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.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
@ ExplicitSpecialization
We are parsing an explicit specialization.
@ ExplicitInstantiation
We are parsing an explicit instantiation.
@ NonTemplate
We are not parsing a template at all.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
@ FunctionTemplate
The name was classified as a function template name.
@ Keyword
The name has been typo-corrected to a keyword.
@ DependentNonType
The name denotes a member of a dependent type that could not be resolved.
@ UndeclaredTemplate
The name was classified as an ADL-only function template name.
@ NonType
The name was classified as a specific non-type, non-template declaration.
@ Unknown
This name is not a type or template in this context, but might be something else.
@ Error
Classification failed; an error has been produced.
@ Type
The name was classified as a type.
@ TypeTemplate
The name was classified as a template whose specializations are types.
@ Concept
The name was classified as a concept name.
@ OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ UndeclaredNonType
The name was classified as an ADL-only function name.
@ VarTemplate
The name was classified as a variable template name.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ 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.
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &&Second)
Consumes the attributes from Second and concatenates them at the end of First.
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
ActionResult< Expr * > ExprResult
@ 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
ActionResult< Stmt * > StmtResult
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.
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, SourceLocation AtomicQualLoc, SourceLocation UnalignedQualLoc, SourceLocation OverflowBehaviorLoc={}, bool OverflowBehaviorIsWrap=false)
Return a DeclaratorChunk for a pointer.
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, ArrayRef< NamedDecl * > DeclsInPrototype, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult(), SourceLocation TrailingReturnTypeLoc=SourceLocation(), DeclSpec *MethodQualifiers=nullptr)
DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
static DeclaratorChunk getPipe(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc)
Return a DeclaratorChunk for an array.
SourceLocation Loc
Loc - The place where this type was defined.
static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, unsigned TypeQuals, SourceLocation StarLoc, SourceLocation EndLoc)
enum clang::DeclaratorChunk::@340323374315200305336204205154073066142310370142 Kind
static DeclaratorChunk getParen(SourceLocation LParenLoc, SourceLocation RParenLoc)
Return a DeclaratorChunk for a paren.
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, bool lvalue)
Return a DeclaratorChunk for a reference.
Contains the lexed tokens of an attribute with arguments that may reference member variables and so n...
IdentifierInfo & AttrName
SourceLocation AttrNameLoc
SmallVector< Decl *, 2 > Decls
A late-parsed attribute that will be applied as a type attribute.
void ParseInto(ParsedAttributes &OutAttrs)
Parse this late-parsed type attribute and store results in OutAttrs.
bool isStringLiteralArg(unsigned I) const
ExpressionKind
Describes whether we are in an expression constext which we have to handle differently.
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