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) {
685 Actions.ActOnReenterCXXMethodParameter(
getCurScope(), Param);
689 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
693unsigned Parser::ParseClangAttributeArgs(
697 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
704 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
705 ScopeName, ScopeLoc, Form);
706 case ParsedAttr::AT_ExternalSourceSymbol:
707 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
708 ScopeName, ScopeLoc, Form);
710 case ParsedAttr::AT_Availability:
711 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
714 case ParsedAttr::AT_ObjCBridgeRelated:
715 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
716 ScopeName, ScopeLoc, Form);
718 case ParsedAttr::AT_SwiftNewType:
719 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
722 case ParsedAttr::AT_TypeTagForDatatype:
723 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
724 ScopeName, ScopeLoc, Form);
727 case ParsedAttr::AT_CXXAssume:
728 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
729 ScopeLoc, EndLoc, Form);
732 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
738 unsigned ExistingAttrs = Attrs.
size();
750 SourceLocation OpenParenLoc = Tok.getLocation();
752 if (
AttrName->getName() ==
"property") {
758 T.expectAndConsume(diag::err_expected_lparen_after,
759 AttrName->getNameStart(), tok::r_paren);
766 IdentifierInfo *AccessorNames[] = {
nullptr,
nullptr};
767 bool HasInvalidAccessor =
false;
772 if (!Tok.is(tok::identifier)) {
774 if (Tok.is(tok::r_paren) && !HasInvalidAccessor &&
775 AccessorNames[AK_Put] ==
nullptr &&
776 AccessorNames[AK_Get] ==
nullptr) {
777 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
781 Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor);
786 SourceLocation KindLoc = Tok.getLocation();
787 StringRef KindStr = Tok.getIdentifierInfo()->getName();
788 if (KindStr ==
"get") {
790 }
else if (KindStr ==
"put") {
794 }
else if (KindStr ==
"set") {
795 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
802 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
804 HasInvalidAccessor =
true;
805 goto next_property_accessor;
809 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
810 HasInvalidAccessor =
true;
823 Diag(Tok.getLocation(), diag::err_ms_property_expected_equal)
829 if (!Tok.is(tok::identifier)) {
830 Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name);
834 if (Kind == AK_Invalid) {
836 }
else if (AccessorNames[Kind] !=
nullptr) {
838 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
840 AccessorNames[
Kind] = Tok.getIdentifierInfo();
844 next_property_accessor:
850 if (Tok.is(tok::r_paren))
853 Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen);
858 if (!HasInvalidAccessor)
860 AccessorNames[AK_Get], AccessorNames[AK_Put],
861 ParsedAttr::Form::Declspec());
863 return !HasInvalidAccessor;
867 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
868 SourceLocation(), ParsedAttr::Form::Declspec());
873 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) <<
AttrName;
880 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
881 assert(Tok.is(tok::kw___declspec) &&
"Not a declspec!");
883 SourceLocation StartLoc = Tok.getLocation();
884 SourceLocation EndLoc = StartLoc;
886 while (Tok.is(tok::kw___declspec)) {
889 if (
T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
895 while (Tok.isNot(tok::r_paren)) {
900 if (Tok.is(tok::code_completion)) {
902 Actions.CodeCompletion().CodeCompleteAttribute(
909 bool IsString = Tok.getKind() == tok::string_literal;
910 if (!IsString && Tok.getKind() != tok::identifier &&
911 Tok.getKind() != tok::kw_restrict) {
912 Diag(Tok, diag::err_ms_declspec_type);
918 SourceLocation AttrNameLoc;
920 SmallString<8> StrBuffer;
921 bool Invalid =
false;
922 StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
927 AttrName = PP.getIdentifierInfo(Str);
928 AttrNameLoc = ConsumeStringToken();
934 bool AttrHandled =
false;
937 if (Tok.is(tok::l_paren))
938 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
939 else if (
AttrName->getName() ==
"property")
941 Diag(Tok.getLocation(), diag::err_expected_lparen_after)
945 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
946 ParsedAttr::Form::Declspec());
949 EndLoc =
T.getCloseLocation();
952 Attrs.
Range = SourceRange(StartLoc, EndLoc);
958 auto Kind = Tok.getKind();
960 case tok::kw___fastcall:
961 case tok::kw___stdcall:
962 case tok::kw___thiscall:
963 case tok::kw___regcall:
964 case tok::kw___cdecl:
965 case tok::kw___vectorcall:
966 case tok::kw___ptr64:
968 case tok::kw___ptr32:
970 case tok::kw___uptr: {
971 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
973 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
984 assert(Tok.is(tok::kw___funcref));
985 SourceLocation StartLoc = Tok.getLocation();
988 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
992 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
994 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr,
995 0, tok::kw___funcref);
998void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
999 SourceLocation StartLoc = Tok.getLocation();
1000 SourceLocation EndLoc = SkipExtendedMicrosoftTypeAttributes();
1003 SourceRange
Range(StartLoc, EndLoc);
1004 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) <<
Range;
1009 SourceLocation EndLoc;
1012 switch (Tok.getKind()) {
1014 case tok::kw_volatile:
1015 case tok::kw___fastcall:
1016 case tok::kw___stdcall:
1017 case tok::kw___thiscall:
1018 case tok::kw___cdecl:
1019 case tok::kw___vectorcall:
1020 case tok::kw___ptr32:
1021 case tok::kw___ptr64:
1023 case tok::kw___unaligned:
1024 case tok::kw___sptr:
1025 case tok::kw___uptr:
1036 while (Tok.is(tok::kw___pascal)) {
1037 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1039 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1046 while (Tok.is(tok::kw___kernel)) {
1047 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1049 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1055 while (Tok.is(tok::kw___noinline__)) {
1056 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1058 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1059 tok::kw___noinline__);
1064 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1065 SourceLocation AttrNameLoc = Tok.getLocation();
1066 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1070bool Parser::isHLSLQualifier(
const Token &
Tok)
const {
1071 return Tok.is(tok::kw_groupshared);
1075 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1076 auto Kind = Tok.getKind();
1078 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0, Kind);
1084 auto Kind = Tok.getKind();
1086 case tok::kw__Nonnull:
1087 case tok::kw__Nullable:
1088 case tok::kw__Nullable_result:
1089 case tok::kw__Null_unspecified: {
1090 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1093 Diag(AttrNameLoc, diag::ext_nullability)
1095 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1106 return (Separator ==
'.' || Separator ==
'_');
1109VersionTuple Parser::ParseVersionTuple(
SourceRange &Range) {
1110 Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());
1112 if (!Tok.is(tok::numeric_constant)) {
1113 Diag(Tok, diag::err_expected_version);
1116 return VersionTuple();
1123 SmallString<512> Buffer;
1124 Buffer.resize(Tok.getLength()+1);
1125 const char *ThisTokBegin = &Buffer[0];
1128 bool Invalid =
false;
1129 unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);
1131 return VersionTuple();
1134 unsigned AfterMajor = 0;
1136 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
1137 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
1141 if (AfterMajor == 0) {
1142 Diag(Tok, diag::err_expected_version);
1145 return VersionTuple();
1148 if (AfterMajor == ActualLength) {
1153 Diag(Tok, diag::err_zero_version);
1154 return VersionTuple();
1157 return VersionTuple(Major);
1160 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1162 || (AfterMajor + 1 == ActualLength)) {
1163 Diag(Tok, diag::err_expected_version);
1166 return VersionTuple();
1170 unsigned AfterMinor = AfterMajor + 1;
1172 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
1173 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
1177 if (AfterMinor == ActualLength) {
1181 if (Major == 0 && Minor == 0) {
1182 Diag(Tok, diag::err_zero_version);
1183 return VersionTuple();
1186 return VersionTuple(Major, Minor);
1189 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1192 Diag(Tok, diag::err_expected_version);
1195 return VersionTuple();
1199 if (AfterMajorSeparator != AfterMinorSeparator)
1200 Diag(Tok, diag::warn_expected_consistent_version_separator);
1203 unsigned AfterSubminor = AfterMinor + 1;
1204 unsigned Subminor = 0;
1205 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
1206 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
1210 if (AfterSubminor != ActualLength) {
1211 Diag(Tok, diag::err_expected_version);
1214 return VersionTuple();
1217 return VersionTuple(Major, Minor, Subminor);
1220void Parser::ParseAvailabilityAttribute(
1224 enum { Introduced, Deprecated, Obsoleted,
Unknown };
1225 AvailabilityChange Changes[
Unknown];
1227 IdentifierLoc *EnvironmentLoc =
nullptr;
1231 if (
T.consumeOpen()) {
1232 Diag(Tok, diag::err_expected) << tok::l_paren;
1237 if (Tok.isNot(tok::identifier)) {
1238 Diag(Tok, diag::err_availability_expected_platform);
1242 IdentifierLoc *Platform = ParseIdentifierLoc();
1245 if (Ident->getName().contains(
"xrOS") || Ident->getName().contains(
"xros"))
1246 Diag(Platform->
getLoc(), diag::warn_availability_unknown_platform)
1249 else if (Ident->getName() ==
"macosx")
1253 else if (Ident->getName() ==
"macosx_app_extension")
1257 AvailabilityAttr::canonicalizePlatformName(Ident->getName())));
1261 if (ExpectAndConsume(tok::comma)) {
1268 if (!Ident_introduced) {
1269 Ident_introduced = PP.getIdentifierInfo(
"introduced");
1270 Ident_deprecated = PP.getIdentifierInfo(
"deprecated");
1271 Ident_obsoleted = PP.getIdentifierInfo(
"obsoleted");
1272 Ident_unavailable = PP.getIdentifierInfo(
"unavailable");
1273 Ident_message = PP.getIdentifierInfo(
"message");
1274 Ident_strict = PP.getIdentifierInfo(
"strict");
1275 Ident_replacement = PP.getIdentifierInfo(
"replacement");
1276 Ident_environment = PP.getIdentifierInfo(
"environment");
1281 SourceLocation UnavailableLoc, StrictLoc;
1283 if (Tok.isNot(tok::identifier)) {
1284 Diag(Tok, diag::err_availability_expected_change);
1288 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1291 if (
Keyword == Ident_strict) {
1293 Diag(KeywordLoc, diag::err_availability_redundant)
1294 <<
Keyword << SourceRange(StrictLoc);
1296 StrictLoc = KeywordLoc;
1300 if (
Keyword == Ident_unavailable) {
1301 if (UnavailableLoc.
isValid()) {
1302 Diag(KeywordLoc, diag::err_availability_redundant)
1303 <<
Keyword << SourceRange(UnavailableLoc);
1305 UnavailableLoc = KeywordLoc;
1312 if (Changes[Deprecated].KeywordLoc.
isValid()) {
1313 Diag(KeywordLoc, diag::err_availability_redundant)
1315 << SourceRange(Changes[Deprecated].KeywordLoc);
1320 Changes[Deprecated].
Version = VersionTuple(1);
1324 if (
Keyword == Ident_environment) {
1325 if (EnvironmentLoc !=
nullptr) {
1326 Diag(KeywordLoc, diag::err_availability_redundant)
1331 if (Tok.isNot(tok::equal)) {
1332 Diag(Tok, diag::err_expected_after) <<
Keyword << tok::equal;
1338 if (!isTokenStringLiteral()) {
1339 Diag(Tok, diag::err_expected_string_literal)
1344 if (
Keyword == Ident_message) {
1352 if (
Keyword == Ident_environment) {
1353 if (Tok.isNot(tok::identifier)) {
1354 Diag(Tok, diag::err_availability_expected_environment);
1358 EnvironmentLoc = ParseIdentifierLoc();
1364 if ((
Keyword == Ident_introduced ||
Keyword == Ident_deprecated) &&
1365 Tok.is(tok::identifier)) {
1366 IdentifierInfo *NA = Tok.getIdentifierInfo();
1369 if (
Keyword == Ident_introduced)
1370 UnavailableLoc = KeywordLoc;
1375 SourceRange VersionRange;
1376 VersionTuple Version = ParseVersionTuple(VersionRange);
1378 if (Version.empty()) {
1384 if (
Keyword == Ident_introduced)
1386 else if (
Keyword == Ident_deprecated)
1388 else if (
Keyword == Ident_obsoleted)
1394 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1395 Diag(KeywordLoc, diag::err_availability_redundant)
1397 << SourceRange(Changes[Index].KeywordLoc,
1398 Changes[Index].VersionRange.
getEnd());
1402 Changes[Index].
Version = Version;
1405 Diag(KeywordLoc, diag::err_availability_unknown_change)
1412 if (
T.consumeClose())
1416 *endLoc =
T.getCloseLocation();
1420 if (UnavailableLoc.
isValid()) {
1421 bool Complained =
false;
1422 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1423 if (Changes[Index].KeywordLoc.
isValid()) {
1425 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1426 << SourceRange(Changes[Index].KeywordLoc,
1427 Changes[Index].VersionRange.
getEnd());
1432 Changes[Index] = AvailabilityChange();
1438 attrs.
addNew(&Availability,
1439 SourceRange(AvailabilityLoc,
T.getCloseLocation()),
1440 AttributeScopeInfo(ScopeName, ScopeLoc), Platform,
1441 Changes[Introduced], Changes[Deprecated], Changes[Obsoleted],
1442 UnavailableLoc, MessageExpr.
get(), Form, StrictLoc,
1443 ReplacementExpr.
get(), EnvironmentLoc);
1446void Parser::ParseExternalSourceSymbolAttribute(
1452 if (
T.expectAndConsume())
1456 if (!Ident_language) {
1457 Ident_language = PP.getIdentifierInfo(
"language");
1458 Ident_defined_in = PP.getIdentifierInfo(
"defined_in");
1459 Ident_generated_declaration = PP.getIdentifierInfo(
"generated_declaration");
1460 Ident_USR = PP.getIdentifierInfo(
"USR");
1464 bool HasLanguage =
false;
1466 bool HasDefinedIn =
false;
1467 IdentifierLoc *GeneratedDeclaration =
nullptr;
1469 bool HasUSR =
false;
1473 if (Tok.isNot(tok::identifier)) {
1474 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1479 SourceLocation KeywordLoc = Tok.getLocation();
1480 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1481 if (
Keyword == Ident_generated_declaration) {
1482 if (GeneratedDeclaration) {
1483 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) <<
Keyword;
1487 GeneratedDeclaration = ParseIdentifierLoc();
1493 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1499 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1505 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1507 if (
Keyword == Ident_language)
1509 else if (
Keyword == Ident_USR)
1512 HasDefinedIn =
true;
1514 if (!isTokenStringLiteral()) {
1515 Diag(Tok, diag::err_expected_string_literal)
1520 : (
Keyword == Ident_defined_in ? 1 : 2));
1524 if (
Keyword == Ident_language) {
1526 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1532 }
else if (
Keyword == Ident_USR) {
1534 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1541 assert(
Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1543 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1553 if (
T.consumeClose())
1556 *EndLoc =
T.getCloseLocation();
1560 Attrs.
addNew(&ExternalSourceSymbol, SourceRange(Loc,
T.getCloseLocation()),
1561 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1565void Parser::ParseObjCBridgeRelatedAttribute(
1571 if (
T.consumeOpen()) {
1572 Diag(Tok, diag::err_expected) << tok::l_paren;
1577 if (Tok.isNot(tok::identifier)) {
1578 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1582 IdentifierLoc *RelatedClass = ParseIdentifierLoc();
1583 if (ExpectAndConsume(tok::comma)) {
1592 if (Tok.is(tok::identifier)) {
1595 Diag(Tok, diag::err_objcbridge_related_selector_name);
1601 if (Tok.is(tok::colon))
1602 Diag(Tok, diag::err_objcbridge_related_selector_name);
1604 Diag(Tok, diag::err_expected) << tok::comma;
1612 if (Tok.is(tok::identifier))
1614 else if (Tok.isNot(tok::r_paren)) {
1615 Diag(Tok, diag::err_expected) << tok::r_paren;
1621 if (
T.consumeClose())
1625 *EndLoc =
T.getCloseLocation();
1628 Attrs.
addNew(&ObjCBridgeRelated,
1629 SourceRange(ObjCBridgeRelatedLoc,
T.getCloseLocation()),
1630 AttributeScopeInfo(ScopeName, ScopeLoc), RelatedClass,
1631 ClassMethod, InstanceMethod, Form);
1634void Parser::ParseSwiftNewTypeAttribute(
1641 if (
T.consumeOpen()) {
1642 Diag(Tok, diag::err_expected) << tok::l_paren;
1646 if (Tok.is(tok::r_paren)) {
1647 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
1651 if (Tok.isNot(tok::kw_struct) && Tok.isNot(tok::kw_enum)) {
1652 Diag(Tok, diag::warn_attribute_type_not_supported)
1653 << &
AttrName << Tok.getIdentifierInfo();
1654 if (!isTokenSpecial())
1660 auto *SwiftType =
new (Actions.Context)
1661 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
1665 if (
T.consumeClose())
1668 *EndLoc =
T.getCloseLocation();
1671 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
T.getCloseLocation()),
1672 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1676void Parser::ParseTypeTagForDatatypeAttribute(
1680 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1685 if (Tok.isNot(tok::identifier)) {
1686 Diag(Tok, diag::err_expected) << tok::identifier;
1690 IdentifierLoc *ArgumentKind = ParseIdentifierLoc();
1692 if (ExpectAndConsume(tok::comma)) {
1697 SourceRange MatchingCTypeRange;
1704 bool LayoutCompatible =
false;
1705 bool MustBeNull =
false;
1707 if (Tok.isNot(tok::identifier)) {
1708 Diag(Tok, diag::err_expected) << tok::identifier;
1712 IdentifierInfo *Flag = Tok.getIdentifierInfo();
1713 if (Flag->
isStr(
"layout_compatible"))
1714 LayoutCompatible =
true;
1715 else if (Flag->
isStr(
"must_be_null"))
1718 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1725 if (!
T.consumeClose()) {
1727 &AttrName, AttrNameLoc, AttributeScopeInfo(ScopeName, ScopeLoc),
1728 ArgumentKind, MatchingCType.
get(), LayoutCompatible, MustBeNull, Form);
1732 *EndLoc =
T.getCloseLocation();
1735bool Parser::DiagnoseProhibitedCXX11Attribute() {
1736 assert(Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square));
1738 switch (isCXX11AttributeSpecifier(
true)) {
1744 Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1749 SourceLocation BeginLoc = ConsumeBracket();
1752 assert(Tok.is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1753 SourceLocation EndLoc = ConsumeBracket();
1754 Diag(BeginLoc, diag::err_attributes_not_allowed)
1755 << SourceRange(BeginLoc, EndLoc);
1758 llvm_unreachable(
"All cases handled above.");
1763 assert((Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square)) ||
1764 Tok.is(tok::kw_alignas) || Tok.isRegularKeywordAttribute());
1768 Tok.isRegularKeywordAttribute() ? Tok.getIdentifierInfo() :
nullptr;
1769 SourceLocation Loc = Tok.getLocation();
1770 ParseCXX11Attributes(Attrs);
1771 CharSourceRange AttrRange(SourceRange(Loc, Attrs.
Range.
getEnd()),
true);
1774 :
Diag(Loc, diag::err_attributes_not_allowed))
1779void Parser::DiagnoseProhibitedAttributes(
1782 if (CorrectLocation.
isValid()) {
1783 CharSourceRange AttrRange(Attrs.
Range,
true);
1784 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1785 ?
Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1786 :
Diag(CorrectLocation, diag::err_attributes_misplaced))
1791 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1792 ?
Diag(
Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr
1793 :
Diag(
Range.getBegin(), diag::err_attributes_not_allowed))
1799 unsigned AttrDiagID,
1800 unsigned KeywordDiagID,
1801 bool DiagnoseEmptyAttrs,
1802 bool WarnOnUnknownAttrs) {
1808 auto &
SM = PP.getSourceManager();
1812 if (FirstLSquare.
is(tok::l_square)) {
1813 std::optional<Token> SecondLSquare =
1816 if (SecondLSquare && SecondLSquare->is(tok::l_square)) {
1826 for (
const ParsedAttr &AL : Attrs) {
1827 if (AL.isRegularKeywordAttribute()) {
1828 Diag(AL.getLoc(), KeywordDiagID) << AL;
1832 if (!AL.isStandardAttributeSyntax())
1835 if (WarnOnUnknownAttrs) {
1836 Actions.DiagnoseUnknownAttribute(AL);
1840 Diag(AL.getLoc(), AttrDiagID) << AL;
1847 for (
const ParsedAttr &PA : Attrs) {
1848 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1849 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1850 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
1859 llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;
1862 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1863 AL.isDeclspecAttribute()) ||
1864 AL.isMicrosoftAttribute())
1865 ToBeMoved.push_back(&AL);
1868 for (ParsedAttr *AL : ToBeMoved) {
1882 ObjCDeclContextSwitch ObjCDC(*
this);
1884 Decl *SingleDecl =
nullptr;
1885 switch (Tok.getKind()) {
1886 case tok::kw_template:
1887 case tok::kw_export:
1888 ProhibitAttributes(DeclAttrs);
1889 ProhibitAttributes(DeclSpecAttrs);
1890 return ParseDeclarationStartingWithTemplate(Context, DeclEnd, DeclAttrs);
1891 case tok::kw_inline:
1894 ProhibitAttributes(DeclAttrs);
1895 ProhibitAttributes(DeclSpecAttrs);
1897 return ParseNamespace(Context, DeclEnd, InlineLoc);
1899 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1900 true,
nullptr, DeclSpecStart);
1902 case tok::kw_cbuffer:
1903 case tok::kw_tbuffer:
1904 SingleDecl = ParseHLSLBuffer(DeclEnd, DeclAttrs);
1906 case tok::kw_namespace:
1907 ProhibitAttributes(DeclAttrs);
1908 ProhibitAttributes(DeclSpecAttrs);
1909 return ParseNamespace(Context, DeclEnd);
1910 case tok::kw_using: {
1912 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1913 DeclEnd, DeclAttrs);
1915 case tok::kw_static_assert:
1916 case tok::kw__Static_assert:
1917 ProhibitAttributes(DeclAttrs);
1918 ProhibitAttributes(DeclSpecAttrs);
1919 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1922 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1923 true,
nullptr, DeclSpecStart);
1928 return Actions.ConvertDeclToDeclGroup(SingleDecl);
1934 bool RequireSemi, ForRangeInit *FRI,
SourceLocation *DeclSpecStart) {
1936 ParsedAttributesView OriginalDeclSpecAttrs;
1937 OriginalDeclSpecAttrs.
prepend(DeclSpecAttrs.
begin(), DeclSpecAttrs.
end());
1938 OriginalDeclSpecAttrs.
Range = DeclSpecAttrs.
Range;
1941 ParsingDeclSpec DS(*
this);
1944 ParsedTemplateInfo TemplateInfo;
1945 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
1946 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none, DSContext);
1951 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
1956 if (Tok.is(tok::semi)) {
1957 ProhibitAttributes(DeclAttrs);
1958 DeclEnd = Tok.getLocation();
1960 RecordDecl *AnonRecord =
nullptr;
1961 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
1963 Actions.ActOnDefinedDeclarationSpecifier(TheDecl);
1964 DS.complete(TheDecl);
1966 Decl* decls[] = {AnonRecord, TheDecl};
1967 return Actions.BuildDeclaratorGroup(decls);
1969 return Actions.ConvertDeclToDeclGroup(TheDecl);
1973 Actions.ActOnDefinedDeclarationSpecifier(DS.
getRepAsDecl());
1978 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
1982 switch (Tok.getKind()) {
1983 case tok::annot_cxxscope:
1984 case tok::annot_template_id:
1986 case tok::code_completion:
1987 case tok::coloncolon:
1989 case tok::kw___attribute:
1990 case tok::kw_operator:
2006 case tok::identifier:
2008 case tok::code_completion:
2009 case tok::coloncolon:
2012 case tok::equalequal:
2013 case tok::kw_alignas:
2015 case tok::kw___attribute:
2033 case tok::identifier:
2037 return Tok.isRegularKeywordAttribute();
2041 return Tok.isRegularKeywordAttribute();
2047 switch (Tok.getKind()) {
2053 if (Tok.isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
2077 case tok::kw_inline:
2081 if (Tok.isAtStartOfLine() &&
NextToken().
is(tok::kw_namespace) &&
2082 (!ParsingInObjCContainer || CurParsedObjCImpl))
2086 case tok::kw_extern:
2089 case tok::kw_namespace:
2093 if (Tok.isAtStartOfLine() &&
2094 (!ParsingInObjCContainer || CurParsedObjCImpl))
2100 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2101 ParsingInObjCContainer)
2108 if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
2113 case tok::annot_module_begin:
2114 case tok::annot_module_end:
2115 case tok::annot_module_include:
2116 case tok::annot_repl_input_end:
2130 ParsedTemplateInfo &TemplateInfo,
2132 ForRangeInit *FRI) {
2138 LocalAttrs.takeAllPrependingFrom(Attrs);
2140 if (TemplateInfo.TemplateParams)
2143 bool IsTemplateSpecOrInst =
2150 if (IsTemplateSpecOrInst)
2160 while (MaybeParseHLSLAnnotations(D))
2163 if (
Tok.is(tok::kw_requires))
2164 ParseTrailingRequiresClause(D);
2169 LateParsedAttrList LateParsedAttrs(
true);
2171 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2176 if (
Tok.is(tok::kw__Noreturn)) {
2178 const char *PrevSpec;
2184 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2185 Fixit &=
Tok.isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2187 Diag(Loc, diag::err_c11_noreturn_misplaced)
2189 << (Fixit ?
FixItHint::CreateInsertion(D.getBeginLoc(),
"_Noreturn ")
2194 if (Tok.is(tok::equal) &&
NextToken().
is(tok::code_completion)) {
2196 Actions.CodeCompletion().CodeCompleteAfterFunctionEquals(D);
2205 while (
auto Specifier = isCXX11VirtSpecifier()) {
2206 Diag(Tok, diag::err_virt_specifier_outside_class)
2214 if (!isDeclarationAfterDeclarator()) {
2220 if (isStartOfFunctionDefinition(D)) {
2230 diag::err_function_declared_typedef)
2234 Decl *TheDecl =
nullptr;
2240 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2241 TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(),
2244 SourceLocation LAngleLoc =
2245 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2247 diag::err_explicit_instantiation_with_definition)
2248 << SourceRange(TemplateInfo.TemplateLoc)
2253 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2254 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
2255 LAngleLoc,
nullptr));
2257 TheDecl = ParseFunctionDefinition(
2259 ParsedTemplateInfo(&FakedParamLists,
2266 ParseFunctionDefinition(D, TemplateInfo, &LateParsedAttrs);
2269 return Actions.ConvertDeclToDeclGroup(TheDecl);
2273 Tok.is(tok::kw_namespace)) {
2283 Diag(Tok, diag::err_expected_fn_body);
2288 if (Tok.is(tok::l_brace)) {
2289 Diag(Tok, diag::err_function_definition_not_allowed);
2297 if (ParseAsmAttributesAfterDeclarator(D))
2306 if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
2307 bool IsForRangeLoop =
false;
2309 IsForRangeLoop =
true;
2310 EnterExpressionEvaluationContext ForRangeInitContext(
2318 auto &LastRecord = Actions.currentEvaluationContext();
2319 LastRecord.InLifetimeExtendingContext =
true;
2320 LastRecord.RebuildDefaultArgOrDefaultInit =
true;
2324 Actions.OpenMP().startOpenMPCXXRangeFor();
2325 if (Tok.is(tok::l_brace))
2326 FRI->RangeExpr = ParseBraceInitializer();
2333 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
2337 FRI->LifetimeExtendTemps = std::move(
2338 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps);
2342 if (IsForRangeLoop) {
2343 Actions.ActOnCXXForRangeDecl(ThisDecl);
2346 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2347 VD->setObjCForDecl(
true);
2349 Actions.FinalizeDeclaration(ThisDecl);
2350 D.complete(ThisDecl);
2351 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, ThisDecl);
2354 SmallVector<Decl *, 8> DeclsInGroup;
2356 ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo, FRI);
2357 if (LateParsedAttrs.size() > 0)
2358 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2359 D.complete(FirstDecl);
2361 DeclsInGroup.push_back(FirstDecl);
2367 SourceLocation CommaLoc;
2369 if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2373 Diag(CommaLoc, diag::err_expected_semi_declaration)
2385 Diag(CommaLoc, diag::err_multiple_template_declarators)
2386 << TemplateInfo.Kind;
2400 MaybeParseGNUAttributes(D);
2404 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2409 MaybeParseHLSLAnnotations(D);
2416 if (Tok.is(tok::kw_requires))
2417 ParseTrailingRequiresClause(D);
2418 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D, TemplateInfo);
2419 D.complete(ThisDecl);
2421 DeclsInGroup.push_back(ThisDecl);
2426 *DeclEnd = Tok.getLocation();
2428 if (ExpectSemi && ExpectAndConsumeSemi(
2430 ? diag::err_invalid_token_after_toplevel_declarator
2431 : diag::err_expected_semi_declaration)) {
2439 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
2442bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &D) {
2444 if (Tok.is(tok::kw_asm)) {
2446 ExprResult AsmLabel(ParseSimpleAsm(
true, &Loc));
2447 if (AsmLabel.isInvalid()) {
2456 MaybeParseGNUAttributes(D);
2460Decl *Parser::ParseDeclarationAfterDeclarator(
2461 Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
2462 if (ParseAsmAttributesAfterDeclarator(D))
2465 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
2468Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2469 Declarator &D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2471 struct InitializerScopeRAII {
2477 InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl)
2478 : P(P), D(D), ThisDecl(ThisDecl), Entered(
false) {
2481 if (D.getCXXScopeSpec().isSet()) {
2483 S = P.getCurScope();
2486 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2491 ~InitializerScopeRAII() {
2507 InitKind TheInitKind;
2509 if (isTokenEqualOrEqualTypo())
2510 TheInitKind = InitKind::Equal;
2511 else if (
Tok.
is(tok::l_paren))
2512 TheInitKind = InitKind::CXXDirect;
2515 TheInitKind = InitKind::CXXBraced;
2517 TheInitKind = InitKind::Uninitialized;
2518 if (TheInitKind != InitKind::Uninitialized)
2522 Decl *ThisDecl =
nullptr;
2523 Decl *OuterDecl =
nullptr;
2524 switch (TemplateInfo.Kind) {
2526 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2531 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
2532 *TemplateInfo.TemplateParams,
2534 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2537 ThisDecl = VT->getTemplatedDecl();
2543 if (
Tok.
is(tok::semi)) {
2544 DeclResult ThisRes = Actions.ActOnExplicitInstantiation(
2545 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
2547 SkipUntil(tok::semi, StopBeforeMatch);
2550 ThisDecl = ThisRes.
get();
2558 Diag(
Tok, diag::err_template_defn_explicit_instantiation)
2560 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2563 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2565 diag::err_explicit_instantiation_with_definition)
2570 TemplateParameterLists FakedParamLists;
2571 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2573 LAngleLoc,
nullptr));
2576 Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D);
2585 switch (TheInitKind) {
2587 case InitKind::Equal: {
2590 if (
Tok.
is(tok::kw_delete)) {
2592 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2595 Diag(ConsumeToken(), diag::err_deleted_non_function);
2596 SkipDeletedFunctionBody();
2597 }
else if (
Tok.
is(tok::kw_default)) {
2599 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2602 Diag(ConsumeToken(), diag::err_default_special_members)
2603 << getLangOpts().CPlusPlus20;
2605 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2607 if (
Tok.
is(tok::code_completion)) {
2609 Actions.CodeCompletion().CodeCompleteInitializer(getCurScope(),
2611 Actions.FinalizeDeclaration(ThisDecl);
2621 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2625 FRI->ColonLoc = EqualLoc;
2627 FRI->RangeExpr =
Init;
2630 if (
Init.isInvalid()) {
2632 StopTokens.push_back(tok::comma);
2635 StopTokens.push_back(tok::r_paren);
2636 SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch);
2637 Actions.ActOnInitializerError(ThisDecl);
2639 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
2644 case InitKind::CXXDirect: {
2651 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2653 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2654 auto RunSignatureHelp = [&]() {
2656 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2657 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2660 CalledSignatureHelp =
true;
2661 return PreferredType;
2663 auto SetPreferredType = [&] {
2664 PreferredType.enterFunctionArgument(
Tok.
getLocation(), RunSignatureHelp);
2667 llvm::function_ref<void()> ExpressionStarts;
2673 ExpressionStarts = SetPreferredType;
2676 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2679 if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
2680 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2681 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2684 CalledSignatureHelp =
true;
2686 Actions.ActOnInitializerError(ThisDecl);
2687 SkipUntil(tok::r_paren, StopAtSemi);
2693 T.getCloseLocation(),
2695 Actions.AddInitializerToDecl(ThisDecl,
Initializer.get(),
2700 case InitKind::CXXBraced: {
2702 Diag(
Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2704 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2709 if (
Init.isInvalid()) {
2710 Actions.ActOnInitializerError(ThisDecl);
2712 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
true);
2715 case InitKind::Uninitialized: {
2716 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2717 Actions.ActOnUninitializedDecl(ThisDecl);
2722 Actions.FinalizeDeclaration(ThisDecl);
2723 return OuterDecl ? OuterDecl : ThisDecl;
2726void Parser::ParseSpecifierQualifierList(
2729 ParsedTemplateInfo TemplateInfo;
2733 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC,
nullptr,
2734 AllowImplicitTypename);
2739 Diag(Tok, diag::err_expected_type);
2742 Diag(Tok, diag::err_typename_requires_specqual);
2753 diag::err_typename_invalid_storageclass);
2797 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2798 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2803 ParsedTemplateInfo &TemplateInfo,
2806 assert(Tok.is(tok::identifier) &&
"should have identifier");
2808 SourceLocation Loc = Tok.getLocation();
2828 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
2846 AnnotateScopeToken(*SS,
false);
2855 if (
ParsedType T = Actions.ActOnMSVCUnknownTypeName(
2856 *Tok.getIdentifierInfo(), Tok.getLocation(),
2857 DSC == DeclSpecContext::DSC_template_type_arg)) {
2858 const char *PrevSpec;
2861 Actions.getASTContext().getPrintingPolicy());
2874 if (SS ==
nullptr) {
2875 const char *TagName =
nullptr, *FixitTagName =
nullptr;
2878 switch (Actions.isTagName(*Tok.getIdentifierInfo(),
getCurScope())) {
2881 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
2883 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
2885 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
2887 TagName=
"__interface"; FixitTagName =
"__interface ";
2888 TagKind=tok::kw___interface;
break;
2890 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
2894 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
2895 LookupResult R(Actions, TokenName, SourceLocation(),
2898 Diag(Loc, diag::err_use_of_tag_name_without_tag)
2899 << TokenName << TagName <<
getLangOpts().CPlusPlus
2905 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2906 << TokenName << TagName;
2910 if (TagKind == tok::kw_enum)
2911 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,
2912 DeclSpecContext::DSC_normal);
2914 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
2916 DeclSpecContext::DSC_normal, Attrs);
2923 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
2924 DSC == DeclSpecContext::DSC_class)) {
2928 case tok::l_paren: {
2935 TentativeParsingAction PA(*
this);
2937 TPResult TPR = TryParseDeclarator(
false);
2940 if (TPR != TPResult::False) {
2948 if (DSC == DeclSpecContext::DSC_class ||
2949 (DSC == DeclSpecContext::DSC_top_level && SS)) {
2950 IdentifierInfo *II = Tok.getIdentifierInfo();
2951 if (Actions.isCurrentClassNameTypo(II, SS)) {
2952 Diag(Loc, diag::err_constructor_bad_name)
2953 << Tok.getIdentifierInfo() << II
2955 Tok.setIdentifierInfo(II);
2973 AnnotateScopeToken(*SS,
false);
2987 IdentifierInfo *II = Tok.getIdentifierInfo();
2989 Actions.DiagnoseUnknownTypeName(II, Loc,
getCurScope(), SS,
T,
2995 const char *PrevSpec;
2998 Actions.getASTContext().getPrintingPolicy());
3003 }
else if (II != Tok.getIdentifierInfo()) {
3016 if (IsTemplateName) {
3017 SourceLocation LAngle, RAngle;
3018 TemplateArgList Args;
3019 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3028Parser::DeclSpecContext
3032 return DeclSpecContext::DSC_class;
3034 return DeclSpecContext::DSC_top_level;
3036 return DeclSpecContext::DSC_template_param;
3038 return DeclSpecContext::DSC_template_arg;
3040 return DeclSpecContext::DSC_template_type_arg;
3043 return DeclSpecContext::DSC_trailing;
3046 return DeclSpecContext::DSC_alias_declaration;
3048 return DeclSpecContext::DSC_association;
3050 return DeclSpecContext::DSC_type_specifier;
3052 return DeclSpecContext::DSC_condition;
3054 return DeclSpecContext::DSC_conv_operator;
3056 return DeclSpecContext::DSC_new;
3071 return DeclSpecContext::DSC_normal;
3074 llvm_unreachable(
"Missing DeclaratorContext case");
3081 if (isTypeIdInParens()) {
3082 SourceLocation TypeLoc = Tok.getLocation();
3084 SourceRange TypeRange(Start, Tok.getLocation());
3085 if (Actions.ActOnAlignasTypeArgument(KWName, Ty, TypeLoc, TypeRange))
3102 assert(Tok.isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3103 "Not an alignment-specifier!");
3110 if (
T.expectAndConsume())
3115 SourceLocation EllipsisLoc;
3117 ParseAlignArgument(PP.getSpelling(KWTok),
T.getOpenLocation(),
3126 *EndLoc =
T.getCloseLocation();
3133 ArgExprs.push_back(ArgExpr.
get());
3134 Attrs.
addNew(KWName, KWLoc, AttributeScopeInfo(), ArgExprs.data(), 1, Kind,
3139void Parser::DistributeCLateParsedAttrs(
Decl *Dcl,
3140 LateParsedAttrList *LateAttrs) {
3145 for (
auto *LateAttr : *LateAttrs) {
3146 if (LateAttr->Decls.empty())
3147 LateAttr->addDecl(Dcl);
3153 assert(Tok.is(tok::kw___ptrauth));
3155 IdentifierInfo *KwName = Tok.getIdentifierInfo();
3159 if (
T.expectAndConsume())
3169 ArgExprs.push_back(ER.
get());
3173 SourceLocation EndLoc =
T.getCloseLocation();
3175 if (ArgExprs.empty() || ArgExprs.size() > 3) {
3176 Diag(KwLoc, diag::err_ptrauth_qualifier_bad_arg_count);
3180 Attrs.
addNew(KwName, SourceRange(KwLoc, EndLoc), AttributeScopeInfo(),
3181 ArgExprs.data(), ArgExprs.size(),
3182 ParsedAttr::Form::Keyword(
false,
3192 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3197 if (Tok.is(tok::r_paren)) {
3198 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
3205 using ExpressionKind =
3207 EnterExpressionEvaluationContext EC(
3209 ExpressionKind::EK_AttrArgument);
3217 ArgExprs.push_back(ArgExpr.
get());
3220 ASTContext &Ctx = Actions.getASTContext();
3226 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
3227 AttributeScopeInfo(), ArgExprs.data(), ArgExprs.size(), Form);
3230ExprResult Parser::ParseExtIntegerArgument() {
3231 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3232 "Not an extended int type");
3236 if (
T.expectAndConsume())
3245 if(
T.consumeClose())
3252 DeclSpecContext DSContext,
3253 LateParsedAttrList *LateAttrs) {
3256 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3257 DSContext == DeclSpecContext::DSC_top_level);
3260 Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
3261 tok::annot_template_id) &&
3267 bool HasScope = Tok.is(tok::annot_cxxscope);
3269 Token AfterScope = HasScope ?
NextToken() : Tok;
3273 bool MightBeDeclarator =
true;
3274 if (Tok.isOneOf(tok::kw_typename, tok::annot_typename)) {
3276 MightBeDeclarator =
false;
3277 }
else if (AfterScope.
is(tok::annot_template_id)) {
3280 TemplateIdAnnotation *Annot =
3283 MightBeDeclarator =
false;
3284 }
else if (AfterScope.
is(tok::identifier)) {
3289 if (
Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3290 tok::annot_cxxscope, tok::coloncolon)) {
3292 MightBeDeclarator = false;
3293 }
else if (HasScope) {
3298 Actions.RestoreNestedNameSpecifierAnnotation(
3299 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
3301 Sema::NameClassification Classification = Actions.ClassifyName(
3304 switch (Classification.
getKind()) {
3310 llvm_unreachable(
"typo correction is not possible here");
3318 MightBeDeclarator =
false;
3333 if (MightBeDeclarator)
3336 const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
3338 diag::err_expected_after)
3349 ParsedTemplateInfo NotATemplate;
3350 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3354void Parser::ParseDeclarationSpecifiers(
3356 DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
3368 if (DSContext == DeclSpecContext::DSC_conv_operator) {
3371 DSContext = DeclSpecContext::DSC_type_specifier;
3374 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3375 DSContext == DeclSpecContext::DSC_top_level);
3376 bool AttrsLastTime =
false;
3377 ParsedAttributes attrs(AttrFactory);
3379 PrintingPolicy Policy = Actions.getPrintingPolicy();
3382 bool isStorageClass =
false;
3383 const char *PrevSpec =
nullptr;
3384 unsigned DiagID = 0;
3388 SourceLocation ConsumedEnd;
3397 if (
getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&
3400 Tok.setKind(tok::identifier);
3402 SourceLocation Loc = Tok.getLocation();
3405 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3409 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
3410 Tok.setKind(tok::identifier);
3419 bool IsTemplateSpecOrInst =
3423 switch (Tok.getKind()) {
3425 if (Tok.isRegularKeywordAttribute())
3430 ProhibitAttributes(attrs);
3433 for (
const ParsedAttr &PA : attrs) {
3434 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3435 !PA.isRegularKeywordAttribute())
3443 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3444 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3451 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3452 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3455 if (PA.getKind() == ParsedAttr::AT_LifetimeBound)
3456 Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type)
3457 << PA << PA.isRegularKeywordAttribute()
3460 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3461 << PA << PA.isRegularKeywordAttribute();
3470 DS.
Finish(Actions, Policy);
3474 case tok::kw__Alignas:
3475 diagnoseUseOfC11Keyword(Tok);
3477 case tok::kw_alignas:
3483 if (Tok.getKind() == tok::kw_alignas)
3484 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
3490 if (!isAllowedCXX11AttributeSpecifier())
3491 goto DoneWithDeclSpec;
3494 ProhibitAttributes(attrs);
3499 attrs.Range = SourceRange();
3501 ParseCXX11Attributes(attrs);
3502 AttrsLastTime =
true;
3505 case tok::code_completion: {
3509 bool AllowNonIdentifiers
3515 bool AllowNestedNameSpecifiers
3516 = DSContext == DeclSpecContext::DSC_top_level ||
3520 Actions.CodeCompletion().CodeCompleteDeclSpec(
3521 getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3527 CCC = DSContext == DeclSpecContext::DSC_class
3530 else if (DSContext == DeclSpecContext::DSC_class)
3534 else if (CurParsedObjCImpl)
3538 Actions.CodeCompletion().CodeCompleteOrdinaryName(
getCurScope(), CCC);
3542 case tok::coloncolon:
3548 goto DoneWithDeclSpec;
3550 if (Tok.is(tok::coloncolon))
3551 goto DoneWithDeclSpec;
3554 case tok::annot_cxxscope: {
3556 goto DoneWithDeclSpec;
3559 if (TemplateInfo.TemplateParams)
3561 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
3562 Tok.getAnnotationRange(),
3568 TemplateIdAnnotation *TemplateId =
Next.is(tok::annot_template_id)
3569 ? takeTemplateIdAnnotation(
Next)
3575 ConsumeAnnotationToken();
3589 if ((DSContext == DeclSpecContext::DSC_top_level ||
3590 DSContext == DeclSpecContext::DSC_class) &&
3593 isConstructorDeclarator(
false,
3600 goto DoneWithDeclSpec;
3604 ConsumeAnnotationToken();
3605 assert(Tok.is(tok::annot_template_id) &&
3606 "ParseOptionalCXXScopeSpecifier not working");
3607 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3617 ConsumeAnnotationToken();
3621 if (
Next.is(tok::annot_typename)) {
3623 ConsumeAnnotationToken();
3626 Tok.getAnnotationEndLoc(),
3627 PrevSpec, DiagID,
T, Policy);
3631 ConsumeAnnotationToken();
3635 Next.is(tok::annot_template_id) &&
3636 static_cast<TemplateIdAnnotation *
>(
Next.getAnnotationValue())
3639 ConsumeAnnotationToken();
3640 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3644 if (
Next.isNot(tok::identifier))
3645 goto DoneWithDeclSpec;
3650 if ((DSContext == DeclSpecContext::DSC_top_level ||
3651 DSContext == DeclSpecContext::DSC_class) &&
3654 isConstructorDeclarator(
false,
3658 goto DoneWithDeclSpec;
3664 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3668 false,
false,
nullptr,
3671 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3673 if (IsTemplateSpecOrInst)
3681 if (TryAnnotateTypeConstraint())
3682 goto DoneWithDeclSpec;
3683 if (Tok.isNot(tok::annot_cxxscope) ||
3687 ConsumeAnnotationToken();
3688 ParsedAttributes Attrs(AttrFactory);
3689 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3690 if (!Attrs.
empty()) {
3691 AttrsLastTime =
true;
3692 attrs.takeAllAppendingFrom(Attrs);
3696 goto DoneWithDeclSpec;
3700 ConsumeAnnotationToken();
3703 DiagID, TypeRep, Policy);
3713 case tok::annot_typename: {
3717 goto DoneWithDeclSpec;
3726 ConsumeAnnotationToken();
3731 case tok::kw___is_signed:
3743 TryKeywordIdentFallback(
true);
3746 goto DoneWithDeclSpec;
3749 case tok::kw___super:
3750 case tok::kw_decltype:
3751 case tok::identifier:
3757 goto DoneWithDeclSpec;
3763 if (!
getLangOpts().DeclSpecKeyword && Tok.is(tok::identifier) &&
3764 Tok.getIdentifierInfo()->getName() ==
"__declspec") {
3765 Diag(Loc, diag::err_ms_attributes_not_enabled);
3775 if (
T.consumeOpen()) {
3776 assert(
false &&
"Not a left paren?");
3791 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3795 if (IsTemplateSpecOrInst)
3799 if (IsTemplateSpecOrInst)
3802 goto DoneWithDeclSpec;
3805 if (!Tok.is(tok::identifier))
3810 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID,
isInvalid))
3816 goto DoneWithDeclSpec;
3818 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3819 isObjCInstancetype()) {
3820 ParsedType TypeRep = Actions.ObjC().ActOnObjCInstanceType(Loc);
3823 DiagID, TypeRep, Policy);
3835 Actions.isCurrentClassName(*Tok.getIdentifierInfo(),
getCurScope()) &&
3836 isConstructorDeclarator(
true,
3839 goto DoneWithDeclSpec;
3842 *Tok.getIdentifierInfo(), Tok.getLocation(),
getCurScope(),
nullptr,
3843 false,
false,
nullptr,
false,
false,
3844 isClassTemplateDeductionContext(DSContext));
3849 if (TryAnnotateTypeConstraint())
3850 goto DoneWithDeclSpec;
3851 if (Tok.isNot(tok::identifier))
3853 ParsedAttributes Attrs(AttrFactory);
3854 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
3855 if (!Attrs.
empty()) {
3856 AttrsLastTime =
true;
3857 attrs.takeAllAppendingFrom(Attrs);
3861 goto DoneWithDeclSpec;
3868 (DSContext == DeclSpecContext::DSC_class ||
3869 DSContext == DeclSpecContext::DSC_top_level) &&
3870 Actions.isDeductionGuideName(
getCurScope(), *Tok.getIdentifierInfo(),
3871 Tok.getLocation(), SS) &&
3872 isConstructorDeclarator(
true,
3874 goto DoneWithDeclSpec;
3877 DiagID, TypeRep, Policy);
3888 SourceLocation NewEndLoc;
3889 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3904 case tok::annot_template_id: {
3905 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
3916 TemplateId =
nullptr;
3924 tok::kw_volatile, tok::kw_restrict, tok::amp,
3926 Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
3930 TemplateId, Policy);
3934 goto DoneWithDeclSpec;
3936 if (TemplateId && !
isInvalid && Actions.CheckTypeConstraint(TemplateId))
3937 TemplateId =
nullptr;
3939 ConsumeAnnotationToken();
3940 SourceLocation AutoLoc = Tok.getLocation();
3943 if (Tracker.consumeOpen()) {
3945 Diag(Tok, diag::err_expected) << tok::l_paren;
3949 Tracker.skipToEnd();
3950 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
3955 Tracker.consumeClose();
3958 ConsumedEnd = Tok.getLocation();
3963 DiagID, TemplateId, Policy);
3966 TemplateId, Policy);
3975 goto DoneWithDeclSpec;
3983 isConstructorDeclarator(
true,
3986 goto DoneWithDeclSpec;
3991 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3996 case tok::kw___attribute:
3997 case tok::kw___declspec:
3998 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4002 case tok::kw___forceinline: {
4004 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
4005 SourceLocation AttrNameLoc = Tok.getLocation();
4007 nullptr, 0, tok::kw___forceinline);
4011 case tok::kw___unaligned:
4017 case tok::kw___ptrauth:
4021 case tok::kw___sptr:
4022 case tok::kw___uptr:
4023 case tok::kw___ptr64:
4024 case tok::kw___ptr32:
4026 case tok::kw___cdecl:
4027 case tok::kw___stdcall:
4028 case tok::kw___fastcall:
4029 case tok::kw___thiscall:
4030 case tok::kw___regcall:
4031 case tok::kw___vectorcall:
4035 case tok::kw___funcref:
4040 case tok::kw___pascal:
4045 case tok::kw___kernel:
4050 case tok::kw___noinline__:
4055 case tok::kw__Nonnull:
4056 case tok::kw__Nullable:
4057 case tok::kw__Nullable_result:
4058 case tok::kw__Null_unspecified:
4063 case tok::kw___kindof:
4065 AttributeScopeInfo(),
nullptr, 0,
4071 case tok::kw_typedef:
4073 PrevSpec, DiagID, Policy);
4074 isStorageClass =
true;
4076 case tok::kw_extern:
4078 Diag(Tok, diag::ext_thread_before) <<
"extern";
4080 PrevSpec, DiagID, Policy);
4081 isStorageClass =
true;
4083 case tok::kw___private_extern__:
4085 Loc, PrevSpec, DiagID, Policy);
4086 isStorageClass =
true;
4088 case tok::kw_static:
4090 Diag(Tok, diag::ext_thread_before) <<
"static";
4092 PrevSpec, DiagID, Policy);
4093 isStorageClass =
true;
4099 PrevSpec, DiagID, Policy);
4101 Diag(Tok, diag::ext_auto_storage_class)
4108 PrevSpec, DiagID, Policy);
4109 isStorageClass =
true;
4111 case tok::kw___auto_type:
4112 Diag(Tok, diag::ext_auto_type);
4116 case tok::kw_register:
4118 PrevSpec, DiagID, Policy);
4119 isStorageClass =
true;
4121 case tok::kw_mutable:
4123 PrevSpec, DiagID, Policy);
4124 isStorageClass =
true;
4126 case tok::kw___thread:
4129 isStorageClass =
true;
4131 case tok::kw_thread_local:
4133 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4142 Loc, PrevSpec, DiagID);
4143 isStorageClass =
true;
4145 case tok::kw__Thread_local:
4146 diagnoseUseOfC11Keyword(Tok);
4148 Loc, PrevSpec, DiagID);
4149 isStorageClass =
true;
4153 case tok::kw_inline:
4156 case tok::kw_virtual:
4160 !
getActions().getOpenCLOptions().isAvailableOption(
4162 DiagID = diag::err_openclcxx_virtual_function;
4163 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4166 DiagID = diag::err_hlsl_virtual_function;
4167 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4173 case tok::kw_explicit: {
4174 SourceLocation ExplicitLoc = Loc;
4175 SourceLocation CloseParenLoc;
4177 ConsumedEnd = ExplicitLoc;
4179 if (Tok.is(tok::l_paren)) {
4182 ? diag::warn_cxx17_compat_explicit_bool
4183 : diag::ext_explicit_bool);
4185 ExprResult ExplicitExpr(
static_cast<Expr *
>(
nullptr));
4187 Tracker.consumeOpen();
4189 EnterExpressionEvaluationContext ConstantEvaluated(
4193 ConsumedEnd = Tok.getLocation();
4194 if (ExplicitExpr.isUsable()) {
4195 CloseParenLoc = Tok.getLocation();
4196 Tracker.consumeClose();
4198 Actions.ActOnExplicitBoolSpecifier(ExplicitExpr.get());
4200 Tracker.skipToEnd();
4202 Diag(Tok.getLocation(), diag::warn_cxx20_compat_explicit_bool);
4206 ExplicitSpec, CloseParenLoc);
4209 case tok::kw__Noreturn:
4210 diagnoseUseOfC11Keyword(Tok);
4215 case tok::kw_friend:
4216 if (DSContext == DeclSpecContext::DSC_class) {
4223 DiagID = diag::err_friend_invalid_in_context;
4229 case tok::kw___module_private__:
4234 case tok::kw_constexpr:
4236 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4240 case tok::kw_consteval:
4244 case tok::kw_constinit:
4260 PrevSpec, DiagID, Policy);
4262 case tok::kw___int64:
4264 PrevSpec, DiagID, Policy);
4266 case tok::kw_signed:
4270 case tok::kw_unsigned:
4274 case tok::kw__Complex:
4276 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4280 case tok::kw__Imaginary:
4282 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4298 case tok::kw__ExtInt:
4299 case tok::kw__BitInt: {
4300 DiagnoseBitIntUse(Tok);
4305 ConsumedEnd = PrevTokLocation;
4308 case tok::kw___int128:
4316 case tok::kw___bf16:
4324 case tok::kw_double:
4328 case tok::kw__Float16:
4332 case tok::kw__Accum:
4334 "This keyword is only used when fixed point types are enabled "
4335 "with `-ffixed-point`");
4339 case tok::kw__Fract:
4341 "This keyword is only used when fixed point types are enabled "
4342 "with `-ffixed-point`");
4348 "This keyword is only used when fixed point types are enabled "
4349 "with `-ffixed-point`");
4352 case tok::kw___float128:
4356 case tok::kw___ibm128:
4360 case tok::kw_wchar_t:
4364 case tok::kw_char8_t:
4368 case tok::kw_char16_t:
4372 case tok::kw_char32_t:
4378 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4382 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4384 if (Tok.is(tok::kw_bool) &&
4388 DiagID = diag::err_bool_redeclaration;
4390 Tok.setKind(tok::identifier);
4397 case tok::kw__Decimal32:
4401 case tok::kw__Decimal64:
4405 case tok::kw__Decimal128:
4409 case tok::kw___vector:
4412 case tok::kw___pixel:
4415 case tok::kw___bool:
4420 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4423 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
4424 Tok.setKind(tok::identifier);
4425 goto DoneWithDeclSpec;
4427 DiagID = diag::err_opencl_unknown_type_specifier;
4428 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4434#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4435#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4436#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4437 case tok::kw_##ImgType##_t: \
4438 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4439 goto DoneWithDeclSpec; \
4441#include "clang/Basic/OpenCLImageTypes.def"
4442 case tok::kw___unknown_anytype:
4444 PrevSpec, DiagID, Policy);
4449 case tok::kw_struct:
4450 case tok::kw___interface:
4451 case tok::kw_union: {
4458 ParsedAttributes Attributes(AttrFactory);
4459 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
4460 EnteringContext, DSContext, Attributes);
4464 if (!Attributes.empty()) {
4465 AttrsLastTime =
true;
4466 attrs.takeAllAppendingFrom(Attributes);
4474 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
4482 case tok::kw_volatile:
4486 case tok::kw_restrict:
4492 case tok::kw_typename:
4495 goto DoneWithDeclSpec;
4497 if (!Tok.is(tok::kw_typename))
4502 case tok::kw_typeof:
4503 case tok::kw_typeof_unqual:
4504 ParseTypeofSpecifier(DS);
4507 case tok::annot_decltype:
4508 ParseDecltypeSpecifier(DS);
4511 case tok::annot_pack_indexing_type:
4512 ParsePackIndexingType(DS);
4515 case tok::annot_pragma_pack:
4519 case tok::annot_pragma_ms_pragma:
4520 HandlePragmaMSPragma();
4523 case tok::annot_pragma_ms_vtordisp:
4524 HandlePragmaMSVtorDisp();
4527 case tok::annot_pragma_ms_pointers_to_members:
4528 HandlePragmaMSPointersToMembers();
4531#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4532#include "clang/Basic/TransformTypeTraits.def"
4536 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4537 goto ParseIdentifier;
4540 case tok::kw__Atomic:
4545 diagnoseUseOfC11Keyword(Tok);
4547 ParseAtomicSpecifier(DS);
4555 case tok::kw___generic:
4560 if (!Actions.getLangOpts().OpenCLGenericAddressSpace) {
4561 DiagID = diag::err_opencl_unknown_type_specifier;
4562 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4567 case tok::kw_private:
4571 goto DoneWithDeclSpec;
4573 case tok::kw___private:
4574 case tok::kw___global:
4575 case tok::kw___local:
4576 case tok::kw___constant:
4578 case tok::kw___read_only:
4579 case tok::kw___write_only:
4580 case tok::kw___read_write:
4584 case tok::kw_groupshared:
4592#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
4593 case tok::kw_##Name: \
4594 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4597#include "clang/Basic/HLSLIntangibleTypes.def"
4604 goto DoneWithDeclSpec;
4606 SourceLocation StartLoc = Tok.getLocation();
4607 SourceLocation EndLoc;
4609 if (
Type.isUsable()) {
4611 PrevSpec, DiagID,
Type.get(),
4612 Actions.getASTContext().getPrintingPolicy()))
4613 Diag(StartLoc, DiagID) << PrevSpec;
4629 assert(PrevSpec &&
"Method did not return previous specifier!");
4632 if (DiagID == diag::ext_duplicate_declspec ||
4633 DiagID == diag::ext_warn_duplicate_declspec ||
4634 DiagID == diag::err_duplicate_declspec)
4635 Diag(Loc, DiagID) << PrevSpec
4638 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4642 Diag(Loc, DiagID) << PrevSpec;
4645 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4649 AttrsLastTime =
false;
4661 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4664 for (
auto *I : RD->decls()) {
4665 auto *VD = dyn_cast<ValueDecl>(I);
4673 for (
const auto &DD : CAT->dependent_decls()) {
4674 if (!RD->containsDecl(DD.getDecl())) {
4675 P.
Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4676 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4677 P.
Diag(DD.getDecl()->getBeginLoc(),
4678 diag::note_flexible_array_counted_by_attr_field)
4685void Parser::ParseStructDeclaration(
4688 LateParsedAttrList *LateFieldAttrs) {
4690 if (Tok.is(tok::kw___extension__)) {
4692 ExtensionRAIIObject O(Diags);
4694 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4698 ParsedAttributes Attrs(AttrFactory);
4699 MaybeParseCXX11Attributes(Attrs);
4702 ParseSpecifierQualifierList(DS);
4706 if (Tok.is(tok::semi)) {
4711 ProhibitAttributes(Attrs);
4712 RecordDecl *AnonRecord =
nullptr;
4713 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
4715 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4721 bool FirstDeclarator =
true;
4722 SourceLocation CommaLoc;
4724 ParsingFieldDeclarator DeclaratorInfo(*
this, DS, Attrs);
4725 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4728 if (!FirstDeclarator) {
4731 DiagnoseAndSkipCXX11Attributes();
4732 MaybeParseGNUAttributes(DeclaratorInfo.D);
4733 DiagnoseAndSkipCXX11Attributes();
4738 if (Tok.isNot(tok::colon)) {
4741 ParseDeclarator(DeclaratorInfo.D);
4743 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.getLocation());
4755 DeclaratorInfo.BitfieldSize = Res.
get();
4759 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
4762 Decl *
Field = FieldsCallback(DeclaratorInfo);
4764 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
4771 FirstDeclarator =
false;
4777void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs,
bool EnterScope,
4779 assert(LAs.parseSoon() &&
4780 "Attribute list should be marked for immediate parsing.");
4781 for (
auto *LA : LAs) {
4782 ParseLexedCAttribute(*LA,
EnterScope, OutAttrs);
4788void Parser::ParseLexedCAttribute(LateParsedAttribute &LA,
bool EnterScope,
4793 AttrEnd.startToken();
4794 AttrEnd.setKind(tok::eof);
4795 AttrEnd.setLocation(Tok.getLocation());
4796 AttrEnd.setEofData(LA.Toks.data());
4797 LA.Toks.push_back(AttrEnd);
4801 LA.Toks.push_back(Tok);
4802 PP.EnterTokenStream(LA.Toks,
true,
4811 ParsedAttributes Attrs(AttrFactory);
4813 assert(LA.Decls.size() <= 1 &&
4814 "late field attribute expects to have at most one declaration.");
4817 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
nullptr,
nullptr,
4818 SourceLocation(), ParsedAttr::Form::GNU(),
nullptr);
4820 for (
auto *D : LA.Decls)
4821 Actions.ActOnFinishDelayedAttribute(
getCurScope(), D, Attrs);
4825 while (Tok.isNot(tok::eof))
4829 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
4839 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl,
RecordLoc,
4840 "parsing struct/union body");
4844 if (
T.consumeOpen())
4848 Actions.ActOnTagStartDefinition(
getCurScope(), TagDecl);
4852 LateParsedAttrList LateFieldAttrs(
true,
4856 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
4857 Tok.isNot(tok::eof)) {
4861 if (Tok.is(tok::semi)) {
4867 if (Tok.isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4868 SourceLocation DeclEnd;
4869 ParseStaticAssertDeclaration(DeclEnd);
4873 if (Tok.is(tok::annot_pragma_pack)) {
4878 if (Tok.is(tok::annot_pragma_align)) {
4879 HandlePragmaAlign();
4883 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4886 ParsedAttributes Attrs(AttrFactory);
4887 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4891 if (Tok.is(tok::annot_pragma_openacc)) {
4893 ParsedAttributes Attrs(AttrFactory);
4899 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
4901 TagType, Actions.getASTContext().getPrintingPolicy());
4902 ConsumeAnnotationToken();
4906 if (!Tok.is(tok::at)) {
4907 auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
4911 FD.D.getDeclSpec().getSourceRange().getBegin(),
4912 FD.D, FD.BitfieldSize);
4918 ParsingDeclSpec DS(*
this);
4919 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
4922 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
4923 Diag(Tok, diag::err_unexpected_at);
4928 ExpectAndConsume(tok::l_paren);
4929 if (!Tok.is(tok::identifier)) {
4930 Diag(Tok, diag::err_expected) << tok::identifier;
4934 SmallVector<Decl *, 16> Fields;
4935 Actions.ObjC().ActOnDefs(
getCurScope(), TagDecl, Tok.getLocation(),
4936 Tok.getIdentifierInfo(), Fields);
4938 ExpectAndConsume(tok::r_paren);
4944 if (Tok.is(tok::r_brace)) {
4945 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
4949 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
4958 ParsedAttributes attrs(AttrFactory);
4960 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
4963 ParseLexedCAttributeList(LateFieldAttrs,
false);
4965 SmallVector<Decl *, 32> FieldDecls(TagDecl->
fields());
4968 T.getOpenLocation(),
T.getCloseLocation(), attrs);
4970 Actions.ActOnTagFinishDefinition(
getCurScope(), TagDecl,
T.getRange());
4974 const ParsedTemplateInfo &TemplateInfo,
4977 if (Tok.is(tok::code_completion)) {
4986 ParsedAttributes attrs(AttrFactory);
4987 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
4989 SourceLocation ScopedEnumKWLoc;
4990 bool IsScopedUsingClassTag =
false;
4995 : diag::ext_scoped_enum);
4996 IsScopedUsingClassTag = Tok.is(tok::kw_class);
5001 ProhibitAttributes(attrs);
5004 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5013 bool shouldDelayDiagsInTag =
5016 SuppressAccessChecks diagsFromTag(*
this, shouldDelayDiagsInTag);
5019 AllowDefiningTypeSpec AllowEnumSpecifier =
5021 bool CanBeOpaqueEnumDeclaration =
5022 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5025 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5026 CanBeOpaqueEnumDeclaration);
5034 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5039 if (Spec.
isSet() && Tok.isNot(tok::identifier)) {
5040 Diag(Tok, diag::err_expected) << tok::identifier;
5042 if (Tok.isNot(tok::l_brace)) {
5054 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
5055 Tok.isNot(tok::colon)) {
5056 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5065 IdentifierInfo *Name =
nullptr;
5066 SourceLocation NameLoc;
5067 if (Tok.is(tok::identifier)) {
5068 Name = Tok.getIdentifierInfo();
5072 if (!Name && ScopedEnumKWLoc.
isValid()) {
5075 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5076 ScopedEnumKWLoc = SourceLocation();
5077 IsScopedUsingClassTag =
false;
5082 if (shouldDelayDiagsInTag)
5083 diagsFromTag.done();
5086 SourceRange BaseRange;
5088 bool CanBeBitfield =
5092 if (Tok.is(tok::colon)) {
5117 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5121 Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
5122 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5129 DeclSpec DS(AttrFactory);
5133 DeclSpecContext::DSC_type_specifier);
5136 BaseType = Actions.ActOnTypeName(DeclaratorInfo);
5138 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5142 DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)
5145 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5149 ? diag::warn_c17_compat_enum_fixed_underlying_type
5150 : diag::ext_c23_enum_fixed_underlying_type)
5167 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5169 else if (Tok.is(tok::l_brace)) {
5171 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
5177 ScopedEnumKWLoc = SourceLocation();
5178 IsScopedUsingClassTag =
false;
5184 }
else if (!isTypeSpecifier(DSC) &&
5185 (Tok.is(tok::semi) ||
5186 (Tok.isAtStartOfLine() &&
5187 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5192 if (Tok.isNot(tok::semi)) {
5194 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5195 PP.EnterToken(Tok,
true);
5196 Tok.setKind(tok::semi);
5202 bool IsElaboratedTypeSpecifier =
5208 diagsFromTag.redelay();
5216 Diag(Tok, diag::err_enum_template);
5224 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5228 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5230 TemplateInfo.TemplateParams->size());
5235 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5251 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5253 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5254 diag::err_keyword_not_allowed,
5257 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5258 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5259 else if (ScopedEnumKWLoc.
isValid())
5260 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5264 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5266 SkipBodyInfo SkipBody;
5269 SkipBody = Actions.shouldSkipAnonEnumBody(
getCurScope(),
5274 bool IsDependent =
false;
5275 const char *PrevSpec =
nullptr;
5280 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5281 IsScopedUsingClassTag,
5282 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5283 DSC == DeclSpecContext::DSC_template_param ||
5284 DSC == DeclSpecContext::DSC_template_type_arg,
5285 OffsetOfState, &SkipBody).get();
5295 NameLoc.
isValid() ? NameLoc : StartLoc,
5296 PrevSpec, DiagID, TagDecl, Owned,
5297 Actions.getASTContext().getPrintingPolicy()))
5298 Diag(StartLoc, DiagID) << PrevSpec;
5307 Diag(Tok, diag::err_expected_type_name_after_typename);
5313 if (
Type.isInvalid()) {
5319 NameLoc.
isValid() ? NameLoc : StartLoc,
5320 PrevSpec, DiagID,
Type.get(),
5321 Actions.getASTContext().getPrintingPolicy()))
5322 Diag(StartLoc, DiagID) << PrevSpec;
5341 ParseEnumBody(StartLoc, D, &SkipBody);
5343 !Actions.ActOnDuplicateDefinition(
getCurScope(), TagDecl, SkipBody)) {
5350 NameLoc.
isValid() ? NameLoc : StartLoc,
5351 PrevSpec, DiagID, TagDecl, Owned,
5352 Actions.getASTContext().getPrintingPolicy()))
5353 Diag(StartLoc, DiagID) << PrevSpec;
5360 Actions.ActOnTagStartDefinition(
getCurScope(), EnumDecl);
5367 Diag(Tok, diag::err_empty_enum);
5369 SmallVector<Decl *, 32> EnumConstantDecls;
5370 SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
5372 Decl *LastEnumConstDecl =
nullptr;
5375 while (Tok.isNot(tok::r_brace)) {
5378 if (Tok.isNot(tok::identifier)) {
5379 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
5385 IdentifierInfo *Ident = Tok.getIdentifierInfo();
5389 ParsedAttributes attrs(AttrFactory);
5390 MaybeParseGNUAttributes(attrs);
5391 if (isAllowedCXX11AttributeSpecifier()) {
5394 ? diag::warn_cxx14_compat_ns_enum_attribute
5395 : diag::ext_ns_enum_attribute)
5397 ParseCXX11Attributes(attrs);
5400 SourceLocation EqualLoc;
5402 EnumAvailabilityDiags.emplace_back(*
this);
5404 EnterExpressionEvaluationContext ConstantEvaluated(
5413 Decl *EnumConstDecl = Actions.ActOnEnumConstant(
5414 getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
5415 EqualLoc, AssignedVal.
get(), SkipBody);
5416 EnumAvailabilityDiags.back().done();
5418 EnumConstantDecls.push_back(EnumConstDecl);
5419 LastEnumConstDecl = EnumConstDecl;
5421 if (Tok.is(tok::identifier)) {
5424 Diag(Loc, diag::err_enumerator_list_missing_comma)
5431 SourceLocation CommaLoc;
5432 if (Tok.isNot(tok::r_brace) && !
TryConsumeToken(tok::comma, CommaLoc)) {
5434 Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
5437 Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
5447 if (Tok.is(tok::r_brace) && CommaLoc.
isValid()) {
5450 diag::ext_enumerator_list_comma_cxx :
5451 diag::ext_enumerator_list_comma_c)
5454 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5464 ParsedAttributes attrs(AttrFactory);
5465 MaybeParseGNUAttributes(attrs);
5467 Actions.ActOnEnumBody(StartLoc,
T.getRange(), EnumDecl, EnumConstantDecls,
5471 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5472 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5474 EnumAvailabilityDiags[i].redelay();
5475 PD.complete(EnumConstantDecls[i]);
5479 Actions.ActOnTagFinishDefinition(
getCurScope(), EnumDecl,
T.getRange());
5484 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5485 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5489 PP.EnterToken(Tok,
true);
5490 Tok.setKind(tok::semi);
5494bool Parser::isKnownToBeTypeSpecifier(
const Token &
Tok)
const {
5495 switch (Tok.getKind()) {
5496 default:
return false;
5500 case tok::kw___int64:
5501 case tok::kw___int128:
5502 case tok::kw_signed:
5503 case tok::kw_unsigned:
5504 case tok::kw__Complex:
5505 case tok::kw__Imaginary:
5508 case tok::kw_wchar_t:
5509 case tok::kw_char8_t:
5510 case tok::kw_char16_t:
5511 case tok::kw_char32_t:
5513 case tok::kw__ExtInt:
5514 case tok::kw__BitInt:
5515 case tok::kw___bf16:
5518 case tok::kw_double:
5519 case tok::kw__Accum:
5520 case tok::kw__Fract:
5521 case tok::kw__Float16:
5522 case tok::kw___float128:
5523 case tok::kw___ibm128:
5526 case tok::kw__Decimal32:
5527 case tok::kw__Decimal64:
5528 case tok::kw__Decimal128:
5529 case tok::kw___vector:
5530#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5531#include "clang/Basic/OpenCLImageTypes.def"
5532#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5533#include "clang/Basic/HLSLIntangibleTypes.def"
5537 case tok::kw_struct:
5538 case tok::kw___interface:
5544 case tok::annot_typename:
5549bool Parser::isTypeSpecifierQualifier() {
5550 switch (Tok.getKind()) {
5551 default:
return false;
5553 case tok::identifier:
5554 if (TryAltiVecVectorToken())
5557 case tok::kw_typename:
5562 if (Tok.is(tok::identifier))
5564 return isTypeSpecifierQualifier();
5566 case tok::coloncolon:
5573 return isTypeSpecifierQualifier();
5576 case tok::kw___attribute:
5578 case tok::kw_typeof:
5579 case tok::kw_typeof_unqual:
5584 case tok::kw___int64:
5585 case tok::kw___int128:
5586 case tok::kw_signed:
5587 case tok::kw_unsigned:
5588 case tok::kw__Complex:
5589 case tok::kw__Imaginary:
5592 case tok::kw_wchar_t:
5593 case tok::kw_char8_t:
5594 case tok::kw_char16_t:
5595 case tok::kw_char32_t:
5597 case tok::kw__ExtInt:
5598 case tok::kw__BitInt:
5600 case tok::kw___bf16:
5602 case tok::kw_double:
5603 case tok::kw__Accum:
5604 case tok::kw__Fract:
5605 case tok::kw__Float16:
5606 case tok::kw___float128:
5607 case tok::kw___ibm128:
5610 case tok::kw__Decimal32:
5611 case tok::kw__Decimal64:
5612 case tok::kw__Decimal128:
5613 case tok::kw___vector:
5614#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5615#include "clang/Basic/OpenCLImageTypes.def"
5616#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5617#include "clang/Basic/HLSLIntangibleTypes.def"
5621 case tok::kw_struct:
5622 case tok::kw___interface:
5629 case tok::kw_volatile:
5630 case tok::kw_restrict:
5634 case tok::kw___unknown_anytype:
5637 case tok::annot_typename:
5644 case tok::kw___cdecl:
5645 case tok::kw___stdcall:
5646 case tok::kw___fastcall:
5647 case tok::kw___thiscall:
5648 case tok::kw___regcall:
5649 case tok::kw___vectorcall:
5651 case tok::kw___ptr64:
5652 case tok::kw___ptr32:
5653 case tok::kw___pascal:
5654 case tok::kw___unaligned:
5655 case tok::kw___ptrauth:
5657 case tok::kw__Nonnull:
5658 case tok::kw__Nullable:
5659 case tok::kw__Nullable_result:
5660 case tok::kw__Null_unspecified:
5662 case tok::kw___kindof:
5664 case tok::kw___private:
5665 case tok::kw___local:
5666 case tok::kw___global:
5667 case tok::kw___constant:
5668 case tok::kw___generic:
5669 case tok::kw___read_only:
5670 case tok::kw___read_write:
5671 case tok::kw___write_only:
5672 case tok::kw___funcref:
5675 case tok::kw_private:
5679 case tok::kw__Atomic:
5683 case tok::kw_groupshared:
5692 assert(PP.isIncrementalProcessingEnabled() &&
"Not in incremental mode");
5696 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5699 TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5700 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5701 Actions.ActOnFinishTopLevelStmtDecl(TLSD, R.get());
5703 R = Actions.ActOnNullStmt(Tok.getLocation());
5705 if (Tok.is(tok::annot_repl_input_end) &&
5706 Tok.getAnnotationValue() !=
nullptr) {
5707 ConsumeAnnotationToken();
5711 SmallVector<Decl *, 2> DeclsInGroup;
5712 DeclsInGroup.push_back(TLSD);
5715 for (Stmt *S : Stmts) {
5718 TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5719 Actions.ActOnFinishTopLevelStmtDecl(D, S);
5720 DeclsInGroup.push_back(D);
5723 return Actions.BuildDeclaratorGroup(DeclsInGroup);
5726bool Parser::isDeclarationSpecifier(
5728 bool DisambiguatingWithExpression) {
5729 switch (Tok.getKind()) {
5730 default:
return false;
5737 case tok::identifier:
5741 if (TryAltiVecVectorToken())
5744 case tok::kw_decltype:
5745 case tok::kw_typename:
5750 if (TryAnnotateTypeConstraint())
5752 if (Tok.is(tok::identifier))
5760 if (DisambiguatingWithExpression &&
5761 isStartOfObjCClassMessageMissingOpenBracket())
5764 return isDeclarationSpecifier(AllowImplicitTypename);
5766 case tok::coloncolon:
5780 case tok::kw_typedef:
5781 case tok::kw_extern:
5782 case tok::kw___private_extern__:
5783 case tok::kw_static:
5785 case tok::kw___auto_type:
5786 case tok::kw_register:
5787 case tok::kw___thread:
5788 case tok::kw_thread_local:
5789 case tok::kw__Thread_local:
5792 case tok::kw___module_private__:
5795 case tok::kw___unknown_anytype:
5800 case tok::kw___int64:
5801 case tok::kw___int128:
5802 case tok::kw_signed:
5803 case tok::kw_unsigned:
5804 case tok::kw__Complex:
5805 case tok::kw__Imaginary:
5808 case tok::kw_wchar_t:
5809 case tok::kw_char8_t:
5810 case tok::kw_char16_t:
5811 case tok::kw_char32_t:
5814 case tok::kw__ExtInt:
5815 case tok::kw__BitInt:
5817 case tok::kw___bf16:
5819 case tok::kw_double:
5820 case tok::kw__Accum:
5821 case tok::kw__Fract:
5822 case tok::kw__Float16:
5823 case tok::kw___float128:
5824 case tok::kw___ibm128:
5827 case tok::kw__Decimal32:
5828 case tok::kw__Decimal64:
5829 case tok::kw__Decimal128:
5830 case tok::kw___vector:
5834 case tok::kw_struct:
5836 case tok::kw___interface:
5842 case tok::kw_volatile:
5843 case tok::kw_restrict:
5847 case tok::kw_inline:
5848 case tok::kw_virtual:
5849 case tok::kw_explicit:
5850 case tok::kw__Noreturn:
5853 case tok::kw__Alignas:
5856 case tok::kw_friend:
5859 case tok::kw_static_assert:
5860 case tok::kw__Static_assert:
5863 case tok::kw_typeof:
5864 case tok::kw_typeof_unqual:
5867 case tok::kw___attribute:
5870 case tok::annot_decltype:
5871 case tok::annot_pack_indexing_type:
5872 case tok::kw_constexpr:
5875 case tok::kw_consteval:
5876 case tok::kw_constinit:
5879 case tok::kw__Atomic:
5882 case tok::kw_alignas:
5892 case tok::annot_typename:
5893 return !DisambiguatingWithExpression ||
5894 !isStartOfObjCClassMessageMissingOpenBracket();
5897 case tok::annot_template_id: {
5898 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
5903 return isTypeConstraintAnnotation() &&
5907 case tok::annot_cxxscope: {
5908 TemplateIdAnnotation *TemplateId =
5916 if (
NextToken().
is(tok::identifier) && TryAnnotateTypeConstraint())
5918 return isTypeConstraintAnnotation() &&
5922 case tok::kw___declspec:
5923 case tok::kw___cdecl:
5924 case tok::kw___stdcall:
5925 case tok::kw___fastcall:
5926 case tok::kw___thiscall:
5927 case tok::kw___regcall:
5928 case tok::kw___vectorcall:
5930 case tok::kw___sptr:
5931 case tok::kw___uptr:
5932 case tok::kw___ptr64:
5933 case tok::kw___ptr32:
5934 case tok::kw___forceinline:
5935 case tok::kw___pascal:
5936 case tok::kw___unaligned:
5937 case tok::kw___ptrauth:
5939 case tok::kw__Nonnull:
5940 case tok::kw__Nullable:
5941 case tok::kw__Nullable_result:
5942 case tok::kw__Null_unspecified:
5944 case tok::kw___kindof:
5946 case tok::kw___private:
5947 case tok::kw___local:
5948 case tok::kw___global:
5949 case tok::kw___constant:
5950 case tok::kw___generic:
5951 case tok::kw___read_only:
5952 case tok::kw___read_write:
5953 case tok::kw___write_only:
5954#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5955#include "clang/Basic/OpenCLImageTypes.def"
5956#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5957#include "clang/Basic/HLSLIntangibleTypes.def"
5959 case tok::kw___funcref:
5960 case tok::kw_groupshared:
5963 case tok::kw_private:
5968bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
5970 const ParsedTemplateInfo *TemplateInfo) {
5971 RevertingTentativeParsingAction TPA(*
this);
5974 if (TemplateInfo && TemplateInfo->TemplateParams)
5977 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
5984 if (Tok.is(tok::identifier)) {
5988 }
else if (Tok.is(tok::annot_template_id)) {
5989 ConsumeAnnotationToken();
5996 SkipCXX11Attributes();
5999 if (Tok.isNot(tok::l_paren)) {
6006 if (Tok.is(tok::r_paren) ||
6007 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren))) {
6013 if (isCXX11AttributeSpecifier(
false,
6020 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6022 DeclScopeObj.EnterDeclaratorScope();
6025 ParsedAttributes Attrs(AttrFactory);
6026 MaybeParseMicrosoftAttributes(Attrs);
6035 bool IsConstructor =
false;
6041 if (Tok.is(tok::kw_this)) {
6043 return isDeclarationSpecifier(ITC);
6046 if (isDeclarationSpecifier(ITC))
6047 IsConstructor =
true;
6048 else if (Tok.is(tok::identifier) ||
6049 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier))) {
6054 if (Tok.is(tok::annot_cxxscope))
6055 ConsumeAnnotationToken();
6061 switch (Tok.getKind()) {
6067 case tok::coloncolon:
6080 SkipCXX11Attributes();
6082 if (DeductionGuide) {
6084 IsConstructor = Tok.is(tok::arrow);
6087 if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
6091 IsConstructor =
true;
6093 if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {
6106 IsConstructor = IsUnqualified;
6111 IsConstructor =
true;
6115 return IsConstructor;
6118void Parser::ParseTypeQualifierListOpt(
6119 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicOrPtrauthAllowed,
6121 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6122 isAllowedCXX11AttributeSpecifier()) {
6123 ParsedAttributes Attrs(AttrFactory);
6124 ParseCXX11Attributes(Attrs);
6128 SourceLocation EndLoc;
6132 const char *PrevSpec =
nullptr;
6133 unsigned DiagID = 0;
6134 SourceLocation Loc = Tok.getLocation();
6136 switch (Tok.getKind()) {
6137 case tok::code_completion:
6139 if (CodeCompletionHandler)
6140 CodeCompletionHandler();
6142 Actions.CodeCompletion().CodeCompleteTypeQualifiers(DS);
6149 case tok::kw_volatile:
6153 case tok::kw_restrict:
6157 case tok::kw__Atomic:
6158 if (!AtomicOrPtrauthAllowed)
6159 goto DoneWithTypeQuals;
6160 diagnoseUseOfC11Keyword(Tok);
6166 case tok::kw_private:
6168 goto DoneWithTypeQuals;
6170 case tok::kw___private:
6171 case tok::kw___global:
6172 case tok::kw___local:
6173 case tok::kw___constant:
6174 case tok::kw___generic:
6175 case tok::kw___read_only:
6176 case tok::kw___write_only:
6177 case tok::kw___read_write:
6181 case tok::kw_groupshared:
6190 case tok::kw___ptrauth:
6191 if (!AtomicOrPtrauthAllowed)
6192 goto DoneWithTypeQuals;
6194 EndLoc = PrevTokLocation;
6197 case tok::kw___unaligned:
6201 case tok::kw___uptr:
6206 if (TryKeywordIdentFallback(
false))
6210 case tok::kw___sptr:
6212 case tok::kw___ptr64:
6213 case tok::kw___ptr32:
6214 case tok::kw___cdecl:
6215 case tok::kw___stdcall:
6216 case tok::kw___fastcall:
6217 case tok::kw___thiscall:
6218 case tok::kw___regcall:
6219 case tok::kw___vectorcall:
6220 if (AttrReqs & AR_DeclspecAttributesParsed) {
6224 goto DoneWithTypeQuals;
6226 case tok::kw___funcref:
6230 case tok::kw___pascal:
6231 if (AttrReqs & AR_VendorAttributesParsed) {
6235 goto DoneWithTypeQuals;
6238 case tok::kw__Nonnull:
6239 case tok::kw__Nullable:
6240 case tok::kw__Nullable_result:
6241 case tok::kw__Null_unspecified:
6246 case tok::kw___kindof:
6248 AttributeScopeInfo(),
nullptr, 0,
6253 case tok::kw___attribute:
6254 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6256 Diag(Tok, diag::err_attributes_not_allowed);
6260 if (AttrReqs & AR_GNUAttributesParsed ||
6261 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6271 DS.
Finish(Actions, Actions.getASTContext().getPrintingPolicy());
6279 assert(PrevSpec &&
"Method did not return previous specifier!");
6280 Diag(Tok, DiagID) << PrevSpec;
6289 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6290 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6296 if (Kind == tok::star || Kind == tok::caret)
6300 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6301 Lang.getOpenCLCompatibleVersion() >= 200)
6304 if (!Lang.CPlusPlus)
6307 if (Kind == tok::amp)
6315 if (Kind == tok::ampamp)
6326 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6333void Parser::ParseDeclaratorInternal(
Declarator &D,
6334 DirectDeclParseFunction DirectDeclParser) {
6335 if (Diags.hasAllExtensionsSilenced())
6342 (Tok.is(tok::coloncolon) || Tok.is(tok::kw_decltype) ||
6343 (Tok.is(tok::identifier) &&
6345 Tok.is(tok::annot_cxxscope))) {
6346 TentativeParsingAction TPA(*
this,
true);
6352 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6362 Tok.is(tok::star)) {
6366 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6367 CompoundToken::MemberPtr);
6372 DeclSpec DS(AttrFactory);
6373 ParseTypeQualifierListOpt(DS);
6377 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6378 ParseDeclaratorInternal(D, DirectDeclParser);
6392 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6402 AnnotateScopeToken(SS,
true);
6404 if (DirectDeclParser)
6405 (this->*DirectDeclParser)(D);
6413 DeclSpec DS(AttrFactory);
6414 ParseTypeQualifierListOpt(DS);
6423 if (DirectDeclParser)
6424 (this->*DirectDeclParser)(D);
6433 if (Kind == tok::star || Kind == tok::caret) {
6435 DeclSpec DS(AttrFactory);
6439 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6441 ? AR_GNUAttributesParsed
6442 : AR_GNUAttributesParsedAndRejected);
6443 ParseTypeQualifierListOpt(DS, Reqs,
true,
6448 Actions.runWithSufficientStackSpace(
6449 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6450 if (Kind == tok::star)
6464 DeclSpec DS(AttrFactory);
6468 if (Kind == tok::ampamp)
6470 diag::warn_cxx98_compat_rvalue_reference :
6471 diag::ext_rvalue_reference);
6474 ParseTypeQualifierListOpt(DS);
6483 diag::err_invalid_reference_qualifier_application) <<
"const";
6486 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6490 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6494 Actions.runWithSufficientStackSpace(
6495 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6502 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6505 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6534void Parser::ParseDirectDeclarator(
Declarator &D) {
6541 return ParseDecompositionDeclarator(D);
6555 ParseOptionalCXXScopeSpecifier(
6557 false, EnteringContext);
6572 if (Actions.ShouldEnterDeclaratorScope(
getCurScope(),
6576 DeclScopeObj.EnterDeclaratorScope();
6583 goto PastIdentifier;
6599 !Actions.containsUnexpandedParameterPacks(D) &&
6607 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6617 if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6621 bool AllowConstructorName;
6622 bool AllowDeductionGuide;
6624 AllowConstructorName =
false;
6625 AllowDeductionGuide =
false;
6629 AllowDeductionGuide =
false;
6637 SourceLocation TemplateKWLoc;
6642 true, AllowConstructorName,
6643 AllowDeductionGuide, &TemplateKWLoc,
6656 DeclScopeObj.EnterDeclaratorScope();
6663 goto PastIdentifier;
6669 diag::err_expected_unqualified_id)
6672 goto PastIdentifier;
6676 "There's a C++-specific check for tok::identifier above");
6677 assert(Tok.getIdentifierInfo() &&
"Not an identifier?");
6678 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6681 goto PastIdentifier;
6686 bool DiagnoseIdentifier =
false;
6690 DiagnoseIdentifier =
true;
6693 DiagnoseIdentifier =
6701 !isCXX11VirtSpecifier(Tok))
6703 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6704 if (DiagnoseIdentifier) {
6705 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
6709 goto PastIdentifier;
6713 if (Tok.is(tok::l_paren)) {
6718 RevertingTentativeParsingAction PA(*
this);
6723 goto PastIdentifier;
6730 ParseParenDeclarator(D);
6743 DeclScopeObj.EnterDeclaratorScope();
6754 diag::ext_abstract_pack_declarator_parens);
6756 if (Tok.getKind() == tok::annot_pragma_parser_crash)
6758 if (Tok.is(tok::l_square))
6759 return ParseMisplacedBracketDeclarator(D);
6764 !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
6765 Tok.getIdentifierInfo()->isCPlusPlusKeyword(
getLangOpts())) {
6767 diag::err_expected_member_name_or_semi_objcxx_keyword)
6768 << Tok.getIdentifierInfo()
6771 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6774 goto PastIdentifier;
6777 diag::err_expected_member_name_or_semi)
6781 if (Tok.getKind() == tok::TokenKind::kw_while) {
6782 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6784 if (Tok.isOneOf(tok::period, tok::arrow))
6785 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
6788 if (Tok.isAtStartOfLine() && Loc.
isValid())
6789 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
6793 diag::err_expected_unqualified_id)
6798 diag::err_expected_either)
6799 << tok::identifier << tok::l_paren;
6808 "Haven't past the location of the identifier yet?");
6812 MaybeParseCXX11Attributes(D);
6815 if (Tok.is(tok::l_paren)) {
6827 bool IsAmbiguous =
false;
6839 AllowImplicitTypename =
6847 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
6848 bool IsFunctionDecl =
6849 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
6850 TentativelyDeclaredIdentifiers.pop_back();
6851 if (!IsFunctionDecl)
6854 ParsedAttributes attrs(AttrFactory);
6857 if (IsFunctionDeclaration)
6858 Actions.ActOnStartFunctionDeclarationDeclarator(D,
6859 TemplateParameterDepth);
6860 ParseFunctionDeclarator(D, attrs,
T, IsAmbiguous);
6861 if (IsFunctionDeclaration)
6862 Actions.ActOnFinishFunctionDeclarationDeclarator(D);
6863 PrototypeScope.Exit();
6864 }
else if (Tok.is(tok::l_square)) {
6865 ParseBracketDeclarator(D);
6866 }
else if (Tok.isRegularKeywordAttribute()) {
6868 Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();
6873 if (!
T.consumeOpen())
6884 Diag(Tok, diag::err_requires_clause_inside_parens);
6898void Parser::ParseDecompositionDeclarator(
Declarator &D) {
6899 assert(Tok.is(tok::l_square));
6901 TentativeParsingAction PA(*
this);
6906 DiagnoseAndSkipCXX11Attributes();
6910 if (!(Tok.isOneOf(tok::identifier, tok::ellipsis) &&
6912 tok::identifier, tok::l_square, tok::ellipsis)) &&
6913 !(Tok.is(tok::r_square) &&
6916 return ParseMisplacedBracketDeclarator(D);
6919 SourceLocation PrevEllipsisLoc;
6920 SmallVector<DecompositionDeclarator::Binding, 32>
Bindings;
6921 while (Tok.isNot(tok::r_square)) {
6923 if (Tok.is(tok::comma))
6926 if (Tok.is(tok::identifier)) {
6928 Diag(EndLoc, diag::err_expected)
6931 Diag(Tok, diag::err_expected_comma_or_rsquare);
6934 SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis},
6936 if (Tok.is(tok::comma))
6938 else if (Tok.is(tok::r_square))
6943 if (isCXX11AttributeSpecifier() !=
6945 DiagnoseAndSkipCXX11Attributes();
6947 SourceLocation EllipsisLoc;
6949 if (Tok.is(tok::ellipsis)) {
6951 : diag::ext_cxx_binding_pack);
6952 if (PrevEllipsisLoc.
isValid()) {
6953 Diag(Tok, diag::err_binding_multiple_ellipses);
6954 Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
6957 EllipsisLoc = Tok.getLocation();
6958 PrevEllipsisLoc = EllipsisLoc;
6962 if (Tok.isNot(tok::identifier)) {
6963 Diag(Tok, diag::err_expected) << tok::identifier;
6967 IdentifierInfo *II = Tok.getIdentifierInfo();
6968 SourceLocation Loc = Tok.getLocation();
6971 if (Tok.is(tok::ellipsis) && !PrevEllipsisLoc.
isValid()) {
6972 DiagnoseMisplacedEllipsis(Tok.getLocation(), Loc, EllipsisLoc.
isValid(),
6974 EllipsisLoc = Tok.getLocation();
6978 ParsedAttributes Attrs(AttrFactory);
6979 if (isCXX11AttributeSpecifier() !=
6982 ? diag::warn_cxx23_compat_decl_attrs_on_binding
6983 : diag::ext_decl_attrs_on_binding);
6984 MaybeParseCXX11Attributes(Attrs);
6987 Bindings.push_back({II, Loc, std::move(Attrs), EllipsisLoc});
6990 if (Tok.isNot(tok::r_square))
6997 Diag(Tok.getLocation(), diag::ext_decomp_decl_empty);
7005 T.getCloseLocation());
7008void Parser::ParseParenDeclarator(
Declarator &D) {
7012 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7024 ParsedAttributes attrs(AttrFactory);
7025 bool RequiresArg =
false;
7026 if (Tok.is(tok::kw___attribute)) {
7027 ParseGNUAttributes(attrs);
7035 ParseMicrosoftTypeAttributes(attrs);
7038 if (Tok.is(tok::kw___pascal))
7039 ParseBorlandTypeAttributes(attrs);
7051 }
else if (Tok.is(tok::r_paren) ||
7053 Tok.is(tok::ellipsis) &&
7055 isDeclarationSpecifier(
7057 isCXX11AttributeSpecifier() !=
7077 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7082 std::move(attrs),
T.getCloseLocation());
7088 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7106 ParseFunctionDeclarator(D, attrs,
T,
false, RequiresArg);
7107 PrototypeScope.Exit();
7110void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7112 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7120 bool IsCXX11MemberFunction =
7127 Actions.CurContext->isRecord());
7128 if (!IsCXX11MemberFunction)
7148 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,
7149 IsCXX11MemberFunction);
7152void Parser::ParseFunctionDeclarator(
Declarator &D,
7157 assert(
getCurScope()->isFunctionPrototypeScope() &&
7158 "Should call from a Function scope");
7164 bool HasProto =
false;
7166 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
7168 SourceLocation EllipsisLoc;
7170 DeclSpec DS(AttrFactory);
7171 bool RefQualifierIsLValueRef =
true;
7172 SourceLocation RefQualifierLoc;
7174 SourceRange ESpecRange;
7175 SmallVector<ParsedType, 2> DynamicExceptions;
7176 SmallVector<SourceRange, 2> DynamicExceptionRanges;
7179 ParsedAttributes FnAttrs(AttrFactory);
7181 SourceLocation TrailingReturnTypeLoc;
7186 SourceLocation StartLoc, LocalEndLoc, EndLoc;
7187 SourceLocation LParenLoc, RParenLoc;
7189 StartLoc = LParenLoc;
7191 if (isFunctionDeclaratorIdentifierList()) {
7193 Diag(Tok, diag::err_argument_required_after_attribute);
7195 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7199 LocalEndLoc = RParenLoc;
7204 MaybeParseCXX11Attributes(FnAttrs);
7205 ProhibitAttributes(FnAttrs);
7207 if (Tok.isNot(tok::r_paren))
7208 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7209 else if (RequiresArg)
7210 Diag(Tok, diag::err_argument_required_after_attribute);
7221 LocalEndLoc = RParenLoc;
7230 ParseTypeQualifierListOpt(
7231 DS, AR_NoAttributesParsed,
7234 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);
7241 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7242 EndLoc = RefQualifierLoc;
7244 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7245 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7262 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
7279 ESpecType = tryParseExceptionSpecification(Delayed,
7282 DynamicExceptionRanges,
7284 ExceptionSpecTokens);
7286 EndLoc = ESpecRange.
getEnd();
7290 MaybeParseCXX11Attributes(FnAttrs);
7293 LocalEndLoc = EndLoc;
7295 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7298 LocalEndLoc = Tok.getLocation();
7300 TrailingReturnType =
7302 TrailingReturnTypeLoc =
Range.getBegin();
7303 EndLoc =
Range.getEnd();
7306 MaybeParseCXX11Attributes(FnAttrs);
7314 SmallVector<NamedDecl *, 0> DeclsInPrototype;
7317 NamedDecl *ND = dyn_cast<NamedDecl>(D);
7320 DeclsInPrototype.push_back(ND);
7327 llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) {
7335 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7336 ParamInfo.size(), EllipsisLoc, RParenLoc,
7337 RefQualifierIsLValueRef, RefQualifierLoc,
7339 ESpecType, ESpecRange, DynamicExceptions.data(),
7340 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7341 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7342 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7343 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7345 std::move(FnAttrs), EndLoc);
7348bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7350 if (Tok.isOneOf(tok::amp, tok::ampamp)) {
7352 diag::warn_cxx98_compat_ref_qualifier :
7353 diag::ext_ref_qualifier);
7355 RefQualifierIsLValueRef = Tok.is(tok::amp);
7362bool Parser::isFunctionDeclaratorIdentifierList() {
7364 && Tok.is(tok::identifier)
7365 && !TryAltiVecVectorToken()
7381 && (!Tok.is(tok::eof) &&
7385void Parser::ParseFunctionDeclaratorIdentifierList(
7389 assert(!
getLangOpts().requiresStrictPrototypes() &&
7390 "Cannot parse an identifier list in C23 or C++");
7397 Diag(Tok, diag::ext_ident_list_in_param);
7400 llvm::SmallPtrSet<const IdentifierInfo *, 16> ParamsSoFar;
7404 if (Tok.isNot(tok::identifier)) {
7405 Diag(Tok, diag::err_expected) << tok::identifier;
7412 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
7415 if (Actions.getTypeName(*ParmII, Tok.getLocation(),
getCurScope()))
7416 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7419 if (!ParamsSoFar.insert(ParmII).second) {
7420 Diag(Tok, diag::err_param_redefinition) << ParmII;
7423 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7434void Parser::ParseParameterDeclarationClause(
7443 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7445 Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)
7464 IsACXXFunctionDeclaration) {
7476 DeclSpec DS(AttrFactory);
7478 ParsedAttributes ArgDeclAttrs(AttrFactory);
7479 ParsedAttributes ArgDeclSpecAttrs(AttrFactory);
7486 ArgDeclSpecAttrs.takeAllPrependingFrom(FirstArgAttrs);
7489 MaybeParseCXX11Attributes(ArgDeclAttrs);
7492 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7495 SourceLocation DSStart = Tok.getLocation();
7499 SourceLocation ThisLoc;
7503 ParsedTemplateInfo TemplateInfo;
7504 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7505 DeclSpecContext::DSC_normal,
7506 nullptr, AllowImplicitTypename);
7519 ParseDeclarator(ParmDeclarator);
7522 ParmDeclarator.SetRangeBegin(ThisLoc);
7525 MaybeParseGNUAttributes(ParmDeclarator);
7529 if (Tok.is(tok::kw_requires)) {
7534 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7540 const IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
7544 std::unique_ptr<CachedTokens> DefArgToks;
7548 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7549 ParmDeclarator.getNumTypeObjects() == 0) {
7551 Diag(DSStart, diag::err_missing_param);
7558 if (Tok.is(tok::ellipsis) &&
7560 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7561 !Actions.isUnexpandedParameterPackPermitted())) &&
7562 Actions.containsUnexpandedParameterPacks(ParmDeclarator))
7563 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7582 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7583 Tok.isNot(tok::raw_identifier) && !Tok.isAnnotation() &&
7584 Tok.getIdentifierInfo() &&
7585 Tok.getIdentifierInfo()->isKeyword(
getLangOpts())) {
7586 Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok);
7595 Diag(ParmDeclarator.getBeginLoc(),
7596 diag::err_function_parameter_limit_exceeded);
7604 Actions.ActOnParamDeclarator(
getCurScope(), ParmDeclarator, ThisLoc);
7609 if (Tok.is(tok::equal)) {
7610 SourceLocation EqualLoc = Tok.getLocation();
7620 ConsumeAndStoreInitializer(*DefArgToks,
7622 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
7630 EnterExpressionEvaluationContext Eval(
7637 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7638 DefArgResult = ParseBraceInitializer();
7640 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
7641 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7642 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7651 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7656 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
7657 DefArgResult.
get());
7662 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7663 ParmDeclarator.getIdentifierLoc(),
7664 Param, std::move(DefArgToks)));
7672 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
7679 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7681 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7682 Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {
7685 SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();
7686 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7687 << ParmEllipsis.
isValid() << ParmEllipsis;
7690 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7692 Diag(ParmDeclarator.getIdentifierLoc(),
7693 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7696 << !ParmDeclarator.hasName();
7698 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7710void Parser::ParseBracketDeclarator(
Declarator &D) {
7711 if (CheckProhibitedCXX11Attribute())
7719 if (Tok.getKind() == tok::r_square) {
7721 ParsedAttributes attrs(AttrFactory);
7722 MaybeParseCXX11Attributes(attrs);
7726 T.getOpenLocation(),
7727 T.getCloseLocation()),
7728 std::move(attrs),
T.getCloseLocation());
7730 }
else if (Tok.getKind() == tok::numeric_constant &&
7737 ParsedAttributes attrs(AttrFactory);
7738 MaybeParseCXX11Attributes(attrs);
7742 T.getOpenLocation(),
7743 T.getCloseLocation()),
7744 std::move(attrs),
T.getCloseLocation());
7746 }
else if (Tok.getKind() == tok::code_completion) {
7748 Actions.CodeCompletion().CodeCompleteBracketDeclarator(
getCurScope());
7753 SourceLocation StaticLoc;
7758 DeclSpec DS(AttrFactory);
7759 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
7767 bool isStar =
false;
7778 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7779 StaticLoc = SourceLocation();
7782 }
else if (Tok.isNot(tok::r_square)) {
7799 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7800 StaticLoc = SourceLocation();
7819 isStar, NumElements.
get(),
T.getOpenLocation(),
7820 T.getCloseLocation()),
7824void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
7825 assert(Tok.is(tok::l_square) &&
"Missing opening bracket");
7828 SourceLocation StartBracketLoc = Tok.getLocation();
7832 while (Tok.is(tok::l_square)) {
7833 ParseBracketDeclarator(TempDeclarator);
7839 if (Tok.is(tok::semi))
7842 SourceLocation SuggestParenLoc = Tok.getLocation();
7845 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7850 if (TempDeclarator.getNumTypeObjects() == 0)
7854 bool NeedParens =
false;
7873 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
7879 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
7880 const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
7881 D.
AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());
7886 if (!D.
hasName() && !NeedParens)
7889 SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();
7892 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
7893 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
7896 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7901 EndLoc, CharSourceRange(BracketRange,
true))
7904 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7907 EndLoc, CharSourceRange(BracketRange,
true))
7912void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
7913 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
7914 "Not a typeof specifier");
7916 bool IsUnqual = Tok.is(tok::kw_typeof_unqual);
7917 const IdentifierInfo *II = Tok.getIdentifierInfo();
7919 Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName();
7923 bool HasParens = Tok.is(tok::l_paren);
7931 SourceRange CastRange;
7933 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);
7949 const char *PrevSpec =
nullptr;
7956 Actions.getASTContext().getPrintingPolicy()))
7957 Diag(StartLoc, DiagID) << PrevSpec;
7968 Operand = Actions.HandleExprEvaluationContextForTypeof(
Operand.get());
7974 const char *PrevSpec =
nullptr;
7981 Actions.getASTContext().getPrintingPolicy()))
7982 Diag(StartLoc, DiagID) << PrevSpec;
7985void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
7986 assert(Tok.is(tok::kw__Atomic) &&
NextToken().
is(tok::l_paren) &&
7987 "Not an atomic specifier");
7991 if (
T.consumeOpen())
7995 if (
Result.isInvalid()) {
8003 if (
T.getCloseLocation().isInvalid())
8009 const char *PrevSpec =
nullptr;
8013 Actions.getASTContext().getPrintingPolicy()))
8014 Diag(StartLoc, DiagID) << PrevSpec;
8017bool Parser::TryAltiVecVectorTokenOutOfLine() {
8019 switch (
Next.getKind()) {
8020 default:
return false;
8023 case tok::kw_signed:
8024 case tok::kw_unsigned:
8029 case tok::kw_double:
8032 case tok::kw___bool:
8033 case tok::kw___pixel:
8034 Tok.setKind(tok::kw___vector);
8036 case tok::identifier:
8037 if (
Next.getIdentifierInfo() == Ident_pixel) {
8038 Tok.setKind(tok::kw___vector);
8041 if (
Next.getIdentifierInfo() == Ident_bool ||
8042 Next.getIdentifierInfo() == Ident_Bool) {
8043 Tok.setKind(tok::kw___vector);
8051 const char *&PrevSpec,
unsigned &DiagID,
8053 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
8054 if (Tok.getIdentifierInfo() == Ident_vector) {
8056 switch (
Next.getKind()) {
8059 case tok::kw_signed:
8060 case tok::kw_unsigned:
8065 case tok::kw_double:
8068 case tok::kw___bool:
8069 case tok::kw___pixel:
8072 case tok::identifier:
8073 if (
Next.getIdentifierInfo() == Ident_pixel) {
8077 if (
Next.getIdentifierInfo() == Ident_bool ||
8078 Next.getIdentifierInfo() == Ident_Bool) {
8087 }
else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
8091 }
else if ((Tok.getIdentifierInfo() == Ident_bool) &&
8099TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8102 SmallVector<Token, 4> Tokens;
8105 auto &SourceMgr = PP.getSourceManager();
8106 FileID FID = SourceMgr.createFileID(
8107 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8111 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8112 L.setParsingPreprocessorDirective(
true);
8118 Tokens.push_back(Tok);
8119 }
while (Tok.isNot(tok::eod));
8124 Token &EndToken = Tokens.back();
8131 Tokens.push_back(Tok);
8134 PP.EnterTokenStream(Tokens,
false,
8149 (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {
8150 Diag(Tok.getLocation(), diag::err_type_unparsed);
8155 while (Tok.isNot(tok::eof))
8159 if (Tok.is(tok::eof) && Tok.getEofData() == TypeStr.data())
8164void Parser::DiagnoseBitIntUse(
const Token &
Tok) {
8168 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8169 "expected either an _ExtInt or _BitInt token!");
8171 SourceLocation Loc = Tok.getLocation();
8172 if (Tok.is(tok::kw__ExtInt)) {
8173 Diag(Loc, diag::warn_ext_int_deprecated)
8179 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.
U cast(CodeGen::Address addr)
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
ActionResult< Expr * > ExprResult
@ Parens
New-expression has a C++98 paren-delimited initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_None
no exception specification
ActionResult< Stmt * > StmtResult
VersionTuple Version
The version number at which the change occurred.
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
SourceRange VersionRange
The source range covering the version number.
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
static DeclaratorChunk 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