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
117 if (
SM.getFileID(StartLoc) !=
SM.getFileID(EndLoc))
120 bool AttrStartIsInMacro =
122 bool AttrEndIsInMacro =
124 return AttrStartIsInMacro && AttrEndIsInMacro;
127void Parser::ParseAttributes(
unsigned WhichAttrKinds,
ParsedAttributes &Attrs,
128 LateParsedAttrList *LateAttrs) {
134 if (WhichAttrKinds & PAKM_CXX11)
135 MoreToParse |= MaybeParseCXX11Attributes(Attrs);
136 if (WhichAttrKinds & PAKM_GNU)
137 MoreToParse |= MaybeParseGNUAttributes(Attrs, LateAttrs);
138 if (WhichAttrKinds & PAKM_Declspec)
139 MoreToParse |= MaybeParseMicrosoftDeclSpecs(Attrs);
140 }
while (MoreToParse);
145 LateParsedAttrList *LateAttrs,
147 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
153 if (Tok.isNot(tok::l_paren)) {
154 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
155 ParsedAttr::Form::GNU());
159 bool LateParse =
false;
162 else if (LateAttrs->lateAttrParseExperimentalExtOnly()) {
166 LateParse =
getLangOpts().ExperimentalLateParseAttributes &&
179 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc,
nullptr,
180 SourceLocation(), ParsedAttr::Form::GNU(), D);
185 LateParsedAttribute *LA =
186 new LateParsedAttribute(
this, *AttrName, AttrNameLoc);
187 LateAttrs->push_back(LA);
191 if (!ClassStack.empty() && !LateAttrs->parseSoon())
192 getCurrentClass().LateParsedDeclarations.push_back(LA);
196 LA->Toks.push_back(Tok);
199 ConsumeAndStoreUntil(tok::r_paren, LA->Toks,
true);
204 LA->Toks.push_back(Eof);
210 LateParsedAttrList *LateAttrs,
Declarator *D) {
211 assert(Tok.is(tok::kw___attribute) &&
"Not a GNU attribute list!");
213 SourceLocation StartLoc = Tok.getLocation();
214 SourceLocation EndLoc = StartLoc;
216 while (Tok.is(tok::kw___attribute)) {
218 unsigned OldNumAttrs = Attrs.
size();
219 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
221 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
226 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"(")) {
237 if (Tok.isAnnotation())
239 if (Tok.is(tok::code_completion)) {
241 Actions.CodeCompletion().CodeCompleteAttribute(
246 if (ParseSingleGNUAttribute(Attrs, EndLoc, LateAttrs, D))
248 }
while (Tok.is(tok::comma));
250 if (ExpectAndConsume(tok::r_paren))
252 SourceLocation Loc = Tok.getLocation();
253 if (ExpectAndConsume(tok::r_paren))
259 auto &
SM = PP.getSourceManager();
260 if (!
SM.isWrittenInBuiltinFile(
SM.getSpellingLoc(AttrTokLoc)) &&
262 CharSourceRange ExpansionRange =
SM.getExpansionRange(AttrTokLoc);
263 StringRef FoundName =
265 IdentifierInfo *MacroII = PP.getIdentifierInfo(FoundName);
267 for (
unsigned i = OldNumAttrs; i < Attrs.
size(); ++i)
268 Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.
getBegin());
271 for (
unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
272 (*LateAttrs)[i]->MacroII = MacroII;
277 Attrs.
Range = SourceRange(StartLoc, EndLoc);
285#define CLANG_ATTR_IDENTIFIER_ARG_LIST
287#include "clang/Parse/AttrParserStringSwitches.inc"
289#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
297#define CLANG_ATTR_STRING_LITERAL_ARG_LIST
299#include "clang/Parse/AttrParserStringSwitches.inc"
301#undef CLANG_ATTR_STRING_LITERAL_ARG_LIST
308#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
310#include "clang/Parse/AttrParserStringSwitches.inc"
312#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
319#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
321#include "clang/Parse/AttrParserStringSwitches.inc"
323#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
330#define CLANG_ATTR_ACCEPTS_EXPR_PACK
332#include "clang/Parse/AttrParserStringSwitches.inc"
334#undef CLANG_ATTR_ACCEPTS_EXPR_PACK
341#define CLANG_ATTR_TYPE_ARG_LIST
343#include "clang/Parse/AttrParserStringSwitches.inc"
345#undef CLANG_ATTR_TYPE_ARG_LIST
352#define CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
354#include "clang/Parse/AttrParserStringSwitches.inc"
356#undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
364#define CLANG_ATTR_ARG_CONTEXT_LIST
366#include "clang/Parse/AttrParserStringSwitches.inc"
368#undef CLANG_ATTR_ARG_CONTEXT_LIST
372 assert(Tok.is(tok::identifier) &&
"expected an identifier");
373 IdentifierLoc *IL =
new (Actions.Context)
374 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
389 if (Tok.isNot(tok::r_paren))
392 if (
Parens.consumeClose())
400 &AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
401 AttributeScopeInfo(ScopeName, ScopeLoc),
T.get(), Form);
403 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
404 AttributeScopeInfo(ScopeName, ScopeLoc),
nullptr, 0, Form);
408Parser::ParseUnevaluatedStringInAttribute(
const IdentifierInfo &AttrName) {
409 if (Tok.is(tok::l_paren)) {
412 ExprResult Res = ParseUnevaluatedStringInAttribute(AttrName);
413 Paren.consumeClose();
416 if (!isTokenStringLiteral()) {
417 Diag(Tok.getLocation(), diag::err_expected_string_literal)
424bool Parser::ParseAttributeArgumentList(
427 bool SawError =
false;
432 Expr = ParseUnevaluatedStringInAttribute(AttrName);
434 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
435 Expr = ParseBraceInitializer();
440 if (Tok.is(tok::ellipsis))
442 else if (Tok.is(tok::code_completion)) {
458 if (Actions.DiagnoseUnexpandedParameterPack(Expr.
get())) {
463 Exprs.push_back(Expr.
get());
465 if (Tok.isNot(tok::comma))
470 checkPotentialAngleBracketDelimiter(Comma);
477unsigned Parser::ParseAttributeArgsCommon(
486 bool AttributeIsTypeArgAttr =
488 bool AttributeHasVariadicIdentifierArg =
492 if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
493 Tok.setKind(tok::identifier);
496 if (Tok.is(tok::identifier)) {
498 bool IsIdentifierArg =
499 AttributeHasVariadicIdentifierArg ||
510 IsIdentifierArg =
Next.isOneOf(tok::r_paren, tok::comma);
514 ArgExprs.push_back(ParseIdentifierLoc());
518 if (!ArgExprs.empty() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren)) {
520 if (!ArgExprs.empty())
523 if (AttributeIsTypeArgAttr) {
531 TheParsedType =
T.get();
532 }
else if (AttributeHasVariadicIdentifierArg ||
542 if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
543 Tok.setKind(tok::identifier);
546 if (Tok.is(tok::identifier)) {
547 ArgExprs.push_back(ParseIdentifierLoc());
563 ArgExprs.push_back(ArgExpr.
get());
579 ExprVector ParsedExprs;
580 ParsedAttributeArgumentsProperties ArgProperties =
583 if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties)) {
589 for (
size_t I = 0; I < ParsedExprs.size(); ++I) {
594 Diag(Tok.getLocation(),
595 diag::err_attribute_argument_parm_pack_not_supported)
602 llvm::append_range(ArgExprs, ParsedExprs);
606 SourceLocation RParen = Tok.getLocation();
607 if (!ExpectAndConsume(tok::r_paren)) {
608 SourceLocation AttrLoc = ScopeLoc.
isValid() ? ScopeLoc : AttrNameLoc;
610 if (AttributeIsTypeArgAttr && !TheParsedType.
get().
isNull()) {
612 AttributeScopeInfo(ScopeName, ScopeLoc),
613 TheParsedType, Form);
615 Attrs.
addNew(AttrName, SourceRange(AttrLoc, RParen),
616 AttributeScopeInfo(ScopeName, ScopeLoc), ArgExprs.data(),
617 ArgExprs.size(), Form);
624 return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.
get().
isNull());
627void Parser::ParseGNUAttributeArgs(
632 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
637 if (AttrKind == ParsedAttr::AT_Availability) {
638 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
641 }
else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
642 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
643 ScopeName, ScopeLoc, Form);
645 }
else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
646 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
647 ScopeName, ScopeLoc, Form);
649 }
else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
650 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
653 }
else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
654 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
655 ScopeName, ScopeLoc, Form);
658 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName,
661 }
else if (AttrKind == ParsedAttr::AT_CountedBy ||
662 AttrKind == ParsedAttr::AT_CountedByOrNull ||
663 AttrKind == ParsedAttr::AT_SizedBy ||
664 AttrKind == ParsedAttr::AT_SizedByOrNull) {
665 ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
668 }
else if (AttrKind == ParsedAttr::AT_CXXAssume) {
669 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
670 ScopeLoc, EndLoc, Form);
676 std::optional<ParseScope> PrototypeScope;
683 for (
unsigned i = 0; i != FTI.
NumParams; ++i)
684 Actions.ActOnReenterCXXMethodParameter(
688 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
692unsigned Parser::ParseClangAttributeArgs(
696 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
703 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
704 ScopeName, ScopeLoc, Form);
705 case ParsedAttr::AT_ExternalSourceSymbol:
706 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
707 ScopeName, ScopeLoc, Form);
709 case ParsedAttr::AT_Availability:
710 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
713 case ParsedAttr::AT_ObjCBridgeRelated:
714 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
715 ScopeName, ScopeLoc, Form);
717 case ParsedAttr::AT_SwiftNewType:
718 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
721 case ParsedAttr::AT_TypeTagForDatatype:
722 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
723 ScopeName, ScopeLoc, Form);
726 case ParsedAttr::AT_CXXAssume:
727 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
728 ScopeLoc, EndLoc, Form);
731 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
737 unsigned ExistingAttrs = Attrs.
size();
749 SourceLocation OpenParenLoc = Tok.getLocation();
751 if (
AttrName->getName() ==
"property") {
757 T.expectAndConsume(diag::err_expected_lparen_after,
758 AttrName->getNameStart(), tok::r_paren);
765 IdentifierInfo *AccessorNames[] = {
nullptr,
nullptr};
766 bool HasInvalidAccessor =
false;
771 if (!Tok.is(tok::identifier)) {
773 if (Tok.is(tok::r_paren) && !HasInvalidAccessor &&
774 AccessorNames[AK_Put] ==
nullptr &&
775 AccessorNames[AK_Get] ==
nullptr) {
776 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
780 Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor);
785 SourceLocation KindLoc = Tok.getLocation();
786 StringRef KindStr = Tok.getIdentifierInfo()->getName();
787 if (KindStr ==
"get") {
789 }
else if (KindStr ==
"put") {
793 }
else if (KindStr ==
"set") {
794 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
801 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
803 HasInvalidAccessor =
true;
804 goto next_property_accessor;
808 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
809 HasInvalidAccessor =
true;
822 Diag(Tok.getLocation(), diag::err_ms_property_expected_equal)
828 if (!Tok.is(tok::identifier)) {
829 Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name);
833 if (Kind == AK_Invalid) {
835 }
else if (AccessorNames[Kind] !=
nullptr) {
837 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
839 AccessorNames[
Kind] = Tok.getIdentifierInfo();
843 next_property_accessor:
849 if (Tok.is(tok::r_paren))
852 Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen);
857 if (!HasInvalidAccessor)
859 AccessorNames[AK_Get], AccessorNames[AK_Put],
860 ParsedAttr::Form::Declspec());
862 return !HasInvalidAccessor;
866 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
867 SourceLocation(), ParsedAttr::Form::Declspec());
872 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) <<
AttrName;
879 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
880 assert(Tok.is(tok::kw___declspec) &&
"Not a declspec!");
882 SourceLocation StartLoc = Tok.getLocation();
883 SourceLocation EndLoc = StartLoc;
885 while (Tok.is(tok::kw___declspec)) {
888 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
894 while (Tok.isNot(tok::r_paren)) {
899 if (Tok.is(tok::code_completion)) {
901 Actions.CodeCompletion().CodeCompleteAttribute(
908 bool IsString = Tok.getKind() == tok::string_literal;
909 if (!IsString && Tok.getKind() != tok::identifier &&
910 Tok.getKind() != tok::kw_restrict) {
911 Diag(Tok, diag::err_ms_declspec_type);
917 SourceLocation AttrNameLoc;
919 SmallString<8> StrBuffer;
920 bool Invalid =
false;
921 StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
926 AttrName = PP.getIdentifierInfo(Str);
927 AttrNameLoc = ConsumeStringToken();
933 bool AttrHandled =
false;
936 if (Tok.is(tok::l_paren))
937 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
938 else if (
AttrName->getName() ==
"property")
940 Diag(Tok.getLocation(), diag::err_expected_lparen_after)
944 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
945 ParsedAttr::Form::Declspec());
948 EndLoc =
T.getCloseLocation();
951 Attrs.
Range = SourceRange(StartLoc, EndLoc);
957 auto Kind = Tok.getKind();
959 case tok::kw___fastcall:
960 case tok::kw___stdcall:
961 case tok::kw___thiscall:
962 case tok::kw___regcall:
963 case tok::kw___cdecl:
964 case tok::kw___vectorcall:
965 case tok::kw___ptr64:
967 case tok::kw___ptr32:
969 case tok::kw___uptr: {
970 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
972 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
983 assert(Tok.is(tok::kw___funcref));
984 SourceLocation StartLoc = Tok.getLocation();
987 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
991 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
993 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr,
994 0, tok::kw___funcref);
997void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
998 SourceLocation StartLoc = Tok.getLocation();
999 SourceLocation EndLoc = SkipExtendedMicrosoftTypeAttributes();
1002 SourceRange
Range(StartLoc, EndLoc);
1003 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) <<
Range;
1008 SourceLocation EndLoc;
1011 switch (Tok.getKind()) {
1013 case tok::kw_volatile:
1014 case tok::kw___fastcall:
1015 case tok::kw___stdcall:
1016 case tok::kw___thiscall:
1017 case tok::kw___cdecl:
1018 case tok::kw___vectorcall:
1019 case tok::kw___ptr32:
1020 case tok::kw___ptr64:
1022 case tok::kw___unaligned:
1023 case tok::kw___sptr:
1024 case tok::kw___uptr:
1035 while (Tok.is(tok::kw___pascal)) {
1036 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1038 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1045 while (Tok.is(tok::kw___kernel)) {
1046 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1048 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1054 while (Tok.is(tok::kw___noinline__)) {
1055 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1057 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1058 tok::kw___noinline__);
1063 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1064 SourceLocation AttrNameLoc = Tok.getLocation();
1065 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1069bool Parser::isHLSLQualifier(
const Token &
Tok)
const {
1070 return Tok.is(tok::kw_groupshared);
1074 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1075 auto Kind = Tok.getKind();
1077 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0, Kind);
1083 auto Kind = Tok.getKind();
1085 case tok::kw__Nonnull:
1086 case tok::kw__Nullable:
1087 case tok::kw__Nullable_result:
1088 case tok::kw__Null_unspecified: {
1089 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1092 Diag(AttrNameLoc, diag::ext_nullability)
1094 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1105 return (Separator ==
'.' || Separator ==
'_');
1108VersionTuple Parser::ParseVersionTuple(
SourceRange &Range) {
1109 Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());
1111 if (!Tok.is(tok::numeric_constant)) {
1112 Diag(Tok, diag::err_expected_version);
1115 return VersionTuple();
1122 SmallString<512> Buffer;
1123 Buffer.resize(Tok.getLength()+1);
1124 const char *ThisTokBegin = &Buffer[0];
1127 bool Invalid =
false;
1128 unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);
1130 return VersionTuple();
1133 unsigned AfterMajor = 0;
1135 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
1136 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
1140 if (AfterMajor == 0) {
1141 Diag(Tok, diag::err_expected_version);
1144 return VersionTuple();
1147 if (AfterMajor == ActualLength) {
1152 Diag(Tok, diag::err_zero_version);
1153 return VersionTuple();
1156 return VersionTuple(Major);
1159 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1161 || (AfterMajor + 1 == ActualLength)) {
1162 Diag(Tok, diag::err_expected_version);
1165 return VersionTuple();
1169 unsigned AfterMinor = AfterMajor + 1;
1171 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
1172 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
1176 if (AfterMinor == ActualLength) {
1180 if (Major == 0 && Minor == 0) {
1181 Diag(Tok, diag::err_zero_version);
1182 return VersionTuple();
1185 return VersionTuple(Major, Minor);
1188 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1191 Diag(Tok, diag::err_expected_version);
1194 return VersionTuple();
1198 if (AfterMajorSeparator != AfterMinorSeparator)
1199 Diag(Tok, diag::warn_expected_consistent_version_separator);
1202 unsigned AfterSubminor = AfterMinor + 1;
1203 unsigned Subminor = 0;
1204 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
1205 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
1209 if (AfterSubminor != ActualLength) {
1210 Diag(Tok, diag::err_expected_version);
1213 return VersionTuple();
1216 return VersionTuple(Major, Minor, Subminor);
1219void Parser::ParseAvailabilityAttribute(
1223 enum { Introduced, Deprecated, Obsoleted,
Unknown };
1224 AvailabilityChange Changes[
Unknown];
1226 IdentifierLoc *EnvironmentLoc =
nullptr;
1230 if (
T.consumeOpen()) {
1231 Diag(Tok, diag::err_expected) << tok::l_paren;
1236 if (Tok.isNot(tok::identifier)) {
1237 Diag(Tok, diag::err_availability_expected_platform);
1241 IdentifierLoc *Platform = ParseIdentifierLoc();
1244 if (Ident->getName().contains(
"xrOS") || Ident->getName().contains(
"xros"))
1245 Diag(Platform->
getLoc(), diag::warn_availability_unknown_platform)
1248 else if (Ident->getName() ==
"macosx")
1252 else if (Ident->getName() ==
"macosx_app_extension")
1256 AvailabilityAttr::canonicalizePlatformName(Ident->getName())));
1260 if (ExpectAndConsume(tok::comma)) {
1267 if (!Ident_introduced) {
1268 Ident_introduced = PP.getIdentifierInfo(
"introduced");
1269 Ident_deprecated = PP.getIdentifierInfo(
"deprecated");
1270 Ident_obsoleted = PP.getIdentifierInfo(
"obsoleted");
1271 Ident_unavailable = PP.getIdentifierInfo(
"unavailable");
1272 Ident_message = PP.getIdentifierInfo(
"message");
1273 Ident_strict = PP.getIdentifierInfo(
"strict");
1274 Ident_replacement = PP.getIdentifierInfo(
"replacement");
1275 Ident_environment = PP.getIdentifierInfo(
"environment");
1280 SourceLocation UnavailableLoc, StrictLoc;
1282 if (Tok.isNot(tok::identifier)) {
1283 Diag(Tok, diag::err_availability_expected_change);
1287 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1290 if (
Keyword == Ident_strict) {
1292 Diag(KeywordLoc, diag::err_availability_redundant)
1293 <<
Keyword << SourceRange(StrictLoc);
1295 StrictLoc = KeywordLoc;
1299 if (
Keyword == Ident_unavailable) {
1300 if (UnavailableLoc.
isValid()) {
1301 Diag(KeywordLoc, diag::err_availability_redundant)
1302 <<
Keyword << SourceRange(UnavailableLoc);
1304 UnavailableLoc = KeywordLoc;
1311 if (Changes[Deprecated].KeywordLoc.
isValid()) {
1312 Diag(KeywordLoc, diag::err_availability_redundant)
1314 << SourceRange(Changes[Deprecated].KeywordLoc);
1319 Changes[Deprecated].
Version = VersionTuple(1);
1323 if (
Keyword == Ident_environment) {
1324 if (EnvironmentLoc !=
nullptr) {
1325 Diag(KeywordLoc, diag::err_availability_redundant)
1330 if (Tok.isNot(tok::equal)) {
1331 Diag(Tok, diag::err_expected_after) <<
Keyword << tok::equal;
1337 if (!isTokenStringLiteral()) {
1338 Diag(Tok, diag::err_expected_string_literal)
1343 if (
Keyword == Ident_message) {
1351 if (
Keyword == Ident_environment) {
1352 if (Tok.isNot(tok::identifier)) {
1353 Diag(Tok, diag::err_availability_expected_environment);
1357 EnvironmentLoc = ParseIdentifierLoc();
1363 if ((
Keyword == Ident_introduced ||
Keyword == Ident_deprecated) &&
1364 Tok.is(tok::identifier)) {
1365 IdentifierInfo *NA = Tok.getIdentifierInfo();
1368 if (
Keyword == Ident_introduced)
1369 UnavailableLoc = KeywordLoc;
1374 SourceRange VersionRange;
1375 VersionTuple Version = ParseVersionTuple(VersionRange);
1377 if (Version.empty()) {
1383 if (
Keyword == Ident_introduced)
1385 else if (
Keyword == Ident_deprecated)
1387 else if (
Keyword == Ident_obsoleted)
1393 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1394 Diag(KeywordLoc, diag::err_availability_redundant)
1396 << SourceRange(Changes[Index].KeywordLoc,
1397 Changes[Index].VersionRange.
getEnd());
1401 Changes[Index].
Version = Version;
1404 Diag(KeywordLoc, diag::err_availability_unknown_change)
1411 if (
T.consumeClose())
1415 *endLoc =
T.getCloseLocation();
1419 if (UnavailableLoc.
isValid()) {
1420 bool Complained =
false;
1421 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1422 if (Changes[Index].KeywordLoc.
isValid()) {
1424 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1425 << SourceRange(Changes[Index].KeywordLoc,
1426 Changes[Index].VersionRange.
getEnd());
1431 Changes[Index] = AvailabilityChange();
1437 attrs.
addNew(&Availability,
1438 SourceRange(AvailabilityLoc,
T.getCloseLocation()),
1439 AttributeScopeInfo(ScopeName, ScopeLoc), Platform,
1440 Changes[Introduced], Changes[Deprecated], Changes[Obsoleted],
1441 UnavailableLoc, MessageExpr.
get(), Form, StrictLoc,
1442 ReplacementExpr.
get(), EnvironmentLoc);
1445void Parser::ParseExternalSourceSymbolAttribute(
1451 if (
T.expectAndConsume())
1455 if (!Ident_language) {
1456 Ident_language = PP.getIdentifierInfo(
"language");
1457 Ident_defined_in = PP.getIdentifierInfo(
"defined_in");
1458 Ident_generated_declaration = PP.getIdentifierInfo(
"generated_declaration");
1459 Ident_USR = PP.getIdentifierInfo(
"USR");
1463 bool HasLanguage =
false;
1465 bool HasDefinedIn =
false;
1466 IdentifierLoc *GeneratedDeclaration =
nullptr;
1468 bool HasUSR =
false;
1472 if (Tok.isNot(tok::identifier)) {
1473 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1478 SourceLocation KeywordLoc = Tok.getLocation();
1479 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1480 if (
Keyword == Ident_generated_declaration) {
1481 if (GeneratedDeclaration) {
1482 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) <<
Keyword;
1486 GeneratedDeclaration = ParseIdentifierLoc();
1492 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1498 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1504 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1506 if (
Keyword == Ident_language)
1508 else if (
Keyword == Ident_USR)
1511 HasDefinedIn =
true;
1513 if (!isTokenStringLiteral()) {
1514 Diag(Tok, diag::err_expected_string_literal)
1519 : (
Keyword == Ident_defined_in ? 1 : 2));
1523 if (
Keyword == Ident_language) {
1525 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1531 }
else if (
Keyword == Ident_USR) {
1533 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1540 assert(
Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1542 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1552 if (
T.consumeClose())
1555 *EndLoc =
T.getCloseLocation();
1559 Attrs.
addNew(&ExternalSourceSymbol, SourceRange(Loc,
T.getCloseLocation()),
1560 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1564void Parser::ParseObjCBridgeRelatedAttribute(
1570 if (
T.consumeOpen()) {
1571 Diag(Tok, diag::err_expected) << tok::l_paren;
1576 if (Tok.isNot(tok::identifier)) {
1577 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1581 IdentifierLoc *RelatedClass = ParseIdentifierLoc();
1582 if (ExpectAndConsume(tok::comma)) {
1591 if (Tok.is(tok::identifier)) {
1594 Diag(Tok, diag::err_objcbridge_related_selector_name);
1600 if (Tok.is(tok::colon))
1601 Diag(Tok, diag::err_objcbridge_related_selector_name);
1603 Diag(Tok, diag::err_expected) << tok::comma;
1611 if (Tok.is(tok::identifier))
1613 else if (Tok.isNot(tok::r_paren)) {
1614 Diag(Tok, diag::err_expected) << tok::r_paren;
1620 if (
T.consumeClose())
1624 *EndLoc =
T.getCloseLocation();
1627 Attrs.
addNew(&ObjCBridgeRelated,
1628 SourceRange(ObjCBridgeRelatedLoc,
T.getCloseLocation()),
1629 AttributeScopeInfo(ScopeName, ScopeLoc), RelatedClass,
1630 ClassMethod, InstanceMethod, Form);
1633void Parser::ParseSwiftNewTypeAttribute(
1640 if (
T.consumeOpen()) {
1641 Diag(Tok, diag::err_expected) << tok::l_paren;
1645 if (Tok.is(tok::r_paren)) {
1646 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
1650 if (Tok.isNot(tok::kw_struct) && Tok.isNot(tok::kw_enum)) {
1651 Diag(Tok, diag::warn_attribute_type_not_supported)
1652 << &
AttrName << Tok.getIdentifierInfo();
1653 if (!isTokenSpecial())
1659 auto *SwiftType =
new (Actions.Context)
1660 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
1664 if (
T.consumeClose())
1667 *EndLoc =
T.getCloseLocation();
1670 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
T.getCloseLocation()),
1671 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1675void Parser::ParseTypeTagForDatatypeAttribute(
1679 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1684 if (Tok.isNot(tok::identifier)) {
1685 Diag(Tok, diag::err_expected) << tok::identifier;
1689 IdentifierLoc *ArgumentKind = ParseIdentifierLoc();
1691 if (ExpectAndConsume(tok::comma)) {
1696 SourceRange MatchingCTypeRange;
1703 bool LayoutCompatible =
false;
1704 bool MustBeNull =
false;
1706 if (Tok.isNot(tok::identifier)) {
1707 Diag(Tok, diag::err_expected) << tok::identifier;
1711 IdentifierInfo *Flag = Tok.getIdentifierInfo();
1712 if (Flag->
isStr(
"layout_compatible"))
1713 LayoutCompatible =
true;
1714 else if (Flag->
isStr(
"must_be_null"))
1717 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1724 if (!
T.consumeClose()) {
1726 &AttrName, AttrNameLoc, AttributeScopeInfo(ScopeName, ScopeLoc),
1727 ArgumentKind, MatchingCType.
get(), LayoutCompatible, MustBeNull, Form);
1731 *EndLoc =
T.getCloseLocation();
1734bool Parser::DiagnoseProhibitedCXX11Attribute() {
1735 assert(Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square));
1737 switch (isCXX11AttributeSpecifier(
true)) {
1743 Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1748 SourceLocation BeginLoc = ConsumeBracket();
1751 assert(Tok.is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1752 SourceLocation EndLoc = ConsumeBracket();
1753 Diag(BeginLoc, diag::err_attributes_not_allowed)
1754 << SourceRange(BeginLoc, EndLoc);
1757 llvm_unreachable(
"All cases handled above.");
1762 assert((Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square)) ||
1763 Tok.is(tok::kw_alignas) || Tok.isRegularKeywordAttribute());
1767 Tok.isRegularKeywordAttribute() ? Tok.getIdentifierInfo() :
nullptr;
1768 SourceLocation Loc = Tok.getLocation();
1769 ParseCXX11Attributes(Attrs);
1770 CharSourceRange AttrRange(SourceRange(Loc, Attrs.
Range.
getEnd()),
true);
1773 :
Diag(Loc, diag::err_attributes_not_allowed))
1778void Parser::DiagnoseProhibitedAttributes(
1781 if (CorrectLocation.
isValid()) {
1782 CharSourceRange AttrRange(Attrs.
Range,
true);
1783 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1784 ?
Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1785 :
Diag(CorrectLocation, diag::err_attributes_misplaced))
1790 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1791 ?
Diag(
Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr
1792 :
Diag(
Range.getBegin(), diag::err_attributes_not_allowed))
1798 unsigned AttrDiagID,
1799 unsigned KeywordDiagID,
1800 bool DiagnoseEmptyAttrs,
1801 bool WarnOnUnknownAttrs) {
1807 auto &
SM = PP.getSourceManager();
1811 if (FirstLSquare.
is(tok::l_square)) {
1812 std::optional<Token> SecondLSquare =
1815 if (SecondLSquare && SecondLSquare->is(tok::l_square)) {
1825 for (
const ParsedAttr &AL : Attrs) {
1826 if (AL.isRegularKeywordAttribute()) {
1827 Diag(AL.getLoc(), KeywordDiagID) << AL;
1831 if (!AL.isStandardAttributeSyntax())
1834 if (WarnOnUnknownAttrs) {
1835 Actions.DiagnoseUnknownAttribute(AL);
1839 Diag(AL.getLoc(), AttrDiagID) << AL;
1846 for (
const ParsedAttr &PA : Attrs) {
1847 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1848 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1849 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
1858 llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;
1861 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1862 AL.isDeclspecAttribute()) ||
1863 AL.isMicrosoftAttribute())
1864 ToBeMoved.push_back(&AL);
1867 for (ParsedAttr *AL : ToBeMoved) {
1881 ObjCDeclContextSwitch ObjCDC(*
this);
1883 Decl *SingleDecl =
nullptr;
1884 switch (Tok.getKind()) {
1885 case tok::kw_template:
1886 case tok::kw_export:
1887 ProhibitAttributes(DeclAttrs);
1888 ProhibitAttributes(DeclSpecAttrs);
1889 return ParseDeclarationStartingWithTemplate(Context, DeclEnd, DeclAttrs);
1890 case tok::kw_inline:
1893 ProhibitAttributes(DeclAttrs);
1894 ProhibitAttributes(DeclSpecAttrs);
1896 return ParseNamespace(Context, DeclEnd, InlineLoc);
1898 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1899 true,
nullptr, DeclSpecStart);
1901 case tok::kw_cbuffer:
1902 case tok::kw_tbuffer:
1903 SingleDecl = ParseHLSLBuffer(DeclEnd, DeclAttrs);
1905 case tok::kw_namespace:
1906 ProhibitAttributes(DeclAttrs);
1907 ProhibitAttributes(DeclSpecAttrs);
1908 return ParseNamespace(Context, DeclEnd);
1909 case tok::kw_using: {
1911 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1912 DeclEnd, DeclAttrs);
1914 case tok::kw_static_assert:
1915 case tok::kw__Static_assert:
1916 ProhibitAttributes(DeclAttrs);
1917 ProhibitAttributes(DeclSpecAttrs);
1918 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1921 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1922 true,
nullptr, DeclSpecStart);
1927 return Actions.ConvertDeclToDeclGroup(SingleDecl);
1933 bool RequireSemi, ForRangeInit *FRI,
SourceLocation *DeclSpecStart) {
1935 ParsedAttributesView OriginalDeclSpecAttrs;
1936 OriginalDeclSpecAttrs.
prepend(DeclSpecAttrs.
begin(), DeclSpecAttrs.
end());
1937 OriginalDeclSpecAttrs.
Range = DeclSpecAttrs.
Range;
1940 ParsingDeclSpec DS(*
this);
1943 ParsedTemplateInfo TemplateInfo;
1944 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
1945 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none, DSContext);
1950 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
1955 if (Tok.is(tok::semi)) {
1956 ProhibitAttributes(DeclAttrs);
1957 DeclEnd = Tok.getLocation();
1959 RecordDecl *AnonRecord =
nullptr;
1960 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
1962 Actions.ActOnDefinedDeclarationSpecifier(TheDecl);
1963 DS.complete(TheDecl);
1965 Decl* decls[] = {AnonRecord, TheDecl};
1966 return Actions.BuildDeclaratorGroup(decls);
1968 return Actions.ConvertDeclToDeclGroup(TheDecl);
1972 Actions.ActOnDefinedDeclarationSpecifier(DS.
getRepAsDecl());
1977 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
1981 switch (Tok.getKind()) {
1982 case tok::annot_cxxscope:
1983 case tok::annot_template_id:
1985 case tok::code_completion:
1986 case tok::coloncolon:
1988 case tok::kw___attribute:
1989 case tok::kw_operator:
2005 case tok::identifier:
2007 case tok::code_completion:
2008 case tok::coloncolon:
2011 case tok::equalequal:
2012 case tok::kw_alignas:
2014 case tok::kw___attribute:
2032 case tok::identifier:
2036 return Tok.isRegularKeywordAttribute();
2040 return Tok.isRegularKeywordAttribute();
2046 switch (Tok.getKind()) {
2052 if (Tok.isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
2076 case tok::kw_inline:
2080 if (Tok.isAtStartOfLine() &&
NextToken().
is(tok::kw_namespace) &&
2081 (!ParsingInObjCContainer || CurParsedObjCImpl))
2085 case tok::kw_extern:
2088 case tok::kw_namespace:
2092 if (Tok.isAtStartOfLine() &&
2093 (!ParsingInObjCContainer || CurParsedObjCImpl))
2099 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2100 ParsingInObjCContainer)
2107 if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
2112 case tok::annot_module_begin:
2113 case tok::annot_module_end:
2114 case tok::annot_module_include:
2115 case tok::annot_repl_input_end:
2129 ParsedTemplateInfo &TemplateInfo,
2131 ForRangeInit *FRI) {
2137 LocalAttrs.takeAllPrependingFrom(Attrs);
2139 if (TemplateInfo.TemplateParams)
2142 bool IsTemplateSpecOrInst =
2149 if (IsTemplateSpecOrInst)
2159 while (MaybeParseHLSLAnnotations(D))
2162 if (
Tok.is(tok::kw_requires))
2163 ParseTrailingRequiresClause(D);
2168 LateParsedAttrList LateParsedAttrs(
true);
2170 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2175 if (
Tok.is(tok::kw__Noreturn)) {
2177 const char *PrevSpec;
2183 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2184 Fixit &=
Tok.isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2186 Diag(Loc, diag::err_c11_noreturn_misplaced)
2188 << (Fixit ?
FixItHint::CreateInsertion(D.getBeginLoc(),
"_Noreturn ")
2193 if (Tok.is(tok::equal) &&
NextToken().
is(tok::code_completion)) {
2195 Actions.CodeCompletion().CodeCompleteAfterFunctionEquals(D);
2204 while (
auto Specifier = isCXX11VirtSpecifier()) {
2205 Diag(Tok, diag::err_virt_specifier_outside_class)
2213 if (!isDeclarationAfterDeclarator()) {
2219 if (isStartOfFunctionDefinition(D)) {
2229 diag::err_function_declared_typedef)
2233 Decl *TheDecl =
nullptr;
2239 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2240 TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(),
2243 SourceLocation LAngleLoc =
2244 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2246 diag::err_explicit_instantiation_with_definition)
2247 << SourceRange(TemplateInfo.TemplateLoc)
2252 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2253 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
2254 LAngleLoc,
nullptr));
2256 TheDecl = ParseFunctionDefinition(
2258 ParsedTemplateInfo(&FakedParamLists,
2265 ParseFunctionDefinition(D, TemplateInfo, &LateParsedAttrs);
2268 return Actions.ConvertDeclToDeclGroup(TheDecl);
2272 Tok.is(tok::kw_namespace)) {
2282 Diag(Tok, diag::err_expected_fn_body);
2287 if (Tok.is(tok::l_brace)) {
2288 Diag(Tok, diag::err_function_definition_not_allowed);
2296 if (ParseAsmAttributesAfterDeclarator(D))
2305 if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
2306 bool IsForRangeLoop =
false;
2308 IsForRangeLoop =
true;
2309 EnterExpressionEvaluationContext ForRangeInitContext(
2317 auto &LastRecord = Actions.currentEvaluationContext();
2318 LastRecord.InLifetimeExtendingContext =
true;
2319 LastRecord.RebuildDefaultArgOrDefaultInit =
true;
2323 Actions.OpenMP().startOpenMPCXXRangeFor();
2324 if (Tok.is(tok::l_brace))
2325 FRI->RangeExpr = ParseBraceInitializer();
2332 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
2336 FRI->LifetimeExtendTemps = std::move(
2337 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps);
2341 if (IsForRangeLoop) {
2342 Actions.ActOnCXXForRangeDecl(ThisDecl);
2345 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2346 VD->setObjCForDecl(
true);
2348 Actions.FinalizeDeclaration(ThisDecl);
2349 D.complete(ThisDecl);
2350 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, ThisDecl);
2353 SmallVector<Decl *, 8> DeclsInGroup;
2355 ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo, FRI);
2356 if (LateParsedAttrs.size() > 0)
2357 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2358 D.complete(FirstDecl);
2360 DeclsInGroup.push_back(FirstDecl);
2366 SourceLocation CommaLoc;
2368 if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2372 Diag(CommaLoc, diag::err_expected_semi_declaration)
2384 Diag(CommaLoc, diag::err_multiple_template_declarators)
2385 << TemplateInfo.Kind;
2399 MaybeParseGNUAttributes(D);
2403 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2408 MaybeParseHLSLAnnotations(D);
2415 if (Tok.is(tok::kw_requires))
2416 ParseTrailingRequiresClause(D);
2417 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D, TemplateInfo);
2418 D.complete(ThisDecl);
2420 DeclsInGroup.push_back(ThisDecl);
2425 *DeclEnd = Tok.getLocation();
2427 if (ExpectSemi && ExpectAndConsumeSemi(
2429 ? diag::err_invalid_token_after_toplevel_declarator
2430 : diag::err_expected_semi_declaration)) {
2438 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
2441bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &D) {
2443 if (Tok.is(tok::kw_asm)) {
2445 ExprResult AsmLabel(ParseSimpleAsm(
true, &Loc));
2446 if (AsmLabel.isInvalid()) {
2455 MaybeParseGNUAttributes(D);
2459Decl *Parser::ParseDeclarationAfterDeclarator(
2460 Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
2461 if (ParseAsmAttributesAfterDeclarator(D))
2464 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
2467Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2468 Declarator &D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2470 struct InitializerScopeRAII {
2476 InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl)
2477 : P(P), D(D), ThisDecl(ThisDecl), Entered(
false) {
2480 if (D.getCXXScopeSpec().isSet()) {
2482 S = P.getCurScope();
2485 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2490 ~InitializerScopeRAII() {
2506 InitKind TheInitKind;
2508 if (isTokenEqualOrEqualTypo())
2509 TheInitKind = InitKind::Equal;
2510 else if (
Tok.
is(tok::l_paren))
2511 TheInitKind = InitKind::CXXDirect;
2514 TheInitKind = InitKind::CXXBraced;
2516 TheInitKind = InitKind::Uninitialized;
2517 if (TheInitKind != InitKind::Uninitialized)
2521 Decl *ThisDecl =
nullptr;
2522 Decl *OuterDecl =
nullptr;
2523 switch (TemplateInfo.Kind) {
2525 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2530 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
2531 *TemplateInfo.TemplateParams,
2533 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2536 ThisDecl = VT->getTemplatedDecl();
2542 if (
Tok.
is(tok::semi)) {
2543 DeclResult ThisRes = Actions.ActOnExplicitInstantiation(
2544 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
2546 SkipUntil(tok::semi, StopBeforeMatch);
2549 ThisDecl = ThisRes.
get();
2557 Diag(
Tok, diag::err_template_defn_explicit_instantiation)
2559 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2562 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2564 diag::err_explicit_instantiation_with_definition)
2569 TemplateParameterLists FakedParamLists;
2570 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2572 LAngleLoc,
nullptr));
2575 Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D);
2584 switch (TheInitKind) {
2586 case InitKind::Equal: {
2589 if (
Tok.
is(tok::kw_delete)) {
2591 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2594 Diag(ConsumeToken(), diag::err_deleted_non_function);
2595 SkipDeletedFunctionBody();
2596 }
else if (
Tok.
is(tok::kw_default)) {
2598 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2601 Diag(ConsumeToken(), diag::err_default_special_members)
2602 << getLangOpts().CPlusPlus20;
2604 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2606 if (
Tok.
is(tok::code_completion)) {
2608 Actions.CodeCompletion().CodeCompleteInitializer(getCurScope(),
2610 Actions.FinalizeDeclaration(ThisDecl);
2620 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2624 FRI->ColonLoc = EqualLoc;
2626 FRI->RangeExpr =
Init;
2629 if (
Init.isInvalid()) {
2631 StopTokens.push_back(tok::comma);
2634 StopTokens.push_back(tok::r_paren);
2635 SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch);
2636 Actions.ActOnInitializerError(ThisDecl);
2638 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
2643 case InitKind::CXXDirect: {
2650 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2652 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2653 auto RunSignatureHelp = [&]() {
2655 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2656 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2659 CalledSignatureHelp =
true;
2660 return PreferredType;
2662 auto SetPreferredType = [&] {
2663 PreferredType.enterFunctionArgument(
Tok.
getLocation(), RunSignatureHelp);
2666 llvm::function_ref<void()> ExpressionStarts;
2672 ExpressionStarts = SetPreferredType;
2675 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2678 if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
2679 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2680 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2683 CalledSignatureHelp =
true;
2685 Actions.ActOnInitializerError(ThisDecl);
2686 SkipUntil(tok::r_paren, StopAtSemi);
2692 T.getCloseLocation(),
2694 Actions.AddInitializerToDecl(ThisDecl,
Initializer.get(),
2699 case InitKind::CXXBraced: {
2701 Diag(
Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2703 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2708 if (
Init.isInvalid()) {
2709 Actions.ActOnInitializerError(ThisDecl);
2711 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
true);
2714 case InitKind::Uninitialized: {
2715 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2716 Actions.ActOnUninitializedDecl(ThisDecl);
2721 Actions.FinalizeDeclaration(ThisDecl);
2722 return OuterDecl ? OuterDecl : ThisDecl;
2725void Parser::ParseSpecifierQualifierList(
2728 ParsedTemplateInfo TemplateInfo;
2732 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC,
nullptr,
2733 AllowImplicitTypename);
2738 Diag(Tok, diag::err_expected_type);
2741 Diag(Tok, diag::err_typename_requires_specqual);
2752 diag::err_typename_invalid_storageclass);
2796 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2797 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2802 ParsedTemplateInfo &TemplateInfo,
2805 assert(Tok.is(tok::identifier) &&
"should have identifier");
2807 SourceLocation Loc = Tok.getLocation();
2827 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
2845 AnnotateScopeToken(*SS,
false);
2854 if (
ParsedType T = Actions.ActOnMSVCUnknownTypeName(
2855 *Tok.getIdentifierInfo(), Tok.getLocation(),
2856 DSC == DeclSpecContext::DSC_template_type_arg)) {
2857 const char *PrevSpec;
2860 Actions.getASTContext().getPrintingPolicy());
2873 if (SS ==
nullptr) {
2874 const char *TagName =
nullptr, *FixitTagName =
nullptr;
2877 switch (Actions.isTagName(*Tok.getIdentifierInfo(),
getCurScope())) {
2880 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
2882 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
2884 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
2886 TagName=
"__interface"; FixitTagName =
"__interface ";
2887 TagKind=tok::kw___interface;
break;
2889 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
2893 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
2894 LookupResult R(Actions, TokenName, SourceLocation(),
2897 Diag(Loc, diag::err_use_of_tag_name_without_tag)
2898 << TokenName << TagName <<
getLangOpts().CPlusPlus
2904 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2905 << TokenName << TagName;
2909 if (TagKind == tok::kw_enum)
2910 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,
2911 DeclSpecContext::DSC_normal);
2913 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
2915 DeclSpecContext::DSC_normal, Attrs);
2922 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
2923 DSC == DeclSpecContext::DSC_class)) {
2927 case tok::l_paren: {
2934 TentativeParsingAction PA(*
this);
2936 TPResult TPR = TryParseDeclarator(
false);
2939 if (TPR != TPResult::False) {
2947 if (DSC == DeclSpecContext::DSC_class ||
2948 (DSC == DeclSpecContext::DSC_top_level && SS)) {
2949 IdentifierInfo *II = Tok.getIdentifierInfo();
2950 if (Actions.isCurrentClassNameTypo(II, SS)) {
2951 Diag(Loc, diag::err_constructor_bad_name)
2952 << Tok.getIdentifierInfo() << II
2954 Tok.setIdentifierInfo(II);
2972 AnnotateScopeToken(*SS,
false);
2986 IdentifierInfo *II = Tok.getIdentifierInfo();
2988 Actions.DiagnoseUnknownTypeName(II, Loc,
getCurScope(), SS,
T,
2994 const char *PrevSpec;
2997 Actions.getASTContext().getPrintingPolicy());
3002 }
else if (II != Tok.getIdentifierInfo()) {
3015 if (IsTemplateName) {
3016 SourceLocation LAngle, RAngle;
3017 TemplateArgList Args;
3018 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3027Parser::DeclSpecContext
3031 return DeclSpecContext::DSC_class;
3033 return DeclSpecContext::DSC_top_level;
3035 return DeclSpecContext::DSC_template_param;
3037 return DeclSpecContext::DSC_template_arg;
3039 return DeclSpecContext::DSC_template_type_arg;
3042 return DeclSpecContext::DSC_trailing;
3045 return DeclSpecContext::DSC_alias_declaration;
3047 return DeclSpecContext::DSC_association;
3049 return DeclSpecContext::DSC_type_specifier;
3051 return DeclSpecContext::DSC_condition;
3053 return DeclSpecContext::DSC_conv_operator;
3055 return DeclSpecContext::DSC_new;
3070 return DeclSpecContext::DSC_normal;
3073 llvm_unreachable(
"Missing DeclaratorContext case");
3080 if (isTypeIdInParens()) {
3081 SourceLocation TypeLoc = Tok.getLocation();
3083 SourceRange TypeRange(Start, Tok.getLocation());
3084 if (Actions.ActOnAlignasTypeArgument(KWName, Ty, TypeLoc, TypeRange))
3101 assert(Tok.isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3102 "Not an alignment-specifier!");
3109 if (
T.expectAndConsume())
3114 SourceLocation EllipsisLoc;
3116 ParseAlignArgument(PP.getSpelling(KWTok),
T.getOpenLocation(),
3125 *EndLoc =
T.getCloseLocation();
3132 ArgExprs.push_back(ArgExpr.
get());
3133 Attrs.
addNew(KWName, KWLoc, AttributeScopeInfo(), ArgExprs.data(), 1, Kind,
3138void Parser::DistributeCLateParsedAttrs(
Decl *Dcl,
3139 LateParsedAttrList *LateAttrs) {
3144 for (
auto *LateAttr : *LateAttrs) {
3145 if (LateAttr->Decls.empty())
3146 LateAttr->addDecl(Dcl);
3152 assert(Tok.is(tok::kw___ptrauth));
3154 IdentifierInfo *KwName = Tok.getIdentifierInfo();
3158 if (
T.expectAndConsume())
3168 ArgExprs.push_back(ER.
get());
3172 SourceLocation EndLoc =
T.getCloseLocation();
3174 if (ArgExprs.empty() || ArgExprs.size() > 3) {
3175 Diag(KwLoc, diag::err_ptrauth_qualifier_bad_arg_count);
3179 Attrs.
addNew(KwName, SourceRange(KwLoc, EndLoc), AttributeScopeInfo(),
3180 ArgExprs.data(), ArgExprs.size(),
3181 ParsedAttr::Form::Keyword(
false,
3191 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3196 if (Tok.is(tok::r_paren)) {
3197 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
3204 using ExpressionKind =
3206 EnterExpressionEvaluationContext EC(
3208 ExpressionKind::EK_AttrArgument);
3216 ArgExprs.push_back(ArgExpr.
get());
3219 ASTContext &Ctx = Actions.getASTContext();
3225 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
3226 AttributeScopeInfo(), ArgExprs.data(), ArgExprs.size(), Form);
3229ExprResult Parser::ParseExtIntegerArgument() {
3230 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3231 "Not an extended int type");
3235 if (
T.expectAndConsume())
3244 if(
T.consumeClose())
3251 DeclSpecContext DSContext,
3252 LateParsedAttrList *LateAttrs) {
3255 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3256 DSContext == DeclSpecContext::DSC_top_level);
3259 Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
3260 tok::annot_template_id) &&
3266 bool HasScope = Tok.is(tok::annot_cxxscope);
3268 Token AfterScope = HasScope ?
NextToken() : Tok;
3272 bool MightBeDeclarator =
true;
3273 if (Tok.isOneOf(tok::kw_typename, tok::annot_typename)) {
3275 MightBeDeclarator =
false;
3276 }
else if (AfterScope.
is(tok::annot_template_id)) {
3279 TemplateIdAnnotation *Annot =
3282 MightBeDeclarator =
false;
3283 }
else if (AfterScope.
is(tok::identifier)) {
3288 if (
Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3289 tok::annot_cxxscope, tok::coloncolon)) {
3291 MightBeDeclarator = false;
3292 }
else if (HasScope) {
3297 Actions.RestoreNestedNameSpecifierAnnotation(
3298 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
3300 Sema::NameClassification Classification = Actions.ClassifyName(
3303 switch (Classification.
getKind()) {
3309 llvm_unreachable(
"typo correction is not possible here");
3317 MightBeDeclarator =
false;
3332 if (MightBeDeclarator)
3335 const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
3337 diag::err_expected_after)
3348 ParsedTemplateInfo NotATemplate;
3349 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3353void Parser::ParseDeclarationSpecifiers(
3355 DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
3367 if (DSContext == DeclSpecContext::DSC_conv_operator) {
3370 DSContext = DeclSpecContext::DSC_type_specifier;
3373 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3374 DSContext == DeclSpecContext::DSC_top_level);
3375 bool AttrsLastTime =
false;
3376 ParsedAttributes attrs(AttrFactory);
3378 PrintingPolicy Policy = Actions.getPrintingPolicy();
3381 bool isStorageClass =
false;
3382 const char *PrevSpec =
nullptr;
3383 unsigned DiagID = 0;
3387 SourceLocation ConsumedEnd;
3396 if (
getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&
3399 Tok.setKind(tok::identifier);
3401 SourceLocation Loc = Tok.getLocation();
3404 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3408 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
3409 Tok.setKind(tok::identifier);
3418 bool IsTemplateSpecOrInst =
3422 switch (Tok.getKind()) {
3424 if (Tok.isRegularKeywordAttribute())
3429 ProhibitAttributes(attrs);
3432 for (
const ParsedAttr &PA : attrs) {
3433 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3434 !PA.isRegularKeywordAttribute())
3442 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3443 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3450 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3451 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3454 if (PA.getKind() == ParsedAttr::AT_LifetimeBound)
3455 Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type)
3456 << PA << PA.isRegularKeywordAttribute()
3459 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3460 << PA << PA.isRegularKeywordAttribute();
3469 DS.
Finish(Actions, Policy);
3473 case tok::kw__Alignas:
3474 diagnoseUseOfC11Keyword(Tok);
3476 case tok::kw_alignas:
3482 if (Tok.getKind() == tok::kw_alignas)
3483 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
3489 if (!isAllowedCXX11AttributeSpecifier())
3490 goto DoneWithDeclSpec;
3493 ProhibitAttributes(attrs);
3498 attrs.Range = SourceRange();
3500 ParseCXX11Attributes(attrs);
3501 AttrsLastTime =
true;
3504 case tok::code_completion: {
3508 bool AllowNonIdentifiers
3514 bool AllowNestedNameSpecifiers
3515 = DSContext == DeclSpecContext::DSC_top_level ||
3519 Actions.CodeCompletion().CodeCompleteDeclSpec(
3520 getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3526 CCC = DSContext == DeclSpecContext::DSC_class
3529 else if (DSContext == DeclSpecContext::DSC_class)
3533 else if (CurParsedObjCImpl)
3537 Actions.CodeCompletion().CodeCompleteOrdinaryName(
getCurScope(), CCC);
3541 case tok::coloncolon:
3547 goto DoneWithDeclSpec;
3549 if (Tok.is(tok::coloncolon))
3550 goto DoneWithDeclSpec;
3553 case tok::annot_cxxscope: {
3555 goto DoneWithDeclSpec;
3558 if (TemplateInfo.TemplateParams)
3560 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
3561 Tok.getAnnotationRange(),
3567 TemplateIdAnnotation *TemplateId =
Next.is(tok::annot_template_id)
3568 ? takeTemplateIdAnnotation(
Next)
3574 ConsumeAnnotationToken();
3588 if ((DSContext == DeclSpecContext::DSC_top_level ||
3589 DSContext == DeclSpecContext::DSC_class) &&
3592 isConstructorDeclarator(
false,
3599 goto DoneWithDeclSpec;
3603 ConsumeAnnotationToken();
3604 assert(Tok.is(tok::annot_template_id) &&
3605 "ParseOptionalCXXScopeSpecifier not working");
3606 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3616 ConsumeAnnotationToken();
3620 if (
Next.is(tok::annot_typename)) {
3622 ConsumeAnnotationToken();
3625 Tok.getAnnotationEndLoc(),
3626 PrevSpec, DiagID,
T, Policy);
3630 ConsumeAnnotationToken();
3634 Next.is(tok::annot_template_id) &&
3635 static_cast<TemplateIdAnnotation *
>(
Next.getAnnotationValue())
3638 ConsumeAnnotationToken();
3639 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3643 if (
Next.isNot(tok::identifier))
3644 goto DoneWithDeclSpec;
3649 if ((DSContext == DeclSpecContext::DSC_top_level ||
3650 DSContext == DeclSpecContext::DSC_class) &&
3653 isConstructorDeclarator(
false,
3657 goto DoneWithDeclSpec;
3663 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3667 false,
false,
nullptr,
3670 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3672 if (IsTemplateSpecOrInst)
3680 if (TryAnnotateTypeConstraint())
3681 goto DoneWithDeclSpec;
3682 if (Tok.isNot(tok::annot_cxxscope) ||
3686 ConsumeAnnotationToken();
3687 ParsedAttributes Attrs(AttrFactory);
3688 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3689 if (!Attrs.
empty()) {
3690 AttrsLastTime =
true;
3691 attrs.takeAllAppendingFrom(Attrs);
3695 goto DoneWithDeclSpec;
3699 ConsumeAnnotationToken();
3702 DiagID, TypeRep, Policy);
3712 case tok::annot_typename: {
3716 goto DoneWithDeclSpec;
3725 ConsumeAnnotationToken();
3730 case tok::kw___is_signed:
3742 TryKeywordIdentFallback(
true);
3745 goto DoneWithDeclSpec;
3748 case tok::kw___super:
3749 case tok::kw_decltype:
3750 case tok::identifier:
3756 goto DoneWithDeclSpec;
3762 if (!
getLangOpts().DeclSpecKeyword && Tok.is(tok::identifier) &&
3763 Tok.getIdentifierInfo()->getName() ==
"__declspec") {
3764 Diag(Loc, diag::err_ms_attributes_not_enabled);
3774 if (
T.consumeOpen()) {
3775 assert(
false &&
"Not a left paren?");
3790 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3794 if (IsTemplateSpecOrInst)
3798 if (IsTemplateSpecOrInst)
3801 goto DoneWithDeclSpec;
3804 if (!Tok.is(tok::identifier))
3809 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID,
isInvalid))
3815 goto DoneWithDeclSpec;
3817 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3818 isObjCInstancetype()) {
3819 ParsedType TypeRep = Actions.ObjC().ActOnObjCInstanceType(Loc);
3822 DiagID, TypeRep, Policy);
3834 Actions.isCurrentClassName(*Tok.getIdentifierInfo(),
getCurScope()) &&
3835 isConstructorDeclarator(
true,
3838 goto DoneWithDeclSpec;
3841 *Tok.getIdentifierInfo(), Tok.getLocation(),
getCurScope(),
nullptr,
3842 false,
false,
nullptr,
false,
false,
3843 isClassTemplateDeductionContext(DSContext));
3848 if (TryAnnotateTypeConstraint())
3849 goto DoneWithDeclSpec;
3850 if (Tok.isNot(tok::identifier))
3852 ParsedAttributes Attrs(AttrFactory);
3853 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
3854 if (!Attrs.
empty()) {
3855 AttrsLastTime =
true;
3856 attrs.takeAllAppendingFrom(Attrs);
3860 goto DoneWithDeclSpec;
3867 (DSContext == DeclSpecContext::DSC_class ||
3868 DSContext == DeclSpecContext::DSC_top_level) &&
3869 Actions.isDeductionGuideName(
getCurScope(), *Tok.getIdentifierInfo(),
3870 Tok.getLocation(), SS) &&
3871 isConstructorDeclarator(
true,
3873 goto DoneWithDeclSpec;
3876 DiagID, TypeRep, Policy);
3887 SourceLocation NewEndLoc;
3888 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3903 case tok::annot_template_id: {
3904 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
3915 TemplateId =
nullptr;
3923 tok::kw_volatile, tok::kw_restrict, tok::amp,
3925 Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
3929 TemplateId, Policy);
3933 goto DoneWithDeclSpec;
3935 if (TemplateId && !
isInvalid && Actions.CheckTypeConstraint(TemplateId))
3936 TemplateId =
nullptr;
3938 ConsumeAnnotationToken();
3939 SourceLocation AutoLoc = Tok.getLocation();
3942 if (Tracker.consumeOpen()) {
3944 Diag(Tok, diag::err_expected) << tok::l_paren;
3948 Tracker.skipToEnd();
3949 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
3954 Tracker.consumeClose();
3957 ConsumedEnd = Tok.getLocation();
3962 DiagID, TemplateId, Policy);
3965 TemplateId, Policy);
3974 goto DoneWithDeclSpec;
3982 isConstructorDeclarator(
true,
3985 goto DoneWithDeclSpec;
3990 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3995 case tok::kw___attribute:
3996 case tok::kw___declspec:
3997 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4001 case tok::kw___forceinline: {
4003 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
4004 SourceLocation AttrNameLoc = Tok.getLocation();
4006 nullptr, 0, tok::kw___forceinline);
4010 case tok::kw___unaligned:
4016 case tok::kw___ptrauth:
4020 case tok::kw___sptr:
4021 case tok::kw___uptr:
4022 case tok::kw___ptr64:
4023 case tok::kw___ptr32:
4025 case tok::kw___cdecl:
4026 case tok::kw___stdcall:
4027 case tok::kw___fastcall:
4028 case tok::kw___thiscall:
4029 case tok::kw___regcall:
4030 case tok::kw___vectorcall:
4034 case tok::kw___funcref:
4039 case tok::kw___pascal:
4044 case tok::kw___kernel:
4049 case tok::kw___noinline__:
4054 case tok::kw__Nonnull:
4055 case tok::kw__Nullable:
4056 case tok::kw__Nullable_result:
4057 case tok::kw__Null_unspecified:
4062 case tok::kw___kindof:
4064 AttributeScopeInfo(),
nullptr, 0,
4070 case tok::kw_typedef:
4072 PrevSpec, DiagID, Policy);
4073 isStorageClass =
true;
4075 case tok::kw_extern:
4077 Diag(Tok, diag::ext_thread_before) <<
"extern";
4079 PrevSpec, DiagID, Policy);
4080 isStorageClass =
true;
4082 case tok::kw___private_extern__:
4084 Loc, PrevSpec, DiagID, Policy);
4085 isStorageClass =
true;
4087 case tok::kw_static:
4089 Diag(Tok, diag::ext_thread_before) <<
"static";
4091 PrevSpec, DiagID, Policy);
4092 isStorageClass =
true;
4098 PrevSpec, DiagID, Policy);
4100 Diag(Tok, diag::ext_auto_storage_class)
4107 PrevSpec, DiagID, Policy);
4108 isStorageClass =
true;
4110 case tok::kw___auto_type:
4111 Diag(Tok, diag::ext_auto_type);
4115 case tok::kw_register:
4117 PrevSpec, DiagID, Policy);
4118 isStorageClass =
true;
4120 case tok::kw_mutable:
4122 PrevSpec, DiagID, Policy);
4123 isStorageClass =
true;
4125 case tok::kw___thread:
4128 isStorageClass =
true;
4130 case tok::kw_thread_local:
4132 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4141 Loc, PrevSpec, DiagID);
4142 isStorageClass =
true;
4144 case tok::kw__Thread_local:
4145 diagnoseUseOfC11Keyword(Tok);
4147 Loc, PrevSpec, DiagID);
4148 isStorageClass =
true;
4152 case tok::kw_inline:
4155 case tok::kw_virtual:
4159 !
getActions().getOpenCLOptions().isAvailableOption(
4161 DiagID = diag::err_openclcxx_virtual_function;
4162 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4165 DiagID = diag::err_hlsl_virtual_function;
4166 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4172 case tok::kw_explicit: {
4173 SourceLocation ExplicitLoc = Loc;
4174 SourceLocation CloseParenLoc;
4176 ConsumedEnd = ExplicitLoc;
4178 if (Tok.is(tok::l_paren)) {
4181 ? diag::warn_cxx17_compat_explicit_bool
4182 : diag::ext_explicit_bool);
4184 ExprResult ExplicitExpr(
static_cast<Expr *
>(
nullptr));
4186 Tracker.consumeOpen();
4188 EnterExpressionEvaluationContext ConstantEvaluated(
4192 ConsumedEnd = Tok.getLocation();
4193 if (ExplicitExpr.isUsable()) {
4194 CloseParenLoc = Tok.getLocation();
4195 Tracker.consumeClose();
4197 Actions.ActOnExplicitBoolSpecifier(ExplicitExpr.get());
4199 Tracker.skipToEnd();
4201 Diag(Tok.getLocation(), diag::warn_cxx20_compat_explicit_bool);
4205 ExplicitSpec, CloseParenLoc);
4208 case tok::kw__Noreturn:
4209 diagnoseUseOfC11Keyword(Tok);
4214 case tok::kw_friend:
4215 if (DSContext == DeclSpecContext::DSC_class) {
4222 DiagID = diag::err_friend_invalid_in_context;
4228 case tok::kw___module_private__:
4233 case tok::kw_constexpr:
4235 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4239 case tok::kw_consteval:
4243 case tok::kw_constinit:
4251 Diag(Tok, diag::err_unknown_typename) << Tok.getName();
4255 goto DoneWithDeclSpec;
4266 PrevSpec, DiagID, Policy);
4268 case tok::kw___int64:
4270 PrevSpec, DiagID, Policy);
4272 case tok::kw_signed:
4276 case tok::kw_unsigned:
4280 case tok::kw__Complex:
4282 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4286 case tok::kw__Imaginary:
4288 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4304 case tok::kw__ExtInt:
4305 case tok::kw__BitInt: {
4306 DiagnoseBitIntUse(Tok);
4311 ConsumedEnd = PrevTokLocation;
4314 case tok::kw___int128:
4322 case tok::kw___bf16:
4330 case tok::kw_double:
4334 case tok::kw__Float16:
4338 case tok::kw__Accum:
4340 "This keyword is only used when fixed point types are enabled "
4341 "with `-ffixed-point`");
4345 case tok::kw__Fract:
4347 "This keyword is only used when fixed point types are enabled "
4348 "with `-ffixed-point`");
4354 "This keyword is only used when fixed point types are enabled "
4355 "with `-ffixed-point`");
4358 case tok::kw___float128:
4362 case tok::kw___ibm128:
4366 case tok::kw_wchar_t:
4370 case tok::kw_char8_t:
4374 case tok::kw_char16_t:
4378 case tok::kw_char32_t:
4384 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4388 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4390 if (Tok.is(tok::kw_bool) &&
4394 DiagID = diag::err_bool_redeclaration;
4396 Tok.setKind(tok::identifier);
4403 case tok::kw__Decimal32:
4407 case tok::kw__Decimal64:
4411 case tok::kw__Decimal128:
4415 case tok::kw___vector:
4418 case tok::kw___pixel:
4421 case tok::kw___bool:
4426 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4429 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
4430 Tok.setKind(tok::identifier);
4431 goto DoneWithDeclSpec;
4433 DiagID = diag::err_opencl_unknown_type_specifier;
4434 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4440#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4441#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4442#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4443 case tok::kw_##ImgType##_t: \
4444 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4445 goto DoneWithDeclSpec; \
4447#include "clang/Basic/OpenCLImageTypes.def"
4448 case tok::kw___unknown_anytype:
4450 PrevSpec, DiagID, Policy);
4455 case tok::kw_struct:
4456 case tok::kw___interface:
4457 case tok::kw_union: {
4464 ParsedAttributes Attributes(AttrFactory);
4465 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
4466 EnteringContext, DSContext, Attributes);
4470 if (!Attributes.empty()) {
4471 AttrsLastTime =
true;
4472 attrs.takeAllAppendingFrom(Attributes);
4480 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
4488 case tok::kw_volatile:
4492 case tok::kw_restrict:
4498 case tok::kw_typename:
4501 goto DoneWithDeclSpec;
4503 if (!Tok.is(tok::kw_typename))
4508 case tok::kw_typeof:
4509 case tok::kw_typeof_unqual:
4510 ParseTypeofSpecifier(DS);
4513 case tok::annot_decltype:
4514 ParseDecltypeSpecifier(DS);
4517 case tok::annot_pack_indexing_type:
4518 ParsePackIndexingType(DS);
4521 case tok::annot_pragma_pack:
4525 case tok::annot_pragma_ms_pragma:
4526 HandlePragmaMSPragma();
4529 case tok::annot_pragma_ms_vtordisp:
4530 HandlePragmaMSVtorDisp();
4533 case tok::annot_pragma_ms_pointers_to_members:
4534 HandlePragmaMSPointersToMembers();
4537#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4538#include "clang/Basic/TransformTypeTraits.def"
4542 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4543 goto ParseIdentifier;
4546 case tok::kw__Atomic:
4551 diagnoseUseOfC11Keyword(Tok);
4553 ParseAtomicSpecifier(DS);
4561 case tok::kw___generic:
4566 if (!Actions.getLangOpts().OpenCLGenericAddressSpace) {
4567 DiagID = diag::err_opencl_unknown_type_specifier;
4568 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4573 case tok::kw_private:
4577 goto DoneWithDeclSpec;
4579 case tok::kw___private:
4580 case tok::kw___global:
4581 case tok::kw___local:
4582 case tok::kw___constant:
4584 case tok::kw___read_only:
4585 case tok::kw___write_only:
4586 case tok::kw___read_write:
4590 case tok::kw_groupshared:
4598#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
4599 case tok::kw_##Name: \
4600 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4603#include "clang/Basic/HLSLIntangibleTypes.def"
4610 goto DoneWithDeclSpec;
4612 SourceLocation StartLoc = Tok.getLocation();
4613 SourceLocation EndLoc;
4615 if (
Type.isUsable()) {
4617 PrevSpec, DiagID,
Type.get(),
4618 Actions.getASTContext().getPrintingPolicy()))
4619 Diag(StartLoc, DiagID) << PrevSpec;
4635 assert(PrevSpec &&
"Method did not return previous specifier!");
4638 if (DiagID == diag::ext_duplicate_declspec ||
4639 DiagID == diag::ext_warn_duplicate_declspec ||
4640 DiagID == diag::err_duplicate_declspec)
4641 Diag(Loc, DiagID) << PrevSpec
4644 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4648 Diag(Loc, DiagID) << PrevSpec;
4651 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4655 AttrsLastTime =
false;
4667 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4670 for (
auto *I : RD->decls()) {
4671 auto *VD = dyn_cast<ValueDecl>(I);
4679 for (
const auto &DD : CAT->dependent_decls()) {
4680 if (!RD->containsDecl(DD.getDecl())) {
4681 P.
Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4682 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4683 P.
Diag(DD.getDecl()->getBeginLoc(),
4684 diag::note_flexible_array_counted_by_attr_field)
4691void Parser::ParseStructDeclaration(
4694 LateParsedAttrList *LateFieldAttrs) {
4696 if (Tok.is(tok::kw___extension__)) {
4698 ExtensionRAIIObject O(Diags);
4700 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4704 ParsedAttributes Attrs(AttrFactory);
4705 MaybeParseCXX11Attributes(Attrs);
4708 ParseSpecifierQualifierList(DS);
4712 if (Tok.is(tok::semi)) {
4717 ProhibitAttributes(Attrs);
4718 RecordDecl *AnonRecord =
nullptr;
4719 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
4721 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4727 bool FirstDeclarator =
true;
4728 SourceLocation CommaLoc;
4730 ParsingFieldDeclarator DeclaratorInfo(*
this, DS, Attrs);
4731 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4734 if (!FirstDeclarator) {
4737 DiagnoseAndSkipCXX11Attributes();
4738 MaybeParseGNUAttributes(DeclaratorInfo.D);
4739 DiagnoseAndSkipCXX11Attributes();
4744 if (Tok.isNot(tok::colon)) {
4747 ParseDeclarator(DeclaratorInfo.D);
4749 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.getLocation());
4761 DeclaratorInfo.BitfieldSize = Res.
get();
4765 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
4768 Decl *
Field = FieldsCallback(DeclaratorInfo);
4770 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
4777 FirstDeclarator =
false;
4783void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs,
bool EnterScope,
4785 assert(LAs.parseSoon() &&
4786 "Attribute list should be marked for immediate parsing.");
4787 for (
auto *LA : LAs) {
4788 ParseLexedCAttribute(*LA,
EnterScope, OutAttrs);
4794void Parser::ParseLexedCAttribute(LateParsedAttribute &LA,
bool EnterScope,
4799 AttrEnd.startToken();
4800 AttrEnd.setKind(tok::eof);
4801 AttrEnd.setLocation(Tok.getLocation());
4802 AttrEnd.setEofData(LA.Toks.data());
4803 LA.Toks.push_back(AttrEnd);
4807 LA.Toks.push_back(Tok);
4808 PP.EnterTokenStream(LA.Toks,
true,
4817 ParsedAttributes Attrs(AttrFactory);
4819 assert(LA.Decls.size() <= 1 &&
4820 "late field attribute expects to have at most one declaration.");
4823 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
nullptr,
nullptr,
4824 SourceLocation(), ParsedAttr::Form::GNU(),
nullptr);
4826 for (
auto *D : LA.Decls)
4827 Actions.ActOnFinishDelayedAttribute(
getCurScope(), D, Attrs);
4831 while (Tok.isNot(tok::eof))
4835 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
4845 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl,
RecordLoc,
4846 "parsing struct/union body");
4850 if (
T.consumeOpen())
4854 Actions.ActOnTagStartDefinition(
getCurScope(), TagDecl);
4858 LateParsedAttrList LateFieldAttrs(
true,
4862 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
4863 Tok.isNot(tok::eof)) {
4867 if (Tok.is(tok::semi)) {
4873 if (Tok.isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4874 SourceLocation DeclEnd;
4875 ParseStaticAssertDeclaration(DeclEnd);
4879 if (Tok.is(tok::annot_pragma_pack)) {
4884 if (Tok.is(tok::annot_pragma_align)) {
4885 HandlePragmaAlign();
4889 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4892 ParsedAttributes Attrs(AttrFactory);
4893 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4897 if (Tok.is(tok::annot_pragma_openacc)) {
4899 ParsedAttributes Attrs(AttrFactory);
4905 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
4907 TagType, Actions.getASTContext().getPrintingPolicy());
4908 ConsumeAnnotationToken();
4912 if (!Tok.is(tok::at)) {
4913 auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
4917 FD.D.getDeclSpec().getSourceRange().getBegin(),
4918 FD.D, FD.BitfieldSize);
4924 ParsingDeclSpec DS(*
this);
4925 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
4928 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
4929 Diag(Tok, diag::err_unexpected_at);
4934 ExpectAndConsume(tok::l_paren);
4935 if (!Tok.is(tok::identifier)) {
4936 Diag(Tok, diag::err_expected) << tok::identifier;
4940 SmallVector<Decl *, 16> Fields;
4941 Actions.ObjC().ActOnDefs(
getCurScope(), TagDecl, Tok.getLocation(),
4942 Tok.getIdentifierInfo(), Fields);
4944 ExpectAndConsume(tok::r_paren);
4950 if (Tok.is(tok::r_brace)) {
4951 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
4955 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
4964 ParsedAttributes attrs(AttrFactory);
4966 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
4969 ParseLexedCAttributeList(LateFieldAttrs,
false);
4971 SmallVector<Decl *, 32> FieldDecls(TagDecl->
fields());
4974 T.getOpenLocation(),
T.getCloseLocation(), attrs);
4976 Actions.ActOnTagFinishDefinition(
getCurScope(), TagDecl,
T.getRange());
4980 const ParsedTemplateInfo &TemplateInfo,
4983 if (Tok.is(tok::code_completion)) {
4992 ParsedAttributes attrs(AttrFactory);
4993 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
4995 SourceLocation ScopedEnumKWLoc;
4996 bool IsScopedUsingClassTag =
false;
5001 : diag::ext_scoped_enum);
5002 IsScopedUsingClassTag = Tok.is(tok::kw_class);
5007 ProhibitAttributes(attrs);
5010 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5019 bool shouldDelayDiagsInTag =
5022 SuppressAccessChecks diagsFromTag(*
this, shouldDelayDiagsInTag);
5025 AllowDefiningTypeSpec AllowEnumSpecifier =
5027 bool CanBeOpaqueEnumDeclaration =
5028 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5031 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5032 CanBeOpaqueEnumDeclaration);
5040 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5045 if (Spec.
isSet() && Tok.isNot(tok::identifier)) {
5046 Diag(Tok, diag::err_expected) << tok::identifier;
5048 if (Tok.isNot(tok::l_brace)) {
5060 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
5061 Tok.isNot(tok::colon)) {
5062 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5071 IdentifierInfo *Name =
nullptr;
5072 SourceLocation NameLoc;
5073 if (Tok.is(tok::identifier)) {
5074 Name = Tok.getIdentifierInfo();
5078 if (!Name && ScopedEnumKWLoc.
isValid()) {
5081 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5082 ScopedEnumKWLoc = SourceLocation();
5083 IsScopedUsingClassTag =
false;
5088 if (shouldDelayDiagsInTag)
5089 diagsFromTag.done();
5092 SourceRange BaseRange;
5094 bool CanBeBitfield =
5098 if (Tok.is(tok::colon)) {
5123 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5127 Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
5128 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5135 DeclSpec DS(AttrFactory);
5139 DeclSpecContext::DSC_type_specifier);
5142 BaseType = Actions.ActOnTypeName(DeclaratorInfo);
5144 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5148 DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)
5151 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5155 ? diag::warn_c17_compat_enum_fixed_underlying_type
5156 : diag::ext_c23_enum_fixed_underlying_type)
5173 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5175 else if (Tok.is(tok::l_brace)) {
5177 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
5183 ScopedEnumKWLoc = SourceLocation();
5184 IsScopedUsingClassTag =
false;
5190 }
else if (!isTypeSpecifier(DSC) &&
5191 (Tok.is(tok::semi) ||
5192 (Tok.isAtStartOfLine() &&
5193 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5198 if (Tok.isNot(tok::semi)) {
5200 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5201 PP.EnterToken(Tok,
true);
5202 Tok.setKind(tok::semi);
5208 bool IsElaboratedTypeSpecifier =
5214 diagsFromTag.redelay();
5222 Diag(Tok, diag::err_enum_template);
5230 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5234 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5236 TemplateInfo.TemplateParams->size());
5241 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5257 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5259 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5260 diag::err_keyword_not_allowed,
5263 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5264 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5265 else if (ScopedEnumKWLoc.
isValid())
5266 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5270 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5272 SkipBodyInfo SkipBody;
5275 SkipBody = Actions.shouldSkipAnonEnumBody(
getCurScope(),
5280 bool IsDependent =
false;
5281 const char *PrevSpec =
nullptr;
5286 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5287 IsScopedUsingClassTag,
5288 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5289 DSC == DeclSpecContext::DSC_template_param ||
5290 DSC == DeclSpecContext::DSC_template_type_arg,
5291 OffsetOfState, &SkipBody).get();
5301 NameLoc.
isValid() ? NameLoc : StartLoc,
5302 PrevSpec, DiagID, TagDecl, Owned,
5303 Actions.getASTContext().getPrintingPolicy()))
5304 Diag(StartLoc, DiagID) << PrevSpec;
5313 Diag(Tok, diag::err_expected_type_name_after_typename);
5319 if (
Type.isInvalid()) {
5325 NameLoc.
isValid() ? NameLoc : StartLoc,
5326 PrevSpec, DiagID,
Type.get(),
5327 Actions.getASTContext().getPrintingPolicy()))
5328 Diag(StartLoc, DiagID) << PrevSpec;
5347 ParseEnumBody(StartLoc, D, &SkipBody);
5349 !Actions.ActOnDuplicateDefinition(
getCurScope(), TagDecl, SkipBody)) {
5356 NameLoc.
isValid() ? NameLoc : StartLoc,
5357 PrevSpec, DiagID, TagDecl, Owned,
5358 Actions.getASTContext().getPrintingPolicy()))
5359 Diag(StartLoc, DiagID) << PrevSpec;
5366 Actions.ActOnTagStartDefinition(
getCurScope(), EnumDecl);
5374 Diag(
T.getOpenLocation(), diag::ext_ms_c_empty_enum_type)
5375 << SourceRange(
T.getOpenLocation(), Tok.getLocation());
5377 Diag(Tok, diag::err_empty_enum);
5380 SmallVector<Decl *, 32> EnumConstantDecls;
5381 SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
5383 Decl *LastEnumConstDecl =
nullptr;
5386 while (Tok.isNot(tok::r_brace)) {
5389 if (Tok.isNot(tok::identifier)) {
5390 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
5396 IdentifierInfo *Ident = Tok.getIdentifierInfo();
5400 ParsedAttributes attrs(AttrFactory);
5401 MaybeParseGNUAttributes(attrs);
5402 if (isAllowedCXX11AttributeSpecifier()) {
5405 ? diag::warn_cxx14_compat_ns_enum_attribute
5406 : diag::ext_ns_enum_attribute)
5408 ParseCXX11Attributes(attrs);
5411 SourceLocation EqualLoc;
5413 EnumAvailabilityDiags.emplace_back(*
this);
5415 EnterExpressionEvaluationContext ConstantEvaluated(
5424 Decl *EnumConstDecl = Actions.ActOnEnumConstant(
5425 getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
5426 EqualLoc, AssignedVal.
get(), SkipBody);
5427 EnumAvailabilityDiags.back().done();
5429 EnumConstantDecls.push_back(EnumConstDecl);
5430 LastEnumConstDecl = EnumConstDecl;
5432 if (Tok.is(tok::identifier)) {
5435 Diag(Loc, diag::err_enumerator_list_missing_comma)
5442 SourceLocation CommaLoc;
5443 if (Tok.isNot(tok::r_brace) && !
TryConsumeToken(tok::comma, CommaLoc)) {
5445 Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
5448 Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
5458 if (Tok.is(tok::r_brace) && CommaLoc.
isValid()) {
5461 diag::ext_enumerator_list_comma_cxx :
5462 diag::ext_enumerator_list_comma_c)
5465 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5475 ParsedAttributes attrs(AttrFactory);
5476 MaybeParseGNUAttributes(attrs);
5478 Actions.ActOnEnumBody(StartLoc,
T.getRange(), EnumDecl, EnumConstantDecls,
5482 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5483 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5485 EnumAvailabilityDiags[i].redelay();
5486 PD.complete(EnumConstantDecls[i]);
5490 Actions.ActOnTagFinishDefinition(
getCurScope(), EnumDecl,
T.getRange());
5495 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5496 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5500 PP.EnterToken(Tok,
true);
5501 Tok.setKind(tok::semi);
5505bool Parser::isKnownToBeTypeSpecifier(
const Token &
Tok)
const {
5506 switch (Tok.getKind()) {
5507 default:
return false;
5511 case tok::kw___int64:
5512 case tok::kw___int128:
5513 case tok::kw_signed:
5514 case tok::kw_unsigned:
5515 case tok::kw__Complex:
5516 case tok::kw__Imaginary:
5519 case tok::kw_wchar_t:
5520 case tok::kw_char8_t:
5521 case tok::kw_char16_t:
5522 case tok::kw_char32_t:
5524 case tok::kw__ExtInt:
5525 case tok::kw__BitInt:
5526 case tok::kw___bf16:
5529 case tok::kw_double:
5530 case tok::kw__Accum:
5531 case tok::kw__Fract:
5532 case tok::kw__Float16:
5533 case tok::kw___float128:
5534 case tok::kw___ibm128:
5537 case tok::kw__Decimal32:
5538 case tok::kw__Decimal64:
5539 case tok::kw__Decimal128:
5540 case tok::kw___vector:
5541#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5542#include "clang/Basic/OpenCLImageTypes.def"
5543#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5544#include "clang/Basic/HLSLIntangibleTypes.def"
5548 case tok::kw_struct:
5549 case tok::kw___interface:
5555 case tok::annot_typename:
5560bool Parser::isTypeSpecifierQualifier() {
5561 switch (Tok.getKind()) {
5562 default:
return false;
5564 case tok::identifier:
5565 if (TryAltiVecVectorToken())
5568 case tok::kw_typename:
5573 if (Tok.is(tok::identifier))
5575 return isTypeSpecifierQualifier();
5577 case tok::coloncolon:
5584 return isTypeSpecifierQualifier();
5587 case tok::kw___attribute:
5589 case tok::kw_typeof:
5590 case tok::kw_typeof_unqual:
5595 case tok::kw___int64:
5596 case tok::kw___int128:
5597 case tok::kw_signed:
5598 case tok::kw_unsigned:
5599 case tok::kw__Complex:
5600 case tok::kw__Imaginary:
5603 case tok::kw_wchar_t:
5604 case tok::kw_char8_t:
5605 case tok::kw_char16_t:
5606 case tok::kw_char32_t:
5608 case tok::kw__ExtInt:
5609 case tok::kw__BitInt:
5611 case tok::kw___bf16:
5613 case tok::kw_double:
5614 case tok::kw__Accum:
5615 case tok::kw__Fract:
5616 case tok::kw__Float16:
5617 case tok::kw___float128:
5618 case tok::kw___ibm128:
5621 case tok::kw__Decimal32:
5622 case tok::kw__Decimal64:
5623 case tok::kw__Decimal128:
5624 case tok::kw___vector:
5625#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5626#include "clang/Basic/OpenCLImageTypes.def"
5627#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5628#include "clang/Basic/HLSLIntangibleTypes.def"
5632 case tok::kw_struct:
5633 case tok::kw___interface:
5640 case tok::kw_volatile:
5641 case tok::kw_restrict:
5645 case tok::kw___unknown_anytype:
5648 case tok::annot_typename:
5655 case tok::kw___cdecl:
5656 case tok::kw___stdcall:
5657 case tok::kw___fastcall:
5658 case tok::kw___thiscall:
5659 case tok::kw___regcall:
5660 case tok::kw___vectorcall:
5662 case tok::kw___ptr64:
5663 case tok::kw___ptr32:
5664 case tok::kw___pascal:
5665 case tok::kw___unaligned:
5666 case tok::kw___ptrauth:
5668 case tok::kw__Nonnull:
5669 case tok::kw__Nullable:
5670 case tok::kw__Nullable_result:
5671 case tok::kw__Null_unspecified:
5673 case tok::kw___kindof:
5675 case tok::kw___private:
5676 case tok::kw___local:
5677 case tok::kw___global:
5678 case tok::kw___constant:
5679 case tok::kw___generic:
5680 case tok::kw___read_only:
5681 case tok::kw___read_write:
5682 case tok::kw___write_only:
5683 case tok::kw___funcref:
5686 case tok::kw_private:
5690 case tok::kw__Atomic:
5694 case tok::kw_groupshared:
5703 assert(PP.isIncrementalProcessingEnabled() &&
"Not in incremental mode");
5707 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5710 TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5711 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5712 Actions.ActOnFinishTopLevelStmtDecl(TLSD, R.get());
5714 R = Actions.ActOnNullStmt(Tok.getLocation());
5716 if (Tok.is(tok::annot_repl_input_end) &&
5717 Tok.getAnnotationValue() !=
nullptr) {
5718 ConsumeAnnotationToken();
5722 SmallVector<Decl *, 2> DeclsInGroup;
5723 DeclsInGroup.push_back(TLSD);
5726 for (Stmt *S : Stmts) {
5729 TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5730 Actions.ActOnFinishTopLevelStmtDecl(D, S);
5731 DeclsInGroup.push_back(D);
5734 return Actions.BuildDeclaratorGroup(DeclsInGroup);
5737bool Parser::isDeclarationSpecifier(
5739 bool DisambiguatingWithExpression) {
5740 switch (Tok.getKind()) {
5741 default:
return false;
5748 case tok::identifier:
5752 if (TryAltiVecVectorToken())
5755 case tok::kw_decltype:
5756 case tok::kw_typename:
5761 if (TryAnnotateTypeConstraint())
5763 if (Tok.is(tok::identifier))
5771 if (DisambiguatingWithExpression &&
5772 isStartOfObjCClassMessageMissingOpenBracket())
5775 return isDeclarationSpecifier(AllowImplicitTypename);
5777 case tok::coloncolon:
5791 case tok::kw_typedef:
5792 case tok::kw_extern:
5793 case tok::kw___private_extern__:
5794 case tok::kw_static:
5796 case tok::kw___auto_type:
5797 case tok::kw_register:
5798 case tok::kw___thread:
5799 case tok::kw_thread_local:
5800 case tok::kw__Thread_local:
5803 case tok::kw___module_private__:
5806 case tok::kw___unknown_anytype:
5811 case tok::kw___int64:
5812 case tok::kw___int128:
5813 case tok::kw_signed:
5814 case tok::kw_unsigned:
5815 case tok::kw__Complex:
5816 case tok::kw__Imaginary:
5819 case tok::kw_wchar_t:
5820 case tok::kw_char8_t:
5821 case tok::kw_char16_t:
5822 case tok::kw_char32_t:
5825 case tok::kw__ExtInt:
5826 case tok::kw__BitInt:
5828 case tok::kw___bf16:
5830 case tok::kw_double:
5831 case tok::kw__Accum:
5832 case tok::kw__Fract:
5833 case tok::kw__Float16:
5834 case tok::kw___float128:
5835 case tok::kw___ibm128:
5838 case tok::kw__Decimal32:
5839 case tok::kw__Decimal64:
5840 case tok::kw__Decimal128:
5841 case tok::kw___vector:
5845 case tok::kw_struct:
5847 case tok::kw___interface:
5853 case tok::kw_volatile:
5854 case tok::kw_restrict:
5858 case tok::kw_inline:
5859 case tok::kw_virtual:
5860 case tok::kw_explicit:
5861 case tok::kw__Noreturn:
5864 case tok::kw__Alignas:
5867 case tok::kw_friend:
5870 case tok::kw_static_assert:
5871 case tok::kw__Static_assert:
5874 case tok::kw_typeof:
5875 case tok::kw_typeof_unqual:
5878 case tok::kw___attribute:
5881 case tok::annot_decltype:
5882 case tok::annot_pack_indexing_type:
5883 case tok::kw_constexpr:
5886 case tok::kw_consteval:
5887 case tok::kw_constinit:
5890 case tok::kw__Atomic:
5893 case tok::kw_alignas:
5903 case tok::annot_typename:
5904 return !DisambiguatingWithExpression ||
5905 !isStartOfObjCClassMessageMissingOpenBracket();
5908 case tok::annot_template_id: {
5909 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
5914 return isTypeConstraintAnnotation() &&
5918 case tok::annot_cxxscope: {
5919 TemplateIdAnnotation *TemplateId =
5927 if (
NextToken().
is(tok::identifier) && TryAnnotateTypeConstraint())
5929 return isTypeConstraintAnnotation() &&
5933 case tok::kw___declspec:
5934 case tok::kw___cdecl:
5935 case tok::kw___stdcall:
5936 case tok::kw___fastcall:
5937 case tok::kw___thiscall:
5938 case tok::kw___regcall:
5939 case tok::kw___vectorcall:
5941 case tok::kw___sptr:
5942 case tok::kw___uptr:
5943 case tok::kw___ptr64:
5944 case tok::kw___ptr32:
5945 case tok::kw___forceinline:
5946 case tok::kw___pascal:
5947 case tok::kw___unaligned:
5948 case tok::kw___ptrauth:
5950 case tok::kw__Nonnull:
5951 case tok::kw__Nullable:
5952 case tok::kw__Nullable_result:
5953 case tok::kw__Null_unspecified:
5955 case tok::kw___kindof:
5957 case tok::kw___private:
5958 case tok::kw___local:
5959 case tok::kw___global:
5960 case tok::kw___constant:
5961 case tok::kw___generic:
5962 case tok::kw___read_only:
5963 case tok::kw___read_write:
5964 case tok::kw___write_only:
5965#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5966#include "clang/Basic/OpenCLImageTypes.def"
5967#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5968#include "clang/Basic/HLSLIntangibleTypes.def"
5970 case tok::kw___funcref:
5971 case tok::kw_groupshared:
5974 case tok::kw_private:
5979bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
5981 const ParsedTemplateInfo *TemplateInfo) {
5982 RevertingTentativeParsingAction TPA(*
this);
5985 if (TemplateInfo && TemplateInfo->TemplateParams)
5988 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
5995 if (Tok.is(tok::identifier)) {
5999 }
else if (Tok.is(tok::annot_template_id)) {
6000 ConsumeAnnotationToken();
6007 SkipCXX11Attributes();
6010 if (Tok.isNot(tok::l_paren)) {
6017 if (Tok.is(tok::r_paren) ||
6018 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren))) {
6024 if (isCXX11AttributeSpecifier(
false,
6031 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6033 DeclScopeObj.EnterDeclaratorScope();
6036 ParsedAttributes Attrs(AttrFactory);
6037 MaybeParseMicrosoftAttributes(Attrs);
6046 bool IsConstructor =
false;
6052 if (Tok.is(tok::kw_this)) {
6054 return isDeclarationSpecifier(ITC);
6057 if (isDeclarationSpecifier(ITC))
6058 IsConstructor =
true;
6059 else if (Tok.is(tok::identifier) ||
6060 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier))) {
6065 if (Tok.is(tok::annot_cxxscope))
6066 ConsumeAnnotationToken();
6072 switch (Tok.getKind()) {
6078 case tok::coloncolon:
6091 SkipCXX11Attributes();
6093 if (DeductionGuide) {
6095 IsConstructor = Tok.is(tok::arrow);
6098 if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
6102 IsConstructor =
true;
6104 if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {
6117 IsConstructor = IsUnqualified;
6122 IsConstructor =
true;
6126 return IsConstructor;
6129void Parser::ParseTypeQualifierListOpt(
6130 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicOrPtrauthAllowed,
6132 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6133 isAllowedCXX11AttributeSpecifier()) {
6134 ParsedAttributes Attrs(AttrFactory);
6135 ParseCXX11Attributes(Attrs);
6139 SourceLocation EndLoc;
6143 const char *PrevSpec =
nullptr;
6144 unsigned DiagID = 0;
6145 SourceLocation Loc = Tok.getLocation();
6147 switch (Tok.getKind()) {
6148 case tok::code_completion:
6150 if (CodeCompletionHandler)
6151 CodeCompletionHandler();
6153 Actions.CodeCompletion().CodeCompleteTypeQualifiers(DS);
6160 case tok::kw_volatile:
6164 case tok::kw_restrict:
6168 case tok::kw__Atomic:
6169 if (!AtomicOrPtrauthAllowed)
6170 goto DoneWithTypeQuals;
6171 diagnoseUseOfC11Keyword(Tok);
6177 case tok::kw_private:
6179 goto DoneWithTypeQuals;
6181 case tok::kw___private:
6182 case tok::kw___global:
6183 case tok::kw___local:
6184 case tok::kw___constant:
6185 case tok::kw___generic:
6186 case tok::kw___read_only:
6187 case tok::kw___write_only:
6188 case tok::kw___read_write:
6192 case tok::kw_groupshared:
6201 case tok::kw___ptrauth:
6202 if (!AtomicOrPtrauthAllowed)
6203 goto DoneWithTypeQuals;
6205 EndLoc = PrevTokLocation;
6208 case tok::kw___unaligned:
6212 case tok::kw___uptr:
6217 if (TryKeywordIdentFallback(
false))
6221 case tok::kw___sptr:
6223 case tok::kw___ptr64:
6224 case tok::kw___ptr32:
6225 case tok::kw___cdecl:
6226 case tok::kw___stdcall:
6227 case tok::kw___fastcall:
6228 case tok::kw___thiscall:
6229 case tok::kw___regcall:
6230 case tok::kw___vectorcall:
6231 if (AttrReqs & AR_DeclspecAttributesParsed) {
6235 goto DoneWithTypeQuals;
6237 case tok::kw___funcref:
6241 case tok::kw___pascal:
6242 if (AttrReqs & AR_VendorAttributesParsed) {
6246 goto DoneWithTypeQuals;
6249 case tok::kw__Nonnull:
6250 case tok::kw__Nullable:
6251 case tok::kw__Nullable_result:
6252 case tok::kw__Null_unspecified:
6257 case tok::kw___kindof:
6259 AttributeScopeInfo(),
nullptr, 0,
6264 case tok::kw___attribute:
6265 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6267 Diag(Tok, diag::err_attributes_not_allowed);
6271 if (AttrReqs & AR_GNUAttributesParsed ||
6272 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6282 DS.
Finish(Actions, Actions.getASTContext().getPrintingPolicy());
6290 assert(PrevSpec &&
"Method did not return previous specifier!");
6291 Diag(Tok, DiagID) << PrevSpec;
6300 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6301 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6307 if (Kind == tok::star || Kind == tok::caret)
6311 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6312 Lang.getOpenCLCompatibleVersion() >= 200)
6315 if (!Lang.CPlusPlus)
6318 if (Kind == tok::amp)
6326 if (Kind == tok::ampamp)
6337 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6344void Parser::ParseDeclaratorInternal(
Declarator &D,
6345 DirectDeclParseFunction DirectDeclParser) {
6346 if (Diags.hasAllExtensionsSilenced())
6353 (Tok.is(tok::coloncolon) || Tok.is(tok::kw_decltype) ||
6354 (Tok.is(tok::identifier) &&
6356 Tok.is(tok::annot_cxxscope))) {
6357 TentativeParsingAction TPA(*
this,
true);
6363 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6373 Tok.is(tok::star)) {
6377 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6378 CompoundToken::MemberPtr);
6383 DeclSpec DS(AttrFactory);
6384 ParseTypeQualifierListOpt(DS);
6388 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6389 ParseDeclaratorInternal(D, DirectDeclParser);
6403 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6413 AnnotateScopeToken(SS,
true);
6415 if (DirectDeclParser)
6416 (this->*DirectDeclParser)(D);
6424 DeclSpec DS(AttrFactory);
6425 ParseTypeQualifierListOpt(DS);
6434 if (DirectDeclParser)
6435 (this->*DirectDeclParser)(D);
6444 if (Kind == tok::star || Kind == tok::caret) {
6446 DeclSpec DS(AttrFactory);
6450 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6452 ? AR_GNUAttributesParsed
6453 : AR_GNUAttributesParsedAndRejected);
6454 ParseTypeQualifierListOpt(DS, Reqs,
true,
6459 Actions.runWithSufficientStackSpace(
6460 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6461 if (Kind == tok::star)
6475 DeclSpec DS(AttrFactory);
6479 if (Kind == tok::ampamp)
6481 diag::warn_cxx98_compat_rvalue_reference :
6482 diag::ext_rvalue_reference);
6485 ParseTypeQualifierListOpt(DS);
6494 diag::err_invalid_reference_qualifier_application) <<
"const";
6497 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6501 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6505 Actions.runWithSufficientStackSpace(
6506 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6513 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6516 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6545void Parser::ParseDirectDeclarator(
Declarator &D) {
6552 return ParseDecompositionDeclarator(D);
6566 ParseOptionalCXXScopeSpecifier(
6568 false, EnteringContext);
6583 if (Actions.ShouldEnterDeclaratorScope(
getCurScope(),
6587 DeclScopeObj.EnterDeclaratorScope();
6594 goto PastIdentifier;
6610 !Actions.containsUnexpandedParameterPacks(D) &&
6618 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6628 if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6632 bool AllowConstructorName;
6633 bool AllowDeductionGuide;
6635 AllowConstructorName =
false;
6636 AllowDeductionGuide =
false;
6640 AllowDeductionGuide =
false;
6648 SourceLocation TemplateKWLoc;
6653 true, AllowConstructorName,
6654 AllowDeductionGuide, &TemplateKWLoc,
6667 DeclScopeObj.EnterDeclaratorScope();
6674 goto PastIdentifier;
6680 diag::err_expected_unqualified_id)
6683 goto PastIdentifier;
6687 "There's a C++-specific check for tok::identifier above");
6688 assert(Tok.getIdentifierInfo() &&
"Not an identifier?");
6689 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6692 goto PastIdentifier;
6697 bool DiagnoseIdentifier =
false;
6701 DiagnoseIdentifier =
true;
6704 DiagnoseIdentifier =
6712 !isCXX11VirtSpecifier(Tok))
6714 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6715 if (DiagnoseIdentifier) {
6716 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
6720 goto PastIdentifier;
6724 if (Tok.is(tok::l_paren)) {
6729 RevertingTentativeParsingAction PA(*
this);
6734 goto PastIdentifier;
6741 ParseParenDeclarator(D);
6754 DeclScopeObj.EnterDeclaratorScope();
6765 diag::ext_abstract_pack_declarator_parens);
6767 if (Tok.getKind() == tok::annot_pragma_parser_crash)
6769 if (Tok.is(tok::l_square))
6770 return ParseMisplacedBracketDeclarator(D);
6775 !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
6776 Tok.getIdentifierInfo()->isCPlusPlusKeyword(
getLangOpts())) {
6778 diag::err_expected_member_name_or_semi_objcxx_keyword)
6779 << Tok.getIdentifierInfo()
6782 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6785 goto PastIdentifier;
6788 diag::err_expected_member_name_or_semi)
6792 if (Tok.getKind() == tok::TokenKind::kw_while) {
6793 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6795 if (Tok.isOneOf(tok::period, tok::arrow))
6796 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
6799 if (Tok.isAtStartOfLine() && Loc.
isValid())
6800 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
6804 diag::err_expected_unqualified_id)
6809 diag::err_expected_either)
6810 << tok::identifier << tok::l_paren;
6819 "Haven't past the location of the identifier yet?");
6823 MaybeParseCXX11Attributes(D);
6826 if (Tok.is(tok::l_paren)) {
6838 bool IsAmbiguous =
false;
6850 AllowImplicitTypename =
6858 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
6859 bool IsFunctionDecl =
6860 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
6861 TentativelyDeclaredIdentifiers.pop_back();
6862 if (!IsFunctionDecl)
6865 ParsedAttributes attrs(AttrFactory);
6868 if (IsFunctionDeclaration)
6869 Actions.ActOnStartFunctionDeclarationDeclarator(D,
6870 TemplateParameterDepth);
6871 ParseFunctionDeclarator(D, attrs,
T, IsAmbiguous);
6872 if (IsFunctionDeclaration)
6873 Actions.ActOnFinishFunctionDeclarationDeclarator(D);
6874 PrototypeScope.Exit();
6875 }
else if (Tok.is(tok::l_square)) {
6876 ParseBracketDeclarator(D);
6877 }
else if (Tok.isRegularKeywordAttribute()) {
6879 Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();
6884 if (!
T.consumeOpen())
6895 Diag(Tok, diag::err_requires_clause_inside_parens);
6909void Parser::ParseDecompositionDeclarator(
Declarator &D) {
6910 assert(Tok.is(tok::l_square));
6912 TentativeParsingAction PA(*
this);
6917 DiagnoseAndSkipCXX11Attributes();
6921 if (!(Tok.isOneOf(tok::identifier, tok::ellipsis) &&
6923 tok::identifier, tok::l_square, tok::ellipsis)) &&
6924 !(Tok.is(tok::r_square) &&
6927 return ParseMisplacedBracketDeclarator(D);
6930 SourceLocation PrevEllipsisLoc;
6931 SmallVector<DecompositionDeclarator::Binding, 32>
Bindings;
6932 while (Tok.isNot(tok::r_square)) {
6934 if (Tok.is(tok::comma))
6937 if (Tok.is(tok::identifier)) {
6939 Diag(EndLoc, diag::err_expected)
6942 Diag(Tok, diag::err_expected_comma_or_rsquare);
6945 SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis},
6947 if (Tok.is(tok::comma))
6949 else if (Tok.is(tok::r_square))
6954 if (isCXX11AttributeSpecifier() !=
6956 DiagnoseAndSkipCXX11Attributes();
6958 SourceLocation EllipsisLoc;
6960 if (Tok.is(tok::ellipsis)) {
6962 : diag::ext_cxx_binding_pack);
6963 if (PrevEllipsisLoc.
isValid()) {
6964 Diag(Tok, diag::err_binding_multiple_ellipses);
6965 Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
6968 EllipsisLoc = Tok.getLocation();
6969 PrevEllipsisLoc = EllipsisLoc;
6973 if (Tok.isNot(tok::identifier)) {
6974 Diag(Tok, diag::err_expected) << tok::identifier;
6978 IdentifierInfo *II = Tok.getIdentifierInfo();
6979 SourceLocation Loc = Tok.getLocation();
6982 if (Tok.is(tok::ellipsis) && !PrevEllipsisLoc.
isValid()) {
6983 DiagnoseMisplacedEllipsis(Tok.getLocation(), Loc, EllipsisLoc.
isValid(),
6985 EllipsisLoc = Tok.getLocation();
6989 ParsedAttributes Attrs(AttrFactory);
6990 if (isCXX11AttributeSpecifier() !=
6993 ? diag::warn_cxx23_compat_decl_attrs_on_binding
6994 : diag::ext_decl_attrs_on_binding);
6995 MaybeParseCXX11Attributes(Attrs);
6998 Bindings.push_back({II, Loc, std::move(Attrs), EllipsisLoc});
7001 if (Tok.isNot(tok::r_square))
7008 Diag(Tok.getLocation(), diag::ext_decomp_decl_empty);
7016 T.getCloseLocation());
7019void Parser::ParseParenDeclarator(
Declarator &D) {
7023 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7035 ParsedAttributes attrs(AttrFactory);
7036 bool RequiresArg =
false;
7037 if (Tok.is(tok::kw___attribute)) {
7038 ParseGNUAttributes(attrs);
7046 ParseMicrosoftTypeAttributes(attrs);
7049 if (Tok.is(tok::kw___pascal))
7050 ParseBorlandTypeAttributes(attrs);
7062 }
else if (Tok.is(tok::r_paren) ||
7064 Tok.is(tok::ellipsis) &&
7066 isDeclarationSpecifier(
7068 isCXX11AttributeSpecifier() !=
7088 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7093 std::move(attrs),
T.getCloseLocation());
7099 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7117 ParseFunctionDeclarator(D, attrs,
T,
false, RequiresArg);
7118 PrototypeScope.Exit();
7121void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7123 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7131 bool IsCXX11MemberFunction =
7138 Actions.CurContext->isRecord());
7139 if (!IsCXX11MemberFunction)
7159 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,
7160 IsCXX11MemberFunction);
7163void Parser::ParseFunctionDeclarator(
Declarator &D,
7168 assert(
getCurScope()->isFunctionPrototypeScope() &&
7169 "Should call from a Function scope");
7175 bool HasProto =
false;
7177 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
7179 SourceLocation EllipsisLoc;
7181 DeclSpec DS(AttrFactory);
7182 bool RefQualifierIsLValueRef =
true;
7183 SourceLocation RefQualifierLoc;
7185 SourceRange ESpecRange;
7186 SmallVector<ParsedType, 2> DynamicExceptions;
7187 SmallVector<SourceRange, 2> DynamicExceptionRanges;
7190 ParsedAttributes FnAttrs(AttrFactory);
7192 SourceLocation TrailingReturnTypeLoc;
7197 SourceLocation StartLoc, LocalEndLoc, EndLoc;
7198 SourceLocation LParenLoc, RParenLoc;
7200 StartLoc = LParenLoc;
7202 if (isFunctionDeclaratorIdentifierList()) {
7204 Diag(Tok, diag::err_argument_required_after_attribute);
7206 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7210 LocalEndLoc = RParenLoc;
7215 MaybeParseCXX11Attributes(FnAttrs);
7216 ProhibitAttributes(FnAttrs);
7218 if (Tok.isNot(tok::r_paren))
7219 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7220 else if (RequiresArg)
7221 Diag(Tok, diag::err_argument_required_after_attribute);
7232 LocalEndLoc = RParenLoc;
7241 ParseTypeQualifierListOpt(
7242 DS, AR_NoAttributesParsed,
7245 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);
7252 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7253 EndLoc = RefQualifierLoc;
7255 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7256 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7273 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
7290 ESpecType = tryParseExceptionSpecification(Delayed,
7293 DynamicExceptionRanges,
7295 ExceptionSpecTokens);
7297 EndLoc = ESpecRange.
getEnd();
7301 MaybeParseCXX11Attributes(FnAttrs);
7304 LocalEndLoc = EndLoc;
7306 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7309 LocalEndLoc = Tok.getLocation();
7311 TrailingReturnType =
7313 TrailingReturnTypeLoc =
Range.getBegin();
7314 EndLoc =
Range.getEnd();
7317 MaybeParseCXX11Attributes(FnAttrs);
7325 SmallVector<NamedDecl *, 0> DeclsInPrototype;
7328 NamedDecl *ND = dyn_cast<NamedDecl>(D);
7331 DeclsInPrototype.push_back(ND);
7338 llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) {
7346 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7347 ParamInfo.size(), EllipsisLoc, RParenLoc,
7348 RefQualifierIsLValueRef, RefQualifierLoc,
7350 ESpecType, ESpecRange, DynamicExceptions.data(),
7351 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7352 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7353 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7354 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7356 std::move(FnAttrs), EndLoc);
7359bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7361 if (Tok.isOneOf(tok::amp, tok::ampamp)) {
7363 diag::warn_cxx98_compat_ref_qualifier :
7364 diag::ext_ref_qualifier);
7366 RefQualifierIsLValueRef = Tok.is(tok::amp);
7373bool Parser::isFunctionDeclaratorIdentifierList() {
7375 && Tok.is(tok::identifier)
7376 && !TryAltiVecVectorToken()
7392 && (!Tok.is(tok::eof) &&
7396void Parser::ParseFunctionDeclaratorIdentifierList(
7400 assert(!
getLangOpts().requiresStrictPrototypes() &&
7401 "Cannot parse an identifier list in C23 or C++");
7408 Diag(Tok, diag::ext_ident_list_in_param);
7411 llvm::SmallPtrSet<const IdentifierInfo *, 16> ParamsSoFar;
7415 if (Tok.isNot(tok::identifier)) {
7416 Diag(Tok, diag::err_expected) << tok::identifier;
7423 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
7426 if (Actions.getTypeName(*ParmII, Tok.getLocation(),
getCurScope()))
7427 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7430 if (!ParamsSoFar.insert(ParmII).second) {
7431 Diag(Tok, diag::err_param_redefinition) << ParmII;
7434 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7445void Parser::ParseParameterDeclarationClause(
7454 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7456 Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)
7475 IsACXXFunctionDeclaration) {
7487 DeclSpec DS(AttrFactory);
7489 ParsedAttributes ArgDeclAttrs(AttrFactory);
7490 ParsedAttributes ArgDeclSpecAttrs(AttrFactory);
7497 ArgDeclSpecAttrs.takeAllPrependingFrom(FirstArgAttrs);
7500 MaybeParseCXX11Attributes(ArgDeclAttrs);
7503 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7506 SourceLocation DSStart = Tok.getLocation();
7510 SourceLocation ThisLoc;
7514 ParsedTemplateInfo TemplateInfo;
7515 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7516 DeclSpecContext::DSC_normal,
7517 nullptr, AllowImplicitTypename);
7530 ParseDeclarator(ParmDeclarator);
7533 ParmDeclarator.SetRangeBegin(ThisLoc);
7536 MaybeParseGNUAttributes(ParmDeclarator);
7540 if (Tok.is(tok::kw_requires)) {
7545 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7551 const IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
7555 std::unique_ptr<CachedTokens> DefArgToks;
7559 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7560 ParmDeclarator.getNumTypeObjects() == 0) {
7562 Diag(DSStart, diag::err_missing_param);
7569 if (Tok.is(tok::ellipsis) &&
7571 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7572 !Actions.isUnexpandedParameterPackPermitted())) &&
7573 Actions.containsUnexpandedParameterPacks(ParmDeclarator))
7574 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7593 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7594 Tok.isNot(tok::raw_identifier) && !Tok.isAnnotation() &&
7595 Tok.getIdentifierInfo() &&
7596 Tok.getIdentifierInfo()->isKeyword(
getLangOpts())) {
7597 Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok);
7606 Diag(ParmDeclarator.getBeginLoc(),
7607 diag::err_function_parameter_limit_exceeded);
7615 Actions.ActOnParamDeclarator(
getCurScope(), ParmDeclarator, ThisLoc);
7620 if (Tok.is(tok::equal)) {
7621 SourceLocation EqualLoc = Tok.getLocation();
7631 ConsumeAndStoreInitializer(*DefArgToks,
7633 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
7641 EnterExpressionEvaluationContext Eval(
7648 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7649 DefArgResult = ParseBraceInitializer();
7651 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
7652 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7653 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7662 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7667 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
7668 DefArgResult.
get());
7673 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7674 ParmDeclarator.getIdentifierLoc(),
7675 Param, std::move(DefArgToks)));
7683 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
7690 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7692 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7693 Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {
7696 SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();
7697 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7698 << ParmEllipsis.
isValid() << ParmEllipsis;
7701 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7703 Diag(ParmDeclarator.getIdentifierLoc(),
7704 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7707 << !ParmDeclarator.hasName();
7709 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7721void Parser::ParseBracketDeclarator(
Declarator &D) {
7722 if (CheckProhibitedCXX11Attribute())
7730 if (Tok.getKind() == tok::r_square) {
7732 ParsedAttributes attrs(AttrFactory);
7733 MaybeParseCXX11Attributes(attrs);
7737 T.getOpenLocation(),
7738 T.getCloseLocation()),
7739 std::move(attrs),
T.getCloseLocation());
7741 }
else if (Tok.getKind() == tok::numeric_constant &&
7748 ParsedAttributes attrs(AttrFactory);
7749 MaybeParseCXX11Attributes(attrs);
7753 T.getOpenLocation(),
7754 T.getCloseLocation()),
7755 std::move(attrs),
T.getCloseLocation());
7757 }
else if (Tok.getKind() == tok::code_completion) {
7759 Actions.CodeCompletion().CodeCompleteBracketDeclarator(
getCurScope());
7764 SourceLocation StaticLoc;
7769 DeclSpec DS(AttrFactory);
7770 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
7778 bool isStar =
false;
7789 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7790 StaticLoc = SourceLocation();
7793 }
else if (Tok.isNot(tok::r_square)) {
7810 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7811 StaticLoc = SourceLocation();
7830 isStar, NumElements.
get(),
T.getOpenLocation(),
7831 T.getCloseLocation()),
7835void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
7836 assert(Tok.is(tok::l_square) &&
"Missing opening bracket");
7839 SourceLocation StartBracketLoc = Tok.getLocation();
7843 while (Tok.is(tok::l_square)) {
7844 ParseBracketDeclarator(TempDeclarator);
7850 if (Tok.is(tok::semi))
7853 SourceLocation SuggestParenLoc = Tok.getLocation();
7856 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7861 if (TempDeclarator.getNumTypeObjects() == 0)
7865 bool NeedParens =
false;
7884 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
7890 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
7891 const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
7892 D.
AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());
7897 if (!D.
hasName() && !NeedParens)
7900 SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();
7903 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
7904 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
7907 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7912 EndLoc, CharSourceRange(BracketRange,
true))
7915 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7918 EndLoc, CharSourceRange(BracketRange,
true))
7923void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
7924 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
7925 "Not a typeof specifier");
7927 bool IsUnqual = Tok.is(tok::kw_typeof_unqual);
7928 const IdentifierInfo *II = Tok.getIdentifierInfo();
7930 Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName();
7934 bool HasParens = Tok.is(tok::l_paren);
7942 SourceRange CastRange;
7944 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);
7960 const char *PrevSpec =
nullptr;
7967 Actions.getASTContext().getPrintingPolicy()))
7968 Diag(StartLoc, DiagID) << PrevSpec;
7979 Operand = Actions.HandleExprEvaluationContextForTypeof(
Operand.get());
7985 const char *PrevSpec =
nullptr;
7992 Actions.getASTContext().getPrintingPolicy()))
7993 Diag(StartLoc, DiagID) << PrevSpec;
7996void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
7997 assert(Tok.is(tok::kw__Atomic) &&
NextToken().
is(tok::l_paren) &&
7998 "Not an atomic specifier");
8002 if (
T.consumeOpen())
8006 if (
Result.isInvalid()) {
8014 if (
T.getCloseLocation().isInvalid())
8020 const char *PrevSpec =
nullptr;
8024 Actions.getASTContext().getPrintingPolicy()))
8025 Diag(StartLoc, DiagID) << PrevSpec;
8028bool Parser::TryAltiVecVectorTokenOutOfLine() {
8030 switch (
Next.getKind()) {
8031 default:
return false;
8034 case tok::kw_signed:
8035 case tok::kw_unsigned:
8040 case tok::kw_double:
8043 case tok::kw___bool:
8044 case tok::kw___pixel:
8045 Tok.setKind(tok::kw___vector);
8047 case tok::identifier:
8048 if (
Next.getIdentifierInfo() == Ident_pixel) {
8049 Tok.setKind(tok::kw___vector);
8052 if (
Next.getIdentifierInfo() == Ident_bool ||
8053 Next.getIdentifierInfo() == Ident_Bool) {
8054 Tok.setKind(tok::kw___vector);
8062 const char *&PrevSpec,
unsigned &DiagID,
8064 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
8065 if (Tok.getIdentifierInfo() == Ident_vector) {
8067 switch (
Next.getKind()) {
8070 case tok::kw_signed:
8071 case tok::kw_unsigned:
8076 case tok::kw_double:
8079 case tok::kw___bool:
8080 case tok::kw___pixel:
8083 case tok::identifier:
8084 if (
Next.getIdentifierInfo() == Ident_pixel) {
8088 if (
Next.getIdentifierInfo() == Ident_bool ||
8089 Next.getIdentifierInfo() == Ident_Bool) {
8098 }
else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
8102 }
else if ((Tok.getIdentifierInfo() == Ident_bool) &&
8110TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8113 SmallVector<Token, 4> Tokens;
8116 auto &SourceMgr = PP.getSourceManager();
8117 FileID FID = SourceMgr.createFileID(
8118 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8122 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8123 L.setParsingPreprocessorDirective(
true);
8129 Tokens.push_back(Tok);
8130 }
while (Tok.isNot(tok::eod));
8135 Token &EndToken = Tokens.back();
8142 Tokens.push_back(Tok);
8145 PP.EnterTokenStream(Tokens,
false,
8160 (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {
8161 Diag(Tok.getLocation(), diag::err_type_unparsed);
8166 while (Tok.isNot(tok::eof))
8170 if (Tok.is(tok::eof) && Tok.getEofData() == TypeStr.data())
8175void Parser::DiagnoseBitIntUse(
const Token &
Tok) {
8179 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8180 "expected either an _ExtInt or _BitInt token!");
8182 SourceLocation Loc = Tok.getLocation();
8183 if (Tok.is(tok::kw__ExtInt)) {
8184 Diag(Loc, diag::warn_ext_int_deprecated)
8190 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 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 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)
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()
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)
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.
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
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.
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.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation getEndOfPreviousToken() const
DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagId)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Sema & getActions() const
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
ExprResult ParseConstantExpressionInExprEvalContext(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
SmallVector< Stmt *, 24 > StmtVector
A SmallVector of statements.
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
friend class ColonProtectionRAIIObject
DeclGroupPtrTy ParseOpenACCDirectiveDecl(AccessSpecifier &AS, ParsedAttributes &Attrs, DeclSpec::TST TagType, Decl *TagDecl)
Parse OpenACC directive on a declaration.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
const Token & GetLookAheadToken(unsigned N)
GetLookAheadToken - This peeks ahead N tokens and returns that token without consuming any tokens.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
ExprResult ParseArrayBoundExpression()
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...
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.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
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.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isPragmaAnnotation(TokenKind K)
Return true if this is an annotation token representing a pragma.
The JSON file list parser is used to communicate input to InstallAPI.
TypeSpecifierType
Specifies the kind of type.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
bool isa(CodeGen::Address addr)
@ NotAttributeSpecifier
This is not an attribute specifier.
@ AttributeSpecifier
This should be treated as an attribute-specifier.
@ InvalidAttributeSpecifier
The next tokens are '[[', but this is not an attribute-specifier.
@ ExpectedParameterOrImplicitObjectParameter
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
@ IK_TemplateId
A template-id, e.g., f<int>.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
ActionResult< Decl * > DeclResult
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
llvm::SmallVector< ArgsUnion, 12U > ArgsVector
Language
The language for the input, used to select and validate the language standard and possible actions.
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
@ ExplicitSpecialization
We are parsing an explicit specialization.
@ ExplicitInstantiation
We are parsing an explicit instantiation.
@ NonTemplate
We are not parsing a template at all.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
@ FunctionTemplate
The name was classified as a function template name.
@ Keyword
The name has been typo-corrected to a keyword.
@ DependentNonType
The name denotes a member of a dependent type that could not be resolved.
@ UndeclaredTemplate
The name was classified as an ADL-only function template name.
@ NonType
The name was classified as a specific non-type, non-template declaration.
@ Unknown
This name is not a type or template in this context, but might be something else.
@ Error
Classification failed; an error has been produced.
@ Type
The name was classified as a type.
@ TypeTemplate
The name was classified as a template whose specializations are types.
@ Concept
The name was classified as a concept name.
@ OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ UndeclaredNonType
The name was classified as an ADL-only function name.
@ VarTemplate
The name was classified as a variable template name.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Dependent_template_name
The name refers to a dependent template name:
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &&Second)
Consumes the attributes from Second and concatenates them at the end of First.
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
ActionResult< Expr * > ExprResult
@ Parens
New-expression has a C++98 paren-delimited initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_None
no exception specification
ActionResult< Stmt * > StmtResult
VersionTuple Version
The version number at which the change occurred.
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
SourceRange VersionRange
The source range covering the version number.
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
static DeclaratorChunk 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 getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, SourceLocation AtomicQualLoc, SourceLocation UnalignedQualLoc)
Return a DeclaratorChunk for a pointer.
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, bool lvalue)
Return a DeclaratorChunk for a reference.
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