34#include "llvm/ADT/ScopeExit.h"
35#include "llvm/ADT/SmallSet.h"
36#include "llvm/ADT/StringSwitch.h"
48 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
49 if (DSC == DeclSpecContext::DSC_normal)
50 DSC = DeclSpecContext::DSC_type_specifier;
56 ParseSpecifierQualifierList(DS, AS, DSC);
64 if (AL.isDeclspecAttribute())
65 ToBeMoved.push_back(&AL);
74 ParseDeclarator(DeclaratorInfo);
81 return Actions.ActOnTypeName(DeclaratorInfo);
86 if (Name.size() >= 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
87 return Name.drop_front(2).drop_back(2);
94#define CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
96#include "clang/Parse/AttrParserStringSwitches.inc"
98#undef CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
104#define CLANG_ATTR_LATE_PARSED_LIST
106#include "clang/Parse/AttrParserStringSwitches.inc"
108#undef CLANG_ATTR_LATE_PARSED_LIST
114#define CLANG_ATTR_PARSE_ARGS_IN_FUNCTION_SCOPE_LIST
116#include "clang/Parse/AttrParserStringSwitches.inc"
118#undef CLANG_ATTR_PARSE_ARGS_IN_FUNCTION_SCOPE_LIST
131 bool AttrStartIsInMacro =
133 bool AttrEndIsInMacro =
135 return AttrStartIsInMacro && AttrEndIsInMacro;
138void Parser::ParseAttributes(
unsigned WhichAttrKinds,
ParsedAttributes &Attrs,
145 if (WhichAttrKinds & PAKM_CXX11)
146 MoreToParse |= MaybeParseCXX11Attributes(Attrs);
147 if (WhichAttrKinds & PAKM_GNU)
148 MoreToParse |= MaybeParseGNUAttributes(Attrs, LateAttrs);
149 if (WhichAttrKinds & PAKM_Declspec)
150 MoreToParse |= MaybeParseMicrosoftDeclSpecs(Attrs);
151 }
while (MoreToParse);
158 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
164 if (Tok.isNot(tok::l_paren)) {
165 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
166 ParsedAttr::Form::GNU());
170 bool LateParse =
false;
177 LateParse =
getLangOpts().ExperimentalLateParseAttributes &&
190 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc,
nullptr,
191 SourceLocation(), ParsedAttr::Form::GNU(), D);
210 const DeclaratorChunk::FunctionTypeInfo &FTI = Chunk.
Fun;
211 for (
unsigned P = 0, NumParams = FTI.
NumParams; P != NumParams; ++P)
212 if (
auto *Param = dyn_cast_or_null<ParmVarDecl>(FTI.
Params[P].
Param);
213 Param && Param->getIdentifier())
219 LateAttrs->push_back(LA);
223 if (!ClassStack.empty() && !LateAttrs->
parseSoon())
224 getCurrentClass().LateParsedDeclarations.push_back(LA);
228 LA->
Toks.push_back(Tok);
231 ConsumeAndStoreUntil(tok::r_paren, LA->
Toks,
true);
236 LA->
Toks.push_back(Eof);
243 assert(Tok.is(tok::kw___attribute) &&
"Not a GNU attribute list!");
245 SourceLocation StartLoc = Tok.getLocation();
246 SourceLocation EndLoc = StartLoc;
248 while (Tok.is(tok::kw___attribute)) {
250 unsigned OldNumAttrs = Attrs.
size();
251 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
253 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
258 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"(")) {
269 if (Tok.isAnnotation())
271 if (Tok.is(tok::code_completion)) {
273 Actions.CodeCompletion().CodeCompleteAttribute(
278 if (ParseSingleGNUAttribute(Attrs, EndLoc, LateAttrs, D))
280 }
while (Tok.is(tok::comma));
282 if (ExpectAndConsume(tok::r_paren))
284 SourceLocation Loc = Tok.getLocation();
285 if (ExpectAndConsume(tok::r_paren))
291 auto &SM = PP.getSourceManager();
292 if (!SM.isWrittenInBuiltinFile(SM.getSpellingLoc(AttrTokLoc)) &&
294 CharSourceRange ExpansionRange = SM.getExpansionRange(AttrTokLoc);
295 StringRef FoundName =
297 IdentifierInfo *MacroII = PP.getIdentifierInfo(FoundName);
299 for (
unsigned i = OldNumAttrs; i < Attrs.
size(); ++i)
300 Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.
getBegin());
303 for (
unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
304 (*LateAttrs)[i]->MacroII = MacroII;
309 Attrs.
Range = SourceRange(StartLoc, EndLoc);
317#define CLANG_ATTR_IDENTIFIER_ARG_LIST
319#include "clang/Parse/AttrParserStringSwitches.inc"
321#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
329#define CLANG_ATTR_STRING_LITERAL_ARG_LIST
331#include "clang/Parse/AttrParserStringSwitches.inc"
333#undef CLANG_ATTR_STRING_LITERAL_ARG_LIST
340#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
342#include "clang/Parse/AttrParserStringSwitches.inc"
344#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
351#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
353#include "clang/Parse/AttrParserStringSwitches.inc"
355#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
362#define CLANG_ATTR_ACCEPTS_EXPR_PACK
364#include "clang/Parse/AttrParserStringSwitches.inc"
366#undef CLANG_ATTR_ACCEPTS_EXPR_PACK
373#define CLANG_ATTR_TYPE_ARG_LIST
375#include "clang/Parse/AttrParserStringSwitches.inc"
377#undef CLANG_ATTR_TYPE_ARG_LIST
384#define CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
386#include "clang/Parse/AttrParserStringSwitches.inc"
388#undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
396#define CLANG_ATTR_ARG_CONTEXT_LIST
398#include "clang/Parse/AttrParserStringSwitches.inc"
400#undef CLANG_ATTR_ARG_CONTEXT_LIST
404 assert(Tok.is(tok::identifier) &&
"expected an identifier");
405 IdentifierLoc *IL =
new (Actions.Context)
406 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
421 if (Tok.isNot(tok::r_paren))
424 if (
Parens.consumeClose())
432 &AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
433 AttributeScopeInfo(ScopeName, ScopeLoc),
T.get(), Form);
435 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
436 AttributeScopeInfo(ScopeName, ScopeLoc),
nullptr, 0, Form);
440Parser::ParseUnevaluatedStringInAttribute(
const IdentifierInfo &AttrName) {
441 if (Tok.is(tok::l_paren)) {
444 ExprResult Res = ParseUnevaluatedStringInAttribute(AttrName);
445 Paren.consumeClose();
448 if (!isTokenStringLiteral()) {
449 Diag(Tok.getLocation(), diag::err_expected_string_literal)
456bool Parser::ParseAttributeArgumentList(
459 bool SawError =
false;
463 Expr = ParseUnevaluatedStringInAttribute(AttrName);
465 Diag(Tok, diag::compat_cxx11_generalized_initializer_lists);
466 Expr = ParseBraceInitializer();
471 if (Tok.is(tok::ellipsis))
473 else if (Tok.is(tok::code_completion)) {
489 if (Actions.DiagnoseUnexpandedParameterPack(Expr.
get())) {
494 Exprs.push_back(Expr.
get());
496 if (Tok.isNot(tok::comma))
501 checkPotentialAngleBracketDelimiter(Comma);
508unsigned Parser::ParseAttributeArgsCommon(
517 bool AttributeIsTypeArgAttr =
519 bool AttributeHasVariadicIdentifierArg =
523 if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
524 Tok.setKind(tok::identifier);
527 if (Tok.is(tok::identifier)) {
529 bool IsIdentifierArg =
530 AttributeHasVariadicIdentifierArg ||
541 IsIdentifierArg =
Next.isOneOf(tok::r_paren, tok::comma);
545 ArgExprs.push_back(ParseIdentifierLoc());
549 if (!ArgExprs.empty() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren)) {
551 if (!ArgExprs.empty())
554 if (AttributeIsTypeArgAttr) {
562 TheParsedType =
T.get();
563 }
else if (AttributeHasVariadicIdentifierArg ||
573 if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
574 Tok.setKind(tok::identifier);
577 if (Tok.is(tok::identifier)) {
578 ArgExprs.push_back(ParseIdentifierLoc());
594 ArgExprs.push_back(ArgExpr.
get());
610 ExprVector ParsedExprs;
611 ParsedAttributeArgumentsProperties ArgProperties =
614 if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties,
621 for (
size_t I = 0; I < ParsedExprs.size(); ++I) {
626 Diag(Tok.getLocation(),
627 diag::err_attribute_argument_parm_pack_not_supported)
634 llvm::append_range(ArgExprs, ParsedExprs);
638 SourceLocation RParen = Tok.getLocation();
639 if (!ExpectAndConsume(tok::r_paren)) {
640 SourceLocation AttrLoc = ScopeLoc.
isValid() ? ScopeLoc : AttrNameLoc;
642 if (AttributeIsTypeArgAttr && !TheParsedType.
get().
isNull()) {
644 AttributeScopeInfo(ScopeName, ScopeLoc),
645 TheParsedType, Form);
647 Attrs.
addNew(AttrName, SourceRange(AttrLoc, RParen),
648 AttributeScopeInfo(ScopeName, ScopeLoc), ArgExprs.data(),
649 ArgExprs.size(), Form);
656 return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.
get().
isNull());
659void Parser::ParseGNUAttributeArgs(
664 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
669 if (AttrKind == ParsedAttr::AT_Availability) {
670 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
673 }
else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
674 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
675 ScopeName, ScopeLoc, Form);
677 }
else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
678 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
679 ScopeName, ScopeLoc, Form);
681 }
else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
682 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
685 }
else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
686 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
687 ScopeName, ScopeLoc, Form);
690 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName,
693 }
else if (AttrKind == ParsedAttr::AT_CountedBy ||
694 AttrKind == ParsedAttr::AT_CountedByOrNull ||
695 AttrKind == ParsedAttr::AT_SizedBy ||
696 AttrKind == ParsedAttr::AT_SizedByOrNull) {
697 ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
700 }
else if (AttrKind == ParsedAttr::AT_CXXAssume) {
701 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
702 ScopeLoc, EndLoc, Form);
708 std::optional<ParseScope> PrototypeScope;
713 const DeclaratorChunk::FunctionTypeInfo *FTI =
nullptr;
725 PrototypeScope.emplace(
729 for (
unsigned i = 0; i < FTI->
NumParams; ++i)
730 Actions.ActOnReenterCXXMethodParameter(
735 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
739unsigned Parser::ParseClangAttributeArgs(
743 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
750 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
751 ScopeName, ScopeLoc, Form);
752 case ParsedAttr::AT_ExternalSourceSymbol:
753 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
754 ScopeName, ScopeLoc, Form);
756 case ParsedAttr::AT_Availability:
757 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
760 case ParsedAttr::AT_ObjCBridgeRelated:
761 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
762 ScopeName, ScopeLoc, Form);
764 case ParsedAttr::AT_SwiftNewType:
765 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
768 case ParsedAttr::AT_TypeTagForDatatype:
769 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
770 ScopeName, ScopeLoc, Form);
773 case ParsedAttr::AT_CXXAssume:
774 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
775 ScopeLoc, EndLoc, Form);
778 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
784 unsigned ExistingAttrs = Attrs.
size();
796 SourceLocation OpenParenLoc = Tok.getLocation();
798 if (
AttrName->getName() ==
"property") {
804 T.expectAndConsume(diag::err_expected_lparen_after,
805 AttrName->getNameStart(), tok::r_paren);
812 IdentifierInfo *AccessorNames[] = {
nullptr,
nullptr};
813 bool HasInvalidAccessor =
false;
818 if (!Tok.is(tok::identifier)) {
820 if (Tok.is(tok::r_paren) && !HasInvalidAccessor &&
821 AccessorNames[AK_Put] ==
nullptr &&
822 AccessorNames[AK_Get] ==
nullptr) {
823 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
827 Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor);
832 SourceLocation KindLoc = Tok.getLocation();
833 StringRef KindStr = Tok.getIdentifierInfo()->getName();
834 if (KindStr ==
"get") {
836 }
else if (KindStr ==
"put") {
840 }
else if (KindStr ==
"set") {
841 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
848 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
850 HasInvalidAccessor =
true;
851 goto next_property_accessor;
855 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
856 HasInvalidAccessor =
true;
869 Diag(Tok.getLocation(), diag::err_ms_property_expected_equal)
875 if (!Tok.is(tok::identifier)) {
876 Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name);
880 if (Kind == AK_Invalid) {
882 }
else if (AccessorNames[Kind] !=
nullptr) {
884 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
886 AccessorNames[
Kind] = Tok.getIdentifierInfo();
890 next_property_accessor:
896 if (Tok.is(tok::r_paren))
899 Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen);
904 if (!HasInvalidAccessor)
906 AccessorNames[AK_Get], AccessorNames[AK_Put],
907 ParsedAttr::Form::Declspec());
909 return !HasInvalidAccessor;
913 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
914 SourceLocation(), ParsedAttr::Form::Declspec());
919 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) <<
AttrName;
926 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
927 assert(Tok.is(tok::kw___declspec) &&
"Not a declspec!");
929 SourceLocation StartLoc = Tok.getLocation();
930 SourceLocation EndLoc = StartLoc;
932 while (Tok.is(tok::kw___declspec)) {
935 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
941 while (Tok.isNot(tok::r_paren)) {
946 if (Tok.is(tok::code_completion)) {
948 Actions.CodeCompletion().CodeCompleteAttribute(
955 bool IsString = Tok.getKind() == tok::string_literal;
956 if (!IsString && Tok.getKind() != tok::identifier &&
957 Tok.getKind() != tok::kw_restrict) {
958 Diag(Tok, diag::err_ms_declspec_type);
964 SourceLocation AttrNameLoc;
966 SmallString<8> StrBuffer;
967 bool Invalid =
false;
968 StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
973 AttrName = PP.getIdentifierInfo(Str);
974 AttrNameLoc = ConsumeStringToken();
980 bool AttrHandled =
false;
983 if (Tok.is(tok::l_paren))
984 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
985 else if (
AttrName->getName() ==
"property")
987 Diag(Tok.getLocation(), diag::err_expected_lparen_after)
991 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
992 ParsedAttr::Form::Declspec());
995 EndLoc =
T.getCloseLocation();
998 Attrs.
Range = SourceRange(StartLoc, EndLoc);
1004 auto Kind = Tok.getKind();
1006 case tok::kw___fastcall:
1007 case tok::kw___stdcall:
1008 case tok::kw___thiscall:
1009 case tok::kw___regcall:
1010 case tok::kw___cdecl:
1011 case tok::kw___vectorcall:
1012 case tok::kw___ptr64:
1014 case tok::kw___ptr32:
1015 case tok::kw___sptr:
1016 case tok::kw___uptr: {
1017 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1019 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1029void Parser::ParseWebAssemblyFuncrefTypeAttribute(
ParsedAttributes &attrs) {
1030 assert(Tok.is(tok::kw___funcref));
1031 SourceLocation StartLoc = Tok.getLocation();
1034 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
1038 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1040 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr,
1041 0, tok::kw___funcref);
1044void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
1045 SourceLocation StartLoc = Tok.getLocation();
1046 SourceLocation EndLoc = SkipExtendedMicrosoftTypeAttributes();
1049 SourceRange
Range(StartLoc, EndLoc);
1050 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) <<
Range;
1055 SourceLocation EndLoc;
1058 switch (Tok.getKind()) {
1060 case tok::kw_volatile:
1061 case tok::kw___fastcall:
1062 case tok::kw___stdcall:
1063 case tok::kw___thiscall:
1064 case tok::kw___cdecl:
1065 case tok::kw___vectorcall:
1066 case tok::kw___ptr32:
1067 case tok::kw___ptr64:
1069 case tok::kw___unaligned:
1070 case tok::kw___sptr:
1071 case tok::kw___uptr:
1082 while (Tok.is(tok::kw___pascal)) {
1083 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1085 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1092 while (Tok.is(tok::kw___kernel)) {
1093 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1095 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1101 while (Tok.is(tok::kw___noinline__)) {
1102 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1104 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1105 tok::kw___noinline__);
1110 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1111 SourceLocation AttrNameLoc = Tok.getLocation();
1112 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1117 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1118 auto Kind = Tok.getKind();
1120 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0, Kind);
1126 auto Kind = Tok.getKind();
1128 case tok::kw__Nonnull:
1129 case tok::kw__Nullable:
1130 case tok::kw__Nullable_result:
1131 case tok::kw__Null_unspecified: {
1132 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1135 Diag(AttrNameLoc, diag::ext_nullability)
1137 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1148 return (Separator ==
'.' || Separator ==
'_');
1151VersionTuple Parser::ParseVersionTuple(
SourceRange &Range) {
1152 Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());
1154 if (!Tok.is(tok::numeric_constant)) {
1155 Diag(Tok, diag::err_expected_version);
1158 return VersionTuple();
1165 SmallString<512> Buffer;
1166 Buffer.resize(Tok.getLength()+1);
1167 const char *ThisTokBegin = &Buffer[0];
1170 bool Invalid =
false;
1171 unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);
1173 return VersionTuple();
1176 unsigned AfterMajor = 0;
1178 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
1179 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
1183 if (AfterMajor == 0) {
1184 Diag(Tok, diag::err_expected_version);
1187 return VersionTuple();
1190 if (AfterMajor == ActualLength) {
1195 Diag(Tok, diag::err_zero_version);
1196 return VersionTuple();
1199 return VersionTuple(Major);
1202 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1204 || (AfterMajor + 1 == ActualLength)) {
1205 Diag(Tok, diag::err_expected_version);
1208 return VersionTuple();
1212 unsigned AfterMinor = AfterMajor + 1;
1214 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
1215 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
1219 if (AfterMinor == ActualLength) {
1223 if (Major == 0 && Minor == 0) {
1224 Diag(Tok, diag::err_zero_version);
1225 return VersionTuple();
1228 return VersionTuple(Major, Minor);
1231 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1234 Diag(Tok, diag::err_expected_version);
1237 return VersionTuple();
1241 if (AfterMajorSeparator != AfterMinorSeparator)
1242 Diag(Tok, diag::warn_expected_consistent_version_separator);
1245 unsigned AfterSubminor = AfterMinor + 1;
1246 unsigned Subminor = 0;
1247 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
1248 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
1252 if (AfterSubminor != ActualLength) {
1253 Diag(Tok, diag::err_expected_version);
1256 return VersionTuple();
1259 return VersionTuple(Major, Minor, Subminor);
1262void Parser::ParseAvailabilityAttribute(
1266 enum { Introduced, Deprecated, Obsoleted,
Unknown };
1267 AvailabilityChange Changes[
Unknown];
1269 IdentifierLoc *EnvironmentLoc =
nullptr;
1273 if (
T.consumeOpen()) {
1274 Diag(Tok, diag::err_expected) << tok::l_paren;
1279 if (Tok.isNot(tok::identifier)) {
1280 Diag(Tok, diag::err_availability_expected_platform);
1284 IdentifierLoc *Platform = ParseIdentifierLoc();
1287 if (Ident->getName().contains(
"xrOS") || Ident->getName().contains(
"xros"))
1288 Diag(Platform->
getLoc(), diag::warn_availability_unknown_platform)
1291 else if (Ident->getName() ==
"macosx")
1295 else if (Ident->getName() ==
"macosx_app_extension")
1299 AvailabilityAttr::canonicalizePlatformName(Ident->getName())));
1303 if (ExpectAndConsume(tok::comma)) {
1310 if (!Ident_introduced) {
1311 Ident_introduced = PP.getIdentifierInfo(
"introduced");
1312 Ident_deprecated = PP.getIdentifierInfo(
"deprecated");
1313 Ident_obsoleted = PP.getIdentifierInfo(
"obsoleted");
1314 Ident_unavailable = PP.getIdentifierInfo(
"unavailable");
1315 Ident_message = PP.getIdentifierInfo(
"message");
1316 Ident_strict = PP.getIdentifierInfo(
"strict");
1317 Ident_replacement = PP.getIdentifierInfo(
"replacement");
1318 Ident_environment = PP.getIdentifierInfo(
"environment");
1323 SourceLocation UnavailableLoc, StrictLoc;
1325 if (Tok.isNot(tok::identifier)) {
1326 Diag(Tok, diag::err_availability_expected_change);
1330 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1333 if (
Keyword == Ident_strict) {
1335 Diag(KeywordLoc, diag::err_availability_redundant)
1336 <<
Keyword << SourceRange(StrictLoc);
1338 StrictLoc = KeywordLoc;
1342 if (
Keyword == Ident_unavailable) {
1343 if (UnavailableLoc.
isValid()) {
1344 Diag(KeywordLoc, diag::err_availability_redundant)
1345 <<
Keyword << SourceRange(UnavailableLoc);
1347 UnavailableLoc = KeywordLoc;
1354 if (Changes[Deprecated].KeywordLoc.
isValid()) {
1355 Diag(KeywordLoc, diag::err_availability_redundant)
1357 << SourceRange(Changes[Deprecated].KeywordLoc);
1362 Changes[Deprecated].
Version = VersionTuple(1);
1366 if (
Keyword == Ident_environment) {
1367 if (EnvironmentLoc !=
nullptr) {
1368 Diag(KeywordLoc, diag::err_availability_redundant)
1373 if (Tok.isNot(tok::equal)) {
1374 Diag(Tok, diag::err_expected_after) <<
Keyword << tok::equal;
1380 if (!isTokenStringLiteral()) {
1381 Diag(Tok, diag::err_expected_string_literal)
1386 if (
Keyword == Ident_message) {
1394 if (
Keyword == Ident_environment) {
1395 if (Tok.isNot(tok::identifier)) {
1396 Diag(Tok, diag::err_availability_expected_environment);
1400 EnvironmentLoc = ParseIdentifierLoc();
1406 if ((
Keyword == Ident_introduced ||
Keyword == Ident_deprecated) &&
1407 Tok.is(tok::identifier)) {
1408 IdentifierInfo *NA = Tok.getIdentifierInfo();
1411 if (
Keyword == Ident_introduced)
1412 UnavailableLoc = KeywordLoc;
1417 SourceRange VersionRange;
1418 VersionTuple Version = ParseVersionTuple(VersionRange);
1420 if (Version.empty()) {
1426 if (
Keyword == Ident_introduced)
1428 else if (
Keyword == Ident_deprecated)
1430 else if (
Keyword == Ident_obsoleted)
1436 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1437 Diag(KeywordLoc, diag::err_availability_redundant)
1439 << SourceRange(Changes[Index].KeywordLoc,
1440 Changes[Index].VersionRange.
getEnd());
1444 Changes[Index].
Version = Version;
1447 Diag(KeywordLoc, diag::err_availability_unknown_change)
1454 if (
T.consumeClose())
1458 *endLoc =
T.getCloseLocation();
1462 if (UnavailableLoc.
isValid()) {
1463 bool Complained =
false;
1464 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1465 if (Changes[Index].KeywordLoc.
isValid()) {
1467 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1468 << SourceRange(Changes[Index].KeywordLoc,
1469 Changes[Index].VersionRange.
getEnd());
1474 Changes[Index] = AvailabilityChange();
1480 attrs.
addNew(&Availability,
1481 SourceRange(AvailabilityLoc,
T.getCloseLocation()),
1482 AttributeScopeInfo(ScopeName, ScopeLoc), Platform,
1483 Changes[Introduced], Changes[Deprecated], Changes[Obsoleted],
1484 UnavailableLoc, MessageExpr.
get(), Form, StrictLoc,
1485 ReplacementExpr.
get(), EnvironmentLoc);
1488void Parser::ParseExternalSourceSymbolAttribute(
1494 if (
T.expectAndConsume())
1498 if (!Ident_language) {
1499 Ident_language = PP.getIdentifierInfo(
"language");
1500 Ident_defined_in = PP.getIdentifierInfo(
"defined_in");
1501 Ident_generated_declaration = PP.getIdentifierInfo(
"generated_declaration");
1502 Ident_USR = PP.getIdentifierInfo(
"USR");
1506 bool HasLanguage =
false;
1508 bool HasDefinedIn =
false;
1509 IdentifierLoc *GeneratedDeclaration =
nullptr;
1511 bool HasUSR =
false;
1515 if (Tok.isNot(tok::identifier)) {
1516 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1521 SourceLocation KeywordLoc = Tok.getLocation();
1522 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1523 if (
Keyword == Ident_generated_declaration) {
1524 if (GeneratedDeclaration) {
1525 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) <<
Keyword;
1529 GeneratedDeclaration = ParseIdentifierLoc();
1535 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1541 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1547 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1549 if (
Keyword == Ident_language)
1551 else if (
Keyword == Ident_USR)
1554 HasDefinedIn =
true;
1556 if (!isTokenStringLiteral()) {
1557 Diag(Tok, diag::err_expected_string_literal)
1562 : (
Keyword == Ident_defined_in ? 1 : 2));
1566 if (
Keyword == Ident_language) {
1568 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1574 }
else if (
Keyword == Ident_USR) {
1576 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1583 assert(
Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1585 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1595 if (
T.consumeClose())
1598 *EndLoc =
T.getCloseLocation();
1602 Attrs.
addNew(&ExternalSourceSymbol, SourceRange(Loc,
T.getCloseLocation()),
1603 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1607void Parser::ParseObjCBridgeRelatedAttribute(
1613 if (
T.consumeOpen()) {
1614 Diag(Tok, diag::err_expected) << tok::l_paren;
1619 if (Tok.isNot(tok::identifier)) {
1620 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1624 IdentifierLoc *RelatedClass = ParseIdentifierLoc();
1625 if (ExpectAndConsume(tok::comma)) {
1634 if (Tok.is(tok::identifier)) {
1637 Diag(Tok, diag::err_objcbridge_related_selector_name);
1643 if (Tok.is(tok::colon))
1644 Diag(Tok, diag::err_objcbridge_related_selector_name);
1646 Diag(Tok, diag::err_expected) << tok::comma;
1654 if (Tok.is(tok::identifier))
1656 else if (Tok.isNot(tok::r_paren)) {
1657 Diag(Tok, diag::err_expected) << tok::r_paren;
1663 if (
T.consumeClose())
1667 *EndLoc =
T.getCloseLocation();
1670 Attrs.
addNew(&ObjCBridgeRelated,
1671 SourceRange(ObjCBridgeRelatedLoc,
T.getCloseLocation()),
1672 AttributeScopeInfo(ScopeName, ScopeLoc), RelatedClass,
1673 ClassMethod, InstanceMethod, Form);
1676void Parser::ParseSwiftNewTypeAttribute(
1683 if (
T.consumeOpen()) {
1684 Diag(Tok, diag::err_expected) << tok::l_paren;
1688 if (Tok.is(tok::r_paren)) {
1689 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
1693 if (Tok.isNot(tok::kw_struct) && Tok.isNot(tok::kw_enum)) {
1694 Diag(Tok, diag::warn_attribute_type_not_supported)
1695 << &
AttrName << Tok.getIdentifierInfo();
1696 if (!isTokenSpecial())
1702 auto *SwiftType =
new (Actions.Context)
1703 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
1707 if (
T.consumeClose())
1710 *EndLoc =
T.getCloseLocation();
1713 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
T.getCloseLocation()),
1714 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1718void Parser::ParseTypeTagForDatatypeAttribute(
1722 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1727 if (Tok.isNot(tok::identifier)) {
1728 Diag(Tok, diag::err_expected) << tok::identifier;
1732 IdentifierLoc *ArgumentKind = ParseIdentifierLoc();
1734 if (ExpectAndConsume(tok::comma)) {
1739 SourceRange MatchingCTypeRange;
1746 bool LayoutCompatible =
false;
1747 bool MustBeNull =
false;
1749 if (Tok.isNot(tok::identifier)) {
1750 Diag(Tok, diag::err_expected) << tok::identifier;
1754 IdentifierInfo *Flag = Tok.getIdentifierInfo();
1755 if (Flag->
isStr(
"layout_compatible"))
1756 LayoutCompatible =
true;
1757 else if (Flag->
isStr(
"must_be_null"))
1760 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1767 if (!
T.consumeClose()) {
1769 &AttrName, AttrNameLoc, AttributeScopeInfo(ScopeName, ScopeLoc),
1770 ArgumentKind, MatchingCType.
get(), LayoutCompatible, MustBeNull, Form);
1774 *EndLoc =
T.getCloseLocation();
1777bool Parser::DiagnoseProhibitedCXX11Attribute() {
1778 assert(Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square));
1780 switch (isCXX11AttributeSpecifier(
true)) {
1786 Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1791 SourceLocation BeginLoc = ConsumeBracket();
1794 assert(Tok.is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1795 SourceLocation EndLoc = ConsumeBracket();
1796 Diag(BeginLoc, diag::err_attributes_not_allowed)
1797 << SourceRange(BeginLoc, EndLoc);
1800 llvm_unreachable(
"All cases handled above.");
1805 assert((Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square)) ||
1806 Tok.is(tok::kw_alignas) || Tok.isRegularKeywordAttribute());
1810 Tok.isRegularKeywordAttribute() ? Tok.getIdentifierInfo() :
nullptr;
1811 SourceLocation Loc = Tok.getLocation();
1812 ParseCXX11Attributes(Attrs);
1813 CharSourceRange AttrRange(SourceRange(Loc, Attrs.
Range.
getEnd()),
true);
1816 :
Diag(Loc, diag::err_attributes_not_allowed))
1821void Parser::DiagnoseProhibitedAttributes(
1824 if (CorrectLocation.
isValid()) {
1825 CharSourceRange AttrRange(Attrs.
Range,
true);
1826 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1827 ?
Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1828 :
Diag(CorrectLocation, diag::err_attributes_misplaced))
1833 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1834 ?
Diag(
Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr
1835 :
Diag(
Range.getBegin(), diag::err_attributes_not_allowed))
1841 unsigned AttrDiagID,
1842 unsigned KeywordDiagID,
1843 bool DiagnoseEmptyAttrs,
1844 bool WarnOnUnknownAttrs) {
1850 auto &SM = PP.getSourceManager();
1854 if (FirstLSquare.
is(tok::l_square)) {
1855 std::optional<Token> SecondLSquare =
1858 if (SecondLSquare && SecondLSquare->is(tok::l_square)) {
1868 for (
const ParsedAttr &AL : Attrs) {
1869 if (AL.isRegularKeywordAttribute()) {
1870 Diag(AL.getLoc(), KeywordDiagID) << AL;
1874 if (!AL.isStandardAttributeSyntax())
1877 if (WarnOnUnknownAttrs) {
1878 Actions.DiagnoseUnknownAttribute(AL);
1882 Diag(AL.getLoc(), AttrDiagID) << AL;
1889 for (
const ParsedAttr &PA : Attrs) {
1890 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1891 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1892 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
1901 llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;
1904 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1905 AL.isDeclspecAttribute()) ||
1906 AL.isMicrosoftAttribute())
1907 ToBeMoved.push_back(&AL);
1910 for (ParsedAttr *AL : ToBeMoved) {
1924 ObjCDeclContextSwitch ObjCDC(*
this);
1926 Decl *SingleDecl =
nullptr;
1927 switch (Tok.getKind()) {
1928 case tok::kw_template:
1929 case tok::kw_export:
1930 ProhibitAttributes(DeclAttrs);
1931 ProhibitAttributes(DeclSpecAttrs);
1932 return ParseDeclarationStartingWithTemplate(Context, DeclEnd, DeclAttrs);
1933 case tok::kw_inline:
1936 ProhibitAttributes(DeclAttrs);
1937 ProhibitAttributes(DeclSpecAttrs);
1939 return ParseNamespace(Context, DeclEnd, InlineLoc);
1941 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1942 true,
nullptr, DeclSpecStart);
1944 case tok::kw_cbuffer:
1945 case tok::kw_tbuffer:
1946 SingleDecl = ParseHLSLBuffer(DeclEnd, DeclAttrs);
1948 case tok::kw_namespace:
1949 ProhibitAttributes(DeclAttrs);
1950 ProhibitAttributes(DeclSpecAttrs);
1951 return ParseNamespace(Context, DeclEnd);
1952 case tok::kw_using: {
1954 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1955 DeclEnd, DeclAttrs);
1957 case tok::kw_static_assert:
1958 case tok::kw__Static_assert:
1959 ProhibitAttributes(DeclAttrs);
1960 ProhibitAttributes(DeclSpecAttrs);
1961 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1964 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1965 true,
nullptr, DeclSpecStart);
1970 return Actions.ConvertDeclToDeclGroup(SingleDecl);
1976 bool RequireSemi, ForRangeInit *FRI,
SourceLocation *DeclSpecStart) {
1978 ParsedAttributesView OriginalDeclSpecAttrs;
1979 OriginalDeclSpecAttrs.
prepend(DeclSpecAttrs.
begin(), DeclSpecAttrs.
end());
1980 OriginalDeclSpecAttrs.
Range = DeclSpecAttrs.
Range;
1983 ParsingDeclSpec DS(*
this);
1986 ParsedTemplateInfo TemplateInfo;
1987 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
1988 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none, DSContext);
1993 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
1998 if (Tok.is(tok::semi)) {
1999 ProhibitAttributes(DeclAttrs);
2000 DeclEnd = Tok.getLocation();
2002 RecordDecl *AnonRecord =
nullptr;
2003 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
2005 Actions.ActOnDefinedDeclarationSpecifier(TheDecl);
2006 DS.complete(TheDecl);
2008 Decl* decls[] = {AnonRecord, TheDecl};
2009 return Actions.BuildDeclaratorGroup(decls);
2011 return Actions.ConvertDeclToDeclGroup(TheDecl);
2015 Actions.ActOnDefinedDeclarationSpecifier(DS.
getRepAsDecl());
2020 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
2024 switch (Tok.getKind()) {
2025 case tok::annot_cxxscope:
2026 case tok::annot_template_id:
2028 case tok::code_completion:
2029 case tok::coloncolon:
2031 case tok::kw___attribute:
2032 case tok::kw_operator:
2048 case tok::identifier:
2050 case tok::code_completion:
2051 case tok::coloncolon:
2054 case tok::equalequal:
2055 case tok::kw_alignas:
2057 case tok::kw___attribute:
2075 case tok::identifier:
2079 return Tok.isRegularKeywordAttribute();
2083 return Tok.isRegularKeywordAttribute();
2089 switch (Tok.getKind()) {
2095 if (Tok.isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
2119 case tok::kw_inline:
2123 if (Tok.isAtStartOfLine() &&
NextToken().
is(tok::kw_namespace) &&
2124 (!ParsingInObjCContainer || CurParsedObjCImpl))
2128 case tok::kw_extern:
2131 case tok::kw_namespace:
2135 if (Tok.isAtStartOfLine() &&
2136 (!ParsingInObjCContainer || CurParsedObjCImpl))
2142 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2143 ParsingInObjCContainer)
2150 if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
2155 case tok::annot_module_begin:
2156 case tok::annot_module_end:
2157 case tok::annot_module_include:
2158 case tok::annot_repl_input_end:
2172 ParsedTemplateInfo &TemplateInfo,
2174 ForRangeInit *FRI) {
2180 LocalAttrs.takeAllPrependingFrom(Attrs);
2182 if (TemplateInfo.TemplateParams)
2185 bool IsTemplateSpecOrInst =
2192 if (IsTemplateSpecOrInst)
2202 while (MaybeParseHLSLAnnotations(D))
2205 if (
Tok.is(tok::kw_requires)) {
2206 TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
2210 ++CurTemplateDepthTracker;
2211 ParseTrailingRequiresClauseWithScope(D);
2217 LateParsedAttrList LateParsedAttrs(
true);
2219 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2224 if (Tok.is(tok::kw__Noreturn)) {
2226 const char *PrevSpec;
2232 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2233 Fixit &= Tok.isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2235 Diag(Loc, diag::err_c11_noreturn_misplaced)
2237 << (Fixit ? FixItHint::CreateInsertion(D.getBeginLoc(),
"_Noreturn ")
2242 if (Tok.is(tok::equal) &&
NextToken().
is(tok::code_completion)) {
2244 Actions.CodeCompletion().CodeCompleteAfterFunctionEquals(D);
2253 while (
auto Specifier = isCXX11VirtSpecifier()) {
2254 Diag(Tok, diag::err_virt_specifier_outside_class)
2262 if (!isDeclarationAfterDeclarator()) {
2268 if (isStartOfFunctionDefinition(D)) {
2278 diag::err_function_declared_typedef)
2282 Decl *TheDecl =
nullptr;
2288 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2289 TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(),
2292 SourceLocation LAngleLoc =
2293 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2295 diag::err_explicit_instantiation_with_definition)
2296 << SourceRange(TemplateInfo.TemplateLoc)
2301 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2302 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
2303 LAngleLoc,
nullptr));
2305 TheDecl = ParseFunctionDefinition(
2307 ParsedTemplateInfo(&FakedParamLists,
2314 ParseFunctionDefinition(D, TemplateInfo, &LateParsedAttrs);
2317 return Actions.ConvertDeclToDeclGroup(TheDecl);
2321 Tok.is(tok::kw_namespace)) {
2331 Diag(Tok, diag::err_expected_fn_body);
2336 if (Tok.is(tok::l_brace)) {
2337 Diag(Tok, diag::err_function_definition_not_allowed);
2345 if (ParseAsmAttributesAfterDeclarator(D))
2354 if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
2367 bool EnterContext = FRI->ExpansionStmt &&
2368 Actions.CurContext == FRI->ExpansionStmt->getParent();
2370 Actions.PushDeclContext(
nullptr, FRI->ExpansionStmt);
2371 llvm::scope_exit RestoreDeclContext{[&] {
2373 Actions.PopDeclContext();
2376 bool IsForRangeLoopOrExpansionStmt =
false;
2378 IsForRangeLoopOrExpansionStmt =
true;
2380 Actions.OpenMP().startOpenMPCXXRangeFor();
2382 ParseForRangeInitializerAfterColon(*FRI, &DS);
2386 if (IsForRangeLoopOrExpansionStmt) {
2387 Actions.ActOnCXXForRangeDecl(ThisDecl, FRI->ExpansionStmt);
2390 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2391 VD->setObjCForDecl(
true);
2393 Actions.FinalizeDeclaration(ThisDecl);
2394 D.complete(ThisDecl);
2395 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, ThisDecl);
2398 SmallVector<Decl *, 8> DeclsInGroup;
2400 ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo, FRI);
2401 if (LateParsedAttrs.size() > 0)
2402 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2403 D.complete(FirstDecl);
2405 DeclsInGroup.push_back(FirstDecl);
2411 SourceLocation CommaLoc;
2413 if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2417 Diag(CommaLoc, diag::err_expected_semi_declaration)
2429 Diag(CommaLoc, diag::err_multiple_template_declarators)
2430 << TemplateInfo.Kind;
2444 MaybeParseGNUAttributes(D);
2448 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2453 MaybeParseHLSLAnnotations(D);
2460 if (Tok.is(tok::kw_requires))
2461 ParseTrailingRequiresClauseWithScope(D);
2462 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D, TemplateInfo);
2463 D.complete(ThisDecl);
2465 DeclsInGroup.push_back(ThisDecl);
2470 *DeclEnd = Tok.getLocation();
2472 if (ExpectSemi && ExpectAndConsumeSemi(
2474 ? diag::err_invalid_token_after_toplevel_declarator
2475 : diag::err_expected_semi_declaration)) {
2483 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
2486bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &D) {
2488 if (Tok.is(tok::kw_asm)) {
2490 ExprResult AsmLabel(ParseSimpleAsm(
true, &Loc));
2491 if (AsmLabel.isInvalid()) {
2500 MaybeParseGNUAttributes(D);
2504Decl *Parser::ParseDeclarationAfterDeclarator(
2505 Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
2506 if (ParseAsmAttributesAfterDeclarator(D))
2509 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
2512Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2513 Declarator &D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2515 struct InitializerScopeRAII {
2521 InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl)
2522 : P(P), D(D), ThisDecl(ThisDecl), Entered(
false) {
2525 if (D.getCXXScopeSpec().isSet()) {
2527 S = P.getCurScope();
2530 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2535 ~InitializerScopeRAII() {
2551 InitKind TheInitKind;
2553 if (isTokenEqualOrEqualTypo())
2554 TheInitKind = InitKind::Equal;
2556 TheInitKind = InitKind::CXXDirect;
2559 TheInitKind = InitKind::CXXBraced;
2561 TheInitKind = InitKind::Uninitialized;
2562 if (TheInitKind != InitKind::Uninitialized)
2566 Decl *ThisDecl =
nullptr;
2567 Decl *OuterDecl =
nullptr;
2568 switch (TemplateInfo.Kind) {
2570 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2575 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
2576 *TemplateInfo.TemplateParams,
2578 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2581 ThisDecl = VT->getTemplatedDecl();
2587 if (
Tok.
is(tok::semi)) {
2588 DeclResult ThisRes = Actions.ActOnExplicitInstantiation(
2589 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
2591 SkipUntil(tok::semi, StopBeforeMatch);
2594 ThisDecl = ThisRes.
get();
2602 Diag(
Tok, diag::err_template_defn_explicit_instantiation)
2604 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2607 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2609 diag::err_explicit_instantiation_with_definition)
2614 TemplateParameterLists FakedParamLists;
2615 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2617 LAngleLoc,
nullptr));
2620 Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D);
2629 switch (TheInitKind) {
2631 case InitKind::Equal: {
2634 if (
Tok.
is(tok::kw_delete)) {
2636 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2639 Diag(ConsumeToken(), diag::err_deleted_non_function);
2640 SkipDeletedFunctionBody();
2641 }
else if (
Tok.
is(tok::kw_default)) {
2643 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2646 Diag(ConsumeToken(), diag::err_default_special_members)
2647 << getLangOpts().CPlusPlus20;
2649 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2651 if (
Tok.
is(tok::code_completion)) {
2653 Actions.CodeCompletion().CodeCompleteInitializer(getCurScope(),
2655 Actions.FinalizeDeclaration(ThisDecl);
2665 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2669 FRI->ColonLoc = EqualLoc;
2671 FRI->RangeExpr =
Init;
2674 if (
Init.isInvalid()) {
2676 StopTokens.push_back(tok::comma);
2679 StopTokens.push_back(tok::r_paren);
2680 SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch);
2681 Actions.ActOnInitializerError(ThisDecl);
2683 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
2688 case InitKind::CXXDirect: {
2695 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2697 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2698 auto RunSignatureHelp = [&]() {
2700 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2701 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2704 CalledSignatureHelp =
true;
2705 return PreferredType;
2707 auto SetPreferredType = [&] {
2708 PreferredType.enterFunctionArgument(
Tok.
getLocation(), RunSignatureHelp);
2711 llvm::function_ref<void()> ExpressionStarts;
2717 ExpressionStarts = SetPreferredType;
2720 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2723 if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
2724 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2725 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2728 CalledSignatureHelp =
true;
2730 Actions.ActOnInitializerError(ThisDecl);
2731 SkipUntil(tok::r_paren, StopAtSemi);
2737 T.getCloseLocation(),
2739 Actions.AddInitializerToDecl(ThisDecl,
Initializer.get(),
2744 case InitKind::CXXBraced: {
2746 Diag(
Tok, diag::compat_cxx11_generalized_initializer_lists);
2748 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2753 if (
Init.isInvalid()) {
2754 Actions.ActOnInitializerError(ThisDecl);
2756 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
true);
2759 case InitKind::Uninitialized: {
2760 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2761 Actions.ActOnUninitializedDecl(ThisDecl);
2766 Actions.FinalizeDeclaration(ThisDecl);
2767 return OuterDecl ? OuterDecl : ThisDecl;
2770void Parser::ParseSpecifierQualifierList(
2773 ParsedTemplateInfo TemplateInfo;
2777 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC,
nullptr,
2778 AllowImplicitTypename);
2783 Diag(Tok, diag::err_expected_type);
2786 Diag(Tok, diag::err_typename_requires_specqual);
2797 diag::err_typename_invalid_storageclass);
2841 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2842 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2847 ParsedTemplateInfo &TemplateInfo,
2850 assert(Tok.is(tok::identifier) &&
"should have identifier");
2852 SourceLocation Loc = Tok.getLocation();
2872 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
2890 AnnotateScopeToken(*SS,
false);
2899 if (
ParsedType T = Actions.ActOnMSVCUnknownTypeName(
2900 *Tok.getIdentifierInfo(), Tok.getLocation(),
2901 DSC == DeclSpecContext::DSC_template_type_arg)) {
2902 const char *PrevSpec;
2905 Actions.getASTContext().getPrintingPolicy());
2918 if (SS ==
nullptr) {
2919 const char *TagName =
nullptr, *FixitTagName =
nullptr;
2922 switch (Actions.isTagName(*Tok.getIdentifierInfo(),
getCurScope())) {
2925 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
2927 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
2929 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
2931 TagName=
"__interface"; FixitTagName =
"__interface ";
2932 TagKind=tok::kw___interface;
break;
2934 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
2938 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
2939 LookupResult
R(Actions, TokenName, SourceLocation(),
2942 Diag(Loc, diag::err_use_of_tag_name_without_tag)
2943 << TokenName << TagName <<
getLangOpts().CPlusPlus
2949 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2950 << TokenName << TagName;
2954 if (TagKind == tok::kw_enum)
2955 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,
2956 DeclSpecContext::DSC_normal);
2958 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
2960 DeclSpecContext::DSC_normal, Attrs);
2967 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
2968 DSC == DeclSpecContext::DSC_class)) {
2972 case tok::l_paren: {
2979 TentativeParsingAction PA(*
this);
2981 TPResult TPR = TryParseDeclarator(
false);
2984 if (TPR != TPResult::False) {
2992 if (DSC == DeclSpecContext::DSC_class ||
2993 (DSC == DeclSpecContext::DSC_top_level && SS)) {
2994 IdentifierInfo *II = Tok.getIdentifierInfo();
2995 if (Actions.isCurrentClassNameTypo(II, SS)) {
2996 Diag(Loc, diag::err_constructor_bad_name)
2997 << Tok.getIdentifierInfo() << II
2999 Tok.setIdentifierInfo(II);
3017 AnnotateScopeToken(*SS,
false);
3031 IdentifierInfo *II = Tok.getIdentifierInfo();
3033 Actions.DiagnoseUnknownTypeName(II, Loc,
getCurScope(), SS,
T,
3039 const char *PrevSpec;
3042 Actions.getASTContext().getPrintingPolicy());
3047 }
else if (II != Tok.getIdentifierInfo()) {
3060 if (IsTemplateName) {
3061 SourceLocation LAngle, RAngle;
3062 TemplateArgList Args;
3063 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3072Parser::DeclSpecContext
3076 return DeclSpecContext::DSC_class;
3078 return DeclSpecContext::DSC_top_level;
3080 return DeclSpecContext::DSC_template_param;
3082 return DeclSpecContext::DSC_template_arg;
3084 return DeclSpecContext::DSC_template_type_arg;
3087 return DeclSpecContext::DSC_trailing;
3090 return DeclSpecContext::DSC_alias_declaration;
3092 return DeclSpecContext::DSC_association;
3094 return DeclSpecContext::DSC_type_specifier;
3096 return DeclSpecContext::DSC_condition;
3098 return DeclSpecContext::DSC_conv_operator;
3100 return DeclSpecContext::DSC_new;
3115 return DeclSpecContext::DSC_normal;
3118 llvm_unreachable(
"Missing DeclaratorContext case");
3125 if (isTypeIdInParens()) {
3126 SourceLocation TypeLoc = Tok.getLocation();
3128 SourceRange TypeRange(Start, Tok.getLocation());
3129 if (Actions.ActOnAlignasTypeArgument(KWName, Ty, TypeLoc, TypeRange))
3146 assert(Tok.isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3147 "Not an alignment-specifier!");
3154 if (
T.expectAndConsume())
3159 SourceLocation EllipsisLoc;
3161 ParseAlignArgument(PP.getSpelling(KWTok),
T.getOpenLocation(),
3170 *EndLoc =
T.getCloseLocation();
3177 ArgExprs.push_back(ArgExpr.
get());
3178 Attrs.
addNew(KWName, KWLoc, AttributeScopeInfo(), ArgExprs.data(), 1, Kind,
3183void Parser::DistributeCLateParsedAttrs(
Decl *Dcl,
3189 for (
auto *LateAttr : *LateAttrs) {
3190 if (LateAttr->Decls.empty())
3191 LateAttr->addDecl(Dcl);
3197 assert(Tok.is(tok::kw___ptrauth));
3199 IdentifierInfo *KwName = Tok.getIdentifierInfo();
3203 if (
T.expectAndConsume())
3213 ArgExprs.push_back(ER.
get());
3217 SourceLocation EndLoc =
T.getCloseLocation();
3219 if (ArgExprs.empty() || ArgExprs.size() > 3) {
3220 Diag(KwLoc, diag::err_ptrauth_qualifier_bad_arg_count);
3224 Attrs.
addNew(KwName, SourceRange(KwLoc, EndLoc), AttributeScopeInfo(),
3225 ArgExprs.data(), ArgExprs.size(),
3226 ParsedAttr::Form::Keyword(
false,
3236 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3241 if (Tok.is(tok::r_paren)) {
3242 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
3249 using ExpressionKind =
3251 EnterExpressionEvaluationContext EC(
3253 ExpressionKind::EK_AttrArgument);
3261 ArgExprs.push_back(ArgExpr.
get());
3264 ASTContext &Ctx = Actions.getASTContext();
3270 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
3271 AttributeScopeInfo(), ArgExprs.data(), ArgExprs.size(), Form);
3274ExprResult Parser::ParseExtIntegerArgument() {
3275 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3276 "Not an extended int type");
3280 if (
T.expectAndConsume())
3289 if(
T.consumeClose())
3296 DeclSpecContext DSContext,
3300 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3301 DSContext == DeclSpecContext::DSC_top_level);
3304 (Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype) ||
3305 (Tok.is(tok::annot_template_id) &&
NextToken().
is(tok::coloncolon))) &&
3311 bool HasScope = Tok.is(tok::annot_cxxscope);
3313 Token AfterScope = HasScope ?
NextToken() : Tok;
3317 bool MightBeDeclarator =
true;
3318 if (Tok.isOneOf(tok::kw_typename, tok::annot_typename)) {
3320 MightBeDeclarator =
false;
3321 }
else if (AfterScope.
is(tok::annot_template_id)) {
3324 TemplateIdAnnotation *Annot =
3327 MightBeDeclarator =
false;
3328 }
else if (AfterScope.
is(tok::identifier)) {
3333 if (
Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3334 tok::annot_cxxscope, tok::coloncolon)) {
3336 MightBeDeclarator = false;
3337 }
else if (HasScope) {
3342 Actions.RestoreNestedNameSpecifierAnnotation(
3343 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
3345 Sema::NameClassification Classification = Actions.ClassifyName(
3348 switch (Classification.
getKind()) {
3354 llvm_unreachable(
"typo correction is not possible here");
3362 MightBeDeclarator =
false;
3377 if (MightBeDeclarator)
3380 const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
3382 diag::err_expected_after)
3393 ParsedTemplateInfo NotATemplate;
3394 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3398void Parser::ParseDeclarationSpecifiers(
3412 if (DSContext == DeclSpecContext::DSC_conv_operator)
3413 DSContext = DeclSpecContext::DSC_type_specifier;
3415 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3416 DSContext == DeclSpecContext::DSC_top_level);
3417 bool AttrsLastTime =
false;
3418 ParsedAttributes attrs(AttrFactory);
3420 PrintingPolicy Policy = Actions.getPrintingPolicy();
3423 bool isStorageClass =
false;
3424 const char *PrevSpec =
nullptr;
3425 unsigned DiagID = 0;
3429 SourceLocation ConsumedEnd;
3438 if (
getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&
3441 Tok.setKind(tok::identifier);
3443 SourceLocation Loc = Tok.getLocation();
3446 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3450 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
3451 Tok.setKind(tok::identifier);
3460 bool IsTemplateSpecOrInst =
3464 switch (Tok.getKind()) {
3466 if (Tok.isRegularKeywordAttribute())
3471 ProhibitAttributes(attrs);
3474 for (
const ParsedAttr &PA : attrs) {
3475 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3476 !PA.isRegularKeywordAttribute())
3484 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3485 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3492 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3493 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3496 if (PA.getKind() == ParsedAttr::AT_LifetimeBound)
3497 Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type)
3498 << PA << PA.isRegularKeywordAttribute()
3501 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3502 << PA << PA.isRegularKeywordAttribute();
3511 DS.
Finish(Actions, Policy);
3515 case tok::kw__Alignas:
3516 diagnoseUseOfC11Keyword(Tok);
3518 case tok::kw_alignas:
3524 if (Tok.getKind() == tok::kw_alignas)
3525 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
3531 if (!isAllowedCXX11AttributeSpecifier())
3532 goto DoneWithDeclSpec;
3535 ProhibitAttributes(attrs);
3540 attrs.Range = SourceRange();
3542 ParseCXX11Attributes(attrs);
3543 AttrsLastTime =
true;
3546 case tok::code_completion: {
3550 bool AllowNonIdentifiers
3556 bool AllowNestedNameSpecifiers
3557 = DSContext == DeclSpecContext::DSC_top_level ||
3561 Actions.CodeCompletion().CodeCompleteDeclSpec(
3562 getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3568 CCC = DSContext == DeclSpecContext::DSC_class
3571 else if (DSContext == DeclSpecContext::DSC_class)
3575 else if (CurParsedObjCImpl)
3579 Actions.CodeCompletion().CodeCompleteOrdinaryName(
getCurScope(), CCC);
3583 case tok::coloncolon:
3589 goto DoneWithDeclSpec;
3591 if (Tok.is(tok::coloncolon))
3592 goto DoneWithDeclSpec;
3595 case tok::annot_cxxscope: {
3597 goto DoneWithDeclSpec;
3600 if (TemplateInfo.TemplateParams)
3602 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
3603 Tok.getAnnotationRange(),
3609 TemplateIdAnnotation *TemplateId =
Next.is(tok::annot_template_id)
3610 ? takeTemplateIdAnnotation(
Next)
3616 ConsumeAnnotationToken();
3630 if ((DSContext == DeclSpecContext::DSC_top_level ||
3631 DSContext == DeclSpecContext::DSC_class) &&
3634 isConstructorDeclarator(
false,
3641 goto DoneWithDeclSpec;
3645 ConsumeAnnotationToken();
3646 assert(Tok.is(tok::annot_template_id) &&
3647 "ParseOptionalCXXScopeSpecifier not working");
3648 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3658 ConsumeAnnotationToken();
3662 if (
Next.is(tok::annot_typename)) {
3664 ConsumeAnnotationToken();
3667 Tok.getAnnotationEndLoc(),
3668 PrevSpec, DiagID,
T, Policy);
3672 ConsumeAnnotationToken();
3676 Next.is(tok::annot_template_id) &&
3677 static_cast<TemplateIdAnnotation *
>(
Next.getAnnotationValue())
3680 ConsumeAnnotationToken();
3681 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3685 if (
Next.isNot(tok::identifier))
3686 goto DoneWithDeclSpec;
3691 if ((DSContext == DeclSpecContext::DSC_top_level ||
3692 DSContext == DeclSpecContext::DSC_class) &&
3695 isConstructorDeclarator(
false,
3699 goto DoneWithDeclSpec;
3705 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3709 false,
false,
nullptr,
3712 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3714 if (IsTemplateSpecOrInst)
3722 if (TryAnnotateTypeConstraint())
3723 goto DoneWithDeclSpec;
3724 if (Tok.isNot(tok::annot_cxxscope) ||
3728 ConsumeAnnotationToken();
3729 ParsedAttributes Attrs(AttrFactory);
3730 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3731 if (!Attrs.
empty()) {
3732 AttrsLastTime =
true;
3733 attrs.takeAllAppendingFrom(Attrs);
3737 goto DoneWithDeclSpec;
3741 ConsumeAnnotationToken();
3744 DiagID, TypeRep, Policy);
3754 case tok::annot_typename: {
3758 goto DoneWithDeclSpec;
3767 ConsumeAnnotationToken();
3772 case tok::kw___is_signed:
3784 TryKeywordIdentFallback(
true);
3787 goto DoneWithDeclSpec;
3790 case tok::kw___super:
3791 case tok::kw_decltype:
3792 case tok::identifier:
3798 goto DoneWithDeclSpec;
3804 if (!
getLangOpts().DeclSpecKeyword && Tok.is(tok::identifier) &&
3805 Tok.getIdentifierInfo()->getName() ==
"__declspec") {
3806 Diag(Loc, diag::err_ms_attributes_not_enabled);
3816 if (
T.consumeOpen()) {
3817 assert(
false &&
"Not a left paren?");
3832 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3836 if (IsTemplateSpecOrInst)
3840 if (IsTemplateSpecOrInst)
3843 goto DoneWithDeclSpec;
3846 if (!Tok.is(tok::identifier))
3851 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID,
isInvalid))
3857 goto DoneWithDeclSpec;
3859 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3860 isObjCInstancetype()) {
3861 ParsedType TypeRep = Actions.ObjC().ActOnObjCInstanceType(Loc);
3864 DiagID, TypeRep, Policy);
3876 Actions.isCurrentClassName(*Tok.getIdentifierInfo(),
getCurScope()) &&
3877 isConstructorDeclarator(
true,
3880 goto DoneWithDeclSpec;
3883 *Tok.getIdentifierInfo(), Tok.getLocation(),
getCurScope(),
nullptr,
3884 false,
false,
nullptr,
false,
false,
3885 isClassTemplateDeductionContext(DSContext));
3890 if (TryAnnotateTypeConstraint())
3891 goto DoneWithDeclSpec;
3892 if (Tok.isNot(tok::identifier))
3894 ParsedAttributes Attrs(AttrFactory);
3895 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
3896 if (!Attrs.
empty()) {
3897 AttrsLastTime =
true;
3898 attrs.takeAllAppendingFrom(Attrs);
3902 goto DoneWithDeclSpec;
3909 (DSContext == DeclSpecContext::DSC_class ||
3910 DSContext == DeclSpecContext::DSC_top_level) &&
3911 Actions.isDeductionGuideName(
getCurScope(), *Tok.getIdentifierInfo(),
3912 Tok.getLocation(), SS) &&
3913 isConstructorDeclarator(
true,
3915 goto DoneWithDeclSpec;
3918 DiagID, TypeRep, Policy);
3929 SourceLocation NewEndLoc;
3930 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3945 case tok::annot_template_id: {
3946 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
3957 TemplateId =
nullptr;
3965 tok::kw_volatile, tok::kw_restrict, tok::amp,
3967 Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
3971 TemplateId, Policy);
3975 goto DoneWithDeclSpec;
3977 if (TemplateId && !
isInvalid && Actions.CheckTypeConstraint(TemplateId))
3978 TemplateId =
nullptr;
3980 ConsumeAnnotationToken();
3981 SourceLocation AutoLoc = Tok.getLocation();
3984 if (Tracker.consumeOpen()) {
3986 Diag(Tok, diag::err_expected) << tok::l_paren;
3990 Tracker.skipToEnd();
3991 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
3996 Tracker.consumeClose();
3999 ConsumedEnd = Tok.getLocation();
4004 DiagID, TemplateId, Policy);
4007 TemplateId, Policy);
4016 goto DoneWithDeclSpec;
4024 isConstructorDeclarator(
true,
4027 goto DoneWithDeclSpec;
4032 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
4037 case tok::kw___attribute:
4038 case tok::kw___declspec:
4039 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4043 case tok::kw___forceinline: {
4045 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
4046 SourceLocation AttrNameLoc = Tok.getLocation();
4048 nullptr, 0, tok::kw___forceinline);
4052 case tok::kw___unaligned:
4058 case tok::kw___ptrauth:
4062 case tok::kw___sptr:
4063 case tok::kw___uptr:
4064 case tok::kw___ptr64:
4065 case tok::kw___ptr32:
4067 case tok::kw___cdecl:
4068 case tok::kw___stdcall:
4069 case tok::kw___fastcall:
4070 case tok::kw___thiscall:
4071 case tok::kw___regcall:
4072 case tok::kw___vectorcall:
4076 case tok::kw___funcref:
4081 case tok::kw___pascal:
4086 case tok::kw___kernel:
4091 case tok::kw___noinline__:
4096 case tok::kw__Nonnull:
4097 case tok::kw__Nullable:
4098 case tok::kw__Nullable_result:
4099 case tok::kw__Null_unspecified:
4104 case tok::kw___kindof:
4106 AttributeScopeInfo(),
nullptr, 0,
4112 case tok::kw_typedef:
4114 PrevSpec, DiagID, Policy);
4115 isStorageClass =
true;
4117 case tok::kw_extern:
4119 Diag(Tok, diag::ext_thread_before) <<
"extern";
4121 PrevSpec, DiagID, Policy);
4122 isStorageClass =
true;
4124 case tok::kw___private_extern__:
4126 Loc, PrevSpec, DiagID, Policy);
4127 isStorageClass =
true;
4129 case tok::kw_static:
4131 Diag(Tok, diag::ext_thread_before) <<
"static";
4133 PrevSpec, DiagID, Policy);
4134 isStorageClass =
true;
4138 auto IsTypedefName = [&](
const Token &
T) {
4139 if (!
T.is(tok::identifier))
4141 IdentifierInfo *II =
T.getIdentifierInfo();
4145 LookupResult
R(Actions, II,
T.getLocation(),
4149 R.suppressDiagnostics();
4152 auto MayBeTypeSpecifier = [&]() {
4163 if (isKnownToBeTypeSpecifier(
T))
4182 if (MayBeTypeSpecifier()) {
4184 PrevSpec, DiagID, Policy);
4186 Diag(Tok, diag::ext_auto_storage_class)
4193 PrevSpec, DiagID, Policy);
4194 isStorageClass =
true;
4196 case tok::kw___auto_type:
4197 Diag(Tok, diag::ext_auto_type);
4201 case tok::kw_register:
4203 PrevSpec, DiagID, Policy);
4204 isStorageClass =
true;
4206 case tok::kw_mutable:
4208 PrevSpec, DiagID, Policy);
4209 isStorageClass =
true;
4211 case tok::kw___thread:
4214 isStorageClass =
true;
4216 case tok::kw_thread_local:
4218 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4227 Loc, PrevSpec, DiagID);
4228 isStorageClass =
true;
4230 case tok::kw__Thread_local:
4231 diagnoseUseOfC11Keyword(Tok);
4233 Loc, PrevSpec, DiagID);
4234 isStorageClass =
true;
4238 case tok::kw_inline:
4241 case tok::kw_virtual:
4245 !
getActions().getOpenCLOptions().isAvailableOption(
4247 DiagID = diag::err_openclcxx_virtual_function;
4248 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4251 DiagID = diag::err_hlsl_virtual_function;
4252 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4258 case tok::kw_explicit: {
4259 SourceLocation ExplicitLoc = Loc;
4260 SourceLocation CloseParenLoc;
4262 ConsumedEnd = ExplicitLoc;
4264 if (Tok.is(tok::l_paren)) {
4266 DiagCompat(Tok.getLocation(), diag_compat::explicit_bool);
4268 ExprResult ExplicitExpr(
static_cast<Expr *
>(
nullptr));
4270 Tracker.consumeOpen();
4272 EnterExpressionEvaluationContext ConstantEvaluated(
4276 ConsumedEnd = Tok.getLocation();
4277 if (ExplicitExpr.isUsable()) {
4278 CloseParenLoc = Tok.getLocation();
4279 Tracker.consumeClose();
4281 Actions.ActOnExplicitBoolSpecifier(ExplicitExpr.get());
4283 Tracker.skipToEnd();
4285 Diag(Tok.getLocation(), diag::warn_cxx20_compat_explicit_bool);
4289 ExplicitSpec, CloseParenLoc);
4292 case tok::kw__Noreturn:
4293 diagnoseUseOfC11Keyword(Tok);
4298 case tok::kw_friend:
4299 if (DSContext == DeclSpecContext::DSC_class) {
4306 DiagID = diag::err_friend_invalid_in_context;
4312 case tok::kw___module_private__:
4317 case tok::kw_constexpr:
4319 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4323 case tok::kw_consteval:
4327 case tok::kw_constinit:
4335 Diag(Tok, diag::err_unknown_typename) << Tok.getName();
4339 goto DoneWithDeclSpec;
4350 PrevSpec, DiagID, Policy);
4352 case tok::kw___int64:
4354 PrevSpec, DiagID, Policy);
4356 case tok::kw_signed:
4360 case tok::kw_unsigned:
4364 case tok::kw__Complex:
4366 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4370 case tok::kw__Imaginary:
4372 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4388 case tok::kw__ExtInt:
4389 case tok::kw__BitInt: {
4390 DiagnoseBitIntUse(Tok);
4395 ConsumedEnd = PrevTokLocation;
4398 case tok::kw___int128:
4406 case tok::kw___bf16:
4414 case tok::kw_double:
4418 case tok::kw__Float16:
4422 case tok::kw__Accum:
4424 "This keyword is only used when fixed point types are enabled "
4425 "with `-ffixed-point`");
4429 case tok::kw__Fract:
4431 "This keyword is only used when fixed point types are enabled "
4432 "with `-ffixed-point`");
4438 "This keyword is only used when fixed point types are enabled "
4439 "with `-ffixed-point`");
4442 case tok::kw___float128:
4446 case tok::kw___ibm128:
4450 case tok::kw_wchar_t:
4454 case tok::kw_char8_t:
4458 case tok::kw_char16_t:
4462 case tok::kw_char32_t:
4468 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4472 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4474 if (Tok.is(tok::kw_bool) &&
4478 DiagID = diag::err_bool_redeclaration;
4480 Tok.setKind(tok::identifier);
4487 case tok::kw__Decimal32:
4491 case tok::kw__Decimal64:
4495 case tok::kw__Decimal128:
4499 case tok::kw___vector:
4502 case tok::kw___pixel:
4505 case tok::kw___bool:
4510 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4513 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
4514 Tok.setKind(tok::identifier);
4515 goto DoneWithDeclSpec;
4517 DiagID = diag::err_opencl_unknown_type_specifier;
4518 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4524#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4525#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4526#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4527 case tok::kw_##ImgType##_t: \
4528 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4529 goto DoneWithDeclSpec; \
4531#include "clang/Basic/OpenCLImageTypes.def"
4532 case tok::kw___unknown_anytype:
4534 PrevSpec, DiagID, Policy);
4539 case tok::kw_struct:
4540 case tok::kw___interface:
4541 case tok::kw_union: {
4548 ParsedAttributes Attributes(AttrFactory);
4549 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
4550 EnteringContext, DSContext, Attributes);
4554 if (!Attributes.empty()) {
4555 AttrsLastTime =
true;
4556 attrs.takeAllAppendingFrom(Attributes);
4564 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
4572 case tok::kw_volatile:
4576 case tok::kw_restrict:
4580 case tok::kw___ob_wrap:
4582 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
4587 OverflowBehaviorType::OverflowBehaviorKind::Wrap, Loc, PrevSpec,
4590 case tok::kw___ob_trap:
4592 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
4597 OverflowBehaviorType::OverflowBehaviorKind::Trap, Loc, PrevSpec,
4602 case tok::kw_typename:
4605 goto DoneWithDeclSpec;
4607 if (!Tok.is(tok::kw_typename))
4612 case tok::kw_typeof:
4613 case tok::kw_typeof_unqual:
4614 ParseTypeofSpecifier(DS);
4617 case tok::annot_decltype:
4618 ParseDecltypeSpecifier(DS);
4621 case tok::annot_pack_indexing_type:
4622 ParsePackIndexingType(DS);
4625 case tok::annot_pragma_pack:
4629 case tok::annot_pragma_ms_pragma:
4630 HandlePragmaMSPragma();
4633 case tok::annot_pragma_ms_vtordisp:
4634 HandlePragmaMSVtorDisp();
4637 case tok::annot_pragma_ms_pointers_to_members:
4638 HandlePragmaMSPointersToMembers();
4641 case tok::annot_pragma_export:
4642 HandlePragmaExport();
4645#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4646#include "clang/Basic/BuiltinTraits.inc"
4650 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4651 goto ParseIdentifier;
4654 case tok::kw__Atomic:
4659 diagnoseUseOfC11Keyword(Tok);
4661 ParseAtomicSpecifier(DS);
4669 case tok::kw___generic:
4674 if (!Actions.getLangOpts().OpenCLGenericAddressSpace) {
4675 DiagID = diag::err_opencl_unknown_type_specifier;
4676 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4681 case tok::kw_private:
4685 goto DoneWithDeclSpec;
4687 case tok::kw___private:
4688 case tok::kw___global:
4689 case tok::kw___local:
4690 case tok::kw___constant:
4692 case tok::kw___read_only:
4693 case tok::kw___write_only:
4694 case tok::kw___read_write:
4697 case tok::kw_row_major:
4698 case tok::kw_column_major:
4699 case tok::kw_nointerpolation:
4700 case tok::kw_linear:
4701 case tok::kw_centroid:
4702 case tok::kw_noperspective:
4703 case tok::kw_sample:
4704 case tok::kw_center:
4705 case tok::kw_groupshared:
4713#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
4714 case tok::kw_##Name: \
4715 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4718#include "clang/Basic/HLSLIntangibleTypes.def"
4720#define HLSL_PACKED_TYPE(Name, Id, SingletonId) \
4721 case tok::kw_##Name: \
4722 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4725#include "clang/Basic/HLSLPackedTypes.def"
4732 goto DoneWithDeclSpec;
4734 SourceLocation StartLoc = Tok.getLocation();
4735 SourceLocation EndLoc;
4737 if (
Type.isUsable()) {
4739 PrevSpec, DiagID,
Type.get(),
4740 Actions.getASTContext().getPrintingPolicy()))
4741 Diag(StartLoc, DiagID) << PrevSpec;
4757 assert(PrevSpec &&
"Method did not return previous specifier!");
4760 if (DiagID == diag::ext_duplicate_declspec ||
4761 DiagID == diag::ext_warn_duplicate_declspec ||
4762 DiagID == diag::err_duplicate_declspec)
4763 Diag(Loc, DiagID) << PrevSpec
4766 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4770 Diag(Loc, DiagID) << PrevSpec;
4773 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4777 AttrsLastTime =
false;
4789 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4792 for (
auto *I : RD->decls()) {
4793 auto *VD = dyn_cast<ValueDecl>(I);
4801 for (
const auto &DD : CAT->dependent_decls()) {
4802 if (!RD->containsDecl(DD.getDecl())) {
4803 P.
Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4804 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4805 P.
Diag(DD.getDecl()->getBeginLoc(),
4806 diag::note_flexible_array_counted_by_attr_field)
4813void Parser::ParseStructDeclaration(
4818 if (Tok.is(tok::kw___extension__)) {
4820 ExtensionRAIIObject O(Diags);
4822 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4826 ParsedAttributes Attrs(AttrFactory);
4827 MaybeParseCXX11Attributes(Attrs);
4830 ParseSpecifierQualifierList(DS);
4834 if (Tok.is(tok::semi)) {
4839 ProhibitAttributes(Attrs);
4840 RecordDecl *AnonRecord =
nullptr;
4841 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
4843 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4849 bool FirstDeclarator =
true;
4850 SourceLocation CommaLoc;
4852 ParsingFieldDeclarator DeclaratorInfo(*
this, DS, Attrs);
4853 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4856 if (!FirstDeclarator) {
4859 DiagnoseAndSkipCXX11Attributes();
4860 MaybeParseGNUAttributes(DeclaratorInfo.D);
4861 DiagnoseAndSkipCXX11Attributes();
4866 if (Tok.isNot(tok::colon)) {
4869 ParseDeclarator(DeclaratorInfo.D);
4871 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.getLocation());
4883 DeclaratorInfo.BitfieldSize = Res.
get();
4887 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
4890 Decl *
Field = FieldsCallback(DeclaratorInfo);
4892 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
4899 FirstDeclarator =
false;
4907 LPA.
Toks.push_back(AttrEnd);
4911 LPA.
Toks.push_back(Tok);
4912 PP.EnterTokenStream(LPA.
Toks,
true,
4919 ParsedAttributes Attrs(AttrFactory);
4923 SourceLocation(), ParsedAttr::Form::GNU(),
4928 while (Tok.isNot(tok::eof))
4932 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
4940 assert(LA.
Decls.size() <= 1 &&
4941 "late field attribute expects to have at most one declaration.");
4943 ParsedAttributes Attrs = ParseLexedAttributeTokens(LA);
4947void Parser::CompleteLateParsedTypeAttributes(
4950 std::unique_ptr<LateParsedTypeAttribute> LTA(RawLTA);
4952 BoundsAttributedType *BATy = LTA->TypeToComplete;
4953 if (!BATy || Actions.isLateParsedBoundsTypeRejected(BATy))
4956 ArrayRef<Decl *> Fields = LTA->Decls;
4958 AttributeFactory AF;
4959 ParsedAttributes Attrs(AF);
4960 ParseLexedTypeAttribute(*LTA, Attrs);
4965 assert(Attrs.
size() == 1);
4967 Expr *Arg = Attrs[0].getArgAsExpr(0);
4971 assert(!Fields.empty());
4972 for (Decl *FD : Fields)
4973 Valid &= Actions.ActOnLateParsedTypeAttrArgument(
4977 Attrs[0].setUsedAsTypeAttr();
4979 Attrs[0].setInvalid();
4981 LateTypeAttrs.clear();
4986 Self->ParseLexedTypeAttribute(*
this, OutAttrs);
4991 LateParsedAttrList::iterator It =
4999 From.erase(It, From.end());
5004 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl,
RecordLoc,
5005 "parsing struct/union body");
5009 if (
T.consumeOpen())
5013 Actions.ActOnTagStartDefinition(
getCurScope(), TagDecl);
5017 LateParsedAttrList LateFieldAttrs(
true,
5021 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
5022 Tok.isNot(tok::eof)) {
5026 if (Tok.is(tok::semi)) {
5032 if (Tok.isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
5033 SourceLocation DeclEnd;
5034 ParseStaticAssertDeclaration(DeclEnd);
5038 if (Tok.is(tok::annot_pragma_pack)) {
5043 if (Tok.is(tok::annot_pragma_align)) {
5044 HandlePragmaAlign();
5048 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
5051 ParsedAttributes Attrs(AttrFactory);
5052 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
5056 if (Tok.is(tok::annot_pragma_openacc)) {
5058 ParsedAttributes Attrs(AttrFactory);
5064 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
5066 TagType, Actions.getASTContext().getPrintingPolicy());
5067 ConsumeAnnotationToken();
5071 if (!Tok.is(tok::at)) {
5072 auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
5076 FD.D.getDeclSpec().getSourceRange().getBegin(),
5077 FD.D, FD.BitfieldSize);
5083 ParsingDeclSpec DS(*
this);
5084 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
5087 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
5088 Diag(Tok, diag::err_unexpected_at);
5093 ExpectAndConsume(tok::l_paren);
5094 if (!Tok.is(tok::identifier)) {
5095 Diag(Tok, diag::err_expected) << tok::identifier;
5099 SmallVector<Decl *, 16> Fields;
5100 Actions.ObjC().ActOnDefs(
getCurScope(), TagDecl, Tok.getLocation(),
5101 Tok.getIdentifierInfo(), Fields);
5103 ExpectAndConsume(tok::r_paren);
5109 if (Tok.is(tok::r_brace)) {
5110 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
5114 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
5123 ParsedAttributes attrs(AttrFactory);
5125 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
5127 SmallVector<Decl *, 32> FieldDecls(TagDecl->
fields());
5130 T.getOpenLocation(),
T.getCloseLocation(), attrs);
5133 ParseLexedAttributeList(LateFieldAttrs,
nullptr,
false,
5136 Actions.ActOnTagFinishDefinition(
getCurScope(), TagDecl,
T.getRange());
5140 const ParsedTemplateInfo &TemplateInfo,
5143 if (Tok.is(tok::code_completion)) {
5152 ParsedAttributes attrs(AttrFactory);
5153 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5155 SourceLocation ScopedEnumKWLoc;
5156 bool IsScopedUsingClassTag =
false;
5161 IsScopedUsingClassTag = Tok.is(tok::kw_class);
5166 ProhibitAttributes(attrs);
5169 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5178 bool shouldDelayDiagsInTag =
5181 SuppressAccessChecks diagsFromTag(*
this, shouldDelayDiagsInTag);
5184 AllowDefiningTypeSpec AllowEnumSpecifier =
5186 bool CanBeOpaqueEnumDeclaration =
5187 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5190 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5191 CanBeOpaqueEnumDeclaration);
5195 CXXScopeSpec InvalidDeclScope;
5203 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5208 if (Spec.
isSet() && Tok.isNot(tok::identifier)) {
5209 Diag(Tok, diag::err_expected) << tok::identifier;
5211 if (Tok.isNot(tok::l_brace)) {
5219 SS = std::move(Spec);
5223 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
5224 Tok.isNot(tok::colon)) {
5225 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5234 IdentifierInfo *Name =
nullptr;
5235 SourceLocation NameLoc;
5236 if (Tok.is(tok::identifier)) {
5237 Name = Tok.getIdentifierInfo();
5241 if (!Name && ScopedEnumKWLoc.
isValid()) {
5244 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5245 ScopedEnumKWLoc = SourceLocation();
5246 IsScopedUsingClassTag =
false;
5251 if (shouldDelayDiagsInTag)
5252 diagsFromTag.done();
5255 SourceRange BaseRange;
5257 bool CanBeBitfield =
5260 auto IsCXXTypeAhead = [
this]() {
5261 RevertingTentativeParsingAction PA(*
this);
5267 if (Tok.is(tok::colon) &&
5268 (!ParsingGenericAssociationType || IsCXXTypeAhead())) {
5293 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5297 Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
5298 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5305 DeclSpec DS(AttrFactory);
5309 DeclSpecContext::DSC_type_specifier);
5312 BaseType = Actions.ActOnTypeName(DeclaratorInfo);
5314 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5318 DiagCompat(ColonLoc, diag_compat::cxx_enum_fixed_underlying_type)
5321 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5324 DiagCompat(ColonLoc, diag_compat::c_enum_fixed_underlying_type)
5341 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5343 else if (Tok.is(tok::l_brace)) {
5345 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
5351 ScopedEnumKWLoc = SourceLocation();
5352 IsScopedUsingClassTag =
false;
5358 }
else if (!isTypeSpecifier(DSC) &&
5359 (Tok.is(tok::semi) ||
5360 (Tok.isAtStartOfLine() &&
5361 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5366 if (Tok.isNot(tok::semi)) {
5368 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5369 PP.EnterToken(Tok,
true);
5370 Tok.setKind(tok::semi);
5376 bool IsElaboratedTypeSpecifier =
5382 diagsFromTag.redelay();
5390 Diag(Tok, diag::err_enum_template);
5398 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5402 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5404 TemplateInfo.TemplateParams->size());
5409 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5425 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5427 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5428 diag::err_keyword_not_allowed,
5431 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5432 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5433 else if (ScopedEnumKWLoc.
isValid())
5434 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5438 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5440 SkipBodyInfo SkipBody;
5443 SkipBody = Actions.shouldSkipAnonEnumBody(
getCurScope(),
5448 bool IsDependent =
false;
5449 const char *PrevSpec =
nullptr;
5454 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5455 IsScopedUsingClassTag,
5456 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5457 DSC == DeclSpecContext::DSC_template_param ||
5458 DSC == DeclSpecContext::DSC_template_type_arg,
5459 OffsetOfState, &SkipBody).get();
5469 NameLoc.
isValid() ? NameLoc : StartLoc,
5470 PrevSpec, DiagID, TagDecl, Owned,
5471 Actions.getASTContext().getPrintingPolicy()))
5472 Diag(StartLoc, DiagID) << PrevSpec;
5481 Diag(Tok, diag::err_expected_type_name_after_typename);
5487 if (
Type.isInvalid()) {
5493 NameLoc.
isValid() ? NameLoc : StartLoc,
5494 PrevSpec, DiagID,
Type.get(),
5495 Actions.getASTContext().getPrintingPolicy()))
5496 Diag(StartLoc, DiagID) << PrevSpec;
5515 ParseEnumBody(StartLoc, D, &SkipBody);
5517 !Actions.ActOnDuplicateDefinition(
getCurScope(), TagDecl, SkipBody)) {
5524 NameLoc.
isValid() ? NameLoc : StartLoc,
5525 PrevSpec, DiagID, TagDecl, Owned,
5526 Actions.getASTContext().getPrintingPolicy()))
5527 Diag(StartLoc, DiagID) << PrevSpec;
5534 Actions.ActOnTagStartDefinition(
getCurScope(), EnumDecl);
5542 Diag(
T.getOpenLocation(), diag::ext_ms_c_empty_enum_type)
5543 << SourceRange(
T.getOpenLocation(), Tok.getLocation());
5545 Diag(Tok, diag::err_empty_enum);
5548 SmallVector<Decl *, 32> EnumConstantDecls;
5549 SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
5551 Decl *LastEnumConstDecl =
nullptr;
5554 while (Tok.isNot(tok::r_brace)) {
5557 if (Tok.isNot(tok::identifier)) {
5558 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
5564 IdentifierInfo *Ident = Tok.getIdentifierInfo();
5568 ParsedAttributes attrs(AttrFactory);
5569 MaybeParseGNUAttributes(attrs);
5570 if (isAllowedCXX11AttributeSpecifier()) {
5572 DiagCompat(Tok.getLocation(), diag_compat::ns_enum_attribute)
5574 ParseCXX11Attributes(attrs);
5577 SourceLocation EqualLoc;
5579 EnumAvailabilityDiags.emplace_back(*
this);
5581 EnterExpressionEvaluationContext ConstantEvaluated(
5590 Decl *EnumConstDecl = Actions.ActOnEnumConstant(
5591 getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
5592 EqualLoc, AssignedVal.
get(), SkipBody);
5593 EnumAvailabilityDiags.back().done();
5595 EnumConstantDecls.push_back(EnumConstDecl);
5596 LastEnumConstDecl = EnumConstDecl;
5598 if (Tok.is(tok::identifier)) {
5601 Diag(Loc, diag::err_enumerator_list_missing_comma)
5608 SourceLocation CommaLoc;
5609 if (Tok.isNot(tok::r_brace) && !
TryConsumeToken(tok::comma, CommaLoc)) {
5611 Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
5614 Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
5624 if (Tok.is(tok::r_brace) && CommaLoc.
isValid()) {
5626 DiagCompat(CommaLoc, diag_compat::cxx_enumerator_list_comma)
5629 Diag(CommaLoc, diag::ext_enumerator_list_comma_c)
5639 ParsedAttributes attrs(AttrFactory);
5640 MaybeParseGNUAttributes(attrs);
5642 Actions.ActOnEnumBody(StartLoc,
T.getRange(), EnumDecl, EnumConstantDecls,
5646 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5647 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5649 EnumAvailabilityDiags[i].redelay();
5650 PD.complete(EnumConstantDecls[i]);
5654 Actions.ActOnTagFinishDefinition(
getCurScope(), EnumDecl,
T.getRange());
5659 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5660 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5664 PP.EnterToken(Tok,
true);
5665 Tok.setKind(tok::semi);
5669bool Parser::isKnownToBeTypeSpecifier(
const Token &
Tok)
const {
5670 switch (Tok.getKind()) {
5671 default:
return false;
5675 case tok::kw___int64:
5676 case tok::kw___int128:
5677 case tok::kw_signed:
5678 case tok::kw_unsigned:
5679 case tok::kw__Complex:
5680 case tok::kw__Imaginary:
5683 case tok::kw_wchar_t:
5684 case tok::kw_char8_t:
5685 case tok::kw_char16_t:
5686 case tok::kw_char32_t:
5688 case tok::kw__ExtInt:
5689 case tok::kw__BitInt:
5690 case tok::kw___bf16:
5693 case tok::kw_double:
5694 case tok::kw__Accum:
5695 case tok::kw__Fract:
5696 case tok::kw__Float16:
5697 case tok::kw___float128:
5698 case tok::kw___ibm128:
5701 case tok::kw__Decimal32:
5702 case tok::kw__Decimal64:
5703 case tok::kw__Decimal128:
5704 case tok::kw___vector:
5705#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5706#include "clang/Basic/OpenCLImageTypes.def"
5707#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5708#include "clang/Basic/HLSLIntangibleTypes.def"
5709#define HLSL_PACKED_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5710#include "clang/Basic/HLSLPackedTypes.def"
5714 case tok::kw_struct:
5715 case tok::kw___interface:
5720 case tok::kw_typeof:
5721 case tok::kw_typeof_unqual:
5724 case tok::kw__Atomic:
5727 case tok::annot_typename:
5732bool Parser::isTypeSpecifierQualifier(
const Token &
Tok) {
5733 switch (Tok.getKind()) {
5734 default:
return false;
5736 case tok::identifier:
5737 if (TryAltiVecVectorToken())
5740 case tok::kw_typename:
5749 case tok::coloncolon:
5759 case tok::kw___attribute:
5761 case tok::kw_typeof:
5762 case tok::kw_typeof_unqual:
5767 case tok::kw___int64:
5768 case tok::kw___int128:
5769 case tok::kw_signed:
5770 case tok::kw_unsigned:
5771 case tok::kw__Complex:
5772 case tok::kw__Imaginary:
5775 case tok::kw_wchar_t:
5776 case tok::kw_char8_t:
5777 case tok::kw_char16_t:
5778 case tok::kw_char32_t:
5780 case tok::kw__ExtInt:
5781 case tok::kw__BitInt:
5783 case tok::kw___bf16:
5785 case tok::kw_double:
5786 case tok::kw__Accum:
5787 case tok::kw__Fract:
5788 case tok::kw__Float16:
5789 case tok::kw___float128:
5790 case tok::kw___ibm128:
5793 case tok::kw__Decimal32:
5794 case tok::kw__Decimal64:
5795 case tok::kw__Decimal128:
5796 case tok::kw___vector:
5797#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5798#include "clang/Basic/OpenCLImageTypes.def"
5799#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5800#include "clang/Basic/HLSLIntangibleTypes.def"
5801#define HLSL_PACKED_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5802#include "clang/Basic/HLSLPackedTypes.def"
5806 case tok::kw_struct:
5807 case tok::kw___interface:
5814 case tok::kw_volatile:
5815 case tok::kw_restrict:
5816 case tok::kw___ob_wrap:
5817 case tok::kw___ob_trap:
5821 case tok::kw___unknown_anytype:
5824 case tok::annot_typename:
5831 case tok::kw___cdecl:
5832 case tok::kw___stdcall:
5833 case tok::kw___fastcall:
5834 case tok::kw___thiscall:
5835 case tok::kw___regcall:
5836 case tok::kw___vectorcall:
5838 case tok::kw___ptr64:
5839 case tok::kw___ptr32:
5840 case tok::kw___pascal:
5841 case tok::kw___unaligned:
5842 case tok::kw___ptrauth:
5844 case tok::kw__Nonnull:
5845 case tok::kw__Nullable:
5846 case tok::kw__Nullable_result:
5847 case tok::kw__Null_unspecified:
5849 case tok::kw___kindof:
5851 case tok::kw___private:
5852 case tok::kw___local:
5853 case tok::kw___global:
5854 case tok::kw___constant:
5855 case tok::kw___generic:
5856 case tok::kw___read_only:
5857 case tok::kw___read_write:
5858 case tok::kw___write_only:
5859 case tok::kw___funcref:
5862 case tok::kw_private:
5866 case tok::kw__Atomic:
5870 case tok::kw_nointerpolation:
5871 case tok::kw_linear:
5872 case tok::kw_centroid:
5873 case tok::kw_noperspective:
5874 case tok::kw_sample:
5875 case tok::kw_center:
5876 case tok::kw_groupshared:
5880 case tok::kw_row_major:
5881 case tok::kw_column_major:
5887 assert(PP.isIncrementalProcessingEnabled() &&
"Not in incremental mode");
5891 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5894 TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5895 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5896 Actions.ActOnFinishTopLevelStmtDecl(TLSD,
R.get());
5897 if (!
R.isUsable()) {
5898 R = Actions.ActOnNullStmt(Tok.getLocation());
5902 if (Tok.is(tok::annot_repl_input_end) &&
5903 Tok.getAnnotationValue() !=
nullptr) {
5904 ConsumeAnnotationToken();
5908 SmallVector<Decl *, 2> DeclsInGroup;
5909 DeclsInGroup.push_back(TLSD);
5912 for (Stmt *S : Stmts) {
5915 TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5916 Actions.ActOnFinishTopLevelStmtDecl(D, S);
5917 DeclsInGroup.push_back(D);
5920 return Actions.BuildDeclaratorGroup(DeclsInGroup);
5923bool Parser::isDeclarationSpecifier(
5925 bool DisambiguatingWithExpression) {
5926 switch (Tok.getKind()) {
5927 default:
return false;
5934 case tok::identifier:
5938 if (TryAltiVecVectorToken())
5941 case tok::kw_decltype:
5942 case tok::kw_typename:
5947 if (TryAnnotateTypeConstraint())
5949 if (Tok.is(tok::identifier))
5957 if (DisambiguatingWithExpression &&
5958 isStartOfObjCClassMessageMissingOpenBracket())
5961 return isDeclarationSpecifier(AllowImplicitTypename);
5963 case tok::coloncolon:
5977 case tok::kw_typedef:
5978 case tok::kw_extern:
5979 case tok::kw___private_extern__:
5980 case tok::kw_static:
5982 case tok::kw___auto_type:
5983 case tok::kw_register:
5984 case tok::kw___thread:
5985 case tok::kw_thread_local:
5986 case tok::kw__Thread_local:
5989 case tok::kw___module_private__:
5992 case tok::kw___unknown_anytype:
5997 case tok::kw___int64:
5998 case tok::kw___int128:
5999 case tok::kw_signed:
6000 case tok::kw_unsigned:
6001 case tok::kw__Complex:
6002 case tok::kw__Imaginary:
6005 case tok::kw_wchar_t:
6006 case tok::kw_char8_t:
6007 case tok::kw_char16_t:
6008 case tok::kw_char32_t:
6011 case tok::kw__ExtInt:
6012 case tok::kw__BitInt:
6014 case tok::kw___bf16:
6016 case tok::kw_double:
6017 case tok::kw__Accum:
6018 case tok::kw__Fract:
6019 case tok::kw__Float16:
6020 case tok::kw___float128:
6021 case tok::kw___ibm128:
6024 case tok::kw__Decimal32:
6025 case tok::kw__Decimal64:
6026 case tok::kw__Decimal128:
6027 case tok::kw___vector:
6031 case tok::kw_struct:
6033 case tok::kw___interface:
6039 case tok::kw_volatile:
6040 case tok::kw_restrict:
6041 case tok::kw___ob_wrap:
6042 case tok::kw___ob_trap:
6046 case tok::kw_inline:
6047 case tok::kw_virtual:
6048 case tok::kw_explicit:
6049 case tok::kw__Noreturn:
6052 case tok::kw__Alignas:
6055 case tok::kw_friend:
6058 case tok::kw_static_assert:
6059 case tok::kw__Static_assert:
6062 case tok::kw_typeof:
6063 case tok::kw_typeof_unqual:
6066 case tok::kw___attribute:
6069 case tok::annot_decltype:
6070 case tok::annot_pack_indexing_type:
6071 case tok::kw_constexpr:
6074 case tok::kw_consteval:
6075 case tok::kw_constinit:
6078 case tok::kw__Atomic:
6081 case tok::kw_alignas:
6091 case tok::annot_typename:
6092 return !DisambiguatingWithExpression ||
6093 !isStartOfObjCClassMessageMissingOpenBracket();
6096 case tok::annot_template_id: {
6097 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
6102 return isTypeConstraintAnnotation() &&
6106 case tok::annot_cxxscope: {
6107 TemplateIdAnnotation *TemplateId =
6115 if (
NextToken().
is(tok::identifier) && TryAnnotateTypeConstraint())
6117 return isTypeConstraintAnnotation() &&
6121 case tok::kw___declspec:
6122 case tok::kw___cdecl:
6123 case tok::kw___stdcall:
6124 case tok::kw___fastcall:
6125 case tok::kw___thiscall:
6126 case tok::kw___regcall:
6127 case tok::kw___vectorcall:
6129 case tok::kw___sptr:
6130 case tok::kw___uptr:
6131 case tok::kw___ptr64:
6132 case tok::kw___ptr32:
6133 case tok::kw___forceinline:
6134 case tok::kw___pascal:
6135 case tok::kw___unaligned:
6136 case tok::kw___ptrauth:
6138 case tok::kw__Nonnull:
6139 case tok::kw__Nullable:
6140 case tok::kw__Nullable_result:
6141 case tok::kw__Null_unspecified:
6143 case tok::kw___kindof:
6145 case tok::kw___private:
6146 case tok::kw___local:
6147 case tok::kw___global:
6148 case tok::kw___constant:
6149 case tok::kw___generic:
6150 case tok::kw___read_only:
6151 case tok::kw___read_write:
6152 case tok::kw___write_only:
6153#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
6154#include "clang/Basic/OpenCLImageTypes.def"
6155#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
6156#include "clang/Basic/HLSLIntangibleTypes.def"
6157#define HLSL_PACKED_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
6158#include "clang/Basic/HLSLPackedTypes.def"
6160 case tok::kw___funcref:
6161 case tok::kw_groupshared:
6164 case tok::kw_nointerpolation:
6165 case tok::kw_linear:
6166 case tok::kw_centroid:
6167 case tok::kw_noperspective:
6168 case tok::kw_sample:
6169 case tok::kw_center:
6170 case tok::kw_row_major:
6171 case tok::kw_column_major:
6174 case tok::kw_private:
6179bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
6181 const ParsedTemplateInfo *TemplateInfo) {
6182 RevertingTentativeParsingAction TPA(*
this);
6185 if (TemplateInfo && TemplateInfo->TemplateParams)
6188 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6195 if (Tok.is(tok::identifier)) {
6199 }
else if (Tok.is(tok::annot_template_id)) {
6200 ConsumeAnnotationToken();
6207 SkipCXX11Attributes();
6210 if (Tok.isNot(tok::l_paren)) {
6217 if (Tok.is(tok::r_paren) ||
6218 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren))) {
6224 if (isCXX11AttributeSpecifier(
false,
6231 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6233 DeclScopeObj.EnterDeclaratorScope();
6236 ParsedAttributes Attrs(AttrFactory);
6237 MaybeParseMicrosoftAttributes(Attrs);
6246 bool IsConstructor =
false;
6252 if (Tok.is(tok::kw_this)) {
6254 return isDeclarationSpecifier(ITC);
6257 if (isDeclarationSpecifier(ITC))
6258 IsConstructor =
true;
6259 else if (Tok.is(tok::identifier) ||
6260 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier))) {
6265 if (Tok.is(tok::annot_cxxscope))
6266 ConsumeAnnotationToken();
6272 switch (Tok.getKind()) {
6278 case tok::coloncolon:
6291 SkipCXX11Attributes();
6293 if (DeductionGuide) {
6295 IsConstructor = Tok.is(tok::arrow);
6298 if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
6302 IsConstructor =
true;
6304 if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {
6317 IsConstructor = IsUnqualified;
6322 IsConstructor =
true;
6326 return IsConstructor;
6329void Parser::ParseTypeQualifierListOpt(
6330 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicOrPtrauthAllowed,
6332 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6333 isAllowedCXX11AttributeSpecifier()) {
6334 ParsedAttributes Attrs(AttrFactory);
6335 ParseCXX11Attributes(Attrs);
6339 SourceLocation EndLoc;
6343 const char *PrevSpec =
nullptr;
6344 unsigned DiagID = 0;
6345 SourceLocation Loc = Tok.getLocation();
6347 switch (Tok.getKind()) {
6348 case tok::code_completion:
6350 if (CodeCompletionHandler)
6351 CodeCompletionHandler();
6353 Actions.CodeCompletion().CodeCompleteTypeQualifiers(DS);
6360 case tok::kw_volatile:
6364 case tok::kw_restrict:
6368 case tok::kw___ob_wrap:
6370 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6375 OverflowBehaviorType::OverflowBehaviorKind::Wrap, Loc, PrevSpec,
6378 case tok::kw___ob_trap:
6380 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6385 OverflowBehaviorType::OverflowBehaviorKind::Trap, Loc, PrevSpec,
6388 case tok::kw__Atomic:
6389 if (!AtomicOrPtrauthAllowed)
6390 goto DoneWithTypeQuals;
6391 diagnoseUseOfC11Keyword(Tok);
6397 case tok::kw_private:
6399 goto DoneWithTypeQuals;
6401 case tok::kw___private:
6402 case tok::kw___global:
6403 case tok::kw___local:
6404 case tok::kw___constant:
6405 case tok::kw___generic:
6406 case tok::kw___read_only:
6407 case tok::kw___write_only:
6408 case tok::kw___read_write:
6412 case tok::kw_groupshared:
6416 case tok::kw_nointerpolation:
6417 case tok::kw_linear:
6418 case tok::kw_centroid:
6419 case tok::kw_noperspective:
6420 case tok::kw_sample:
6421 case tok::kw_center:
6427 case tok::kw___ptrauth:
6428 if (!AtomicOrPtrauthAllowed)
6429 goto DoneWithTypeQuals;
6431 EndLoc = PrevTokLocation;
6434 case tok::kw___unaligned:
6438 case tok::kw___uptr:
6443 if (TryKeywordIdentFallback(
false))
6447 case tok::kw___sptr:
6449 case tok::kw___ptr64:
6450 case tok::kw___ptr32:
6451 case tok::kw___cdecl:
6452 case tok::kw___stdcall:
6453 case tok::kw___fastcall:
6454 case tok::kw___thiscall:
6455 case tok::kw___regcall:
6456 case tok::kw___vectorcall:
6457 if (AttrReqs & AR_DeclspecAttributesParsed) {
6461 goto DoneWithTypeQuals;
6463 case tok::kw___funcref:
6467 case tok::kw___pascal:
6468 if (AttrReqs & AR_VendorAttributesParsed) {
6472 goto DoneWithTypeQuals;
6475 case tok::kw__Nonnull:
6476 case tok::kw__Nullable:
6477 case tok::kw__Nullable_result:
6478 case tok::kw__Null_unspecified:
6483 case tok::kw___kindof:
6485 AttributeScopeInfo(),
nullptr, 0,
6490 case tok::kw___attribute:
6491 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6493 Diag(Tok, diag::err_attributes_not_allowed);
6497 if (AttrReqs & AR_GNUAttributesParsed ||
6498 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6508 DS.
Finish(Actions, Actions.getASTContext().getPrintingPolicy());
6516 assert(PrevSpec &&
"Method did not return previous specifier!");
6517 Diag(Tok, DiagID) << PrevSpec;
6526 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6527 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6533 if (Kind == tok::star || Kind == tok::caret)
6537 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6538 Lang.getOpenCLCompatibleVersion() >= 200)
6541 if (!Lang.CPlusPlus)
6544 if (Kind == tok::amp)
6552 if (Kind == tok::ampamp)
6563 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6570void Parser::ParseDeclaratorInternal(
Declarator &D,
6571 DirectDeclParseFunction DirectDeclParser) {
6572 if (Diags.hasAllExtensionsSilenced())
6582 (Tok.is(tok::coloncolon) ||
6583 (Tok.is(tok::kw_decltype) &&
NextToken().
is(tok::l_paren)) ||
6584 (Tok.is(tok::identifier) &&
6586 Tok.is(tok::annot_cxxscope))) {
6587 TentativeParsingAction TPA(*
this,
true);
6593 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6605 Tok.is(tok::star)) {
6609 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6610 CompoundToken::MemberPtr);
6615 DeclSpec DS(AttrFactory);
6616 ParseTypeQualifierListOpt(DS);
6620 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6621 ParseDeclaratorInternal(D, DirectDeclParser);
6635 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6645 AnnotateScopeToken(SS,
true);
6647 if (DirectDeclParser)
6648 (this->*DirectDeclParser)(D);
6656 DeclSpec DS(AttrFactory);
6657 ParseTypeQualifierListOpt(DS);
6666 if (DirectDeclParser)
6667 (this->*DirectDeclParser)(D);
6676 if (Kind == tok::star || Kind == tok::caret) {
6678 DeclSpec DS(AttrFactory);
6682 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6684 ? AR_GNUAttributesParsed
6685 : AR_GNUAttributesParsedAndRejected);
6686 ParseTypeQualifierListOpt(DS, Reqs,
true,
6691 Actions.runWithSufficientStackSpace(
6692 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6693 if (Kind == tok::star)
6708 DeclSpec DS(AttrFactory);
6712 if (Kind == tok::ampamp)
6713 DiagCompat(Loc, diag_compat::rvalue_reference);
6716 ParseTypeQualifierListOpt(DS);
6725 diag::err_invalid_reference_qualifier_application) <<
"const";
6728 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6732 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6736 Actions.runWithSufficientStackSpace(
6737 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6744 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6747 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6776void Parser::ParseDirectDeclarator(
Declarator &D) {
6783 return ParseDecompositionDeclarator(D);
6797 ParseOptionalCXXScopeSpecifier(
6799 false, EnteringContext);
6814 if (Actions.ShouldEnterDeclaratorScope(
getCurScope(),
6818 DeclScopeObj.EnterDeclaratorScope();
6825 goto PastIdentifier;
6841 !Actions.containsUnexpandedParameterPacks(D) &&
6849 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6859 if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6863 bool AllowConstructorName;
6864 bool AllowDeductionGuide;
6866 AllowConstructorName =
false;
6867 AllowDeductionGuide =
false;
6871 AllowDeductionGuide =
false;
6879 SourceLocation TemplateKWLoc;
6884 true, AllowConstructorName,
6885 AllowDeductionGuide, &TemplateKWLoc,
6898 DeclScopeObj.EnterDeclaratorScope();
6905 goto PastIdentifier;
6911 diag::err_expected_unqualified_id)
6914 goto PastIdentifier;
6918 "There's a C++-specific check for tok::identifier above");
6919 assert(Tok.getIdentifierInfo() &&
"Not an identifier?");
6920 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6923 goto PastIdentifier;
6928 bool DiagnoseIdentifier =
false;
6932 DiagnoseIdentifier =
true;
6935 DiagnoseIdentifier =
6943 !isCXX11VirtSpecifier(Tok))
6945 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6946 if (DiagnoseIdentifier) {
6947 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
6951 goto PastIdentifier;
6955 if (Tok.is(tok::l_paren)) {
6960 RevertingTentativeParsingAction PA(*
this);
6965 goto PastIdentifier;
6972 ParseParenDeclarator(D);
6990 DeclScopeObj.EnterDeclaratorScope();
7001 diag::ext_abstract_pack_declarator_parens);
7003 if (Tok.getKind() == tok::annot_pragma_parser_crash)
7005 if (Tok.is(tok::l_square))
7006 return ParseMisplacedBracketDeclarator(D);
7011 !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
7012 Tok.getIdentifierInfo()->isCPlusPlusKeyword(
getLangOpts())) {
7014 diag::err_expected_member_name_or_semi_objcxx_keyword)
7015 << Tok.getIdentifierInfo()
7018 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
7021 goto PastIdentifier;
7024 diag::err_expected_member_name_or_semi)
7028 if (Tok.getKind() == tok::TokenKind::kw_while) {
7029 Diag(Tok, diag::err_while_loop_outside_of_a_function);
7031 if (Tok.isOneOf(tok::period, tok::arrow))
7032 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
7035 if (Tok.isAtStartOfLine() && Loc.
isValid())
7036 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
7040 diag::err_expected_unqualified_id)
7045 diag::err_expected_either)
7046 << tok::identifier << tok::l_paren;
7055 "Haven't past the location of the identifier yet?");
7059 MaybeParseCXX11Attributes(D);
7062 if (Tok.is(tok::l_paren)) {
7074 bool IsAmbiguous =
false;
7086 AllowImplicitTypename =
7094 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
7095 bool IsFunctionDecl =
7096 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
7097 TentativelyDeclaredIdentifiers.pop_back();
7098 if (!IsFunctionDecl)
7101 ParsedAttributes attrs(AttrFactory);
7104 if (IsFunctionDeclaration)
7105 Actions.ActOnStartFunctionDeclarationDeclarator(D,
7106 TemplateParameterDepth);
7107 ParseFunctionDeclarator(D, attrs,
T, IsAmbiguous);
7108 if (IsFunctionDeclaration)
7109 Actions.ActOnFinishFunctionDeclarationDeclarator(D);
7110 PrototypeScope.Exit();
7111 }
else if (Tok.is(tok::l_square)) {
7112 ParseBracketDeclarator(D);
7113 }
else if (Tok.isRegularKeywordAttribute()) {
7115 Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();
7120 if (!
T.consumeOpen())
7131 Diag(Tok, diag::err_requires_clause_inside_parens);
7145void Parser::ParseDecompositionDeclarator(
Declarator &D) {
7146 assert(Tok.is(tok::l_square));
7148 TentativeParsingAction PA(*
this);
7153 DiagnoseAndSkipCXX11Attributes();
7157 if (!(Tok.isOneOf(tok::identifier, tok::ellipsis) &&
7159 tok::identifier, tok::l_square, tok::ellipsis)) &&
7160 !(Tok.is(tok::r_square) &&
7163 return ParseMisplacedBracketDeclarator(D);
7166 SourceLocation PrevEllipsisLoc;
7167 SmallVector<DecompositionDeclarator::Binding, 32>
Bindings;
7168 while (Tok.isNot(tok::r_square)) {
7170 if (Tok.is(tok::comma))
7173 if (Tok.is(tok::identifier)) {
7175 Diag(EndLoc, diag::err_expected)
7178 Diag(Tok, diag::err_expected_comma_or_rsquare);
7181 SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis},
7183 if (Tok.is(tok::comma))
7185 else if (Tok.is(tok::r_square))
7190 if (isCXX11AttributeSpecifier() !=
7192 DiagnoseAndSkipCXX11Attributes();
7194 SourceLocation EllipsisLoc;
7196 if (Tok.is(tok::ellipsis)) {
7198 if (PrevEllipsisLoc.
isValid()) {
7199 Diag(Tok, diag::err_binding_multiple_ellipses);
7200 Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
7203 EllipsisLoc = Tok.getLocation();
7204 PrevEllipsisLoc = EllipsisLoc;
7208 if (Tok.isNot(tok::identifier)) {
7209 Diag(Tok, diag::err_expected) << tok::identifier;
7213 IdentifierInfo *II = Tok.getIdentifierInfo();
7214 SourceLocation Loc = Tok.getLocation();
7217 if (Tok.is(tok::ellipsis) && !PrevEllipsisLoc.
isValid()) {
7218 DiagnoseMisplacedEllipsis(Tok.getLocation(), Loc, EllipsisLoc.
isValid(),
7220 EllipsisLoc = Tok.getLocation();
7224 ParsedAttributes Attrs(AttrFactory);
7225 if (isCXX11AttributeSpecifier() !=
7227 DiagCompat(Tok, diag_compat::attrs_on_binding);
7228 MaybeParseCXX11Attributes(Attrs);
7231 Bindings.push_back({II, Loc, std::move(Attrs), EllipsisLoc});
7234 if (Tok.isNot(tok::r_square))
7241 Diag(Tok.getLocation(), diag::ext_decomp_decl_empty);
7249 T.getCloseLocation());
7252void Parser::ParseParenDeclarator(
Declarator &D) {
7256 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7268 ParsedAttributes attrs(AttrFactory);
7269 bool RequiresArg =
false;
7270 if (Tok.is(tok::kw___attribute)) {
7271 ParseGNUAttributes(attrs);
7279 ParseMicrosoftTypeAttributes(attrs);
7282 if (Tok.is(tok::kw___pascal))
7283 ParseBorlandTypeAttributes(attrs);
7295 }
else if (Tok.is(tok::r_paren) ||
7297 Tok.is(tok::ellipsis) &&
7299 isDeclarationSpecifier(
7301 isCXX11AttributeSpecifier() !=
7321 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7326 std::move(attrs),
T.getCloseLocation());
7332 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7350 ParseFunctionDeclarator(D, attrs,
T,
false, RequiresArg);
7351 PrototypeScope.Exit();
7354void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7356 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7364 bool IsCXX11MemberFunction =
7371 Actions.CurContext->isRecord());
7372 if (!IsCXX11MemberFunction)
7392 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,
7393 IsCXX11MemberFunction);
7396void Parser::ParseFunctionDeclarator(
Declarator &D,
7401 assert(
getCurScope()->isFunctionPrototypeScope() &&
7402 "Should call from a Function scope");
7408 bool HasProto =
false;
7410 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
7412 SourceLocation EllipsisLoc;
7414 DeclSpec DS(AttrFactory);
7415 bool RefQualifierIsLValueRef =
true;
7416 SourceLocation RefQualifierLoc;
7418 SourceRange ESpecRange;
7419 SmallVector<ParsedType, 2> DynamicExceptions;
7420 SmallVector<SourceRange, 2> DynamicExceptionRanges;
7423 ParsedAttributes FnAttrs(AttrFactory);
7425 SourceLocation TrailingReturnTypeLoc;
7430 SourceLocation StartLoc, LocalEndLoc, EndLoc;
7431 SourceLocation LParenLoc, RParenLoc;
7433 StartLoc = LParenLoc;
7435 if (isFunctionDeclaratorIdentifierList()) {
7437 Diag(Tok, diag::err_argument_required_after_attribute);
7439 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7443 LocalEndLoc = RParenLoc;
7448 MaybeParseCXX11Attributes(FnAttrs);
7449 ProhibitAttributes(FnAttrs);
7451 if (Tok.isNot(tok::r_paren))
7452 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7453 else if (RequiresArg)
7454 Diag(Tok, diag::err_argument_required_after_attribute);
7465 LocalEndLoc = RParenLoc;
7474 ParseTypeQualifierListOpt(
7475 DS, AR_NoAttributesParsed,
7478 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);
7485 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7486 EndLoc = RefQualifierLoc;
7488 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7489 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7506 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
7523 ESpecType = tryParseExceptionSpecification(Delayed,
7526 DynamicExceptionRanges,
7528 ExceptionSpecTokens);
7530 EndLoc = ESpecRange.
getEnd();
7534 MaybeParseCXX11Attributes(FnAttrs);
7537 LocalEndLoc = EndLoc;
7539 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7542 LocalEndLoc = Tok.getLocation();
7546 TrailingReturnTypeLoc =
Range.getBegin();
7547 EndLoc =
Range.getEnd();
7550 MaybeParseCXX11Attributes(FnAttrs);
7558 SmallVector<NamedDecl *, 0> DeclsInPrototype;
7561 NamedDecl *ND = dyn_cast<NamedDecl>(D);
7564 DeclsInPrototype.push_back(ND);
7571 llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) {
7579 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7580 ParamInfo.size(), EllipsisLoc, RParenLoc,
7581 RefQualifierIsLValueRef, RefQualifierLoc,
7583 ESpecType, ESpecRange, DynamicExceptions.data(),
7584 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7585 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7586 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7587 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7589 std::move(FnAttrs), EndLoc);
7592bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7594 if (Tok.isOneOf(tok::amp, tok::ampamp)) {
7596 RefQualifierIsLValueRef = Tok.is(tok::amp);
7603bool Parser::isFunctionDeclaratorIdentifierList() {
7605 && Tok.is(tok::identifier)
7606 && !TryAltiVecVectorToken()
7622 && (!Tok.is(tok::eof) &&
7626void Parser::ParseFunctionDeclaratorIdentifierList(
7630 assert(!
getLangOpts().requiresStrictPrototypes() &&
7631 "Cannot parse an identifier list in C23 or C++");
7638 Diag(Tok, diag::ext_ident_list_in_param);
7641 llvm::SmallPtrSet<const IdentifierInfo *, 16> ParamsSoFar;
7645 if (Tok.isNot(tok::identifier)) {
7646 Diag(Tok, diag::err_expected) << tok::identifier;
7653 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
7656 if (Actions.getTypeName(*ParmII, Tok.getLocation(),
getCurScope()))
7657 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7660 if (!ParamsSoFar.insert(ParmII).second) {
7661 Diag(Tok, diag::err_param_redefinition) << ParmII;
7664 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7675void Parser::ParseParameterDeclarationClause(
7684 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7686 Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)
7705 IsACXXFunctionDeclaration) {
7714 LateParsedAttrList LateParamAttrs(
true,
7725 DeclSpec DS(AttrFactory);
7727 ParsedAttributes ArgDeclAttrs(AttrFactory);
7728 ParsedAttributes ArgDeclSpecAttrs(AttrFactory);
7735 ArgDeclSpecAttrs.takeAllPrependingFrom(FirstArgAttrs);
7738 MaybeParseCXX11Attributes(ArgDeclAttrs);
7741 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7744 SourceLocation DSStart = Tok.getLocation();
7748 SourceLocation ThisLoc;
7752 ParsedTemplateInfo TemplateInfo;
7753 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7754 DeclSpecContext::DSC_normal,
7755 nullptr, AllowImplicitTypename);
7768 ParseDeclarator(ParmDeclarator);
7771 ParmDeclarator.SetRangeBegin(ThisLoc);
7774 MaybeParseGNUAttributes(ParmDeclarator, &LateParamAttrs);
7778 if (Tok.is(tok::kw_requires)) {
7783 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7789 const IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
7793 std::unique_ptr<CachedTokens> DefArgToks;
7797 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7798 ParmDeclarator.getNumTypeObjects() == 0) {
7800 Diag(DSStart, diag::err_missing_param);
7807 if (Tok.is(tok::ellipsis) &&
7809 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7810 !Actions.isUnexpandedParameterPackPermitted())) &&
7811 Actions.containsUnexpandedParameterPacks(ParmDeclarator))
7812 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7831 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7832 Tok.isNot(tok::raw_identifier) && !Tok.isAnnotation() &&
7833 Tok.getIdentifierInfo() &&
7834 Tok.getIdentifierInfo()->isKeyword(
getLangOpts())) {
7835 Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok);
7844 Diag(ParmDeclarator.getBeginLoc(),
7845 diag::err_function_parameter_limit_exceeded);
7853 Actions.ActOnParamDeclarator(
getCurScope(), ParmDeclarator, ThisLoc);
7855 DistributeCLateParsedAttrs(Param, &LateParamAttrs);
7860 if (Tok.is(tok::equal)) {
7861 SourceLocation EqualLoc = Tok.getLocation();
7871 ConsumeAndStoreInitializer(*DefArgToks,
7873 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
7884 DelayTemplateIdDestructionRAII DontDestructTemplateIds(
7889 EnterExpressionEvaluationContext Eval(
7896 Diag(Tok, diag::compat_cxx11_generalized_initializer_lists);
7897 DefArgResult = ParseBraceInitializer();
7899 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
7900 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7901 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7911 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7916 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
7917 DefArgResult.
get());
7922 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7923 ParmDeclarator.getIdentifierLoc(),
7924 Param, std::move(DefArgToks)));
7932 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
7939 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7941 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7942 Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {
7945 SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();
7946 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7947 << ParmEllipsis.
isValid() << ParmEllipsis;
7950 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7952 Diag(ParmDeclarator.getIdentifierLoc(),
7953 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7956 << !ParmDeclarator.hasName();
7958 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7971 if (!LateParamAttrs.empty())
7972 ParseLexedAttributeList(LateParamAttrs,
nullptr,
false,
7976void Parser::ParseBracketDeclarator(
Declarator &D) {
7977 if (CheckProhibitedCXX11Attribute())
7985 if (Tok.getKind() == tok::r_square) {
7987 ParsedAttributes attrs(AttrFactory);
7988 MaybeParseCXX11Attributes(attrs);
7992 T.getOpenLocation(),
7993 T.getCloseLocation()),
7994 std::move(attrs),
T.getCloseLocation());
7996 }
else if (Tok.getKind() == tok::numeric_constant &&
8003 ParsedAttributes attrs(AttrFactory);
8004 MaybeParseCXX11Attributes(attrs);
8008 T.getOpenLocation(),
8009 T.getCloseLocation()),
8010 std::move(attrs),
T.getCloseLocation());
8012 }
else if (Tok.getKind() == tok::code_completion) {
8014 Actions.CodeCompletion().CodeCompleteBracketDeclarator(
getCurScope());
8019 SourceLocation StaticLoc;
8024 DeclSpec DS(AttrFactory);
8025 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
8033 bool isStar =
false;
8044 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
8045 StaticLoc = SourceLocation();
8048 }
else if (Tok.isNot(tok::r_square)) {
8065 Diag(StaticLoc, diag::err_unspecified_size_with_static);
8066 StaticLoc = SourceLocation();
8085 isStar, NumElements.
get(),
T.getOpenLocation(),
8086 T.getCloseLocation()),
8090void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
8091 assert(Tok.is(tok::l_square) &&
"Missing opening bracket");
8094 SourceLocation StartBracketLoc = Tok.getLocation();
8098 while (Tok.is(tok::l_square)) {
8099 ParseBracketDeclarator(TempDeclarator);
8105 if (Tok.is(tok::semi))
8108 SourceLocation SuggestParenLoc = Tok.getLocation();
8111 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
8116 if (TempDeclarator.getNumTypeObjects() == 0)
8120 bool NeedParens =
false;
8139 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
8145 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
8146 const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
8147 D.
AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());
8152 if (!D.
hasName() && !NeedParens)
8155 SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();
8158 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
8159 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
8162 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8167 EndLoc, CharSourceRange(BracketRange,
true))
8170 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8173 EndLoc, CharSourceRange(BracketRange,
true))
8178void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
8179 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
8180 "Not a typeof specifier");
8182 bool IsUnqual = Tok.is(tok::kw_typeof_unqual);
8183 const IdentifierInfo *II = Tok.getIdentifierInfo();
8185 Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName();
8189 bool HasParens = Tok.is(tok::l_paren);
8197 SourceRange CastRange;
8199 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);
8215 const char *PrevSpec =
nullptr;
8222 Actions.getASTContext().getPrintingPolicy()))
8223 Diag(StartLoc, DiagID) << PrevSpec;
8234 Operand = Actions.HandleExprEvaluationContextForTypeof(
Operand.get());
8240 const char *PrevSpec =
nullptr;
8247 Actions.getASTContext().getPrintingPolicy()))
8248 Diag(StartLoc, DiagID) << PrevSpec;
8251void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
8252 assert(Tok.is(tok::kw__Atomic) &&
NextToken().
is(tok::l_paren) &&
8253 "Not an atomic specifier");
8257 if (
T.consumeOpen())
8261 if (
Result.isInvalid()) {
8269 if (
T.getCloseLocation().isInvalid())
8275 const char *PrevSpec =
nullptr;
8279 Actions.getASTContext().getPrintingPolicy()))
8280 Diag(StartLoc, DiagID) << PrevSpec;
8283bool Parser::TryAltiVecVectorTokenOutOfLine() {
8285 switch (
Next.getKind()) {
8286 default:
return false;
8289 case tok::kw_signed:
8290 case tok::kw_unsigned:
8295 case tok::kw_double:
8298 case tok::kw___bool:
8299 case tok::kw___pixel:
8300 Tok.setKind(tok::kw___vector);
8302 case tok::identifier:
8303 if (
Next.getIdentifierInfo() == Ident_pixel) {
8304 Tok.setKind(tok::kw___vector);
8307 if (
Next.getIdentifierInfo() == Ident_bool ||
8308 Next.getIdentifierInfo() == Ident_Bool) {
8309 Tok.setKind(tok::kw___vector);
8317 const char *&PrevSpec,
unsigned &DiagID,
8319 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
8320 if (Tok.getIdentifierInfo() == Ident_vector) {
8322 switch (
Next.getKind()) {
8325 case tok::kw_signed:
8326 case tok::kw_unsigned:
8331 case tok::kw_double:
8334 case tok::kw___bool:
8335 case tok::kw___pixel:
8338 case tok::identifier:
8339 if (
Next.getIdentifierInfo() == Ident_pixel) {
8343 if (
Next.getIdentifierInfo() == Ident_bool ||
8344 Next.getIdentifierInfo() == Ident_Bool) {
8353 }
else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
8357 }
else if ((Tok.getIdentifierInfo() == Ident_bool) &&
8365TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8368 SmallVector<Token, 4> Tokens;
8371 auto &SourceMgr = PP.getSourceManager();
8372 FileID FID = SourceMgr.createFileID(
8373 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8377 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8378 L.setParsingPreprocessorDirective(
true);
8384 Tokens.push_back(Tok);
8385 }
while (Tok.isNot(tok::eod));
8390 Token &EndToken = Tokens.back();
8394 Tokens.push_back(Tok);
8397 PP.EnterTokenStream(Tokens,
false,
8412 (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {
8413 Diag(Tok.getLocation(), diag::err_type_unparsed);
8418 while (Tok.isNot(tok::eof))
8422 if (Tok.is(tok::eof) && Tok.getEofData() == TypeStr.data())
8427void Parser::DiagnoseBitIntUse(
const Token &
Tok) {
8431 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8432 "expected either an _ExtInt or _BitInt token!");
8434 SourceLocation Loc = Tok.getLocation();
8435 if (Tok.is(tok::kw__ExtInt)) {
8436 Diag(Loc, diag::warn_ext_int_deprecated)
8442 Diag(Loc, diag::warn_c23_compat_keyword) << Tok.getName();
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
static StringRef normalizeAttrName(StringRef AttrName, StringRef NormalizedScopeName, AttributeCommonInfo::Syntax SyntaxUsed)
static Decl::Kind getKind(const Decl *D)
Defines the C++ template declaration subclasses.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::RecordLoc RecordLoc
static StringRef getTriple(const Command &Job)
static bool IsAttributeLateParsedExperimentalExt(const IdentifierInfo &II)
returns true iff attribute is annotated with LateAttrParseExperimentalExt in Attr....
static bool FindLocsWithCommonFileID(Preprocessor &PP, SourceLocation StartLoc, SourceLocation EndLoc)
Check if the a start and end source location expand to the same macro.
static bool IsAttributeArgsParsedInFunctionScope(const IdentifierInfo &II)
Such attributes need their arguments parsed inside a function prototype scope so the arguments can re...
static bool IsAttributeLateParsedStandard(const IdentifierInfo &II)
returns true iff attribute is annotated with LateAttrParseStandard in Attr.td.
static ParsedAttributeArgumentsProperties attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has string arguments.
static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute takes a strict identifier argument.
static bool attributeIsTypeArgAttr(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute parses a type argument.
static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute treats kw_this as an identifier.
static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute requires parsing its arguments in an unevaluated context or not...
static bool attributeHasIdentifierArg(const llvm::Triple &T, const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has an identifier argument.
static bool isValidAfterIdentifierInDeclarator(const Token &T)
isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the specified token is valid after t...
static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has a variadic identifier argument.
static bool isPipeDeclarator(const Declarator &D)
static SourceLocation getMissingDeclaratorIdLoc(Declarator &D, SourceLocation Loc)
static bool attributeAcceptsExprPack(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine if an attribute accepts parameter packs.
static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS, Parser &P)
static bool VersionNumberSeparator(const char Separator)
static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, DeclaratorContext TheContext)
llvm::SmallVector< std::pair< const MemRegion *, SVal >, 4 > Bindings
static constexpr bool isOneOf()
This file declares semantic analysis for CUDA constructs.
This file declares facilities that support code completion.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenMP constructs and clauses.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the clang::TokenKind enum and support functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Syntax
The style used to specify an attribute.
@ AS_Declspec
__declspec(...)
Kind getParsedKind() const
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
SourceLocation getOpenLocation() const
SourceLocation getCloseLocation() const
Represents a C++ nested-name-specifier or a global scope specifier.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
SourceLocation getEndLoc() const
bool isSet() const
Deprecated.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
void setTemplateParamLists(ArrayRef< TemplateParameterList * > L)
bool isEmpty() const
No scope specifier.
SourceLocation getBegin() const
Callback handler that receives notifications when performing code completion within the preprocessor.
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Captures information about "declaration specifiers".
bool isVirtualSpecified() const
bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, ExplicitSpecifier ExplicitSpec, SourceLocation CloseParenLoc)
bool isTypeSpecPipe() const
static const TSCS TSCS___thread
static const TST TST_typeof_unqualType
void setTypeArgumentRange(SourceRange range)
bool SetTypePipe(bool isPipe, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
SourceLocation getPipeLoc() const
static const TST TST_typename
SourceLocation getEndLoc() const LLVM_READONLY
bool hasTypeSpecifier() const
Return true if any type-specifier has been found.
bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec and return false if there was no error.
static const TST TST_char8
static const TST TST_BFloat16
void ClearStorageClassSpecs()
bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TSCS TSCS__Thread_local
bool SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec, but return true and ignore the request if ...
bool isNoreturnSpecified() const
TST getTypeSpecType() const
SourceLocation getStorageClassSpecLoc() const
SCS getStorageClassSpec() const
bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getOverflowBehaviorLoc() const
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceRange getSourceRange() const LLVM_READONLY
bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void SetRangeEnd(SourceLocation Loc)
bool SetBitIntType(SourceLocation KWLoc, Expr *BitWidth, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_auto_type
static const TST TST_interface
static const TST TST_double
static const TST TST_typeofExpr
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
void SetRangeStart(SourceLocation Loc)
bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getNoreturnSpecLoc() const
static const TST TST_union
static const TST TST_char
static const TST TST_bool
static const TST TST_char16
SourceLocation getExplicitSpecLoc() const
SourceLocation getFriendSpecLoc() const
SourceLocation getModulePrivateSpecLoc() const
bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void UpdateTypeRep(ParsedType Rep)
TSCS getThreadStorageClassSpec() const
bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasAttributes() const
static const TST TST_accum
static const TST TST_half
ParsedAttributes & getAttributes()
bool SetOverflowBehavior(OverflowBehaviorType::OverflowBehaviorKind Kind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getConstSpecLoc() const
static const TST TST_ibm128
void addAttributes(const ParsedAttributesView &AL)
Concatenates two attribute lists.
static const TST TST_enum
bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool isWrapSpecified() const
static const TST TST_float128
void takeAttributesAppendingingFrom(ParsedAttributes &attrs)
void Finish(Sema &S, const PrintingPolicy &Policy)
Finish - This does final analysis of the declspec, issuing diagnostics for things like "_Complex" (la...
bool isInlineSpecified() const
SourceLocation getRestrictSpecLoc() const
static const TST TST_typeof_unqualExpr
static const TST TST_class
bool hasTagDefinition() const
static const TST TST_decimal64
unsigned getParsedSpecifiers() const
Return a bitmask of which flavors of specifiers this DeclSpec includes.
void ClearFunctionSpecs()
bool SetTypeQual(TQ T, SourceLocation Loc)
static const TST TST_wchar
static const TST TST_void
bool isTypeAltiVecVector() const
void ClearConstexprSpec()
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
static const TST TST_float
static const TST TST_atomic
static const TST TST_fract
SourceLocation getThreadStorageClassSpecLoc() const
Decl * getRepAsDecl() const
static const TST TST_float16
static const TST TST_unspecified
SourceLocation getAtomicSpecLoc() const
SourceLocation getVirtualSpecLoc() const
SourceLocation getConstexprSpecLoc() const
CXXScopeSpec & getTypeSpecScope()
bool isEmpty() const
isEmpty - Return true if this declaration specifier is completely empty: no tokens were parsed in the...
SourceLocation getTypeSpecTypeLoc() const
static const TSCS TSCS_thread_local
bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal32
bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
TypeSpecifierWidth getTypeSpecWidth() const
static const TST TST_char32
bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal128
bool isTypeSpecOwned() const
SourceLocation getInlineSpecLoc() const
SourceLocation getUnalignedSpecLoc() const
static const TST TST_int128
SourceLocation getVolatileSpecLoc() const
FriendSpecified isFriendSpecified() const
bool hasExplicitSpecifier() const
bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasConstexprSpecifier() const
static const TST TST_typeofType
bool SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_auto
@ PQ_StorageClassSpecifier
ConstexprSpecKind getConstexprSpecifier() const
static const TST TST_struct
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
Information about one declarator, including the parsed type information and the identifier.
bool isFunctionDeclarator(unsigned &idx) const
isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...
bool isPastIdentifier() const
isPastIdentifier - Return true if we have parsed beyond the point where the name would appear.
void SetRangeBegin(SourceLocation Loc)
SetRangeBegin - Set the start of the source range to Loc, unless it's invalid.
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
void setCommaLoc(SourceLocation CL)
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
SourceLocation getIdentifierLoc() const
void SetIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
bool mayOmitIdentifier() const
mayOmitIdentifier - Return true if the identifier is either optional or not allowed.
SourceLocation getEndLoc() const LLVM_READONLY
bool mayBeFollowedByCXXDirectInit() const
mayBeFollowedByCXXDirectInit - Return true if the declarator can be followed by a C++ direct initiali...
bool hasGroupingParens() const
void setDecompositionBindings(SourceLocation LSquareLoc, MutableArrayRef< DecompositionDeclarator::Binding > Bindings, SourceLocation RSquareLoc)
Set the decomposition bindings for this declarator.
void setInvalidType(bool Val=true)
TemplateParameterList * getInventedTemplateParameterList() const
The template parameter list generated from the explicit template parameters along with any invented t...
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
bool mayHaveIdentifier() const
mayHaveIdentifier - Return true if the identifier is either optional or required.
void setGroupingParens(bool flag)
SourceLocation getEllipsisLoc() const
DeclaratorContext getContext() const
SourceLocation getBeginLoc() const LLVM_READONLY
void setTrailingRequiresClause(Expr *TRC)
Sets a trailing requires clause for this declarator.
void setHasInitializer(bool Val=true)
UnqualifiedId & getName()
Retrieve the name specified by this declarator.
void setTemplateParameterLists(ArrayRef< TemplateParameterList * > TPLs)
Sets the template parameter lists that preceded the declarator.
bool isFirstDeclarator() const
bool hasTrailingRequiresClause() const
Determine whether a trailing requires clause was written in this declarator.
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
The template parameter lists that preceded the declarator.
bool isFunctionDeclaratorAFunctionDeclaration() const
Return true if a function declarator at this position would be a function declaration.
void clear()
Reset the contents of this Declarator.
void setAsmLabel(Expr *E)
void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &&attrs, SourceLocation EndLoc)
AddTypeInfo - Add a chunk to this declarator.
void ExtendWithDeclSpec(const DeclSpec &DS)
ExtendWithDeclSpec - Extend the declarator source range to include the given declspec,...
void SetRangeEnd(SourceLocation Loc)
SetRangeEnd - Set the end of the source range to Loc, unless it's invalid.
void setExtension(bool Val=true)
bool isInvalidType() const
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
bool isDecompositionDeclarator() const
Return whether this declarator is a decomposition declarator.
bool isPrototypeContext() const
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.
friend struct LateParsedTypeAttribute
const Token & GetLookAheadToken(unsigned N)
GetLookAheadToken - This peeks ahead N tokens and returns that token without consuming any tokens.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
ExprResult ParseArrayBoundExpression()
friend struct LateParsedAttribute
const TargetInfo & getTargetInfo() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
const Token & getCurToken() const
void ExitScope()
ExitScope - Pop a scope off the scope stack.
const LangOptions & getLangOpts() const
friend class ParenBraceBracketBalancer
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtCodeCompletion
Stop at code completion.
@ StopAtSemi
Stop skipping at semicolon.
ExprResult ParseUnevaluatedStringLiteralExpression()
ObjCContainerDecl * getObjCDeclContext() const
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
friend class BalancedDelimiterTracker
SmallVector< TemplateParameterList *, 4 > TemplateParameterLists
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
A class for parsing a DeclSpec.
A class for parsing a declarator.
A class for parsing a field declarator.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
SourceManager & getSourceManager() const
const LangOptions & getLangOpts() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
void addAddressSpace(LangAS space)
static Qualifiers fromCVRUMask(unsigned CVRU)
Represents a struct/union/class.
field_range fields() const
bool isClassScope() const
isClassScope - Return true if this scope is a class/struct/union scope.
unsigned getFlags() const
getFlags - Return the flags for this scope.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ BlockScope
This is a scope that corresponds to a block/closure object.
@ FriendScope
This is a scope of friend declaration.
@ ControlScope
The controlling scope in a if/switch/while/for statement.
@ AtCatchScope
This is a scope that corresponds to the Objective-C @catch statement.
@ TemplateParamScope
This is a scope that corresponds to the template parameters of a C++ template.
@ CompoundStmtScope
This is a compound statement scope.
@ ClassScope
The scope of a struct/union/class definition.
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ EnumScope
This scope corresponds to an enum.
@ DeclScope
This is a scope that can contain a declaration.
@ CTCK_InitGlobalVar
Unknown context.
ParserCompletionContext
Describes the context in which code completion occurs.
@ PCC_LocalDeclarationSpecifiers
Code completion occurs within a sequence of declaration specifiers within a function,...
@ PCC_MemberTemplate
Code completion occurs following one or more template headers within a class.
@ PCC_Class
Code completion occurs within a class, struct, or union.
@ PCC_ObjCImplementation
Code completion occurs within an Objective-C implementation or category implementation.
@ PCC_Namespace
Code completion occurs at top-level or namespace context.
@ PCC_Template
Code completion occurs following one or more template headers.
NameClassificationKind getKind() const
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
@ PotentiallyEvaluatedIfUsed
The current expression is potentially evaluated, but any declarations referenced inside that expressi...
void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl)
ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an initializer for the declaratio...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
This class handles loading and caching of source files into memory.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
A RAII object used to temporarily suppress access-like checking.
Represents the declaration of a struct/union/class/enum.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
static Token createEof(SourceLocation Loc=SourceLocation(), const void *Data=nullptr)
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 setLocation(SourceLocation L)
void startToken()
Reset all flags to cleared.
void setSemiMissing(bool Missing=true)
static constexpr int FunctionTypeNumParamsLimit
SourceLocation EndLocation
The location of the last token that describes this unqualified-id.
SourceRange getSourceRange() const LLVM_READONLY
Return the source range that covers this unqualified-id.
SourceLocation StartLocation
The location of the first token that describes this unqualified-id, which will be the location of the...
UnqualifiedIdKind getKind() const
Determine what kind of name we have.
Declaration of a variable template.
static const char * getSpecifierName(Specifier VS)
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
bool InitScope(InterpState &S, uint32_t I)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
const char * getKeywordSpelling(TokenKind Kind) LLVM_READNONE
Determines the spelling of simple keyword and contextual keyword tokens like 'int' and 'dynamic_cast'...
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isPragmaAnnotation(TokenKind K)
Return true if this is an annotation token representing a pragma.
Top level wrappers for InstallAPI frontend operations.
TypeSpecifierType
Specifies the kind of type.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
bool isa(CodeGen::Address addr)
@ NotAttributeSpecifier
This is not an attribute specifier.
@ AttributeSpecifier
This should be treated as an attribute-specifier.
@ InvalidAttributeSpecifier
The next tokens are '[[', but this is not an attribute-specifier.
@ ExpectedParameterOrImplicitObjectParameter
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
@ IK_TemplateId
A template-id, e.g., f<int>.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
ActionResult< Decl * > DeclResult
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
llvm::SmallVector< ArgsUnion, 12U > ArgsVector
Language
The language for the input, used to select and validate the language standard and possible actions.
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
@ ExplicitSpecialization
We are parsing an explicit specialization.
@ ExplicitInstantiation
We are parsing an explicit instantiation.
@ NonTemplate
We are not parsing a template at all.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
@ FunctionTemplate
The name was classified as a function template name.
@ Keyword
The name has been typo-corrected to a keyword.
@ DependentNonType
The name denotes a member of a dependent type that could not be resolved.
@ UndeclaredTemplate
The name was classified as an ADL-only function template name.
@ NonType
The name was classified as a specific non-type, non-template declaration.
@ Unknown
This name is not a type or template in this context, but might be something else.
@ Error
Classification failed; an error has been produced.
@ Type
The name was classified as a type.
@ TypeTemplate
The name was classified as a template whose specializations are types.
@ Concept
The name was classified as a concept name.
@ OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ UndeclaredNonType
The name was classified as an ADL-only function name.
@ VarTemplate
The name was classified as a variable template name.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Dependent_template_name
The name refers to a dependent template name:
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &&Second)
Consumes the attributes from Second and concatenates them at the end of First.
U cast(CodeGen::Address addr)
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...
SmallVector< ParmVarDecl *, 4 > ProtoParams
Parameters of the prototype the attribute was written on, kept because late parsing runs after their ...
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