34#include "llvm/ADT/SmallSet.h"
35#include "llvm/ADT/StringSwitch.h"
47 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
48 if (DSC == DeclSpecContext::DSC_normal)
49 DSC = DeclSpecContext::DSC_type_specifier;
55 ParseSpecifierQualifierList(DS, AS, DSC);
63 if (AL.isDeclspecAttribute())
64 ToBeMoved.push_back(&AL);
73 ParseDeclarator(DeclaratorInfo);
80 return Actions.ActOnTypeName(DeclaratorInfo);
85 if (Name.size() >= 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
86 return Name.drop_front(2).drop_back(2);
93#define CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
95#include "clang/Parse/AttrParserStringSwitches.inc"
97#undef CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
103#define CLANG_ATTR_LATE_PARSED_LIST
105#include "clang/Parse/AttrParserStringSwitches.inc"
107#undef CLANG_ATTR_LATE_PARSED_LIST
113#define CLANG_ATTR_PARSE_ARGS_IN_FUNCTION_SCOPE_LIST
115#include "clang/Parse/AttrParserStringSwitches.inc"
117#undef CLANG_ATTR_PARSE_ARGS_IN_FUNCTION_SCOPE_LIST
127 if (
SM.getFileID(StartLoc) !=
SM.getFileID(EndLoc))
130 bool AttrStartIsInMacro =
132 bool AttrEndIsInMacro =
134 return AttrStartIsInMacro && AttrEndIsInMacro;
137void Parser::ParseAttributes(
unsigned WhichAttrKinds,
ParsedAttributes &Attrs,
144 if (WhichAttrKinds & PAKM_CXX11)
145 MoreToParse |= MaybeParseCXX11Attributes(Attrs);
146 if (WhichAttrKinds & PAKM_GNU)
147 MoreToParse |= MaybeParseGNUAttributes(Attrs, LateAttrs);
148 if (WhichAttrKinds & PAKM_Declspec)
149 MoreToParse |= MaybeParseMicrosoftDeclSpecs(Attrs);
150 }
while (MoreToParse);
157 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
163 if (Tok.isNot(tok::l_paren)) {
164 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
165 ParsedAttr::Form::GNU());
169 bool LateParse =
false;
176 LateParse =
getLangOpts().ExperimentalLateParseAttributes &&
189 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc,
nullptr,
190 SourceLocation(), ParsedAttr::Form::GNU(), D);
197 LateAttrs->push_back(LA);
201 if (!ClassStack.empty() && !LateAttrs->
parseSoon())
202 getCurrentClass().LateParsedDeclarations.push_back(LA);
206 LA->
Toks.push_back(Tok);
209 ConsumeAndStoreUntil(tok::r_paren, LA->
Toks,
true);
214 LA->
Toks.push_back(Eof);
221 assert(Tok.is(tok::kw___attribute) &&
"Not a GNU attribute list!");
223 SourceLocation StartLoc = Tok.getLocation();
224 SourceLocation EndLoc = StartLoc;
226 while (Tok.is(tok::kw___attribute)) {
228 unsigned OldNumAttrs = Attrs.
size();
229 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
231 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
236 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"(")) {
247 if (Tok.isAnnotation())
249 if (Tok.is(tok::code_completion)) {
251 Actions.CodeCompletion().CodeCompleteAttribute(
256 if (ParseSingleGNUAttribute(Attrs, EndLoc, LateAttrs, D))
258 }
while (Tok.is(tok::comma));
260 if (ExpectAndConsume(tok::r_paren))
262 SourceLocation Loc = Tok.getLocation();
263 if (ExpectAndConsume(tok::r_paren))
269 auto &
SM = PP.getSourceManager();
270 if (!
SM.isWrittenInBuiltinFile(
SM.getSpellingLoc(AttrTokLoc)) &&
272 CharSourceRange ExpansionRange =
SM.getExpansionRange(AttrTokLoc);
273 StringRef FoundName =
275 IdentifierInfo *MacroII = PP.getIdentifierInfo(FoundName);
277 for (
unsigned i = OldNumAttrs; i < Attrs.
size(); ++i)
278 Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.
getBegin());
281 for (
unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
282 (*LateAttrs)[i]->MacroII = MacroII;
287 Attrs.
Range = SourceRange(StartLoc, EndLoc);
295#define CLANG_ATTR_IDENTIFIER_ARG_LIST
297#include "clang/Parse/AttrParserStringSwitches.inc"
299#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
307#define CLANG_ATTR_STRING_LITERAL_ARG_LIST
309#include "clang/Parse/AttrParserStringSwitches.inc"
311#undef CLANG_ATTR_STRING_LITERAL_ARG_LIST
318#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
320#include "clang/Parse/AttrParserStringSwitches.inc"
322#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
329#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
331#include "clang/Parse/AttrParserStringSwitches.inc"
333#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
340#define CLANG_ATTR_ACCEPTS_EXPR_PACK
342#include "clang/Parse/AttrParserStringSwitches.inc"
344#undef CLANG_ATTR_ACCEPTS_EXPR_PACK
351#define CLANG_ATTR_TYPE_ARG_LIST
353#include "clang/Parse/AttrParserStringSwitches.inc"
355#undef CLANG_ATTR_TYPE_ARG_LIST
362#define CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
364#include "clang/Parse/AttrParserStringSwitches.inc"
366#undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
374#define CLANG_ATTR_ARG_CONTEXT_LIST
376#include "clang/Parse/AttrParserStringSwitches.inc"
378#undef CLANG_ATTR_ARG_CONTEXT_LIST
382 assert(Tok.is(tok::identifier) &&
"expected an identifier");
383 IdentifierLoc *IL =
new (Actions.Context)
384 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
399 if (Tok.isNot(tok::r_paren))
402 if (
Parens.consumeClose())
410 &AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
411 AttributeScopeInfo(ScopeName, ScopeLoc), T.
get(), Form);
413 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
414 AttributeScopeInfo(ScopeName, ScopeLoc),
nullptr, 0, Form);
418Parser::ParseUnevaluatedStringInAttribute(
const IdentifierInfo &AttrName) {
419 if (Tok.is(tok::l_paren)) {
422 ExprResult Res = ParseUnevaluatedStringInAttribute(AttrName);
423 Paren.consumeClose();
426 if (!isTokenStringLiteral()) {
427 Diag(Tok.getLocation(), diag::err_expected_string_literal)
434bool Parser::ParseAttributeArgumentList(
437 bool SawError =
false;
441 Expr = ParseUnevaluatedStringInAttribute(AttrName);
443 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
444 Expr = ParseBraceInitializer();
449 if (Tok.is(tok::ellipsis))
451 else if (Tok.is(tok::code_completion)) {
467 if (Actions.DiagnoseUnexpandedParameterPack(Expr.
get())) {
472 Exprs.push_back(Expr.
get());
474 if (Tok.isNot(tok::comma))
479 checkPotentialAngleBracketDelimiter(Comma);
486unsigned Parser::ParseAttributeArgsCommon(
495 bool AttributeIsTypeArgAttr =
497 bool AttributeHasVariadicIdentifierArg =
501 if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
502 Tok.setKind(tok::identifier);
505 if (Tok.is(tok::identifier)) {
507 bool IsIdentifierArg =
508 AttributeHasVariadicIdentifierArg ||
519 IsIdentifierArg =
Next.isOneOf(tok::r_paren, tok::comma);
523 ArgExprs.push_back(ParseIdentifierLoc());
527 if (!ArgExprs.empty() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren)) {
529 if (!ArgExprs.empty())
532 if (AttributeIsTypeArgAttr) {
540 TheParsedType = T.
get();
541 }
else if (AttributeHasVariadicIdentifierArg ||
551 if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
552 Tok.setKind(tok::identifier);
555 if (Tok.is(tok::identifier)) {
556 ArgExprs.push_back(ParseIdentifierLoc());
572 ArgExprs.push_back(ArgExpr.
get());
588 ExprVector ParsedExprs;
589 ParsedAttributeArgumentsProperties ArgProperties =
592 if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties,
599 for (
size_t I = 0; I < ParsedExprs.size(); ++I) {
604 Diag(Tok.getLocation(),
605 diag::err_attribute_argument_parm_pack_not_supported)
612 llvm::append_range(ArgExprs, ParsedExprs);
616 SourceLocation RParen = Tok.getLocation();
617 if (!ExpectAndConsume(tok::r_paren)) {
618 SourceLocation AttrLoc = ScopeLoc.
isValid() ? ScopeLoc : AttrNameLoc;
620 if (AttributeIsTypeArgAttr && !TheParsedType.
get().
isNull()) {
622 AttributeScopeInfo(ScopeName, ScopeLoc),
623 TheParsedType, Form);
625 Attrs.
addNew(AttrName, SourceRange(AttrLoc, RParen),
626 AttributeScopeInfo(ScopeName, ScopeLoc), ArgExprs.data(),
627 ArgExprs.size(), Form);
634 return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.
get().
isNull());
637void Parser::ParseGNUAttributeArgs(
642 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
647 if (AttrKind == ParsedAttr::AT_Availability) {
648 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
651 }
else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
652 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
653 ScopeName, ScopeLoc, Form);
655 }
else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
656 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
657 ScopeName, ScopeLoc, Form);
659 }
else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
660 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
663 }
else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
664 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
665 ScopeName, ScopeLoc, Form);
668 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName,
671 }
else if (AttrKind == ParsedAttr::AT_CountedBy ||
672 AttrKind == ParsedAttr::AT_CountedByOrNull ||
673 AttrKind == ParsedAttr::AT_SizedBy ||
674 AttrKind == ParsedAttr::AT_SizedByOrNull) {
675 ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
678 }
else if (AttrKind == ParsedAttr::AT_CXXAssume) {
679 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
680 ScopeLoc, EndLoc, Form);
686 std::optional<ParseScope> PrototypeScope;
691 const DeclaratorChunk::FunctionTypeInfo *FTI =
nullptr;
703 PrototypeScope.emplace(
707 for (
unsigned i = 0; i < FTI->
NumParams; ++i)
708 Actions.ActOnReenterCXXMethodParameter(
713 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
717unsigned Parser::ParseClangAttributeArgs(
721 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
728 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
729 ScopeName, ScopeLoc, Form);
730 case ParsedAttr::AT_ExternalSourceSymbol:
731 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
732 ScopeName, ScopeLoc, Form);
734 case ParsedAttr::AT_Availability:
735 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
738 case ParsedAttr::AT_ObjCBridgeRelated:
739 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
740 ScopeName, ScopeLoc, Form);
742 case ParsedAttr::AT_SwiftNewType:
743 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
746 case ParsedAttr::AT_TypeTagForDatatype:
747 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
748 ScopeName, ScopeLoc, Form);
751 case ParsedAttr::AT_CXXAssume:
752 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
753 ScopeLoc, EndLoc, Form);
756 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
762 unsigned ExistingAttrs = Attrs.
size();
774 SourceLocation OpenParenLoc = Tok.getLocation();
776 if (
AttrName->getName() ==
"property") {
782 T.expectAndConsume(diag::err_expected_lparen_after,
783 AttrName->getNameStart(), tok::r_paren);
790 IdentifierInfo *AccessorNames[] = {
nullptr,
nullptr};
791 bool HasInvalidAccessor =
false;
796 if (!Tok.is(tok::identifier)) {
798 if (Tok.is(tok::r_paren) && !HasInvalidAccessor &&
799 AccessorNames[AK_Put] ==
nullptr &&
800 AccessorNames[AK_Get] ==
nullptr) {
801 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
805 Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor);
810 SourceLocation KindLoc = Tok.getLocation();
811 StringRef KindStr = Tok.getIdentifierInfo()->getName();
812 if (KindStr ==
"get") {
814 }
else if (KindStr ==
"put") {
818 }
else if (KindStr ==
"set") {
819 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
826 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
828 HasInvalidAccessor =
true;
829 goto next_property_accessor;
833 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
834 HasInvalidAccessor =
true;
847 Diag(Tok.getLocation(), diag::err_ms_property_expected_equal)
853 if (!Tok.is(tok::identifier)) {
854 Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name);
858 if (Kind == AK_Invalid) {
860 }
else if (AccessorNames[Kind] !=
nullptr) {
862 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
864 AccessorNames[
Kind] = Tok.getIdentifierInfo();
868 next_property_accessor:
874 if (Tok.is(tok::r_paren))
877 Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen);
882 if (!HasInvalidAccessor)
884 AccessorNames[AK_Get], AccessorNames[AK_Put],
885 ParsedAttr::Form::Declspec());
887 return !HasInvalidAccessor;
891 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
892 SourceLocation(), ParsedAttr::Form::Declspec());
897 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) <<
AttrName;
904 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
905 assert(Tok.is(tok::kw___declspec) &&
"Not a declspec!");
907 SourceLocation StartLoc = Tok.getLocation();
908 SourceLocation EndLoc = StartLoc;
910 while (Tok.is(tok::kw___declspec)) {
913 if (T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
919 while (Tok.isNot(tok::r_paren)) {
924 if (Tok.is(tok::code_completion)) {
926 Actions.CodeCompletion().CodeCompleteAttribute(
933 bool IsString = Tok.getKind() == tok::string_literal;
934 if (!IsString && Tok.getKind() != tok::identifier &&
935 Tok.getKind() != tok::kw_restrict) {
936 Diag(Tok, diag::err_ms_declspec_type);
942 SourceLocation AttrNameLoc;
944 SmallString<8> StrBuffer;
945 bool Invalid =
false;
946 StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
951 AttrName = PP.getIdentifierInfo(Str);
952 AttrNameLoc = ConsumeStringToken();
958 bool AttrHandled =
false;
961 if (Tok.is(tok::l_paren))
962 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
963 else if (
AttrName->getName() ==
"property")
965 Diag(Tok.getLocation(), diag::err_expected_lparen_after)
969 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
970 ParsedAttr::Form::Declspec());
973 EndLoc = T.getCloseLocation();
976 Attrs.
Range = SourceRange(StartLoc, EndLoc);
982 auto Kind = Tok.getKind();
984 case tok::kw___fastcall:
985 case tok::kw___stdcall:
986 case tok::kw___thiscall:
987 case tok::kw___regcall:
988 case tok::kw___cdecl:
989 case tok::kw___vectorcall:
990 case tok::kw___ptr64:
992 case tok::kw___ptr32:
994 case tok::kw___uptr: {
995 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
997 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1007void Parser::ParseWebAssemblyFuncrefTypeAttribute(
ParsedAttributes &attrs) {
1008 assert(Tok.is(tok::kw___funcref));
1009 SourceLocation StartLoc = Tok.getLocation();
1012 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
1016 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1018 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr,
1019 0, tok::kw___funcref);
1022void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
1023 SourceLocation StartLoc = Tok.getLocation();
1024 SourceLocation EndLoc = SkipExtendedMicrosoftTypeAttributes();
1027 SourceRange
Range(StartLoc, EndLoc);
1028 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) <<
Range;
1033 SourceLocation EndLoc;
1036 switch (Tok.getKind()) {
1038 case tok::kw_volatile:
1039 case tok::kw___fastcall:
1040 case tok::kw___stdcall:
1041 case tok::kw___thiscall:
1042 case tok::kw___cdecl:
1043 case tok::kw___vectorcall:
1044 case tok::kw___ptr32:
1045 case tok::kw___ptr64:
1047 case tok::kw___unaligned:
1048 case tok::kw___sptr:
1049 case tok::kw___uptr:
1060 while (Tok.is(tok::kw___pascal)) {
1061 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1063 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1070 while (Tok.is(tok::kw___kernel)) {
1071 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1073 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1079 while (Tok.is(tok::kw___noinline__)) {
1080 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1082 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1083 tok::kw___noinline__);
1088 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1089 SourceLocation AttrNameLoc = Tok.getLocation();
1090 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1094bool Parser::isHLSLQualifier(
const Token &
Tok)
const {
1095 return Tok.is(tok::kw_groupshared) || Tok.is(tok::kw_row_major) ||
1096 Tok.is(tok::kw_column_major);
1100 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1101 auto Kind = Tok.getKind();
1103 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0, Kind);
1109 auto Kind = Tok.getKind();
1111 case tok::kw__Nonnull:
1112 case tok::kw__Nullable:
1113 case tok::kw__Nullable_result:
1114 case tok::kw__Null_unspecified: {
1115 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1118 Diag(AttrNameLoc, diag::ext_nullability)
1120 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1131 return (Separator ==
'.' || Separator ==
'_');
1134VersionTuple Parser::ParseVersionTuple(
SourceRange &Range) {
1135 Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());
1137 if (!Tok.is(tok::numeric_constant)) {
1138 Diag(Tok, diag::err_expected_version);
1141 return VersionTuple();
1148 SmallString<512> Buffer;
1149 Buffer.resize(Tok.getLength()+1);
1150 const char *ThisTokBegin = &Buffer[0];
1153 bool Invalid =
false;
1154 unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);
1156 return VersionTuple();
1159 unsigned AfterMajor = 0;
1161 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
1162 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
1166 if (AfterMajor == 0) {
1167 Diag(Tok, diag::err_expected_version);
1170 return VersionTuple();
1173 if (AfterMajor == ActualLength) {
1178 Diag(Tok, diag::err_zero_version);
1179 return VersionTuple();
1182 return VersionTuple(Major);
1185 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1187 || (AfterMajor + 1 == ActualLength)) {
1188 Diag(Tok, diag::err_expected_version);
1191 return VersionTuple();
1195 unsigned AfterMinor = AfterMajor + 1;
1197 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
1198 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
1202 if (AfterMinor == ActualLength) {
1206 if (Major == 0 && Minor == 0) {
1207 Diag(Tok, diag::err_zero_version);
1208 return VersionTuple();
1211 return VersionTuple(Major, Minor);
1214 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1217 Diag(Tok, diag::err_expected_version);
1220 return VersionTuple();
1224 if (AfterMajorSeparator != AfterMinorSeparator)
1225 Diag(Tok, diag::warn_expected_consistent_version_separator);
1228 unsigned AfterSubminor = AfterMinor + 1;
1229 unsigned Subminor = 0;
1230 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
1231 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
1235 if (AfterSubminor != ActualLength) {
1236 Diag(Tok, diag::err_expected_version);
1239 return VersionTuple();
1242 return VersionTuple(Major, Minor, Subminor);
1245void Parser::ParseAvailabilityAttribute(
1249 enum { Introduced, Deprecated, Obsoleted,
Unknown };
1250 AvailabilityChange Changes[
Unknown];
1252 IdentifierLoc *EnvironmentLoc =
nullptr;
1256 if (T.consumeOpen()) {
1257 Diag(Tok, diag::err_expected) << tok::l_paren;
1262 if (Tok.isNot(tok::identifier)) {
1263 Diag(Tok, diag::err_availability_expected_platform);
1267 IdentifierLoc *Platform = ParseIdentifierLoc();
1270 if (Ident->getName().contains(
"xrOS") || Ident->getName().contains(
"xros"))
1271 Diag(Platform->
getLoc(), diag::warn_availability_unknown_platform)
1274 else if (Ident->getName() ==
"macosx")
1278 else if (Ident->getName() ==
"macosx_app_extension")
1282 AvailabilityAttr::canonicalizePlatformName(Ident->getName())));
1286 if (ExpectAndConsume(tok::comma)) {
1293 if (!Ident_introduced) {
1294 Ident_introduced = PP.getIdentifierInfo(
"introduced");
1295 Ident_deprecated = PP.getIdentifierInfo(
"deprecated");
1296 Ident_obsoleted = PP.getIdentifierInfo(
"obsoleted");
1297 Ident_unavailable = PP.getIdentifierInfo(
"unavailable");
1298 Ident_message = PP.getIdentifierInfo(
"message");
1299 Ident_strict = PP.getIdentifierInfo(
"strict");
1300 Ident_replacement = PP.getIdentifierInfo(
"replacement");
1301 Ident_environment = PP.getIdentifierInfo(
"environment");
1306 SourceLocation UnavailableLoc, StrictLoc;
1308 if (Tok.isNot(tok::identifier)) {
1309 Diag(Tok, diag::err_availability_expected_change);
1313 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1316 if (
Keyword == Ident_strict) {
1318 Diag(KeywordLoc, diag::err_availability_redundant)
1319 <<
Keyword << SourceRange(StrictLoc);
1321 StrictLoc = KeywordLoc;
1325 if (
Keyword == Ident_unavailable) {
1326 if (UnavailableLoc.
isValid()) {
1327 Diag(KeywordLoc, diag::err_availability_redundant)
1328 <<
Keyword << SourceRange(UnavailableLoc);
1330 UnavailableLoc = KeywordLoc;
1337 if (Changes[Deprecated].KeywordLoc.
isValid()) {
1338 Diag(KeywordLoc, diag::err_availability_redundant)
1340 << SourceRange(Changes[Deprecated].KeywordLoc);
1345 Changes[Deprecated].
Version = VersionTuple(1);
1349 if (
Keyword == Ident_environment) {
1350 if (EnvironmentLoc !=
nullptr) {
1351 Diag(KeywordLoc, diag::err_availability_redundant)
1356 if (Tok.isNot(tok::equal)) {
1357 Diag(Tok, diag::err_expected_after) <<
Keyword << tok::equal;
1363 if (!isTokenStringLiteral()) {
1364 Diag(Tok, diag::err_expected_string_literal)
1369 if (
Keyword == Ident_message) {
1377 if (
Keyword == Ident_environment) {
1378 if (Tok.isNot(tok::identifier)) {
1379 Diag(Tok, diag::err_availability_expected_environment);
1383 EnvironmentLoc = ParseIdentifierLoc();
1389 if ((
Keyword == Ident_introduced ||
Keyword == Ident_deprecated) &&
1390 Tok.is(tok::identifier)) {
1391 IdentifierInfo *NA = Tok.getIdentifierInfo();
1394 if (
Keyword == Ident_introduced)
1395 UnavailableLoc = KeywordLoc;
1400 SourceRange VersionRange;
1401 VersionTuple Version = ParseVersionTuple(VersionRange);
1403 if (Version.empty()) {
1409 if (
Keyword == Ident_introduced)
1411 else if (
Keyword == Ident_deprecated)
1413 else if (
Keyword == Ident_obsoleted)
1419 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1420 Diag(KeywordLoc, diag::err_availability_redundant)
1422 << SourceRange(Changes[Index].KeywordLoc,
1423 Changes[Index].VersionRange.
getEnd());
1427 Changes[Index].
Version = Version;
1430 Diag(KeywordLoc, diag::err_availability_unknown_change)
1437 if (T.consumeClose())
1441 *endLoc = T.getCloseLocation();
1445 if (UnavailableLoc.
isValid()) {
1446 bool Complained =
false;
1447 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1448 if (Changes[Index].KeywordLoc.
isValid()) {
1450 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1451 << SourceRange(Changes[Index].KeywordLoc,
1452 Changes[Index].VersionRange.
getEnd());
1457 Changes[Index] = AvailabilityChange();
1463 attrs.
addNew(&Availability,
1464 SourceRange(AvailabilityLoc, T.getCloseLocation()),
1465 AttributeScopeInfo(ScopeName, ScopeLoc), Platform,
1466 Changes[Introduced], Changes[Deprecated], Changes[Obsoleted],
1467 UnavailableLoc, MessageExpr.
get(), Form, StrictLoc,
1468 ReplacementExpr.
get(), EnvironmentLoc);
1471void Parser::ParseExternalSourceSymbolAttribute(
1477 if (T.expectAndConsume())
1481 if (!Ident_language) {
1482 Ident_language = PP.getIdentifierInfo(
"language");
1483 Ident_defined_in = PP.getIdentifierInfo(
"defined_in");
1484 Ident_generated_declaration = PP.getIdentifierInfo(
"generated_declaration");
1485 Ident_USR = PP.getIdentifierInfo(
"USR");
1489 bool HasLanguage =
false;
1491 bool HasDefinedIn =
false;
1492 IdentifierLoc *GeneratedDeclaration =
nullptr;
1494 bool HasUSR =
false;
1498 if (Tok.isNot(tok::identifier)) {
1499 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1504 SourceLocation KeywordLoc = Tok.getLocation();
1505 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1506 if (
Keyword == Ident_generated_declaration) {
1507 if (GeneratedDeclaration) {
1508 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) <<
Keyword;
1512 GeneratedDeclaration = ParseIdentifierLoc();
1518 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1524 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1530 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1532 if (
Keyword == Ident_language)
1534 else if (
Keyword == Ident_USR)
1537 HasDefinedIn =
true;
1539 if (!isTokenStringLiteral()) {
1540 Diag(Tok, diag::err_expected_string_literal)
1545 : (
Keyword == Ident_defined_in ? 1 : 2));
1549 if (
Keyword == Ident_language) {
1551 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1557 }
else if (
Keyword == Ident_USR) {
1559 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1566 assert(
Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1568 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1578 if (T.consumeClose())
1581 *EndLoc = T.getCloseLocation();
1585 Attrs.
addNew(&ExternalSourceSymbol, SourceRange(Loc, T.getCloseLocation()),
1586 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1590void Parser::ParseObjCBridgeRelatedAttribute(
1596 if (T.consumeOpen()) {
1597 Diag(Tok, diag::err_expected) << tok::l_paren;
1602 if (Tok.isNot(tok::identifier)) {
1603 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1607 IdentifierLoc *RelatedClass = ParseIdentifierLoc();
1608 if (ExpectAndConsume(tok::comma)) {
1617 if (Tok.is(tok::identifier)) {
1620 Diag(Tok, diag::err_objcbridge_related_selector_name);
1626 if (Tok.is(tok::colon))
1627 Diag(Tok, diag::err_objcbridge_related_selector_name);
1629 Diag(Tok, diag::err_expected) << tok::comma;
1637 if (Tok.is(tok::identifier))
1639 else if (Tok.isNot(tok::r_paren)) {
1640 Diag(Tok, diag::err_expected) << tok::r_paren;
1646 if (T.consumeClose())
1650 *EndLoc = T.getCloseLocation();
1653 Attrs.
addNew(&ObjCBridgeRelated,
1654 SourceRange(ObjCBridgeRelatedLoc, T.getCloseLocation()),
1655 AttributeScopeInfo(ScopeName, ScopeLoc), RelatedClass,
1656 ClassMethod, InstanceMethod, Form);
1659void Parser::ParseSwiftNewTypeAttribute(
1666 if (T.consumeOpen()) {
1667 Diag(Tok, diag::err_expected) << tok::l_paren;
1671 if (Tok.is(tok::r_paren)) {
1672 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
1676 if (Tok.isNot(tok::kw_struct) && Tok.isNot(tok::kw_enum)) {
1677 Diag(Tok, diag::warn_attribute_type_not_supported)
1678 << &
AttrName << Tok.getIdentifierInfo();
1679 if (!isTokenSpecial())
1685 auto *SwiftType =
new (Actions.Context)
1686 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
1690 if (T.consumeClose())
1693 *EndLoc = T.getCloseLocation();
1696 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc, T.getCloseLocation()),
1697 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1701void Parser::ParseTypeTagForDatatypeAttribute(
1705 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1710 if (Tok.isNot(tok::identifier)) {
1711 Diag(Tok, diag::err_expected) << tok::identifier;
1715 IdentifierLoc *ArgumentKind = ParseIdentifierLoc();
1717 if (ExpectAndConsume(tok::comma)) {
1722 SourceRange MatchingCTypeRange;
1729 bool LayoutCompatible =
false;
1730 bool MustBeNull =
false;
1732 if (Tok.isNot(tok::identifier)) {
1733 Diag(Tok, diag::err_expected) << tok::identifier;
1737 IdentifierInfo *Flag = Tok.getIdentifierInfo();
1738 if (Flag->
isStr(
"layout_compatible"))
1739 LayoutCompatible =
true;
1740 else if (Flag->
isStr(
"must_be_null"))
1743 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1750 if (!T.consumeClose()) {
1752 &AttrName, AttrNameLoc, AttributeScopeInfo(ScopeName, ScopeLoc),
1753 ArgumentKind, MatchingCType.
get(), LayoutCompatible, MustBeNull, Form);
1757 *EndLoc = T.getCloseLocation();
1760bool Parser::DiagnoseProhibitedCXX11Attribute() {
1761 assert(Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square));
1763 switch (isCXX11AttributeSpecifier(
true)) {
1769 Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1774 SourceLocation BeginLoc = ConsumeBracket();
1777 assert(Tok.is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1778 SourceLocation EndLoc = ConsumeBracket();
1779 Diag(BeginLoc, diag::err_attributes_not_allowed)
1780 << SourceRange(BeginLoc, EndLoc);
1783 llvm_unreachable(
"All cases handled above.");
1788 assert((Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square)) ||
1789 Tok.is(tok::kw_alignas) || Tok.isRegularKeywordAttribute());
1793 Tok.isRegularKeywordAttribute() ? Tok.getIdentifierInfo() :
nullptr;
1794 SourceLocation Loc = Tok.getLocation();
1795 ParseCXX11Attributes(Attrs);
1796 CharSourceRange AttrRange(SourceRange(Loc, Attrs.
Range.
getEnd()),
true);
1799 :
Diag(Loc, diag::err_attributes_not_allowed))
1804void Parser::DiagnoseProhibitedAttributes(
1807 if (CorrectLocation.
isValid()) {
1808 CharSourceRange AttrRange(Attrs.
Range,
true);
1809 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1810 ?
Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1811 :
Diag(CorrectLocation, diag::err_attributes_misplaced))
1816 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1817 ?
Diag(
Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr
1818 :
Diag(
Range.getBegin(), diag::err_attributes_not_allowed))
1824 unsigned AttrDiagID,
1825 unsigned KeywordDiagID,
1826 bool DiagnoseEmptyAttrs,
1827 bool WarnOnUnknownAttrs) {
1833 auto &
SM = PP.getSourceManager();
1837 if (FirstLSquare.
is(tok::l_square)) {
1838 std::optional<Token> SecondLSquare =
1841 if (SecondLSquare && SecondLSquare->is(tok::l_square)) {
1851 for (
const ParsedAttr &AL : Attrs) {
1852 if (AL.isRegularKeywordAttribute()) {
1853 Diag(AL.getLoc(), KeywordDiagID) << AL;
1857 if (!AL.isStandardAttributeSyntax())
1860 if (WarnOnUnknownAttrs) {
1861 Actions.DiagnoseUnknownAttribute(AL);
1865 Diag(AL.getLoc(), AttrDiagID) << AL;
1872 for (
const ParsedAttr &PA : Attrs) {
1873 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1874 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1875 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
1884 llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;
1887 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1888 AL.isDeclspecAttribute()) ||
1889 AL.isMicrosoftAttribute())
1890 ToBeMoved.push_back(&AL);
1893 for (ParsedAttr *AL : ToBeMoved) {
1907 ObjCDeclContextSwitch ObjCDC(*
this);
1909 Decl *SingleDecl =
nullptr;
1910 switch (Tok.getKind()) {
1911 case tok::kw_template:
1912 case tok::kw_export:
1913 ProhibitAttributes(DeclAttrs);
1914 ProhibitAttributes(DeclSpecAttrs);
1915 return ParseDeclarationStartingWithTemplate(Context, DeclEnd, DeclAttrs);
1916 case tok::kw_inline:
1919 ProhibitAttributes(DeclAttrs);
1920 ProhibitAttributes(DeclSpecAttrs);
1922 return ParseNamespace(Context, DeclEnd, InlineLoc);
1924 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1925 true,
nullptr, DeclSpecStart);
1927 case tok::kw_cbuffer:
1928 case tok::kw_tbuffer:
1929 SingleDecl = ParseHLSLBuffer(DeclEnd, DeclAttrs);
1931 case tok::kw_namespace:
1932 ProhibitAttributes(DeclAttrs);
1933 ProhibitAttributes(DeclSpecAttrs);
1934 return ParseNamespace(Context, DeclEnd);
1935 case tok::kw_using: {
1937 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1938 DeclEnd, DeclAttrs);
1940 case tok::kw_static_assert:
1941 case tok::kw__Static_assert:
1942 ProhibitAttributes(DeclAttrs);
1943 ProhibitAttributes(DeclSpecAttrs);
1944 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1947 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1948 true,
nullptr, DeclSpecStart);
1953 return Actions.ConvertDeclToDeclGroup(SingleDecl);
1959 bool RequireSemi, ForRangeInit *FRI,
SourceLocation *DeclSpecStart) {
1961 ParsedAttributesView OriginalDeclSpecAttrs;
1962 OriginalDeclSpecAttrs.
prepend(DeclSpecAttrs.
begin(), DeclSpecAttrs.
end());
1963 OriginalDeclSpecAttrs.
Range = DeclSpecAttrs.
Range;
1966 ParsingDeclSpec DS(*
this);
1969 ParsedTemplateInfo TemplateInfo;
1970 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
1971 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none, DSContext);
1976 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
1981 if (Tok.is(tok::semi)) {
1982 ProhibitAttributes(DeclAttrs);
1983 DeclEnd = Tok.getLocation();
1985 RecordDecl *AnonRecord =
nullptr;
1986 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
1988 Actions.ActOnDefinedDeclarationSpecifier(TheDecl);
1989 DS.complete(TheDecl);
1991 Decl* decls[] = {AnonRecord, TheDecl};
1992 return Actions.BuildDeclaratorGroup(decls);
1994 return Actions.ConvertDeclToDeclGroup(TheDecl);
1998 Actions.ActOnDefinedDeclarationSpecifier(DS.
getRepAsDecl());
2003 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
2007 switch (Tok.getKind()) {
2008 case tok::annot_cxxscope:
2009 case tok::annot_template_id:
2011 case tok::code_completion:
2012 case tok::coloncolon:
2014 case tok::kw___attribute:
2015 case tok::kw_operator:
2031 case tok::identifier:
2033 case tok::code_completion:
2034 case tok::coloncolon:
2037 case tok::equalequal:
2038 case tok::kw_alignas:
2040 case tok::kw___attribute:
2058 case tok::identifier:
2062 return Tok.isRegularKeywordAttribute();
2066 return Tok.isRegularKeywordAttribute();
2072 switch (Tok.getKind()) {
2078 if (Tok.isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
2102 case tok::kw_inline:
2106 if (Tok.isAtStartOfLine() &&
NextToken().
is(tok::kw_namespace) &&
2107 (!ParsingInObjCContainer || CurParsedObjCImpl))
2111 case tok::kw_extern:
2114 case tok::kw_namespace:
2118 if (Tok.isAtStartOfLine() &&
2119 (!ParsingInObjCContainer || CurParsedObjCImpl))
2125 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2126 ParsingInObjCContainer)
2133 if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
2138 case tok::annot_module_begin:
2139 case tok::annot_module_end:
2140 case tok::annot_module_include:
2141 case tok::annot_repl_input_end:
2155 ParsedTemplateInfo &TemplateInfo,
2157 ForRangeInit *FRI) {
2163 LocalAttrs.takeAllPrependingFrom(Attrs);
2165 if (TemplateInfo.TemplateParams)
2168 bool IsTemplateSpecOrInst =
2175 if (IsTemplateSpecOrInst)
2185 while (MaybeParseHLSLAnnotations(D))
2188 if (
Tok.is(tok::kw_requires))
2189 ParseTrailingRequiresClauseWithScope(D);
2196 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2201 if (
Tok.is(tok::kw__Noreturn)) {
2203 const char *PrevSpec;
2209 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2210 Fixit &=
Tok.isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2212 Diag(Loc, diag::err_c11_noreturn_misplaced)
2214 << (Fixit ?
FixItHint::CreateInsertion(D.getBeginLoc(),
"_Noreturn ")
2219 if (Tok.is(tok::equal) &&
NextToken().
is(tok::code_completion)) {
2221 Actions.CodeCompletion().CodeCompleteAfterFunctionEquals(D);
2230 while (
auto Specifier = isCXX11VirtSpecifier()) {
2231 Diag(Tok, diag::err_virt_specifier_outside_class)
2239 if (!isDeclarationAfterDeclarator()) {
2245 if (isStartOfFunctionDefinition(D)) {
2255 diag::err_function_declared_typedef)
2259 Decl *TheDecl =
nullptr;
2265 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2266 TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(),
2269 SourceLocation LAngleLoc =
2270 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2272 diag::err_explicit_instantiation_with_definition)
2273 << SourceRange(TemplateInfo.TemplateLoc)
2278 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2279 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
2280 LAngleLoc,
nullptr));
2282 TheDecl = ParseFunctionDefinition(
2284 ParsedTemplateInfo(&FakedParamLists,
2291 ParseFunctionDefinition(D, TemplateInfo, &LateParsedAttrs);
2294 return Actions.ConvertDeclToDeclGroup(TheDecl);
2298 Tok.is(tok::kw_namespace)) {
2308 Diag(Tok, diag::err_expected_fn_body);
2313 if (Tok.is(tok::l_brace)) {
2314 Diag(Tok, diag::err_function_definition_not_allowed);
2322 if (ParseAsmAttributesAfterDeclarator(D))
2331 if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
2332 bool IsForRangeLoop =
false;
2334 IsForRangeLoop =
true;
2335 EnterExpressionEvaluationContext ForRangeInitContext(
2343 auto &LastRecord = Actions.currentEvaluationContext();
2344 LastRecord.InLifetimeExtendingContext =
true;
2345 LastRecord.RebuildDefaultArgOrDefaultInit =
true;
2349 Actions.OpenMP().startOpenMPCXXRangeFor();
2350 if (Tok.is(tok::l_brace))
2351 FRI->RangeExpr = ParseBraceInitializer();
2358 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
2362 FRI->LifetimeExtendTemps = std::move(
2363 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps);
2367 if (IsForRangeLoop) {
2368 Actions.ActOnCXXForRangeDecl(ThisDecl);
2371 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2372 VD->setObjCForDecl(
true);
2374 Actions.FinalizeDeclaration(ThisDecl);
2375 D.complete(ThisDecl);
2376 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, ThisDecl);
2379 SmallVector<Decl *, 8> DeclsInGroup;
2381 ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo, FRI);
2382 if (LateParsedAttrs.size() > 0)
2383 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2384 D.complete(FirstDecl);
2386 DeclsInGroup.push_back(FirstDecl);
2392 SourceLocation CommaLoc;
2394 if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2398 Diag(CommaLoc, diag::err_expected_semi_declaration)
2410 Diag(CommaLoc, diag::err_multiple_template_declarators)
2411 << TemplateInfo.Kind;
2425 MaybeParseGNUAttributes(D);
2429 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2434 MaybeParseHLSLAnnotations(D);
2441 if (Tok.is(tok::kw_requires))
2442 ParseTrailingRequiresClauseWithScope(D);
2443 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D, TemplateInfo);
2444 D.complete(ThisDecl);
2446 DeclsInGroup.push_back(ThisDecl);
2451 *DeclEnd = Tok.getLocation();
2453 if (ExpectSemi && ExpectAndConsumeSemi(
2455 ? diag::err_invalid_token_after_toplevel_declarator
2456 : diag::err_expected_semi_declaration)) {
2464 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
2467bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &D) {
2469 if (Tok.is(tok::kw_asm)) {
2471 ExprResult AsmLabel(ParseSimpleAsm(
true, &Loc));
2472 if (AsmLabel.isInvalid()) {
2481 MaybeParseGNUAttributes(D);
2485Decl *Parser::ParseDeclarationAfterDeclarator(
2486 Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
2487 if (ParseAsmAttributesAfterDeclarator(D))
2490 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
2493Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2494 Declarator &D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2496 struct InitializerScopeRAII {
2502 InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl)
2503 : P(P), D(D), ThisDecl(ThisDecl), Entered(
false) {
2506 if (D.getCXXScopeSpec().isSet()) {
2508 S = P.getCurScope();
2511 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2516 ~InitializerScopeRAII() {
2532 InitKind TheInitKind;
2534 if (isTokenEqualOrEqualTypo())
2535 TheInitKind = InitKind::Equal;
2536 else if (
Tok.
is(tok::l_paren))
2537 TheInitKind = InitKind::CXXDirect;
2540 TheInitKind = InitKind::CXXBraced;
2542 TheInitKind = InitKind::Uninitialized;
2543 if (TheInitKind != InitKind::Uninitialized)
2547 Decl *ThisDecl =
nullptr;
2548 Decl *OuterDecl =
nullptr;
2549 switch (TemplateInfo.Kind) {
2551 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2556 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
2557 *TemplateInfo.TemplateParams,
2559 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2562 ThisDecl = VT->getTemplatedDecl();
2568 if (
Tok.
is(tok::semi)) {
2569 DeclResult ThisRes = Actions.ActOnExplicitInstantiation(
2570 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
2572 SkipUntil(tok::semi, StopBeforeMatch);
2575 ThisDecl = ThisRes.
get();
2583 Diag(
Tok, diag::err_template_defn_explicit_instantiation)
2585 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2588 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2590 diag::err_explicit_instantiation_with_definition)
2595 TemplateParameterLists FakedParamLists;
2596 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2598 LAngleLoc,
nullptr));
2601 Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D);
2610 switch (TheInitKind) {
2612 case InitKind::Equal: {
2615 if (
Tok.
is(tok::kw_delete)) {
2617 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2620 Diag(ConsumeToken(), diag::err_deleted_non_function);
2621 SkipDeletedFunctionBody();
2622 }
else if (
Tok.
is(tok::kw_default)) {
2624 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2627 Diag(ConsumeToken(), diag::err_default_special_members)
2628 << getLangOpts().CPlusPlus20;
2630 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2632 if (
Tok.
is(tok::code_completion)) {
2634 Actions.CodeCompletion().CodeCompleteInitializer(getCurScope(),
2636 Actions.FinalizeDeclaration(ThisDecl);
2646 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2650 FRI->ColonLoc = EqualLoc;
2652 FRI->RangeExpr =
Init;
2655 if (
Init.isInvalid()) {
2657 StopTokens.push_back(tok::comma);
2660 StopTokens.push_back(tok::r_paren);
2661 SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch);
2662 Actions.ActOnInitializerError(ThisDecl);
2664 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
2669 case InitKind::CXXDirect: {
2676 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2678 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2679 auto RunSignatureHelp = [&]() {
2681 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2682 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2683 ThisDecl->
getLocation(), Exprs, T.getOpenLocation(),
2685 CalledSignatureHelp =
true;
2686 return PreferredType;
2688 auto SetPreferredType = [&] {
2689 PreferredType.enterFunctionArgument(
Tok.
getLocation(), RunSignatureHelp);
2692 llvm::function_ref<void()> ExpressionStarts;
2698 ExpressionStarts = SetPreferredType;
2701 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2704 if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
2705 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2706 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2707 ThisDecl->
getLocation(), Exprs, T.getOpenLocation(),
2709 CalledSignatureHelp =
true;
2711 Actions.ActOnInitializerError(ThisDecl);
2712 SkipUntil(tok::r_paren, StopAtSemi);
2718 T.getCloseLocation(),
2720 Actions.AddInitializerToDecl(ThisDecl,
Initializer.get(),
2725 case InitKind::CXXBraced: {
2727 Diag(
Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2729 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2734 if (
Init.isInvalid()) {
2735 Actions.ActOnInitializerError(ThisDecl);
2737 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
true);
2740 case InitKind::Uninitialized: {
2741 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2742 Actions.ActOnUninitializedDecl(ThisDecl);
2747 Actions.FinalizeDeclaration(ThisDecl);
2748 return OuterDecl ? OuterDecl : ThisDecl;
2751void Parser::ParseSpecifierQualifierList(
2754 ParsedTemplateInfo TemplateInfo;
2758 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC,
nullptr,
2759 AllowImplicitTypename);
2764 Diag(Tok, diag::err_expected_type);
2767 Diag(Tok, diag::err_typename_requires_specqual);
2778 diag::err_typename_invalid_storageclass);
2822 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2823 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2828 ParsedTemplateInfo &TemplateInfo,
2831 assert(Tok.is(tok::identifier) &&
"should have identifier");
2833 SourceLocation Loc = Tok.getLocation();
2853 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
2871 AnnotateScopeToken(*SS,
false);
2880 if (
ParsedType T = Actions.ActOnMSVCUnknownTypeName(
2881 *Tok.getIdentifierInfo(), Tok.getLocation(),
2882 DSC == DeclSpecContext::DSC_template_type_arg)) {
2883 const char *PrevSpec;
2886 Actions.getASTContext().getPrintingPolicy());
2899 if (SS ==
nullptr) {
2900 const char *TagName =
nullptr, *FixitTagName =
nullptr;
2903 switch (Actions.isTagName(*Tok.getIdentifierInfo(),
getCurScope())) {
2906 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
2908 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
2910 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
2912 TagName=
"__interface"; FixitTagName =
"__interface ";
2913 TagKind=tok::kw___interface;
break;
2915 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
2919 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
2920 LookupResult
R(Actions, TokenName, SourceLocation(),
2923 Diag(Loc, diag::err_use_of_tag_name_without_tag)
2924 << TokenName << TagName <<
getLangOpts().CPlusPlus
2930 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2931 << TokenName << TagName;
2935 if (TagKind == tok::kw_enum)
2936 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,
2937 DeclSpecContext::DSC_normal);
2939 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
2941 DeclSpecContext::DSC_normal, Attrs);
2948 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
2949 DSC == DeclSpecContext::DSC_class)) {
2953 case tok::l_paren: {
2960 TentativeParsingAction PA(*
this);
2962 TPResult TPR = TryParseDeclarator(
false);
2965 if (TPR != TPResult::False) {
2973 if (DSC == DeclSpecContext::DSC_class ||
2974 (DSC == DeclSpecContext::DSC_top_level && SS)) {
2975 IdentifierInfo *II = Tok.getIdentifierInfo();
2976 if (Actions.isCurrentClassNameTypo(II, SS)) {
2977 Diag(Loc, diag::err_constructor_bad_name)
2978 << Tok.getIdentifierInfo() << II
2980 Tok.setIdentifierInfo(II);
2998 AnnotateScopeToken(*SS,
false);
3012 IdentifierInfo *II = Tok.getIdentifierInfo();
3014 Actions.DiagnoseUnknownTypeName(II, Loc,
getCurScope(), SS, T,
3020 const char *PrevSpec;
3023 Actions.getASTContext().getPrintingPolicy());
3028 }
else if (II != Tok.getIdentifierInfo()) {
3041 if (IsTemplateName) {
3042 SourceLocation LAngle, RAngle;
3043 TemplateArgList Args;
3044 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3053Parser::DeclSpecContext
3057 return DeclSpecContext::DSC_class;
3059 return DeclSpecContext::DSC_top_level;
3061 return DeclSpecContext::DSC_template_param;
3063 return DeclSpecContext::DSC_template_arg;
3065 return DeclSpecContext::DSC_template_type_arg;
3068 return DeclSpecContext::DSC_trailing;
3071 return DeclSpecContext::DSC_alias_declaration;
3073 return DeclSpecContext::DSC_association;
3075 return DeclSpecContext::DSC_type_specifier;
3077 return DeclSpecContext::DSC_condition;
3079 return DeclSpecContext::DSC_conv_operator;
3081 return DeclSpecContext::DSC_new;
3096 return DeclSpecContext::DSC_normal;
3099 llvm_unreachable(
"Missing DeclaratorContext case");
3106 if (isTypeIdInParens()) {
3107 SourceLocation TypeLoc = Tok.getLocation();
3109 SourceRange TypeRange(Start, Tok.getLocation());
3110 if (Actions.ActOnAlignasTypeArgument(KWName, Ty, TypeLoc, TypeRange))
3127 assert(Tok.isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3128 "Not an alignment-specifier!");
3135 if (T.expectAndConsume())
3140 SourceLocation EllipsisLoc;
3142 ParseAlignArgument(PP.getSpelling(KWTok), T.getOpenLocation(),
3151 *EndLoc = T.getCloseLocation();
3158 ArgExprs.push_back(ArgExpr.
get());
3159 Attrs.
addNew(KWName, KWLoc, AttributeScopeInfo(), ArgExprs.data(), 1, Kind,
3164void Parser::DistributeCLateParsedAttrs(
Decl *Dcl,
3170 for (
auto *LateAttr : *LateAttrs) {
3171 if (LateAttr->Decls.empty())
3172 LateAttr->addDecl(Dcl);
3178 assert(Tok.is(tok::kw___ptrauth));
3180 IdentifierInfo *KwName = Tok.getIdentifierInfo();
3184 if (T.expectAndConsume())
3194 ArgExprs.push_back(ER.
get());
3198 SourceLocation EndLoc = T.getCloseLocation();
3200 if (ArgExprs.empty() || ArgExprs.size() > 3) {
3201 Diag(KwLoc, diag::err_ptrauth_qualifier_bad_arg_count);
3205 Attrs.
addNew(KwName, SourceRange(KwLoc, EndLoc), AttributeScopeInfo(),
3206 ArgExprs.data(), ArgExprs.size(),
3207 ParsedAttr::Form::Keyword(
false,
3217 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3222 if (Tok.is(tok::r_paren)) {
3223 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
3230 using ExpressionKind =
3232 EnterExpressionEvaluationContext EC(
3234 ExpressionKind::EK_AttrArgument);
3242 ArgExprs.push_back(ArgExpr.
get());
3245 ASTContext &Ctx = Actions.getASTContext();
3251 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
3252 AttributeScopeInfo(), ArgExprs.data(), ArgExprs.size(), Form);
3255ExprResult Parser::ParseExtIntegerArgument() {
3256 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3257 "Not an extended int type");
3261 if (T.expectAndConsume())
3270 if(T.consumeClose())
3277 DeclSpecContext DSContext,
3281 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3282 DSContext == DeclSpecContext::DSC_top_level);
3285 Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
3286 tok::annot_template_id) &&
3292 bool HasScope = Tok.is(tok::annot_cxxscope);
3294 Token AfterScope = HasScope ?
NextToken() : Tok;
3298 bool MightBeDeclarator =
true;
3299 if (Tok.isOneOf(tok::kw_typename, tok::annot_typename)) {
3301 MightBeDeclarator =
false;
3302 }
else if (AfterScope.
is(tok::annot_template_id)) {
3305 TemplateIdAnnotation *Annot =
3308 MightBeDeclarator =
false;
3309 }
else if (AfterScope.
is(tok::identifier)) {
3314 if (
Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3315 tok::annot_cxxscope, tok::coloncolon)) {
3317 MightBeDeclarator = false;
3318 }
else if (HasScope) {
3323 Actions.RestoreNestedNameSpecifierAnnotation(
3324 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
3326 Sema::NameClassification Classification = Actions.ClassifyName(
3329 switch (Classification.
getKind()) {
3335 llvm_unreachable(
"typo correction is not possible here");
3343 MightBeDeclarator =
false;
3358 if (MightBeDeclarator)
3361 const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
3363 diag::err_expected_after)
3374 ParsedTemplateInfo NotATemplate;
3375 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3379void Parser::ParseDeclarationSpecifiers(
3393 if (DSContext == DeclSpecContext::DSC_conv_operator)
3394 DSContext = DeclSpecContext::DSC_type_specifier;
3396 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3397 DSContext == DeclSpecContext::DSC_top_level);
3398 bool AttrsLastTime =
false;
3399 ParsedAttributes attrs(AttrFactory);
3401 PrintingPolicy Policy = Actions.getPrintingPolicy();
3404 bool isStorageClass =
false;
3405 const char *PrevSpec =
nullptr;
3406 unsigned DiagID = 0;
3410 SourceLocation ConsumedEnd;
3419 if (
getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&
3422 Tok.setKind(tok::identifier);
3424 SourceLocation Loc = Tok.getLocation();
3427 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3431 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
3432 Tok.setKind(tok::identifier);
3441 bool IsTemplateSpecOrInst =
3445 switch (Tok.getKind()) {
3447 if (Tok.isRegularKeywordAttribute())
3452 ProhibitAttributes(attrs);
3455 for (
const ParsedAttr &PA : attrs) {
3456 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3457 !PA.isRegularKeywordAttribute())
3465 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3466 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3473 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3474 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3477 if (PA.getKind() == ParsedAttr::AT_LifetimeBound)
3478 Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type)
3479 << PA << PA.isRegularKeywordAttribute()
3482 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3483 << PA << PA.isRegularKeywordAttribute();
3492 DS.
Finish(Actions, Policy);
3496 case tok::kw__Alignas:
3497 diagnoseUseOfC11Keyword(Tok);
3499 case tok::kw_alignas:
3505 if (Tok.getKind() == tok::kw_alignas)
3506 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
3512 if (!isAllowedCXX11AttributeSpecifier())
3513 goto DoneWithDeclSpec;
3516 ProhibitAttributes(attrs);
3521 attrs.Range = SourceRange();
3523 ParseCXX11Attributes(attrs);
3524 AttrsLastTime =
true;
3527 case tok::code_completion: {
3531 bool AllowNonIdentifiers
3537 bool AllowNestedNameSpecifiers
3538 = DSContext == DeclSpecContext::DSC_top_level ||
3542 Actions.CodeCompletion().CodeCompleteDeclSpec(
3543 getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3549 CCC = DSContext == DeclSpecContext::DSC_class
3552 else if (DSContext == DeclSpecContext::DSC_class)
3556 else if (CurParsedObjCImpl)
3560 Actions.CodeCompletion().CodeCompleteOrdinaryName(
getCurScope(), CCC);
3564 case tok::coloncolon:
3570 goto DoneWithDeclSpec;
3572 if (Tok.is(tok::coloncolon))
3573 goto DoneWithDeclSpec;
3576 case tok::annot_cxxscope: {
3578 goto DoneWithDeclSpec;
3581 if (TemplateInfo.TemplateParams)
3583 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
3584 Tok.getAnnotationRange(),
3590 TemplateIdAnnotation *TemplateId =
Next.is(tok::annot_template_id)
3591 ? takeTemplateIdAnnotation(
Next)
3597 ConsumeAnnotationToken();
3611 if ((DSContext == DeclSpecContext::DSC_top_level ||
3612 DSContext == DeclSpecContext::DSC_class) &&
3615 isConstructorDeclarator(
false,
3622 goto DoneWithDeclSpec;
3626 ConsumeAnnotationToken();
3627 assert(Tok.is(tok::annot_template_id) &&
3628 "ParseOptionalCXXScopeSpecifier not working");
3629 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3639 ConsumeAnnotationToken();
3643 if (
Next.is(tok::annot_typename)) {
3645 ConsumeAnnotationToken();
3648 Tok.getAnnotationEndLoc(),
3649 PrevSpec, DiagID, T, Policy);
3653 ConsumeAnnotationToken();
3657 Next.is(tok::annot_template_id) &&
3658 static_cast<TemplateIdAnnotation *
>(
Next.getAnnotationValue())
3661 ConsumeAnnotationToken();
3662 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3666 if (
Next.isNot(tok::identifier))
3667 goto DoneWithDeclSpec;
3672 if ((DSContext == DeclSpecContext::DSC_top_level ||
3673 DSContext == DeclSpecContext::DSC_class) &&
3676 isConstructorDeclarator(
false,
3680 goto DoneWithDeclSpec;
3686 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3690 false,
false,
nullptr,
3693 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3695 if (IsTemplateSpecOrInst)
3703 if (TryAnnotateTypeConstraint())
3704 goto DoneWithDeclSpec;
3705 if (Tok.isNot(tok::annot_cxxscope) ||
3709 ConsumeAnnotationToken();
3710 ParsedAttributes Attrs(AttrFactory);
3711 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3712 if (!Attrs.
empty()) {
3713 AttrsLastTime =
true;
3714 attrs.takeAllAppendingFrom(Attrs);
3718 goto DoneWithDeclSpec;
3722 ConsumeAnnotationToken();
3725 DiagID, TypeRep, Policy);
3735 case tok::annot_typename: {
3739 goto DoneWithDeclSpec;
3748 ConsumeAnnotationToken();
3753 case tok::kw___is_signed:
3765 TryKeywordIdentFallback(
true);
3768 goto DoneWithDeclSpec;
3771 case tok::kw___super:
3772 case tok::kw_decltype:
3773 case tok::identifier:
3779 goto DoneWithDeclSpec;
3785 if (!
getLangOpts().DeclSpecKeyword && Tok.is(tok::identifier) &&
3786 Tok.getIdentifierInfo()->getName() ==
"__declspec") {
3787 Diag(Loc, diag::err_ms_attributes_not_enabled);
3797 if (T.consumeOpen()) {
3798 assert(
false &&
"Not a left paren?");
3813 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3817 if (IsTemplateSpecOrInst)
3821 if (IsTemplateSpecOrInst)
3824 goto DoneWithDeclSpec;
3827 if (!Tok.is(tok::identifier))
3832 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID,
isInvalid))
3838 goto DoneWithDeclSpec;
3840 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3841 isObjCInstancetype()) {
3842 ParsedType TypeRep = Actions.ObjC().ActOnObjCInstanceType(Loc);
3845 DiagID, TypeRep, Policy);
3857 Actions.isCurrentClassName(*Tok.getIdentifierInfo(),
getCurScope()) &&
3858 isConstructorDeclarator(
true,
3861 goto DoneWithDeclSpec;
3864 *Tok.getIdentifierInfo(), Tok.getLocation(),
getCurScope(),
nullptr,
3865 false,
false,
nullptr,
false,
false,
3866 isClassTemplateDeductionContext(DSContext));
3871 if (TryAnnotateTypeConstraint())
3872 goto DoneWithDeclSpec;
3873 if (Tok.isNot(tok::identifier))
3875 ParsedAttributes Attrs(AttrFactory);
3876 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
3877 if (!Attrs.
empty()) {
3878 AttrsLastTime =
true;
3879 attrs.takeAllAppendingFrom(Attrs);
3883 goto DoneWithDeclSpec;
3890 (DSContext == DeclSpecContext::DSC_class ||
3891 DSContext == DeclSpecContext::DSC_top_level) &&
3892 Actions.isDeductionGuideName(
getCurScope(), *Tok.getIdentifierInfo(),
3893 Tok.getLocation(), SS) &&
3894 isConstructorDeclarator(
true,
3896 goto DoneWithDeclSpec;
3899 DiagID, TypeRep, Policy);
3910 SourceLocation NewEndLoc;
3911 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3926 case tok::annot_template_id: {
3927 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
3938 TemplateId =
nullptr;
3946 tok::kw_volatile, tok::kw_restrict, tok::amp,
3948 Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
3952 TemplateId, Policy);
3956 goto DoneWithDeclSpec;
3958 if (TemplateId && !
isInvalid && Actions.CheckTypeConstraint(TemplateId))
3959 TemplateId =
nullptr;
3961 ConsumeAnnotationToken();
3962 SourceLocation AutoLoc = Tok.getLocation();
3965 if (Tracker.consumeOpen()) {
3967 Diag(Tok, diag::err_expected) << tok::l_paren;
3971 Tracker.skipToEnd();
3972 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
3977 Tracker.consumeClose();
3980 ConsumedEnd = Tok.getLocation();
3985 DiagID, TemplateId, Policy);
3988 TemplateId, Policy);
3997 goto DoneWithDeclSpec;
4005 isConstructorDeclarator(
true,
4008 goto DoneWithDeclSpec;
4013 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
4018 case tok::kw___attribute:
4019 case tok::kw___declspec:
4020 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4024 case tok::kw___forceinline: {
4026 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
4027 SourceLocation AttrNameLoc = Tok.getLocation();
4029 nullptr, 0, tok::kw___forceinline);
4033 case tok::kw___unaligned:
4039 case tok::kw___ptrauth:
4043 case tok::kw___sptr:
4044 case tok::kw___uptr:
4045 case tok::kw___ptr64:
4046 case tok::kw___ptr32:
4048 case tok::kw___cdecl:
4049 case tok::kw___stdcall:
4050 case tok::kw___fastcall:
4051 case tok::kw___thiscall:
4052 case tok::kw___regcall:
4053 case tok::kw___vectorcall:
4057 case tok::kw___funcref:
4062 case tok::kw___pascal:
4067 case tok::kw___kernel:
4072 case tok::kw___noinline__:
4077 case tok::kw__Nonnull:
4078 case tok::kw__Nullable:
4079 case tok::kw__Nullable_result:
4080 case tok::kw__Null_unspecified:
4085 case tok::kw___kindof:
4087 AttributeScopeInfo(),
nullptr, 0,
4093 case tok::kw_typedef:
4095 PrevSpec, DiagID, Policy);
4096 isStorageClass =
true;
4098 case tok::kw_extern:
4100 Diag(Tok, diag::ext_thread_before) <<
"extern";
4102 PrevSpec, DiagID, Policy);
4103 isStorageClass =
true;
4105 case tok::kw___private_extern__:
4107 Loc, PrevSpec, DiagID, Policy);
4108 isStorageClass =
true;
4110 case tok::kw_static:
4112 Diag(Tok, diag::ext_thread_before) <<
"static";
4114 PrevSpec, DiagID, Policy);
4115 isStorageClass =
true;
4119 auto MayBeTypeSpecifier = [&]() {
4130 if (isKnownToBeTypeSpecifier(T))
4140 if (MayBeTypeSpecifier()) {
4142 PrevSpec, DiagID, Policy);
4144 Diag(Tok, diag::ext_auto_storage_class)
4151 PrevSpec, DiagID, Policy);
4152 isStorageClass =
true;
4154 case tok::kw___auto_type:
4155 Diag(Tok, diag::ext_auto_type);
4159 case tok::kw_register:
4161 PrevSpec, DiagID, Policy);
4162 isStorageClass =
true;
4164 case tok::kw_mutable:
4166 PrevSpec, DiagID, Policy);
4167 isStorageClass =
true;
4169 case tok::kw___thread:
4172 isStorageClass =
true;
4174 case tok::kw_thread_local:
4176 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4185 Loc, PrevSpec, DiagID);
4186 isStorageClass =
true;
4188 case tok::kw__Thread_local:
4189 diagnoseUseOfC11Keyword(Tok);
4191 Loc, PrevSpec, DiagID);
4192 isStorageClass =
true;
4196 case tok::kw_inline:
4199 case tok::kw_virtual:
4203 !
getActions().getOpenCLOptions().isAvailableOption(
4205 DiagID = diag::err_openclcxx_virtual_function;
4206 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4209 DiagID = diag::err_hlsl_virtual_function;
4210 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4216 case tok::kw_explicit: {
4217 SourceLocation ExplicitLoc = Loc;
4218 SourceLocation CloseParenLoc;
4220 ConsumedEnd = ExplicitLoc;
4222 if (Tok.is(tok::l_paren)) {
4225 ? diag::warn_cxx17_compat_explicit_bool
4226 : diag::ext_explicit_bool);
4228 ExprResult ExplicitExpr(
static_cast<Expr *
>(
nullptr));
4230 Tracker.consumeOpen();
4232 EnterExpressionEvaluationContext ConstantEvaluated(
4236 ConsumedEnd = Tok.getLocation();
4237 if (ExplicitExpr.isUsable()) {
4238 CloseParenLoc = Tok.getLocation();
4239 Tracker.consumeClose();
4241 Actions.ActOnExplicitBoolSpecifier(ExplicitExpr.get());
4243 Tracker.skipToEnd();
4245 Diag(Tok.getLocation(), diag::warn_cxx20_compat_explicit_bool);
4249 ExplicitSpec, CloseParenLoc);
4252 case tok::kw__Noreturn:
4253 diagnoseUseOfC11Keyword(Tok);
4258 case tok::kw_friend:
4259 if (DSContext == DeclSpecContext::DSC_class) {
4266 DiagID = diag::err_friend_invalid_in_context;
4272 case tok::kw___module_private__:
4277 case tok::kw_constexpr:
4279 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4283 case tok::kw_consteval:
4287 case tok::kw_constinit:
4295 Diag(Tok, diag::err_unknown_typename) << Tok.getName();
4299 goto DoneWithDeclSpec;
4310 PrevSpec, DiagID, Policy);
4312 case tok::kw___int64:
4314 PrevSpec, DiagID, Policy);
4316 case tok::kw_signed:
4320 case tok::kw_unsigned:
4324 case tok::kw__Complex:
4326 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4330 case tok::kw__Imaginary:
4332 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4348 case tok::kw__ExtInt:
4349 case tok::kw__BitInt: {
4350 DiagnoseBitIntUse(Tok);
4355 ConsumedEnd = PrevTokLocation;
4358 case tok::kw___int128:
4366 case tok::kw___bf16:
4374 case tok::kw_double:
4378 case tok::kw__Float16:
4382 case tok::kw__Accum:
4384 "This keyword is only used when fixed point types are enabled "
4385 "with `-ffixed-point`");
4389 case tok::kw__Fract:
4391 "This keyword is only used when fixed point types are enabled "
4392 "with `-ffixed-point`");
4398 "This keyword is only used when fixed point types are enabled "
4399 "with `-ffixed-point`");
4402 case tok::kw___float128:
4406 case tok::kw___ibm128:
4410 case tok::kw_wchar_t:
4414 case tok::kw_char8_t:
4418 case tok::kw_char16_t:
4422 case tok::kw_char32_t:
4428 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4432 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4434 if (Tok.is(tok::kw_bool) &&
4438 DiagID = diag::err_bool_redeclaration;
4440 Tok.setKind(tok::identifier);
4447 case tok::kw__Decimal32:
4451 case tok::kw__Decimal64:
4455 case tok::kw__Decimal128:
4459 case tok::kw___vector:
4462 case tok::kw___pixel:
4465 case tok::kw___bool:
4470 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4473 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
4474 Tok.setKind(tok::identifier);
4475 goto DoneWithDeclSpec;
4477 DiagID = diag::err_opencl_unknown_type_specifier;
4478 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4484#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4485#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4486#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4487 case tok::kw_##ImgType##_t: \
4488 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4489 goto DoneWithDeclSpec; \
4491#include "clang/Basic/OpenCLImageTypes.def"
4492 case tok::kw___unknown_anytype:
4494 PrevSpec, DiagID, Policy);
4499 case tok::kw_struct:
4500 case tok::kw___interface:
4501 case tok::kw_union: {
4508 ParsedAttributes Attributes(AttrFactory);
4509 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
4510 EnteringContext, DSContext, Attributes);
4514 if (!Attributes.empty()) {
4515 AttrsLastTime =
true;
4516 attrs.takeAllAppendingFrom(Attributes);
4524 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
4532 case tok::kw_volatile:
4536 case tok::kw_restrict:
4540 case tok::kw___ob_wrap:
4542 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
4547 OverflowBehaviorType::OverflowBehaviorKind::Wrap, Loc, PrevSpec,
4550 case tok::kw___ob_trap:
4552 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
4557 OverflowBehaviorType::OverflowBehaviorKind::Trap, Loc, PrevSpec,
4562 case tok::kw_typename:
4565 goto DoneWithDeclSpec;
4567 if (!Tok.is(tok::kw_typename))
4572 case tok::kw_typeof:
4573 case tok::kw_typeof_unqual:
4574 ParseTypeofSpecifier(DS);
4577 case tok::annot_decltype:
4578 ParseDecltypeSpecifier(DS);
4581 case tok::annot_pack_indexing_type:
4582 ParsePackIndexingType(DS);
4585 case tok::annot_pragma_pack:
4589 case tok::annot_pragma_ms_pragma:
4590 HandlePragmaMSPragma();
4593 case tok::annot_pragma_ms_vtordisp:
4594 HandlePragmaMSVtorDisp();
4597 case tok::annot_pragma_ms_pointers_to_members:
4598 HandlePragmaMSPointersToMembers();
4601 case tok::annot_pragma_export:
4602 HandlePragmaExport();
4605#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4606#include "clang/Basic/TransformTypeTraits.def"
4610 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4611 goto ParseIdentifier;
4614 case tok::kw__Atomic:
4619 diagnoseUseOfC11Keyword(Tok);
4621 ParseAtomicSpecifier(DS);
4629 case tok::kw___generic:
4634 if (!Actions.getLangOpts().OpenCLGenericAddressSpace) {
4635 DiagID = diag::err_opencl_unknown_type_specifier;
4636 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4641 case tok::kw_private:
4645 goto DoneWithDeclSpec;
4647 case tok::kw___private:
4648 case tok::kw___global:
4649 case tok::kw___local:
4650 case tok::kw___constant:
4652 case tok::kw___read_only:
4653 case tok::kw___write_only:
4654 case tok::kw___read_write:
4657 case tok::kw_row_major:
4658 case tok::kw_column_major:
4659 case tok::kw_groupshared:
4667#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
4668 case tok::kw_##Name: \
4669 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4672#include "clang/Basic/HLSLIntangibleTypes.def"
4679 goto DoneWithDeclSpec;
4681 SourceLocation StartLoc = Tok.getLocation();
4682 SourceLocation EndLoc;
4684 if (
Type.isUsable()) {
4686 PrevSpec, DiagID,
Type.get(),
4687 Actions.getASTContext().getPrintingPolicy()))
4688 Diag(StartLoc, DiagID) << PrevSpec;
4704 assert(PrevSpec &&
"Method did not return previous specifier!");
4707 if (DiagID == diag::ext_duplicate_declspec ||
4708 DiagID == diag::ext_warn_duplicate_declspec ||
4709 DiagID == diag::err_duplicate_declspec)
4710 Diag(Loc, DiagID) << PrevSpec
4713 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4717 Diag(Loc, DiagID) << PrevSpec;
4720 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4724 AttrsLastTime =
false;
4736 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4739 for (
auto *I : RD->decls()) {
4740 auto *VD = dyn_cast<ValueDecl>(I);
4748 for (
const auto &DD : CAT->dependent_decls()) {
4749 if (!RD->containsDecl(DD.getDecl())) {
4750 P.
Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4751 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4752 P.
Diag(DD.getDecl()->getBeginLoc(),
4753 diag::note_flexible_array_counted_by_attr_field)
4760void Parser::ParseStructDeclaration(
4765 if (Tok.is(tok::kw___extension__)) {
4767 ExtensionRAIIObject O(Diags);
4769 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4773 ParsedAttributes Attrs(AttrFactory);
4774 MaybeParseCXX11Attributes(Attrs);
4777 ParseSpecifierQualifierList(DS);
4781 if (Tok.is(tok::semi)) {
4786 ProhibitAttributes(Attrs);
4787 RecordDecl *AnonRecord =
nullptr;
4788 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
4790 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4796 bool FirstDeclarator =
true;
4797 SourceLocation CommaLoc;
4799 ParsingFieldDeclarator DeclaratorInfo(*
this, DS, Attrs);
4800 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4803 if (!FirstDeclarator) {
4806 DiagnoseAndSkipCXX11Attributes();
4807 MaybeParseGNUAttributes(DeclaratorInfo.D);
4808 DiagnoseAndSkipCXX11Attributes();
4813 if (Tok.isNot(tok::colon)) {
4816 ParseDeclarator(DeclaratorInfo.D);
4818 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.getLocation());
4830 DeclaratorInfo.BitfieldSize = Res.
get();
4834 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
4837 Decl *
Field = FieldsCallback(DeclaratorInfo);
4839 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
4846 FirstDeclarator =
false;
4855 "Attribute list should be marked for immediate parsing.");
4856 for (
auto *LA : LAs) {
4857 ParseLexedCAttribute(*LA,
EnterScope, OutAttrs);
4868 AttrEnd.startToken();
4869 AttrEnd.setKind(tok::eof);
4870 AttrEnd.setLocation(Tok.getLocation());
4871 AttrEnd.setEofData(LA.
Toks.data());
4872 LA.
Toks.push_back(AttrEnd);
4876 LA.
Toks.push_back(Tok);
4877 PP.EnterTokenStream(LA.
Toks,
true,
4886 ParsedAttributes Attrs(AttrFactory);
4888 assert(LA.
Decls.size() <= 1 &&
4889 "late field attribute expects to have at most one declaration.");
4893 SourceLocation(), ParsedAttr::Form::GNU(),
nullptr);
4895 for (
auto *D : LA.
Decls)
4896 Actions.ActOnFinishDelayedAttribute(
getCurScope(), D, Attrs);
4900 while (Tok.isNot(tok::eof))
4904 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
4914 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl,
RecordLoc,
4915 "parsing struct/union body");
4919 if (T.consumeOpen())
4923 Actions.ActOnTagStartDefinition(
getCurScope(), TagDecl);
4927 LateParsedAttrList LateFieldAttrs(
true,
4931 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
4932 Tok.isNot(tok::eof)) {
4936 if (Tok.is(tok::semi)) {
4942 if (Tok.isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4943 SourceLocation DeclEnd;
4944 ParseStaticAssertDeclaration(DeclEnd);
4948 if (Tok.is(tok::annot_pragma_pack)) {
4953 if (Tok.is(tok::annot_pragma_align)) {
4954 HandlePragmaAlign();
4958 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4961 ParsedAttributes Attrs(AttrFactory);
4962 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4966 if (Tok.is(tok::annot_pragma_openacc)) {
4968 ParsedAttributes Attrs(AttrFactory);
4974 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
4976 TagType, Actions.getASTContext().getPrintingPolicy());
4977 ConsumeAnnotationToken();
4981 if (!Tok.is(tok::at)) {
4982 auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
4986 FD.D.getDeclSpec().getSourceRange().getBegin(),
4987 FD.D, FD.BitfieldSize);
4993 ParsingDeclSpec DS(*
this);
4994 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
4997 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
4998 Diag(Tok, diag::err_unexpected_at);
5003 ExpectAndConsume(tok::l_paren);
5004 if (!Tok.is(tok::identifier)) {
5005 Diag(Tok, diag::err_expected) << tok::identifier;
5009 SmallVector<Decl *, 16> Fields;
5010 Actions.ObjC().ActOnDefs(
getCurScope(), TagDecl, Tok.getLocation(),
5011 Tok.getIdentifierInfo(), Fields);
5013 ExpectAndConsume(tok::r_paren);
5019 if (Tok.is(tok::r_brace)) {
5020 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
5024 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
5033 ParsedAttributes attrs(AttrFactory);
5035 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
5038 ParseLexedCAttributeList(LateFieldAttrs,
false);
5040 SmallVector<Decl *, 32> FieldDecls(TagDecl->
fields());
5043 T.getOpenLocation(), T.getCloseLocation(), attrs);
5045 Actions.ActOnTagFinishDefinition(
getCurScope(), TagDecl, T.getRange());
5049 const ParsedTemplateInfo &TemplateInfo,
5052 if (Tok.is(tok::code_completion)) {
5061 ParsedAttributes attrs(AttrFactory);
5062 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5064 SourceLocation ScopedEnumKWLoc;
5065 bool IsScopedUsingClassTag =
false;
5070 : diag::ext_scoped_enum);
5071 IsScopedUsingClassTag = Tok.is(tok::kw_class);
5076 ProhibitAttributes(attrs);
5079 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5088 bool shouldDelayDiagsInTag =
5091 SuppressAccessChecks diagsFromTag(*
this, shouldDelayDiagsInTag);
5094 AllowDefiningTypeSpec AllowEnumSpecifier =
5096 bool CanBeOpaqueEnumDeclaration =
5097 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5100 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5101 CanBeOpaqueEnumDeclaration);
5105 CXXScopeSpec InvalidDeclScope;
5113 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5118 if (Spec.
isSet() && Tok.isNot(tok::identifier)) {
5119 Diag(Tok, diag::err_expected) << tok::identifier;
5121 if (Tok.isNot(tok::l_brace)) {
5129 SS = std::move(Spec);
5133 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
5134 Tok.isNot(tok::colon)) {
5135 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5144 IdentifierInfo *Name =
nullptr;
5145 SourceLocation NameLoc;
5146 if (Tok.is(tok::identifier)) {
5147 Name = Tok.getIdentifierInfo();
5151 if (!Name && ScopedEnumKWLoc.
isValid()) {
5154 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5155 ScopedEnumKWLoc = SourceLocation();
5156 IsScopedUsingClassTag =
false;
5161 if (shouldDelayDiagsInTag)
5162 diagsFromTag.done();
5165 SourceRange BaseRange;
5167 bool CanBeBitfield =
5171 if (Tok.is(tok::colon)) {
5196 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5200 Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
5201 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5208 DeclSpec DS(AttrFactory);
5212 DeclSpecContext::DSC_type_specifier);
5215 BaseType = Actions.ActOnTypeName(DeclaratorInfo);
5217 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5221 DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)
5224 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5228 ? diag::warn_c17_compat_enum_fixed_underlying_type
5229 : diag::ext_c23_enum_fixed_underlying_type)
5246 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5248 else if (Tok.is(tok::l_brace)) {
5250 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
5256 ScopedEnumKWLoc = SourceLocation();
5257 IsScopedUsingClassTag =
false;
5263 }
else if (!isTypeSpecifier(DSC) &&
5264 (Tok.is(tok::semi) ||
5265 (Tok.isAtStartOfLine() &&
5266 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5271 if (Tok.isNot(tok::semi)) {
5273 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5274 PP.EnterToken(Tok,
true);
5275 Tok.setKind(tok::semi);
5281 bool IsElaboratedTypeSpecifier =
5287 diagsFromTag.redelay();
5295 Diag(Tok, diag::err_enum_template);
5303 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5307 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5309 TemplateInfo.TemplateParams->size());
5314 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5330 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5332 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5333 diag::err_keyword_not_allowed,
5336 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5337 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5338 else if (ScopedEnumKWLoc.
isValid())
5339 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5343 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5345 SkipBodyInfo SkipBody;
5348 SkipBody = Actions.shouldSkipAnonEnumBody(
getCurScope(),
5353 bool IsDependent =
false;
5354 const char *PrevSpec =
nullptr;
5359 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5360 IsScopedUsingClassTag,
5361 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5362 DSC == DeclSpecContext::DSC_template_param ||
5363 DSC == DeclSpecContext::DSC_template_type_arg,
5364 OffsetOfState, &SkipBody).get();
5374 NameLoc.
isValid() ? NameLoc : StartLoc,
5375 PrevSpec, DiagID, TagDecl, Owned,
5376 Actions.getASTContext().getPrintingPolicy()))
5377 Diag(StartLoc, DiagID) << PrevSpec;
5386 Diag(Tok, diag::err_expected_type_name_after_typename);
5392 if (
Type.isInvalid()) {
5398 NameLoc.
isValid() ? NameLoc : StartLoc,
5399 PrevSpec, DiagID,
Type.get(),
5400 Actions.getASTContext().getPrintingPolicy()))
5401 Diag(StartLoc, DiagID) << PrevSpec;
5420 ParseEnumBody(StartLoc, D, &SkipBody);
5422 !Actions.ActOnDuplicateDefinition(
getCurScope(), TagDecl, SkipBody)) {
5429 NameLoc.
isValid() ? NameLoc : StartLoc,
5430 PrevSpec, DiagID, TagDecl, Owned,
5431 Actions.getASTContext().getPrintingPolicy()))
5432 Diag(StartLoc, DiagID) << PrevSpec;
5439 Actions.ActOnTagStartDefinition(
getCurScope(), EnumDecl);
5447 Diag(T.getOpenLocation(), diag::ext_ms_c_empty_enum_type)
5448 << SourceRange(T.getOpenLocation(), Tok.
getLocation());
5450 Diag(Tok, diag::err_empty_enum);
5453 SmallVector<Decl *, 32> EnumConstantDecls;
5454 SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
5456 Decl *LastEnumConstDecl =
nullptr;
5459 while (Tok.isNot(tok::r_brace)) {
5462 if (Tok.isNot(tok::identifier)) {
5463 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
5469 IdentifierInfo *Ident = Tok.getIdentifierInfo();
5473 ParsedAttributes attrs(AttrFactory);
5474 MaybeParseGNUAttributes(attrs);
5475 if (isAllowedCXX11AttributeSpecifier()) {
5478 ? diag::warn_cxx14_compat_ns_enum_attribute
5479 : diag::ext_ns_enum_attribute)
5481 ParseCXX11Attributes(attrs);
5484 SourceLocation EqualLoc;
5486 EnumAvailabilityDiags.emplace_back(*
this);
5488 EnterExpressionEvaluationContext ConstantEvaluated(
5497 Decl *EnumConstDecl = Actions.ActOnEnumConstant(
5498 getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
5499 EqualLoc, AssignedVal.
get(), SkipBody);
5500 EnumAvailabilityDiags.back().done();
5502 EnumConstantDecls.push_back(EnumConstDecl);
5503 LastEnumConstDecl = EnumConstDecl;
5505 if (Tok.is(tok::identifier)) {
5508 Diag(Loc, diag::err_enumerator_list_missing_comma)
5515 SourceLocation CommaLoc;
5516 if (Tok.isNot(tok::r_brace) && !
TryConsumeToken(tok::comma, CommaLoc)) {
5518 Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
5521 Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
5531 if (Tok.is(tok::r_brace) && CommaLoc.
isValid()) {
5534 diag::ext_enumerator_list_comma_cxx :
5535 diag::ext_enumerator_list_comma_c)
5538 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5548 ParsedAttributes attrs(AttrFactory);
5549 MaybeParseGNUAttributes(attrs);
5551 Actions.ActOnEnumBody(StartLoc, T.getRange(), EnumDecl, EnumConstantDecls,
5555 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5556 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5558 EnumAvailabilityDiags[i].redelay();
5559 PD.complete(EnumConstantDecls[i]);
5563 Actions.ActOnTagFinishDefinition(
getCurScope(), EnumDecl, T.getRange());
5568 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5569 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5573 PP.EnterToken(Tok,
true);
5574 Tok.setKind(tok::semi);
5578bool Parser::isKnownToBeTypeSpecifier(
const Token &
Tok)
const {
5579 switch (Tok.getKind()) {
5580 default:
return false;
5584 case tok::kw___int64:
5585 case tok::kw___int128:
5586 case tok::kw_signed:
5587 case tok::kw_unsigned:
5588 case tok::kw__Complex:
5589 case tok::kw__Imaginary:
5592 case tok::kw_wchar_t:
5593 case tok::kw_char8_t:
5594 case tok::kw_char16_t:
5595 case tok::kw_char32_t:
5597 case tok::kw__ExtInt:
5598 case tok::kw__BitInt:
5599 case tok::kw___bf16:
5602 case tok::kw_double:
5603 case tok::kw__Accum:
5604 case tok::kw__Fract:
5605 case tok::kw__Float16:
5606 case tok::kw___float128:
5607 case tok::kw___ibm128:
5610 case tok::kw__Decimal32:
5611 case tok::kw__Decimal64:
5612 case tok::kw__Decimal128:
5613 case tok::kw___vector:
5614#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5615#include "clang/Basic/OpenCLImageTypes.def"
5616#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5617#include "clang/Basic/HLSLIntangibleTypes.def"
5621 case tok::kw_struct:
5622 case tok::kw___interface:
5627 case tok::kw_typeof:
5628 case tok::kw_typeof_unqual:
5631 case tok::kw__Atomic:
5634 case tok::annot_typename:
5639bool Parser::isTypeSpecifierQualifier(
const Token &
Tok) {
5640 switch (Tok.getKind()) {
5641 default:
return false;
5643 case tok::identifier:
5644 if (TryAltiVecVectorToken())
5647 case tok::kw_typename:
5656 case tok::coloncolon:
5666 case tok::kw___attribute:
5668 case tok::kw_typeof:
5669 case tok::kw_typeof_unqual:
5674 case tok::kw___int64:
5675 case tok::kw___int128:
5676 case tok::kw_signed:
5677 case tok::kw_unsigned:
5678 case tok::kw__Complex:
5679 case tok::kw__Imaginary:
5682 case tok::kw_wchar_t:
5683 case tok::kw_char8_t:
5684 case tok::kw_char16_t:
5685 case tok::kw_char32_t:
5687 case tok::kw__ExtInt:
5688 case tok::kw__BitInt:
5690 case tok::kw___bf16:
5692 case tok::kw_double:
5693 case tok::kw__Accum:
5694 case tok::kw__Fract:
5695 case tok::kw__Float16:
5696 case tok::kw___float128:
5697 case tok::kw___ibm128:
5700 case tok::kw__Decimal32:
5701 case tok::kw__Decimal64:
5702 case tok::kw__Decimal128:
5703 case tok::kw___vector:
5704#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5705#include "clang/Basic/OpenCLImageTypes.def"
5706#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5707#include "clang/Basic/HLSLIntangibleTypes.def"
5711 case tok::kw_struct:
5712 case tok::kw___interface:
5719 case tok::kw_volatile:
5720 case tok::kw_restrict:
5721 case tok::kw___ob_wrap:
5722 case tok::kw___ob_trap:
5726 case tok::kw___unknown_anytype:
5729 case tok::annot_typename:
5736 case tok::kw___cdecl:
5737 case tok::kw___stdcall:
5738 case tok::kw___fastcall:
5739 case tok::kw___thiscall:
5740 case tok::kw___regcall:
5741 case tok::kw___vectorcall:
5743 case tok::kw___ptr64:
5744 case tok::kw___ptr32:
5745 case tok::kw___pascal:
5746 case tok::kw___unaligned:
5747 case tok::kw___ptrauth:
5749 case tok::kw__Nonnull:
5750 case tok::kw__Nullable:
5751 case tok::kw__Nullable_result:
5752 case tok::kw__Null_unspecified:
5754 case tok::kw___kindof:
5756 case tok::kw___private:
5757 case tok::kw___local:
5758 case tok::kw___global:
5759 case tok::kw___constant:
5760 case tok::kw___generic:
5761 case tok::kw___read_only:
5762 case tok::kw___read_write:
5763 case tok::kw___write_only:
5764 case tok::kw___funcref:
5767 case tok::kw_private:
5771 case tok::kw__Atomic:
5775 case tok::kw_groupshared:
5779 case tok::kw_row_major:
5780 case tok::kw_column_major:
5786 assert(PP.isIncrementalProcessingEnabled() &&
"Not in incremental mode");
5790 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5793 TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5794 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5795 Actions.ActOnFinishTopLevelStmtDecl(TLSD,
R.get());
5797 R = Actions.ActOnNullStmt(Tok.getLocation());
5799 if (Tok.is(tok::annot_repl_input_end) &&
5800 Tok.getAnnotationValue() !=
nullptr) {
5801 ConsumeAnnotationToken();
5805 SmallVector<Decl *, 2> DeclsInGroup;
5806 DeclsInGroup.push_back(TLSD);
5809 for (Stmt *S : Stmts) {
5812 TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5813 Actions.ActOnFinishTopLevelStmtDecl(D, S);
5814 DeclsInGroup.push_back(D);
5817 return Actions.BuildDeclaratorGroup(DeclsInGroup);
5820bool Parser::isDeclarationSpecifier(
5822 bool DisambiguatingWithExpression) {
5823 switch (Tok.getKind()) {
5824 default:
return false;
5831 case tok::identifier:
5835 if (TryAltiVecVectorToken())
5838 case tok::kw_decltype:
5839 case tok::kw_typename:
5844 if (TryAnnotateTypeConstraint())
5846 if (Tok.is(tok::identifier))
5854 if (DisambiguatingWithExpression &&
5855 isStartOfObjCClassMessageMissingOpenBracket())
5858 return isDeclarationSpecifier(AllowImplicitTypename);
5860 case tok::coloncolon:
5874 case tok::kw_typedef:
5875 case tok::kw_extern:
5876 case tok::kw___private_extern__:
5877 case tok::kw_static:
5879 case tok::kw___auto_type:
5880 case tok::kw_register:
5881 case tok::kw___thread:
5882 case tok::kw_thread_local:
5883 case tok::kw__Thread_local:
5886 case tok::kw___module_private__:
5889 case tok::kw___unknown_anytype:
5894 case tok::kw___int64:
5895 case tok::kw___int128:
5896 case tok::kw_signed:
5897 case tok::kw_unsigned:
5898 case tok::kw__Complex:
5899 case tok::kw__Imaginary:
5902 case tok::kw_wchar_t:
5903 case tok::kw_char8_t:
5904 case tok::kw_char16_t:
5905 case tok::kw_char32_t:
5908 case tok::kw__ExtInt:
5909 case tok::kw__BitInt:
5911 case tok::kw___bf16:
5913 case tok::kw_double:
5914 case tok::kw__Accum:
5915 case tok::kw__Fract:
5916 case tok::kw__Float16:
5917 case tok::kw___float128:
5918 case tok::kw___ibm128:
5921 case tok::kw__Decimal32:
5922 case tok::kw__Decimal64:
5923 case tok::kw__Decimal128:
5924 case tok::kw___vector:
5928 case tok::kw_struct:
5930 case tok::kw___interface:
5936 case tok::kw_volatile:
5937 case tok::kw_restrict:
5938 case tok::kw___ob_wrap:
5939 case tok::kw___ob_trap:
5943 case tok::kw_inline:
5944 case tok::kw_virtual:
5945 case tok::kw_explicit:
5946 case tok::kw__Noreturn:
5949 case tok::kw__Alignas:
5952 case tok::kw_friend:
5955 case tok::kw_static_assert:
5956 case tok::kw__Static_assert:
5959 case tok::kw_typeof:
5960 case tok::kw_typeof_unqual:
5963 case tok::kw___attribute:
5966 case tok::annot_decltype:
5967 case tok::annot_pack_indexing_type:
5968 case tok::kw_constexpr:
5971 case tok::kw_consteval:
5972 case tok::kw_constinit:
5975 case tok::kw__Atomic:
5978 case tok::kw_alignas:
5988 case tok::annot_typename:
5989 return !DisambiguatingWithExpression ||
5990 !isStartOfObjCClassMessageMissingOpenBracket();
5993 case tok::annot_template_id: {
5994 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
5999 return isTypeConstraintAnnotation() &&
6003 case tok::annot_cxxscope: {
6004 TemplateIdAnnotation *TemplateId =
6012 if (
NextToken().
is(tok::identifier) && TryAnnotateTypeConstraint())
6014 return isTypeConstraintAnnotation() &&
6018 case tok::kw___declspec:
6019 case tok::kw___cdecl:
6020 case tok::kw___stdcall:
6021 case tok::kw___fastcall:
6022 case tok::kw___thiscall:
6023 case tok::kw___regcall:
6024 case tok::kw___vectorcall:
6026 case tok::kw___sptr:
6027 case tok::kw___uptr:
6028 case tok::kw___ptr64:
6029 case tok::kw___ptr32:
6030 case tok::kw___forceinline:
6031 case tok::kw___pascal:
6032 case tok::kw___unaligned:
6033 case tok::kw___ptrauth:
6035 case tok::kw__Nonnull:
6036 case tok::kw__Nullable:
6037 case tok::kw__Nullable_result:
6038 case tok::kw__Null_unspecified:
6040 case tok::kw___kindof:
6042 case tok::kw___private:
6043 case tok::kw___local:
6044 case tok::kw___global:
6045 case tok::kw___constant:
6046 case tok::kw___generic:
6047 case tok::kw___read_only:
6048 case tok::kw___read_write:
6049 case tok::kw___write_only:
6050#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
6051#include "clang/Basic/OpenCLImageTypes.def"
6052#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
6053#include "clang/Basic/HLSLIntangibleTypes.def"
6055 case tok::kw___funcref:
6056 case tok::kw_groupshared:
6059 case tok::kw_row_major:
6060 case tok::kw_column_major:
6063 case tok::kw_private:
6068bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
6070 const ParsedTemplateInfo *TemplateInfo) {
6071 RevertingTentativeParsingAction TPA(*
this);
6074 if (TemplateInfo && TemplateInfo->TemplateParams)
6077 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6084 if (Tok.is(tok::identifier)) {
6088 }
else if (Tok.is(tok::annot_template_id)) {
6089 ConsumeAnnotationToken();
6096 SkipCXX11Attributes();
6099 if (Tok.isNot(tok::l_paren)) {
6106 if (Tok.is(tok::r_paren) ||
6107 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren))) {
6113 if (isCXX11AttributeSpecifier(
false,
6120 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6122 DeclScopeObj.EnterDeclaratorScope();
6125 ParsedAttributes Attrs(AttrFactory);
6126 MaybeParseMicrosoftAttributes(Attrs);
6135 bool IsConstructor =
false;
6141 if (Tok.is(tok::kw_this)) {
6143 return isDeclarationSpecifier(ITC);
6146 if (isDeclarationSpecifier(ITC))
6147 IsConstructor =
true;
6148 else if (Tok.is(tok::identifier) ||
6149 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier))) {
6154 if (Tok.is(tok::annot_cxxscope))
6155 ConsumeAnnotationToken();
6161 switch (Tok.getKind()) {
6167 case tok::coloncolon:
6180 SkipCXX11Attributes();
6182 if (DeductionGuide) {
6184 IsConstructor = Tok.is(tok::arrow);
6187 if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
6191 IsConstructor =
true;
6193 if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {
6206 IsConstructor = IsUnqualified;
6211 IsConstructor =
true;
6215 return IsConstructor;
6218void Parser::ParseTypeQualifierListOpt(
6219 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicOrPtrauthAllowed,
6221 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6222 isAllowedCXX11AttributeSpecifier()) {
6223 ParsedAttributes Attrs(AttrFactory);
6224 ParseCXX11Attributes(Attrs);
6228 SourceLocation EndLoc;
6232 const char *PrevSpec =
nullptr;
6233 unsigned DiagID = 0;
6234 SourceLocation Loc = Tok.getLocation();
6236 switch (Tok.getKind()) {
6237 case tok::code_completion:
6239 if (CodeCompletionHandler)
6240 CodeCompletionHandler();
6242 Actions.CodeCompletion().CodeCompleteTypeQualifiers(DS);
6249 case tok::kw_volatile:
6253 case tok::kw_restrict:
6257 case tok::kw___ob_wrap:
6259 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6264 OverflowBehaviorType::OverflowBehaviorKind::Wrap, Loc, PrevSpec,
6267 case tok::kw___ob_trap:
6269 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6274 OverflowBehaviorType::OverflowBehaviorKind::Trap, Loc, PrevSpec,
6277 case tok::kw__Atomic:
6278 if (!AtomicOrPtrauthAllowed)
6279 goto DoneWithTypeQuals;
6280 diagnoseUseOfC11Keyword(Tok);
6286 case tok::kw_private:
6288 goto DoneWithTypeQuals;
6290 case tok::kw___private:
6291 case tok::kw___global:
6292 case tok::kw___local:
6293 case tok::kw___constant:
6294 case tok::kw___generic:
6295 case tok::kw___read_only:
6296 case tok::kw___write_only:
6297 case tok::kw___read_write:
6301 case tok::kw_groupshared:
6310 case tok::kw___ptrauth:
6311 if (!AtomicOrPtrauthAllowed)
6312 goto DoneWithTypeQuals;
6314 EndLoc = PrevTokLocation;
6317 case tok::kw___unaligned:
6321 case tok::kw___uptr:
6326 if (TryKeywordIdentFallback(
false))
6330 case tok::kw___sptr:
6332 case tok::kw___ptr64:
6333 case tok::kw___ptr32:
6334 case tok::kw___cdecl:
6335 case tok::kw___stdcall:
6336 case tok::kw___fastcall:
6337 case tok::kw___thiscall:
6338 case tok::kw___regcall:
6339 case tok::kw___vectorcall:
6340 if (AttrReqs & AR_DeclspecAttributesParsed) {
6344 goto DoneWithTypeQuals;
6346 case tok::kw___funcref:
6350 case tok::kw___pascal:
6351 if (AttrReqs & AR_VendorAttributesParsed) {
6355 goto DoneWithTypeQuals;
6358 case tok::kw__Nonnull:
6359 case tok::kw__Nullable:
6360 case tok::kw__Nullable_result:
6361 case tok::kw__Null_unspecified:
6366 case tok::kw___kindof:
6368 AttributeScopeInfo(),
nullptr, 0,
6373 case tok::kw___attribute:
6374 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6376 Diag(Tok, diag::err_attributes_not_allowed);
6380 if (AttrReqs & AR_GNUAttributesParsed ||
6381 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6391 DS.
Finish(Actions, Actions.getASTContext().getPrintingPolicy());
6399 assert(PrevSpec &&
"Method did not return previous specifier!");
6400 Diag(Tok, DiagID) << PrevSpec;
6409 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6410 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6416 if (Kind == tok::star || Kind == tok::caret)
6420 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6421 Lang.getOpenCLCompatibleVersion() >= 200)
6424 if (!Lang.CPlusPlus)
6427 if (Kind == tok::amp)
6435 if (Kind == tok::ampamp)
6446 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6453void Parser::ParseDeclaratorInternal(
Declarator &D,
6454 DirectDeclParseFunction DirectDeclParser) {
6455 if (Diags.hasAllExtensionsSilenced())
6462 (Tok.is(tok::coloncolon) || Tok.is(tok::kw_decltype) ||
6463 (Tok.is(tok::identifier) &&
6465 Tok.is(tok::annot_cxxscope))) {
6466 TentativeParsingAction TPA(*
this,
true);
6472 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6484 Tok.is(tok::star)) {
6488 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6489 CompoundToken::MemberPtr);
6494 DeclSpec DS(AttrFactory);
6495 ParseTypeQualifierListOpt(DS);
6499 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6500 ParseDeclaratorInternal(D, DirectDeclParser);
6514 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6524 AnnotateScopeToken(SS,
true);
6526 if (DirectDeclParser)
6527 (this->*DirectDeclParser)(D);
6535 DeclSpec DS(AttrFactory);
6536 ParseTypeQualifierListOpt(DS);
6545 if (DirectDeclParser)
6546 (this->*DirectDeclParser)(D);
6555 if (Kind == tok::star || Kind == tok::caret) {
6557 DeclSpec DS(AttrFactory);
6561 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6563 ? AR_GNUAttributesParsed
6564 : AR_GNUAttributesParsedAndRejected);
6565 ParseTypeQualifierListOpt(DS, Reqs,
true,
6570 Actions.runWithSufficientStackSpace(
6571 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6572 if (Kind == tok::star)
6587 DeclSpec DS(AttrFactory);
6591 if (Kind == tok::ampamp)
6593 diag::warn_cxx98_compat_rvalue_reference :
6594 diag::ext_rvalue_reference);
6597 ParseTypeQualifierListOpt(DS);
6606 diag::err_invalid_reference_qualifier_application) <<
"const";
6609 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6613 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6617 Actions.runWithSufficientStackSpace(
6618 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6625 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6628 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6657void Parser::ParseDirectDeclarator(
Declarator &D) {
6664 return ParseDecompositionDeclarator(D);
6678 ParseOptionalCXXScopeSpecifier(
6680 false, EnteringContext);
6695 if (Actions.ShouldEnterDeclaratorScope(
getCurScope(),
6699 DeclScopeObj.EnterDeclaratorScope();
6706 goto PastIdentifier;
6722 !Actions.containsUnexpandedParameterPacks(D) &&
6730 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6740 if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6744 bool AllowConstructorName;
6745 bool AllowDeductionGuide;
6747 AllowConstructorName =
false;
6748 AllowDeductionGuide =
false;
6752 AllowDeductionGuide =
false;
6760 SourceLocation TemplateKWLoc;
6765 true, AllowConstructorName,
6766 AllowDeductionGuide, &TemplateKWLoc,
6779 DeclScopeObj.EnterDeclaratorScope();
6786 goto PastIdentifier;
6792 diag::err_expected_unqualified_id)
6795 goto PastIdentifier;
6799 "There's a C++-specific check for tok::identifier above");
6800 assert(Tok.getIdentifierInfo() &&
"Not an identifier?");
6801 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6804 goto PastIdentifier;
6809 bool DiagnoseIdentifier =
false;
6813 DiagnoseIdentifier =
true;
6816 DiagnoseIdentifier =
6824 !isCXX11VirtSpecifier(Tok))
6826 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6827 if (DiagnoseIdentifier) {
6828 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
6832 goto PastIdentifier;
6836 if (Tok.is(tok::l_paren)) {
6841 RevertingTentativeParsingAction PA(*
this);
6846 goto PastIdentifier;
6853 ParseParenDeclarator(D);
6866 DeclScopeObj.EnterDeclaratorScope();
6877 diag::ext_abstract_pack_declarator_parens);
6879 if (Tok.getKind() == tok::annot_pragma_parser_crash)
6881 if (Tok.is(tok::l_square))
6882 return ParseMisplacedBracketDeclarator(D);
6887 !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
6888 Tok.getIdentifierInfo()->isCPlusPlusKeyword(
getLangOpts())) {
6890 diag::err_expected_member_name_or_semi_objcxx_keyword)
6891 << Tok.getIdentifierInfo()
6894 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6897 goto PastIdentifier;
6900 diag::err_expected_member_name_or_semi)
6904 if (Tok.getKind() == tok::TokenKind::kw_while) {
6905 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6907 if (Tok.isOneOf(tok::period, tok::arrow))
6908 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
6911 if (Tok.isAtStartOfLine() && Loc.
isValid())
6912 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
6916 diag::err_expected_unqualified_id)
6921 diag::err_expected_either)
6922 << tok::identifier << tok::l_paren;
6931 "Haven't past the location of the identifier yet?");
6935 MaybeParseCXX11Attributes(D);
6938 if (Tok.is(tok::l_paren)) {
6950 bool IsAmbiguous =
false;
6962 AllowImplicitTypename =
6970 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
6971 bool IsFunctionDecl =
6972 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
6973 TentativelyDeclaredIdentifiers.pop_back();
6974 if (!IsFunctionDecl)
6977 ParsedAttributes attrs(AttrFactory);
6980 if (IsFunctionDeclaration)
6981 Actions.ActOnStartFunctionDeclarationDeclarator(D,
6982 TemplateParameterDepth);
6983 ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
6984 if (IsFunctionDeclaration)
6985 Actions.ActOnFinishFunctionDeclarationDeclarator(D);
6986 PrototypeScope.Exit();
6987 }
else if (Tok.is(tok::l_square)) {
6988 ParseBracketDeclarator(D);
6989 }
else if (Tok.isRegularKeywordAttribute()) {
6991 Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();
6996 if (!T.consumeOpen())
7007 Diag(Tok, diag::err_requires_clause_inside_parens);
7021void Parser::ParseDecompositionDeclarator(
Declarator &D) {
7022 assert(Tok.is(tok::l_square));
7024 TentativeParsingAction PA(*
this);
7029 DiagnoseAndSkipCXX11Attributes();
7033 if (!(Tok.isOneOf(tok::identifier, tok::ellipsis) &&
7035 tok::identifier, tok::l_square, tok::ellipsis)) &&
7036 !(Tok.is(tok::r_square) &&
7039 return ParseMisplacedBracketDeclarator(D);
7042 SourceLocation PrevEllipsisLoc;
7043 SmallVector<DecompositionDeclarator::Binding, 32>
Bindings;
7044 while (Tok.isNot(tok::r_square)) {
7046 if (Tok.is(tok::comma))
7049 if (Tok.is(tok::identifier)) {
7051 Diag(EndLoc, diag::err_expected)
7054 Diag(Tok, diag::err_expected_comma_or_rsquare);
7057 SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis},
7059 if (Tok.is(tok::comma))
7061 else if (Tok.is(tok::r_square))
7066 if (isCXX11AttributeSpecifier() !=
7068 DiagnoseAndSkipCXX11Attributes();
7070 SourceLocation EllipsisLoc;
7072 if (Tok.is(tok::ellipsis)) {
7074 : diag::ext_cxx_binding_pack);
7075 if (PrevEllipsisLoc.
isValid()) {
7076 Diag(Tok, diag::err_binding_multiple_ellipses);
7077 Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
7080 EllipsisLoc = Tok.getLocation();
7081 PrevEllipsisLoc = EllipsisLoc;
7085 if (Tok.isNot(tok::identifier)) {
7086 Diag(Tok, diag::err_expected) << tok::identifier;
7090 IdentifierInfo *II = Tok.getIdentifierInfo();
7091 SourceLocation Loc = Tok.getLocation();
7094 if (Tok.is(tok::ellipsis) && !PrevEllipsisLoc.
isValid()) {
7095 DiagnoseMisplacedEllipsis(Tok.getLocation(), Loc, EllipsisLoc.
isValid(),
7097 EllipsisLoc = Tok.getLocation();
7101 ParsedAttributes Attrs(AttrFactory);
7102 if (isCXX11AttributeSpecifier() !=
7105 ? diag::warn_cxx23_compat_decl_attrs_on_binding
7106 : diag::ext_decl_attrs_on_binding);
7107 MaybeParseCXX11Attributes(Attrs);
7110 Bindings.push_back({II, Loc, std::move(Attrs), EllipsisLoc});
7113 if (Tok.isNot(tok::r_square))
7120 Diag(Tok.getLocation(), diag::ext_decomp_decl_empty);
7128 T.getCloseLocation());
7131void Parser::ParseParenDeclarator(
Declarator &D) {
7135 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7147 ParsedAttributes attrs(AttrFactory);
7148 bool RequiresArg =
false;
7149 if (Tok.is(tok::kw___attribute)) {
7150 ParseGNUAttributes(attrs);
7158 ParseMicrosoftTypeAttributes(attrs);
7161 if (Tok.is(tok::kw___pascal))
7162 ParseBorlandTypeAttributes(attrs);
7174 }
else if (Tok.is(tok::r_paren) ||
7176 Tok.is(tok::ellipsis) &&
7178 isDeclarationSpecifier(
7180 isCXX11AttributeSpecifier() !=
7200 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7205 std::move(attrs), T.getCloseLocation());
7211 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7229 ParseFunctionDeclarator(D, attrs, T,
false, RequiresArg);
7230 PrototypeScope.Exit();
7233void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7235 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7243 bool IsCXX11MemberFunction =
7250 Actions.CurContext->isRecord());
7251 if (!IsCXX11MemberFunction)
7271 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,
7272 IsCXX11MemberFunction);
7275void Parser::ParseFunctionDeclarator(
Declarator &D,
7280 assert(
getCurScope()->isFunctionPrototypeScope() &&
7281 "Should call from a Function scope");
7287 bool HasProto =
false;
7289 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
7291 SourceLocation EllipsisLoc;
7293 DeclSpec DS(AttrFactory);
7294 bool RefQualifierIsLValueRef =
true;
7295 SourceLocation RefQualifierLoc;
7297 SourceRange ESpecRange;
7298 SmallVector<ParsedType, 2> DynamicExceptions;
7299 SmallVector<SourceRange, 2> DynamicExceptionRanges;
7302 ParsedAttributes FnAttrs(AttrFactory);
7304 SourceLocation TrailingReturnTypeLoc;
7309 SourceLocation StartLoc, LocalEndLoc, EndLoc;
7310 SourceLocation LParenLoc, RParenLoc;
7312 StartLoc = LParenLoc;
7314 if (isFunctionDeclaratorIdentifierList()) {
7316 Diag(Tok, diag::err_argument_required_after_attribute);
7318 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7322 LocalEndLoc = RParenLoc;
7327 MaybeParseCXX11Attributes(FnAttrs);
7328 ProhibitAttributes(FnAttrs);
7330 if (Tok.isNot(tok::r_paren))
7331 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7332 else if (RequiresArg)
7333 Diag(Tok, diag::err_argument_required_after_attribute);
7344 LocalEndLoc = RParenLoc;
7353 ParseTypeQualifierListOpt(
7354 DS, AR_NoAttributesParsed,
7357 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);
7364 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7365 EndLoc = RefQualifierLoc;
7367 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7368 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7385 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
7402 ESpecType = tryParseExceptionSpecification(Delayed,
7405 DynamicExceptionRanges,
7407 ExceptionSpecTokens);
7409 EndLoc = ESpecRange.
getEnd();
7413 MaybeParseCXX11Attributes(FnAttrs);
7416 LocalEndLoc = EndLoc;
7418 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7421 LocalEndLoc = Tok.getLocation();
7423 TrailingReturnType =
7425 TrailingReturnTypeLoc =
Range.getBegin();
7426 EndLoc =
Range.getEnd();
7429 MaybeParseCXX11Attributes(FnAttrs);
7437 SmallVector<NamedDecl *, 0> DeclsInPrototype;
7440 NamedDecl *ND = dyn_cast<NamedDecl>(D);
7443 DeclsInPrototype.push_back(ND);
7450 llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) {
7458 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7459 ParamInfo.size(), EllipsisLoc, RParenLoc,
7460 RefQualifierIsLValueRef, RefQualifierLoc,
7462 ESpecType, ESpecRange, DynamicExceptions.data(),
7463 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7464 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7465 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7466 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7468 std::move(FnAttrs), EndLoc);
7471bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7473 if (Tok.isOneOf(tok::amp, tok::ampamp)) {
7475 diag::warn_cxx98_compat_ref_qualifier :
7476 diag::ext_ref_qualifier);
7478 RefQualifierIsLValueRef = Tok.is(tok::amp);
7485bool Parser::isFunctionDeclaratorIdentifierList() {
7487 && Tok.is(tok::identifier)
7488 && !TryAltiVecVectorToken()
7504 && (!Tok.is(tok::eof) &&
7508void Parser::ParseFunctionDeclaratorIdentifierList(
7512 assert(!
getLangOpts().requiresStrictPrototypes() &&
7513 "Cannot parse an identifier list in C23 or C++");
7520 Diag(Tok, diag::ext_ident_list_in_param);
7523 llvm::SmallPtrSet<const IdentifierInfo *, 16> ParamsSoFar;
7527 if (Tok.isNot(tok::identifier)) {
7528 Diag(Tok, diag::err_expected) << tok::identifier;
7535 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
7538 if (Actions.getTypeName(*ParmII, Tok.getLocation(),
getCurScope()))
7539 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7542 if (!ParamsSoFar.insert(ParmII).second) {
7543 Diag(Tok, diag::err_param_redefinition) << ParmII;
7546 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7557void Parser::ParseParameterDeclarationClause(
7566 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7568 Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)
7587 IsACXXFunctionDeclaration) {
7599 DeclSpec DS(AttrFactory);
7601 ParsedAttributes ArgDeclAttrs(AttrFactory);
7602 ParsedAttributes ArgDeclSpecAttrs(AttrFactory);
7609 ArgDeclSpecAttrs.takeAllPrependingFrom(FirstArgAttrs);
7612 MaybeParseCXX11Attributes(ArgDeclAttrs);
7615 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7618 SourceLocation DSStart = Tok.getLocation();
7622 SourceLocation ThisLoc;
7626 ParsedTemplateInfo TemplateInfo;
7627 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7628 DeclSpecContext::DSC_normal,
7629 nullptr, AllowImplicitTypename);
7642 ParseDeclarator(ParmDeclarator);
7645 ParmDeclarator.SetRangeBegin(ThisLoc);
7648 MaybeParseGNUAttributes(ParmDeclarator);
7652 if (Tok.is(tok::kw_requires)) {
7657 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7663 const IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
7667 std::unique_ptr<CachedTokens> DefArgToks;
7671 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7672 ParmDeclarator.getNumTypeObjects() == 0) {
7674 Diag(DSStart, diag::err_missing_param);
7681 if (Tok.is(tok::ellipsis) &&
7683 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7684 !Actions.isUnexpandedParameterPackPermitted())) &&
7685 Actions.containsUnexpandedParameterPacks(ParmDeclarator))
7686 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7705 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7706 Tok.isNot(tok::raw_identifier) && !Tok.isAnnotation() &&
7707 Tok.getIdentifierInfo() &&
7708 Tok.getIdentifierInfo()->isKeyword(
getLangOpts())) {
7709 Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok);
7718 Diag(ParmDeclarator.getBeginLoc(),
7719 diag::err_function_parameter_limit_exceeded);
7727 Actions.ActOnParamDeclarator(
getCurScope(), ParmDeclarator, ThisLoc);
7732 if (Tok.is(tok::equal)) {
7733 SourceLocation EqualLoc = Tok.getLocation();
7743 ConsumeAndStoreInitializer(*DefArgToks,
7745 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
7753 EnterExpressionEvaluationContext Eval(
7760 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7761 DefArgResult = ParseBraceInitializer();
7763 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
7764 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7765 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7774 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7779 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
7780 DefArgResult.
get());
7785 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7786 ParmDeclarator.getIdentifierLoc(),
7787 Param, std::move(DefArgToks)));
7795 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
7802 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7804 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7805 Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {
7808 SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();
7809 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7810 << ParmEllipsis.
isValid() << ParmEllipsis;
7813 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7815 Diag(ParmDeclarator.getIdentifierLoc(),
7816 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7819 << !ParmDeclarator.hasName();
7821 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7833void Parser::ParseBracketDeclarator(
Declarator &D) {
7834 if (CheckProhibitedCXX11Attribute())
7842 if (Tok.getKind() == tok::r_square) {
7844 ParsedAttributes attrs(AttrFactory);
7845 MaybeParseCXX11Attributes(attrs);
7849 T.getOpenLocation(),
7850 T.getCloseLocation()),
7851 std::move(attrs), T.getCloseLocation());
7853 }
else if (Tok.getKind() == tok::numeric_constant &&
7860 ParsedAttributes attrs(AttrFactory);
7861 MaybeParseCXX11Attributes(attrs);
7865 T.getOpenLocation(),
7866 T.getCloseLocation()),
7867 std::move(attrs), T.getCloseLocation());
7869 }
else if (Tok.getKind() == tok::code_completion) {
7871 Actions.CodeCompletion().CodeCompleteBracketDeclarator(
getCurScope());
7876 SourceLocation StaticLoc;
7881 DeclSpec DS(AttrFactory);
7882 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
7890 bool isStar =
false;
7901 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7902 StaticLoc = SourceLocation();
7905 }
else if (Tok.isNot(tok::r_square)) {
7922 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7923 StaticLoc = SourceLocation();
7942 isStar, NumElements.
get(), T.getOpenLocation(),
7943 T.getCloseLocation()),
7947void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
7948 assert(Tok.is(tok::l_square) &&
"Missing opening bracket");
7951 SourceLocation StartBracketLoc = Tok.getLocation();
7955 while (Tok.is(tok::l_square)) {
7956 ParseBracketDeclarator(TempDeclarator);
7962 if (Tok.is(tok::semi))
7965 SourceLocation SuggestParenLoc = Tok.getLocation();
7968 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7973 if (TempDeclarator.getNumTypeObjects() == 0)
7977 bool NeedParens =
false;
7996 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
8002 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
8003 const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
8004 D.
AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());
8009 if (!D.
hasName() && !NeedParens)
8012 SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();
8015 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
8016 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
8019 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8024 EndLoc, CharSourceRange(BracketRange,
true))
8027 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8030 EndLoc, CharSourceRange(BracketRange,
true))
8035void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
8036 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
8037 "Not a typeof specifier");
8039 bool IsUnqual = Tok.is(tok::kw_typeof_unqual);
8040 const IdentifierInfo *II = Tok.getIdentifierInfo();
8042 Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName();
8046 bool HasParens = Tok.is(tok::l_paren);
8054 SourceRange CastRange;
8056 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);
8072 const char *PrevSpec =
nullptr;
8079 Actions.getASTContext().getPrintingPolicy()))
8080 Diag(StartLoc, DiagID) << PrevSpec;
8091 Operand = Actions.HandleExprEvaluationContextForTypeof(
Operand.get());
8097 const char *PrevSpec =
nullptr;
8104 Actions.getASTContext().getPrintingPolicy()))
8105 Diag(StartLoc, DiagID) << PrevSpec;
8108void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
8109 assert(Tok.is(tok::kw__Atomic) &&
NextToken().
is(tok::l_paren) &&
8110 "Not an atomic specifier");
8114 if (T.consumeOpen())
8118 if (
Result.isInvalid()) {
8126 if (T.getCloseLocation().isInvalid())
8132 const char *PrevSpec =
nullptr;
8136 Actions.getASTContext().getPrintingPolicy()))
8137 Diag(StartLoc, DiagID) << PrevSpec;
8140bool Parser::TryAltiVecVectorTokenOutOfLine() {
8142 switch (
Next.getKind()) {
8143 default:
return false;
8146 case tok::kw_signed:
8147 case tok::kw_unsigned:
8152 case tok::kw_double:
8155 case tok::kw___bool:
8156 case tok::kw___pixel:
8157 Tok.setKind(tok::kw___vector);
8159 case tok::identifier:
8160 if (
Next.getIdentifierInfo() == Ident_pixel) {
8161 Tok.setKind(tok::kw___vector);
8164 if (
Next.getIdentifierInfo() == Ident_bool ||
8165 Next.getIdentifierInfo() == Ident_Bool) {
8166 Tok.setKind(tok::kw___vector);
8174 const char *&PrevSpec,
unsigned &DiagID,
8176 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
8177 if (Tok.getIdentifierInfo() == Ident_vector) {
8179 switch (
Next.getKind()) {
8182 case tok::kw_signed:
8183 case tok::kw_unsigned:
8188 case tok::kw_double:
8191 case tok::kw___bool:
8192 case tok::kw___pixel:
8195 case tok::identifier:
8196 if (
Next.getIdentifierInfo() == Ident_pixel) {
8200 if (
Next.getIdentifierInfo() == Ident_bool ||
8201 Next.getIdentifierInfo() == Ident_Bool) {
8210 }
else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
8214 }
else if ((Tok.getIdentifierInfo() == Ident_bool) &&
8222TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8225 SmallVector<Token, 4> Tokens;
8228 auto &SourceMgr = PP.getSourceManager();
8229 FileID FID = SourceMgr.createFileID(
8230 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8234 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8235 L.setParsingPreprocessorDirective(
true);
8241 Tokens.push_back(Tok);
8242 }
while (Tok.isNot(tok::eod));
8247 Token &EndToken = Tokens.back();
8254 Tokens.push_back(Tok);
8257 PP.EnterTokenStream(Tokens,
false,
8272 (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {
8273 Diag(Tok.getLocation(), diag::err_type_unparsed);
8278 while (Tok.isNot(tok::eof))
8282 if (Tok.is(tok::eof) && Tok.getEofData() == TypeStr.data())
8287void Parser::DiagnoseBitIntUse(
const Token &
Tok) {
8291 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8292 "expected either an _ExtInt or _BitInt token!");
8294 SourceLocation Loc = Tok.getLocation();
8295 if (Tok.is(tok::kw__ExtInt)) {
8296 Diag(Loc, diag::warn_ext_int_deprecated)
8302 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)
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
bool mayHaveIdentifier() const
mayHaveIdentifier - Return true if the identifier is either optional or required.
void setGroupingParens(bool flag)
SourceLocation getEllipsisLoc() const
DeclaratorContext getContext() const
SourceLocation getBeginLoc() const LLVM_READONLY
void setTrailingRequiresClause(Expr *TRC)
Sets a trailing requires clause for this declarator.
void setHasInitializer(bool Val=true)
UnqualifiedId & getName()
Retrieve the name specified by this declarator.
void setTemplateParameterLists(ArrayRef< TemplateParameterList * > TPLs)
Sets the template parameter lists that preceded the declarator.
bool isFirstDeclarator() const
bool hasTrailingRequiresClause() const
Determine whether a trailing requires clause was written in this declarator.
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
The template parameter lists that preceded the declarator.
bool isFunctionDeclaratorAFunctionDeclaration() const
Return true if a function declarator at this position would be a function declaration.
void clear()
Reset the contents of this Declarator.
void setAsmLabel(Expr *E)
void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &&attrs, SourceLocation EndLoc)
AddTypeInfo - Add a chunk to this declarator.
void ExtendWithDeclSpec(const DeclSpec &DS)
ExtendWithDeclSpec - Extend the declarator source range to include the given declspec,...
void SetRangeEnd(SourceLocation Loc)
SetRangeEnd - Set the end of the source range to Loc, unless it's invalid.
void setExtension(bool Val=true)
bool isInvalidType() const
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
void setEllipsisLoc(SourceLocation EL)
const IdentifierInfo * getIdentifier() const
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code from FromRange at a specific location.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
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()
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.
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
ExprResult ParseConstantExpressionInExprEvalContext(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
SmallVector< Stmt *, 24 > StmtVector
A SmallVector of statements.
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
friend class ColonProtectionRAIIObject
DeclGroupPtrTy ParseOpenACCDirectiveDecl(AccessSpecifier &AS, ParsedAttributes &Attrs, DeclSpec::TST TagType, Decl *TagDecl)
Parse OpenACC directive on a declaration.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
const Token & GetLookAheadToken(unsigned N)
GetLookAheadToken - This peeks ahead N tokens and returns that token without consuming any tokens.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
ExprResult ParseArrayBoundExpression()
friend struct LateParsedAttribute
const TargetInfo & getTargetInfo() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
const Token & getCurToken() const
void ExitScope()
ExitScope - Pop a scope off the scope stack.
const LangOptions & getLangOpts() const
friend class ParenBraceBracketBalancer
ExprResult ParseExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtCodeCompletion
Stop at code completion.
@ StopAtSemi
Stop skipping at semicolon.
ExprResult ParseUnevaluatedStringLiteralExpression()
ObjCContainerDecl * getObjCDeclContext() const
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
friend class BalancedDelimiterTracker
SmallVector< TemplateParameterList *, 4 > TemplateParameterLists
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
A class for parsing a DeclSpec.
A class for parsing a declarator.
A class for parsing a field declarator.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
SourceManager & getSourceManager() const
const LangOptions & getLangOpts() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
void addAddressSpace(LangAS space)
static Qualifiers fromCVRUMask(unsigned CVRU)
Represents a struct/union/class.
field_range fields() const
bool isClassScope() const
isClassScope - Return true if this scope is a class/struct/union scope.
unsigned getFlags() const
getFlags - Return the flags for this scope.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ BlockScope
This is a scope that corresponds to a block/closure object.
@ FriendScope
This is a scope of friend declaration.
@ ControlScope
The controlling scope in a if/switch/while/for statement.
@ AtCatchScope
This is a scope that corresponds to the Objective-C @catch statement.
@ TemplateParamScope
This is a scope that corresponds to the template parameters of a C++ template.
@ CompoundStmtScope
This is a compound statement scope.
@ ClassScope
The scope of a struct/union/class definition.
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ EnumScope
This scope corresponds to an enum.
@ DeclScope
This is a scope that can contain a declaration.
@ CTCK_InitGlobalVar
Unknown context.
ParserCompletionContext
Describes the context in which code completion occurs.
@ PCC_LocalDeclarationSpecifiers
Code completion occurs within a sequence of declaration specifiers within a function,...
@ PCC_MemberTemplate
Code completion occurs following one or more template headers within a class.
@ PCC_Class
Code completion occurs within a class, struct, or union.
@ PCC_ObjCImplementation
Code completion occurs within an Objective-C implementation or category implementation.
@ PCC_Namespace
Code completion occurs at top-level or namespace context.
@ PCC_Template
Code completion occurs following one or more template headers.
NameClassificationKind getKind() const
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
@ PotentiallyEvaluatedIfUsed
The current expression is potentially evaluated, but any declarations referenced inside that expressi...
void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl)
ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an initializer for the declaratio...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
A RAII object used to temporarily suppress access-like checking.
Represents the declaration of a struct/union/class/enum.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
void setKind(tok::TokenKind K)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
void * getAnnotationValue() const
tok::TokenKind getKind() const
bool isOneOf(Ts... Ks) const
void setEofData(const void *D)
void setLocation(SourceLocation L)
void startToken()
Reset all flags to cleared.
void setSemiMissing(bool Missing=true)
static constexpr int FunctionTypeNumParamsLimit
SourceLocation EndLocation
The location of the last token that describes this unqualified-id.
SourceRange getSourceRange() const LLVM_READONLY
Return the source range that covers this unqualified-id.
SourceLocation StartLocation
The location of the first token that describes this unqualified-id, which will be the location of the...
UnqualifiedIdKind getKind() const
Determine what kind of name we have.
Declaration of a variable template.
static const char * getSpecifierName(Specifier VS)
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
bool InitScope(InterpState &S, CodePtr OpPC, uint32_t I)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
const char * getKeywordSpelling(TokenKind Kind) LLVM_READNONE
Determines the spelling of simple keyword and contextual keyword tokens like 'int' and 'dynamic_cast'...
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isPragmaAnnotation(TokenKind K)
Return true if this is an annotation token representing a pragma.
The JSON file list parser is used to communicate input to InstallAPI.
TypeSpecifierType
Specifies the kind of type.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
bool isa(CodeGen::Address addr)
@ NotAttributeSpecifier
This is not an attribute specifier.
@ AttributeSpecifier
This should be treated as an attribute-specifier.
@ InvalidAttributeSpecifier
The next tokens are '[[', but this is not an attribute-specifier.
@ ExpectedParameterOrImplicitObjectParameter
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
@ IK_TemplateId
A template-id, e.g., f<int>.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
ActionResult< Decl * > DeclResult
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
llvm::SmallVector< ArgsUnion, 12U > ArgsVector
Language
The language for the input, used to select and validate the language standard and possible actions.
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
@ Template
We are parsing a template declaration.
@ ExplicitSpecialization
We are parsing an explicit specialization.
@ ExplicitInstantiation
We are parsing an explicit instantiation.
@ NonTemplate
We are not parsing a template at all.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
@ FunctionTemplate
The name was classified as a function template name.
@ Keyword
The name has been typo-corrected to a keyword.
@ DependentNonType
The name denotes a member of a dependent type that could not be resolved.
@ UndeclaredTemplate
The name was classified as an ADL-only function template name.
@ NonType
The name was classified as a specific non-type, non-template declaration.
@ Unknown
This name is not a type or template in this context, but might be something else.
@ Error
Classification failed; an error has been produced.
@ Type
The name was classified as a type.
@ TypeTemplate
The name was classified as a template whose specializations are types.
@ Concept
The name was classified as a concept name.
@ OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ UndeclaredNonType
The name was classified as an ADL-only function name.
@ VarTemplate
The name was classified as a variable template name.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Dependent_template_name
The name refers to a dependent template name:
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &&Second)
Consumes the attributes from Second and concatenates them at the end of First.
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
ActionResult< Expr * > ExprResult
@ Parens
New-expression has a C++98 paren-delimited initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_None
no exception specification
ActionResult< Stmt * > StmtResult
VersionTuple Version
The version number at which the change occurred.
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
SourceRange VersionRange
The source range covering the version number.
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, SourceLocation AtomicQualLoc, SourceLocation UnalignedQualLoc, SourceLocation OverflowBehaviorLoc={}, bool OverflowBehaviorIsWrap=false)
Return a DeclaratorChunk for a pointer.
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, ArrayRef< NamedDecl * > DeclsInPrototype, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult(), SourceLocation TrailingReturnTypeLoc=SourceLocation(), DeclSpec *MethodQualifiers=nullptr)
DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
static DeclaratorChunk getPipe(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc)
Return a DeclaratorChunk for an array.
SourceLocation Loc
Loc - The place where this type was defined.
static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, unsigned TypeQuals, SourceLocation StarLoc, SourceLocation EndLoc)
enum clang::DeclaratorChunk::@340323374315200305336204205154073066142310370142 Kind
static DeclaratorChunk getParen(SourceLocation LParenLoc, SourceLocation RParenLoc)
Return a DeclaratorChunk for a paren.
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, bool lvalue)
Return a DeclaratorChunk for a reference.
Contains the lexed tokens of an attribute with arguments that may reference member variables and so n...
IdentifierInfo & AttrName
SourceLocation AttrNameLoc
SmallVector< Decl *, 2 > Decls
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