34#include "llvm/ADT/SmallSet.h"
35#include "llvm/ADT/StringSwitch.h"
47 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
48 if (DSC == DeclSpecContext::DSC_normal)
49 DSC = DeclSpecContext::DSC_type_specifier;
55 ParseSpecifierQualifierList(DS, AS, DSC);
63 if (AL.isDeclspecAttribute())
64 ToBeMoved.push_back(&AL);
73 ParseDeclarator(DeclaratorInfo);
80 return Actions.ActOnTypeName(DeclaratorInfo);
85 if (Name.size() >= 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
86 return Name.drop_front(2).drop_back(2);
93#define CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
95#include "clang/Parse/AttrParserStringSwitches.inc"
97#undef CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
103#define CLANG_ATTR_LATE_PARSED_LIST
105#include "clang/Parse/AttrParserStringSwitches.inc"
107#undef CLANG_ATTR_LATE_PARSED_LIST
113#define CLANG_ATTR_PARSE_ARGS_IN_FUNCTION_SCOPE_LIST
115#include "clang/Parse/AttrParserStringSwitches.inc"
117#undef CLANG_ATTR_PARSE_ARGS_IN_FUNCTION_SCOPE_LIST
127 if (
SM.getFileID(StartLoc) !=
SM.getFileID(EndLoc))
130 bool AttrStartIsInMacro =
132 bool AttrEndIsInMacro =
134 return AttrStartIsInMacro && AttrEndIsInMacro;
137void Parser::ParseAttributes(
unsigned WhichAttrKinds,
ParsedAttributes &Attrs,
144 if (WhichAttrKinds & PAKM_CXX11)
145 MoreToParse |= MaybeParseCXX11Attributes(Attrs);
146 if (WhichAttrKinds & PAKM_GNU)
147 MoreToParse |= MaybeParseGNUAttributes(Attrs, LateAttrs);
148 if (WhichAttrKinds & PAKM_Declspec)
149 MoreToParse |= MaybeParseMicrosoftDeclSpecs(Attrs);
150 }
while (MoreToParse);
157 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
163 if (Tok.isNot(tok::l_paren)) {
164 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
165 ParsedAttr::Form::GNU());
169 bool LateParse =
false;
176 LateParse =
getLangOpts().ExperimentalLateParseAttributes &&
189 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc,
nullptr,
190 SourceLocation(), ParsedAttr::Form::GNU(), D);
197 LateAttrs->push_back(LA);
201 if (!ClassStack.empty() && !LateAttrs->
parseSoon())
202 getCurrentClass().LateParsedDeclarations.push_back(LA);
206 LA->
Toks.push_back(Tok);
209 ConsumeAndStoreUntil(tok::r_paren, LA->
Toks,
true);
214 LA->
Toks.push_back(Eof);
221 assert(Tok.is(tok::kw___attribute) &&
"Not a GNU attribute list!");
223 SourceLocation StartLoc = Tok.getLocation();
224 SourceLocation EndLoc = StartLoc;
226 while (Tok.is(tok::kw___attribute)) {
228 unsigned OldNumAttrs = Attrs.
size();
229 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
231 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
236 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"(")) {
247 if (Tok.isAnnotation())
249 if (Tok.is(tok::code_completion)) {
251 Actions.CodeCompletion().CodeCompleteAttribute(
256 if (ParseSingleGNUAttribute(Attrs, EndLoc, LateAttrs, D))
258 }
while (Tok.is(tok::comma));
260 if (ExpectAndConsume(tok::r_paren))
262 SourceLocation Loc = Tok.getLocation();
263 if (ExpectAndConsume(tok::r_paren))
269 auto &
SM = PP.getSourceManager();
270 if (!
SM.isWrittenInBuiltinFile(
SM.getSpellingLoc(AttrTokLoc)) &&
272 CharSourceRange ExpansionRange =
SM.getExpansionRange(AttrTokLoc);
273 StringRef FoundName =
275 IdentifierInfo *MacroII = PP.getIdentifierInfo(FoundName);
277 for (
unsigned i = OldNumAttrs; i < Attrs.
size(); ++i)
278 Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.
getBegin());
281 for (
unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
282 (*LateAttrs)[i]->MacroII = MacroII;
287 Attrs.
Range = SourceRange(StartLoc, EndLoc);
295#define CLANG_ATTR_IDENTIFIER_ARG_LIST
297#include "clang/Parse/AttrParserStringSwitches.inc"
299#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
307#define CLANG_ATTR_STRING_LITERAL_ARG_LIST
309#include "clang/Parse/AttrParserStringSwitches.inc"
311#undef CLANG_ATTR_STRING_LITERAL_ARG_LIST
318#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
320#include "clang/Parse/AttrParserStringSwitches.inc"
322#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
329#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
331#include "clang/Parse/AttrParserStringSwitches.inc"
333#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
340#define CLANG_ATTR_ACCEPTS_EXPR_PACK
342#include "clang/Parse/AttrParserStringSwitches.inc"
344#undef CLANG_ATTR_ACCEPTS_EXPR_PACK
351#define CLANG_ATTR_TYPE_ARG_LIST
353#include "clang/Parse/AttrParserStringSwitches.inc"
355#undef CLANG_ATTR_TYPE_ARG_LIST
362#define CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
364#include "clang/Parse/AttrParserStringSwitches.inc"
366#undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
374#define CLANG_ATTR_ARG_CONTEXT_LIST
376#include "clang/Parse/AttrParserStringSwitches.inc"
378#undef CLANG_ATTR_ARG_CONTEXT_LIST
382 assert(Tok.is(tok::identifier) &&
"expected an identifier");
383 IdentifierLoc *IL =
new (Actions.Context)
384 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
399 if (Tok.isNot(tok::r_paren))
402 if (
Parens.consumeClose())
410 &AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
411 AttributeScopeInfo(ScopeName, ScopeLoc), T.
get(), Form);
413 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
414 AttributeScopeInfo(ScopeName, ScopeLoc),
nullptr, 0, Form);
418Parser::ParseUnevaluatedStringInAttribute(
const IdentifierInfo &AttrName) {
419 if (Tok.is(tok::l_paren)) {
422 ExprResult Res = ParseUnevaluatedStringInAttribute(AttrName);
423 Paren.consumeClose();
426 if (!isTokenStringLiteral()) {
427 Diag(Tok.getLocation(), diag::err_expected_string_literal)
434bool Parser::ParseAttributeArgumentList(
437 bool SawError =
false;
441 Expr = ParseUnevaluatedStringInAttribute(AttrName);
443 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
444 Expr = ParseBraceInitializer();
449 if (Tok.is(tok::ellipsis))
451 else if (Tok.is(tok::code_completion)) {
467 if (Actions.DiagnoseUnexpandedParameterPack(Expr.
get())) {
472 Exprs.push_back(Expr.
get());
474 if (Tok.isNot(tok::comma))
479 checkPotentialAngleBracketDelimiter(Comma);
486unsigned Parser::ParseAttributeArgsCommon(
495 bool AttributeIsTypeArgAttr =
497 bool AttributeHasVariadicIdentifierArg =
501 if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
502 Tok.setKind(tok::identifier);
505 if (Tok.is(tok::identifier)) {
507 bool IsIdentifierArg =
508 AttributeHasVariadicIdentifierArg ||
519 IsIdentifierArg =
Next.isOneOf(tok::r_paren, tok::comma);
523 ArgExprs.push_back(ParseIdentifierLoc());
527 if (!ArgExprs.empty() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren)) {
529 if (!ArgExprs.empty())
532 if (AttributeIsTypeArgAttr) {
540 TheParsedType = T.
get();
541 }
else if (AttributeHasVariadicIdentifierArg ||
551 if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
552 Tok.setKind(tok::identifier);
555 if (Tok.is(tok::identifier)) {
556 ArgExprs.push_back(ParseIdentifierLoc());
572 ArgExprs.push_back(ArgExpr.
get());
588 ExprVector ParsedExprs;
589 ParsedAttributeArgumentsProperties ArgProperties =
592 if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties,
599 for (
size_t I = 0; I < ParsedExprs.size(); ++I) {
604 Diag(Tok.getLocation(),
605 diag::err_attribute_argument_parm_pack_not_supported)
612 llvm::append_range(ArgExprs, ParsedExprs);
616 SourceLocation RParen = Tok.getLocation();
617 if (!ExpectAndConsume(tok::r_paren)) {
618 SourceLocation AttrLoc = ScopeLoc.
isValid() ? ScopeLoc : AttrNameLoc;
620 if (AttributeIsTypeArgAttr && !TheParsedType.
get().
isNull()) {
622 AttributeScopeInfo(ScopeName, ScopeLoc),
623 TheParsedType, Form);
625 Attrs.
addNew(AttrName, SourceRange(AttrLoc, RParen),
626 AttributeScopeInfo(ScopeName, ScopeLoc), ArgExprs.data(),
627 ArgExprs.size(), Form);
634 return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.
get().
isNull());
637void Parser::ParseGNUAttributeArgs(
642 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
647 if (AttrKind == ParsedAttr::AT_Availability) {
648 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
651 }
else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
652 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
653 ScopeName, ScopeLoc, Form);
655 }
else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
656 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
657 ScopeName, ScopeLoc, Form);
659 }
else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
660 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
663 }
else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
664 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
665 ScopeName, ScopeLoc, Form);
668 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName,
671 }
else if (AttrKind == ParsedAttr::AT_CountedBy ||
672 AttrKind == ParsedAttr::AT_CountedByOrNull ||
673 AttrKind == ParsedAttr::AT_SizedBy ||
674 AttrKind == ParsedAttr::AT_SizedByOrNull) {
675 ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
678 }
else if (AttrKind == ParsedAttr::AT_CXXAssume) {
679 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
680 ScopeLoc, EndLoc, Form);
686 std::optional<ParseScope> PrototypeScope;
691 const DeclaratorChunk::FunctionTypeInfo *FTI =
nullptr;
703 PrototypeScope.emplace(
707 for (
unsigned i = 0; i < FTI->
NumParams; ++i)
708 Actions.ActOnReenterCXXMethodParameter(
713 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
717unsigned Parser::ParseClangAttributeArgs(
721 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
728 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
729 ScopeName, ScopeLoc, Form);
730 case ParsedAttr::AT_ExternalSourceSymbol:
731 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
732 ScopeName, ScopeLoc, Form);
734 case ParsedAttr::AT_Availability:
735 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
738 case ParsedAttr::AT_ObjCBridgeRelated:
739 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
740 ScopeName, ScopeLoc, Form);
742 case ParsedAttr::AT_SwiftNewType:
743 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
746 case ParsedAttr::AT_TypeTagForDatatype:
747 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
748 ScopeName, ScopeLoc, Form);
751 case ParsedAttr::AT_CXXAssume:
752 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
753 ScopeLoc, EndLoc, Form);
756 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
762 unsigned ExistingAttrs = Attrs.
size();
774 SourceLocation OpenParenLoc = Tok.getLocation();
776 if (
AttrName->getName() ==
"property") {
782 T.expectAndConsume(diag::err_expected_lparen_after,
783 AttrName->getNameStart(), tok::r_paren);
790 IdentifierInfo *AccessorNames[] = {
nullptr,
nullptr};
791 bool HasInvalidAccessor =
false;
796 if (!Tok.is(tok::identifier)) {
798 if (Tok.is(tok::r_paren) && !HasInvalidAccessor &&
799 AccessorNames[AK_Put] ==
nullptr &&
800 AccessorNames[AK_Get] ==
nullptr) {
801 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
805 Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor);
810 SourceLocation KindLoc = Tok.getLocation();
811 StringRef KindStr = Tok.getIdentifierInfo()->getName();
812 if (KindStr ==
"get") {
814 }
else if (KindStr ==
"put") {
818 }
else if (KindStr ==
"set") {
819 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
826 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
828 HasInvalidAccessor =
true;
829 goto next_property_accessor;
833 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
834 HasInvalidAccessor =
true;
847 Diag(Tok.getLocation(), diag::err_ms_property_expected_equal)
853 if (!Tok.is(tok::identifier)) {
854 Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name);
858 if (Kind == AK_Invalid) {
860 }
else if (AccessorNames[Kind] !=
nullptr) {
862 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
864 AccessorNames[
Kind] = Tok.getIdentifierInfo();
868 next_property_accessor:
874 if (Tok.is(tok::r_paren))
877 Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen);
882 if (!HasInvalidAccessor)
884 AccessorNames[AK_Get], AccessorNames[AK_Put],
885 ParsedAttr::Form::Declspec());
887 return !HasInvalidAccessor;
891 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
892 SourceLocation(), ParsedAttr::Form::Declspec());
897 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) <<
AttrName;
904 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
905 assert(Tok.is(tok::kw___declspec) &&
"Not a declspec!");
907 SourceLocation StartLoc = Tok.getLocation();
908 SourceLocation EndLoc = StartLoc;
910 while (Tok.is(tok::kw___declspec)) {
913 if (T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
919 while (Tok.isNot(tok::r_paren)) {
924 if (Tok.is(tok::code_completion)) {
926 Actions.CodeCompletion().CodeCompleteAttribute(
933 bool IsString = Tok.getKind() == tok::string_literal;
934 if (!IsString && Tok.getKind() != tok::identifier &&
935 Tok.getKind() != tok::kw_restrict) {
936 Diag(Tok, diag::err_ms_declspec_type);
942 SourceLocation AttrNameLoc;
944 SmallString<8> StrBuffer;
945 bool Invalid =
false;
946 StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
951 AttrName = PP.getIdentifierInfo(Str);
952 AttrNameLoc = ConsumeStringToken();
958 bool AttrHandled =
false;
961 if (Tok.is(tok::l_paren))
962 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
963 else if (
AttrName->getName() ==
"property")
965 Diag(Tok.getLocation(), diag::err_expected_lparen_after)
969 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
970 ParsedAttr::Form::Declspec());
973 EndLoc = T.getCloseLocation();
976 Attrs.
Range = SourceRange(StartLoc, EndLoc);
982 auto Kind = Tok.getKind();
984 case tok::kw___fastcall:
985 case tok::kw___stdcall:
986 case tok::kw___thiscall:
987 case tok::kw___regcall:
988 case tok::kw___cdecl:
989 case tok::kw___vectorcall:
990 case tok::kw___ptr64:
992 case tok::kw___ptr32:
994 case tok::kw___uptr: {
995 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
997 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1007void Parser::ParseWebAssemblyFuncrefTypeAttribute(
ParsedAttributes &attrs) {
1008 assert(Tok.is(tok::kw___funcref));
1009 SourceLocation StartLoc = Tok.getLocation();
1012 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
1016 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1018 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr,
1019 0, tok::kw___funcref);
1022void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
1023 SourceLocation StartLoc = Tok.getLocation();
1024 SourceLocation EndLoc = SkipExtendedMicrosoftTypeAttributes();
1027 SourceRange
Range(StartLoc, EndLoc);
1028 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) <<
Range;
1033 SourceLocation EndLoc;
1036 switch (Tok.getKind()) {
1038 case tok::kw_volatile:
1039 case tok::kw___fastcall:
1040 case tok::kw___stdcall:
1041 case tok::kw___thiscall:
1042 case tok::kw___cdecl:
1043 case tok::kw___vectorcall:
1044 case tok::kw___ptr32:
1045 case tok::kw___ptr64:
1047 case tok::kw___unaligned:
1048 case tok::kw___sptr:
1049 case tok::kw___uptr:
1060 while (Tok.is(tok::kw___pascal)) {
1061 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1063 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1070 while (Tok.is(tok::kw___kernel)) {
1071 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1073 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1079 while (Tok.is(tok::kw___noinline__)) {
1080 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1082 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1083 tok::kw___noinline__);
1088 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1089 SourceLocation AttrNameLoc = Tok.getLocation();
1090 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1094bool Parser::isHLSLQualifier(
const Token &
Tok)
const {
1095 return Tok.is(tok::kw_groupshared) || Tok.is(tok::kw_row_major) ||
1096 Tok.is(tok::kw_column_major);
1100 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1101 auto Kind = Tok.getKind();
1103 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0, Kind);
1109 auto Kind = Tok.getKind();
1111 case tok::kw__Nonnull:
1112 case tok::kw__Nullable:
1113 case tok::kw__Nullable_result:
1114 case tok::kw__Null_unspecified: {
1115 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1118 Diag(AttrNameLoc, diag::ext_nullability)
1120 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1131 return (Separator ==
'.' || Separator ==
'_');
1134VersionTuple Parser::ParseVersionTuple(
SourceRange &Range) {
1135 Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());
1137 if (!Tok.is(tok::numeric_constant)) {
1138 Diag(Tok, diag::err_expected_version);
1141 return VersionTuple();
1148 SmallString<512> Buffer;
1149 Buffer.resize(Tok.getLength()+1);
1150 const char *ThisTokBegin = &Buffer[0];
1153 bool Invalid =
false;
1154 unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);
1156 return VersionTuple();
1159 unsigned AfterMajor = 0;
1161 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
1162 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
1166 if (AfterMajor == 0) {
1167 Diag(Tok, diag::err_expected_version);
1170 return VersionTuple();
1173 if (AfterMajor == ActualLength) {
1178 Diag(Tok, diag::err_zero_version);
1179 return VersionTuple();
1182 return VersionTuple(Major);
1185 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1187 || (AfterMajor + 1 == ActualLength)) {
1188 Diag(Tok, diag::err_expected_version);
1191 return VersionTuple();
1195 unsigned AfterMinor = AfterMajor + 1;
1197 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
1198 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
1202 if (AfterMinor == ActualLength) {
1206 if (Major == 0 && Minor == 0) {
1207 Diag(Tok, diag::err_zero_version);
1208 return VersionTuple();
1211 return VersionTuple(Major, Minor);
1214 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1217 Diag(Tok, diag::err_expected_version);
1220 return VersionTuple();
1224 if (AfterMajorSeparator != AfterMinorSeparator)
1225 Diag(Tok, diag::warn_expected_consistent_version_separator);
1228 unsigned AfterSubminor = AfterMinor + 1;
1229 unsigned Subminor = 0;
1230 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
1231 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
1235 if (AfterSubminor != ActualLength) {
1236 Diag(Tok, diag::err_expected_version);
1239 return VersionTuple();
1242 return VersionTuple(Major, Minor, Subminor);
1245void Parser::ParseAvailabilityAttribute(
1249 enum { Introduced, Deprecated, Obsoleted,
Unknown };
1250 AvailabilityChange Changes[
Unknown];
1252 IdentifierLoc *EnvironmentLoc =
nullptr;
1256 if (T.consumeOpen()) {
1257 Diag(Tok, diag::err_expected) << tok::l_paren;
1262 if (Tok.isNot(tok::identifier)) {
1263 Diag(Tok, diag::err_availability_expected_platform);
1267 IdentifierLoc *Platform = ParseIdentifierLoc();
1270 if (Ident->getName().contains(
"xrOS") || Ident->getName().contains(
"xros"))
1271 Diag(Platform->
getLoc(), diag::warn_availability_unknown_platform)
1274 else if (Ident->getName() ==
"macosx")
1278 else if (Ident->getName() ==
"macosx_app_extension")
1282 AvailabilityAttr::canonicalizePlatformName(Ident->getName())));
1286 if (ExpectAndConsume(tok::comma)) {
1293 if (!Ident_introduced) {
1294 Ident_introduced = PP.getIdentifierInfo(
"introduced");
1295 Ident_deprecated = PP.getIdentifierInfo(
"deprecated");
1296 Ident_obsoleted = PP.getIdentifierInfo(
"obsoleted");
1297 Ident_unavailable = PP.getIdentifierInfo(
"unavailable");
1298 Ident_message = PP.getIdentifierInfo(
"message");
1299 Ident_strict = PP.getIdentifierInfo(
"strict");
1300 Ident_replacement = PP.getIdentifierInfo(
"replacement");
1301 Ident_environment = PP.getIdentifierInfo(
"environment");
1306 SourceLocation UnavailableLoc, StrictLoc;
1308 if (Tok.isNot(tok::identifier)) {
1309 Diag(Tok, diag::err_availability_expected_change);
1313 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1316 if (
Keyword == Ident_strict) {
1318 Diag(KeywordLoc, diag::err_availability_redundant)
1319 <<
Keyword << SourceRange(StrictLoc);
1321 StrictLoc = KeywordLoc;
1325 if (
Keyword == Ident_unavailable) {
1326 if (UnavailableLoc.
isValid()) {
1327 Diag(KeywordLoc, diag::err_availability_redundant)
1328 <<
Keyword << SourceRange(UnavailableLoc);
1330 UnavailableLoc = KeywordLoc;
1337 if (Changes[Deprecated].KeywordLoc.
isValid()) {
1338 Diag(KeywordLoc, diag::err_availability_redundant)
1340 << SourceRange(Changes[Deprecated].KeywordLoc);
1345 Changes[Deprecated].
Version = VersionTuple(1);
1349 if (
Keyword == Ident_environment) {
1350 if (EnvironmentLoc !=
nullptr) {
1351 Diag(KeywordLoc, diag::err_availability_redundant)
1356 if (Tok.isNot(tok::equal)) {
1357 Diag(Tok, diag::err_expected_after) <<
Keyword << tok::equal;
1363 if (!isTokenStringLiteral()) {
1364 Diag(Tok, diag::err_expected_string_literal)
1369 if (
Keyword == Ident_message) {
1377 if (
Keyword == Ident_environment) {
1378 if (Tok.isNot(tok::identifier)) {
1379 Diag(Tok, diag::err_availability_expected_environment);
1383 EnvironmentLoc = ParseIdentifierLoc();
1389 if ((
Keyword == Ident_introduced ||
Keyword == Ident_deprecated) &&
1390 Tok.is(tok::identifier)) {
1391 IdentifierInfo *NA = Tok.getIdentifierInfo();
1394 if (
Keyword == Ident_introduced)
1395 UnavailableLoc = KeywordLoc;
1400 SourceRange VersionRange;
1401 VersionTuple Version = ParseVersionTuple(VersionRange);
1403 if (Version.empty()) {
1409 if (
Keyword == Ident_introduced)
1411 else if (
Keyword == Ident_deprecated)
1413 else if (
Keyword == Ident_obsoleted)
1419 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1420 Diag(KeywordLoc, diag::err_availability_redundant)
1422 << SourceRange(Changes[Index].KeywordLoc,
1423 Changes[Index].VersionRange.
getEnd());
1427 Changes[Index].
Version = Version;
1430 Diag(KeywordLoc, diag::err_availability_unknown_change)
1437 if (T.consumeClose())
1441 *endLoc = T.getCloseLocation();
1445 if (UnavailableLoc.
isValid()) {
1446 bool Complained =
false;
1447 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1448 if (Changes[Index].KeywordLoc.
isValid()) {
1450 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1451 << SourceRange(Changes[Index].KeywordLoc,
1452 Changes[Index].VersionRange.
getEnd());
1457 Changes[Index] = AvailabilityChange();
1463 attrs.
addNew(&Availability,
1464 SourceRange(AvailabilityLoc, T.getCloseLocation()),
1465 AttributeScopeInfo(ScopeName, ScopeLoc), Platform,
1466 Changes[Introduced], Changes[Deprecated], Changes[Obsoleted],
1467 UnavailableLoc, MessageExpr.
get(), Form, StrictLoc,
1468 ReplacementExpr.
get(), EnvironmentLoc);
1471void Parser::ParseExternalSourceSymbolAttribute(
1477 if (T.expectAndConsume())
1481 if (!Ident_language) {
1482 Ident_language = PP.getIdentifierInfo(
"language");
1483 Ident_defined_in = PP.getIdentifierInfo(
"defined_in");
1484 Ident_generated_declaration = PP.getIdentifierInfo(
"generated_declaration");
1485 Ident_USR = PP.getIdentifierInfo(
"USR");
1489 bool HasLanguage =
false;
1491 bool HasDefinedIn =
false;
1492 IdentifierLoc *GeneratedDeclaration =
nullptr;
1494 bool HasUSR =
false;
1498 if (Tok.isNot(tok::identifier)) {
1499 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1504 SourceLocation KeywordLoc = Tok.getLocation();
1505 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1506 if (
Keyword == Ident_generated_declaration) {
1507 if (GeneratedDeclaration) {
1508 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) <<
Keyword;
1512 GeneratedDeclaration = ParseIdentifierLoc();
1518 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1524 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1530 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1532 if (
Keyword == Ident_language)
1534 else if (
Keyword == Ident_USR)
1537 HasDefinedIn =
true;
1539 if (!isTokenStringLiteral()) {
1540 Diag(Tok, diag::err_expected_string_literal)
1545 : (
Keyword == Ident_defined_in ? 1 : 2));
1549 if (
Keyword == Ident_language) {
1551 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1557 }
else if (
Keyword == Ident_USR) {
1559 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1566 assert(
Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1568 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1578 if (T.consumeClose())
1581 *EndLoc = T.getCloseLocation();
1585 Attrs.
addNew(&ExternalSourceSymbol, SourceRange(Loc, T.getCloseLocation()),
1586 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1590void Parser::ParseObjCBridgeRelatedAttribute(
1596 if (T.consumeOpen()) {
1597 Diag(Tok, diag::err_expected) << tok::l_paren;
1602 if (Tok.isNot(tok::identifier)) {
1603 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1607 IdentifierLoc *RelatedClass = ParseIdentifierLoc();
1608 if (ExpectAndConsume(tok::comma)) {
1617 if (Tok.is(tok::identifier)) {
1620 Diag(Tok, diag::err_objcbridge_related_selector_name);
1626 if (Tok.is(tok::colon))
1627 Diag(Tok, diag::err_objcbridge_related_selector_name);
1629 Diag(Tok, diag::err_expected) << tok::comma;
1637 if (Tok.is(tok::identifier))
1639 else if (Tok.isNot(tok::r_paren)) {
1640 Diag(Tok, diag::err_expected) << tok::r_paren;
1646 if (T.consumeClose())
1650 *EndLoc = T.getCloseLocation();
1653 Attrs.
addNew(&ObjCBridgeRelated,
1654 SourceRange(ObjCBridgeRelatedLoc, T.getCloseLocation()),
1655 AttributeScopeInfo(ScopeName, ScopeLoc), RelatedClass,
1656 ClassMethod, InstanceMethod, Form);
1659void Parser::ParseSwiftNewTypeAttribute(
1666 if (T.consumeOpen()) {
1667 Diag(Tok, diag::err_expected) << tok::l_paren;
1671 if (Tok.is(tok::r_paren)) {
1672 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
1676 if (Tok.isNot(tok::kw_struct) && Tok.isNot(tok::kw_enum)) {
1677 Diag(Tok, diag::warn_attribute_type_not_supported)
1678 << &
AttrName << Tok.getIdentifierInfo();
1679 if (!isTokenSpecial())
1685 auto *SwiftType =
new (Actions.Context)
1686 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
1690 if (T.consumeClose())
1693 *EndLoc = T.getCloseLocation();
1696 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc, T.getCloseLocation()),
1697 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1701void Parser::ParseTypeTagForDatatypeAttribute(
1705 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1710 if (Tok.isNot(tok::identifier)) {
1711 Diag(Tok, diag::err_expected) << tok::identifier;
1715 IdentifierLoc *ArgumentKind = ParseIdentifierLoc();
1717 if (ExpectAndConsume(tok::comma)) {
1722 SourceRange MatchingCTypeRange;
1729 bool LayoutCompatible =
false;
1730 bool MustBeNull =
false;
1732 if (Tok.isNot(tok::identifier)) {
1733 Diag(Tok, diag::err_expected) << tok::identifier;
1737 IdentifierInfo *Flag = Tok.getIdentifierInfo();
1738 if (Flag->
isStr(
"layout_compatible"))
1739 LayoutCompatible =
true;
1740 else if (Flag->
isStr(
"must_be_null"))
1743 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1750 if (!T.consumeClose()) {
1752 &AttrName, AttrNameLoc, AttributeScopeInfo(ScopeName, ScopeLoc),
1753 ArgumentKind, MatchingCType.
get(), LayoutCompatible, MustBeNull, Form);
1757 *EndLoc = T.getCloseLocation();
1760bool Parser::DiagnoseProhibitedCXX11Attribute() {
1761 assert(Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square));
1763 switch (isCXX11AttributeSpecifier(
true)) {
1769 Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1774 SourceLocation BeginLoc = ConsumeBracket();
1777 assert(Tok.is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1778 SourceLocation EndLoc = ConsumeBracket();
1779 Diag(BeginLoc, diag::err_attributes_not_allowed)
1780 << SourceRange(BeginLoc, EndLoc);
1783 llvm_unreachable(
"All cases handled above.");
1788 assert((Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square)) ||
1789 Tok.is(tok::kw_alignas) || Tok.isRegularKeywordAttribute());
1793 Tok.isRegularKeywordAttribute() ? Tok.getIdentifierInfo() :
nullptr;
1794 SourceLocation Loc = Tok.getLocation();
1795 ParseCXX11Attributes(Attrs);
1796 CharSourceRange AttrRange(SourceRange(Loc, Attrs.
Range.
getEnd()),
true);
1799 :
Diag(Loc, diag::err_attributes_not_allowed))
1804void Parser::DiagnoseProhibitedAttributes(
1807 if (CorrectLocation.
isValid()) {
1808 CharSourceRange AttrRange(Attrs.
Range,
true);
1809 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1810 ?
Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1811 :
Diag(CorrectLocation, diag::err_attributes_misplaced))
1816 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1817 ?
Diag(
Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr
1818 :
Diag(
Range.getBegin(), diag::err_attributes_not_allowed))
1824 unsigned AttrDiagID,
1825 unsigned KeywordDiagID,
1826 bool DiagnoseEmptyAttrs,
1827 bool WarnOnUnknownAttrs) {
1833 auto &
SM = PP.getSourceManager();
1837 if (FirstLSquare.
is(tok::l_square)) {
1838 std::optional<Token> SecondLSquare =
1841 if (SecondLSquare && SecondLSquare->is(tok::l_square)) {
1851 for (
const ParsedAttr &AL : Attrs) {
1852 if (AL.isRegularKeywordAttribute()) {
1853 Diag(AL.getLoc(), KeywordDiagID) << AL;
1857 if (!AL.isStandardAttributeSyntax())
1860 if (WarnOnUnknownAttrs) {
1861 Actions.DiagnoseUnknownAttribute(AL);
1865 Diag(AL.getLoc(), AttrDiagID) << AL;
1872 for (
const ParsedAttr &PA : Attrs) {
1873 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1874 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1875 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
1884 llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;
1887 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1888 AL.isDeclspecAttribute()) ||
1889 AL.isMicrosoftAttribute())
1890 ToBeMoved.push_back(&AL);
1893 for (ParsedAttr *AL : ToBeMoved) {
1907 ObjCDeclContextSwitch ObjCDC(*
this);
1909 Decl *SingleDecl =
nullptr;
1910 switch (Tok.getKind()) {
1911 case tok::kw_template:
1912 case tok::kw_export:
1913 ProhibitAttributes(DeclAttrs);
1914 ProhibitAttributes(DeclSpecAttrs);
1915 return ParseDeclarationStartingWithTemplate(Context, DeclEnd, DeclAttrs);
1916 case tok::kw_inline:
1919 ProhibitAttributes(DeclAttrs);
1920 ProhibitAttributes(DeclSpecAttrs);
1922 return ParseNamespace(Context, DeclEnd, InlineLoc);
1924 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1925 true,
nullptr, DeclSpecStart);
1927 case tok::kw_cbuffer:
1928 case tok::kw_tbuffer:
1929 SingleDecl = ParseHLSLBuffer(DeclEnd, DeclAttrs);
1931 case tok::kw_namespace:
1932 ProhibitAttributes(DeclAttrs);
1933 ProhibitAttributes(DeclSpecAttrs);
1934 return ParseNamespace(Context, DeclEnd);
1935 case tok::kw_using: {
1937 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1938 DeclEnd, DeclAttrs);
1940 case tok::kw_static_assert:
1941 case tok::kw__Static_assert:
1942 ProhibitAttributes(DeclAttrs);
1943 ProhibitAttributes(DeclSpecAttrs);
1944 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1947 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1948 true,
nullptr, DeclSpecStart);
1953 return Actions.ConvertDeclToDeclGroup(SingleDecl);
1959 bool RequireSemi, ForRangeInit *FRI,
SourceLocation *DeclSpecStart) {
1961 ParsedAttributesView OriginalDeclSpecAttrs;
1962 OriginalDeclSpecAttrs.
prepend(DeclSpecAttrs.
begin(), DeclSpecAttrs.
end());
1963 OriginalDeclSpecAttrs.
Range = DeclSpecAttrs.
Range;
1966 ParsingDeclSpec DS(*
this);
1969 ParsedTemplateInfo TemplateInfo;
1970 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
1971 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none, DSContext);
1976 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
1981 if (Tok.is(tok::semi)) {
1982 ProhibitAttributes(DeclAttrs);
1983 DeclEnd = Tok.getLocation();
1985 RecordDecl *AnonRecord =
nullptr;
1986 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
1988 Actions.ActOnDefinedDeclarationSpecifier(TheDecl);
1989 DS.complete(TheDecl);
1991 Decl* decls[] = {AnonRecord, TheDecl};
1992 return Actions.BuildDeclaratorGroup(decls);
1994 return Actions.ConvertDeclToDeclGroup(TheDecl);
1998 Actions.ActOnDefinedDeclarationSpecifier(DS.
getRepAsDecl());
2003 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
2007 switch (Tok.getKind()) {
2008 case tok::annot_cxxscope:
2009 case tok::annot_template_id:
2011 case tok::code_completion:
2012 case tok::coloncolon:
2014 case tok::kw___attribute:
2015 case tok::kw_operator:
2031 case tok::identifier:
2033 case tok::code_completion:
2034 case tok::coloncolon:
2037 case tok::equalequal:
2038 case tok::kw_alignas:
2040 case tok::kw___attribute:
2058 case tok::identifier:
2062 return Tok.isRegularKeywordAttribute();
2066 return Tok.isRegularKeywordAttribute();
2072 switch (Tok.getKind()) {
2078 if (Tok.isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
2102 case tok::kw_inline:
2106 if (Tok.isAtStartOfLine() &&
NextToken().
is(tok::kw_namespace) &&
2107 (!ParsingInObjCContainer || CurParsedObjCImpl))
2111 case tok::kw_extern:
2114 case tok::kw_namespace:
2118 if (Tok.isAtStartOfLine() &&
2119 (!ParsingInObjCContainer || CurParsedObjCImpl))
2125 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2126 ParsingInObjCContainer)
2133 if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
2138 case tok::annot_module_begin:
2139 case tok::annot_module_end:
2140 case tok::annot_module_include:
2141 case tok::annot_repl_input_end:
2155 ParsedTemplateInfo &TemplateInfo,
2157 ForRangeInit *FRI) {
2163 LocalAttrs.takeAllPrependingFrom(Attrs);
2165 if (TemplateInfo.TemplateParams)
2168 bool IsTemplateSpecOrInst =
2175 if (IsTemplateSpecOrInst)
2185 while (MaybeParseHLSLAnnotations(D))
2188 if (
Tok.is(tok::kw_requires))
2189 ParseTrailingRequiresClauseWithScope(D);
2196 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2201 if (
Tok.is(tok::kw__Noreturn)) {
2203 const char *PrevSpec;
2209 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2210 Fixit &=
Tok.isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2212 Diag(Loc, diag::err_c11_noreturn_misplaced)
2214 << (Fixit ?
FixItHint::CreateInsertion(D.getBeginLoc(),
"_Noreturn ")
2219 if (Tok.is(tok::equal) &&
NextToken().
is(tok::code_completion)) {
2221 Actions.CodeCompletion().CodeCompleteAfterFunctionEquals(D);
2230 while (
auto Specifier = isCXX11VirtSpecifier()) {
2231 Diag(Tok, diag::err_virt_specifier_outside_class)
2239 if (!isDeclarationAfterDeclarator()) {
2245 if (isStartOfFunctionDefinition(D)) {
2255 diag::err_function_declared_typedef)
2259 Decl *TheDecl =
nullptr;
2265 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2266 TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(),
2269 SourceLocation LAngleLoc =
2270 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2272 diag::err_explicit_instantiation_with_definition)
2273 << SourceRange(TemplateInfo.TemplateLoc)
2278 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2279 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
2280 LAngleLoc,
nullptr));
2282 TheDecl = ParseFunctionDefinition(
2284 ParsedTemplateInfo(&FakedParamLists,
2291 ParseFunctionDefinition(D, TemplateInfo, &LateParsedAttrs);
2294 return Actions.ConvertDeclToDeclGroup(TheDecl);
2298 Tok.is(tok::kw_namespace)) {
2308 Diag(Tok, diag::err_expected_fn_body);
2313 if (Tok.is(tok::l_brace)) {
2314 Diag(Tok, diag::err_function_definition_not_allowed);
2322 if (ParseAsmAttributesAfterDeclarator(D))
2331 if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
2332 bool IsForRangeLoop =
false;
2334 IsForRangeLoop =
true;
2335 EnterExpressionEvaluationContext ForRangeInitContext(
2343 auto &LastRecord = Actions.currentEvaluationContext();
2344 LastRecord.InLifetimeExtendingContext =
true;
2345 LastRecord.RebuildDefaultArgOrDefaultInit =
true;
2349 Actions.OpenMP().startOpenMPCXXRangeFor();
2350 if (Tok.is(tok::l_brace))
2351 FRI->RangeExpr = ParseBraceInitializer();
2358 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
2362 FRI->LifetimeExtendTemps = std::move(
2363 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps);
2367 if (IsForRangeLoop) {
2368 Actions.ActOnCXXForRangeDecl(ThisDecl);
2371 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2372 VD->setObjCForDecl(
true);
2374 Actions.FinalizeDeclaration(ThisDecl);
2375 D.complete(ThisDecl);
2376 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, ThisDecl);
2379 SmallVector<Decl *, 8> DeclsInGroup;
2381 ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo, FRI);
2382 if (LateParsedAttrs.size() > 0)
2383 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2384 D.complete(FirstDecl);
2386 DeclsInGroup.push_back(FirstDecl);
2392 SourceLocation CommaLoc;
2394 if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2398 Diag(CommaLoc, diag::err_expected_semi_declaration)
2410 Diag(CommaLoc, diag::err_multiple_template_declarators)
2411 << TemplateInfo.Kind;
2425 MaybeParseGNUAttributes(D);
2429 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2434 MaybeParseHLSLAnnotations(D);
2441 if (Tok.is(tok::kw_requires))
2442 ParseTrailingRequiresClauseWithScope(D);
2443 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D, TemplateInfo);
2444 D.complete(ThisDecl);
2446 DeclsInGroup.push_back(ThisDecl);
2451 *DeclEnd = Tok.getLocation();
2453 if (ExpectSemi && ExpectAndConsumeSemi(
2455 ? diag::err_invalid_token_after_toplevel_declarator
2456 : diag::err_expected_semi_declaration)) {
2464 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
2467bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &D) {
2469 if (Tok.is(tok::kw_asm)) {
2471 ExprResult AsmLabel(ParseSimpleAsm(
true, &Loc));
2472 if (AsmLabel.isInvalid()) {
2481 MaybeParseGNUAttributes(D);
2485Decl *Parser::ParseDeclarationAfterDeclarator(
2486 Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
2487 if (ParseAsmAttributesAfterDeclarator(D))
2490 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
2493Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2494 Declarator &D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2496 struct InitializerScopeRAII {
2502 InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl)
2503 : P(P), D(D), ThisDecl(ThisDecl), Entered(
false) {
2506 if (D.getCXXScopeSpec().isSet()) {
2508 S = P.getCurScope();
2511 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2516 ~InitializerScopeRAII() {
2532 InitKind TheInitKind;
2534 if (isTokenEqualOrEqualTypo())
2535 TheInitKind = InitKind::Equal;
2536 else if (
Tok.
is(tok::l_paren))
2537 TheInitKind = InitKind::CXXDirect;
2540 TheInitKind = InitKind::CXXBraced;
2542 TheInitKind = InitKind::Uninitialized;
2543 if (TheInitKind != InitKind::Uninitialized)
2547 Decl *ThisDecl =
nullptr;
2548 Decl *OuterDecl =
nullptr;
2549 switch (TemplateInfo.Kind) {
2551 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2556 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
2557 *TemplateInfo.TemplateParams,
2559 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2562 ThisDecl = VT->getTemplatedDecl();
2568 if (
Tok.
is(tok::semi)) {
2569 DeclResult ThisRes = Actions.ActOnExplicitInstantiation(
2570 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
2572 SkipUntil(tok::semi, StopBeforeMatch);
2575 ThisDecl = ThisRes.
get();
2583 Diag(
Tok, diag::err_template_defn_explicit_instantiation)
2585 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2588 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2590 diag::err_explicit_instantiation_with_definition)
2595 TemplateParameterLists FakedParamLists;
2596 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2598 LAngleLoc,
nullptr));
2601 Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D);
2610 switch (TheInitKind) {
2612 case InitKind::Equal: {
2615 if (
Tok.
is(tok::kw_delete)) {
2617 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2620 Diag(ConsumeToken(), diag::err_deleted_non_function);
2621 SkipDeletedFunctionBody();
2622 }
else if (
Tok.
is(tok::kw_default)) {
2624 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2627 Diag(ConsumeToken(), diag::err_default_special_members)
2628 << getLangOpts().CPlusPlus20;
2630 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2632 if (
Tok.
is(tok::code_completion)) {
2634 Actions.CodeCompletion().CodeCompleteInitializer(getCurScope(),
2636 Actions.FinalizeDeclaration(ThisDecl);
2646 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2650 FRI->ColonLoc = EqualLoc;
2652 FRI->RangeExpr =
Init;
2655 if (
Init.isInvalid()) {
2657 StopTokens.push_back(tok::comma);
2660 StopTokens.push_back(tok::r_paren);
2661 SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch);
2662 Actions.ActOnInitializerError(ThisDecl);
2664 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
2669 case InitKind::CXXDirect: {
2676 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2678 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2679 auto RunSignatureHelp = [&]() {
2681 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2682 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2683 ThisDecl->
getLocation(), Exprs, T.getOpenLocation(),
2685 CalledSignatureHelp =
true;
2686 return PreferredType;
2688 auto SetPreferredType = [&] {
2689 PreferredType.enterFunctionArgument(
Tok.
getLocation(), RunSignatureHelp);
2692 llvm::function_ref<void()> ExpressionStarts;
2698 ExpressionStarts = SetPreferredType;
2701 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2704 if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
2705 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2706 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2707 ThisDecl->
getLocation(), Exprs, T.getOpenLocation(),
2709 CalledSignatureHelp =
true;
2711 Actions.ActOnInitializerError(ThisDecl);
2712 SkipUntil(tok::r_paren, StopAtSemi);
2718 T.getCloseLocation(),
2720 Actions.AddInitializerToDecl(ThisDecl,
Initializer.get(),
2725 case InitKind::CXXBraced: {
2727 Diag(
Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2729 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2734 if (
Init.isInvalid()) {
2735 Actions.ActOnInitializerError(ThisDecl);
2737 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
true);
2740 case InitKind::Uninitialized: {
2741 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2742 Actions.ActOnUninitializedDecl(ThisDecl);
2747 Actions.FinalizeDeclaration(ThisDecl);
2748 return OuterDecl ? OuterDecl : ThisDecl;
2751void Parser::ParseSpecifierQualifierList(
2754 ParsedTemplateInfo TemplateInfo;
2758 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC,
nullptr,
2759 AllowImplicitTypename);
2764 Diag(Tok, diag::err_expected_type);
2767 Diag(Tok, diag::err_typename_requires_specqual);
2778 diag::err_typename_invalid_storageclass);
2822 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2823 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2828 ParsedTemplateInfo &TemplateInfo,
2831 assert(Tok.is(tok::identifier) &&
"should have identifier");
2833 SourceLocation Loc = Tok.getLocation();
2853 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
2871 AnnotateScopeToken(*SS,
false);
2880 if (
ParsedType T = Actions.ActOnMSVCUnknownTypeName(
2881 *Tok.getIdentifierInfo(), Tok.getLocation(),
2882 DSC == DeclSpecContext::DSC_template_type_arg)) {
2883 const char *PrevSpec;
2886 Actions.getASTContext().getPrintingPolicy());
2899 if (SS ==
nullptr) {
2900 const char *TagName =
nullptr, *FixitTagName =
nullptr;
2903 switch (Actions.isTagName(*Tok.getIdentifierInfo(),
getCurScope())) {
2906 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
2908 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
2910 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
2912 TagName=
"__interface"; FixitTagName =
"__interface ";
2913 TagKind=tok::kw___interface;
break;
2915 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
2919 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
2920 LookupResult
R(Actions, TokenName, SourceLocation(),
2923 Diag(Loc, diag::err_use_of_tag_name_without_tag)
2924 << TokenName << TagName <<
getLangOpts().CPlusPlus
2930 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2931 << TokenName << TagName;
2935 if (TagKind == tok::kw_enum)
2936 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,
2937 DeclSpecContext::DSC_normal);
2939 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
2941 DeclSpecContext::DSC_normal, Attrs);
2948 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
2949 DSC == DeclSpecContext::DSC_class)) {
2953 case tok::l_paren: {
2960 TentativeParsingAction PA(*
this);
2962 TPResult TPR = TryParseDeclarator(
false);
2965 if (TPR != TPResult::False) {
2973 if (DSC == DeclSpecContext::DSC_class ||
2974 (DSC == DeclSpecContext::DSC_top_level && SS)) {
2975 IdentifierInfo *II = Tok.getIdentifierInfo();
2976 if (Actions.isCurrentClassNameTypo(II, SS)) {
2977 Diag(Loc, diag::err_constructor_bad_name)
2978 << Tok.getIdentifierInfo() << II
2980 Tok.setIdentifierInfo(II);
2998 AnnotateScopeToken(*SS,
false);
3012 IdentifierInfo *II = Tok.getIdentifierInfo();
3014 Actions.DiagnoseUnknownTypeName(II, Loc,
getCurScope(), SS, T,
3020 const char *PrevSpec;
3023 Actions.getASTContext().getPrintingPolicy());
3028 }
else if (II != Tok.getIdentifierInfo()) {
3041 if (IsTemplateName) {
3042 SourceLocation LAngle, RAngle;
3043 TemplateArgList Args;
3044 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3053Parser::DeclSpecContext
3057 return DeclSpecContext::DSC_class;
3059 return DeclSpecContext::DSC_top_level;
3061 return DeclSpecContext::DSC_template_param;
3063 return DeclSpecContext::DSC_template_arg;
3065 return DeclSpecContext::DSC_template_type_arg;
3068 return DeclSpecContext::DSC_trailing;
3071 return DeclSpecContext::DSC_alias_declaration;
3073 return DeclSpecContext::DSC_association;
3075 return DeclSpecContext::DSC_type_specifier;
3077 return DeclSpecContext::DSC_condition;
3079 return DeclSpecContext::DSC_conv_operator;
3081 return DeclSpecContext::DSC_new;
3096 return DeclSpecContext::DSC_normal;
3099 llvm_unreachable(
"Missing DeclaratorContext case");
3106 if (isTypeIdInParens()) {
3107 SourceLocation TypeLoc = Tok.getLocation();
3109 SourceRange TypeRange(Start, Tok.getLocation());
3110 if (Actions.ActOnAlignasTypeArgument(KWName, Ty, TypeLoc, TypeRange))
3127 assert(Tok.isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3128 "Not an alignment-specifier!");
3135 if (T.expectAndConsume())
3140 SourceLocation EllipsisLoc;
3142 ParseAlignArgument(PP.getSpelling(KWTok), T.getOpenLocation(),
3151 *EndLoc = T.getCloseLocation();
3158 ArgExprs.push_back(ArgExpr.
get());
3159 Attrs.
addNew(KWName, KWLoc, AttributeScopeInfo(), ArgExprs.data(), 1, Kind,
3164void Parser::DistributeCLateParsedAttrs(
Decl *Dcl,
3170 for (
auto *LateAttr : *LateAttrs) {
3171 if (LateAttr->Decls.empty())
3172 LateAttr->addDecl(Dcl);
3178 assert(Tok.is(tok::kw___ptrauth));
3180 IdentifierInfo *KwName = Tok.getIdentifierInfo();
3184 if (T.expectAndConsume())
3194 ArgExprs.push_back(ER.
get());
3198 SourceLocation EndLoc = T.getCloseLocation();
3200 if (ArgExprs.empty() || ArgExprs.size() > 3) {
3201 Diag(KwLoc, diag::err_ptrauth_qualifier_bad_arg_count);
3205 Attrs.
addNew(KwName, SourceRange(KwLoc, EndLoc), AttributeScopeInfo(),
3206 ArgExprs.data(), ArgExprs.size(),
3207 ParsedAttr::Form::Keyword(
false,
3217 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3222 if (Tok.is(tok::r_paren)) {
3223 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
3230 using ExpressionKind =
3232 EnterExpressionEvaluationContext EC(
3234 ExpressionKind::EK_AttrArgument);
3242 ArgExprs.push_back(ArgExpr.
get());
3245 ASTContext &Ctx = Actions.getASTContext();
3251 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
3252 AttributeScopeInfo(), ArgExprs.data(), ArgExprs.size(), Form);
3255ExprResult Parser::ParseExtIntegerArgument() {
3256 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3257 "Not an extended int type");
3261 if (T.expectAndConsume())
3270 if(T.consumeClose())
3277 DeclSpecContext DSContext,
3281 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3282 DSContext == DeclSpecContext::DSC_top_level);
3285 Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
3286 tok::annot_template_id) &&
3292 bool HasScope = Tok.is(tok::annot_cxxscope);
3294 Token AfterScope = HasScope ?
NextToken() : Tok;
3298 bool MightBeDeclarator =
true;
3299 if (Tok.isOneOf(tok::kw_typename, tok::annot_typename)) {
3301 MightBeDeclarator =
false;
3302 }
else if (AfterScope.
is(tok::annot_template_id)) {
3305 TemplateIdAnnotation *Annot =
3308 MightBeDeclarator =
false;
3309 }
else if (AfterScope.
is(tok::identifier)) {
3314 if (
Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3315 tok::annot_cxxscope, tok::coloncolon)) {
3317 MightBeDeclarator = false;
3318 }
else if (HasScope) {
3323 Actions.RestoreNestedNameSpecifierAnnotation(
3324 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
3326 Sema::NameClassification Classification = Actions.ClassifyName(
3329 switch (Classification.
getKind()) {
3335 llvm_unreachable(
"typo correction is not possible here");
3343 MightBeDeclarator =
false;
3358 if (MightBeDeclarator)
3361 const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
3363 diag::err_expected_after)
3374 ParsedTemplateInfo NotATemplate;
3375 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3379void Parser::ParseDeclarationSpecifiers(
3393 if (DSContext == DeclSpecContext::DSC_conv_operator)
3394 DSContext = DeclSpecContext::DSC_type_specifier;
3396 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3397 DSContext == DeclSpecContext::DSC_top_level);
3398 bool AttrsLastTime =
false;
3399 ParsedAttributes attrs(AttrFactory);
3401 PrintingPolicy Policy = Actions.getPrintingPolicy();
3404 bool isStorageClass =
false;
3405 const char *PrevSpec =
nullptr;
3406 unsigned DiagID = 0;
3410 SourceLocation ConsumedEnd;
3419 if (
getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&
3422 Tok.setKind(tok::identifier);
3424 SourceLocation Loc = Tok.getLocation();
3427 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3431 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
3432 Tok.setKind(tok::identifier);
3441 bool IsTemplateSpecOrInst =
3445 switch (Tok.getKind()) {
3447 if (Tok.isRegularKeywordAttribute())
3452 ProhibitAttributes(attrs);
3455 for (
const ParsedAttr &PA : attrs) {
3456 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3457 !PA.isRegularKeywordAttribute())
3465 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3466 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3473 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3474 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3477 if (PA.getKind() == ParsedAttr::AT_LifetimeBound)
3478 Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type)
3479 << PA << PA.isRegularKeywordAttribute()
3482 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3483 << PA << PA.isRegularKeywordAttribute();
3492 DS.
Finish(Actions, Policy);
3496 case tok::kw__Alignas:
3497 diagnoseUseOfC11Keyword(Tok);
3499 case tok::kw_alignas:
3505 if (Tok.getKind() == tok::kw_alignas)
3506 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
3512 if (!isAllowedCXX11AttributeSpecifier())
3513 goto DoneWithDeclSpec;
3516 ProhibitAttributes(attrs);
3521 attrs.Range = SourceRange();
3523 ParseCXX11Attributes(attrs);
3524 AttrsLastTime =
true;
3527 case tok::code_completion: {
3531 bool AllowNonIdentifiers
3537 bool AllowNestedNameSpecifiers
3538 = DSContext == DeclSpecContext::DSC_top_level ||
3542 Actions.CodeCompletion().CodeCompleteDeclSpec(
3543 getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3549 CCC = DSContext == DeclSpecContext::DSC_class
3552 else if (DSContext == DeclSpecContext::DSC_class)
3556 else if (CurParsedObjCImpl)
3560 Actions.CodeCompletion().CodeCompleteOrdinaryName(
getCurScope(), CCC);
3564 case tok::coloncolon:
3570 goto DoneWithDeclSpec;
3572 if (Tok.is(tok::coloncolon))
3573 goto DoneWithDeclSpec;
3576 case tok::annot_cxxscope: {
3578 goto DoneWithDeclSpec;
3581 if (TemplateInfo.TemplateParams)
3583 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
3584 Tok.getAnnotationRange(),
3590 TemplateIdAnnotation *TemplateId =
Next.is(tok::annot_template_id)
3591 ? takeTemplateIdAnnotation(
Next)
3597 ConsumeAnnotationToken();
3611 if ((DSContext == DeclSpecContext::DSC_top_level ||
3612 DSContext == DeclSpecContext::DSC_class) &&
3615 isConstructorDeclarator(
false,
3622 goto DoneWithDeclSpec;
3626 ConsumeAnnotationToken();
3627 assert(Tok.is(tok::annot_template_id) &&
3628 "ParseOptionalCXXScopeSpecifier not working");
3629 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3639 ConsumeAnnotationToken();
3643 if (
Next.is(tok::annot_typename)) {
3645 ConsumeAnnotationToken();
3648 Tok.getAnnotationEndLoc(),
3649 PrevSpec, DiagID, T, Policy);
3653 ConsumeAnnotationToken();
3657 Next.is(tok::annot_template_id) &&
3658 static_cast<TemplateIdAnnotation *
>(
Next.getAnnotationValue())
3661 ConsumeAnnotationToken();
3662 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3666 if (
Next.isNot(tok::identifier))
3667 goto DoneWithDeclSpec;
3672 if ((DSContext == DeclSpecContext::DSC_top_level ||
3673 DSContext == DeclSpecContext::DSC_class) &&
3676 isConstructorDeclarator(
false,
3680 goto DoneWithDeclSpec;
3686 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3690 false,
false,
nullptr,
3693 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3695 if (IsTemplateSpecOrInst)
3703 if (TryAnnotateTypeConstraint())
3704 goto DoneWithDeclSpec;
3705 if (Tok.isNot(tok::annot_cxxscope) ||
3709 ConsumeAnnotationToken();
3710 ParsedAttributes Attrs(AttrFactory);
3711 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3712 if (!Attrs.
empty()) {
3713 AttrsLastTime =
true;
3714 attrs.takeAllAppendingFrom(Attrs);
3718 goto DoneWithDeclSpec;
3722 ConsumeAnnotationToken();
3725 DiagID, TypeRep, Policy);
3735 case tok::annot_typename: {
3739 goto DoneWithDeclSpec;
3748 ConsumeAnnotationToken();
3753 case tok::kw___is_signed:
3765 TryKeywordIdentFallback(
true);
3768 goto DoneWithDeclSpec;
3771 case tok::kw___super:
3772 case tok::kw_decltype:
3773 case tok::identifier:
3779 goto DoneWithDeclSpec;
3785 if (!
getLangOpts().DeclSpecKeyword && Tok.is(tok::identifier) &&
3786 Tok.getIdentifierInfo()->getName() ==
"__declspec") {
3787 Diag(Loc, diag::err_ms_attributes_not_enabled);
3797 if (T.consumeOpen()) {
3798 assert(
false &&
"Not a left paren?");
3813 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3817 if (IsTemplateSpecOrInst)
3821 if (IsTemplateSpecOrInst)
3824 goto DoneWithDeclSpec;
3827 if (!Tok.is(tok::identifier))
3832 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID,
isInvalid))
3838 goto DoneWithDeclSpec;
3840 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3841 isObjCInstancetype()) {
3842 ParsedType TypeRep = Actions.ObjC().ActOnObjCInstanceType(Loc);
3845 DiagID, TypeRep, Policy);
3857 Actions.isCurrentClassName(*Tok.getIdentifierInfo(),
getCurScope()) &&
3858 isConstructorDeclarator(
true,
3861 goto DoneWithDeclSpec;
3864 *Tok.getIdentifierInfo(), Tok.getLocation(),
getCurScope(),
nullptr,
3865 false,
false,
nullptr,
false,
false,
3866 isClassTemplateDeductionContext(DSContext));
3871 if (TryAnnotateTypeConstraint())
3872 goto DoneWithDeclSpec;
3873 if (Tok.isNot(tok::identifier))
3875 ParsedAttributes Attrs(AttrFactory);
3876 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
3877 if (!Attrs.
empty()) {
3878 AttrsLastTime =
true;
3879 attrs.takeAllAppendingFrom(Attrs);
3883 goto DoneWithDeclSpec;
3890 (DSContext == DeclSpecContext::DSC_class ||
3891 DSContext == DeclSpecContext::DSC_top_level) &&
3892 Actions.isDeductionGuideName(
getCurScope(), *Tok.getIdentifierInfo(),
3893 Tok.getLocation(), SS) &&
3894 isConstructorDeclarator(
true,
3896 goto DoneWithDeclSpec;
3899 DiagID, TypeRep, Policy);
3910 SourceLocation NewEndLoc;
3911 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3926 case tok::annot_template_id: {
3927 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
3938 TemplateId =
nullptr;
3946 tok::kw_volatile, tok::kw_restrict, tok::amp,
3948 Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
3952 TemplateId, Policy);
3956 goto DoneWithDeclSpec;
3958 if (TemplateId && !
isInvalid && Actions.CheckTypeConstraint(TemplateId))
3959 TemplateId =
nullptr;
3961 ConsumeAnnotationToken();
3962 SourceLocation AutoLoc = Tok.getLocation();
3965 if (Tracker.consumeOpen()) {
3967 Diag(Tok, diag::err_expected) << tok::l_paren;
3971 Tracker.skipToEnd();
3972 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
3977 Tracker.consumeClose();
3980 ConsumedEnd = Tok.getLocation();
3985 DiagID, TemplateId, Policy);
3988 TemplateId, Policy);
3997 goto DoneWithDeclSpec;
4005 isConstructorDeclarator(
true,
4008 goto DoneWithDeclSpec;
4013 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
4018 case tok::kw___attribute:
4019 case tok::kw___declspec:
4020 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4024 case tok::kw___forceinline: {
4026 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
4027 SourceLocation AttrNameLoc = Tok.getLocation();
4029 nullptr, 0, tok::kw___forceinline);
4033 case tok::kw___unaligned:
4039 case tok::kw___ptrauth:
4043 case tok::kw___sptr:
4044 case tok::kw___uptr:
4045 case tok::kw___ptr64:
4046 case tok::kw___ptr32:
4048 case tok::kw___cdecl:
4049 case tok::kw___stdcall:
4050 case tok::kw___fastcall:
4051 case tok::kw___thiscall:
4052 case tok::kw___regcall:
4053 case tok::kw___vectorcall:
4057 case tok::kw___funcref:
4062 case tok::kw___pascal:
4067 case tok::kw___kernel:
4072 case tok::kw___noinline__:
4077 case tok::kw__Nonnull:
4078 case tok::kw__Nullable:
4079 case tok::kw__Nullable_result:
4080 case tok::kw__Null_unspecified:
4085 case tok::kw___kindof:
4087 AttributeScopeInfo(),
nullptr, 0,
4093 case tok::kw_typedef:
4095 PrevSpec, DiagID, Policy);
4096 isStorageClass =
true;
4098 case tok::kw_extern:
4100 Diag(Tok, diag::ext_thread_before) <<
"extern";
4102 PrevSpec, DiagID, Policy);
4103 isStorageClass =
true;
4105 case tok::kw___private_extern__:
4107 Loc, PrevSpec, DiagID, Policy);
4108 isStorageClass =
true;
4110 case tok::kw_static:
4112 Diag(Tok, diag::ext_thread_before) <<
"static";
4114 PrevSpec, DiagID, Policy);
4115 isStorageClass =
true;
4119 auto MayBeTypeSpecifier = [&]() {
4130 if (isKnownToBeTypeSpecifier(T))
4140 if (MayBeTypeSpecifier()) {
4142 PrevSpec, DiagID, Policy);
4144 Diag(Tok, diag::ext_auto_storage_class)
4151 PrevSpec, DiagID, Policy);
4152 isStorageClass =
true;
4154 case tok::kw___auto_type:
4155 Diag(Tok, diag::ext_auto_type);
4159 case tok::kw_register:
4161 PrevSpec, DiagID, Policy);
4162 isStorageClass =
true;
4164 case tok::kw_mutable:
4166 PrevSpec, DiagID, Policy);
4167 isStorageClass =
true;
4169 case tok::kw___thread:
4172 isStorageClass =
true;
4174 case tok::kw_thread_local:
4176 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4185 Loc, PrevSpec, DiagID);
4186 isStorageClass =
true;
4188 case tok::kw__Thread_local:
4189 diagnoseUseOfC11Keyword(Tok);
4191 Loc, PrevSpec, DiagID);
4192 isStorageClass =
true;
4196 case tok::kw_inline:
4199 case tok::kw_virtual:
4203 !
getActions().getOpenCLOptions().isAvailableOption(
4205 DiagID = diag::err_openclcxx_virtual_function;
4206 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4209 DiagID = diag::err_hlsl_virtual_function;
4210 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4216 case tok::kw_explicit: {
4217 SourceLocation ExplicitLoc = Loc;
4218 SourceLocation CloseParenLoc;
4220 ConsumedEnd = ExplicitLoc;
4222 if (Tok.is(tok::l_paren)) {
4225 ? diag::warn_cxx17_compat_explicit_bool
4226 : diag::ext_explicit_bool);
4228 ExprResult ExplicitExpr(
static_cast<Expr *
>(
nullptr));
4230 Tracker.consumeOpen();
4232 EnterExpressionEvaluationContext ConstantEvaluated(
4236 ConsumedEnd = Tok.getLocation();
4237 if (ExplicitExpr.isUsable()) {
4238 CloseParenLoc = Tok.getLocation();
4239 Tracker.consumeClose();
4241 Actions.ActOnExplicitBoolSpecifier(ExplicitExpr.get());
4243 Tracker.skipToEnd();
4245 Diag(Tok.getLocation(), diag::warn_cxx20_compat_explicit_bool);
4249 ExplicitSpec, CloseParenLoc);
4252 case tok::kw__Noreturn:
4253 diagnoseUseOfC11Keyword(Tok);
4258 case tok::kw_friend:
4259 if (DSContext == DeclSpecContext::DSC_class) {
4266 DiagID = diag::err_friend_invalid_in_context;
4272 case tok::kw___module_private__:
4277 case tok::kw_constexpr:
4279 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4283 case tok::kw_consteval:
4287 case tok::kw_constinit:
4295 Diag(Tok, diag::err_unknown_typename) << Tok.getName();
4299 goto DoneWithDeclSpec;
4310 PrevSpec, DiagID, Policy);
4312 case tok::kw___int64:
4314 PrevSpec, DiagID, Policy);
4316 case tok::kw_signed:
4320 case tok::kw_unsigned:
4324 case tok::kw__Complex:
4326 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4330 case tok::kw__Imaginary:
4332 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4348 case tok::kw__ExtInt:
4349 case tok::kw__BitInt: {
4350 DiagnoseBitIntUse(Tok);
4355 ConsumedEnd = PrevTokLocation;
4358 case tok::kw___int128:
4366 case tok::kw___bf16:
4374 case tok::kw_double:
4378 case tok::kw__Float16:
4382 case tok::kw__Accum:
4384 "This keyword is only used when fixed point types are enabled "
4385 "with `-ffixed-point`");
4389 case tok::kw__Fract:
4391 "This keyword is only used when fixed point types are enabled "
4392 "with `-ffixed-point`");
4398 "This keyword is only used when fixed point types are enabled "
4399 "with `-ffixed-point`");
4402 case tok::kw___float128:
4406 case tok::kw___ibm128:
4410 case tok::kw_wchar_t:
4414 case tok::kw_char8_t:
4418 case tok::kw_char16_t:
4422 case tok::kw_char32_t:
4428 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4432 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4434 if (Tok.is(tok::kw_bool) &&
4438 DiagID = diag::err_bool_redeclaration;
4440 Tok.setKind(tok::identifier);
4447 case tok::kw__Decimal32:
4451 case tok::kw__Decimal64:
4455 case tok::kw__Decimal128:
4459 case tok::kw___vector:
4462 case tok::kw___pixel:
4465 case tok::kw___bool:
4470 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4473 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
4474 Tok.setKind(tok::identifier);
4475 goto DoneWithDeclSpec;
4477 DiagID = diag::err_opencl_unknown_type_specifier;
4478 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4484#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4485#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4486#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4487 case tok::kw_##ImgType##_t: \
4488 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4489 goto DoneWithDeclSpec; \
4491#include "clang/Basic/OpenCLImageTypes.def"
4492 case tok::kw___unknown_anytype:
4494 PrevSpec, DiagID, Policy);
4499 case tok::kw_struct:
4500 case tok::kw___interface:
4501 case tok::kw_union: {
4508 ParsedAttributes Attributes(AttrFactory);
4509 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
4510 EnteringContext, DSContext, Attributes);
4514 if (!Attributes.empty()) {
4515 AttrsLastTime =
true;
4516 attrs.takeAllAppendingFrom(Attributes);
4524 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
4532 case tok::kw_volatile:
4536 case tok::kw_restrict:
4540 case tok::kw___ob_wrap:
4542 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
4547 OverflowBehaviorType::OverflowBehaviorKind::Wrap, Loc, PrevSpec,
4550 case tok::kw___ob_trap:
4552 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
4557 OverflowBehaviorType::OverflowBehaviorKind::Trap, Loc, PrevSpec,
4562 case tok::kw_typename:
4565 goto DoneWithDeclSpec;
4567 if (!Tok.is(tok::kw_typename))
4572 case tok::kw_typeof:
4573 case tok::kw_typeof_unqual:
4574 ParseTypeofSpecifier(DS);
4577 case tok::annot_decltype:
4578 ParseDecltypeSpecifier(DS);
4581 case tok::annot_pack_indexing_type:
4582 ParsePackIndexingType(DS);
4585 case tok::annot_pragma_pack:
4589 case tok::annot_pragma_ms_pragma:
4590 HandlePragmaMSPragma();
4593 case tok::annot_pragma_ms_vtordisp:
4594 HandlePragmaMSVtorDisp();
4597 case tok::annot_pragma_ms_pointers_to_members:
4598 HandlePragmaMSPointersToMembers();
4601 case tok::annot_pragma_export:
4602 HandlePragmaExport();
4605#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4606#include "clang/Basic/TransformTypeTraits.def"
4610 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4611 goto ParseIdentifier;
4614 case tok::kw__Atomic:
4619 diagnoseUseOfC11Keyword(Tok);
4621 ParseAtomicSpecifier(DS);
4629 case tok::kw___generic:
4634 if (!Actions.getLangOpts().OpenCLGenericAddressSpace) {
4635 DiagID = diag::err_opencl_unknown_type_specifier;
4636 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4641 case tok::kw_private:
4645 goto DoneWithDeclSpec;
4647 case tok::kw___private:
4648 case tok::kw___global:
4649 case tok::kw___local:
4650 case tok::kw___constant:
4652 case tok::kw___read_only:
4653 case tok::kw___write_only:
4654 case tok::kw___read_write:
4657 case tok::kw_row_major:
4658 case tok::kw_column_major:
4659 case tok::kw_groupshared:
4667#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
4668 case tok::kw_##Name: \
4669 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4672#include "clang/Basic/HLSLIntangibleTypes.def"
4679 goto DoneWithDeclSpec;
4681 SourceLocation StartLoc = Tok.getLocation();
4682 SourceLocation EndLoc;
4684 if (
Type.isUsable()) {
4686 PrevSpec, DiagID,
Type.get(),
4687 Actions.getASTContext().getPrintingPolicy()))
4688 Diag(StartLoc, DiagID) << PrevSpec;
4704 assert(PrevSpec &&
"Method did not return previous specifier!");
4707 if (DiagID == diag::ext_duplicate_declspec ||
4708 DiagID == diag::ext_warn_duplicate_declspec ||
4709 DiagID == diag::err_duplicate_declspec)
4710 Diag(Loc, DiagID) << PrevSpec
4713 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4717 Diag(Loc, DiagID) << PrevSpec;
4720 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4724 AttrsLastTime =
false;
4736 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4739 for (
auto *I : RD->decls()) {
4740 auto *VD = dyn_cast<ValueDecl>(I);
4748 for (
const auto &DD : CAT->dependent_decls()) {
4749 if (!RD->containsDecl(DD.getDecl())) {
4750 P.
Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4751 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4752 P.
Diag(DD.getDecl()->getBeginLoc(),
4753 diag::note_flexible_array_counted_by_attr_field)
4760void Parser::ParseStructDeclaration(
4765 if (Tok.is(tok::kw___extension__)) {
4767 ExtensionRAIIObject O(Diags);
4769 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4773 ParsedAttributes Attrs(AttrFactory);
4774 MaybeParseCXX11Attributes(Attrs);
4777 ParseSpecifierQualifierList(DS);
4781 if (Tok.is(tok::semi)) {
4786 ProhibitAttributes(Attrs);
4787 RecordDecl *AnonRecord =
nullptr;
4788 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
4790 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4796 bool FirstDeclarator =
true;
4797 SourceLocation CommaLoc;
4799 ParsingFieldDeclarator DeclaratorInfo(*
this, DS, Attrs);
4800 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4803 if (!FirstDeclarator) {
4806 DiagnoseAndSkipCXX11Attributes();
4807 MaybeParseGNUAttributes(DeclaratorInfo.D);
4808 DiagnoseAndSkipCXX11Attributes();
4813 if (Tok.isNot(tok::colon)) {
4816 ParseDeclarator(DeclaratorInfo.D);
4818 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.getLocation());
4830 DeclaratorInfo.BitfieldSize = Res.
get();
4834 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
4837 Decl *
Field = FieldsCallback(DeclaratorInfo);
4839 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
4846 FirstDeclarator =
false;
4855 "Attribute list should be marked for immediate parsing.");
4856 for (
auto *LA : LAs) {
4857 ParseLexedCAttribute(*LA, OutAttrs);
4867 AttrEnd.startToken();
4868 AttrEnd.setKind(tok::eof);
4869 AttrEnd.setLocation(Tok.getLocation());
4870 AttrEnd.setEofData(LA.
Toks.data());
4871 LA.
Toks.push_back(AttrEnd);
4875 LA.
Toks.push_back(Tok);
4876 PP.EnterTokenStream(LA.
Toks,
true,
4882 ParsedAttributes Attrs(AttrFactory);
4884 assert(LA.
Decls.size() <= 1 &&
4885 "late field attribute expects to have at most one declaration.");
4889 SourceLocation(), ParsedAttr::Form::GNU(),
nullptr);
4893 while (Tok.isNot(tok::eof))
4897 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
4905 ParsedAttributes Attrs = ParseLexedCAttributeTokens(LA);
4907 for (Decl *D : LA.
Decls)
4908 Actions.ActOnFinishDelayedAttribute(
getCurScope(), D, Attrs);
4916 ParsedAttributes Attrs = ParseLexedCAttributeTokens(LA);
4922 Self->ParseLexedTypeAttribute(*
this, OutAttrs);
4927 LateParsedAttrList::iterator It =
4935 From.erase(It, From.end());
4940 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl,
RecordLoc,
4941 "parsing struct/union body");
4945 if (T.consumeOpen())
4949 Actions.ActOnTagStartDefinition(
getCurScope(), TagDecl);
4953 LateParsedAttrList LateFieldAttrs(
true,
4957 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
4958 Tok.isNot(tok::eof)) {
4962 if (Tok.is(tok::semi)) {
4968 if (Tok.isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4969 SourceLocation DeclEnd;
4970 ParseStaticAssertDeclaration(DeclEnd);
4974 if (Tok.is(tok::annot_pragma_pack)) {
4979 if (Tok.is(tok::annot_pragma_align)) {
4980 HandlePragmaAlign();
4984 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4987 ParsedAttributes Attrs(AttrFactory);
4988 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4992 if (Tok.is(tok::annot_pragma_openacc)) {
4994 ParsedAttributes Attrs(AttrFactory);
5000 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
5002 TagType, Actions.getASTContext().getPrintingPolicy());
5003 ConsumeAnnotationToken();
5007 if (!Tok.is(tok::at)) {
5008 auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
5012 FD.D.getDeclSpec().getSourceRange().getBegin(),
5013 FD.D, FD.BitfieldSize);
5019 ParsingDeclSpec DS(*
this);
5020 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
5023 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
5024 Diag(Tok, diag::err_unexpected_at);
5029 ExpectAndConsume(tok::l_paren);
5030 if (!Tok.is(tok::identifier)) {
5031 Diag(Tok, diag::err_expected) << tok::identifier;
5035 SmallVector<Decl *, 16> Fields;
5036 Actions.ObjC().ActOnDefs(
getCurScope(), TagDecl, Tok.getLocation(),
5037 Tok.getIdentifierInfo(), Fields);
5039 ExpectAndConsume(tok::r_paren);
5045 if (Tok.is(tok::r_brace)) {
5046 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
5050 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
5059 ParsedAttributes attrs(AttrFactory);
5061 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
5063 SmallVector<Decl *, 32> FieldDecls(TagDecl->
fields());
5066 T.getOpenLocation(), T.getCloseLocation(), attrs);
5069 ParseLexedCAttributeList(LateFieldAttrs);
5071 Actions.ActOnTagFinishDefinition(
getCurScope(), TagDecl, T.getRange());
5075 const ParsedTemplateInfo &TemplateInfo,
5078 if (Tok.is(tok::code_completion)) {
5087 ParsedAttributes attrs(AttrFactory);
5088 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5090 SourceLocation ScopedEnumKWLoc;
5091 bool IsScopedUsingClassTag =
false;
5096 : diag::ext_scoped_enum);
5097 IsScopedUsingClassTag = Tok.is(tok::kw_class);
5102 ProhibitAttributes(attrs);
5105 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5114 bool shouldDelayDiagsInTag =
5117 SuppressAccessChecks diagsFromTag(*
this, shouldDelayDiagsInTag);
5120 AllowDefiningTypeSpec AllowEnumSpecifier =
5122 bool CanBeOpaqueEnumDeclaration =
5123 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5126 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5127 CanBeOpaqueEnumDeclaration);
5131 CXXScopeSpec InvalidDeclScope;
5139 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5144 if (Spec.
isSet() && Tok.isNot(tok::identifier)) {
5145 Diag(Tok, diag::err_expected) << tok::identifier;
5147 if (Tok.isNot(tok::l_brace)) {
5155 SS = std::move(Spec);
5159 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
5160 Tok.isNot(tok::colon)) {
5161 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5170 IdentifierInfo *Name =
nullptr;
5171 SourceLocation NameLoc;
5172 if (Tok.is(tok::identifier)) {
5173 Name = Tok.getIdentifierInfo();
5177 if (!Name && ScopedEnumKWLoc.
isValid()) {
5180 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5181 ScopedEnumKWLoc = SourceLocation();
5182 IsScopedUsingClassTag =
false;
5187 if (shouldDelayDiagsInTag)
5188 diagsFromTag.done();
5191 SourceRange BaseRange;
5193 bool CanBeBitfield =
5197 if (Tok.is(tok::colon)) {
5222 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5226 Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
5227 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5234 DeclSpec DS(AttrFactory);
5238 DeclSpecContext::DSC_type_specifier);
5241 BaseType = Actions.ActOnTypeName(DeclaratorInfo);
5243 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5247 DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)
5250 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5254 ? diag::warn_c17_compat_enum_fixed_underlying_type
5255 : diag::ext_c23_enum_fixed_underlying_type)
5272 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5274 else if (Tok.is(tok::l_brace)) {
5276 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
5282 ScopedEnumKWLoc = SourceLocation();
5283 IsScopedUsingClassTag =
false;
5289 }
else if (!isTypeSpecifier(DSC) &&
5290 (Tok.is(tok::semi) ||
5291 (Tok.isAtStartOfLine() &&
5292 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5297 if (Tok.isNot(tok::semi)) {
5299 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5300 PP.EnterToken(Tok,
true);
5301 Tok.setKind(tok::semi);
5307 bool IsElaboratedTypeSpecifier =
5313 diagsFromTag.redelay();
5321 Diag(Tok, diag::err_enum_template);
5329 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5333 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5335 TemplateInfo.TemplateParams->size());
5340 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5356 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5358 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5359 diag::err_keyword_not_allowed,
5362 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5363 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5364 else if (ScopedEnumKWLoc.
isValid())
5365 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5369 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5371 SkipBodyInfo SkipBody;
5374 SkipBody = Actions.shouldSkipAnonEnumBody(
getCurScope(),
5379 bool IsDependent =
false;
5380 const char *PrevSpec =
nullptr;
5385 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5386 IsScopedUsingClassTag,
5387 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5388 DSC == DeclSpecContext::DSC_template_param ||
5389 DSC == DeclSpecContext::DSC_template_type_arg,
5390 OffsetOfState, &SkipBody).get();
5400 NameLoc.
isValid() ? NameLoc : StartLoc,
5401 PrevSpec, DiagID, TagDecl, Owned,
5402 Actions.getASTContext().getPrintingPolicy()))
5403 Diag(StartLoc, DiagID) << PrevSpec;
5412 Diag(Tok, diag::err_expected_type_name_after_typename);
5418 if (
Type.isInvalid()) {
5424 NameLoc.
isValid() ? NameLoc : StartLoc,
5425 PrevSpec, DiagID,
Type.get(),
5426 Actions.getASTContext().getPrintingPolicy()))
5427 Diag(StartLoc, DiagID) << PrevSpec;
5446 ParseEnumBody(StartLoc, D, &SkipBody);
5448 !Actions.ActOnDuplicateDefinition(
getCurScope(), TagDecl, SkipBody)) {
5455 NameLoc.
isValid() ? NameLoc : StartLoc,
5456 PrevSpec, DiagID, TagDecl, Owned,
5457 Actions.getASTContext().getPrintingPolicy()))
5458 Diag(StartLoc, DiagID) << PrevSpec;
5465 Actions.ActOnTagStartDefinition(
getCurScope(), EnumDecl);
5473 Diag(T.getOpenLocation(), diag::ext_ms_c_empty_enum_type)
5474 << SourceRange(T.getOpenLocation(), Tok.
getLocation());
5476 Diag(Tok, diag::err_empty_enum);
5479 SmallVector<Decl *, 32> EnumConstantDecls;
5480 SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
5482 Decl *LastEnumConstDecl =
nullptr;
5485 while (Tok.isNot(tok::r_brace)) {
5488 if (Tok.isNot(tok::identifier)) {
5489 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
5495 IdentifierInfo *Ident = Tok.getIdentifierInfo();
5499 ParsedAttributes attrs(AttrFactory);
5500 MaybeParseGNUAttributes(attrs);
5501 if (isAllowedCXX11AttributeSpecifier()) {
5504 ? diag::warn_cxx14_compat_ns_enum_attribute
5505 : diag::ext_ns_enum_attribute)
5507 ParseCXX11Attributes(attrs);
5510 SourceLocation EqualLoc;
5512 EnumAvailabilityDiags.emplace_back(*
this);
5514 EnterExpressionEvaluationContext ConstantEvaluated(
5523 Decl *EnumConstDecl = Actions.ActOnEnumConstant(
5524 getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
5525 EqualLoc, AssignedVal.
get(), SkipBody);
5526 EnumAvailabilityDiags.back().done();
5528 EnumConstantDecls.push_back(EnumConstDecl);
5529 LastEnumConstDecl = EnumConstDecl;
5531 if (Tok.is(tok::identifier)) {
5534 Diag(Loc, diag::err_enumerator_list_missing_comma)
5541 SourceLocation CommaLoc;
5542 if (Tok.isNot(tok::r_brace) && !
TryConsumeToken(tok::comma, CommaLoc)) {
5544 Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
5547 Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
5557 if (Tok.is(tok::r_brace) && CommaLoc.
isValid()) {
5560 diag::ext_enumerator_list_comma_cxx :
5561 diag::ext_enumerator_list_comma_c)
5564 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5574 ParsedAttributes attrs(AttrFactory);
5575 MaybeParseGNUAttributes(attrs);
5577 Actions.ActOnEnumBody(StartLoc, T.getRange(), EnumDecl, EnumConstantDecls,
5581 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5582 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5584 EnumAvailabilityDiags[i].redelay();
5585 PD.complete(EnumConstantDecls[i]);
5589 Actions.ActOnTagFinishDefinition(
getCurScope(), EnumDecl, T.getRange());
5594 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5595 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5599 PP.EnterToken(Tok,
true);
5600 Tok.setKind(tok::semi);
5604bool Parser::isKnownToBeTypeSpecifier(
const Token &
Tok)
const {
5605 switch (Tok.getKind()) {
5606 default:
return false;
5610 case tok::kw___int64:
5611 case tok::kw___int128:
5612 case tok::kw_signed:
5613 case tok::kw_unsigned:
5614 case tok::kw__Complex:
5615 case tok::kw__Imaginary:
5618 case tok::kw_wchar_t:
5619 case tok::kw_char8_t:
5620 case tok::kw_char16_t:
5621 case tok::kw_char32_t:
5623 case tok::kw__ExtInt:
5624 case tok::kw__BitInt:
5625 case tok::kw___bf16:
5628 case tok::kw_double:
5629 case tok::kw__Accum:
5630 case tok::kw__Fract:
5631 case tok::kw__Float16:
5632 case tok::kw___float128:
5633 case tok::kw___ibm128:
5636 case tok::kw__Decimal32:
5637 case tok::kw__Decimal64:
5638 case tok::kw__Decimal128:
5639 case tok::kw___vector:
5640#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5641#include "clang/Basic/OpenCLImageTypes.def"
5642#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5643#include "clang/Basic/HLSLIntangibleTypes.def"
5647 case tok::kw_struct:
5648 case tok::kw___interface:
5653 case tok::kw_typeof:
5654 case tok::kw_typeof_unqual:
5657 case tok::kw__Atomic:
5660 case tok::annot_typename:
5665bool Parser::isTypeSpecifierQualifier(
const Token &
Tok) {
5666 switch (Tok.getKind()) {
5667 default:
return false;
5669 case tok::identifier:
5670 if (TryAltiVecVectorToken())
5673 case tok::kw_typename:
5682 case tok::coloncolon:
5692 case tok::kw___attribute:
5694 case tok::kw_typeof:
5695 case tok::kw_typeof_unqual:
5700 case tok::kw___int64:
5701 case tok::kw___int128:
5702 case tok::kw_signed:
5703 case tok::kw_unsigned:
5704 case tok::kw__Complex:
5705 case tok::kw__Imaginary:
5708 case tok::kw_wchar_t:
5709 case tok::kw_char8_t:
5710 case tok::kw_char16_t:
5711 case tok::kw_char32_t:
5713 case tok::kw__ExtInt:
5714 case tok::kw__BitInt:
5716 case tok::kw___bf16:
5718 case tok::kw_double:
5719 case tok::kw__Accum:
5720 case tok::kw__Fract:
5721 case tok::kw__Float16:
5722 case tok::kw___float128:
5723 case tok::kw___ibm128:
5726 case tok::kw__Decimal32:
5727 case tok::kw__Decimal64:
5728 case tok::kw__Decimal128:
5729 case tok::kw___vector:
5730#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5731#include "clang/Basic/OpenCLImageTypes.def"
5732#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5733#include "clang/Basic/HLSLIntangibleTypes.def"
5737 case tok::kw_struct:
5738 case tok::kw___interface:
5745 case tok::kw_volatile:
5746 case tok::kw_restrict:
5747 case tok::kw___ob_wrap:
5748 case tok::kw___ob_trap:
5752 case tok::kw___unknown_anytype:
5755 case tok::annot_typename:
5762 case tok::kw___cdecl:
5763 case tok::kw___stdcall:
5764 case tok::kw___fastcall:
5765 case tok::kw___thiscall:
5766 case tok::kw___regcall:
5767 case tok::kw___vectorcall:
5769 case tok::kw___ptr64:
5770 case tok::kw___ptr32:
5771 case tok::kw___pascal:
5772 case tok::kw___unaligned:
5773 case tok::kw___ptrauth:
5775 case tok::kw__Nonnull:
5776 case tok::kw__Nullable:
5777 case tok::kw__Nullable_result:
5778 case tok::kw__Null_unspecified:
5780 case tok::kw___kindof:
5782 case tok::kw___private:
5783 case tok::kw___local:
5784 case tok::kw___global:
5785 case tok::kw___constant:
5786 case tok::kw___generic:
5787 case tok::kw___read_only:
5788 case tok::kw___read_write:
5789 case tok::kw___write_only:
5790 case tok::kw___funcref:
5793 case tok::kw_private:
5797 case tok::kw__Atomic:
5801 case tok::kw_groupshared:
5805 case tok::kw_row_major:
5806 case tok::kw_column_major:
5812 assert(PP.isIncrementalProcessingEnabled() &&
"Not in incremental mode");
5816 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5819 TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5820 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5821 Actions.ActOnFinishTopLevelStmtDecl(TLSD,
R.get());
5823 R = Actions.ActOnNullStmt(Tok.getLocation());
5825 if (Tok.is(tok::annot_repl_input_end) &&
5826 Tok.getAnnotationValue() !=
nullptr) {
5827 ConsumeAnnotationToken();
5831 SmallVector<Decl *, 2> DeclsInGroup;
5832 DeclsInGroup.push_back(TLSD);
5835 for (Stmt *S : Stmts) {
5838 TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5839 Actions.ActOnFinishTopLevelStmtDecl(D, S);
5840 DeclsInGroup.push_back(D);
5843 return Actions.BuildDeclaratorGroup(DeclsInGroup);
5846bool Parser::isDeclarationSpecifier(
5848 bool DisambiguatingWithExpression) {
5849 switch (Tok.getKind()) {
5850 default:
return false;
5857 case tok::identifier:
5861 if (TryAltiVecVectorToken())
5864 case tok::kw_decltype:
5865 case tok::kw_typename:
5870 if (TryAnnotateTypeConstraint())
5872 if (Tok.is(tok::identifier))
5880 if (DisambiguatingWithExpression &&
5881 isStartOfObjCClassMessageMissingOpenBracket())
5884 return isDeclarationSpecifier(AllowImplicitTypename);
5886 case tok::coloncolon:
5900 case tok::kw_typedef:
5901 case tok::kw_extern:
5902 case tok::kw___private_extern__:
5903 case tok::kw_static:
5905 case tok::kw___auto_type:
5906 case tok::kw_register:
5907 case tok::kw___thread:
5908 case tok::kw_thread_local:
5909 case tok::kw__Thread_local:
5912 case tok::kw___module_private__:
5915 case tok::kw___unknown_anytype:
5920 case tok::kw___int64:
5921 case tok::kw___int128:
5922 case tok::kw_signed:
5923 case tok::kw_unsigned:
5924 case tok::kw__Complex:
5925 case tok::kw__Imaginary:
5928 case tok::kw_wchar_t:
5929 case tok::kw_char8_t:
5930 case tok::kw_char16_t:
5931 case tok::kw_char32_t:
5934 case tok::kw__ExtInt:
5935 case tok::kw__BitInt:
5937 case tok::kw___bf16:
5939 case tok::kw_double:
5940 case tok::kw__Accum:
5941 case tok::kw__Fract:
5942 case tok::kw__Float16:
5943 case tok::kw___float128:
5944 case tok::kw___ibm128:
5947 case tok::kw__Decimal32:
5948 case tok::kw__Decimal64:
5949 case tok::kw__Decimal128:
5950 case tok::kw___vector:
5954 case tok::kw_struct:
5956 case tok::kw___interface:
5962 case tok::kw_volatile:
5963 case tok::kw_restrict:
5964 case tok::kw___ob_wrap:
5965 case tok::kw___ob_trap:
5969 case tok::kw_inline:
5970 case tok::kw_virtual:
5971 case tok::kw_explicit:
5972 case tok::kw__Noreturn:
5975 case tok::kw__Alignas:
5978 case tok::kw_friend:
5981 case tok::kw_static_assert:
5982 case tok::kw__Static_assert:
5985 case tok::kw_typeof:
5986 case tok::kw_typeof_unqual:
5989 case tok::kw___attribute:
5992 case tok::annot_decltype:
5993 case tok::annot_pack_indexing_type:
5994 case tok::kw_constexpr:
5997 case tok::kw_consteval:
5998 case tok::kw_constinit:
6001 case tok::kw__Atomic:
6004 case tok::kw_alignas:
6014 case tok::annot_typename:
6015 return !DisambiguatingWithExpression ||
6016 !isStartOfObjCClassMessageMissingOpenBracket();
6019 case tok::annot_template_id: {
6020 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
6025 return isTypeConstraintAnnotation() &&
6029 case tok::annot_cxxscope: {
6030 TemplateIdAnnotation *TemplateId =
6038 if (
NextToken().
is(tok::identifier) && TryAnnotateTypeConstraint())
6040 return isTypeConstraintAnnotation() &&
6044 case tok::kw___declspec:
6045 case tok::kw___cdecl:
6046 case tok::kw___stdcall:
6047 case tok::kw___fastcall:
6048 case tok::kw___thiscall:
6049 case tok::kw___regcall:
6050 case tok::kw___vectorcall:
6052 case tok::kw___sptr:
6053 case tok::kw___uptr:
6054 case tok::kw___ptr64:
6055 case tok::kw___ptr32:
6056 case tok::kw___forceinline:
6057 case tok::kw___pascal:
6058 case tok::kw___unaligned:
6059 case tok::kw___ptrauth:
6061 case tok::kw__Nonnull:
6062 case tok::kw__Nullable:
6063 case tok::kw__Nullable_result:
6064 case tok::kw__Null_unspecified:
6066 case tok::kw___kindof:
6068 case tok::kw___private:
6069 case tok::kw___local:
6070 case tok::kw___global:
6071 case tok::kw___constant:
6072 case tok::kw___generic:
6073 case tok::kw___read_only:
6074 case tok::kw___read_write:
6075 case tok::kw___write_only:
6076#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
6077#include "clang/Basic/OpenCLImageTypes.def"
6078#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
6079#include "clang/Basic/HLSLIntangibleTypes.def"
6081 case tok::kw___funcref:
6082 case tok::kw_groupshared:
6085 case tok::kw_row_major:
6086 case tok::kw_column_major:
6089 case tok::kw_private:
6094bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
6096 const ParsedTemplateInfo *TemplateInfo) {
6097 RevertingTentativeParsingAction TPA(*
this);
6100 if (TemplateInfo && TemplateInfo->TemplateParams)
6103 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6110 if (Tok.is(tok::identifier)) {
6114 }
else if (Tok.is(tok::annot_template_id)) {
6115 ConsumeAnnotationToken();
6122 SkipCXX11Attributes();
6125 if (Tok.isNot(tok::l_paren)) {
6132 if (Tok.is(tok::r_paren) ||
6133 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren))) {
6139 if (isCXX11AttributeSpecifier(
false,
6146 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6148 DeclScopeObj.EnterDeclaratorScope();
6151 ParsedAttributes Attrs(AttrFactory);
6152 MaybeParseMicrosoftAttributes(Attrs);
6161 bool IsConstructor =
false;
6167 if (Tok.is(tok::kw_this)) {
6169 return isDeclarationSpecifier(ITC);
6172 if (isDeclarationSpecifier(ITC))
6173 IsConstructor =
true;
6174 else if (Tok.is(tok::identifier) ||
6175 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier))) {
6180 if (Tok.is(tok::annot_cxxscope))
6181 ConsumeAnnotationToken();
6187 switch (Tok.getKind()) {
6193 case tok::coloncolon:
6206 SkipCXX11Attributes();
6208 if (DeductionGuide) {
6210 IsConstructor = Tok.is(tok::arrow);
6213 if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
6217 IsConstructor =
true;
6219 if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {
6232 IsConstructor = IsUnqualified;
6237 IsConstructor =
true;
6241 return IsConstructor;
6244void Parser::ParseTypeQualifierListOpt(
6245 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicOrPtrauthAllowed,
6247 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6248 isAllowedCXX11AttributeSpecifier()) {
6249 ParsedAttributes Attrs(AttrFactory);
6250 ParseCXX11Attributes(Attrs);
6254 SourceLocation EndLoc;
6258 const char *PrevSpec =
nullptr;
6259 unsigned DiagID = 0;
6260 SourceLocation Loc = Tok.getLocation();
6262 switch (Tok.getKind()) {
6263 case tok::code_completion:
6265 if (CodeCompletionHandler)
6266 CodeCompletionHandler();
6268 Actions.CodeCompletion().CodeCompleteTypeQualifiers(DS);
6275 case tok::kw_volatile:
6279 case tok::kw_restrict:
6283 case tok::kw___ob_wrap:
6285 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6290 OverflowBehaviorType::OverflowBehaviorKind::Wrap, Loc, PrevSpec,
6293 case tok::kw___ob_trap:
6295 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6300 OverflowBehaviorType::OverflowBehaviorKind::Trap, Loc, PrevSpec,
6303 case tok::kw__Atomic:
6304 if (!AtomicOrPtrauthAllowed)
6305 goto DoneWithTypeQuals;
6306 diagnoseUseOfC11Keyword(Tok);
6312 case tok::kw_private:
6314 goto DoneWithTypeQuals;
6316 case tok::kw___private:
6317 case tok::kw___global:
6318 case tok::kw___local:
6319 case tok::kw___constant:
6320 case tok::kw___generic:
6321 case tok::kw___read_only:
6322 case tok::kw___write_only:
6323 case tok::kw___read_write:
6327 case tok::kw_groupshared:
6336 case tok::kw___ptrauth:
6337 if (!AtomicOrPtrauthAllowed)
6338 goto DoneWithTypeQuals;
6340 EndLoc = PrevTokLocation;
6343 case tok::kw___unaligned:
6347 case tok::kw___uptr:
6352 if (TryKeywordIdentFallback(
false))
6356 case tok::kw___sptr:
6358 case tok::kw___ptr64:
6359 case tok::kw___ptr32:
6360 case tok::kw___cdecl:
6361 case tok::kw___stdcall:
6362 case tok::kw___fastcall:
6363 case tok::kw___thiscall:
6364 case tok::kw___regcall:
6365 case tok::kw___vectorcall:
6366 if (AttrReqs & AR_DeclspecAttributesParsed) {
6370 goto DoneWithTypeQuals;
6372 case tok::kw___funcref:
6376 case tok::kw___pascal:
6377 if (AttrReqs & AR_VendorAttributesParsed) {
6381 goto DoneWithTypeQuals;
6384 case tok::kw__Nonnull:
6385 case tok::kw__Nullable:
6386 case tok::kw__Nullable_result:
6387 case tok::kw__Null_unspecified:
6392 case tok::kw___kindof:
6394 AttributeScopeInfo(),
nullptr, 0,
6399 case tok::kw___attribute:
6400 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6402 Diag(Tok, diag::err_attributes_not_allowed);
6406 if (AttrReqs & AR_GNUAttributesParsed ||
6407 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6417 DS.
Finish(Actions, Actions.getASTContext().getPrintingPolicy());
6425 assert(PrevSpec &&
"Method did not return previous specifier!");
6426 Diag(Tok, DiagID) << PrevSpec;
6435 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6436 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6442 if (Kind == tok::star || Kind == tok::caret)
6446 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6447 Lang.getOpenCLCompatibleVersion() >= 200)
6450 if (!Lang.CPlusPlus)
6453 if (Kind == tok::amp)
6461 if (Kind == tok::ampamp)
6472 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6479void Parser::ParseDeclaratorInternal(
Declarator &D,
6480 DirectDeclParseFunction DirectDeclParser) {
6481 if (Diags.hasAllExtensionsSilenced())
6488 (Tok.is(tok::coloncolon) || Tok.is(tok::kw_decltype) ||
6489 (Tok.is(tok::identifier) &&
6491 Tok.is(tok::annot_cxxscope))) {
6492 TentativeParsingAction TPA(*
this,
true);
6498 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6510 Tok.is(tok::star)) {
6514 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6515 CompoundToken::MemberPtr);
6520 DeclSpec DS(AttrFactory);
6521 ParseTypeQualifierListOpt(DS);
6525 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6526 ParseDeclaratorInternal(D, DirectDeclParser);
6540 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6550 AnnotateScopeToken(SS,
true);
6552 if (DirectDeclParser)
6553 (this->*DirectDeclParser)(D);
6561 DeclSpec DS(AttrFactory);
6562 ParseTypeQualifierListOpt(DS);
6571 if (DirectDeclParser)
6572 (this->*DirectDeclParser)(D);
6581 if (Kind == tok::star || Kind == tok::caret) {
6583 DeclSpec DS(AttrFactory);
6587 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6589 ? AR_GNUAttributesParsed
6590 : AR_GNUAttributesParsedAndRejected);
6591 ParseTypeQualifierListOpt(DS, Reqs,
true,
6596 Actions.runWithSufficientStackSpace(
6597 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6598 if (Kind == tok::star)
6613 DeclSpec DS(AttrFactory);
6617 if (Kind == tok::ampamp)
6619 diag::warn_cxx98_compat_rvalue_reference :
6620 diag::ext_rvalue_reference);
6623 ParseTypeQualifierListOpt(DS);
6632 diag::err_invalid_reference_qualifier_application) <<
"const";
6635 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6639 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6643 Actions.runWithSufficientStackSpace(
6644 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6651 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6654 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6683void Parser::ParseDirectDeclarator(
Declarator &D) {
6690 return ParseDecompositionDeclarator(D);
6704 ParseOptionalCXXScopeSpecifier(
6706 false, EnteringContext);
6721 if (Actions.ShouldEnterDeclaratorScope(
getCurScope(),
6725 DeclScopeObj.EnterDeclaratorScope();
6732 goto PastIdentifier;
6748 !Actions.containsUnexpandedParameterPacks(D) &&
6756 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6766 if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6770 bool AllowConstructorName;
6771 bool AllowDeductionGuide;
6773 AllowConstructorName =
false;
6774 AllowDeductionGuide =
false;
6778 AllowDeductionGuide =
false;
6786 SourceLocation TemplateKWLoc;
6791 true, AllowConstructorName,
6792 AllowDeductionGuide, &TemplateKWLoc,
6805 DeclScopeObj.EnterDeclaratorScope();
6812 goto PastIdentifier;
6818 diag::err_expected_unqualified_id)
6821 goto PastIdentifier;
6825 "There's a C++-specific check for tok::identifier above");
6826 assert(Tok.getIdentifierInfo() &&
"Not an identifier?");
6827 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6830 goto PastIdentifier;
6835 bool DiagnoseIdentifier =
false;
6839 DiagnoseIdentifier =
true;
6842 DiagnoseIdentifier =
6850 !isCXX11VirtSpecifier(Tok))
6852 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6853 if (DiagnoseIdentifier) {
6854 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
6858 goto PastIdentifier;
6862 if (Tok.is(tok::l_paren)) {
6867 RevertingTentativeParsingAction PA(*
this);
6872 goto PastIdentifier;
6879 ParseParenDeclarator(D);
6892 DeclScopeObj.EnterDeclaratorScope();
6903 diag::ext_abstract_pack_declarator_parens);
6905 if (Tok.getKind() == tok::annot_pragma_parser_crash)
6907 if (Tok.is(tok::l_square))
6908 return ParseMisplacedBracketDeclarator(D);
6913 !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
6914 Tok.getIdentifierInfo()->isCPlusPlusKeyword(
getLangOpts())) {
6916 diag::err_expected_member_name_or_semi_objcxx_keyword)
6917 << Tok.getIdentifierInfo()
6920 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6923 goto PastIdentifier;
6926 diag::err_expected_member_name_or_semi)
6930 if (Tok.getKind() == tok::TokenKind::kw_while) {
6931 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6933 if (Tok.isOneOf(tok::period, tok::arrow))
6934 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
6937 if (Tok.isAtStartOfLine() && Loc.
isValid())
6938 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
6942 diag::err_expected_unqualified_id)
6947 diag::err_expected_either)
6948 << tok::identifier << tok::l_paren;
6957 "Haven't past the location of the identifier yet?");
6961 MaybeParseCXX11Attributes(D);
6964 if (Tok.is(tok::l_paren)) {
6976 bool IsAmbiguous =
false;
6988 AllowImplicitTypename =
6996 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
6997 bool IsFunctionDecl =
6998 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
6999 TentativelyDeclaredIdentifiers.pop_back();
7000 if (!IsFunctionDecl)
7003 ParsedAttributes attrs(AttrFactory);
7006 if (IsFunctionDeclaration)
7007 Actions.ActOnStartFunctionDeclarationDeclarator(D,
7008 TemplateParameterDepth);
7009 ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
7010 if (IsFunctionDeclaration)
7011 Actions.ActOnFinishFunctionDeclarationDeclarator(D);
7012 PrototypeScope.Exit();
7013 }
else if (Tok.is(tok::l_square)) {
7014 ParseBracketDeclarator(D);
7015 }
else if (Tok.isRegularKeywordAttribute()) {
7017 Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();
7022 if (!T.consumeOpen())
7033 Diag(Tok, diag::err_requires_clause_inside_parens);
7047void Parser::ParseDecompositionDeclarator(
Declarator &D) {
7048 assert(Tok.is(tok::l_square));
7050 TentativeParsingAction PA(*
this);
7055 DiagnoseAndSkipCXX11Attributes();
7059 if (!(Tok.isOneOf(tok::identifier, tok::ellipsis) &&
7061 tok::identifier, tok::l_square, tok::ellipsis)) &&
7062 !(Tok.is(tok::r_square) &&
7065 return ParseMisplacedBracketDeclarator(D);
7068 SourceLocation PrevEllipsisLoc;
7069 SmallVector<DecompositionDeclarator::Binding, 32>
Bindings;
7070 while (Tok.isNot(tok::r_square)) {
7072 if (Tok.is(tok::comma))
7075 if (Tok.is(tok::identifier)) {
7077 Diag(EndLoc, diag::err_expected)
7080 Diag(Tok, diag::err_expected_comma_or_rsquare);
7083 SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis},
7085 if (Tok.is(tok::comma))
7087 else if (Tok.is(tok::r_square))
7092 if (isCXX11AttributeSpecifier() !=
7094 DiagnoseAndSkipCXX11Attributes();
7096 SourceLocation EllipsisLoc;
7098 if (Tok.is(tok::ellipsis)) {
7100 : diag::ext_cxx_binding_pack);
7101 if (PrevEllipsisLoc.
isValid()) {
7102 Diag(Tok, diag::err_binding_multiple_ellipses);
7103 Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
7106 EllipsisLoc = Tok.getLocation();
7107 PrevEllipsisLoc = EllipsisLoc;
7111 if (Tok.isNot(tok::identifier)) {
7112 Diag(Tok, diag::err_expected) << tok::identifier;
7116 IdentifierInfo *II = Tok.getIdentifierInfo();
7117 SourceLocation Loc = Tok.getLocation();
7120 if (Tok.is(tok::ellipsis) && !PrevEllipsisLoc.
isValid()) {
7121 DiagnoseMisplacedEllipsis(Tok.getLocation(), Loc, EllipsisLoc.
isValid(),
7123 EllipsisLoc = Tok.getLocation();
7127 ParsedAttributes Attrs(AttrFactory);
7128 if (isCXX11AttributeSpecifier() !=
7131 ? diag::warn_cxx23_compat_decl_attrs_on_binding
7132 : diag::ext_decl_attrs_on_binding);
7133 MaybeParseCXX11Attributes(Attrs);
7136 Bindings.push_back({II, Loc, std::move(Attrs), EllipsisLoc});
7139 if (Tok.isNot(tok::r_square))
7146 Diag(Tok.getLocation(), diag::ext_decomp_decl_empty);
7154 T.getCloseLocation());
7157void Parser::ParseParenDeclarator(
Declarator &D) {
7161 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7173 ParsedAttributes attrs(AttrFactory);
7174 bool RequiresArg =
false;
7175 if (Tok.is(tok::kw___attribute)) {
7176 ParseGNUAttributes(attrs);
7184 ParseMicrosoftTypeAttributes(attrs);
7187 if (Tok.is(tok::kw___pascal))
7188 ParseBorlandTypeAttributes(attrs);
7200 }
else if (Tok.is(tok::r_paren) ||
7202 Tok.is(tok::ellipsis) &&
7204 isDeclarationSpecifier(
7206 isCXX11AttributeSpecifier() !=
7226 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7231 std::move(attrs), T.getCloseLocation());
7237 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7255 ParseFunctionDeclarator(D, attrs, T,
false, RequiresArg);
7256 PrototypeScope.Exit();
7259void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7261 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7269 bool IsCXX11MemberFunction =
7276 Actions.CurContext->isRecord());
7277 if (!IsCXX11MemberFunction)
7297 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,
7298 IsCXX11MemberFunction);
7301void Parser::ParseFunctionDeclarator(
Declarator &D,
7306 assert(
getCurScope()->isFunctionPrototypeScope() &&
7307 "Should call from a Function scope");
7313 bool HasProto =
false;
7315 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
7317 SourceLocation EllipsisLoc;
7319 DeclSpec DS(AttrFactory);
7320 bool RefQualifierIsLValueRef =
true;
7321 SourceLocation RefQualifierLoc;
7323 SourceRange ESpecRange;
7324 SmallVector<ParsedType, 2> DynamicExceptions;
7325 SmallVector<SourceRange, 2> DynamicExceptionRanges;
7328 ParsedAttributes FnAttrs(AttrFactory);
7330 SourceLocation TrailingReturnTypeLoc;
7335 SourceLocation StartLoc, LocalEndLoc, EndLoc;
7336 SourceLocation LParenLoc, RParenLoc;
7338 StartLoc = LParenLoc;
7340 if (isFunctionDeclaratorIdentifierList()) {
7342 Diag(Tok, diag::err_argument_required_after_attribute);
7344 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7348 LocalEndLoc = RParenLoc;
7353 MaybeParseCXX11Attributes(FnAttrs);
7354 ProhibitAttributes(FnAttrs);
7356 if (Tok.isNot(tok::r_paren))
7357 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7358 else if (RequiresArg)
7359 Diag(Tok, diag::err_argument_required_after_attribute);
7370 LocalEndLoc = RParenLoc;
7379 ParseTypeQualifierListOpt(
7380 DS, AR_NoAttributesParsed,
7383 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);
7390 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7391 EndLoc = RefQualifierLoc;
7393 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7394 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7411 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
7428 ESpecType = tryParseExceptionSpecification(Delayed,
7431 DynamicExceptionRanges,
7433 ExceptionSpecTokens);
7435 EndLoc = ESpecRange.
getEnd();
7439 MaybeParseCXX11Attributes(FnAttrs);
7442 LocalEndLoc = EndLoc;
7444 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7447 LocalEndLoc = Tok.getLocation();
7449 TrailingReturnType =
7451 TrailingReturnTypeLoc =
Range.getBegin();
7452 EndLoc =
Range.getEnd();
7455 MaybeParseCXX11Attributes(FnAttrs);
7463 SmallVector<NamedDecl *, 0> DeclsInPrototype;
7466 NamedDecl *ND = dyn_cast<NamedDecl>(D);
7469 DeclsInPrototype.push_back(ND);
7476 llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) {
7484 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7485 ParamInfo.size(), EllipsisLoc, RParenLoc,
7486 RefQualifierIsLValueRef, RefQualifierLoc,
7488 ESpecType, ESpecRange, DynamicExceptions.data(),
7489 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7490 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7491 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7492 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7494 std::move(FnAttrs), EndLoc);
7497bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7499 if (Tok.isOneOf(tok::amp, tok::ampamp)) {
7501 diag::warn_cxx98_compat_ref_qualifier :
7502 diag::ext_ref_qualifier);
7504 RefQualifierIsLValueRef = Tok.is(tok::amp);
7511bool Parser::isFunctionDeclaratorIdentifierList() {
7513 && Tok.is(tok::identifier)
7514 && !TryAltiVecVectorToken()
7530 && (!Tok.is(tok::eof) &&
7534void Parser::ParseFunctionDeclaratorIdentifierList(
7538 assert(!
getLangOpts().requiresStrictPrototypes() &&
7539 "Cannot parse an identifier list in C23 or C++");
7546 Diag(Tok, diag::ext_ident_list_in_param);
7549 llvm::SmallPtrSet<const IdentifierInfo *, 16> ParamsSoFar;
7553 if (Tok.isNot(tok::identifier)) {
7554 Diag(Tok, diag::err_expected) << tok::identifier;
7561 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
7564 if (Actions.getTypeName(*ParmII, Tok.getLocation(),
getCurScope()))
7565 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7568 if (!ParamsSoFar.insert(ParmII).second) {
7569 Diag(Tok, diag::err_param_redefinition) << ParmII;
7572 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7583void Parser::ParseParameterDeclarationClause(
7592 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7594 Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)
7613 IsACXXFunctionDeclaration) {
7625 DeclSpec DS(AttrFactory);
7627 ParsedAttributes ArgDeclAttrs(AttrFactory);
7628 ParsedAttributes ArgDeclSpecAttrs(AttrFactory);
7635 ArgDeclSpecAttrs.takeAllPrependingFrom(FirstArgAttrs);
7638 MaybeParseCXX11Attributes(ArgDeclAttrs);
7641 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7644 SourceLocation DSStart = Tok.getLocation();
7648 SourceLocation ThisLoc;
7652 ParsedTemplateInfo TemplateInfo;
7653 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7654 DeclSpecContext::DSC_normal,
7655 nullptr, AllowImplicitTypename);
7668 ParseDeclarator(ParmDeclarator);
7671 ParmDeclarator.SetRangeBegin(ThisLoc);
7674 MaybeParseGNUAttributes(ParmDeclarator);
7678 if (Tok.is(tok::kw_requires)) {
7683 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7689 const IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
7693 std::unique_ptr<CachedTokens> DefArgToks;
7697 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7698 ParmDeclarator.getNumTypeObjects() == 0) {
7700 Diag(DSStart, diag::err_missing_param);
7707 if (Tok.is(tok::ellipsis) &&
7709 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7710 !Actions.isUnexpandedParameterPackPermitted())) &&
7711 Actions.containsUnexpandedParameterPacks(ParmDeclarator))
7712 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7731 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7732 Tok.isNot(tok::raw_identifier) && !Tok.isAnnotation() &&
7733 Tok.getIdentifierInfo() &&
7734 Tok.getIdentifierInfo()->isKeyword(
getLangOpts())) {
7735 Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok);
7744 Diag(ParmDeclarator.getBeginLoc(),
7745 diag::err_function_parameter_limit_exceeded);
7753 Actions.ActOnParamDeclarator(
getCurScope(), ParmDeclarator, ThisLoc);
7758 if (Tok.is(tok::equal)) {
7759 SourceLocation EqualLoc = Tok.getLocation();
7769 ConsumeAndStoreInitializer(*DefArgToks,
7771 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
7782 DelayTemplateIdDestructionRAII DontDestructTemplateIds(
7787 EnterExpressionEvaluationContext Eval(
7794 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7795 DefArgResult = ParseBraceInitializer();
7797 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
7798 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7799 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7808 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7813 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
7814 DefArgResult.
get());
7819 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7820 ParmDeclarator.getIdentifierLoc(),
7821 Param, std::move(DefArgToks)));
7829 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
7836 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7838 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7839 Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {
7842 SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();
7843 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7844 << ParmEllipsis.
isValid() << ParmEllipsis;
7847 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7849 Diag(ParmDeclarator.getIdentifierLoc(),
7850 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7853 << !ParmDeclarator.hasName();
7855 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7867void Parser::ParseBracketDeclarator(
Declarator &D) {
7868 if (CheckProhibitedCXX11Attribute())
7876 if (Tok.getKind() == tok::r_square) {
7878 ParsedAttributes attrs(AttrFactory);
7879 MaybeParseCXX11Attributes(attrs);
7883 T.getOpenLocation(),
7884 T.getCloseLocation()),
7885 std::move(attrs), T.getCloseLocation());
7887 }
else if (Tok.getKind() == tok::numeric_constant &&
7894 ParsedAttributes attrs(AttrFactory);
7895 MaybeParseCXX11Attributes(attrs);
7899 T.getOpenLocation(),
7900 T.getCloseLocation()),
7901 std::move(attrs), T.getCloseLocation());
7903 }
else if (Tok.getKind() == tok::code_completion) {
7905 Actions.CodeCompletion().CodeCompleteBracketDeclarator(
getCurScope());
7910 SourceLocation StaticLoc;
7915 DeclSpec DS(AttrFactory);
7916 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
7924 bool isStar =
false;
7935 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7936 StaticLoc = SourceLocation();
7939 }
else if (Tok.isNot(tok::r_square)) {
7956 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7957 StaticLoc = SourceLocation();
7976 isStar, NumElements.
get(), T.getOpenLocation(),
7977 T.getCloseLocation()),
7981void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
7982 assert(Tok.is(tok::l_square) &&
"Missing opening bracket");
7985 SourceLocation StartBracketLoc = Tok.getLocation();
7989 while (Tok.is(tok::l_square)) {
7990 ParseBracketDeclarator(TempDeclarator);
7996 if (Tok.is(tok::semi))
7999 SourceLocation SuggestParenLoc = Tok.getLocation();
8002 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
8007 if (TempDeclarator.getNumTypeObjects() == 0)
8011 bool NeedParens =
false;
8030 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
8036 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
8037 const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
8038 D.
AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());
8043 if (!D.
hasName() && !NeedParens)
8046 SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();
8049 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
8050 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
8053 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8058 EndLoc, CharSourceRange(BracketRange,
true))
8061 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
8064 EndLoc, CharSourceRange(BracketRange,
true))
8069void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
8070 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
8071 "Not a typeof specifier");
8073 bool IsUnqual = Tok.is(tok::kw_typeof_unqual);
8074 const IdentifierInfo *II = Tok.getIdentifierInfo();
8076 Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName();
8080 bool HasParens = Tok.is(tok::l_paren);
8088 SourceRange CastRange;
8090 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);
8106 const char *PrevSpec =
nullptr;
8113 Actions.getASTContext().getPrintingPolicy()))
8114 Diag(StartLoc, DiagID) << PrevSpec;
8125 Operand = Actions.HandleExprEvaluationContextForTypeof(
Operand.get());
8131 const char *PrevSpec =
nullptr;
8138 Actions.getASTContext().getPrintingPolicy()))
8139 Diag(StartLoc, DiagID) << PrevSpec;
8142void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
8143 assert(Tok.is(tok::kw__Atomic) &&
NextToken().
is(tok::l_paren) &&
8144 "Not an atomic specifier");
8148 if (T.consumeOpen())
8152 if (
Result.isInvalid()) {
8160 if (T.getCloseLocation().isInvalid())
8166 const char *PrevSpec =
nullptr;
8170 Actions.getASTContext().getPrintingPolicy()))
8171 Diag(StartLoc, DiagID) << PrevSpec;
8174bool Parser::TryAltiVecVectorTokenOutOfLine() {
8176 switch (
Next.getKind()) {
8177 default:
return false;
8180 case tok::kw_signed:
8181 case tok::kw_unsigned:
8186 case tok::kw_double:
8189 case tok::kw___bool:
8190 case tok::kw___pixel:
8191 Tok.setKind(tok::kw___vector);
8193 case tok::identifier:
8194 if (
Next.getIdentifierInfo() == Ident_pixel) {
8195 Tok.setKind(tok::kw___vector);
8198 if (
Next.getIdentifierInfo() == Ident_bool ||
8199 Next.getIdentifierInfo() == Ident_Bool) {
8200 Tok.setKind(tok::kw___vector);
8208 const char *&PrevSpec,
unsigned &DiagID,
8210 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
8211 if (Tok.getIdentifierInfo() == Ident_vector) {
8213 switch (
Next.getKind()) {
8216 case tok::kw_signed:
8217 case tok::kw_unsigned:
8222 case tok::kw_double:
8225 case tok::kw___bool:
8226 case tok::kw___pixel:
8229 case tok::identifier:
8230 if (
Next.getIdentifierInfo() == Ident_pixel) {
8234 if (
Next.getIdentifierInfo() == Ident_bool ||
8235 Next.getIdentifierInfo() == Ident_Bool) {
8244 }
else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
8248 }
else if ((Tok.getIdentifierInfo() == Ident_bool) &&
8256TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8259 SmallVector<Token, 4> Tokens;
8262 auto &SourceMgr = PP.getSourceManager();
8263 FileID FID = SourceMgr.createFileID(
8264 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8268 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8269 L.setParsingPreprocessorDirective(
true);
8275 Tokens.push_back(Tok);
8276 }
while (Tok.isNot(tok::eod));
8281 Token &EndToken = Tokens.back();
8288 Tokens.push_back(Tok);
8291 PP.EnterTokenStream(Tokens,
false,
8306 (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {
8307 Diag(Tok.getLocation(), diag::err_type_unparsed);
8312 while (Tok.isNot(tok::eof))
8316 if (Tok.is(tok::eof) && Tok.getEofData() == TypeStr.data())
8321void Parser::DiagnoseBitIntUse(
const Token &
Tok) {
8325 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8326 "expected either an _ExtInt or _BitInt token!");
8328 SourceLocation Loc = Tok.getLocation();
8329 if (Tok.is(tok::kw__ExtInt)) {
8330 Diag(Loc, diag::warn_ext_int_deprecated)
8336 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, CodePtr OpPC, uint32_t I)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
const char * getKeywordSpelling(TokenKind Kind) LLVM_READNONE
Determines the spelling of simple keyword and contextual keyword tokens like 'int' and 'dynamic_cast'...
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isPragmaAnnotation(TokenKind K)
Return true if this is an annotation token representing a pragma.
The JSON file list parser is used to communicate input to InstallAPI.
TypeSpecifierType
Specifies the kind of type.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
bool isa(CodeGen::Address addr)
@ NotAttributeSpecifier
This is not an attribute specifier.
@ AttributeSpecifier
This should be treated as an attribute-specifier.
@ InvalidAttributeSpecifier
The next tokens are '[[', but this is not an attribute-specifier.
@ ExpectedParameterOrImplicitObjectParameter
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
@ IK_TemplateId
A template-id, e.g., f<int>.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
ActionResult< Decl * > DeclResult
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
llvm::SmallVector< ArgsUnion, 12U > ArgsVector
Language
The language for the input, used to select and validate the language standard and possible actions.
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
@ Template
We are parsing a template declaration.
@ ExplicitSpecialization
We are parsing an explicit specialization.
@ ExplicitInstantiation
We are parsing an explicit instantiation.
@ NonTemplate
We are not parsing a template at all.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
@ FunctionTemplate
The name was classified as a function template name.
@ Keyword
The name has been typo-corrected to a keyword.
@ DependentNonType
The name denotes a member of a dependent type that could not be resolved.
@ UndeclaredTemplate
The name was classified as an ADL-only function template name.
@ NonType
The name was classified as a specific non-type, non-template declaration.
@ Unknown
This name is not a type or template in this context, but might be something else.
@ Error
Classification failed; an error has been produced.
@ Type
The name was classified as a type.
@ TypeTemplate
The name was classified as a template whose specializations are types.
@ Concept
The name was classified as a concept name.
@ OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ UndeclaredNonType
The name was classified as an ADL-only function name.
@ VarTemplate
The name was classified as a variable template name.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Dependent_template_name
The name refers to a dependent template name:
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &&Second)
Consumes the attributes from Second and concatenates them at the end of First.
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
ActionResult< Expr * > ExprResult
@ Parens
New-expression has a C++98 paren-delimited initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_None
no exception specification
ActionResult< Stmt * > StmtResult
VersionTuple Version
The version number at which the change occurred.
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
SourceRange VersionRange
The source range covering the version number.
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, SourceLocation AtomicQualLoc, SourceLocation UnalignedQualLoc, SourceLocation OverflowBehaviorLoc={}, bool OverflowBehaviorIsWrap=false)
Return a DeclaratorChunk for a pointer.
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, ArrayRef< NamedDecl * > DeclsInPrototype, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult(), SourceLocation TrailingReturnTypeLoc=SourceLocation(), DeclSpec *MethodQualifiers=nullptr)
DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
static DeclaratorChunk getPipe(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc)
Return a DeclaratorChunk for an array.
SourceLocation Loc
Loc - The place where this type was defined.
static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, unsigned TypeQuals, SourceLocation StarLoc, SourceLocation EndLoc)
enum clang::DeclaratorChunk::@340323374315200305336204205154073066142310370142 Kind
static DeclaratorChunk getParen(SourceLocation LParenLoc, SourceLocation RParenLoc)
Return a DeclaratorChunk for a paren.
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, bool lvalue)
Return a DeclaratorChunk for a reference.
Contains the lexed tokens of an attribute with arguments that may reference member variables and so n...
IdentifierInfo & AttrName
SourceLocation AttrNameLoc
SmallVector< Decl *, 2 > Decls
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