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;
4854 AttrEnd.startToken();
4855 AttrEnd.setKind(tok::eof);
4856 AttrEnd.setLocation(Tok.getLocation());
4857 AttrEnd.setEofData(LA.
Toks.data());
4858 LA.
Toks.push_back(AttrEnd);
4862 LA.
Toks.push_back(Tok);
4863 PP.EnterTokenStream(LA.
Toks,
true,
4869 ParsedAttributes Attrs(AttrFactory);
4871 assert(LA.
Decls.size() <= 1 &&
4872 "late field attribute expects to have at most one declaration.");
4876 SourceLocation(), ParsedAttr::Form::GNU(),
nullptr);
4880 while (Tok.isNot(tok::eof))
4884 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
4892 ParsedAttributes Attrs = ParseLexedCAttributeTokens(LA);
4898 Self->ParseLexedTypeAttribute(*
this, OutAttrs);
4903 LateParsedAttrList::iterator It =
4911 From.erase(It, From.end());
4916 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl,
RecordLoc,
4917 "parsing struct/union body");
4921 if (T.consumeOpen())
4925 Actions.ActOnTagStartDefinition(
getCurScope(), TagDecl);
4929 LateParsedAttrList LateFieldAttrs(
true,
4933 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
4934 Tok.isNot(tok::eof)) {
4938 if (Tok.is(tok::semi)) {
4944 if (Tok.isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4945 SourceLocation DeclEnd;
4946 ParseStaticAssertDeclaration(DeclEnd);
4950 if (Tok.is(tok::annot_pragma_pack)) {
4955 if (Tok.is(tok::annot_pragma_align)) {
4956 HandlePragmaAlign();
4960 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4963 ParsedAttributes Attrs(AttrFactory);
4964 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4968 if (Tok.is(tok::annot_pragma_openacc)) {
4970 ParsedAttributes Attrs(AttrFactory);
4976 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
4978 TagType, Actions.getASTContext().getPrintingPolicy());
4979 ConsumeAnnotationToken();
4983 if (!Tok.is(tok::at)) {
4984 auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
4988 FD.D.getDeclSpec().getSourceRange().getBegin(),
4989 FD.D, FD.BitfieldSize);
4995 ParsingDeclSpec DS(*
this);
4996 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
4999 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
5000 Diag(Tok, diag::err_unexpected_at);
5005 ExpectAndConsume(tok::l_paren);
5006 if (!Tok.is(tok::identifier)) {
5007 Diag(Tok, diag::err_expected) << tok::identifier;
5011 SmallVector<Decl *, 16> Fields;
5012 Actions.ObjC().ActOnDefs(
getCurScope(), TagDecl, Tok.getLocation(),
5013 Tok.getIdentifierInfo(), Fields);
5015 ExpectAndConsume(tok::r_paren);
5021 if (Tok.is(tok::r_brace)) {
5022 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
5026 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
5035 ParsedAttributes attrs(AttrFactory);
5037 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
5039 SmallVector<Decl *, 32> FieldDecls(TagDecl->
fields());
5042 T.getOpenLocation(), T.getCloseLocation(), attrs);
5045 ParseLexedAttributeList(LateFieldAttrs,
nullptr,
false,
5048 Actions.ActOnTagFinishDefinition(
getCurScope(), TagDecl, T.getRange());
5052 const ParsedTemplateInfo &TemplateInfo,
5055 if (Tok.is(tok::code_completion)) {
5064 ParsedAttributes attrs(AttrFactory);
5065 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5067 SourceLocation ScopedEnumKWLoc;
5068 bool IsScopedUsingClassTag =
false;
5073 : diag::ext_scoped_enum);
5074 IsScopedUsingClassTag = Tok.is(tok::kw_class);
5079 ProhibitAttributes(attrs);
5082 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5091 bool shouldDelayDiagsInTag =
5094 SuppressAccessChecks diagsFromTag(*
this, shouldDelayDiagsInTag);
5097 AllowDefiningTypeSpec AllowEnumSpecifier =
5099 bool CanBeOpaqueEnumDeclaration =
5100 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5103 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5104 CanBeOpaqueEnumDeclaration);
5108 CXXScopeSpec InvalidDeclScope;
5116 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5121 if (Spec.
isSet() && Tok.isNot(tok::identifier)) {
5122 Diag(Tok, diag::err_expected) << tok::identifier;
5124 if (Tok.isNot(tok::l_brace)) {
5132 SS = std::move(Spec);
5136 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
5137 Tok.isNot(tok::colon)) {
5138 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5147 IdentifierInfo *Name =
nullptr;
5148 SourceLocation NameLoc;
5149 if (Tok.is(tok::identifier)) {
5150 Name = Tok.getIdentifierInfo();
5154 if (!Name && ScopedEnumKWLoc.
isValid()) {
5157 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5158 ScopedEnumKWLoc = SourceLocation();
5159 IsScopedUsingClassTag =
false;
5164 if (shouldDelayDiagsInTag)
5165 diagsFromTag.done();
5168 SourceRange BaseRange;
5170 bool CanBeBitfield =
5174 if (Tok.is(tok::colon)) {
5199 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5203 Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
5204 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5211 DeclSpec DS(AttrFactory);
5215 DeclSpecContext::DSC_type_specifier);
5218 BaseType = Actions.ActOnTypeName(DeclaratorInfo);
5220 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5224 DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)
5227 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5231 ? diag::warn_c17_compat_enum_fixed_underlying_type
5232 : diag::ext_c23_enum_fixed_underlying_type)
5249 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5251 else if (Tok.is(tok::l_brace)) {
5253 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
5259 ScopedEnumKWLoc = SourceLocation();
5260 IsScopedUsingClassTag =
false;
5266 }
else if (!isTypeSpecifier(DSC) &&
5267 (Tok.is(tok::semi) ||
5268 (Tok.isAtStartOfLine() &&
5269 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5274 if (Tok.isNot(tok::semi)) {
5276 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5277 PP.EnterToken(Tok,
true);
5278 Tok.setKind(tok::semi);
5284 bool IsElaboratedTypeSpecifier =
5290 diagsFromTag.redelay();
5298 Diag(Tok, diag::err_enum_template);
5306 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5310 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5312 TemplateInfo.TemplateParams->size());
5317 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5333 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5335 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5336 diag::err_keyword_not_allowed,
5339 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5340 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5341 else if (ScopedEnumKWLoc.
isValid())
5342 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5346 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5348 SkipBodyInfo SkipBody;
5351 SkipBody = Actions.shouldSkipAnonEnumBody(
getCurScope(),
5356 bool IsDependent =
false;
5357 const char *PrevSpec =
nullptr;
5362 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5363 IsScopedUsingClassTag,
5364 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5365 DSC == DeclSpecContext::DSC_template_param ||
5366 DSC == DeclSpecContext::DSC_template_type_arg,
5367 OffsetOfState, &SkipBody).get();
5377 NameLoc.
isValid() ? NameLoc : StartLoc,
5378 PrevSpec, DiagID, TagDecl, Owned,
5379 Actions.getASTContext().getPrintingPolicy()))
5380 Diag(StartLoc, DiagID) << PrevSpec;
5389 Diag(Tok, diag::err_expected_type_name_after_typename);
5395 if (
Type.isInvalid()) {
5401 NameLoc.
isValid() ? NameLoc : StartLoc,
5402 PrevSpec, DiagID,
Type.get(),
5403 Actions.getASTContext().getPrintingPolicy()))
5404 Diag(StartLoc, DiagID) << PrevSpec;
5423 ParseEnumBody(StartLoc, D, &SkipBody);
5425 !Actions.ActOnDuplicateDefinition(
getCurScope(), TagDecl, SkipBody)) {
5432 NameLoc.
isValid() ? NameLoc : StartLoc,
5433 PrevSpec, DiagID, TagDecl, Owned,
5434 Actions.getASTContext().getPrintingPolicy()))
5435 Diag(StartLoc, DiagID) << PrevSpec;
5442 Actions.ActOnTagStartDefinition(
getCurScope(), EnumDecl);
5450 Diag(T.getOpenLocation(), diag::ext_ms_c_empty_enum_type)
5451 << SourceRange(T.getOpenLocation(), Tok.
getLocation());
5453 Diag(Tok, diag::err_empty_enum);
5456 SmallVector<Decl *, 32> EnumConstantDecls;
5457 SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
5459 Decl *LastEnumConstDecl =
nullptr;
5462 while (Tok.isNot(tok::r_brace)) {
5465 if (Tok.isNot(tok::identifier)) {
5466 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
5472 IdentifierInfo *Ident = Tok.getIdentifierInfo();
5476 ParsedAttributes attrs(AttrFactory);
5477 MaybeParseGNUAttributes(attrs);
5478 if (isAllowedCXX11AttributeSpecifier()) {
5481 ? diag::warn_cxx14_compat_ns_enum_attribute
5482 : diag::ext_ns_enum_attribute)
5484 ParseCXX11Attributes(attrs);
5487 SourceLocation EqualLoc;
5489 EnumAvailabilityDiags.emplace_back(*
this);
5491 EnterExpressionEvaluationContext ConstantEvaluated(
5500 Decl *EnumConstDecl = Actions.ActOnEnumConstant(
5501 getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
5502 EqualLoc, AssignedVal.
get(), SkipBody);
5503 EnumAvailabilityDiags.back().done();
5505 EnumConstantDecls.push_back(EnumConstDecl);
5506 LastEnumConstDecl = EnumConstDecl;
5508 if (Tok.is(tok::identifier)) {
5511 Diag(Loc, diag::err_enumerator_list_missing_comma)
5518 SourceLocation CommaLoc;
5519 if (Tok.isNot(tok::r_brace) && !
TryConsumeToken(tok::comma, CommaLoc)) {
5521 Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
5524 Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
5534 if (Tok.is(tok::r_brace) && CommaLoc.
isValid()) {
5537 diag::ext_enumerator_list_comma_cxx :
5538 diag::ext_enumerator_list_comma_c)
5541 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5551 ParsedAttributes attrs(AttrFactory);
5552 MaybeParseGNUAttributes(attrs);
5554 Actions.ActOnEnumBody(StartLoc, T.getRange(), EnumDecl, EnumConstantDecls,
5558 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5559 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5561 EnumAvailabilityDiags[i].redelay();
5562 PD.complete(EnumConstantDecls[i]);
5566 Actions.ActOnTagFinishDefinition(
getCurScope(), EnumDecl, T.getRange());
5571 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5572 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5576 PP.EnterToken(Tok,
true);
5577 Tok.setKind(tok::semi);
5581bool Parser::isKnownToBeTypeSpecifier(
const Token &
Tok)
const {
5582 switch (Tok.getKind()) {
5583 default:
return false;
5587 case tok::kw___int64:
5588 case tok::kw___int128:
5589 case tok::kw_signed:
5590 case tok::kw_unsigned:
5591 case tok::kw__Complex:
5592 case tok::kw__Imaginary:
5595 case tok::kw_wchar_t:
5596 case tok::kw_char8_t:
5597 case tok::kw_char16_t:
5598 case tok::kw_char32_t:
5600 case tok::kw__ExtInt:
5601 case tok::kw__BitInt:
5602 case tok::kw___bf16:
5605 case tok::kw_double:
5606 case tok::kw__Accum:
5607 case tok::kw__Fract:
5608 case tok::kw__Float16:
5609 case tok::kw___float128:
5610 case tok::kw___ibm128:
5613 case tok::kw__Decimal32:
5614 case tok::kw__Decimal64:
5615 case tok::kw__Decimal128:
5616 case tok::kw___vector:
5617#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5618#include "clang/Basic/OpenCLImageTypes.def"
5619#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5620#include "clang/Basic/HLSLIntangibleTypes.def"
5624 case tok::kw_struct:
5625 case tok::kw___interface:
5630 case tok::kw_typeof:
5631 case tok::kw_typeof_unqual:
5634 case tok::kw__Atomic:
5637 case tok::annot_typename:
5642bool Parser::isTypeSpecifierQualifier(
const Token &
Tok) {
5643 switch (Tok.getKind()) {
5644 default:
return false;
5646 case tok::identifier:
5647 if (TryAltiVecVectorToken())
5650 case tok::kw_typename:
5659 case tok::coloncolon:
5669 case tok::kw___attribute:
5671 case tok::kw_typeof:
5672 case tok::kw_typeof_unqual:
5677 case tok::kw___int64:
5678 case tok::kw___int128:
5679 case tok::kw_signed:
5680 case tok::kw_unsigned:
5681 case tok::kw__Complex:
5682 case tok::kw__Imaginary:
5685 case tok::kw_wchar_t:
5686 case tok::kw_char8_t:
5687 case tok::kw_char16_t:
5688 case tok::kw_char32_t:
5690 case tok::kw__ExtInt:
5691 case tok::kw__BitInt:
5693 case tok::kw___bf16:
5695 case tok::kw_double:
5696 case tok::kw__Accum:
5697 case tok::kw__Fract:
5698 case tok::kw__Float16:
5699 case tok::kw___float128:
5700 case tok::kw___ibm128:
5703 case tok::kw__Decimal32:
5704 case tok::kw__Decimal64:
5705 case tok::kw__Decimal128:
5706 case tok::kw___vector:
5707#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5708#include "clang/Basic/OpenCLImageTypes.def"
5709#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5710#include "clang/Basic/HLSLIntangibleTypes.def"
5714 case tok::kw_struct:
5715 case tok::kw___interface:
5722 case tok::kw_volatile:
5723 case tok::kw_restrict:
5724 case tok::kw___ob_wrap:
5725 case tok::kw___ob_trap:
5729 case tok::kw___unknown_anytype:
5732 case tok::annot_typename:
5739 case tok::kw___cdecl:
5740 case tok::kw___stdcall:
5741 case tok::kw___fastcall:
5742 case tok::kw___thiscall:
5743 case tok::kw___regcall:
5744 case tok::kw___vectorcall:
5746 case tok::kw___ptr64:
5747 case tok::kw___ptr32:
5748 case tok::kw___pascal:
5749 case tok::kw___unaligned:
5750 case tok::kw___ptrauth:
5752 case tok::kw__Nonnull:
5753 case tok::kw__Nullable:
5754 case tok::kw__Nullable_result:
5755 case tok::kw__Null_unspecified:
5757 case tok::kw___kindof:
5759 case tok::kw___private:
5760 case tok::kw___local:
5761 case tok::kw___global:
5762 case tok::kw___constant:
5763 case tok::kw___generic:
5764 case tok::kw___read_only:
5765 case tok::kw___read_write:
5766 case tok::kw___write_only:
5767 case tok::kw___funcref:
5770 case tok::kw_private:
5774 case tok::kw__Atomic:
5778 case tok::kw_groupshared:
5782 case tok::kw_row_major:
5783 case tok::kw_column_major:
5789 assert(PP.isIncrementalProcessingEnabled() &&
"Not in incremental mode");
5793 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5796 TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5797 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5798 Actions.ActOnFinishTopLevelStmtDecl(TLSD,
R.get());
5800 R = Actions.ActOnNullStmt(Tok.getLocation());
5802 if (Tok.is(tok::annot_repl_input_end) &&
5803 Tok.getAnnotationValue() !=
nullptr) {
5804 ConsumeAnnotationToken();
5808 SmallVector<Decl *, 2> DeclsInGroup;
5809 DeclsInGroup.push_back(TLSD);
5812 for (Stmt *S : Stmts) {
5815 TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5816 Actions.ActOnFinishTopLevelStmtDecl(D, S);
5817 DeclsInGroup.push_back(D);
5820 return Actions.BuildDeclaratorGroup(DeclsInGroup);
5823bool Parser::isDeclarationSpecifier(
5825 bool DisambiguatingWithExpression) {
5826 switch (Tok.getKind()) {
5827 default:
return false;
5834 case tok::identifier:
5838 if (TryAltiVecVectorToken())
5841 case tok::kw_decltype:
5842 case tok::kw_typename:
5847 if (TryAnnotateTypeConstraint())
5849 if (Tok.is(tok::identifier))
5857 if (DisambiguatingWithExpression &&
5858 isStartOfObjCClassMessageMissingOpenBracket())
5861 return isDeclarationSpecifier(AllowImplicitTypename);
5863 case tok::coloncolon:
5877 case tok::kw_typedef:
5878 case tok::kw_extern:
5879 case tok::kw___private_extern__:
5880 case tok::kw_static:
5882 case tok::kw___auto_type:
5883 case tok::kw_register:
5884 case tok::kw___thread:
5885 case tok::kw_thread_local:
5886 case tok::kw__Thread_local:
5889 case tok::kw___module_private__:
5892 case tok::kw___unknown_anytype:
5897 case tok::kw___int64:
5898 case tok::kw___int128:
5899 case tok::kw_signed:
5900 case tok::kw_unsigned:
5901 case tok::kw__Complex:
5902 case tok::kw__Imaginary:
5905 case tok::kw_wchar_t:
5906 case tok::kw_char8_t:
5907 case tok::kw_char16_t:
5908 case tok::kw_char32_t:
5911 case tok::kw__ExtInt:
5912 case tok::kw__BitInt:
5914 case tok::kw___bf16:
5916 case tok::kw_double:
5917 case tok::kw__Accum:
5918 case tok::kw__Fract:
5919 case tok::kw__Float16:
5920 case tok::kw___float128:
5921 case tok::kw___ibm128:
5924 case tok::kw__Decimal32:
5925 case tok::kw__Decimal64:
5926 case tok::kw__Decimal128:
5927 case tok::kw___vector:
5931 case tok::kw_struct:
5933 case tok::kw___interface:
5939 case tok::kw_volatile:
5940 case tok::kw_restrict:
5941 case tok::kw___ob_wrap:
5942 case tok::kw___ob_trap:
5946 case tok::kw_inline:
5947 case tok::kw_virtual:
5948 case tok::kw_explicit:
5949 case tok::kw__Noreturn:
5952 case tok::kw__Alignas:
5955 case tok::kw_friend:
5958 case tok::kw_static_assert:
5959 case tok::kw__Static_assert:
5962 case tok::kw_typeof:
5963 case tok::kw_typeof_unqual:
5966 case tok::kw___attribute:
5969 case tok::annot_decltype:
5970 case tok::annot_pack_indexing_type:
5971 case tok::kw_constexpr:
5974 case tok::kw_consteval:
5975 case tok::kw_constinit:
5978 case tok::kw__Atomic:
5981 case tok::kw_alignas:
5991 case tok::annot_typename:
5992 return !DisambiguatingWithExpression ||
5993 !isStartOfObjCClassMessageMissingOpenBracket();
5996 case tok::annot_template_id: {
5997 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
6002 return isTypeConstraintAnnotation() &&
6006 case tok::annot_cxxscope: {
6007 TemplateIdAnnotation *TemplateId =
6015 if (
NextToken().
is(tok::identifier) && TryAnnotateTypeConstraint())
6017 return isTypeConstraintAnnotation() &&
6021 case tok::kw___declspec:
6022 case tok::kw___cdecl:
6023 case tok::kw___stdcall:
6024 case tok::kw___fastcall:
6025 case tok::kw___thiscall:
6026 case tok::kw___regcall:
6027 case tok::kw___vectorcall:
6029 case tok::kw___sptr:
6030 case tok::kw___uptr:
6031 case tok::kw___ptr64:
6032 case tok::kw___ptr32:
6033 case tok::kw___forceinline:
6034 case tok::kw___pascal:
6035 case tok::kw___unaligned:
6036 case tok::kw___ptrauth:
6038 case tok::kw__Nonnull:
6039 case tok::kw__Nullable:
6040 case tok::kw__Nullable_result:
6041 case tok::kw__Null_unspecified:
6043 case tok::kw___kindof:
6045 case tok::kw___private:
6046 case tok::kw___local:
6047 case tok::kw___global:
6048 case tok::kw___constant:
6049 case tok::kw___generic:
6050 case tok::kw___read_only:
6051 case tok::kw___read_write:
6052 case tok::kw___write_only:
6053#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
6054#include "clang/Basic/OpenCLImageTypes.def"
6055#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
6056#include "clang/Basic/HLSLIntangibleTypes.def"
6058 case tok::kw___funcref:
6059 case tok::kw_groupshared:
6062 case tok::kw_row_major:
6063 case tok::kw_column_major:
6066 case tok::kw_private:
6071bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
6073 const ParsedTemplateInfo *TemplateInfo) {
6074 RevertingTentativeParsingAction TPA(*
this);
6077 if (TemplateInfo && TemplateInfo->TemplateParams)
6080 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6087 if (Tok.is(tok::identifier)) {
6091 }
else if (Tok.is(tok::annot_template_id)) {
6092 ConsumeAnnotationToken();
6099 SkipCXX11Attributes();
6102 if (Tok.isNot(tok::l_paren)) {
6109 if (Tok.is(tok::r_paren) ||
6110 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren))) {
6116 if (isCXX11AttributeSpecifier(
false,
6123 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6125 DeclScopeObj.EnterDeclaratorScope();
6128 ParsedAttributes Attrs(AttrFactory);
6129 MaybeParseMicrosoftAttributes(Attrs);
6138 bool IsConstructor =
false;
6144 if (Tok.is(tok::kw_this)) {
6146 return isDeclarationSpecifier(ITC);
6149 if (isDeclarationSpecifier(ITC))
6150 IsConstructor =
true;
6151 else if (Tok.is(tok::identifier) ||
6152 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier))) {
6157 if (Tok.is(tok::annot_cxxscope))
6158 ConsumeAnnotationToken();
6164 switch (Tok.getKind()) {
6170 case tok::coloncolon:
6183 SkipCXX11Attributes();
6185 if (DeductionGuide) {
6187 IsConstructor = Tok.is(tok::arrow);
6190 if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
6194 IsConstructor =
true;
6196 if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {
6209 IsConstructor = IsUnqualified;
6214 IsConstructor =
true;
6218 return IsConstructor;
6221void Parser::ParseTypeQualifierListOpt(
6222 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicOrPtrauthAllowed,
6224 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6225 isAllowedCXX11AttributeSpecifier()) {
6226 ParsedAttributes Attrs(AttrFactory);
6227 ParseCXX11Attributes(Attrs);
6231 SourceLocation EndLoc;
6235 const char *PrevSpec =
nullptr;
6236 unsigned DiagID = 0;
6237 SourceLocation Loc = Tok.getLocation();
6239 switch (Tok.getKind()) {
6240 case tok::code_completion:
6242 if (CodeCompletionHandler)
6243 CodeCompletionHandler();
6245 Actions.CodeCompletion().CodeCompleteTypeQualifiers(DS);
6252 case tok::kw_volatile:
6256 case tok::kw_restrict:
6260 case tok::kw___ob_wrap:
6262 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6267 OverflowBehaviorType::OverflowBehaviorKind::Wrap, Loc, PrevSpec,
6270 case tok::kw___ob_trap:
6272 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6277 OverflowBehaviorType::OverflowBehaviorKind::Trap, Loc, PrevSpec,
6280 case tok::kw__Atomic:
6281 if (!AtomicOrPtrauthAllowed)
6282 goto DoneWithTypeQuals;
6283 diagnoseUseOfC11Keyword(Tok);
6289 case tok::kw_private:
6291 goto DoneWithTypeQuals;
6293 case tok::kw___private:
6294 case tok::kw___global:
6295 case tok::kw___local:
6296 case tok::kw___constant:
6297 case tok::kw___generic:
6298 case tok::kw___read_only:
6299 case tok::kw___write_only:
6300 case tok::kw___read_write:
6304 case tok::kw_groupshared:
6313 case tok::kw___ptrauth:
6314 if (!AtomicOrPtrauthAllowed)
6315 goto DoneWithTypeQuals;
6317 EndLoc = PrevTokLocation;
6320 case tok::kw___unaligned:
6324 case tok::kw___uptr:
6329 if (TryKeywordIdentFallback(
false))
6333 case tok::kw___sptr:
6335 case tok::kw___ptr64:
6336 case tok::kw___ptr32:
6337 case tok::kw___cdecl:
6338 case tok::kw___stdcall:
6339 case tok::kw___fastcall:
6340 case tok::kw___thiscall:
6341 case tok::kw___regcall:
6342 case tok::kw___vectorcall:
6343 if (AttrReqs & AR_DeclspecAttributesParsed) {
6347 goto DoneWithTypeQuals;
6349 case tok::kw___funcref:
6353 case tok::kw___pascal:
6354 if (AttrReqs & AR_VendorAttributesParsed) {
6358 goto DoneWithTypeQuals;
6361 case tok::kw__Nonnull:
6362 case tok::kw__Nullable:
6363 case tok::kw__Nullable_result:
6364 case tok::kw__Null_unspecified:
6369 case tok::kw___kindof:
6371 AttributeScopeInfo(),
nullptr, 0,
6376 case tok::kw___attribute:
6377 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6379 Diag(Tok, diag::err_attributes_not_allowed);
6383 if (AttrReqs & AR_GNUAttributesParsed ||
6384 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6394 DS.
Finish(Actions, Actions.getASTContext().getPrintingPolicy());
6402 assert(PrevSpec &&
"Method did not return previous specifier!");
6403 Diag(Tok, DiagID) << PrevSpec;
6412 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6413 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6419 if (Kind == tok::star || Kind == tok::caret)
6423 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6424 Lang.getOpenCLCompatibleVersion() >= 200)
6427 if (!Lang.CPlusPlus)
6430 if (Kind == tok::amp)
6438 if (Kind == tok::ampamp)
6449 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6456void Parser::ParseDeclaratorInternal(
Declarator &D,
6457 DirectDeclParseFunction DirectDeclParser) {
6458 if (Diags.hasAllExtensionsSilenced())
6465 (Tok.is(tok::coloncolon) || Tok.is(tok::kw_decltype) ||
6466 (Tok.is(tok::identifier) &&
6468 Tok.is(tok::annot_cxxscope))) {
6469 TentativeParsingAction TPA(*
this,
true);
6475 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6487 Tok.is(tok::star)) {
6491 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6492 CompoundToken::MemberPtr);
6497 DeclSpec DS(AttrFactory);
6498 ParseTypeQualifierListOpt(DS);
6502 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6503 ParseDeclaratorInternal(D, DirectDeclParser);
6517 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6527 AnnotateScopeToken(SS,
true);
6529 if (DirectDeclParser)
6530 (this->*DirectDeclParser)(D);
6538 DeclSpec DS(AttrFactory);
6539 ParseTypeQualifierListOpt(DS);
6548 if (DirectDeclParser)
6549 (this->*DirectDeclParser)(D);
6558 if (Kind == tok::star || Kind == tok::caret) {
6560 DeclSpec DS(AttrFactory);
6564 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6566 ? AR_GNUAttributesParsed
6567 : AR_GNUAttributesParsedAndRejected);
6568 ParseTypeQualifierListOpt(DS, Reqs,
true,
6573 Actions.runWithSufficientStackSpace(
6574 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6575 if (Kind == tok::star)
6590 DeclSpec DS(AttrFactory);
6594 if (Kind == tok::ampamp)
6596 diag::warn_cxx98_compat_rvalue_reference :
6597 diag::ext_rvalue_reference);
6600 ParseTypeQualifierListOpt(DS);
6609 diag::err_invalid_reference_qualifier_application) <<
"const";
6612 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6616 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6620 Actions.runWithSufficientStackSpace(
6621 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6628 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6631 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6660void Parser::ParseDirectDeclarator(
Declarator &D) {
6667 return ParseDecompositionDeclarator(D);
6681 ParseOptionalCXXScopeSpecifier(
6683 false, EnteringContext);
6698 if (Actions.ShouldEnterDeclaratorScope(
getCurScope(),
6702 DeclScopeObj.EnterDeclaratorScope();
6709 goto PastIdentifier;
6725 !Actions.containsUnexpandedParameterPacks(D) &&
6733 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6743 if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6747 bool AllowConstructorName;
6748 bool AllowDeductionGuide;
6750 AllowConstructorName =
false;
6751 AllowDeductionGuide =
false;
6755 AllowDeductionGuide =
false;
6763 SourceLocation TemplateKWLoc;
6768 true, AllowConstructorName,
6769 AllowDeductionGuide, &TemplateKWLoc,
6782 DeclScopeObj.EnterDeclaratorScope();
6789 goto PastIdentifier;
6795 diag::err_expected_unqualified_id)
6798 goto PastIdentifier;
6802 "There's a C++-specific check for tok::identifier above");
6803 assert(Tok.getIdentifierInfo() &&
"Not an identifier?");
6804 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6807 goto PastIdentifier;
6812 bool DiagnoseIdentifier =
false;
6816 DiagnoseIdentifier =
true;
6819 DiagnoseIdentifier =
6827 !isCXX11VirtSpecifier(Tok))
6829 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6830 if (DiagnoseIdentifier) {
6831 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
6835 goto PastIdentifier;
6839 if (Tok.is(tok::l_paren)) {
6844 RevertingTentativeParsingAction PA(*
this);
6849 goto PastIdentifier;
6856 ParseParenDeclarator(D);
6869 DeclScopeObj.EnterDeclaratorScope();
6880 diag::ext_abstract_pack_declarator_parens);
6882 if (Tok.getKind() == tok::annot_pragma_parser_crash)
6884 if (Tok.is(tok::l_square))
6885 return ParseMisplacedBracketDeclarator(D);
6890 !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
6891 Tok.getIdentifierInfo()->isCPlusPlusKeyword(
getLangOpts())) {
6893 diag::err_expected_member_name_or_semi_objcxx_keyword)
6894 << Tok.getIdentifierInfo()
6897 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6900 goto PastIdentifier;
6903 diag::err_expected_member_name_or_semi)
6907 if (Tok.getKind() == tok::TokenKind::kw_while) {
6908 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6910 if (Tok.isOneOf(tok::period, tok::arrow))
6911 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
6914 if (Tok.isAtStartOfLine() && Loc.
isValid())
6915 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
6919 diag::err_expected_unqualified_id)
6924 diag::err_expected_either)
6925 << tok::identifier << tok::l_paren;
6934 "Haven't past the location of the identifier yet?");
6938 MaybeParseCXX11Attributes(D);
6941 if (Tok.is(tok::l_paren)) {
6953 bool IsAmbiguous =
false;
6965 AllowImplicitTypename =
6973 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
6974 bool IsFunctionDecl =
6975 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
6976 TentativelyDeclaredIdentifiers.pop_back();
6977 if (!IsFunctionDecl)
6980 ParsedAttributes attrs(AttrFactory);
6983 if (IsFunctionDeclaration)
6984 Actions.ActOnStartFunctionDeclarationDeclarator(D,
6985 TemplateParameterDepth);
6986 ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
6987 if (IsFunctionDeclaration)
6988 Actions.ActOnFinishFunctionDeclarationDeclarator(D);
6989 PrototypeScope.Exit();
6990 }
else if (Tok.is(tok::l_square)) {
6991 ParseBracketDeclarator(D);
6992 }
else if (Tok.isRegularKeywordAttribute()) {
6994 Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();
6999 if (!T.consumeOpen())
7010 Diag(Tok, diag::err_requires_clause_inside_parens);
7024void Parser::ParseDecompositionDeclarator(
Declarator &D) {
7025 assert(Tok.is(tok::l_square));
7027 TentativeParsingAction PA(*
this);
7032 DiagnoseAndSkipCXX11Attributes();
7036 if (!(Tok.isOneOf(tok::identifier, tok::ellipsis) &&
7038 tok::identifier, tok::l_square, tok::ellipsis)) &&
7039 !(Tok.is(tok::r_square) &&
7042 return ParseMisplacedBracketDeclarator(D);
7045 SourceLocation PrevEllipsisLoc;
7046 SmallVector<DecompositionDeclarator::Binding, 32>
Bindings;
7047 while (Tok.isNot(tok::r_square)) {
7049 if (Tok.is(tok::comma))
7052 if (Tok.is(tok::identifier)) {
7054 Diag(EndLoc, diag::err_expected)
7057 Diag(Tok, diag::err_expected_comma_or_rsquare);
7060 SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis},
7062 if (Tok.is(tok::comma))
7064 else if (Tok.is(tok::r_square))
7069 if (isCXX11AttributeSpecifier() !=
7071 DiagnoseAndSkipCXX11Attributes();
7073 SourceLocation EllipsisLoc;
7075 if (Tok.is(tok::ellipsis)) {
7077 : diag::ext_cxx_binding_pack);
7078 if (PrevEllipsisLoc.
isValid()) {
7079 Diag(Tok, diag::err_binding_multiple_ellipses);
7080 Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
7083 EllipsisLoc = Tok.getLocation();
7084 PrevEllipsisLoc = EllipsisLoc;
7088 if (Tok.isNot(tok::identifier)) {
7089 Diag(Tok, diag::err_expected) << tok::identifier;
7093 IdentifierInfo *II = Tok.getIdentifierInfo();
7094 SourceLocation Loc = Tok.getLocation();
7097 if (Tok.is(tok::ellipsis) && !PrevEllipsisLoc.
isValid()) {
7098 DiagnoseMisplacedEllipsis(Tok.getLocation(), Loc, EllipsisLoc.
isValid(),
7100 EllipsisLoc = Tok.getLocation();
7104 ParsedAttributes Attrs(AttrFactory);
7105 if (isCXX11AttributeSpecifier() !=
7108 ? diag::warn_cxx23_compat_decl_attrs_on_binding
7109 : diag::ext_decl_attrs_on_binding);
7110 MaybeParseCXX11Attributes(Attrs);
7113 Bindings.push_back({II, Loc, std::move(Attrs), EllipsisLoc});
7116 if (Tok.isNot(tok::r_square))
7123 Diag(Tok.getLocation(), diag::ext_decomp_decl_empty);
7131 T.getCloseLocation());
7134void Parser::ParseParenDeclarator(
Declarator &D) {
7138 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7150 ParsedAttributes attrs(AttrFactory);
7151 bool RequiresArg =
false;
7152 if (Tok.is(tok::kw___attribute)) {
7153 ParseGNUAttributes(attrs);
7161 ParseMicrosoftTypeAttributes(attrs);
7164 if (Tok.is(tok::kw___pascal))
7165 ParseBorlandTypeAttributes(attrs);
7177 }
else if (Tok.is(tok::r_paren) ||
7179 Tok.is(tok::ellipsis) &&
7181 isDeclarationSpecifier(
7183 isCXX11AttributeSpecifier() !=
7203 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7208 std::move(attrs), T.getCloseLocation());
7214 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7232 ParseFunctionDeclarator(D, attrs, T,
false, RequiresArg);
7233 PrototypeScope.Exit();
7236void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7238 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7246 bool IsCXX11MemberFunction =
7253 Actions.CurContext->isRecord());
7254 if (!IsCXX11MemberFunction)
7274 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,
7275 IsCXX11MemberFunction);
7278void Parser::ParseFunctionDeclarator(
Declarator &D,
7283 assert(
getCurScope()->isFunctionPrototypeScope() &&
7284 "Should call from a Function scope");
7290 bool HasProto =
false;
7292 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
7294 SourceLocation EllipsisLoc;
7296 DeclSpec DS(AttrFactory);
7297 bool RefQualifierIsLValueRef =
true;
7298 SourceLocation RefQualifierLoc;
7300 SourceRange ESpecRange;
7301 SmallVector<ParsedType, 2> DynamicExceptions;
7302 SmallVector<SourceRange, 2> DynamicExceptionRanges;
7305 ParsedAttributes FnAttrs(AttrFactory);
7307 SourceLocation TrailingReturnTypeLoc;
7312 SourceLocation StartLoc, LocalEndLoc, EndLoc;
7313 SourceLocation LParenLoc, RParenLoc;
7315 StartLoc = LParenLoc;
7317 if (isFunctionDeclaratorIdentifierList()) {
7319 Diag(Tok, diag::err_argument_required_after_attribute);
7321 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7325 LocalEndLoc = RParenLoc;
7330 MaybeParseCXX11Attributes(FnAttrs);
7331 ProhibitAttributes(FnAttrs);
7333 if (Tok.isNot(tok::r_paren))
7334 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7335 else if (RequiresArg)
7336 Diag(Tok, diag::err_argument_required_after_attribute);
7347 LocalEndLoc = RParenLoc;
7356 ParseTypeQualifierListOpt(
7357 DS, AR_NoAttributesParsed,
7360 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);
7367 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7368 EndLoc = RefQualifierLoc;
7370 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7371 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7388 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
7405 ESpecType = tryParseExceptionSpecification(Delayed,
7408 DynamicExceptionRanges,
7410 ExceptionSpecTokens);
7412 EndLoc = ESpecRange.
getEnd();
7416 MaybeParseCXX11Attributes(FnAttrs);
7419 LocalEndLoc = EndLoc;
7421 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7424 LocalEndLoc = Tok.getLocation();
7426 TrailingReturnType =
7428 TrailingReturnTypeLoc =
Range.getBegin();
7429 EndLoc =
Range.getEnd();
7432 MaybeParseCXX11Attributes(FnAttrs);
7440 SmallVector<NamedDecl *, 0> DeclsInPrototype;
7443 NamedDecl *ND = dyn_cast<NamedDecl>(D);
7446 DeclsInPrototype.push_back(ND);
7453 llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) {
7461 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7462 ParamInfo.size(), EllipsisLoc, RParenLoc,
7463 RefQualifierIsLValueRef, RefQualifierLoc,
7465 ESpecType, ESpecRange, DynamicExceptions.data(),
7466 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7467 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7468 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7469 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7471 std::move(FnAttrs), EndLoc);
7474bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7476 if (Tok.isOneOf(tok::amp, tok::ampamp)) {
7478 diag::warn_cxx98_compat_ref_qualifier :
7479 diag::ext_ref_qualifier);
7481 RefQualifierIsLValueRef = Tok.is(tok::amp);
7488bool Parser::isFunctionDeclaratorIdentifierList() {
7490 && Tok.is(tok::identifier)
7491 && !TryAltiVecVectorToken()
7507 && (!Tok.is(tok::eof) &&
7511void Parser::ParseFunctionDeclaratorIdentifierList(
7515 assert(!
getLangOpts().requiresStrictPrototypes() &&
7516 "Cannot parse an identifier list in C23 or C++");
7523 Diag(Tok, diag::ext_ident_list_in_param);
7526 llvm::SmallPtrSet<const IdentifierInfo *, 16> ParamsSoFar;
7530 if (Tok.isNot(tok::identifier)) {
7531 Diag(Tok, diag::err_expected) << tok::identifier;
7538 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
7541 if (Actions.getTypeName(*ParmII, Tok.getLocation(),
getCurScope()))
7542 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7545 if (!ParamsSoFar.insert(ParmII).second) {
7546 Diag(Tok, diag::err_param_redefinition) << ParmII;
7549 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7560void Parser::ParseParameterDeclarationClause(
7569 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7571 Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)
7590 IsACXXFunctionDeclaration) {
7602 DeclSpec DS(AttrFactory);
7604 ParsedAttributes ArgDeclAttrs(AttrFactory);
7605 ParsedAttributes ArgDeclSpecAttrs(AttrFactory);
7612 ArgDeclSpecAttrs.takeAllPrependingFrom(FirstArgAttrs);
7615 MaybeParseCXX11Attributes(ArgDeclAttrs);
7618 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7621 SourceLocation DSStart = Tok.getLocation();
7625 SourceLocation ThisLoc;
7629 ParsedTemplateInfo TemplateInfo;
7630 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7631 DeclSpecContext::DSC_normal,
7632 nullptr, AllowImplicitTypename);
7645 ParseDeclarator(ParmDeclarator);
7648 ParmDeclarator.SetRangeBegin(ThisLoc);
7651 MaybeParseGNUAttributes(ParmDeclarator);
7655 if (Tok.is(tok::kw_requires)) {
7660 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7666 const IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
7670 std::unique_ptr<CachedTokens> DefArgToks;
7674 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7675 ParmDeclarator.getNumTypeObjects() == 0) {
7677 Diag(DSStart, diag::err_missing_param);
7684 if (Tok.is(tok::ellipsis) &&
7686 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7687 !Actions.isUnexpandedParameterPackPermitted())) &&
7688 Actions.containsUnexpandedParameterPacks(ParmDeclarator))
7689 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7708 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7709 Tok.isNot(tok::raw_identifier) && !Tok.isAnnotation() &&
7710 Tok.getIdentifierInfo() &&
7711 Tok.getIdentifierInfo()->isKeyword(
getLangOpts())) {
7712 Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok);
7721 Diag(ParmDeclarator.getBeginLoc(),
7722 diag::err_function_parameter_limit_exceeded);
7730 Actions.ActOnParamDeclarator(
getCurScope(), ParmDeclarator, ThisLoc);
7735 if (Tok.is(tok::equal)) {
7736 SourceLocation EqualLoc = Tok.getLocation();
7746 ConsumeAndStoreInitializer(*DefArgToks,
7748 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
7759 DelayTemplateIdDestructionRAII DontDestructTemplateIds(
7764 EnterExpressionEvaluationContext Eval(
7771 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7772 DefArgResult = ParseBraceInitializer();
7774 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
7775 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7776 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7785 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7790 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
7791 DefArgResult.
get());
7796 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7797 ParmDeclarator.getIdentifierLoc(),
7798 Param, std::move(DefArgToks)));
7806 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
7813 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7815 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7816 Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {
7819 SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();
7820 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7821 << ParmEllipsis.
isValid() << ParmEllipsis;
7824 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7826 Diag(ParmDeclarator.getIdentifierLoc(),
7827 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7830 << !ParmDeclarator.hasName();
7832 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7844void Parser::ParseBracketDeclarator(
Declarator &D) {
7845 if (CheckProhibitedCXX11Attribute())
7853 if (Tok.getKind() == tok::r_square) {
7855 ParsedAttributes attrs(AttrFactory);
7856 MaybeParseCXX11Attributes(attrs);
7860 T.getOpenLocation(),
7861 T.getCloseLocation()),
7862 std::move(attrs), T.getCloseLocation());
7864 }
else if (Tok.getKind() == tok::numeric_constant &&
7871 ParsedAttributes attrs(AttrFactory);
7872 MaybeParseCXX11Attributes(attrs);
7876 T.getOpenLocation(),
7877 T.getCloseLocation()),
7878 std::move(attrs), T.getCloseLocation());
7880 }
else if (Tok.getKind() == tok::code_completion) {
7882 Actions.CodeCompletion().CodeCompleteBracketDeclarator(
getCurScope());
7887 SourceLocation StaticLoc;
7892 DeclSpec DS(AttrFactory);
7893 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
7901 bool isStar =
false;
7912 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7913 StaticLoc = SourceLocation();
7916 }
else if (Tok.isNot(tok::r_square)) {
7933 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7934 StaticLoc = SourceLocation();
7953 isStar, NumElements.
get(), T.getOpenLocation(),
7954 T.getCloseLocation()),
7958void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
7959 assert(Tok.is(tok::l_square) &&
"Missing opening bracket");
7962 SourceLocation StartBracketLoc = Tok.getLocation();
7966 while (Tok.is(tok::l_square)) {
7967 ParseBracketDeclarator(TempDeclarator);
7973 if (Tok.is(tok::semi))
7976 SourceLocation SuggestParenLoc = Tok.getLocation();
7979 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7984 if (TempDeclarator.getNumTypeObjects() == 0)
7988 bool NeedParens =
false;
8007 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
8013 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
8014 const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
8015 D.
AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());
8020 if (!D.
hasName() && !NeedParens)
8023 SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();
8026 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
8027 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
8030 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8035 EndLoc, CharSourceRange(BracketRange,
true))
8038 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8041 EndLoc, CharSourceRange(BracketRange,
true))
8046void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
8047 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
8048 "Not a typeof specifier");
8050 bool IsUnqual = Tok.is(tok::kw_typeof_unqual);
8051 const IdentifierInfo *II = Tok.getIdentifierInfo();
8053 Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName();
8057 bool HasParens = Tok.is(tok::l_paren);
8065 SourceRange CastRange;
8067 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);
8083 const char *PrevSpec =
nullptr;
8090 Actions.getASTContext().getPrintingPolicy()))
8091 Diag(StartLoc, DiagID) << PrevSpec;
8102 Operand = Actions.HandleExprEvaluationContextForTypeof(
Operand.get());
8108 const char *PrevSpec =
nullptr;
8115 Actions.getASTContext().getPrintingPolicy()))
8116 Diag(StartLoc, DiagID) << PrevSpec;
8119void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
8120 assert(Tok.is(tok::kw__Atomic) &&
NextToken().
is(tok::l_paren) &&
8121 "Not an atomic specifier");
8125 if (T.consumeOpen())
8129 if (
Result.isInvalid()) {
8137 if (T.getCloseLocation().isInvalid())
8143 const char *PrevSpec =
nullptr;
8147 Actions.getASTContext().getPrintingPolicy()))
8148 Diag(StartLoc, DiagID) << PrevSpec;
8151bool Parser::TryAltiVecVectorTokenOutOfLine() {
8153 switch (
Next.getKind()) {
8154 default:
return false;
8157 case tok::kw_signed:
8158 case tok::kw_unsigned:
8163 case tok::kw_double:
8166 case tok::kw___bool:
8167 case tok::kw___pixel:
8168 Tok.setKind(tok::kw___vector);
8170 case tok::identifier:
8171 if (
Next.getIdentifierInfo() == Ident_pixel) {
8172 Tok.setKind(tok::kw___vector);
8175 if (
Next.getIdentifierInfo() == Ident_bool ||
8176 Next.getIdentifierInfo() == Ident_Bool) {
8177 Tok.setKind(tok::kw___vector);
8185 const char *&PrevSpec,
unsigned &DiagID,
8187 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
8188 if (Tok.getIdentifierInfo() == Ident_vector) {
8190 switch (
Next.getKind()) {
8193 case tok::kw_signed:
8194 case tok::kw_unsigned:
8199 case tok::kw_double:
8202 case tok::kw___bool:
8203 case tok::kw___pixel:
8206 case tok::identifier:
8207 if (
Next.getIdentifierInfo() == Ident_pixel) {
8211 if (
Next.getIdentifierInfo() == Ident_bool ||
8212 Next.getIdentifierInfo() == Ident_Bool) {
8221 }
else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
8225 }
else if ((Tok.getIdentifierInfo() == Ident_bool) &&
8233TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8236 SmallVector<Token, 4> Tokens;
8239 auto &SourceMgr = PP.getSourceManager();
8240 FileID FID = SourceMgr.createFileID(
8241 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8245 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8246 L.setParsingPreprocessorDirective(
true);
8252 Tokens.push_back(Tok);
8253 }
while (Tok.isNot(tok::eod));
8258 Token &EndToken = Tokens.back();
8265 Tokens.push_back(Tok);
8268 PP.EnterTokenStream(Tokens,
false,
8283 (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {
8284 Diag(Tok.getLocation(), diag::err_type_unparsed);
8289 while (Tok.isNot(tok::eof))
8293 if (Tok.is(tok::eof) && Tok.getEofData() == TypeStr.data())
8298void Parser::DiagnoseBitIntUse(
const Token &
Tok) {
8302 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8303 "expected either an _ExtInt or _BitInt token!");
8305 SourceLocation Loc = Tok.getLocation();
8306 if (Tok.is(tok::kw__ExtInt)) {
8307 Diag(Loc, diag::warn_ext_int_deprecated)
8313 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() const
returns true iff the attribute to be parsed should only be late parsed if it is annotated with LateAt...
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static bool isAtStartOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroBegin=nullptr)
Returns true if the given MacroID location points at the first token of the macro expansion.
static bool isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroEnd=nullptr)
Returns true if the given MacroID location points at the last token of the macro expansion.
static std::optional< Token > findNextToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeComments=false)
Finds the token that comes right after the given location.
static bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, const LangOptions &LangOpts, bool IgnoreWhiteSpace=false)
Relex the token at the specified location.
UnresolvedSetImpl::iterator iterator
static constexpr unsigned getMaxFunctionScopeDepth()
ParsedAttr - Represents a syntactic attribute.
unsigned getMaxArgs() const
static const ParsedAttributesView & none()
void prepend(iterator B, iterator E)
void addAtEnd(ParsedAttr *newAttr)
void remove(ParsedAttr *ToBeRemoved)
ParsedAttributes - A collection of parsed attributes.
void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA)
ParsedAttr * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Form formUsed)
Add microsoft __delspec(property) attribute.
ParsedAttr * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ParsedType typeArg, ParsedAttr::Form formUsed, SourceLocation ellipsisLoc=SourceLocation())
Add an attribute with a single type argument.
ParsedAttr * addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, ParsedAttr::Form form)
Add type_tag_for_datatype attribute.
void takeAllAppendingFrom(ParsedAttributes &Other)
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, bool IsAddressOfOperand=false)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation getEndOfPreviousToken() const
DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagId)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Sema & getActions() const
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
ExprResult ParseConstantExpressionInExprEvalContext(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
SmallVector< Stmt *, 24 > StmtVector
A SmallVector of statements.
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
friend class ColonProtectionRAIIObject
DeclGroupPtrTy ParseOpenACCDirectiveDecl(AccessSpecifier &AS, ParsedAttributes &Attrs, DeclSpec::TST TagType, Decl *TagDecl)
Parse OpenACC directive on a declaration.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
const Token & GetLookAheadToken(unsigned N)
GetLookAheadToken - This peeks ahead N tokens and returns that token without consuming any tokens.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
ExprResult ParseArrayBoundExpression()
friend struct LateParsedAttribute
const TargetInfo & getTargetInfo() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
const Token & getCurToken() const
void ExitScope()
ExitScope - Pop a scope off the scope stack.
const LangOptions & getLangOpts() const
friend class ParenBraceBracketBalancer
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, 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
A late-parsed attribute that will be applied as a type attribute.
void ParseInto(ParsedAttributes &OutAttrs)
Parse this late-parsed type attribute and store results in OutAttrs.
bool isStringLiteralArg(unsigned I) const
ExpressionKind
Describes whether we are in an expression constext which we have to handle differently.
bool hasInvalidName() const
const IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
TemplateNameKind Kind
The kind of template that Template refers to.
bool hasInvalidArgs() const