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:
4252 Diag(Tok, diag::err_unknown_typename) << Tok.getName();
4256 goto DoneWithDeclSpec;
4267 PrevSpec, DiagID, Policy);
4269 case tok::kw___int64:
4271 PrevSpec, DiagID, Policy);
4273 case tok::kw_signed:
4277 case tok::kw_unsigned:
4281 case tok::kw__Complex:
4283 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4287 case tok::kw__Imaginary:
4289 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4305 case tok::kw__ExtInt:
4306 case tok::kw__BitInt: {
4307 DiagnoseBitIntUse(Tok);
4312 ConsumedEnd = PrevTokLocation;
4315 case tok::kw___int128:
4323 case tok::kw___bf16:
4331 case tok::kw_double:
4335 case tok::kw__Float16:
4339 case tok::kw__Accum:
4341 "This keyword is only used when fixed point types are enabled "
4342 "with `-ffixed-point`");
4346 case tok::kw__Fract:
4348 "This keyword is only used when fixed point types are enabled "
4349 "with `-ffixed-point`");
4355 "This keyword is only used when fixed point types are enabled "
4356 "with `-ffixed-point`");
4359 case tok::kw___float128:
4363 case tok::kw___ibm128:
4367 case tok::kw_wchar_t:
4371 case tok::kw_char8_t:
4375 case tok::kw_char16_t:
4379 case tok::kw_char32_t:
4385 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4389 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4391 if (Tok.is(tok::kw_bool) &&
4395 DiagID = diag::err_bool_redeclaration;
4397 Tok.setKind(tok::identifier);
4404 case tok::kw__Decimal32:
4408 case tok::kw__Decimal64:
4412 case tok::kw__Decimal128:
4416 case tok::kw___vector:
4419 case tok::kw___pixel:
4422 case tok::kw___bool:
4427 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4430 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
4431 Tok.setKind(tok::identifier);
4432 goto DoneWithDeclSpec;
4434 DiagID = diag::err_opencl_unknown_type_specifier;
4435 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4441#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4442#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4443#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4444 case tok::kw_##ImgType##_t: \
4445 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4446 goto DoneWithDeclSpec; \
4448#include "clang/Basic/OpenCLImageTypes.def"
4449 case tok::kw___unknown_anytype:
4451 PrevSpec, DiagID, Policy);
4456 case tok::kw_struct:
4457 case tok::kw___interface:
4458 case tok::kw_union: {
4465 ParsedAttributes Attributes(AttrFactory);
4466 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
4467 EnteringContext, DSContext, Attributes);
4471 if (!Attributes.empty()) {
4472 AttrsLastTime =
true;
4473 attrs.takeAllAppendingFrom(Attributes);
4481 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
4489 case tok::kw_volatile:
4493 case tok::kw_restrict:
4499 case tok::kw_typename:
4502 goto DoneWithDeclSpec;
4504 if (!Tok.is(tok::kw_typename))
4509 case tok::kw_typeof:
4510 case tok::kw_typeof_unqual:
4511 ParseTypeofSpecifier(DS);
4514 case tok::annot_decltype:
4515 ParseDecltypeSpecifier(DS);
4518 case tok::annot_pack_indexing_type:
4519 ParsePackIndexingType(DS);
4522 case tok::annot_pragma_pack:
4526 case tok::annot_pragma_ms_pragma:
4527 HandlePragmaMSPragma();
4530 case tok::annot_pragma_ms_vtordisp:
4531 HandlePragmaMSVtorDisp();
4534 case tok::annot_pragma_ms_pointers_to_members:
4535 HandlePragmaMSPointersToMembers();
4538#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4539#include "clang/Basic/TransformTypeTraits.def"
4543 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4544 goto ParseIdentifier;
4547 case tok::kw__Atomic:
4552 diagnoseUseOfC11Keyword(Tok);
4554 ParseAtomicSpecifier(DS);
4562 case tok::kw___generic:
4567 if (!Actions.getLangOpts().OpenCLGenericAddressSpace) {
4568 DiagID = diag::err_opencl_unknown_type_specifier;
4569 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4574 case tok::kw_private:
4578 goto DoneWithDeclSpec;
4580 case tok::kw___private:
4581 case tok::kw___global:
4582 case tok::kw___local:
4583 case tok::kw___constant:
4585 case tok::kw___read_only:
4586 case tok::kw___write_only:
4587 case tok::kw___read_write:
4591 case tok::kw_groupshared:
4599#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
4600 case tok::kw_##Name: \
4601 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4604#include "clang/Basic/HLSLIntangibleTypes.def"
4611 goto DoneWithDeclSpec;
4613 SourceLocation StartLoc = Tok.getLocation();
4614 SourceLocation EndLoc;
4616 if (
Type.isUsable()) {
4618 PrevSpec, DiagID,
Type.get(),
4619 Actions.getASTContext().getPrintingPolicy()))
4620 Diag(StartLoc, DiagID) << PrevSpec;
4636 assert(PrevSpec &&
"Method did not return previous specifier!");
4639 if (DiagID == diag::ext_duplicate_declspec ||
4640 DiagID == diag::ext_warn_duplicate_declspec ||
4641 DiagID == diag::err_duplicate_declspec)
4642 Diag(Loc, DiagID) << PrevSpec
4645 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4649 Diag(Loc, DiagID) << PrevSpec;
4652 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4656 AttrsLastTime =
false;
4668 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4671 for (
auto *I : RD->decls()) {
4672 auto *VD = dyn_cast<ValueDecl>(I);
4680 for (
const auto &DD : CAT->dependent_decls()) {
4681 if (!RD->containsDecl(DD.getDecl())) {
4682 P.
Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4683 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4684 P.
Diag(DD.getDecl()->getBeginLoc(),
4685 diag::note_flexible_array_counted_by_attr_field)
4692void Parser::ParseStructDeclaration(
4695 LateParsedAttrList *LateFieldAttrs) {
4697 if (Tok.is(tok::kw___extension__)) {
4699 ExtensionRAIIObject O(Diags);
4701 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4705 ParsedAttributes Attrs(AttrFactory);
4706 MaybeParseCXX11Attributes(Attrs);
4709 ParseSpecifierQualifierList(DS);
4713 if (Tok.is(tok::semi)) {
4718 ProhibitAttributes(Attrs);
4719 RecordDecl *AnonRecord =
nullptr;
4720 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
4722 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4728 bool FirstDeclarator =
true;
4729 SourceLocation CommaLoc;
4731 ParsingFieldDeclarator DeclaratorInfo(*
this, DS, Attrs);
4732 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4735 if (!FirstDeclarator) {
4738 DiagnoseAndSkipCXX11Attributes();
4739 MaybeParseGNUAttributes(DeclaratorInfo.D);
4740 DiagnoseAndSkipCXX11Attributes();
4745 if (Tok.isNot(tok::colon)) {
4748 ParseDeclarator(DeclaratorInfo.D);
4750 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.getLocation());
4762 DeclaratorInfo.BitfieldSize = Res.
get();
4766 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
4769 Decl *
Field = FieldsCallback(DeclaratorInfo);
4771 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
4778 FirstDeclarator =
false;
4784void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs,
bool EnterScope,
4786 assert(LAs.parseSoon() &&
4787 "Attribute list should be marked for immediate parsing.");
4788 for (
auto *LA : LAs) {
4789 ParseLexedCAttribute(*LA,
EnterScope, OutAttrs);
4795void Parser::ParseLexedCAttribute(LateParsedAttribute &LA,
bool EnterScope,
4800 AttrEnd.startToken();
4801 AttrEnd.setKind(tok::eof);
4802 AttrEnd.setLocation(Tok.getLocation());
4803 AttrEnd.setEofData(LA.Toks.data());
4804 LA.Toks.push_back(AttrEnd);
4808 LA.Toks.push_back(Tok);
4809 PP.EnterTokenStream(LA.Toks,
true,
4818 ParsedAttributes Attrs(AttrFactory);
4820 assert(LA.Decls.size() <= 1 &&
4821 "late field attribute expects to have at most one declaration.");
4824 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
nullptr,
nullptr,
4825 SourceLocation(), ParsedAttr::Form::GNU(),
nullptr);
4827 for (
auto *D : LA.Decls)
4828 Actions.ActOnFinishDelayedAttribute(
getCurScope(), D, Attrs);
4832 while (Tok.isNot(tok::eof))
4836 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
4846 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl,
RecordLoc,
4847 "parsing struct/union body");
4851 if (
T.consumeOpen())
4855 Actions.ActOnTagStartDefinition(
getCurScope(), TagDecl);
4859 LateParsedAttrList LateFieldAttrs(
true,
4863 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
4864 Tok.isNot(tok::eof)) {
4868 if (Tok.is(tok::semi)) {
4874 if (Tok.isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4875 SourceLocation DeclEnd;
4876 ParseStaticAssertDeclaration(DeclEnd);
4880 if (Tok.is(tok::annot_pragma_pack)) {
4885 if (Tok.is(tok::annot_pragma_align)) {
4886 HandlePragmaAlign();
4890 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4893 ParsedAttributes Attrs(AttrFactory);
4894 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4898 if (Tok.is(tok::annot_pragma_openacc)) {
4900 ParsedAttributes Attrs(AttrFactory);
4906 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
4908 TagType, Actions.getASTContext().getPrintingPolicy());
4909 ConsumeAnnotationToken();
4913 if (!Tok.is(tok::at)) {
4914 auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
4918 FD.D.getDeclSpec().getSourceRange().getBegin(),
4919 FD.D, FD.BitfieldSize);
4925 ParsingDeclSpec DS(*
this);
4926 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
4929 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
4930 Diag(Tok, diag::err_unexpected_at);
4935 ExpectAndConsume(tok::l_paren);
4936 if (!Tok.is(tok::identifier)) {
4937 Diag(Tok, diag::err_expected) << tok::identifier;
4941 SmallVector<Decl *, 16> Fields;
4942 Actions.ObjC().ActOnDefs(
getCurScope(), TagDecl, Tok.getLocation(),
4943 Tok.getIdentifierInfo(), Fields);
4945 ExpectAndConsume(tok::r_paren);
4951 if (Tok.is(tok::r_brace)) {
4952 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
4956 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
4965 ParsedAttributes attrs(AttrFactory);
4967 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
4970 ParseLexedCAttributeList(LateFieldAttrs,
false);
4972 SmallVector<Decl *, 32> FieldDecls(TagDecl->
fields());
4975 T.getOpenLocation(),
T.getCloseLocation(), attrs);
4977 Actions.ActOnTagFinishDefinition(
getCurScope(), TagDecl,
T.getRange());
4981 const ParsedTemplateInfo &TemplateInfo,
4984 if (Tok.is(tok::code_completion)) {
4993 ParsedAttributes attrs(AttrFactory);
4994 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
4996 SourceLocation ScopedEnumKWLoc;
4997 bool IsScopedUsingClassTag =
false;
5002 : diag::ext_scoped_enum);
5003 IsScopedUsingClassTag = Tok.is(tok::kw_class);
5008 ProhibitAttributes(attrs);
5011 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5020 bool shouldDelayDiagsInTag =
5023 SuppressAccessChecks diagsFromTag(*
this, shouldDelayDiagsInTag);
5026 AllowDefiningTypeSpec AllowEnumSpecifier =
5028 bool CanBeOpaqueEnumDeclaration =
5029 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5032 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5033 CanBeOpaqueEnumDeclaration);
5041 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5046 if (Spec.
isSet() && Tok.isNot(tok::identifier)) {
5047 Diag(Tok, diag::err_expected) << tok::identifier;
5049 if (Tok.isNot(tok::l_brace)) {
5061 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
5062 Tok.isNot(tok::colon)) {
5063 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5072 IdentifierInfo *Name =
nullptr;
5073 SourceLocation NameLoc;
5074 if (Tok.is(tok::identifier)) {
5075 Name = Tok.getIdentifierInfo();
5079 if (!Name && ScopedEnumKWLoc.
isValid()) {
5082 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5083 ScopedEnumKWLoc = SourceLocation();
5084 IsScopedUsingClassTag =
false;
5089 if (shouldDelayDiagsInTag)
5090 diagsFromTag.done();
5093 SourceRange BaseRange;
5095 bool CanBeBitfield =
5099 if (Tok.is(tok::colon)) {
5124 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5128 Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
5129 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5136 DeclSpec DS(AttrFactory);
5140 DeclSpecContext::DSC_type_specifier);
5143 BaseType = Actions.ActOnTypeName(DeclaratorInfo);
5145 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5149 DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)
5152 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5156 ? diag::warn_c17_compat_enum_fixed_underlying_type
5157 : diag::ext_c23_enum_fixed_underlying_type)
5174 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5176 else if (Tok.is(tok::l_brace)) {
5178 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
5184 ScopedEnumKWLoc = SourceLocation();
5185 IsScopedUsingClassTag =
false;
5191 }
else if (!isTypeSpecifier(DSC) &&
5192 (Tok.is(tok::semi) ||
5193 (Tok.isAtStartOfLine() &&
5194 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5199 if (Tok.isNot(tok::semi)) {
5201 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5202 PP.EnterToken(Tok,
true);
5203 Tok.setKind(tok::semi);
5209 bool IsElaboratedTypeSpecifier =
5215 diagsFromTag.redelay();
5223 Diag(Tok, diag::err_enum_template);
5231 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5235 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5237 TemplateInfo.TemplateParams->size());
5242 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5258 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5260 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5261 diag::err_keyword_not_allowed,
5264 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5265 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5266 else if (ScopedEnumKWLoc.
isValid())
5267 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5271 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5273 SkipBodyInfo SkipBody;
5276 SkipBody = Actions.shouldSkipAnonEnumBody(
getCurScope(),
5281 bool IsDependent =
false;
5282 const char *PrevSpec =
nullptr;
5287 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5288 IsScopedUsingClassTag,
5289 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5290 DSC == DeclSpecContext::DSC_template_param ||
5291 DSC == DeclSpecContext::DSC_template_type_arg,
5292 OffsetOfState, &SkipBody).get();
5302 NameLoc.
isValid() ? NameLoc : StartLoc,
5303 PrevSpec, DiagID, TagDecl, Owned,
5304 Actions.getASTContext().getPrintingPolicy()))
5305 Diag(StartLoc, DiagID) << PrevSpec;
5314 Diag(Tok, diag::err_expected_type_name_after_typename);
5320 if (
Type.isInvalid()) {
5326 NameLoc.
isValid() ? NameLoc : StartLoc,
5327 PrevSpec, DiagID,
Type.get(),
5328 Actions.getASTContext().getPrintingPolicy()))
5329 Diag(StartLoc, DiagID) << PrevSpec;
5348 ParseEnumBody(StartLoc, D, &SkipBody);
5350 !Actions.ActOnDuplicateDefinition(
getCurScope(), TagDecl, SkipBody)) {
5357 NameLoc.
isValid() ? NameLoc : StartLoc,
5358 PrevSpec, DiagID, TagDecl, Owned,
5359 Actions.getASTContext().getPrintingPolicy()))
5360 Diag(StartLoc, DiagID) << PrevSpec;
5367 Actions.ActOnTagStartDefinition(
getCurScope(), EnumDecl);
5375 Diag(
T.getOpenLocation(), diag::ext_ms_c_empty_enum_type)
5376 << SourceRange(
T.getOpenLocation(), Tok.getLocation());
5378 Diag(Tok, diag::err_empty_enum);
5381 SmallVector<Decl *, 32> EnumConstantDecls;
5382 SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
5384 Decl *LastEnumConstDecl =
nullptr;
5387 while (Tok.isNot(tok::r_brace)) {
5390 if (Tok.isNot(tok::identifier)) {
5391 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
5397 IdentifierInfo *Ident = Tok.getIdentifierInfo();
5401 ParsedAttributes attrs(AttrFactory);
5402 MaybeParseGNUAttributes(attrs);
5403 if (isAllowedCXX11AttributeSpecifier()) {
5406 ? diag::warn_cxx14_compat_ns_enum_attribute
5407 : diag::ext_ns_enum_attribute)
5409 ParseCXX11Attributes(attrs);
5412 SourceLocation EqualLoc;
5414 EnumAvailabilityDiags.emplace_back(*
this);
5416 EnterExpressionEvaluationContext ConstantEvaluated(
5425 Decl *EnumConstDecl = Actions.ActOnEnumConstant(
5426 getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
5427 EqualLoc, AssignedVal.
get(), SkipBody);
5428 EnumAvailabilityDiags.back().done();
5430 EnumConstantDecls.push_back(EnumConstDecl);
5431 LastEnumConstDecl = EnumConstDecl;
5433 if (Tok.is(tok::identifier)) {
5436 Diag(Loc, diag::err_enumerator_list_missing_comma)
5443 SourceLocation CommaLoc;
5444 if (Tok.isNot(tok::r_brace) && !
TryConsumeToken(tok::comma, CommaLoc)) {
5446 Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
5449 Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
5459 if (Tok.is(tok::r_brace) && CommaLoc.
isValid()) {
5462 diag::ext_enumerator_list_comma_cxx :
5463 diag::ext_enumerator_list_comma_c)
5466 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5476 ParsedAttributes attrs(AttrFactory);
5477 MaybeParseGNUAttributes(attrs);
5479 Actions.ActOnEnumBody(StartLoc,
T.getRange(), EnumDecl, EnumConstantDecls,
5483 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5484 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5486 EnumAvailabilityDiags[i].redelay();
5487 PD.complete(EnumConstantDecls[i]);
5491 Actions.ActOnTagFinishDefinition(
getCurScope(), EnumDecl,
T.getRange());
5496 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5497 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5501 PP.EnterToken(Tok,
true);
5502 Tok.setKind(tok::semi);
5506bool Parser::isKnownToBeTypeSpecifier(
const Token &
Tok)
const {
5507 switch (Tok.getKind()) {
5508 default:
return false;
5512 case tok::kw___int64:
5513 case tok::kw___int128:
5514 case tok::kw_signed:
5515 case tok::kw_unsigned:
5516 case tok::kw__Complex:
5517 case tok::kw__Imaginary:
5520 case tok::kw_wchar_t:
5521 case tok::kw_char8_t:
5522 case tok::kw_char16_t:
5523 case tok::kw_char32_t:
5525 case tok::kw__ExtInt:
5526 case tok::kw__BitInt:
5527 case tok::kw___bf16:
5530 case tok::kw_double:
5531 case tok::kw__Accum:
5532 case tok::kw__Fract:
5533 case tok::kw__Float16:
5534 case tok::kw___float128:
5535 case tok::kw___ibm128:
5538 case tok::kw__Decimal32:
5539 case tok::kw__Decimal64:
5540 case tok::kw__Decimal128:
5541 case tok::kw___vector:
5542#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5543#include "clang/Basic/OpenCLImageTypes.def"
5544#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5545#include "clang/Basic/HLSLIntangibleTypes.def"
5549 case tok::kw_struct:
5550 case tok::kw___interface:
5556 case tok::annot_typename:
5561bool Parser::isTypeSpecifierQualifier() {
5562 switch (Tok.getKind()) {
5563 default:
return false;
5565 case tok::identifier:
5566 if (TryAltiVecVectorToken())
5569 case tok::kw_typename:
5574 if (Tok.is(tok::identifier))
5576 return isTypeSpecifierQualifier();
5578 case tok::coloncolon:
5585 return isTypeSpecifierQualifier();
5588 case tok::kw___attribute:
5590 case tok::kw_typeof:
5591 case tok::kw_typeof_unqual:
5596 case tok::kw___int64:
5597 case tok::kw___int128:
5598 case tok::kw_signed:
5599 case tok::kw_unsigned:
5600 case tok::kw__Complex:
5601 case tok::kw__Imaginary:
5604 case tok::kw_wchar_t:
5605 case tok::kw_char8_t:
5606 case tok::kw_char16_t:
5607 case tok::kw_char32_t:
5609 case tok::kw__ExtInt:
5610 case tok::kw__BitInt:
5612 case tok::kw___bf16:
5614 case tok::kw_double:
5615 case tok::kw__Accum:
5616 case tok::kw__Fract:
5617 case tok::kw__Float16:
5618 case tok::kw___float128:
5619 case tok::kw___ibm128:
5622 case tok::kw__Decimal32:
5623 case tok::kw__Decimal64:
5624 case tok::kw__Decimal128:
5625 case tok::kw___vector:
5626#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5627#include "clang/Basic/OpenCLImageTypes.def"
5628#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5629#include "clang/Basic/HLSLIntangibleTypes.def"
5633 case tok::kw_struct:
5634 case tok::kw___interface:
5641 case tok::kw_volatile:
5642 case tok::kw_restrict:
5646 case tok::kw___unknown_anytype:
5649 case tok::annot_typename:
5656 case tok::kw___cdecl:
5657 case tok::kw___stdcall:
5658 case tok::kw___fastcall:
5659 case tok::kw___thiscall:
5660 case tok::kw___regcall:
5661 case tok::kw___vectorcall:
5663 case tok::kw___ptr64:
5664 case tok::kw___ptr32:
5665 case tok::kw___pascal:
5666 case tok::kw___unaligned:
5667 case tok::kw___ptrauth:
5669 case tok::kw__Nonnull:
5670 case tok::kw__Nullable:
5671 case tok::kw__Nullable_result:
5672 case tok::kw__Null_unspecified:
5674 case tok::kw___kindof:
5676 case tok::kw___private:
5677 case tok::kw___local:
5678 case tok::kw___global:
5679 case tok::kw___constant:
5680 case tok::kw___generic:
5681 case tok::kw___read_only:
5682 case tok::kw___read_write:
5683 case tok::kw___write_only:
5684 case tok::kw___funcref:
5687 case tok::kw_private:
5691 case tok::kw__Atomic:
5695 case tok::kw_groupshared:
5704 assert(PP.isIncrementalProcessingEnabled() &&
"Not in incremental mode");
5708 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5711 TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5712 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5713 Actions.ActOnFinishTopLevelStmtDecl(TLSD, R.get());
5715 R = Actions.ActOnNullStmt(Tok.getLocation());
5717 if (Tok.is(tok::annot_repl_input_end) &&
5718 Tok.getAnnotationValue() !=
nullptr) {
5719 ConsumeAnnotationToken();
5723 SmallVector<Decl *, 2> DeclsInGroup;
5724 DeclsInGroup.push_back(TLSD);
5727 for (Stmt *S : Stmts) {
5730 TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5731 Actions.ActOnFinishTopLevelStmtDecl(D, S);
5732 DeclsInGroup.push_back(D);
5735 return Actions.BuildDeclaratorGroup(DeclsInGroup);
5738bool Parser::isDeclarationSpecifier(
5740 bool DisambiguatingWithExpression) {
5741 switch (Tok.getKind()) {
5742 default:
return false;
5749 case tok::identifier:
5753 if (TryAltiVecVectorToken())
5756 case tok::kw_decltype:
5757 case tok::kw_typename:
5762 if (TryAnnotateTypeConstraint())
5764 if (Tok.is(tok::identifier))
5772 if (DisambiguatingWithExpression &&
5773 isStartOfObjCClassMessageMissingOpenBracket())
5776 return isDeclarationSpecifier(AllowImplicitTypename);
5778 case tok::coloncolon:
5792 case tok::kw_typedef:
5793 case tok::kw_extern:
5794 case tok::kw___private_extern__:
5795 case tok::kw_static:
5797 case tok::kw___auto_type:
5798 case tok::kw_register:
5799 case tok::kw___thread:
5800 case tok::kw_thread_local:
5801 case tok::kw__Thread_local:
5804 case tok::kw___module_private__:
5807 case tok::kw___unknown_anytype:
5812 case tok::kw___int64:
5813 case tok::kw___int128:
5814 case tok::kw_signed:
5815 case tok::kw_unsigned:
5816 case tok::kw__Complex:
5817 case tok::kw__Imaginary:
5820 case tok::kw_wchar_t:
5821 case tok::kw_char8_t:
5822 case tok::kw_char16_t:
5823 case tok::kw_char32_t:
5826 case tok::kw__ExtInt:
5827 case tok::kw__BitInt:
5829 case tok::kw___bf16:
5831 case tok::kw_double:
5832 case tok::kw__Accum:
5833 case tok::kw__Fract:
5834 case tok::kw__Float16:
5835 case tok::kw___float128:
5836 case tok::kw___ibm128:
5839 case tok::kw__Decimal32:
5840 case tok::kw__Decimal64:
5841 case tok::kw__Decimal128:
5842 case tok::kw___vector:
5846 case tok::kw_struct:
5848 case tok::kw___interface:
5854 case tok::kw_volatile:
5855 case tok::kw_restrict:
5859 case tok::kw_inline:
5860 case tok::kw_virtual:
5861 case tok::kw_explicit:
5862 case tok::kw__Noreturn:
5865 case tok::kw__Alignas:
5868 case tok::kw_friend:
5871 case tok::kw_static_assert:
5872 case tok::kw__Static_assert:
5875 case tok::kw_typeof:
5876 case tok::kw_typeof_unqual:
5879 case tok::kw___attribute:
5882 case tok::annot_decltype:
5883 case tok::annot_pack_indexing_type:
5884 case tok::kw_constexpr:
5887 case tok::kw_consteval:
5888 case tok::kw_constinit:
5891 case tok::kw__Atomic:
5894 case tok::kw_alignas:
5904 case tok::annot_typename:
5905 return !DisambiguatingWithExpression ||
5906 !isStartOfObjCClassMessageMissingOpenBracket();
5909 case tok::annot_template_id: {
5910 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
5915 return isTypeConstraintAnnotation() &&
5919 case tok::annot_cxxscope: {
5920 TemplateIdAnnotation *TemplateId =
5928 if (
NextToken().
is(tok::identifier) && TryAnnotateTypeConstraint())
5930 return isTypeConstraintAnnotation() &&
5934 case tok::kw___declspec:
5935 case tok::kw___cdecl:
5936 case tok::kw___stdcall:
5937 case tok::kw___fastcall:
5938 case tok::kw___thiscall:
5939 case tok::kw___regcall:
5940 case tok::kw___vectorcall:
5942 case tok::kw___sptr:
5943 case tok::kw___uptr:
5944 case tok::kw___ptr64:
5945 case tok::kw___ptr32:
5946 case tok::kw___forceinline:
5947 case tok::kw___pascal:
5948 case tok::kw___unaligned:
5949 case tok::kw___ptrauth:
5951 case tok::kw__Nonnull:
5952 case tok::kw__Nullable:
5953 case tok::kw__Nullable_result:
5954 case tok::kw__Null_unspecified:
5956 case tok::kw___kindof:
5958 case tok::kw___private:
5959 case tok::kw___local:
5960 case tok::kw___global:
5961 case tok::kw___constant:
5962 case tok::kw___generic:
5963 case tok::kw___read_only:
5964 case tok::kw___read_write:
5965 case tok::kw___write_only:
5966#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5967#include "clang/Basic/OpenCLImageTypes.def"
5968#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5969#include "clang/Basic/HLSLIntangibleTypes.def"
5971 case tok::kw___funcref:
5972 case tok::kw_groupshared:
5975 case tok::kw_private:
5980bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
5982 const ParsedTemplateInfo *TemplateInfo) {
5983 RevertingTentativeParsingAction TPA(*
this);
5986 if (TemplateInfo && TemplateInfo->TemplateParams)
5989 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
5996 if (Tok.is(tok::identifier)) {
6000 }
else if (Tok.is(tok::annot_template_id)) {
6001 ConsumeAnnotationToken();
6008 SkipCXX11Attributes();
6011 if (Tok.isNot(tok::l_paren)) {
6018 if (Tok.is(tok::r_paren) ||
6019 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren))) {
6025 if (isCXX11AttributeSpecifier(
false,
6032 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6034 DeclScopeObj.EnterDeclaratorScope();
6037 ParsedAttributes Attrs(AttrFactory);
6038 MaybeParseMicrosoftAttributes(Attrs);
6047 bool IsConstructor =
false;
6053 if (Tok.is(tok::kw_this)) {
6055 return isDeclarationSpecifier(ITC);
6058 if (isDeclarationSpecifier(ITC))
6059 IsConstructor =
true;
6060 else if (Tok.is(tok::identifier) ||
6061 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier))) {
6066 if (Tok.is(tok::annot_cxxscope))
6067 ConsumeAnnotationToken();
6073 switch (Tok.getKind()) {
6079 case tok::coloncolon:
6092 SkipCXX11Attributes();
6094 if (DeductionGuide) {
6096 IsConstructor = Tok.is(tok::arrow);
6099 if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
6103 IsConstructor =
true;
6105 if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {
6118 IsConstructor = IsUnqualified;
6123 IsConstructor =
true;
6127 return IsConstructor;
6130void Parser::ParseTypeQualifierListOpt(
6131 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicOrPtrauthAllowed,
6133 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6134 isAllowedCXX11AttributeSpecifier()) {
6135 ParsedAttributes Attrs(AttrFactory);
6136 ParseCXX11Attributes(Attrs);
6140 SourceLocation EndLoc;
6144 const char *PrevSpec =
nullptr;
6145 unsigned DiagID = 0;
6146 SourceLocation Loc = Tok.getLocation();
6148 switch (Tok.getKind()) {
6149 case tok::code_completion:
6151 if (CodeCompletionHandler)
6152 CodeCompletionHandler();
6154 Actions.CodeCompletion().CodeCompleteTypeQualifiers(DS);
6161 case tok::kw_volatile:
6165 case tok::kw_restrict:
6169 case tok::kw__Atomic:
6170 if (!AtomicOrPtrauthAllowed)
6171 goto DoneWithTypeQuals;
6172 diagnoseUseOfC11Keyword(Tok);
6178 case tok::kw_private:
6180 goto DoneWithTypeQuals;
6182 case tok::kw___private:
6183 case tok::kw___global:
6184 case tok::kw___local:
6185 case tok::kw___constant:
6186 case tok::kw___generic:
6187 case tok::kw___read_only:
6188 case tok::kw___write_only:
6189 case tok::kw___read_write:
6193 case tok::kw_groupshared:
6202 case tok::kw___ptrauth:
6203 if (!AtomicOrPtrauthAllowed)
6204 goto DoneWithTypeQuals;
6206 EndLoc = PrevTokLocation;
6209 case tok::kw___unaligned:
6213 case tok::kw___uptr:
6218 if (TryKeywordIdentFallback(
false))
6222 case tok::kw___sptr:
6224 case tok::kw___ptr64:
6225 case tok::kw___ptr32:
6226 case tok::kw___cdecl:
6227 case tok::kw___stdcall:
6228 case tok::kw___fastcall:
6229 case tok::kw___thiscall:
6230 case tok::kw___regcall:
6231 case tok::kw___vectorcall:
6232 if (AttrReqs & AR_DeclspecAttributesParsed) {
6236 goto DoneWithTypeQuals;
6238 case tok::kw___funcref:
6242 case tok::kw___pascal:
6243 if (AttrReqs & AR_VendorAttributesParsed) {
6247 goto DoneWithTypeQuals;
6250 case tok::kw__Nonnull:
6251 case tok::kw__Nullable:
6252 case tok::kw__Nullable_result:
6253 case tok::kw__Null_unspecified:
6258 case tok::kw___kindof:
6260 AttributeScopeInfo(),
nullptr, 0,
6265 case tok::kw___attribute:
6266 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6268 Diag(Tok, diag::err_attributes_not_allowed);
6272 if (AttrReqs & AR_GNUAttributesParsed ||
6273 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6283 DS.
Finish(Actions, Actions.getASTContext().getPrintingPolicy());
6291 assert(PrevSpec &&
"Method did not return previous specifier!");
6292 Diag(Tok, DiagID) << PrevSpec;
6301 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6302 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6308 if (Kind == tok::star || Kind == tok::caret)
6312 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6313 Lang.getOpenCLCompatibleVersion() >= 200)
6316 if (!Lang.CPlusPlus)
6319 if (Kind == tok::amp)
6327 if (Kind == tok::ampamp)
6338 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6345void Parser::ParseDeclaratorInternal(
Declarator &D,
6346 DirectDeclParseFunction DirectDeclParser) {
6347 if (Diags.hasAllExtensionsSilenced())
6354 (Tok.is(tok::coloncolon) || Tok.is(tok::kw_decltype) ||
6355 (Tok.is(tok::identifier) &&
6357 Tok.is(tok::annot_cxxscope))) {
6358 TentativeParsingAction TPA(*
this,
true);
6364 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6374 Tok.is(tok::star)) {
6378 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6379 CompoundToken::MemberPtr);
6384 DeclSpec DS(AttrFactory);
6385 ParseTypeQualifierListOpt(DS);
6389 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6390 ParseDeclaratorInternal(D, DirectDeclParser);
6404 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6414 AnnotateScopeToken(SS,
true);
6416 if (DirectDeclParser)
6417 (this->*DirectDeclParser)(D);
6425 DeclSpec DS(AttrFactory);
6426 ParseTypeQualifierListOpt(DS);
6435 if (DirectDeclParser)
6436 (this->*DirectDeclParser)(D);
6445 if (Kind == tok::star || Kind == tok::caret) {
6447 DeclSpec DS(AttrFactory);
6451 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6453 ? AR_GNUAttributesParsed
6454 : AR_GNUAttributesParsedAndRejected);
6455 ParseTypeQualifierListOpt(DS, Reqs,
true,
6460 Actions.runWithSufficientStackSpace(
6461 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6462 if (Kind == tok::star)
6476 DeclSpec DS(AttrFactory);
6480 if (Kind == tok::ampamp)
6482 diag::warn_cxx98_compat_rvalue_reference :
6483 diag::ext_rvalue_reference);
6486 ParseTypeQualifierListOpt(DS);
6495 diag::err_invalid_reference_qualifier_application) <<
"const";
6498 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6502 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6506 Actions.runWithSufficientStackSpace(
6507 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6514 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6517 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6546void Parser::ParseDirectDeclarator(
Declarator &D) {
6553 return ParseDecompositionDeclarator(D);
6567 ParseOptionalCXXScopeSpecifier(
6569 false, EnteringContext);
6584 if (Actions.ShouldEnterDeclaratorScope(
getCurScope(),
6588 DeclScopeObj.EnterDeclaratorScope();
6595 goto PastIdentifier;
6611 !Actions.containsUnexpandedParameterPacks(D) &&
6619 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6629 if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6633 bool AllowConstructorName;
6634 bool AllowDeductionGuide;
6636 AllowConstructorName =
false;
6637 AllowDeductionGuide =
false;
6641 AllowDeductionGuide =
false;
6649 SourceLocation TemplateKWLoc;
6654 true, AllowConstructorName,
6655 AllowDeductionGuide, &TemplateKWLoc,
6668 DeclScopeObj.EnterDeclaratorScope();
6675 goto PastIdentifier;
6681 diag::err_expected_unqualified_id)
6684 goto PastIdentifier;
6688 "There's a C++-specific check for tok::identifier above");
6689 assert(Tok.getIdentifierInfo() &&
"Not an identifier?");
6690 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6693 goto PastIdentifier;
6698 bool DiagnoseIdentifier =
false;
6702 DiagnoseIdentifier =
true;
6705 DiagnoseIdentifier =
6713 !isCXX11VirtSpecifier(Tok))
6715 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6716 if (DiagnoseIdentifier) {
6717 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
6721 goto PastIdentifier;
6725 if (Tok.is(tok::l_paren)) {
6730 RevertingTentativeParsingAction PA(*
this);
6735 goto PastIdentifier;
6742 ParseParenDeclarator(D);
6755 DeclScopeObj.EnterDeclaratorScope();
6766 diag::ext_abstract_pack_declarator_parens);
6768 if (Tok.getKind() == tok::annot_pragma_parser_crash)
6770 if (Tok.is(tok::l_square))
6771 return ParseMisplacedBracketDeclarator(D);
6776 !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
6777 Tok.getIdentifierInfo()->isCPlusPlusKeyword(
getLangOpts())) {
6779 diag::err_expected_member_name_or_semi_objcxx_keyword)
6780 << Tok.getIdentifierInfo()
6783 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6786 goto PastIdentifier;
6789 diag::err_expected_member_name_or_semi)
6793 if (Tok.getKind() == tok::TokenKind::kw_while) {
6794 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6796 if (Tok.isOneOf(tok::period, tok::arrow))
6797 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
6800 if (Tok.isAtStartOfLine() && Loc.
isValid())
6801 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
6805 diag::err_expected_unqualified_id)
6810 diag::err_expected_either)
6811 << tok::identifier << tok::l_paren;
6820 "Haven't past the location of the identifier yet?");
6824 MaybeParseCXX11Attributes(D);
6827 if (Tok.is(tok::l_paren)) {
6839 bool IsAmbiguous =
false;
6851 AllowImplicitTypename =
6859 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
6860 bool IsFunctionDecl =
6861 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
6862 TentativelyDeclaredIdentifiers.pop_back();
6863 if (!IsFunctionDecl)
6866 ParsedAttributes attrs(AttrFactory);
6869 if (IsFunctionDeclaration)
6870 Actions.ActOnStartFunctionDeclarationDeclarator(D,
6871 TemplateParameterDepth);
6872 ParseFunctionDeclarator(D, attrs,
T, IsAmbiguous);
6873 if (IsFunctionDeclaration)
6874 Actions.ActOnFinishFunctionDeclarationDeclarator(D);
6875 PrototypeScope.Exit();
6876 }
else if (Tok.is(tok::l_square)) {
6877 ParseBracketDeclarator(D);
6878 }
else if (Tok.isRegularKeywordAttribute()) {
6880 Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();
6885 if (!
T.consumeOpen())
6896 Diag(Tok, diag::err_requires_clause_inside_parens);
6910void Parser::ParseDecompositionDeclarator(
Declarator &D) {
6911 assert(Tok.is(tok::l_square));
6913 TentativeParsingAction PA(*
this);
6918 DiagnoseAndSkipCXX11Attributes();
6922 if (!(Tok.isOneOf(tok::identifier, tok::ellipsis) &&
6924 tok::identifier, tok::l_square, tok::ellipsis)) &&
6925 !(Tok.is(tok::r_square) &&
6928 return ParseMisplacedBracketDeclarator(D);
6931 SourceLocation PrevEllipsisLoc;
6932 SmallVector<DecompositionDeclarator::Binding, 32>
Bindings;
6933 while (Tok.isNot(tok::r_square)) {
6935 if (Tok.is(tok::comma))
6938 if (Tok.is(tok::identifier)) {
6940 Diag(EndLoc, diag::err_expected)
6943 Diag(Tok, diag::err_expected_comma_or_rsquare);
6946 SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis},
6948 if (Tok.is(tok::comma))
6950 else if (Tok.is(tok::r_square))
6955 if (isCXX11AttributeSpecifier() !=
6957 DiagnoseAndSkipCXX11Attributes();
6959 SourceLocation EllipsisLoc;
6961 if (Tok.is(tok::ellipsis)) {
6963 : diag::ext_cxx_binding_pack);
6964 if (PrevEllipsisLoc.
isValid()) {
6965 Diag(Tok, diag::err_binding_multiple_ellipses);
6966 Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
6969 EllipsisLoc = Tok.getLocation();
6970 PrevEllipsisLoc = EllipsisLoc;
6974 if (Tok.isNot(tok::identifier)) {
6975 Diag(Tok, diag::err_expected) << tok::identifier;
6979 IdentifierInfo *II = Tok.getIdentifierInfo();
6980 SourceLocation Loc = Tok.getLocation();
6983 if (Tok.is(tok::ellipsis) && !PrevEllipsisLoc.
isValid()) {
6984 DiagnoseMisplacedEllipsis(Tok.getLocation(), Loc, EllipsisLoc.
isValid(),
6986 EllipsisLoc = Tok.getLocation();
6990 ParsedAttributes Attrs(AttrFactory);
6991 if (isCXX11AttributeSpecifier() !=
6994 ? diag::warn_cxx23_compat_decl_attrs_on_binding
6995 : diag::ext_decl_attrs_on_binding);
6996 MaybeParseCXX11Attributes(Attrs);
6999 Bindings.push_back({II, Loc, std::move(Attrs), EllipsisLoc});
7002 if (Tok.isNot(tok::r_square))
7009 Diag(Tok.getLocation(), diag::ext_decomp_decl_empty);
7017 T.getCloseLocation());
7020void Parser::ParseParenDeclarator(
Declarator &D) {
7024 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7036 ParsedAttributes attrs(AttrFactory);
7037 bool RequiresArg =
false;
7038 if (Tok.is(tok::kw___attribute)) {
7039 ParseGNUAttributes(attrs);
7047 ParseMicrosoftTypeAttributes(attrs);
7050 if (Tok.is(tok::kw___pascal))
7051 ParseBorlandTypeAttributes(attrs);
7063 }
else if (Tok.is(tok::r_paren) ||
7065 Tok.is(tok::ellipsis) &&
7067 isDeclarationSpecifier(
7069 isCXX11AttributeSpecifier() !=
7089 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7094 std::move(attrs),
T.getCloseLocation());
7100 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7118 ParseFunctionDeclarator(D, attrs,
T,
false, RequiresArg);
7119 PrototypeScope.Exit();
7122void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7124 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7132 bool IsCXX11MemberFunction =
7139 Actions.CurContext->isRecord());
7140 if (!IsCXX11MemberFunction)
7160 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,
7161 IsCXX11MemberFunction);
7164void Parser::ParseFunctionDeclarator(
Declarator &D,
7169 assert(
getCurScope()->isFunctionPrototypeScope() &&
7170 "Should call from a Function scope");
7176 bool HasProto =
false;
7178 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
7180 SourceLocation EllipsisLoc;
7182 DeclSpec DS(AttrFactory);
7183 bool RefQualifierIsLValueRef =
true;
7184 SourceLocation RefQualifierLoc;
7186 SourceRange ESpecRange;
7187 SmallVector<ParsedType, 2> DynamicExceptions;
7188 SmallVector<SourceRange, 2> DynamicExceptionRanges;
7191 ParsedAttributes FnAttrs(AttrFactory);
7193 SourceLocation TrailingReturnTypeLoc;
7198 SourceLocation StartLoc, LocalEndLoc, EndLoc;
7199 SourceLocation LParenLoc, RParenLoc;
7201 StartLoc = LParenLoc;
7203 if (isFunctionDeclaratorIdentifierList()) {
7205 Diag(Tok, diag::err_argument_required_after_attribute);
7207 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7211 LocalEndLoc = RParenLoc;
7216 MaybeParseCXX11Attributes(FnAttrs);
7217 ProhibitAttributes(FnAttrs);
7219 if (Tok.isNot(tok::r_paren))
7220 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7221 else if (RequiresArg)
7222 Diag(Tok, diag::err_argument_required_after_attribute);
7233 LocalEndLoc = RParenLoc;
7242 ParseTypeQualifierListOpt(
7243 DS, AR_NoAttributesParsed,
7246 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);
7253 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7254 EndLoc = RefQualifierLoc;
7256 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7257 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7274 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
7291 ESpecType = tryParseExceptionSpecification(Delayed,
7294 DynamicExceptionRanges,
7296 ExceptionSpecTokens);
7298 EndLoc = ESpecRange.
getEnd();
7302 MaybeParseCXX11Attributes(FnAttrs);
7305 LocalEndLoc = EndLoc;
7307 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7310 LocalEndLoc = Tok.getLocation();
7312 TrailingReturnType =
7314 TrailingReturnTypeLoc =
Range.getBegin();
7315 EndLoc =
Range.getEnd();
7318 MaybeParseCXX11Attributes(FnAttrs);
7326 SmallVector<NamedDecl *, 0> DeclsInPrototype;
7329 NamedDecl *ND = dyn_cast<NamedDecl>(D);
7332 DeclsInPrototype.push_back(ND);
7339 llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) {
7347 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7348 ParamInfo.size(), EllipsisLoc, RParenLoc,
7349 RefQualifierIsLValueRef, RefQualifierLoc,
7351 ESpecType, ESpecRange, DynamicExceptions.data(),
7352 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7353 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7354 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7355 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7357 std::move(FnAttrs), EndLoc);
7360bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7362 if (Tok.isOneOf(tok::amp, tok::ampamp)) {
7364 diag::warn_cxx98_compat_ref_qualifier :
7365 diag::ext_ref_qualifier);
7367 RefQualifierIsLValueRef = Tok.is(tok::amp);
7374bool Parser::isFunctionDeclaratorIdentifierList() {
7376 && Tok.is(tok::identifier)
7377 && !TryAltiVecVectorToken()
7393 && (!Tok.is(tok::eof) &&
7397void Parser::ParseFunctionDeclaratorIdentifierList(
7401 assert(!
getLangOpts().requiresStrictPrototypes() &&
7402 "Cannot parse an identifier list in C23 or C++");
7409 Diag(Tok, diag::ext_ident_list_in_param);
7412 llvm::SmallPtrSet<const IdentifierInfo *, 16> ParamsSoFar;
7416 if (Tok.isNot(tok::identifier)) {
7417 Diag(Tok, diag::err_expected) << tok::identifier;
7424 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
7427 if (Actions.getTypeName(*ParmII, Tok.getLocation(),
getCurScope()))
7428 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7431 if (!ParamsSoFar.insert(ParmII).second) {
7432 Diag(Tok, diag::err_param_redefinition) << ParmII;
7435 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7446void Parser::ParseParameterDeclarationClause(
7455 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7457 Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)
7476 IsACXXFunctionDeclaration) {
7488 DeclSpec DS(AttrFactory);
7490 ParsedAttributes ArgDeclAttrs(AttrFactory);
7491 ParsedAttributes ArgDeclSpecAttrs(AttrFactory);
7498 ArgDeclSpecAttrs.takeAllPrependingFrom(FirstArgAttrs);
7501 MaybeParseCXX11Attributes(ArgDeclAttrs);
7504 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7507 SourceLocation DSStart = Tok.getLocation();
7511 SourceLocation ThisLoc;
7515 ParsedTemplateInfo TemplateInfo;
7516 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7517 DeclSpecContext::DSC_normal,
7518 nullptr, AllowImplicitTypename);
7531 ParseDeclarator(ParmDeclarator);
7534 ParmDeclarator.SetRangeBegin(ThisLoc);
7537 MaybeParseGNUAttributes(ParmDeclarator);
7541 if (Tok.is(tok::kw_requires)) {
7546 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7552 const IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
7556 std::unique_ptr<CachedTokens> DefArgToks;
7560 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7561 ParmDeclarator.getNumTypeObjects() == 0) {
7563 Diag(DSStart, diag::err_missing_param);
7570 if (Tok.is(tok::ellipsis) &&
7572 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7573 !Actions.isUnexpandedParameterPackPermitted())) &&
7574 Actions.containsUnexpandedParameterPacks(ParmDeclarator))
7575 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7594 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7595 Tok.isNot(tok::raw_identifier) && !Tok.isAnnotation() &&
7596 Tok.getIdentifierInfo() &&
7597 Tok.getIdentifierInfo()->isKeyword(
getLangOpts())) {
7598 Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok);
7607 Diag(ParmDeclarator.getBeginLoc(),
7608 diag::err_function_parameter_limit_exceeded);
7616 Actions.ActOnParamDeclarator(
getCurScope(), ParmDeclarator, ThisLoc);
7621 if (Tok.is(tok::equal)) {
7622 SourceLocation EqualLoc = Tok.getLocation();
7632 ConsumeAndStoreInitializer(*DefArgToks,
7634 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
7642 EnterExpressionEvaluationContext Eval(
7649 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7650 DefArgResult = ParseBraceInitializer();
7652 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
7653 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7654 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7663 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7668 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
7669 DefArgResult.
get());
7674 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7675 ParmDeclarator.getIdentifierLoc(),
7676 Param, std::move(DefArgToks)));
7684 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
7691 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7693 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7694 Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {
7697 SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();
7698 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7699 << ParmEllipsis.
isValid() << ParmEllipsis;
7702 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7704 Diag(ParmDeclarator.getIdentifierLoc(),
7705 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7708 << !ParmDeclarator.hasName();
7710 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7722void Parser::ParseBracketDeclarator(
Declarator &D) {
7723 if (CheckProhibitedCXX11Attribute())
7731 if (Tok.getKind() == tok::r_square) {
7733 ParsedAttributes attrs(AttrFactory);
7734 MaybeParseCXX11Attributes(attrs);
7738 T.getOpenLocation(),
7739 T.getCloseLocation()),
7740 std::move(attrs),
T.getCloseLocation());
7742 }
else if (Tok.getKind() == tok::numeric_constant &&
7749 ParsedAttributes attrs(AttrFactory);
7750 MaybeParseCXX11Attributes(attrs);
7754 T.getOpenLocation(),
7755 T.getCloseLocation()),
7756 std::move(attrs),
T.getCloseLocation());
7758 }
else if (Tok.getKind() == tok::code_completion) {
7760 Actions.CodeCompletion().CodeCompleteBracketDeclarator(
getCurScope());
7765 SourceLocation StaticLoc;
7770 DeclSpec DS(AttrFactory);
7771 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
7779 bool isStar =
false;
7790 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7791 StaticLoc = SourceLocation();
7794 }
else if (Tok.isNot(tok::r_square)) {
7811 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7812 StaticLoc = SourceLocation();
7831 isStar, NumElements.
get(),
T.getOpenLocation(),
7832 T.getCloseLocation()),
7836void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
7837 assert(Tok.is(tok::l_square) &&
"Missing opening bracket");
7840 SourceLocation StartBracketLoc = Tok.getLocation();
7844 while (Tok.is(tok::l_square)) {
7845 ParseBracketDeclarator(TempDeclarator);
7851 if (Tok.is(tok::semi))
7854 SourceLocation SuggestParenLoc = Tok.getLocation();
7857 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7862 if (TempDeclarator.getNumTypeObjects() == 0)
7866 bool NeedParens =
false;
7885 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
7891 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
7892 const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
7893 D.
AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());
7898 if (!D.
hasName() && !NeedParens)
7901 SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();
7904 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
7905 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
7908 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7913 EndLoc, CharSourceRange(BracketRange,
true))
7916 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7919 EndLoc, CharSourceRange(BracketRange,
true))
7924void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
7925 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
7926 "Not a typeof specifier");
7928 bool IsUnqual = Tok.is(tok::kw_typeof_unqual);
7929 const IdentifierInfo *II = Tok.getIdentifierInfo();
7931 Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName();
7935 bool HasParens = Tok.is(tok::l_paren);
7943 SourceRange CastRange;
7945 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);
7961 const char *PrevSpec =
nullptr;
7968 Actions.getASTContext().getPrintingPolicy()))
7969 Diag(StartLoc, DiagID) << PrevSpec;
7980 Operand = Actions.HandleExprEvaluationContextForTypeof(
Operand.get());
7986 const char *PrevSpec =
nullptr;
7993 Actions.getASTContext().getPrintingPolicy()))
7994 Diag(StartLoc, DiagID) << PrevSpec;
7997void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
7998 assert(Tok.is(tok::kw__Atomic) &&
NextToken().
is(tok::l_paren) &&
7999 "Not an atomic specifier");
8003 if (
T.consumeOpen())
8007 if (
Result.isInvalid()) {
8015 if (
T.getCloseLocation().isInvalid())
8021 const char *PrevSpec =
nullptr;
8025 Actions.getASTContext().getPrintingPolicy()))
8026 Diag(StartLoc, DiagID) << PrevSpec;
8029bool Parser::TryAltiVecVectorTokenOutOfLine() {
8031 switch (
Next.getKind()) {
8032 default:
return false;
8035 case tok::kw_signed:
8036 case tok::kw_unsigned:
8041 case tok::kw_double:
8044 case tok::kw___bool:
8045 case tok::kw___pixel:
8046 Tok.setKind(tok::kw___vector);
8048 case tok::identifier:
8049 if (
Next.getIdentifierInfo() == Ident_pixel) {
8050 Tok.setKind(tok::kw___vector);
8053 if (
Next.getIdentifierInfo() == Ident_bool ||
8054 Next.getIdentifierInfo() == Ident_Bool) {
8055 Tok.setKind(tok::kw___vector);
8063 const char *&PrevSpec,
unsigned &DiagID,
8065 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
8066 if (Tok.getIdentifierInfo() == Ident_vector) {
8068 switch (
Next.getKind()) {
8071 case tok::kw_signed:
8072 case tok::kw_unsigned:
8077 case tok::kw_double:
8080 case tok::kw___bool:
8081 case tok::kw___pixel:
8084 case tok::identifier:
8085 if (
Next.getIdentifierInfo() == Ident_pixel) {
8089 if (
Next.getIdentifierInfo() == Ident_bool ||
8090 Next.getIdentifierInfo() == Ident_Bool) {
8099 }
else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
8103 }
else if ((Tok.getIdentifierInfo() == Ident_bool) &&
8111TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8114 SmallVector<Token, 4> Tokens;
8117 auto &SourceMgr = PP.getSourceManager();
8118 FileID FID = SourceMgr.createFileID(
8119 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8123 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8124 L.setParsingPreprocessorDirective(
true);
8130 Tokens.push_back(Tok);
8131 }
while (Tok.isNot(tok::eod));
8136 Token &EndToken = Tokens.back();
8143 Tokens.push_back(Tok);
8146 PP.EnterTokenStream(Tokens,
false,
8161 (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {
8162 Diag(Tok.getLocation(), diag::err_type_unparsed);
8167 while (Tok.isNot(tok::eof))
8171 if (Tok.is(tok::eof) && Tok.getEofData() == TypeStr.data())
8176void Parser::DiagnoseBitIntUse(
const Token &
Tok) {
8180 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8181 "expected either an _ExtInt or _BitInt token!");
8183 SourceLocation Loc = Tok.getLocation();
8184 if (Tok.is(tok::kw__ExtInt)) {
8185 Diag(Loc, diag::warn_ext_int_deprecated)
8191 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