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
128 if (
SM.getFileID(StartLoc) !=
SM.getFileID(EndLoc))
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:
3784 goto DoneWithDeclSpec;
3790 if (!
getLangOpts().DeclSpecKeyword && Tok.is(tok::identifier) &&
3791 Tok.getIdentifierInfo()->getName() ==
"__declspec") {
3792 Diag(Loc, diag::err_ms_attributes_not_enabled);
3802 if (
T.consumeOpen()) {
3803 assert(
false &&
"Not a left paren?");
3818 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3822 if (IsTemplateSpecOrInst)
3826 if (IsTemplateSpecOrInst)
3829 goto DoneWithDeclSpec;
3832 if (!Tok.is(tok::identifier))
3837 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID,
isInvalid))
3843 goto DoneWithDeclSpec;
3845 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3846 isObjCInstancetype()) {
3847 ParsedType TypeRep = Actions.ObjC().ActOnObjCInstanceType(Loc);
3850 DiagID, TypeRep, Policy);
3862 Actions.isCurrentClassName(*Tok.getIdentifierInfo(),
getCurScope()) &&
3863 isConstructorDeclarator(
true,
3866 goto DoneWithDeclSpec;
3872 DSContext == DeclSpecContext::DSC_template_param) {
3873 goto DoneWithDeclSpec;
3882 if (
Next.isOneOf(tok::equal, tok::l_paren, tok::l_square, tok::l_brace,
3883 tok::amp, tok::ampamp, tok::star, tok::coloncolon,
3884 tok::comma, tok::semi, tok::colon, tok::greater,
3885 tok::r_paren, tok::arrow))
3886 goto DoneWithDeclSpec;
3890 *Tok.getIdentifierInfo(), Tok.getLocation(),
getCurScope(),
nullptr,
3891 false,
false,
nullptr,
false,
false,
3892 isClassTemplateDeductionContext(DSContext));
3898 if (TryAnnotateTypeConstraint())
3899 goto DoneWithDeclSpec;
3900 if (Tok.isNot(tok::identifier))
3905 goto DoneWithDeclSpec;
3906 ParsedAttributes Attrs(AttrFactory);
3907 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
3908 if (!Attrs.
empty()) {
3909 AttrsLastTime =
true;
3910 attrs.takeAllAppendingFrom(Attrs);
3914 goto DoneWithDeclSpec;
3921 (DSContext == DeclSpecContext::DSC_class ||
3922 DSContext == DeclSpecContext::DSC_top_level) &&
3923 Actions.isDeductionGuideName(
getCurScope(), *Tok.getIdentifierInfo(),
3924 Tok.getLocation(), SS) &&
3925 isConstructorDeclarator(
true,
3927 goto DoneWithDeclSpec;
3930 DiagID, TypeRep, Policy);
3941 SourceLocation NewEndLoc;
3942 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3957 case tok::annot_template_id: {
3958 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
3969 TemplateId =
nullptr;
3977 tok::kw_volatile, tok::kw_restrict, tok::amp,
3979 Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
3983 TemplateId, Policy);
3987 goto DoneWithDeclSpec;
3989 if (TemplateId && !
isInvalid && Actions.CheckTypeConstraint(TemplateId))
3990 TemplateId =
nullptr;
3992 ConsumeAnnotationToken();
3993 SourceLocation AutoLoc = Tok.getLocation();
3996 if (Tracker.consumeOpen()) {
3998 Diag(Tok, diag::err_expected) << tok::l_paren;
4002 Tracker.skipToEnd();
4003 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
4008 Tracker.consumeClose();
4011 ConsumedEnd = Tok.getLocation();
4016 DiagID, TemplateId, Policy);
4019 TemplateId, Policy);
4028 goto DoneWithDeclSpec;
4036 isConstructorDeclarator(
true,
4039 goto DoneWithDeclSpec;
4044 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
4049 case tok::kw___attribute:
4050 case tok::kw___declspec:
4051 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4055 case tok::kw___forceinline: {
4057 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
4058 SourceLocation AttrNameLoc = Tok.getLocation();
4060 nullptr, 0, tok::kw___forceinline);
4064 case tok::kw___unaligned:
4070 case tok::kw___ptrauth:
4074 case tok::kw___sptr:
4075 case tok::kw___uptr:
4076 case tok::kw___ptr64:
4077 case tok::kw___ptr32:
4079 case tok::kw___cdecl:
4080 case tok::kw___stdcall:
4081 case tok::kw___fastcall:
4082 case tok::kw___thiscall:
4083 case tok::kw___regcall:
4084 case tok::kw___vectorcall:
4088 case tok::kw___funcref:
4093 case tok::kw___pascal:
4098 case tok::kw___kernel:
4103 case tok::kw___noinline__:
4108 case tok::kw__Nonnull:
4109 case tok::kw__Nullable:
4110 case tok::kw__Nullable_result:
4111 case tok::kw__Null_unspecified:
4116 case tok::kw___kindof:
4118 AttributeScopeInfo(),
nullptr, 0,
4124 case tok::kw_typedef:
4126 PrevSpec, DiagID, Policy);
4127 isStorageClass =
true;
4129 case tok::kw_extern:
4131 Diag(Tok, diag::ext_thread_before) <<
"extern";
4133 PrevSpec, DiagID, Policy);
4134 isStorageClass =
true;
4136 case tok::kw___private_extern__:
4138 Loc, PrevSpec, DiagID, Policy);
4139 isStorageClass =
true;
4141 case tok::kw_static:
4143 Diag(Tok, diag::ext_thread_before) <<
"static";
4145 PrevSpec, DiagID, Policy);
4146 isStorageClass =
true;
4150 auto MayBeTypeSpecifier = [&]() {
4161 if (isKnownToBeTypeSpecifier(
T))
4173 PrevSpec, DiagID, Policy);
4177 tok::kw___interface, tok::kw_union,
4179 Diag(Loc, diag::ext_auto_storage_class);
4185 PrevSpec, DiagID, Policy);
4186 isStorageClass =
true;
4188 case tok::kw___auto_type:
4189 Diag(Tok, diag::ext_auto_type);
4193 case tok::kw_register:
4195 PrevSpec, DiagID, Policy);
4196 isStorageClass =
true;
4198 case tok::kw_mutable:
4200 PrevSpec, DiagID, Policy);
4201 isStorageClass =
true;
4203 case tok::kw___thread:
4206 isStorageClass =
true;
4208 case tok::kw_thread_local:
4210 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4219 Loc, PrevSpec, DiagID);
4220 isStorageClass =
true;
4222 case tok::kw__Thread_local:
4223 diagnoseUseOfC11Keyword(Tok);
4225 Loc, PrevSpec, DiagID);
4226 isStorageClass =
true;
4230 case tok::kw_inline:
4233 case tok::kw_virtual:
4237 !
getActions().getOpenCLOptions().isAvailableOption(
4239 DiagID = diag::err_openclcxx_virtual_function;
4240 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4243 DiagID = diag::err_hlsl_virtual_function;
4244 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4250 case tok::kw_explicit: {
4251 SourceLocation ExplicitLoc = Loc;
4252 SourceLocation CloseParenLoc;
4254 ConsumedEnd = ExplicitLoc;
4256 if (Tok.is(tok::l_paren)) {
4259 ? diag::warn_cxx17_compat_explicit_bool
4260 : diag::ext_explicit_bool);
4262 ExprResult ExplicitExpr(
static_cast<Expr *
>(
nullptr));
4264 Tracker.consumeOpen();
4266 EnterExpressionEvaluationContext ConstantEvaluated(
4270 ConsumedEnd = Tok.getLocation();
4271 if (ExplicitExpr.isUsable()) {
4272 CloseParenLoc = Tok.getLocation();
4273 Tracker.consumeClose();
4275 Actions.ActOnExplicitBoolSpecifier(ExplicitExpr.get());
4277 Tracker.skipToEnd();
4279 Diag(Tok.getLocation(), diag::warn_cxx20_compat_explicit_bool);
4283 ExplicitSpec, CloseParenLoc);
4286 case tok::kw__Noreturn:
4287 diagnoseUseOfC11Keyword(Tok);
4292 case tok::kw_friend:
4293 if (DSContext == DeclSpecContext::DSC_class) {
4300 DiagID = diag::err_friend_invalid_in_context;
4306 case tok::kw___module_private__:
4311 case tok::kw_constexpr:
4313 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4317 case tok::kw_consteval:
4321 case tok::kw_constinit:
4329 Diag(Tok, diag::err_unknown_typename) << Tok.getName();
4333 goto DoneWithDeclSpec;
4344 PrevSpec, DiagID, Policy);
4346 case tok::kw___int64:
4348 PrevSpec, DiagID, Policy);
4350 case tok::kw_signed:
4354 case tok::kw_unsigned:
4358 case tok::kw__Complex:
4360 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4364 case tok::kw__Imaginary:
4366 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4382 case tok::kw__ExtInt:
4383 case tok::kw__BitInt: {
4384 DiagnoseBitIntUse(Tok);
4389 ConsumedEnd = PrevTokLocation;
4392 case tok::kw___int128:
4400 case tok::kw___bf16:
4408 case tok::kw_double:
4412 case tok::kw__Float16:
4416 case tok::kw__Accum:
4418 "This keyword is only used when fixed point types are enabled "
4419 "with `-ffixed-point`");
4423 case tok::kw__Fract:
4425 "This keyword is only used when fixed point types are enabled "
4426 "with `-ffixed-point`");
4432 "This keyword is only used when fixed point types are enabled "
4433 "with `-ffixed-point`");
4436 case tok::kw___float128:
4440 case tok::kw___ibm128:
4444 case tok::kw_wchar_t:
4448 case tok::kw_char8_t:
4452 case tok::kw_char16_t:
4456 case tok::kw_char32_t:
4462 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4466 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4468 if (Tok.is(tok::kw_bool) &&
4472 DiagID = diag::err_bool_redeclaration;
4474 Tok.setKind(tok::identifier);
4481 case tok::kw__Decimal32:
4485 case tok::kw__Decimal64:
4489 case tok::kw__Decimal128:
4493 case tok::kw___vector:
4496 case tok::kw___pixel:
4499 case tok::kw___bool:
4504 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4507 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
4508 Tok.setKind(tok::identifier);
4509 goto DoneWithDeclSpec;
4511 DiagID = diag::err_opencl_unknown_type_specifier;
4512 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4518#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4519#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4520#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4521 case tok::kw_##ImgType##_t: \
4522 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4523 goto DoneWithDeclSpec; \
4525#include "clang/Basic/OpenCLImageTypes.def"
4526 case tok::kw___unknown_anytype:
4528 PrevSpec, DiagID, Policy);
4533 case tok::kw_struct:
4534 case tok::kw___interface:
4535 case tok::kw_union: {
4542 ParsedAttributes Attributes(AttrFactory);
4543 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
4544 EnteringContext, DSContext, Attributes);
4548 if (!Attributes.empty()) {
4549 AttrsLastTime =
true;
4550 attrs.takeAllAppendingFrom(Attributes);
4558 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
4566 case tok::kw_volatile:
4570 case tok::kw_restrict:
4574 case tok::kw___ob_wrap:
4576 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
4581 OverflowBehaviorType::OverflowBehaviorKind::Wrap, Loc, PrevSpec,
4584 case tok::kw___ob_trap:
4586 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
4591 OverflowBehaviorType::OverflowBehaviorKind::Trap, Loc, PrevSpec,
4596 case tok::kw_typename:
4599 goto DoneWithDeclSpec;
4601 if (!Tok.is(tok::kw_typename))
4606 case tok::kw_typeof:
4607 case tok::kw_typeof_unqual:
4608 ParseTypeofSpecifier(DS);
4611 case tok::annot_decltype:
4612 ParseDecltypeSpecifier(DS);
4615 case tok::annot_pack_indexing_type:
4616 ParsePackIndexingType(DS);
4619 case tok::annot_pragma_pack:
4623 case tok::annot_pragma_ms_pragma:
4624 HandlePragmaMSPragma();
4627 case tok::annot_pragma_ms_vtordisp:
4628 HandlePragmaMSVtorDisp();
4631 case tok::annot_pragma_ms_pointers_to_members:
4632 HandlePragmaMSPointersToMembers();
4635 case tok::annot_pragma_export:
4636 HandlePragmaExport();
4639#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4640#include "clang/Basic/Traits.inc"
4644 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4645 goto ParseIdentifier;
4648 case tok::kw__Atomic:
4653 diagnoseUseOfC11Keyword(Tok);
4655 ParseAtomicSpecifier(DS);
4663 case tok::kw___generic:
4668 if (!Actions.getLangOpts().OpenCLGenericAddressSpace) {
4669 DiagID = diag::err_opencl_unknown_type_specifier;
4670 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4675 case tok::kw_private:
4679 goto DoneWithDeclSpec;
4681 case tok::kw___private:
4682 case tok::kw___global:
4683 case tok::kw___local:
4684 case tok::kw___constant:
4686 case tok::kw___read_only:
4687 case tok::kw___write_only:
4688 case tok::kw___read_write:
4691 case tok::kw_row_major:
4692 case tok::kw_column_major:
4693 case tok::kw_groupshared:
4701#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
4702 case tok::kw_##Name: \
4703 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4706#include "clang/Basic/HLSLIntangibleTypes.def"
4713 goto DoneWithDeclSpec;
4715 SourceLocation StartLoc = Tok.getLocation();
4716 SourceLocation EndLoc;
4718 if (
Type.isUsable()) {
4720 PrevSpec, DiagID,
Type.get(),
4721 Actions.getASTContext().getPrintingPolicy()))
4722 Diag(StartLoc, DiagID) << PrevSpec;
4739 assert(PrevSpec &&
"Method did not return previous specifier!");
4742 if (DiagID == diag::ext_duplicate_declspec ||
4743 DiagID == diag::ext_warn_duplicate_declspec ||
4744 DiagID == diag::err_duplicate_declspec)
4745 Diag(Loc, DiagID) << PrevSpec
4748 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4752 Diag(Loc, DiagID) << PrevSpec;
4755 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4759 AttrsLastTime =
false;
4771 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4774 for (
auto *I : RD->decls()) {
4775 auto *VD = dyn_cast<ValueDecl>(I);
4783 for (
const auto &DD : CAT->dependent_decls()) {
4784 if (!RD->containsDecl(DD.getDecl())) {
4785 P.
Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4786 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4787 P.
Diag(DD.getDecl()->getBeginLoc(),
4788 diag::note_flexible_array_counted_by_attr_field)
4795void Parser::ParseStructDeclaration(
4800 if (Tok.is(tok::kw___extension__)) {
4802 ExtensionRAIIObject O(Diags);
4804 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4808 ParsedAttributes Attrs(AttrFactory);
4809 MaybeParseCXX11Attributes(Attrs);
4812 ParseSpecifierQualifierList(DS);
4816 if (Tok.is(tok::semi)) {
4821 ProhibitAttributes(Attrs);
4822 RecordDecl *AnonRecord =
nullptr;
4823 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
4825 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4831 bool FirstDeclarator =
true;
4832 SourceLocation CommaLoc;
4834 ParsingFieldDeclarator DeclaratorInfo(*
this, DS, Attrs);
4835 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4838 if (!FirstDeclarator) {
4841 DiagnoseAndSkipCXX11Attributes();
4842 MaybeParseGNUAttributes(DeclaratorInfo.D);
4843 DiagnoseAndSkipCXX11Attributes();
4848 if (Tok.isNot(tok::colon)) {
4851 ParseDeclarator(DeclaratorInfo.D);
4853 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.getLocation());
4865 DeclaratorInfo.BitfieldSize = Res.
get();
4869 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
4872 Decl *
Field = FieldsCallback(DeclaratorInfo);
4874 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
4881 FirstDeclarator =
false;
4889 AttrEnd.startToken();
4890 AttrEnd.setKind(tok::eof);
4891 AttrEnd.setLocation(Tok.getLocation());
4892 AttrEnd.setEofData(LA.
Toks.data());
4893 LA.
Toks.push_back(AttrEnd);
4897 LA.
Toks.push_back(Tok);
4898 PP.EnterTokenStream(LA.
Toks,
true,
4904 ParsedAttributes Attrs(AttrFactory);
4906 assert(LA.
Decls.size() <= 1 &&
4907 "late field attribute expects to have at most one declaration.");
4911 SourceLocation(), ParsedAttr::Form::GNU(),
nullptr);
4915 while (Tok.isNot(tok::eof))
4919 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
4927 ParsedAttributes Attrs = ParseLexedCAttributeTokens(LA);
4933 Self->ParseLexedTypeAttribute(*
this, OutAttrs);
4938 LateParsedAttrList::iterator It =
4946 From.erase(It, From.end());
4951 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl,
RecordLoc,
4952 "parsing struct/union body");
4956 if (
T.consumeOpen())
4960 Actions.ActOnTagStartDefinition(
getCurScope(), TagDecl);
4964 LateParsedAttrList LateFieldAttrs(
true,
4968 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
4969 Tok.isNot(tok::eof)) {
4973 if (Tok.is(tok::semi)) {
4979 if (Tok.isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4980 SourceLocation DeclEnd;
4981 ParseStaticAssertDeclaration(DeclEnd);
4985 if (Tok.is(tok::annot_pragma_pack)) {
4990 if (Tok.is(tok::annot_pragma_align)) {
4991 HandlePragmaAlign();
4995 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4998 ParsedAttributes Attrs(AttrFactory);
4999 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
5003 if (Tok.is(tok::annot_pragma_openacc)) {
5005 ParsedAttributes Attrs(AttrFactory);
5011 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
5013 TagType, Actions.getASTContext().getPrintingPolicy());
5014 ConsumeAnnotationToken();
5018 if (!Tok.is(tok::at)) {
5019 auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
5023 FD.D.getDeclSpec().getSourceRange().getBegin(),
5024 FD.D, FD.BitfieldSize);
5030 ParsingDeclSpec DS(*
this);
5031 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
5034 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
5035 Diag(Tok, diag::err_unexpected_at);
5040 ExpectAndConsume(tok::l_paren);
5041 if (!Tok.is(tok::identifier)) {
5042 Diag(Tok, diag::err_expected) << tok::identifier;
5046 SmallVector<Decl *, 16> Fields;
5047 Actions.ObjC().ActOnDefs(
getCurScope(), TagDecl, Tok.getLocation(),
5048 Tok.getIdentifierInfo(), Fields);
5050 ExpectAndConsume(tok::r_paren);
5056 if (Tok.is(tok::r_brace)) {
5057 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
5061 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
5070 ParsedAttributes attrs(AttrFactory);
5072 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
5074 SmallVector<Decl *, 32> FieldDecls(TagDecl->
fields());
5077 T.getOpenLocation(),
T.getCloseLocation(), attrs);
5080 ParseLexedAttributeList(LateFieldAttrs,
nullptr,
false,
5083 Actions.ActOnTagFinishDefinition(
getCurScope(), TagDecl,
T.getRange());
5087 const ParsedTemplateInfo &TemplateInfo,
5090 if (Tok.is(tok::code_completion)) {
5099 ParsedAttributes attrs(AttrFactory);
5100 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5102 SourceLocation ScopedEnumKWLoc;
5103 bool IsScopedUsingClassTag =
false;
5108 : diag::ext_scoped_enum);
5109 IsScopedUsingClassTag = Tok.is(tok::kw_class);
5114 ProhibitAttributes(attrs);
5117 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5126 bool shouldDelayDiagsInTag =
5129 SuppressAccessChecks diagsFromTag(*
this, shouldDelayDiagsInTag);
5132 AllowDefiningTypeSpec AllowEnumSpecifier =
5134 bool CanBeOpaqueEnumDeclaration =
5135 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5138 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5139 CanBeOpaqueEnumDeclaration);
5143 CXXScopeSpec InvalidDeclScope;
5151 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5156 if (Spec.
isSet() && Tok.isNot(tok::identifier)) {
5157 Diag(Tok, diag::err_expected) << tok::identifier;
5159 if (Tok.isNot(tok::l_brace)) {
5167 SS = std::move(Spec);
5171 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
5172 Tok.isNot(tok::colon)) {
5173 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5182 IdentifierInfo *Name =
nullptr;
5183 SourceLocation NameLoc;
5184 if (Tok.is(tok::identifier)) {
5185 Name = Tok.getIdentifierInfo();
5189 if (!Name && ScopedEnumKWLoc.
isValid()) {
5192 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5193 ScopedEnumKWLoc = SourceLocation();
5194 IsScopedUsingClassTag =
false;
5199 if (shouldDelayDiagsInTag)
5200 diagsFromTag.done();
5203 SourceRange BaseRange;
5205 bool CanBeBitfield =
5209 if (Tok.is(tok::colon)) {
5234 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5238 Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
5239 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5246 DeclSpec DS(AttrFactory);
5250 DeclSpecContext::DSC_type_specifier);
5253 BaseType = Actions.ActOnTypeName(DeclaratorInfo);
5255 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5259 DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)
5262 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5266 ? diag::warn_c17_compat_enum_fixed_underlying_type
5267 : diag::ext_c23_enum_fixed_underlying_type)
5284 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5286 else if (Tok.is(tok::l_brace)) {
5288 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
5294 ScopedEnumKWLoc = SourceLocation();
5295 IsScopedUsingClassTag =
false;
5301 }
else if (!isTypeSpecifier(DSC) &&
5302 (Tok.is(tok::semi) ||
5303 (Tok.isAtStartOfLine() &&
5304 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5309 if (Tok.isNot(tok::semi)) {
5311 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5312 PP.EnterToken(Tok,
true);
5313 Tok.setKind(tok::semi);
5319 bool IsElaboratedTypeSpecifier =
5325 diagsFromTag.redelay();
5333 Diag(Tok, diag::err_enum_template);
5341 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5345 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5347 TemplateInfo.TemplateParams->size());
5352 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5368 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5370 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5371 diag::err_keyword_not_allowed,
5374 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5375 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5376 else if (ScopedEnumKWLoc.
isValid())
5377 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5381 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5383 SkipBodyInfo SkipBody;
5386 SkipBody = Actions.shouldSkipAnonEnumBody(
getCurScope(),
5391 bool IsDependent =
false;
5392 const char *PrevSpec =
nullptr;
5397 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5398 IsScopedUsingClassTag,
5399 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5400 DSC == DeclSpecContext::DSC_template_param ||
5401 DSC == DeclSpecContext::DSC_template_type_arg,
5402 OffsetOfState, &SkipBody).get();
5412 NameLoc.
isValid() ? NameLoc : StartLoc,
5413 PrevSpec, DiagID, TagDecl, Owned,
5414 Actions.getASTContext().getPrintingPolicy()))
5415 Diag(StartLoc, DiagID) << PrevSpec;
5424 Diag(Tok, diag::err_expected_type_name_after_typename);
5430 if (
Type.isInvalid()) {
5436 NameLoc.
isValid() ? NameLoc : StartLoc,
5437 PrevSpec, DiagID,
Type.get(),
5438 Actions.getASTContext().getPrintingPolicy()))
5439 Diag(StartLoc, DiagID) << PrevSpec;
5458 ParseEnumBody(StartLoc, D, &SkipBody);
5460 !Actions.ActOnDuplicateDefinition(
getCurScope(), TagDecl, SkipBody)) {
5467 NameLoc.
isValid() ? NameLoc : StartLoc,
5468 PrevSpec, DiagID, TagDecl, Owned,
5469 Actions.getASTContext().getPrintingPolicy()))
5470 Diag(StartLoc, DiagID) << PrevSpec;
5477 Actions.ActOnTagStartDefinition(
getCurScope(), EnumDecl);
5485 Diag(
T.getOpenLocation(), diag::ext_ms_c_empty_enum_type)
5486 << SourceRange(
T.getOpenLocation(), Tok.getLocation());
5488 Diag(Tok, diag::err_empty_enum);
5491 SmallVector<Decl *, 32> EnumConstantDecls;
5492 SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
5494 Decl *LastEnumConstDecl =
nullptr;
5497 while (Tok.isNot(tok::r_brace)) {
5500 if (Tok.isNot(tok::identifier)) {
5501 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
5507 IdentifierInfo *Ident = Tok.getIdentifierInfo();
5511 ParsedAttributes attrs(AttrFactory);
5512 MaybeParseGNUAttributes(attrs);
5513 if (isAllowedCXX11AttributeSpecifier()) {
5516 ? diag::warn_cxx14_compat_ns_enum_attribute
5517 : diag::ext_ns_enum_attribute)
5519 ParseCXX11Attributes(attrs);
5522 SourceLocation EqualLoc;
5524 EnumAvailabilityDiags.emplace_back(*
this);
5526 EnterExpressionEvaluationContext ConstantEvaluated(
5535 Decl *EnumConstDecl = Actions.ActOnEnumConstant(
5536 getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
5537 EqualLoc, AssignedVal.
get(), SkipBody);
5538 EnumAvailabilityDiags.back().done();
5540 EnumConstantDecls.push_back(EnumConstDecl);
5541 LastEnumConstDecl = EnumConstDecl;
5543 if (Tok.is(tok::identifier)) {
5546 Diag(Loc, diag::err_enumerator_list_missing_comma)
5553 SourceLocation CommaLoc;
5554 if (Tok.isNot(tok::r_brace) && !
TryConsumeToken(tok::comma, CommaLoc)) {
5556 Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
5559 Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
5569 if (Tok.is(tok::r_brace) && CommaLoc.
isValid()) {
5572 diag::ext_enumerator_list_comma_cxx :
5573 diag::ext_enumerator_list_comma_c)
5576 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5586 ParsedAttributes attrs(AttrFactory);
5587 MaybeParseGNUAttributes(attrs);
5589 Actions.ActOnEnumBody(StartLoc,
T.getRange(), EnumDecl, EnumConstantDecls,
5593 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5594 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5596 EnumAvailabilityDiags[i].redelay();
5597 PD.complete(EnumConstantDecls[i]);
5601 Actions.ActOnTagFinishDefinition(
getCurScope(), EnumDecl,
T.getRange());
5606 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5607 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5611 PP.EnterToken(Tok,
true);
5612 Tok.setKind(tok::semi);
5616bool Parser::isKnownToBeTypeSpecifier(
const Token &
Tok)
const {
5617 switch (Tok.getKind()) {
5618 default:
return false;
5622 case tok::kw___int64:
5623 case tok::kw___int128:
5624 case tok::kw_signed:
5625 case tok::kw_unsigned:
5626 case tok::kw__Complex:
5627 case tok::kw__Imaginary:
5630 case tok::kw_wchar_t:
5631 case tok::kw_char8_t:
5632 case tok::kw_char16_t:
5633 case tok::kw_char32_t:
5635 case tok::kw__ExtInt:
5636 case tok::kw__BitInt:
5637 case tok::kw___bf16:
5640 case tok::kw_double:
5641 case tok::kw__Accum:
5642 case tok::kw__Fract:
5643 case tok::kw__Float16:
5644 case tok::kw___float128:
5645 case tok::kw___ibm128:
5648 case tok::kw__Decimal32:
5649 case tok::kw__Decimal64:
5650 case tok::kw__Decimal128:
5651 case tok::kw___vector:
5652#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5653#include "clang/Basic/OpenCLImageTypes.def"
5654#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5655#include "clang/Basic/HLSLIntangibleTypes.def"
5659 case tok::kw_struct:
5660 case tok::kw___interface:
5665 case tok::kw_typeof:
5666 case tok::kw_typeof_unqual:
5669 case tok::kw__Atomic:
5672 case tok::annot_typename:
5677bool Parser::isTypeSpecifierQualifier(
const Token &
Tok) {
5678 switch (Tok.getKind()) {
5679 default:
return false;
5681 case tok::identifier:
5682 if (TryAltiVecVectorToken())
5685 case tok::kw_typename:
5694 case tok::coloncolon:
5704 case tok::kw___attribute:
5706 case tok::kw_typeof:
5707 case tok::kw_typeof_unqual:
5712 case tok::kw___int64:
5713 case tok::kw___int128:
5714 case tok::kw_signed:
5715 case tok::kw_unsigned:
5716 case tok::kw__Complex:
5717 case tok::kw__Imaginary:
5720 case tok::kw_wchar_t:
5721 case tok::kw_char8_t:
5722 case tok::kw_char16_t:
5723 case tok::kw_char32_t:
5725 case tok::kw__ExtInt:
5726 case tok::kw__BitInt:
5728 case tok::kw___bf16:
5730 case tok::kw_double:
5731 case tok::kw__Accum:
5732 case tok::kw__Fract:
5733 case tok::kw__Float16:
5734 case tok::kw___float128:
5735 case tok::kw___ibm128:
5738 case tok::kw__Decimal32:
5739 case tok::kw__Decimal64:
5740 case tok::kw__Decimal128:
5741 case tok::kw___vector:
5742#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5743#include "clang/Basic/OpenCLImageTypes.def"
5744#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5745#include "clang/Basic/HLSLIntangibleTypes.def"
5749 case tok::kw_struct:
5750 case tok::kw___interface:
5757 case tok::kw_volatile:
5758 case tok::kw_restrict:
5759 case tok::kw___ob_wrap:
5760 case tok::kw___ob_trap:
5764 case tok::kw___unknown_anytype:
5767 case tok::annot_typename:
5774 case tok::kw___cdecl:
5775 case tok::kw___stdcall:
5776 case tok::kw___fastcall:
5777 case tok::kw___thiscall:
5778 case tok::kw___regcall:
5779 case tok::kw___vectorcall:
5781 case tok::kw___ptr64:
5782 case tok::kw___ptr32:
5783 case tok::kw___pascal:
5784 case tok::kw___unaligned:
5785 case tok::kw___ptrauth:
5787 case tok::kw__Nonnull:
5788 case tok::kw__Nullable:
5789 case tok::kw__Nullable_result:
5790 case tok::kw__Null_unspecified:
5792 case tok::kw___kindof:
5794 case tok::kw___private:
5795 case tok::kw___local:
5796 case tok::kw___global:
5797 case tok::kw___constant:
5798 case tok::kw___generic:
5799 case tok::kw___read_only:
5800 case tok::kw___read_write:
5801 case tok::kw___write_only:
5802 case tok::kw___funcref:
5805 case tok::kw_private:
5809 case tok::kw__Atomic:
5813 case tok::kw_groupshared:
5817 case tok::kw_row_major:
5818 case tok::kw_column_major:
5824 assert(PP.isIncrementalProcessingEnabled() &&
"Not in incremental mode");
5828 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5831 TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5832 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5833 Actions.ActOnFinishTopLevelStmtDecl(TLSD,
R.get());
5835 R = Actions.ActOnNullStmt(Tok.getLocation());
5837 if (Tok.is(tok::annot_repl_input_end) &&
5838 Tok.getAnnotationValue() !=
nullptr) {
5839 ConsumeAnnotationToken();
5843 SmallVector<Decl *, 2> DeclsInGroup;
5844 DeclsInGroup.push_back(TLSD);
5847 for (Stmt *S : Stmts) {
5850 TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5851 Actions.ActOnFinishTopLevelStmtDecl(D, S);
5852 DeclsInGroup.push_back(D);
5855 return Actions.BuildDeclaratorGroup(DeclsInGroup);
5858bool Parser::isDeclarationSpecifier(
5860 bool DisambiguatingWithExpression) {
5861 switch (Tok.getKind()) {
5862 default:
return false;
5869 case tok::identifier:
5873 if (TryAltiVecVectorToken())
5876 case tok::kw_decltype:
5877 case tok::kw_typename:
5882 if (TryAnnotateTypeConstraint())
5884 if (Tok.is(tok::identifier))
5892 if (DisambiguatingWithExpression &&
5893 isStartOfObjCClassMessageMissingOpenBracket())
5896 return isDeclarationSpecifier(AllowImplicitTypename);
5898 case tok::coloncolon:
5912 case tok::kw_typedef:
5913 case tok::kw_extern:
5914 case tok::kw___private_extern__:
5915 case tok::kw_static:
5917 case tok::kw___auto_type:
5918 case tok::kw_register:
5919 case tok::kw___thread:
5920 case tok::kw_thread_local:
5921 case tok::kw__Thread_local:
5924 case tok::kw___module_private__:
5927 case tok::kw___unknown_anytype:
5932 case tok::kw___int64:
5933 case tok::kw___int128:
5934 case tok::kw_signed:
5935 case tok::kw_unsigned:
5936 case tok::kw__Complex:
5937 case tok::kw__Imaginary:
5940 case tok::kw_wchar_t:
5941 case tok::kw_char8_t:
5942 case tok::kw_char16_t:
5943 case tok::kw_char32_t:
5946 case tok::kw__ExtInt:
5947 case tok::kw__BitInt:
5949 case tok::kw___bf16:
5951 case tok::kw_double:
5952 case tok::kw__Accum:
5953 case tok::kw__Fract:
5954 case tok::kw__Float16:
5955 case tok::kw___float128:
5956 case tok::kw___ibm128:
5959 case tok::kw__Decimal32:
5960 case tok::kw__Decimal64:
5961 case tok::kw__Decimal128:
5962 case tok::kw___vector:
5966 case tok::kw_struct:
5968 case tok::kw___interface:
5974 case tok::kw_volatile:
5975 case tok::kw_restrict:
5976 case tok::kw___ob_wrap:
5977 case tok::kw___ob_trap:
5981 case tok::kw_inline:
5982 case tok::kw_virtual:
5983 case tok::kw_explicit:
5984 case tok::kw__Noreturn:
5987 case tok::kw__Alignas:
5990 case tok::kw_friend:
5993 case tok::kw_static_assert:
5994 case tok::kw__Static_assert:
5997 case tok::kw_typeof:
5998 case tok::kw_typeof_unqual:
6001 case tok::kw___attribute:
6004 case tok::annot_decltype:
6005 case tok::annot_pack_indexing_type:
6006 case tok::kw_constexpr:
6009 case tok::kw_consteval:
6010 case tok::kw_constinit:
6013 case tok::kw__Atomic:
6016 case tok::kw_alignas:
6026 case tok::annot_typename:
6027 return !DisambiguatingWithExpression ||
6028 !isStartOfObjCClassMessageMissingOpenBracket();
6031 case tok::annot_template_id: {
6032 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
6037 return isTypeConstraintAnnotation() &&
6041 case tok::annot_cxxscope: {
6042 TemplateIdAnnotation *TemplateId =
6050 if (
NextToken().
is(tok::identifier) && TryAnnotateTypeConstraint())
6052 return isTypeConstraintAnnotation() &&
6056 case tok::kw___declspec:
6057 case tok::kw___cdecl:
6058 case tok::kw___stdcall:
6059 case tok::kw___fastcall:
6060 case tok::kw___thiscall:
6061 case tok::kw___regcall:
6062 case tok::kw___vectorcall:
6064 case tok::kw___sptr:
6065 case tok::kw___uptr:
6066 case tok::kw___ptr64:
6067 case tok::kw___ptr32:
6068 case tok::kw___forceinline:
6069 case tok::kw___pascal:
6070 case tok::kw___unaligned:
6071 case tok::kw___ptrauth:
6073 case tok::kw__Nonnull:
6074 case tok::kw__Nullable:
6075 case tok::kw__Nullable_result:
6076 case tok::kw__Null_unspecified:
6078 case tok::kw___kindof:
6080 case tok::kw___private:
6081 case tok::kw___local:
6082 case tok::kw___global:
6083 case tok::kw___constant:
6084 case tok::kw___generic:
6085 case tok::kw___read_only:
6086 case tok::kw___read_write:
6087 case tok::kw___write_only:
6088#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
6089#include "clang/Basic/OpenCLImageTypes.def"
6090#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
6091#include "clang/Basic/HLSLIntangibleTypes.def"
6093 case tok::kw___funcref:
6094 case tok::kw_groupshared:
6097 case tok::kw_row_major:
6098 case tok::kw_column_major:
6101 case tok::kw_private:
6106bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
6108 const ParsedTemplateInfo *TemplateInfo) {
6109 RevertingTentativeParsingAction TPA(*
this);
6112 if (TemplateInfo && TemplateInfo->TemplateParams)
6115 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6122 if (Tok.is(tok::identifier)) {
6126 }
else if (Tok.is(tok::annot_template_id)) {
6127 ConsumeAnnotationToken();
6134 SkipCXX11Attributes();
6137 if (Tok.isNot(tok::l_paren)) {
6144 if (Tok.is(tok::r_paren) ||
6145 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren))) {
6151 if (isCXX11AttributeSpecifier(
false,
6158 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6160 DeclScopeObj.EnterDeclaratorScope();
6163 ParsedAttributes Attrs(AttrFactory);
6164 MaybeParseMicrosoftAttributes(Attrs);
6173 bool IsConstructor =
false;
6179 if (Tok.is(tok::kw_this)) {
6181 return isDeclarationSpecifier(ITC);
6184 if (isDeclarationSpecifier(ITC))
6185 IsConstructor =
true;
6186 else if (Tok.is(tok::identifier) ||
6187 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier))) {
6192 if (Tok.is(tok::annot_cxxscope))
6193 ConsumeAnnotationToken();
6199 switch (Tok.getKind()) {
6205 case tok::coloncolon:
6218 SkipCXX11Attributes();
6220 if (DeductionGuide) {
6222 IsConstructor = Tok.is(tok::arrow);
6225 if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
6229 IsConstructor =
true;
6231 if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {
6244 IsConstructor = IsUnqualified;
6249 IsConstructor =
true;
6253 return IsConstructor;
6256void Parser::ParseTypeQualifierListOpt(
6257 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicOrPtrauthAllowed,
6259 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6260 isAllowedCXX11AttributeSpecifier()) {
6261 ParsedAttributes Attrs(AttrFactory);
6262 ParseCXX11Attributes(Attrs);
6266 SourceLocation EndLoc;
6270 const char *PrevSpec =
nullptr;
6271 unsigned DiagID = 0;
6272 SourceLocation Loc = Tok.getLocation();
6274 switch (Tok.getKind()) {
6275 case tok::code_completion:
6277 if (CodeCompletionHandler)
6278 CodeCompletionHandler();
6280 Actions.CodeCompletion().CodeCompleteTypeQualifiers(DS);
6287 case tok::kw_volatile:
6291 case tok::kw_restrict:
6295 case tok::kw___ob_wrap:
6297 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6302 OverflowBehaviorType::OverflowBehaviorKind::Wrap, Loc, PrevSpec,
6305 case tok::kw___ob_trap:
6307 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6312 OverflowBehaviorType::OverflowBehaviorKind::Trap, Loc, PrevSpec,
6315 case tok::kw__Atomic:
6316 if (!AtomicOrPtrauthAllowed)
6317 goto DoneWithTypeQuals;
6318 diagnoseUseOfC11Keyword(Tok);
6324 case tok::kw_private:
6326 goto DoneWithTypeQuals;
6328 case tok::kw___private:
6329 case tok::kw___global:
6330 case tok::kw___local:
6331 case tok::kw___constant:
6332 case tok::kw___generic:
6333 case tok::kw___read_only:
6334 case tok::kw___write_only:
6335 case tok::kw___read_write:
6339 case tok::kw_groupshared:
6348 case tok::kw___ptrauth:
6349 if (!AtomicOrPtrauthAllowed)
6350 goto DoneWithTypeQuals;
6352 EndLoc = PrevTokLocation;
6355 case tok::kw___unaligned:
6359 case tok::kw___uptr:
6364 if (TryKeywordIdentFallback(
false))
6368 case tok::kw___sptr:
6370 case tok::kw___ptr64:
6371 case tok::kw___ptr32:
6372 case tok::kw___cdecl:
6373 case tok::kw___stdcall:
6374 case tok::kw___fastcall:
6375 case tok::kw___thiscall:
6376 case tok::kw___regcall:
6377 case tok::kw___vectorcall:
6378 if (AttrReqs & AR_DeclspecAttributesParsed) {
6382 goto DoneWithTypeQuals;
6384 case tok::kw___funcref:
6388 case tok::kw___pascal:
6389 if (AttrReqs & AR_VendorAttributesParsed) {
6393 goto DoneWithTypeQuals;
6396 case tok::kw__Nonnull:
6397 case tok::kw__Nullable:
6398 case tok::kw__Nullable_result:
6399 case tok::kw__Null_unspecified:
6404 case tok::kw___kindof:
6406 AttributeScopeInfo(),
nullptr, 0,
6411 case tok::kw___attribute:
6412 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6414 Diag(Tok, diag::err_attributes_not_allowed);
6418 if (AttrReqs & AR_GNUAttributesParsed ||
6419 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6429 DS.
Finish(Actions, Actions.getASTContext().getPrintingPolicy());
6437 assert(PrevSpec &&
"Method did not return previous specifier!");
6438 Diag(Tok, DiagID) << PrevSpec;
6447 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6448 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6454 if (Kind == tok::star || Kind == tok::caret)
6458 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6459 Lang.getOpenCLCompatibleVersion() >= 200)
6462 if (!Lang.CPlusPlus)
6465 if (Kind == tok::amp)
6473 if (Kind == tok::ampamp)
6484 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6491void Parser::ParseDeclaratorInternal(
Declarator &D,
6492 DirectDeclParseFunction DirectDeclParser) {
6493 if (Diags.hasAllExtensionsSilenced())
6503 (Tok.is(tok::coloncolon) ||
6504 (Tok.is(tok::kw_decltype) &&
NextToken().
is(tok::l_paren)) ||
6505 (Tok.is(tok::identifier) &&
6507 Tok.is(tok::annot_cxxscope))) {
6508 TentativeParsingAction TPA(*
this,
true);
6514 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6526 Tok.is(tok::star)) {
6530 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6531 CompoundToken::MemberPtr);
6536 DeclSpec DS(AttrFactory);
6537 ParseTypeQualifierListOpt(DS);
6541 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6542 ParseDeclaratorInternal(D, DirectDeclParser);
6556 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6566 AnnotateScopeToken(SS,
true);
6568 if (DirectDeclParser)
6569 (this->*DirectDeclParser)(D);
6577 DeclSpec DS(AttrFactory);
6578 ParseTypeQualifierListOpt(DS);
6587 if (DirectDeclParser)
6588 (this->*DirectDeclParser)(D);
6597 if (Kind == tok::star || Kind == tok::caret) {
6599 DeclSpec DS(AttrFactory);
6603 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6605 ? AR_GNUAttributesParsed
6606 : AR_GNUAttributesParsedAndRejected);
6607 ParseTypeQualifierListOpt(DS, Reqs,
true,
6612 Actions.runWithSufficientStackSpace(
6613 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6614 if (Kind == tok::star)
6629 DeclSpec DS(AttrFactory);
6633 if (Kind == tok::ampamp)
6635 diag::warn_cxx98_compat_rvalue_reference :
6636 diag::ext_rvalue_reference);
6639 ParseTypeQualifierListOpt(DS);
6648 diag::err_invalid_reference_qualifier_application) <<
"const";
6651 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6655 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6659 Actions.runWithSufficientStackSpace(
6660 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6667 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6670 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6699void Parser::ParseDirectDeclarator(
Declarator &D) {
6706 return ParseDecompositionDeclarator(D);
6720 ParseOptionalCXXScopeSpecifier(
6722 false, EnteringContext);
6737 if (Actions.ShouldEnterDeclaratorScope(
getCurScope(),
6741 DeclScopeObj.EnterDeclaratorScope();
6748 goto PastIdentifier;
6764 !Actions.containsUnexpandedParameterPacks(D) &&
6772 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6782 if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6786 bool AllowConstructorName;
6787 bool AllowDeductionGuide;
6789 AllowConstructorName =
false;
6790 AllowDeductionGuide =
false;
6794 AllowDeductionGuide =
false;
6802 SourceLocation TemplateKWLoc;
6807 true, AllowConstructorName,
6808 AllowDeductionGuide, &TemplateKWLoc,
6821 DeclScopeObj.EnterDeclaratorScope();
6828 goto PastIdentifier;
6834 diag::err_expected_unqualified_id)
6837 goto PastIdentifier;
6841 "There's a C++-specific check for tok::identifier above");
6842 assert(Tok.getIdentifierInfo() &&
"Not an identifier?");
6843 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6846 goto PastIdentifier;
6851 bool DiagnoseIdentifier =
false;
6855 DiagnoseIdentifier =
true;
6858 DiagnoseIdentifier =
6866 !isCXX11VirtSpecifier(Tok))
6868 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6869 if (DiagnoseIdentifier) {
6870 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
6874 goto PastIdentifier;
6878 if (Tok.is(tok::l_paren)) {
6883 RevertingTentativeParsingAction PA(*
this);
6888 goto PastIdentifier;
6895 ParseParenDeclarator(D);
6908 DeclScopeObj.EnterDeclaratorScope();
6919 diag::ext_abstract_pack_declarator_parens);
6921 if (Tok.getKind() == tok::annot_pragma_parser_crash)
6923 if (Tok.is(tok::l_square))
6924 return ParseMisplacedBracketDeclarator(D);
6929 !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
6930 Tok.getIdentifierInfo()->isCPlusPlusKeyword(
getLangOpts())) {
6932 diag::err_expected_member_name_or_semi_objcxx_keyword)
6933 << Tok.getIdentifierInfo()
6936 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6939 goto PastIdentifier;
6942 diag::err_expected_member_name_or_semi)
6946 if (Tok.getKind() == tok::TokenKind::kw_while) {
6947 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6949 if (Tok.isOneOf(tok::period, tok::arrow))
6950 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
6953 if (Tok.isAtStartOfLine() && Loc.
isValid())
6954 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
6958 diag::err_expected_unqualified_id)
6963 diag::err_expected_either)
6964 << tok::identifier << tok::l_paren;
6973 "Haven't past the location of the identifier yet?");
6977 MaybeParseCXX11Attributes(D);
6980 if (Tok.is(tok::l_paren)) {
6992 bool IsAmbiguous =
false;
7004 AllowImplicitTypename =
7012 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
7013 bool IsFunctionDecl =
7014 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
7015 TentativelyDeclaredIdentifiers.pop_back();
7016 if (!IsFunctionDecl)
7019 ParsedAttributes attrs(AttrFactory);
7022 if (IsFunctionDeclaration)
7023 Actions.ActOnStartFunctionDeclarationDeclarator(D,
7024 TemplateParameterDepth);
7025 ParseFunctionDeclarator(D, attrs,
T, IsAmbiguous);
7026 if (IsFunctionDeclaration)
7027 Actions.ActOnFinishFunctionDeclarationDeclarator(D);
7028 PrototypeScope.Exit();
7029 }
else if (Tok.is(tok::l_square)) {
7030 ParseBracketDeclarator(D);
7031 }
else if (Tok.isRegularKeywordAttribute()) {
7033 Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();
7038 if (!
T.consumeOpen())
7049 Diag(Tok, diag::err_requires_clause_inside_parens);
7063void Parser::ParseDecompositionDeclarator(
Declarator &D) {
7064 assert(Tok.is(tok::l_square));
7066 TentativeParsingAction PA(*
this);
7071 DiagnoseAndSkipCXX11Attributes();
7075 if (!(Tok.isOneOf(tok::identifier, tok::ellipsis) &&
7077 tok::identifier, tok::l_square, tok::ellipsis)) &&
7078 !(Tok.is(tok::r_square) &&
7081 return ParseMisplacedBracketDeclarator(D);
7084 SourceLocation PrevEllipsisLoc;
7085 SmallVector<DecompositionDeclarator::Binding, 32>
Bindings;
7086 while (Tok.isNot(tok::r_square)) {
7088 if (Tok.is(tok::comma))
7091 if (Tok.is(tok::identifier)) {
7093 Diag(EndLoc, diag::err_expected)
7096 Diag(Tok, diag::err_expected_comma_or_rsquare);
7099 SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis},
7101 if (Tok.is(tok::comma))
7103 else if (Tok.is(tok::r_square))
7108 if (isCXX11AttributeSpecifier() !=
7110 DiagnoseAndSkipCXX11Attributes();
7112 SourceLocation EllipsisLoc;
7114 if (Tok.is(tok::ellipsis)) {
7116 : diag::ext_cxx_binding_pack);
7117 if (PrevEllipsisLoc.
isValid()) {
7118 Diag(Tok, diag::err_binding_multiple_ellipses);
7119 Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
7122 EllipsisLoc = Tok.getLocation();
7123 PrevEllipsisLoc = EllipsisLoc;
7127 if (Tok.isNot(tok::identifier)) {
7128 Diag(Tok, diag::err_expected) << tok::identifier;
7132 IdentifierInfo *II = Tok.getIdentifierInfo();
7133 SourceLocation Loc = Tok.getLocation();
7136 if (Tok.is(tok::ellipsis) && !PrevEllipsisLoc.
isValid()) {
7137 DiagnoseMisplacedEllipsis(Tok.getLocation(), Loc, EllipsisLoc.
isValid(),
7139 EllipsisLoc = Tok.getLocation();
7143 ParsedAttributes Attrs(AttrFactory);
7144 if (isCXX11AttributeSpecifier() !=
7147 ? diag::warn_cxx23_compat_decl_attrs_on_binding
7148 : diag::ext_decl_attrs_on_binding);
7149 MaybeParseCXX11Attributes(Attrs);
7152 Bindings.push_back({II, Loc, std::move(Attrs), EllipsisLoc});
7155 if (Tok.isNot(tok::r_square))
7162 Diag(Tok.getLocation(), diag::ext_decomp_decl_empty);
7170 T.getCloseLocation());
7173void Parser::ParseParenDeclarator(
Declarator &D) {
7177 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7189 ParsedAttributes attrs(AttrFactory);
7190 bool RequiresArg =
false;
7191 if (Tok.is(tok::kw___attribute)) {
7192 ParseGNUAttributes(attrs);
7200 ParseMicrosoftTypeAttributes(attrs);
7203 if (Tok.is(tok::kw___pascal))
7204 ParseBorlandTypeAttributes(attrs);
7216 }
else if (Tok.is(tok::r_paren) ||
7218 Tok.is(tok::ellipsis) &&
7220 isDeclarationSpecifier(
7222 isCXX11AttributeSpecifier() !=
7242 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7247 std::move(attrs),
T.getCloseLocation());
7253 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7271 ParseFunctionDeclarator(D, attrs,
T,
false, RequiresArg);
7272 PrototypeScope.Exit();
7275void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7277 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7285 bool IsCXX11MemberFunction =
7292 Actions.CurContext->isRecord());
7293 if (!IsCXX11MemberFunction)
7313 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,
7314 IsCXX11MemberFunction);
7317void Parser::ParseFunctionDeclarator(
Declarator &D,
7322 assert(
getCurScope()->isFunctionPrototypeScope() &&
7323 "Should call from a Function scope");
7329 bool HasProto =
false;
7331 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
7333 SourceLocation EllipsisLoc;
7335 DeclSpec DS(AttrFactory);
7336 bool RefQualifierIsLValueRef =
true;
7337 SourceLocation RefQualifierLoc;
7339 SourceRange ESpecRange;
7340 SmallVector<ParsedType, 2> DynamicExceptions;
7341 SmallVector<SourceRange, 2> DynamicExceptionRanges;
7344 ParsedAttributes FnAttrs(AttrFactory);
7346 SourceLocation TrailingReturnTypeLoc;
7351 SourceLocation StartLoc, LocalEndLoc, EndLoc;
7352 SourceLocation LParenLoc, RParenLoc;
7354 StartLoc = LParenLoc;
7356 if (isFunctionDeclaratorIdentifierList()) {
7358 Diag(Tok, diag::err_argument_required_after_attribute);
7360 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7364 LocalEndLoc = RParenLoc;
7369 MaybeParseCXX11Attributes(FnAttrs);
7370 ProhibitAttributes(FnAttrs);
7372 if (Tok.isNot(tok::r_paren))
7373 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7374 else if (RequiresArg)
7375 Diag(Tok, diag::err_argument_required_after_attribute);
7386 LocalEndLoc = RParenLoc;
7395 ParseTypeQualifierListOpt(
7396 DS, AR_NoAttributesParsed,
7399 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);
7406 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7407 EndLoc = RefQualifierLoc;
7409 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7410 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7427 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
7444 ESpecType = tryParseExceptionSpecification(Delayed,
7447 DynamicExceptionRanges,
7449 ExceptionSpecTokens);
7451 EndLoc = ESpecRange.
getEnd();
7455 MaybeParseCXX11Attributes(FnAttrs);
7458 LocalEndLoc = EndLoc;
7460 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7463 LocalEndLoc = Tok.getLocation();
7465 TrailingReturnType =
7467 TrailingReturnTypeLoc =
Range.getBegin();
7468 EndLoc =
Range.getEnd();
7471 MaybeParseCXX11Attributes(FnAttrs);
7479 SmallVector<NamedDecl *, 0> DeclsInPrototype;
7482 NamedDecl *ND = dyn_cast<NamedDecl>(D);
7485 DeclsInPrototype.push_back(ND);
7492 llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) {
7500 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7501 ParamInfo.size(), EllipsisLoc, RParenLoc,
7502 RefQualifierIsLValueRef, RefQualifierLoc,
7504 ESpecType, ESpecRange, DynamicExceptions.data(),
7505 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7506 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7507 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7508 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7510 std::move(FnAttrs), EndLoc);
7513bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7515 if (Tok.isOneOf(tok::amp, tok::ampamp)) {
7517 diag::warn_cxx98_compat_ref_qualifier :
7518 diag::ext_ref_qualifier);
7520 RefQualifierIsLValueRef = Tok.is(tok::amp);
7527bool Parser::isFunctionDeclaratorIdentifierList() {
7529 && Tok.is(tok::identifier)
7530 && !TryAltiVecVectorToken()
7546 && (!Tok.is(tok::eof) &&
7550void Parser::ParseFunctionDeclaratorIdentifierList(
7554 assert(!
getLangOpts().requiresStrictPrototypes() &&
7555 "Cannot parse an identifier list in C23 or C++");
7562 Diag(Tok, diag::ext_ident_list_in_param);
7565 llvm::SmallPtrSet<const IdentifierInfo *, 16> ParamsSoFar;
7569 if (Tok.isNot(tok::identifier)) {
7570 Diag(Tok, diag::err_expected) << tok::identifier;
7577 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
7580 if (Actions.getTypeName(*ParmII, Tok.getLocation(),
getCurScope()))
7581 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7584 if (!ParamsSoFar.insert(ParmII).second) {
7585 Diag(Tok, diag::err_param_redefinition) << ParmII;
7588 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7599void Parser::ParseParameterDeclarationClause(
7608 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7610 Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)
7629 IsACXXFunctionDeclaration) {
7641 DeclSpec DS(AttrFactory);
7643 ParsedAttributes ArgDeclAttrs(AttrFactory);
7644 ParsedAttributes ArgDeclSpecAttrs(AttrFactory);
7651 ArgDeclSpecAttrs.takeAllPrependingFrom(FirstArgAttrs);
7654 MaybeParseCXX11Attributes(ArgDeclAttrs);
7657 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7660 SourceLocation DSStart = Tok.getLocation();
7664 SourceLocation ThisLoc;
7668 ParsedTemplateInfo TemplateInfo;
7669 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7670 DeclSpecContext::DSC_normal,
7671 nullptr, AllowImplicitTypename);
7684 ParseDeclarator(ParmDeclarator);
7687 ParmDeclarator.SetRangeBegin(ThisLoc);
7690 MaybeParseGNUAttributes(ParmDeclarator);
7694 if (Tok.is(tok::kw_requires)) {
7699 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7705 const IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
7709 std::unique_ptr<CachedTokens> DefArgToks;
7713 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7714 ParmDeclarator.getNumTypeObjects() == 0) {
7716 Diag(DSStart, diag::err_missing_param);
7723 if (Tok.is(tok::ellipsis) &&
7725 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7726 !Actions.isUnexpandedParameterPackPermitted())) &&
7727 Actions.containsUnexpandedParameterPacks(ParmDeclarator))
7728 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7747 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7748 Tok.isNot(tok::raw_identifier) && !Tok.isAnnotation() &&
7749 Tok.getIdentifierInfo() &&
7750 Tok.getIdentifierInfo()->isKeyword(
getLangOpts())) {
7751 Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok);
7760 Diag(ParmDeclarator.getBeginLoc(),
7761 diag::err_function_parameter_limit_exceeded);
7769 Actions.ActOnParamDeclarator(
getCurScope(), ParmDeclarator, ThisLoc);
7774 if (Tok.is(tok::equal)) {
7775 SourceLocation EqualLoc = Tok.getLocation();
7785 ConsumeAndStoreInitializer(*DefArgToks,
7787 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
7798 DelayTemplateIdDestructionRAII DontDestructTemplateIds(
7803 EnterExpressionEvaluationContext Eval(
7810 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7811 DefArgResult = ParseBraceInitializer();
7813 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
7814 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7815 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7825 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7830 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
7831 DefArgResult.
get());
7836 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7837 ParmDeclarator.getIdentifierLoc(),
7838 Param, std::move(DefArgToks)));
7846 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
7853 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7855 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7856 Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {
7859 SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();
7860 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7861 << ParmEllipsis.
isValid() << ParmEllipsis;
7864 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7866 Diag(ParmDeclarator.getIdentifierLoc(),
7867 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7870 << !ParmDeclarator.hasName();
7872 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7884void Parser::ParseBracketDeclarator(
Declarator &D) {
7885 if (CheckProhibitedCXX11Attribute())
7893 if (Tok.getKind() == tok::r_square) {
7895 ParsedAttributes attrs(AttrFactory);
7896 MaybeParseCXX11Attributes(attrs);
7900 T.getOpenLocation(),
7901 T.getCloseLocation()),
7902 std::move(attrs),
T.getCloseLocation());
7904 }
else if (Tok.getKind() == tok::numeric_constant &&
7911 ParsedAttributes attrs(AttrFactory);
7912 MaybeParseCXX11Attributes(attrs);
7916 T.getOpenLocation(),
7917 T.getCloseLocation()),
7918 std::move(attrs),
T.getCloseLocation());
7920 }
else if (Tok.getKind() == tok::code_completion) {
7922 Actions.CodeCompletion().CodeCompleteBracketDeclarator(
getCurScope());
7927 SourceLocation StaticLoc;
7932 DeclSpec DS(AttrFactory);
7933 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
7941 bool isStar =
false;
7952 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7953 StaticLoc = SourceLocation();
7956 }
else if (Tok.isNot(tok::r_square)) {
7973 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7974 StaticLoc = SourceLocation();
7993 isStar, NumElements.
get(),
T.getOpenLocation(),
7994 T.getCloseLocation()),
7998void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
7999 assert(Tok.is(tok::l_square) &&
"Missing opening bracket");
8002 SourceLocation StartBracketLoc = Tok.getLocation();
8006 while (Tok.is(tok::l_square)) {
8007 ParseBracketDeclarator(TempDeclarator);
8013 if (Tok.is(tok::semi))
8016 SourceLocation SuggestParenLoc = Tok.getLocation();
8019 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
8024 if (TempDeclarator.getNumTypeObjects() == 0)
8028 bool NeedParens =
false;
8047 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
8053 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
8054 const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
8055 D.
AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());
8060 if (!D.
hasName() && !NeedParens)
8063 SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();
8066 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
8067 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
8070 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8075 EndLoc, CharSourceRange(BracketRange,
true))
8078 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8081 EndLoc, CharSourceRange(BracketRange,
true))
8086void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
8087 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
8088 "Not a typeof specifier");
8090 bool IsUnqual = Tok.is(tok::kw_typeof_unqual);
8091 const IdentifierInfo *II = Tok.getIdentifierInfo();
8093 Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName();
8097 bool HasParens = Tok.is(tok::l_paren);
8105 SourceRange CastRange;
8107 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);
8123 const char *PrevSpec =
nullptr;
8130 Actions.getASTContext().getPrintingPolicy()))
8131 Diag(StartLoc, DiagID) << PrevSpec;
8142 Operand = Actions.HandleExprEvaluationContextForTypeof(
Operand.get());
8148 const char *PrevSpec =
nullptr;
8155 Actions.getASTContext().getPrintingPolicy()))
8156 Diag(StartLoc, DiagID) << PrevSpec;
8159void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
8160 assert(Tok.is(tok::kw__Atomic) &&
NextToken().
is(tok::l_paren) &&
8161 "Not an atomic specifier");
8165 if (
T.consumeOpen())
8169 if (
Result.isInvalid()) {
8177 if (
T.getCloseLocation().isInvalid())
8183 const char *PrevSpec =
nullptr;
8187 Actions.getASTContext().getPrintingPolicy()))
8188 Diag(StartLoc, DiagID) << PrevSpec;
8191bool Parser::TryAltiVecVectorTokenOutOfLine() {
8193 switch (
Next.getKind()) {
8194 default:
return false;
8197 case tok::kw_signed:
8198 case tok::kw_unsigned:
8203 case tok::kw_double:
8206 case tok::kw___bool:
8207 case tok::kw___pixel:
8208 Tok.setKind(tok::kw___vector);
8210 case tok::identifier:
8211 if (
Next.getIdentifierInfo() == Ident_pixel) {
8212 Tok.setKind(tok::kw___vector);
8215 if (
Next.getIdentifierInfo() == Ident_bool ||
8216 Next.getIdentifierInfo() == Ident_Bool) {
8217 Tok.setKind(tok::kw___vector);
8225 const char *&PrevSpec,
unsigned &DiagID,
8227 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
8228 if (Tok.getIdentifierInfo() == Ident_vector) {
8230 switch (
Next.getKind()) {
8233 case tok::kw_signed:
8234 case tok::kw_unsigned:
8239 case tok::kw_double:
8242 case tok::kw___bool:
8243 case tok::kw___pixel:
8246 case tok::identifier:
8247 if (
Next.getIdentifierInfo() == Ident_pixel) {
8251 if (
Next.getIdentifierInfo() == Ident_bool ||
8252 Next.getIdentifierInfo() == Ident_Bool) {
8261 }
else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
8265 }
else if ((Tok.getIdentifierInfo() == Ident_bool) &&
8273TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8276 SmallVector<Token, 4> Tokens;
8279 auto &SourceMgr = PP.getSourceManager();
8280 FileID FID = SourceMgr.createFileID(
8281 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8285 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8286 L.setParsingPreprocessorDirective(
true);
8292 Tokens.push_back(Tok);
8293 }
while (Tok.isNot(tok::eod));
8298 Token &EndToken = Tokens.back();
8305 Tokens.push_back(Tok);
8308 PP.EnterTokenStream(Tokens,
false,
8323 (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {
8324 Diag(Tok.getLocation(), diag::err_type_unparsed);
8329 while (Tok.isNot(tok::eof))
8333 if (Tok.is(tok::eof) && Tok.getEofData() == TypeStr.data())
8338void Parser::DiagnoseBitIntUse(
const Token &
Tok) {
8342 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8343 "expected either an _ExtInt or _BitInt token!");
8345 SourceLocation Loc = Tok.getLocation();
8346 if (Tok.is(tok::kw__ExtInt)) {
8347 Diag(Loc, diag::warn_ext_int_deprecated)
8353 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
bool hasConflictingTypeSpecifier() const
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.
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.
The JSON file list parser is used to communicate input to InstallAPI.
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