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.
addAll(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_namespace:
2090 if (Tok.isAtStartOfLine() &&
2091 (!ParsingInObjCContainer || CurParsedObjCImpl))
2097 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2098 ParsingInObjCContainer)
2105 if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
2110 case tok::annot_module_begin:
2111 case tok::annot_module_end:
2112 case tok::annot_module_include:
2113 case tok::annot_repl_input_end:
2127 ParsedTemplateInfo &TemplateInfo,
2129 ForRangeInit *FRI) {
2135 LocalAttrs.takeAllFrom(Attrs);
2137 if (TemplateInfo.TemplateParams)
2140 bool IsTemplateSpecOrInst =
2147 if (IsTemplateSpecOrInst)
2157 while (MaybeParseHLSLAnnotations(D))
2160 if (
Tok.is(tok::kw_requires))
2161 ParseTrailingRequiresClause(D);
2166 LateParsedAttrList LateParsedAttrs(
true);
2168 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2173 if (
Tok.is(tok::kw__Noreturn)) {
2175 const char *PrevSpec;
2181 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2182 Fixit &=
Tok.isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2184 Diag(Loc, diag::err_c11_noreturn_misplaced)
2186 << (Fixit ?
FixItHint::CreateInsertion(D.getBeginLoc(),
"_Noreturn ")
2191 if (Tok.is(tok::equal) &&
NextToken().
is(tok::code_completion)) {
2193 Actions.CodeCompletion().CodeCompleteAfterFunctionEquals(D);
2202 while (
auto Specifier = isCXX11VirtSpecifier()) {
2203 Diag(Tok, diag::err_virt_specifier_outside_class)
2211 if (!isDeclarationAfterDeclarator()) {
2217 if (isStartOfFunctionDefinition(D)) {
2227 diag::err_function_declared_typedef)
2231 Decl *TheDecl =
nullptr;
2237 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2238 TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(),
2241 SourceLocation LAngleLoc =
2242 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2244 diag::err_explicit_instantiation_with_definition)
2245 << SourceRange(TemplateInfo.TemplateLoc)
2250 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2251 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
2252 LAngleLoc,
nullptr));
2254 TheDecl = ParseFunctionDefinition(
2256 ParsedTemplateInfo(&FakedParamLists,
2263 ParseFunctionDefinition(D, TemplateInfo, &LateParsedAttrs);
2266 return Actions.ConvertDeclToDeclGroup(TheDecl);
2270 Tok.is(tok::kw_namespace)) {
2280 Diag(Tok, diag::err_expected_fn_body);
2285 if (Tok.is(tok::l_brace)) {
2286 Diag(Tok, diag::err_function_definition_not_allowed);
2294 if (ParseAsmAttributesAfterDeclarator(D))
2303 if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
2304 bool IsForRangeLoop =
false;
2306 IsForRangeLoop =
true;
2307 EnterExpressionEvaluationContext ForRangeInitContext(
2315 auto &LastRecord = Actions.currentEvaluationContext();
2316 LastRecord.InLifetimeExtendingContext =
true;
2317 LastRecord.RebuildDefaultArgOrDefaultInit =
true;
2321 Actions.OpenMP().startOpenMPCXXRangeFor();
2322 if (Tok.is(tok::l_brace))
2323 FRI->RangeExpr = ParseBraceInitializer();
2330 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
2334 FRI->LifetimeExtendTemps = std::move(
2335 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps);
2339 if (IsForRangeLoop) {
2340 Actions.ActOnCXXForRangeDecl(ThisDecl);
2343 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2344 VD->setObjCForDecl(
true);
2346 Actions.FinalizeDeclaration(ThisDecl);
2347 D.complete(ThisDecl);
2348 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, ThisDecl);
2351 SmallVector<Decl *, 8> DeclsInGroup;
2353 ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo, FRI);
2354 if (LateParsedAttrs.size() > 0)
2355 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2356 D.complete(FirstDecl);
2358 DeclsInGroup.push_back(FirstDecl);
2364 SourceLocation CommaLoc;
2366 if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2370 Diag(CommaLoc, diag::err_expected_semi_declaration)
2382 Diag(CommaLoc, diag::err_multiple_template_declarators)
2383 << TemplateInfo.Kind;
2397 MaybeParseGNUAttributes(D);
2401 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2406 MaybeParseHLSLAnnotations(D);
2413 if (Tok.is(tok::kw_requires))
2414 ParseTrailingRequiresClause(D);
2415 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D, TemplateInfo);
2416 D.complete(ThisDecl);
2418 DeclsInGroup.push_back(ThisDecl);
2423 *DeclEnd = Tok.getLocation();
2425 if (ExpectSemi && ExpectAndConsumeSemi(
2427 ? diag::err_invalid_token_after_toplevel_declarator
2428 : diag::err_expected_semi_declaration)) {
2436 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
2439bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &D) {
2441 if (Tok.is(tok::kw_asm)) {
2443 ExprResult AsmLabel(ParseSimpleAsm(
true, &Loc));
2444 if (AsmLabel.isInvalid()) {
2453 MaybeParseGNUAttributes(D);
2457Decl *Parser::ParseDeclarationAfterDeclarator(
2458 Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
2459 if (ParseAsmAttributesAfterDeclarator(D))
2462 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
2465Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2466 Declarator &D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2468 struct InitializerScopeRAII {
2474 InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl)
2475 : P(P), D(D), ThisDecl(ThisDecl), Entered(
false) {
2478 if (D.getCXXScopeSpec().isSet()) {
2480 S = P.getCurScope();
2483 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2488 ~InitializerScopeRAII() {
2504 InitKind TheInitKind;
2506 if (isTokenEqualOrEqualTypo())
2507 TheInitKind = InitKind::Equal;
2508 else if (
Tok.
is(tok::l_paren))
2509 TheInitKind = InitKind::CXXDirect;
2512 TheInitKind = InitKind::CXXBraced;
2514 TheInitKind = InitKind::Uninitialized;
2515 if (TheInitKind != InitKind::Uninitialized)
2519 Decl *ThisDecl =
nullptr;
2520 Decl *OuterDecl =
nullptr;
2521 switch (TemplateInfo.Kind) {
2523 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2528 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
2529 *TemplateInfo.TemplateParams,
2531 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2534 ThisDecl = VT->getTemplatedDecl();
2540 if (
Tok.
is(tok::semi)) {
2541 DeclResult ThisRes = Actions.ActOnExplicitInstantiation(
2542 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
2544 SkipUntil(tok::semi, StopBeforeMatch);
2547 ThisDecl = ThisRes.
get();
2555 Diag(
Tok, diag::err_template_defn_explicit_instantiation)
2557 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2560 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2562 diag::err_explicit_instantiation_with_definition)
2567 TemplateParameterLists FakedParamLists;
2568 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2570 LAngleLoc,
nullptr));
2573 Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D);
2582 switch (TheInitKind) {
2584 case InitKind::Equal: {
2587 if (
Tok.
is(tok::kw_delete)) {
2589 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2592 Diag(ConsumeToken(), diag::err_deleted_non_function);
2593 SkipDeletedFunctionBody();
2594 }
else if (
Tok.
is(tok::kw_default)) {
2596 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2599 Diag(ConsumeToken(), diag::err_default_special_members)
2600 << getLangOpts().CPlusPlus20;
2602 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2604 if (
Tok.
is(tok::code_completion)) {
2606 Actions.CodeCompletion().CodeCompleteInitializer(getCurScope(),
2608 Actions.FinalizeDeclaration(ThisDecl);
2618 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2622 FRI->ColonLoc = EqualLoc;
2624 FRI->RangeExpr =
Init;
2627 if (
Init.isInvalid()) {
2629 StopTokens.push_back(tok::comma);
2632 StopTokens.push_back(tok::r_paren);
2633 SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch);
2634 Actions.ActOnInitializerError(ThisDecl);
2636 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
2641 case InitKind::CXXDirect: {
2648 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2650 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2651 auto RunSignatureHelp = [&]() {
2653 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2654 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2657 CalledSignatureHelp =
true;
2658 return PreferredType;
2660 auto SetPreferredType = [&] {
2661 PreferredType.enterFunctionArgument(
Tok.
getLocation(), RunSignatureHelp);
2664 llvm::function_ref<void()> ExpressionStarts;
2670 ExpressionStarts = SetPreferredType;
2673 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2676 if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
2677 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2678 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2681 CalledSignatureHelp =
true;
2683 Actions.ActOnInitializerError(ThisDecl);
2684 SkipUntil(tok::r_paren, StopAtSemi);
2690 T.getCloseLocation(),
2692 Actions.AddInitializerToDecl(ThisDecl,
Initializer.get(),
2697 case InitKind::CXXBraced: {
2699 Diag(
Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2701 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2706 if (
Init.isInvalid()) {
2707 Actions.ActOnInitializerError(ThisDecl);
2709 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
true);
2712 case InitKind::Uninitialized: {
2713 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2714 Actions.ActOnUninitializedDecl(ThisDecl);
2719 Actions.FinalizeDeclaration(ThisDecl);
2720 return OuterDecl ? OuterDecl : ThisDecl;
2723void Parser::ParseSpecifierQualifierList(
2726 ParsedTemplateInfo TemplateInfo;
2730 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC,
nullptr,
2731 AllowImplicitTypename);
2736 Diag(Tok, diag::err_expected_type);
2739 Diag(Tok, diag::err_typename_requires_specqual);
2750 diag::err_typename_invalid_storageclass);
2794 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2795 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2800 ParsedTemplateInfo &TemplateInfo,
2803 assert(Tok.is(tok::identifier) &&
"should have identifier");
2805 SourceLocation Loc = Tok.getLocation();
2825 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
2843 AnnotateScopeToken(*SS,
false);
2852 if (
ParsedType T = Actions.ActOnMSVCUnknownTypeName(
2853 *Tok.getIdentifierInfo(), Tok.getLocation(),
2854 DSC == DeclSpecContext::DSC_template_type_arg)) {
2855 const char *PrevSpec;
2858 Actions.getASTContext().getPrintingPolicy());
2871 if (SS ==
nullptr) {
2872 const char *TagName =
nullptr, *FixitTagName =
nullptr;
2875 switch (Actions.isTagName(*Tok.getIdentifierInfo(),
getCurScope())) {
2878 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
2880 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
2882 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
2884 TagName=
"__interface"; FixitTagName =
"__interface ";
2885 TagKind=tok::kw___interface;
break;
2887 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
2891 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
2892 LookupResult R(Actions, TokenName, SourceLocation(),
2895 Diag(Loc, diag::err_use_of_tag_name_without_tag)
2896 << TokenName << TagName <<
getLangOpts().CPlusPlus
2902 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2903 << TokenName << TagName;
2907 if (TagKind == tok::kw_enum)
2908 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,
2909 DeclSpecContext::DSC_normal);
2911 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
2913 DeclSpecContext::DSC_normal, Attrs);
2920 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
2921 DSC == DeclSpecContext::DSC_class)) {
2925 case tok::l_paren: {
2932 TentativeParsingAction PA(*
this);
2934 TPResult TPR = TryParseDeclarator(
false);
2937 if (TPR != TPResult::False) {
2945 if (DSC == DeclSpecContext::DSC_class ||
2946 (DSC == DeclSpecContext::DSC_top_level && SS)) {
2947 IdentifierInfo *II = Tok.getIdentifierInfo();
2948 if (Actions.isCurrentClassNameTypo(II, SS)) {
2949 Diag(Loc, diag::err_constructor_bad_name)
2950 << Tok.getIdentifierInfo() << II
2952 Tok.setIdentifierInfo(II);
2970 AnnotateScopeToken(*SS,
false);
2984 IdentifierInfo *II = Tok.getIdentifierInfo();
2986 Actions.DiagnoseUnknownTypeName(II, Loc,
getCurScope(), SS,
T,
2992 const char *PrevSpec;
2995 Actions.getASTContext().getPrintingPolicy());
3000 }
else if (II != Tok.getIdentifierInfo()) {
3013 if (IsTemplateName) {
3014 SourceLocation LAngle, RAngle;
3015 TemplateArgList Args;
3016 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3025Parser::DeclSpecContext
3029 return DeclSpecContext::DSC_class;
3031 return DeclSpecContext::DSC_top_level;
3033 return DeclSpecContext::DSC_template_param;
3035 return DeclSpecContext::DSC_template_arg;
3037 return DeclSpecContext::DSC_template_type_arg;
3040 return DeclSpecContext::DSC_trailing;
3043 return DeclSpecContext::DSC_alias_declaration;
3045 return DeclSpecContext::DSC_association;
3047 return DeclSpecContext::DSC_type_specifier;
3049 return DeclSpecContext::DSC_condition;
3051 return DeclSpecContext::DSC_conv_operator;
3053 return DeclSpecContext::DSC_new;
3068 return DeclSpecContext::DSC_normal;
3071 llvm_unreachable(
"Missing DeclaratorContext case");
3078 if (isTypeIdInParens()) {
3079 SourceLocation TypeLoc = Tok.getLocation();
3081 SourceRange TypeRange(Start, Tok.getLocation());
3082 if (Actions.ActOnAlignasTypeArgument(KWName, Ty, TypeLoc, TypeRange))
3099 assert(Tok.isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3100 "Not an alignment-specifier!");
3107 if (
T.expectAndConsume())
3112 SourceLocation EllipsisLoc;
3114 ParseAlignArgument(PP.getSpelling(KWTok),
T.getOpenLocation(),
3123 *EndLoc =
T.getCloseLocation();
3130 ArgExprs.push_back(ArgExpr.
get());
3131 Attrs.
addNew(KWName, KWLoc, AttributeScopeInfo(), ArgExprs.data(), 1, Kind,
3136void Parser::DistributeCLateParsedAttrs(
Decl *Dcl,
3137 LateParsedAttrList *LateAttrs) {
3142 for (
auto *LateAttr : *LateAttrs) {
3143 if (LateAttr->Decls.empty())
3144 LateAttr->addDecl(Dcl);
3150 assert(Tok.is(tok::kw___ptrauth));
3152 IdentifierInfo *KwName = Tok.getIdentifierInfo();
3156 if (
T.expectAndConsume())
3166 ArgExprs.push_back(ER.
get());
3170 SourceLocation EndLoc =
T.getCloseLocation();
3172 if (ArgExprs.empty() || ArgExprs.size() > 3) {
3173 Diag(KwLoc, diag::err_ptrauth_qualifier_bad_arg_count);
3177 Attrs.
addNew(KwName, SourceRange(KwLoc, EndLoc), AttributeScopeInfo(),
3178 ArgExprs.data(), ArgExprs.size(),
3179 ParsedAttr::Form::Keyword(
false,
3189 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3194 if (Tok.is(tok::r_paren)) {
3195 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
3202 using ExpressionKind =
3204 EnterExpressionEvaluationContext EC(
3206 ExpressionKind::EK_AttrArgument);
3214 ArgExprs.push_back(ArgExpr.
get());
3217 ASTContext &Ctx = Actions.getASTContext();
3223 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
3224 AttributeScopeInfo(), ArgExprs.data(), ArgExprs.size(), Form);
3227ExprResult Parser::ParseExtIntegerArgument() {
3228 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3229 "Not an extended int type");
3233 if (
T.expectAndConsume())
3242 if(
T.consumeClose())
3249 DeclSpecContext DSContext,
3250 LateParsedAttrList *LateAttrs) {
3253 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3254 DSContext == DeclSpecContext::DSC_top_level);
3257 Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
3258 tok::annot_template_id) &&
3264 bool HasScope = Tok.is(tok::annot_cxxscope);
3266 Token AfterScope = HasScope ?
NextToken() : Tok;
3270 bool MightBeDeclarator =
true;
3271 if (Tok.isOneOf(tok::kw_typename, tok::annot_typename)) {
3273 MightBeDeclarator =
false;
3274 }
else if (AfterScope.
is(tok::annot_template_id)) {
3277 TemplateIdAnnotation *Annot =
3280 MightBeDeclarator =
false;
3281 }
else if (AfterScope.
is(tok::identifier)) {
3286 if (
Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3287 tok::annot_cxxscope, tok::coloncolon)) {
3289 MightBeDeclarator = false;
3290 }
else if (HasScope) {
3295 Actions.RestoreNestedNameSpecifierAnnotation(
3296 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
3298 Sema::NameClassification Classification = Actions.ClassifyName(
3301 switch (Classification.
getKind()) {
3307 llvm_unreachable(
"typo correction is not possible here");
3315 MightBeDeclarator =
false;
3330 if (MightBeDeclarator)
3333 const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
3335 diag::err_expected_after)
3346 ParsedTemplateInfo NotATemplate;
3347 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3351void Parser::ParseDeclarationSpecifiers(
3353 DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
3365 if (DSContext == DeclSpecContext::DSC_conv_operator) {
3368 DSContext = DeclSpecContext::DSC_type_specifier;
3371 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3372 DSContext == DeclSpecContext::DSC_top_level);
3373 bool AttrsLastTime =
false;
3374 ParsedAttributes attrs(AttrFactory);
3376 PrintingPolicy Policy = Actions.getPrintingPolicy();
3379 bool isStorageClass =
false;
3380 const char *PrevSpec =
nullptr;
3381 unsigned DiagID = 0;
3385 SourceLocation ConsumedEnd;
3394 if (
getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&
3397 Tok.setKind(tok::identifier);
3399 SourceLocation Loc = Tok.getLocation();
3402 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3406 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
3407 Tok.setKind(tok::identifier);
3416 bool IsTemplateSpecOrInst =
3420 switch (Tok.getKind()) {
3422 if (Tok.isRegularKeywordAttribute())
3427 ProhibitAttributes(attrs);
3430 for (
const ParsedAttr &PA : attrs) {
3431 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3432 !PA.isRegularKeywordAttribute())
3440 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3441 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3448 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3449 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3452 if (PA.getKind() == ParsedAttr::AT_LifetimeBound)
3453 Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type)
3454 << PA << PA.isRegularKeywordAttribute()
3457 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3458 << PA << PA.isRegularKeywordAttribute();
3467 DS.
Finish(Actions, Policy);
3471 case tok::kw__Alignas:
3472 diagnoseUseOfC11Keyword(Tok);
3474 case tok::kw_alignas:
3480 if (Tok.getKind() == tok::kw_alignas)
3481 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
3487 if (!isAllowedCXX11AttributeSpecifier())
3488 goto DoneWithDeclSpec;
3491 ProhibitAttributes(attrs);
3496 attrs.Range = SourceRange();
3498 ParseCXX11Attributes(attrs);
3499 AttrsLastTime =
true;
3502 case tok::code_completion: {
3506 bool AllowNonIdentifiers
3512 bool AllowNestedNameSpecifiers
3513 = DSContext == DeclSpecContext::DSC_top_level ||
3517 Actions.CodeCompletion().CodeCompleteDeclSpec(
3518 getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3524 CCC = DSContext == DeclSpecContext::DSC_class
3527 else if (DSContext == DeclSpecContext::DSC_class)
3531 else if (CurParsedObjCImpl)
3535 Actions.CodeCompletion().CodeCompleteOrdinaryName(
getCurScope(), CCC);
3539 case tok::coloncolon:
3545 goto DoneWithDeclSpec;
3547 if (Tok.is(tok::coloncolon))
3548 goto DoneWithDeclSpec;
3551 case tok::annot_cxxscope: {
3553 goto DoneWithDeclSpec;
3556 if (TemplateInfo.TemplateParams)
3558 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
3559 Tok.getAnnotationRange(),
3565 TemplateIdAnnotation *TemplateId =
Next.is(tok::annot_template_id)
3566 ? takeTemplateIdAnnotation(
Next)
3572 ConsumeAnnotationToken();
3586 if ((DSContext == DeclSpecContext::DSC_top_level ||
3587 DSContext == DeclSpecContext::DSC_class) &&
3590 isConstructorDeclarator(
false,
3597 goto DoneWithDeclSpec;
3601 ConsumeAnnotationToken();
3602 assert(Tok.is(tok::annot_template_id) &&
3603 "ParseOptionalCXXScopeSpecifier not working");
3604 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3614 ConsumeAnnotationToken();
3618 if (
Next.is(tok::annot_typename)) {
3620 ConsumeAnnotationToken();
3623 Tok.getAnnotationEndLoc(),
3624 PrevSpec, DiagID,
T, Policy);
3628 ConsumeAnnotationToken();
3632 Next.is(tok::annot_template_id) &&
3633 static_cast<TemplateIdAnnotation *
>(
Next.getAnnotationValue())
3636 ConsumeAnnotationToken();
3637 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3641 if (
Next.isNot(tok::identifier))
3642 goto DoneWithDeclSpec;
3647 if ((DSContext == DeclSpecContext::DSC_top_level ||
3648 DSContext == DeclSpecContext::DSC_class) &&
3651 isConstructorDeclarator(
false,
3655 goto DoneWithDeclSpec;
3661 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3665 false,
false,
nullptr,
3668 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3670 if (IsTemplateSpecOrInst)
3678 if (TryAnnotateTypeConstraint())
3679 goto DoneWithDeclSpec;
3680 if (Tok.isNot(tok::annot_cxxscope) ||
3684 ConsumeAnnotationToken();
3685 ParsedAttributes Attrs(AttrFactory);
3686 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3687 if (!Attrs.
empty()) {
3688 AttrsLastTime =
true;
3689 attrs.takeAllFrom(Attrs);
3693 goto DoneWithDeclSpec;
3697 ConsumeAnnotationToken();
3700 DiagID, TypeRep, Policy);
3710 case tok::annot_typename: {
3714 goto DoneWithDeclSpec;
3723 ConsumeAnnotationToken();
3728 case tok::kw___is_signed:
3740 TryKeywordIdentFallback(
true);
3743 goto DoneWithDeclSpec;
3746 case tok::kw___super:
3747 case tok::kw_decltype:
3748 case tok::identifier:
3754 goto DoneWithDeclSpec;
3760 if (!
getLangOpts().DeclSpecKeyword && Tok.is(tok::identifier) &&
3761 Tok.getIdentifierInfo()->getName() ==
"__declspec") {
3762 Diag(Loc, diag::err_ms_attributes_not_enabled);
3772 if (
T.consumeOpen()) {
3773 assert(
false &&
"Not a left paren?");
3788 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3792 if (IsTemplateSpecOrInst)
3796 if (IsTemplateSpecOrInst)
3799 goto DoneWithDeclSpec;
3802 if (!Tok.is(tok::identifier))
3807 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID,
isInvalid))
3813 goto DoneWithDeclSpec;
3815 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3816 isObjCInstancetype()) {
3817 ParsedType TypeRep = Actions.ObjC().ActOnObjCInstanceType(Loc);
3820 DiagID, TypeRep, Policy);
3832 Actions.isCurrentClassName(*Tok.getIdentifierInfo(),
getCurScope()) &&
3833 isConstructorDeclarator(
true,
3836 goto DoneWithDeclSpec;
3839 *Tok.getIdentifierInfo(), Tok.getLocation(),
getCurScope(),
nullptr,
3840 false,
false,
nullptr,
false,
false,
3841 isClassTemplateDeductionContext(DSContext));
3846 if (TryAnnotateTypeConstraint())
3847 goto DoneWithDeclSpec;
3848 if (Tok.isNot(tok::identifier))
3850 ParsedAttributes Attrs(AttrFactory);
3851 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
3852 if (!Attrs.
empty()) {
3853 AttrsLastTime =
true;
3854 attrs.takeAllFrom(Attrs);
3858 goto DoneWithDeclSpec;
3865 (DSContext == DeclSpecContext::DSC_class ||
3866 DSContext == DeclSpecContext::DSC_top_level) &&
3867 Actions.isDeductionGuideName(
getCurScope(), *Tok.getIdentifierInfo(),
3868 Tok.getLocation(), SS) &&
3869 isConstructorDeclarator(
true,
3871 goto DoneWithDeclSpec;
3874 DiagID, TypeRep, Policy);
3885 SourceLocation NewEndLoc;
3886 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3901 case tok::annot_template_id: {
3902 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
3913 TemplateId =
nullptr;
3921 tok::kw_volatile, tok::kw_restrict, tok::amp,
3923 Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
3927 TemplateId, Policy);
3931 goto DoneWithDeclSpec;
3933 if (TemplateId && !
isInvalid && Actions.CheckTypeConstraint(TemplateId))
3934 TemplateId =
nullptr;
3936 ConsumeAnnotationToken();
3937 SourceLocation AutoLoc = Tok.getLocation();
3940 if (Tracker.consumeOpen()) {
3942 Diag(Tok, diag::err_expected) << tok::l_paren;
3946 Tracker.skipToEnd();
3947 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
3952 Tracker.consumeClose();
3955 ConsumedEnd = Tok.getLocation();
3960 DiagID, TemplateId, Policy);
3963 TemplateId, Policy);
3972 goto DoneWithDeclSpec;
3980 isConstructorDeclarator(
true,
3983 goto DoneWithDeclSpec;
3988 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3993 case tok::kw___attribute:
3994 case tok::kw___declspec:
3995 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
3999 case tok::kw___forceinline: {
4001 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
4002 SourceLocation AttrNameLoc = Tok.getLocation();
4004 nullptr, 0, tok::kw___forceinline);
4008 case tok::kw___unaligned:
4014 case tok::kw___ptrauth:
4018 case tok::kw___sptr:
4019 case tok::kw___uptr:
4020 case tok::kw___ptr64:
4021 case tok::kw___ptr32:
4023 case tok::kw___cdecl:
4024 case tok::kw___stdcall:
4025 case tok::kw___fastcall:
4026 case tok::kw___thiscall:
4027 case tok::kw___regcall:
4028 case tok::kw___vectorcall:
4032 case tok::kw___funcref:
4037 case tok::kw___pascal:
4042 case tok::kw___kernel:
4047 case tok::kw___noinline__:
4052 case tok::kw__Nonnull:
4053 case tok::kw__Nullable:
4054 case tok::kw__Nullable_result:
4055 case tok::kw__Null_unspecified:
4060 case tok::kw___kindof:
4062 AttributeScopeInfo(),
nullptr, 0,
4068 case tok::kw_typedef:
4070 PrevSpec, DiagID, Policy);
4071 isStorageClass =
true;
4073 case tok::kw_extern:
4075 Diag(Tok, diag::ext_thread_before) <<
"extern";
4077 PrevSpec, DiagID, Policy);
4078 isStorageClass =
true;
4080 case tok::kw___private_extern__:
4082 Loc, PrevSpec, DiagID, Policy);
4083 isStorageClass =
true;
4085 case tok::kw_static:
4087 Diag(Tok, diag::ext_thread_before) <<
"static";
4089 PrevSpec, DiagID, Policy);
4090 isStorageClass =
true;
4096 PrevSpec, DiagID, Policy);
4098 Diag(Tok, diag::ext_auto_storage_class)
4105 PrevSpec, DiagID, Policy);
4106 isStorageClass =
true;
4108 case tok::kw___auto_type:
4109 Diag(Tok, diag::ext_auto_type);
4113 case tok::kw_register:
4115 PrevSpec, DiagID, Policy);
4116 isStorageClass =
true;
4118 case tok::kw_mutable:
4120 PrevSpec, DiagID, Policy);
4121 isStorageClass =
true;
4123 case tok::kw___thread:
4126 isStorageClass =
true;
4128 case tok::kw_thread_local:
4130 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4139 Loc, PrevSpec, DiagID);
4140 isStorageClass =
true;
4142 case tok::kw__Thread_local:
4143 diagnoseUseOfC11Keyword(Tok);
4145 Loc, PrevSpec, DiagID);
4146 isStorageClass =
true;
4150 case tok::kw_inline:
4153 case tok::kw_virtual:
4157 !
getActions().getOpenCLOptions().isAvailableOption(
4159 DiagID = diag::err_openclcxx_virtual_function;
4160 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4163 DiagID = diag::err_hlsl_virtual_function;
4164 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4170 case tok::kw_explicit: {
4171 SourceLocation ExplicitLoc = Loc;
4172 SourceLocation CloseParenLoc;
4174 ConsumedEnd = ExplicitLoc;
4176 if (Tok.is(tok::l_paren)) {
4179 ? diag::warn_cxx17_compat_explicit_bool
4180 : diag::ext_explicit_bool);
4182 ExprResult ExplicitExpr(
static_cast<Expr *
>(
nullptr));
4184 Tracker.consumeOpen();
4186 EnterExpressionEvaluationContext ConstantEvaluated(
4190 ConsumedEnd = Tok.getLocation();
4191 if (ExplicitExpr.isUsable()) {
4192 CloseParenLoc = Tok.getLocation();
4193 Tracker.consumeClose();
4195 Actions.ActOnExplicitBoolSpecifier(ExplicitExpr.get());
4197 Tracker.skipToEnd();
4199 Diag(Tok.getLocation(), diag::warn_cxx20_compat_explicit_bool);
4203 ExplicitSpec, CloseParenLoc);
4206 case tok::kw__Noreturn:
4207 diagnoseUseOfC11Keyword(Tok);
4212 case tok::kw_friend:
4213 if (DSContext == DeclSpecContext::DSC_class) {
4220 DiagID = diag::err_friend_invalid_in_context;
4226 case tok::kw___module_private__:
4231 case tok::kw_constexpr:
4233 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4237 case tok::kw_consteval:
4241 case tok::kw_constinit:
4257 PrevSpec, DiagID, Policy);
4259 case tok::kw___int64:
4261 PrevSpec, DiagID, Policy);
4263 case tok::kw_signed:
4267 case tok::kw_unsigned:
4271 case tok::kw__Complex:
4273 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4277 case tok::kw__Imaginary:
4279 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4295 case tok::kw__ExtInt:
4296 case tok::kw__BitInt: {
4297 DiagnoseBitIntUse(Tok);
4302 ConsumedEnd = PrevTokLocation;
4305 case tok::kw___int128:
4313 case tok::kw___bf16:
4321 case tok::kw_double:
4325 case tok::kw__Float16:
4329 case tok::kw__Accum:
4331 "This keyword is only used when fixed point types are enabled "
4332 "with `-ffixed-point`");
4336 case tok::kw__Fract:
4338 "This keyword is only used when fixed point types are enabled "
4339 "with `-ffixed-point`");
4345 "This keyword is only used when fixed point types are enabled "
4346 "with `-ffixed-point`");
4349 case tok::kw___float128:
4353 case tok::kw___ibm128:
4357 case tok::kw_wchar_t:
4361 case tok::kw_char8_t:
4365 case tok::kw_char16_t:
4369 case tok::kw_char32_t:
4375 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4379 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4381 if (Tok.is(tok::kw_bool) &&
4385 DiagID = diag::err_bool_redeclaration;
4387 Tok.setKind(tok::identifier);
4394 case tok::kw__Decimal32:
4398 case tok::kw__Decimal64:
4402 case tok::kw__Decimal128:
4406 case tok::kw___vector:
4409 case tok::kw___pixel:
4412 case tok::kw___bool:
4417 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4420 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
4421 Tok.setKind(tok::identifier);
4422 goto DoneWithDeclSpec;
4424 DiagID = diag::err_opencl_unknown_type_specifier;
4425 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4431#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4432#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4433#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4434 case tok::kw_##ImgType##_t: \
4435 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4436 goto DoneWithDeclSpec; \
4438#include "clang/Basic/OpenCLImageTypes.def"
4439 case tok::kw___unknown_anytype:
4441 PrevSpec, DiagID, Policy);
4446 case tok::kw_struct:
4447 case tok::kw___interface:
4448 case tok::kw_union: {
4455 ParsedAttributes Attributes(AttrFactory);
4456 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
4457 EnteringContext, DSContext, Attributes);
4461 if (!Attributes.empty()) {
4462 AttrsLastTime =
true;
4463 attrs.takeAllFrom(Attributes);
4471 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
4479 case tok::kw_volatile:
4483 case tok::kw_restrict:
4489 case tok::kw_typename:
4492 goto DoneWithDeclSpec;
4494 if (!Tok.is(tok::kw_typename))
4499 case tok::kw_typeof:
4500 case tok::kw_typeof_unqual:
4501 ParseTypeofSpecifier(DS);
4504 case tok::annot_decltype:
4505 ParseDecltypeSpecifier(DS);
4508 case tok::annot_pack_indexing_type:
4509 ParsePackIndexingType(DS);
4512 case tok::annot_pragma_pack:
4516 case tok::annot_pragma_ms_pragma:
4517 HandlePragmaMSPragma();
4520 case tok::annot_pragma_ms_vtordisp:
4521 HandlePragmaMSVtorDisp();
4524 case tok::annot_pragma_ms_pointers_to_members:
4525 HandlePragmaMSPointersToMembers();
4528#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4529#include "clang/Basic/TransformTypeTraits.def"
4533 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4534 goto ParseIdentifier;
4537 case tok::kw__Atomic:
4542 diagnoseUseOfC11Keyword(Tok);
4544 ParseAtomicSpecifier(DS);
4552 case tok::kw___generic:
4557 if (!Actions.getLangOpts().OpenCLGenericAddressSpace) {
4558 DiagID = diag::err_opencl_unknown_type_specifier;
4559 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4564 case tok::kw_private:
4568 goto DoneWithDeclSpec;
4570 case tok::kw___private:
4571 case tok::kw___global:
4572 case tok::kw___local:
4573 case tok::kw___constant:
4575 case tok::kw___read_only:
4576 case tok::kw___write_only:
4577 case tok::kw___read_write:
4581 case tok::kw_groupshared:
4589#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
4590 case tok::kw_##Name: \
4591 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4594#include "clang/Basic/HLSLIntangibleTypes.def"
4601 goto DoneWithDeclSpec;
4603 SourceLocation StartLoc = Tok.getLocation();
4604 SourceLocation EndLoc;
4606 if (
Type.isUsable()) {
4608 PrevSpec, DiagID,
Type.get(),
4609 Actions.getASTContext().getPrintingPolicy()))
4610 Diag(StartLoc, DiagID) << PrevSpec;
4626 assert(PrevSpec &&
"Method did not return previous specifier!");
4629 if (DiagID == diag::ext_duplicate_declspec ||
4630 DiagID == diag::ext_warn_duplicate_declspec ||
4631 DiagID == diag::err_duplicate_declspec)
4632 Diag(Loc, DiagID) << PrevSpec
4635 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4639 Diag(Loc, DiagID) << PrevSpec;
4642 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4646 AttrsLastTime =
false;
4658 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4661 for (
auto *I : RD->decls()) {
4662 auto *VD = dyn_cast<ValueDecl>(I);
4670 for (
const auto &DD : CAT->dependent_decls()) {
4671 if (!RD->containsDecl(DD.getDecl())) {
4672 P.
Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4673 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4674 P.
Diag(DD.getDecl()->getBeginLoc(),
4675 diag::note_flexible_array_counted_by_attr_field)
4682void Parser::ParseStructDeclaration(
4685 LateParsedAttrList *LateFieldAttrs) {
4687 if (Tok.is(tok::kw___extension__)) {
4689 ExtensionRAIIObject O(Diags);
4691 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4695 ParsedAttributes Attrs(AttrFactory);
4696 MaybeParseCXX11Attributes(Attrs);
4699 ParseSpecifierQualifierList(DS);
4703 if (Tok.is(tok::semi)) {
4708 ProhibitAttributes(Attrs);
4709 RecordDecl *AnonRecord =
nullptr;
4710 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
4712 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4718 bool FirstDeclarator =
true;
4719 SourceLocation CommaLoc;
4721 ParsingFieldDeclarator DeclaratorInfo(*
this, DS, Attrs);
4722 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4725 if (!FirstDeclarator) {
4728 DiagnoseAndSkipCXX11Attributes();
4729 MaybeParseGNUAttributes(DeclaratorInfo.D);
4730 DiagnoseAndSkipCXX11Attributes();
4735 if (Tok.isNot(tok::colon)) {
4738 ParseDeclarator(DeclaratorInfo.D);
4740 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.getLocation());
4752 DeclaratorInfo.BitfieldSize = Res.
get();
4756 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
4759 Decl *
Field = FieldsCallback(DeclaratorInfo);
4761 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
4768 FirstDeclarator =
false;
4774void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs,
bool EnterScope,
4776 assert(LAs.parseSoon() &&
4777 "Attribute list should be marked for immediate parsing.");
4778 for (
auto *LA : LAs) {
4779 ParseLexedCAttribute(*LA,
EnterScope, OutAttrs);
4785void Parser::ParseLexedCAttribute(LateParsedAttribute &LA,
bool EnterScope,
4790 AttrEnd.startToken();
4791 AttrEnd.setKind(tok::eof);
4792 AttrEnd.setLocation(Tok.getLocation());
4793 AttrEnd.setEofData(LA.Toks.data());
4794 LA.Toks.push_back(AttrEnd);
4798 LA.Toks.push_back(Tok);
4799 PP.EnterTokenStream(LA.Toks,
true,
4808 ParsedAttributes Attrs(AttrFactory);
4810 assert(LA.Decls.size() <= 1 &&
4811 "late field attribute expects to have at most one declaration.");
4814 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
nullptr,
nullptr,
4815 SourceLocation(), ParsedAttr::Form::GNU(),
nullptr);
4817 for (
auto *D : LA.Decls)
4818 Actions.ActOnFinishDelayedAttribute(
getCurScope(), D, Attrs);
4822 while (Tok.isNot(tok::eof))
4826 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
4836 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl,
RecordLoc,
4837 "parsing struct/union body");
4841 if (
T.consumeOpen())
4845 Actions.ActOnTagStartDefinition(
getCurScope(), TagDecl);
4849 LateParsedAttrList LateFieldAttrs(
true,
4853 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
4854 Tok.isNot(tok::eof)) {
4858 if (Tok.is(tok::semi)) {
4864 if (Tok.isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4865 SourceLocation DeclEnd;
4866 ParseStaticAssertDeclaration(DeclEnd);
4870 if (Tok.is(tok::annot_pragma_pack)) {
4875 if (Tok.is(tok::annot_pragma_align)) {
4876 HandlePragmaAlign();
4880 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4883 ParsedAttributes Attrs(AttrFactory);
4884 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4888 if (Tok.is(tok::annot_pragma_openacc)) {
4890 ParsedAttributes Attrs(AttrFactory);
4896 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
4898 TagType, Actions.getASTContext().getPrintingPolicy());
4899 ConsumeAnnotationToken();
4903 if (!Tok.is(tok::at)) {
4904 auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
4908 FD.D.getDeclSpec().getSourceRange().getBegin(),
4909 FD.D, FD.BitfieldSize);
4915 ParsingDeclSpec DS(*
this);
4916 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
4919 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
4920 Diag(Tok, diag::err_unexpected_at);
4925 ExpectAndConsume(tok::l_paren);
4926 if (!Tok.is(tok::identifier)) {
4927 Diag(Tok, diag::err_expected) << tok::identifier;
4931 SmallVector<Decl *, 16> Fields;
4932 Actions.ObjC().ActOnDefs(
getCurScope(), TagDecl, Tok.getLocation(),
4933 Tok.getIdentifierInfo(), Fields);
4935 ExpectAndConsume(tok::r_paren);
4941 if (Tok.is(tok::r_brace)) {
4942 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
4946 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
4955 ParsedAttributes attrs(AttrFactory);
4957 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
4960 ParseLexedCAttributeList(LateFieldAttrs,
false);
4962 SmallVector<Decl *, 32> FieldDecls(TagDecl->
fields());
4965 T.getOpenLocation(),
T.getCloseLocation(), attrs);
4967 Actions.ActOnTagFinishDefinition(
getCurScope(), TagDecl,
T.getRange());
4971 const ParsedTemplateInfo &TemplateInfo,
4974 if (Tok.is(tok::code_completion)) {
4983 ParsedAttributes attrs(AttrFactory);
4984 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
4986 SourceLocation ScopedEnumKWLoc;
4987 bool IsScopedUsingClassTag =
false;
4992 : diag::ext_scoped_enum);
4993 IsScopedUsingClassTag = Tok.is(tok::kw_class);
4998 ProhibitAttributes(attrs);
5001 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5010 bool shouldDelayDiagsInTag =
5013 SuppressAccessChecks diagsFromTag(*
this, shouldDelayDiagsInTag);
5016 AllowDefiningTypeSpec AllowEnumSpecifier =
5018 bool CanBeOpaqueEnumDeclaration =
5019 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5022 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5023 CanBeOpaqueEnumDeclaration);
5031 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5036 if (Spec.
isSet() && Tok.isNot(tok::identifier)) {
5037 Diag(Tok, diag::err_expected) << tok::identifier;
5039 if (Tok.isNot(tok::l_brace)) {
5051 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
5052 Tok.isNot(tok::colon)) {
5053 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5062 IdentifierInfo *Name =
nullptr;
5063 SourceLocation NameLoc;
5064 if (Tok.is(tok::identifier)) {
5065 Name = Tok.getIdentifierInfo();
5069 if (!Name && ScopedEnumKWLoc.
isValid()) {
5072 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5073 ScopedEnumKWLoc = SourceLocation();
5074 IsScopedUsingClassTag =
false;
5079 if (shouldDelayDiagsInTag)
5080 diagsFromTag.done();
5083 SourceRange BaseRange;
5085 bool CanBeBitfield =
5089 if (Tok.is(tok::colon)) {
5114 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5118 Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
5119 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5126 DeclSpec DS(AttrFactory);
5130 DeclSpecContext::DSC_type_specifier);
5133 BaseType = Actions.ActOnTypeName(DeclaratorInfo);
5135 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5139 DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)
5142 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5146 ? diag::warn_c17_compat_enum_fixed_underlying_type
5147 : diag::ext_c23_enum_fixed_underlying_type)
5164 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5166 else if (Tok.is(tok::l_brace)) {
5168 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
5174 ScopedEnumKWLoc = SourceLocation();
5175 IsScopedUsingClassTag =
false;
5181 }
else if (!isTypeSpecifier(DSC) &&
5182 (Tok.is(tok::semi) ||
5183 (Tok.isAtStartOfLine() &&
5184 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5189 if (Tok.isNot(tok::semi)) {
5191 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5192 PP.EnterToken(Tok,
true);
5193 Tok.setKind(tok::semi);
5199 bool IsElaboratedTypeSpecifier =
5205 diagsFromTag.redelay();
5213 Diag(Tok, diag::err_enum_template);
5221 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5225 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5227 TemplateInfo.TemplateParams->size());
5232 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5248 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5250 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5251 diag::err_keyword_not_allowed,
5254 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5255 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5256 else if (ScopedEnumKWLoc.
isValid())
5257 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5261 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5263 SkipBodyInfo SkipBody;
5266 SkipBody = Actions.shouldSkipAnonEnumBody(
getCurScope(),
5271 bool IsDependent =
false;
5272 const char *PrevSpec =
nullptr;
5277 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5278 IsScopedUsingClassTag,
5279 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5280 DSC == DeclSpecContext::DSC_template_param ||
5281 DSC == DeclSpecContext::DSC_template_type_arg,
5282 OffsetOfState, &SkipBody).get();
5292 NameLoc.
isValid() ? NameLoc : StartLoc,
5293 PrevSpec, DiagID, TagDecl, Owned,
5294 Actions.getASTContext().getPrintingPolicy()))
5295 Diag(StartLoc, DiagID) << PrevSpec;
5304 Diag(Tok, diag::err_expected_type_name_after_typename);
5310 if (
Type.isInvalid()) {
5316 NameLoc.
isValid() ? NameLoc : StartLoc,
5317 PrevSpec, DiagID,
Type.get(),
5318 Actions.getASTContext().getPrintingPolicy()))
5319 Diag(StartLoc, DiagID) << PrevSpec;
5338 ParseEnumBody(StartLoc, D, &SkipBody);
5340 !Actions.ActOnDuplicateDefinition(
getCurScope(), TagDecl, SkipBody)) {
5347 NameLoc.
isValid() ? NameLoc : StartLoc,
5348 PrevSpec, DiagID, TagDecl, Owned,
5349 Actions.getASTContext().getPrintingPolicy()))
5350 Diag(StartLoc, DiagID) << PrevSpec;
5357 Actions.ActOnTagStartDefinition(
getCurScope(), EnumDecl);
5364 Diag(Tok, diag::err_empty_enum);
5366 SmallVector<Decl *, 32> EnumConstantDecls;
5367 SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
5369 Decl *LastEnumConstDecl =
nullptr;
5372 while (Tok.isNot(tok::r_brace)) {
5375 if (Tok.isNot(tok::identifier)) {
5376 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
5382 IdentifierInfo *Ident = Tok.getIdentifierInfo();
5386 ParsedAttributes attrs(AttrFactory);
5387 MaybeParseGNUAttributes(attrs);
5388 if (isAllowedCXX11AttributeSpecifier()) {
5391 ? diag::warn_cxx14_compat_ns_enum_attribute
5392 : diag::ext_ns_enum_attribute)
5394 ParseCXX11Attributes(attrs);
5397 SourceLocation EqualLoc;
5399 EnumAvailabilityDiags.emplace_back(*
this);
5401 EnterExpressionEvaluationContext ConstantEvaluated(
5410 Decl *EnumConstDecl = Actions.ActOnEnumConstant(
5411 getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
5412 EqualLoc, AssignedVal.
get(), SkipBody);
5413 EnumAvailabilityDiags.back().done();
5415 EnumConstantDecls.push_back(EnumConstDecl);
5416 LastEnumConstDecl = EnumConstDecl;
5418 if (Tok.is(tok::identifier)) {
5421 Diag(Loc, diag::err_enumerator_list_missing_comma)
5428 SourceLocation CommaLoc;
5429 if (Tok.isNot(tok::r_brace) && !
TryConsumeToken(tok::comma, CommaLoc)) {
5431 Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
5434 Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
5444 if (Tok.is(tok::r_brace) && CommaLoc.
isValid()) {
5447 diag::ext_enumerator_list_comma_cxx :
5448 diag::ext_enumerator_list_comma_c)
5451 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5461 ParsedAttributes attrs(AttrFactory);
5462 MaybeParseGNUAttributes(attrs);
5464 Actions.ActOnEnumBody(StartLoc,
T.getRange(), EnumDecl, EnumConstantDecls,
5468 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5469 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5471 EnumAvailabilityDiags[i].redelay();
5472 PD.complete(EnumConstantDecls[i]);
5476 Actions.ActOnTagFinishDefinition(
getCurScope(), EnumDecl,
T.getRange());
5481 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5482 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5486 PP.EnterToken(Tok,
true);
5487 Tok.setKind(tok::semi);
5491bool Parser::isKnownToBeTypeSpecifier(
const Token &
Tok)
const {
5492 switch (Tok.getKind()) {
5493 default:
return false;
5497 case tok::kw___int64:
5498 case tok::kw___int128:
5499 case tok::kw_signed:
5500 case tok::kw_unsigned:
5501 case tok::kw__Complex:
5502 case tok::kw__Imaginary:
5505 case tok::kw_wchar_t:
5506 case tok::kw_char8_t:
5507 case tok::kw_char16_t:
5508 case tok::kw_char32_t:
5510 case tok::kw__ExtInt:
5511 case tok::kw__BitInt:
5512 case tok::kw___bf16:
5515 case tok::kw_double:
5516 case tok::kw__Accum:
5517 case tok::kw__Fract:
5518 case tok::kw__Float16:
5519 case tok::kw___float128:
5520 case tok::kw___ibm128:
5523 case tok::kw__Decimal32:
5524 case tok::kw__Decimal64:
5525 case tok::kw__Decimal128:
5526 case tok::kw___vector:
5527#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5528#include "clang/Basic/OpenCLImageTypes.def"
5529#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5530#include "clang/Basic/HLSLIntangibleTypes.def"
5534 case tok::kw_struct:
5535 case tok::kw___interface:
5541 case tok::annot_typename:
5546bool Parser::isTypeSpecifierQualifier() {
5547 switch (Tok.getKind()) {
5548 default:
return false;
5550 case tok::identifier:
5551 if (TryAltiVecVectorToken())
5554 case tok::kw_typename:
5559 if (Tok.is(tok::identifier))
5561 return isTypeSpecifierQualifier();
5563 case tok::coloncolon:
5570 return isTypeSpecifierQualifier();
5573 case tok::kw___attribute:
5575 case tok::kw_typeof:
5576 case tok::kw_typeof_unqual:
5581 case tok::kw___int64:
5582 case tok::kw___int128:
5583 case tok::kw_signed:
5584 case tok::kw_unsigned:
5585 case tok::kw__Complex:
5586 case tok::kw__Imaginary:
5589 case tok::kw_wchar_t:
5590 case tok::kw_char8_t:
5591 case tok::kw_char16_t:
5592 case tok::kw_char32_t:
5594 case tok::kw__ExtInt:
5595 case tok::kw__BitInt:
5597 case tok::kw___bf16:
5599 case tok::kw_double:
5600 case tok::kw__Accum:
5601 case tok::kw__Fract:
5602 case tok::kw__Float16:
5603 case tok::kw___float128:
5604 case tok::kw___ibm128:
5607 case tok::kw__Decimal32:
5608 case tok::kw__Decimal64:
5609 case tok::kw__Decimal128:
5610 case tok::kw___vector:
5611#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5612#include "clang/Basic/OpenCLImageTypes.def"
5613#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5614#include "clang/Basic/HLSLIntangibleTypes.def"
5618 case tok::kw_struct:
5619 case tok::kw___interface:
5626 case tok::kw_volatile:
5627 case tok::kw_restrict:
5631 case tok::kw___unknown_anytype:
5634 case tok::annot_typename:
5641 case tok::kw___cdecl:
5642 case tok::kw___stdcall:
5643 case tok::kw___fastcall:
5644 case tok::kw___thiscall:
5645 case tok::kw___regcall:
5646 case tok::kw___vectorcall:
5648 case tok::kw___ptr64:
5649 case tok::kw___ptr32:
5650 case tok::kw___pascal:
5651 case tok::kw___unaligned:
5652 case tok::kw___ptrauth:
5654 case tok::kw__Nonnull:
5655 case tok::kw__Nullable:
5656 case tok::kw__Nullable_result:
5657 case tok::kw__Null_unspecified:
5659 case tok::kw___kindof:
5661 case tok::kw___private:
5662 case tok::kw___local:
5663 case tok::kw___global:
5664 case tok::kw___constant:
5665 case tok::kw___generic:
5666 case tok::kw___read_only:
5667 case tok::kw___read_write:
5668 case tok::kw___write_only:
5669 case tok::kw___funcref:
5672 case tok::kw_private:
5676 case tok::kw__Atomic:
5680 case tok::kw_groupshared:
5689 assert(PP.isIncrementalProcessingEnabled() &&
"Not in incremental mode");
5693 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5696 TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5697 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5698 Actions.ActOnFinishTopLevelStmtDecl(TLSD, R.get());
5700 R = Actions.ActOnNullStmt(Tok.getLocation());
5702 if (Tok.is(tok::annot_repl_input_end) &&
5703 Tok.getAnnotationValue() !=
nullptr) {
5704 ConsumeAnnotationToken();
5708 SmallVector<Decl *, 2> DeclsInGroup;
5709 DeclsInGroup.push_back(TLSD);
5712 for (Stmt *S : Stmts) {
5715 TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5716 Actions.ActOnFinishTopLevelStmtDecl(D, S);
5717 DeclsInGroup.push_back(D);
5720 return Actions.BuildDeclaratorGroup(DeclsInGroup);
5723bool Parser::isDeclarationSpecifier(
5725 bool DisambiguatingWithExpression) {
5726 switch (Tok.getKind()) {
5727 default:
return false;
5734 case tok::identifier:
5738 if (TryAltiVecVectorToken())
5741 case tok::kw_decltype:
5742 case tok::kw_typename:
5747 if (TryAnnotateTypeConstraint())
5749 if (Tok.is(tok::identifier))
5757 if (DisambiguatingWithExpression &&
5758 isStartOfObjCClassMessageMissingOpenBracket())
5761 return isDeclarationSpecifier(AllowImplicitTypename);
5763 case tok::coloncolon:
5777 case tok::kw_typedef:
5778 case tok::kw_extern:
5779 case tok::kw___private_extern__:
5780 case tok::kw_static:
5782 case tok::kw___auto_type:
5783 case tok::kw_register:
5784 case tok::kw___thread:
5785 case tok::kw_thread_local:
5786 case tok::kw__Thread_local:
5789 case tok::kw___module_private__:
5792 case tok::kw___unknown_anytype:
5797 case tok::kw___int64:
5798 case tok::kw___int128:
5799 case tok::kw_signed:
5800 case tok::kw_unsigned:
5801 case tok::kw__Complex:
5802 case tok::kw__Imaginary:
5805 case tok::kw_wchar_t:
5806 case tok::kw_char8_t:
5807 case tok::kw_char16_t:
5808 case tok::kw_char32_t:
5811 case tok::kw__ExtInt:
5812 case tok::kw__BitInt:
5814 case tok::kw___bf16:
5816 case tok::kw_double:
5817 case tok::kw__Accum:
5818 case tok::kw__Fract:
5819 case tok::kw__Float16:
5820 case tok::kw___float128:
5821 case tok::kw___ibm128:
5824 case tok::kw__Decimal32:
5825 case tok::kw__Decimal64:
5826 case tok::kw__Decimal128:
5827 case tok::kw___vector:
5831 case tok::kw_struct:
5833 case tok::kw___interface:
5839 case tok::kw_volatile:
5840 case tok::kw_restrict:
5844 case tok::kw_inline:
5845 case tok::kw_virtual:
5846 case tok::kw_explicit:
5847 case tok::kw__Noreturn:
5850 case tok::kw__Alignas:
5853 case tok::kw_friend:
5856 case tok::kw_static_assert:
5857 case tok::kw__Static_assert:
5860 case tok::kw_typeof:
5861 case tok::kw_typeof_unqual:
5864 case tok::kw___attribute:
5867 case tok::annot_decltype:
5868 case tok::annot_pack_indexing_type:
5869 case tok::kw_constexpr:
5872 case tok::kw_consteval:
5873 case tok::kw_constinit:
5876 case tok::kw__Atomic:
5879 case tok::kw_alignas:
5889 case tok::annot_typename:
5890 return !DisambiguatingWithExpression ||
5891 !isStartOfObjCClassMessageMissingOpenBracket();
5894 case tok::annot_template_id: {
5895 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
5900 return isTypeConstraintAnnotation() &&
5904 case tok::annot_cxxscope: {
5905 TemplateIdAnnotation *TemplateId =
5913 if (
NextToken().
is(tok::identifier) && TryAnnotateTypeConstraint())
5915 return isTypeConstraintAnnotation() &&
5919 case tok::kw___declspec:
5920 case tok::kw___cdecl:
5921 case tok::kw___stdcall:
5922 case tok::kw___fastcall:
5923 case tok::kw___thiscall:
5924 case tok::kw___regcall:
5925 case tok::kw___vectorcall:
5927 case tok::kw___sptr:
5928 case tok::kw___uptr:
5929 case tok::kw___ptr64:
5930 case tok::kw___ptr32:
5931 case tok::kw___forceinline:
5932 case tok::kw___pascal:
5933 case tok::kw___unaligned:
5934 case tok::kw___ptrauth:
5936 case tok::kw__Nonnull:
5937 case tok::kw__Nullable:
5938 case tok::kw__Nullable_result:
5939 case tok::kw__Null_unspecified:
5941 case tok::kw___kindof:
5943 case tok::kw___private:
5944 case tok::kw___local:
5945 case tok::kw___global:
5946 case tok::kw___constant:
5947 case tok::kw___generic:
5948 case tok::kw___read_only:
5949 case tok::kw___read_write:
5950 case tok::kw___write_only:
5951#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5952#include "clang/Basic/OpenCLImageTypes.def"
5953#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5954#include "clang/Basic/HLSLIntangibleTypes.def"
5956 case tok::kw___funcref:
5957 case tok::kw_groupshared:
5960 case tok::kw_private:
5965bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
5967 const ParsedTemplateInfo *TemplateInfo) {
5968 RevertingTentativeParsingAction TPA(*
this);
5971 if (TemplateInfo && TemplateInfo->TemplateParams)
5974 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
5981 if (Tok.is(tok::identifier)) {
5985 }
else if (Tok.is(tok::annot_template_id)) {
5986 ConsumeAnnotationToken();
5993 SkipCXX11Attributes();
5996 if (Tok.isNot(tok::l_paren)) {
6003 if (Tok.is(tok::r_paren) ||
6004 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren))) {
6011 isCXX11AttributeSpecifier(
false,
6018 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6020 DeclScopeObj.EnterDeclaratorScope();
6023 ParsedAttributes Attrs(AttrFactory);
6024 MaybeParseMicrosoftAttributes(Attrs);
6033 bool IsConstructor =
false;
6039 if (Tok.is(tok::kw_this)) {
6041 return isDeclarationSpecifier(ITC);
6044 if (isDeclarationSpecifier(ITC))
6045 IsConstructor =
true;
6046 else if (Tok.is(tok::identifier) ||
6047 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier))) {
6052 if (Tok.is(tok::annot_cxxscope))
6053 ConsumeAnnotationToken();
6059 switch (Tok.getKind()) {
6065 case tok::coloncolon:
6078 SkipCXX11Attributes();
6080 if (DeductionGuide) {
6082 IsConstructor = Tok.is(tok::arrow);
6085 if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
6089 IsConstructor =
true;
6091 if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {
6104 IsConstructor = IsUnqualified;
6109 IsConstructor =
true;
6113 return IsConstructor;
6116void Parser::ParseTypeQualifierListOpt(
6117 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicOrPtrauthAllowed,
6119 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6120 isAllowedCXX11AttributeSpecifier()) {
6121 ParsedAttributes Attrs(AttrFactory);
6122 ParseCXX11Attributes(Attrs);
6126 SourceLocation EndLoc;
6130 const char *PrevSpec =
nullptr;
6131 unsigned DiagID = 0;
6132 SourceLocation Loc = Tok.getLocation();
6134 switch (Tok.getKind()) {
6135 case tok::code_completion:
6137 if (CodeCompletionHandler)
6138 CodeCompletionHandler();
6140 Actions.CodeCompletion().CodeCompleteTypeQualifiers(DS);
6147 case tok::kw_volatile:
6151 case tok::kw_restrict:
6155 case tok::kw__Atomic:
6156 if (!AtomicOrPtrauthAllowed)
6157 goto DoneWithTypeQuals;
6158 diagnoseUseOfC11Keyword(Tok);
6164 case tok::kw_private:
6166 goto DoneWithTypeQuals;
6168 case tok::kw___private:
6169 case tok::kw___global:
6170 case tok::kw___local:
6171 case tok::kw___constant:
6172 case tok::kw___generic:
6173 case tok::kw___read_only:
6174 case tok::kw___write_only:
6175 case tok::kw___read_write:
6179 case tok::kw_groupshared:
6188 case tok::kw___ptrauth:
6189 if (!AtomicOrPtrauthAllowed)
6190 goto DoneWithTypeQuals;
6192 EndLoc = PrevTokLocation;
6195 case tok::kw___unaligned:
6199 case tok::kw___uptr:
6204 if (TryKeywordIdentFallback(
false))
6208 case tok::kw___sptr:
6210 case tok::kw___ptr64:
6211 case tok::kw___ptr32:
6212 case tok::kw___cdecl:
6213 case tok::kw___stdcall:
6214 case tok::kw___fastcall:
6215 case tok::kw___thiscall:
6216 case tok::kw___regcall:
6217 case tok::kw___vectorcall:
6218 if (AttrReqs & AR_DeclspecAttributesParsed) {
6222 goto DoneWithTypeQuals;
6224 case tok::kw___funcref:
6228 case tok::kw___pascal:
6229 if (AttrReqs & AR_VendorAttributesParsed) {
6233 goto DoneWithTypeQuals;
6236 case tok::kw__Nonnull:
6237 case tok::kw__Nullable:
6238 case tok::kw__Nullable_result:
6239 case tok::kw__Null_unspecified:
6244 case tok::kw___kindof:
6246 AttributeScopeInfo(),
nullptr, 0,
6251 case tok::kw___attribute:
6252 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6254 Diag(Tok, diag::err_attributes_not_allowed);
6258 if (AttrReqs & AR_GNUAttributesParsed ||
6259 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6269 DS.
Finish(Actions, Actions.getASTContext().getPrintingPolicy());
6277 assert(PrevSpec &&
"Method did not return previous specifier!");
6278 Diag(Tok, DiagID) << PrevSpec;
6287 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6288 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6294 if (Kind == tok::star || Kind == tok::caret)
6298 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6299 Lang.getOpenCLCompatibleVersion() >= 200)
6302 if (!Lang.CPlusPlus)
6305 if (Kind == tok::amp)
6313 if (Kind == tok::ampamp)
6324 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6331void Parser::ParseDeclaratorInternal(
Declarator &D,
6332 DirectDeclParseFunction DirectDeclParser) {
6333 if (Diags.hasAllExtensionsSilenced())
6340 (Tok.is(tok::coloncolon) || Tok.is(tok::kw_decltype) ||
6341 (Tok.is(tok::identifier) &&
6343 Tok.is(tok::annot_cxxscope))) {
6344 TentativeParsingAction TPA(*
this,
true);
6350 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6360 Tok.is(tok::star)) {
6364 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6365 CompoundToken::MemberPtr);
6370 DeclSpec DS(AttrFactory);
6371 ParseTypeQualifierListOpt(DS);
6375 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6376 ParseDeclaratorInternal(D, DirectDeclParser);
6390 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6400 AnnotateScopeToken(SS,
true);
6402 if (DirectDeclParser)
6403 (this->*DirectDeclParser)(D);
6411 DeclSpec DS(AttrFactory);
6412 ParseTypeQualifierListOpt(DS);
6421 if (DirectDeclParser)
6422 (this->*DirectDeclParser)(D);
6431 if (Kind == tok::star || Kind == tok::caret) {
6433 DeclSpec DS(AttrFactory);
6437 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6439 ? AR_GNUAttributesParsed
6440 : AR_GNUAttributesParsedAndRejected);
6441 ParseTypeQualifierListOpt(DS, Reqs,
true,
6446 Actions.runWithSufficientStackSpace(
6447 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6448 if (Kind == tok::star)
6462 DeclSpec DS(AttrFactory);
6466 if (Kind == tok::ampamp)
6468 diag::warn_cxx98_compat_rvalue_reference :
6469 diag::ext_rvalue_reference);
6472 ParseTypeQualifierListOpt(DS);
6481 diag::err_invalid_reference_qualifier_application) <<
"const";
6484 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6488 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6492 Actions.runWithSufficientStackSpace(
6493 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6500 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6503 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6532void Parser::ParseDirectDeclarator(
Declarator &D) {
6539 return ParseDecompositionDeclarator(D);
6553 ParseOptionalCXXScopeSpecifier(
6555 false, EnteringContext);
6570 if (Actions.ShouldEnterDeclaratorScope(
getCurScope(),
6574 DeclScopeObj.EnterDeclaratorScope();
6581 goto PastIdentifier;
6597 !Actions.containsUnexpandedParameterPacks(D) &&
6605 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6615 if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6619 bool AllowConstructorName;
6620 bool AllowDeductionGuide;
6622 AllowConstructorName =
false;
6623 AllowDeductionGuide =
false;
6627 AllowDeductionGuide =
false;
6635 SourceLocation TemplateKWLoc;
6640 true, AllowConstructorName,
6641 AllowDeductionGuide, &TemplateKWLoc,
6654 DeclScopeObj.EnterDeclaratorScope();
6661 goto PastIdentifier;
6667 diag::err_expected_unqualified_id)
6670 goto PastIdentifier;
6674 "There's a C++-specific check for tok::identifier above");
6675 assert(Tok.getIdentifierInfo() &&
"Not an identifier?");
6676 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6679 goto PastIdentifier;
6684 bool DiagnoseIdentifier =
false;
6688 DiagnoseIdentifier =
true;
6691 DiagnoseIdentifier =
6699 !isCXX11VirtSpecifier(Tok))
6701 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6702 if (DiagnoseIdentifier) {
6703 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
6707 goto PastIdentifier;
6711 if (Tok.is(tok::l_paren)) {
6716 RevertingTentativeParsingAction PA(*
this);
6721 goto PastIdentifier;
6728 ParseParenDeclarator(D);
6741 DeclScopeObj.EnterDeclaratorScope();
6752 diag::ext_abstract_pack_declarator_parens);
6754 if (Tok.getKind() == tok::annot_pragma_parser_crash)
6756 if (Tok.is(tok::l_square))
6757 return ParseMisplacedBracketDeclarator(D);
6762 !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
6763 Tok.getIdentifierInfo()->isCPlusPlusKeyword(
getLangOpts())) {
6765 diag::err_expected_member_name_or_semi_objcxx_keyword)
6766 << Tok.getIdentifierInfo()
6769 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6772 goto PastIdentifier;
6775 diag::err_expected_member_name_or_semi)
6779 if (Tok.getKind() == tok::TokenKind::kw_while) {
6780 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6782 if (Tok.isOneOf(tok::period, tok::arrow))
6783 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
6786 if (Tok.isAtStartOfLine() && Loc.
isValid())
6787 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
6791 diag::err_expected_unqualified_id)
6796 diag::err_expected_either)
6797 << tok::identifier << tok::l_paren;
6806 "Haven't past the location of the identifier yet?");
6810 MaybeParseCXX11Attributes(D);
6813 if (Tok.is(tok::l_paren)) {
6819 (IsFunctionDeclaration
6825 bool IsAmbiguous =
false;
6837 AllowImplicitTypename =
6845 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
6846 bool IsFunctionDecl =
6847 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
6848 TentativelyDeclaredIdentifiers.pop_back();
6849 if (!IsFunctionDecl)
6852 ParsedAttributes attrs(AttrFactory);
6855 if (IsFunctionDeclaration)
6856 Actions.ActOnStartFunctionDeclarationDeclarator(D,
6857 TemplateParameterDepth);
6858 ParseFunctionDeclarator(D, attrs,
T, IsAmbiguous);
6859 if (IsFunctionDeclaration)
6860 Actions.ActOnFinishFunctionDeclarationDeclarator(D);
6861 PrototypeScope.Exit();
6862 }
else if (Tok.is(tok::l_square)) {
6863 ParseBracketDeclarator(D);
6864 }
else if (Tok.isRegularKeywordAttribute()) {
6866 Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();
6871 if (!
T.consumeOpen())
6882 Diag(Tok, diag::err_requires_clause_inside_parens);
6896void Parser::ParseDecompositionDeclarator(
Declarator &D) {
6897 assert(Tok.is(tok::l_square));
6899 TentativeParsingAction PA(*
this);
6904 DiagnoseAndSkipCXX11Attributes();
6908 if (!(Tok.isOneOf(tok::identifier, tok::ellipsis) &&
6910 tok::identifier, tok::l_square, tok::ellipsis)) &&
6911 !(Tok.is(tok::r_square) &&
6914 return ParseMisplacedBracketDeclarator(D);
6917 SourceLocation PrevEllipsisLoc;
6918 SmallVector<DecompositionDeclarator::Binding, 32>
Bindings;
6919 while (Tok.isNot(tok::r_square)) {
6921 if (Tok.is(tok::comma))
6924 if (Tok.is(tok::identifier)) {
6926 Diag(EndLoc, diag::err_expected)
6929 Diag(Tok, diag::err_expected_comma_or_rsquare);
6932 SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis},
6934 if (Tok.is(tok::comma))
6936 else if (Tok.is(tok::r_square))
6941 if (isCXX11AttributeSpecifier() !=
6943 DiagnoseAndSkipCXX11Attributes();
6945 SourceLocation EllipsisLoc;
6947 if (Tok.is(tok::ellipsis)) {
6949 : diag::ext_cxx_binding_pack);
6950 if (PrevEllipsisLoc.
isValid()) {
6951 Diag(Tok, diag::err_binding_multiple_ellipses);
6952 Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
6955 EllipsisLoc = Tok.getLocation();
6956 PrevEllipsisLoc = EllipsisLoc;
6960 if (Tok.isNot(tok::identifier)) {
6961 Diag(Tok, diag::err_expected) << tok::identifier;
6965 IdentifierInfo *II = Tok.getIdentifierInfo();
6966 SourceLocation Loc = Tok.getLocation();
6969 if (Tok.is(tok::ellipsis) && !PrevEllipsisLoc.
isValid()) {
6970 DiagnoseMisplacedEllipsis(Tok.getLocation(), Loc, EllipsisLoc.
isValid(),
6972 EllipsisLoc = Tok.getLocation();
6976 ParsedAttributes Attrs(AttrFactory);
6977 if (isCXX11AttributeSpecifier() !=
6980 ? diag::warn_cxx23_compat_decl_attrs_on_binding
6981 : diag::ext_decl_attrs_on_binding);
6982 MaybeParseCXX11Attributes(Attrs);
6985 Bindings.push_back({II, Loc, std::move(Attrs), EllipsisLoc});
6988 if (Tok.isNot(tok::r_square))
6995 Diag(Tok.getLocation(), diag::ext_decomp_decl_empty);
7003 T.getCloseLocation());
7006void Parser::ParseParenDeclarator(
Declarator &D) {
7010 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7022 ParsedAttributes attrs(AttrFactory);
7023 bool RequiresArg =
false;
7024 if (Tok.is(tok::kw___attribute)) {
7025 ParseGNUAttributes(attrs);
7033 ParseMicrosoftTypeAttributes(attrs);
7036 if (Tok.is(tok::kw___pascal))
7037 ParseBorlandTypeAttributes(attrs);
7049 }
else if (Tok.is(tok::r_paren) ||
7051 Tok.is(tok::ellipsis) &&
7053 isDeclarationSpecifier(
7055 isCXX11AttributeSpecifier() !=
7075 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7080 std::move(attrs),
T.getCloseLocation());
7086 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7103 ParseFunctionDeclarator(D, attrs,
T,
false, RequiresArg);
7104 PrototypeScope.Exit();
7107void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7109 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7117 bool IsCXX11MemberFunction =
7124 Actions.CurContext->isRecord());
7125 if (!IsCXX11MemberFunction)
7145 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,
7146 IsCXX11MemberFunction);
7149void Parser::ParseFunctionDeclarator(
Declarator &D,
7154 assert(
getCurScope()->isFunctionPrototypeScope() &&
7155 "Should call from a Function scope");
7161 bool HasProto =
false;
7163 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
7165 SourceLocation EllipsisLoc;
7167 DeclSpec DS(AttrFactory);
7168 bool RefQualifierIsLValueRef =
true;
7169 SourceLocation RefQualifierLoc;
7171 SourceRange ESpecRange;
7172 SmallVector<ParsedType, 2> DynamicExceptions;
7173 SmallVector<SourceRange, 2> DynamicExceptionRanges;
7176 ParsedAttributes FnAttrs(AttrFactory);
7178 SourceLocation TrailingReturnTypeLoc;
7183 SourceLocation StartLoc, LocalEndLoc, EndLoc;
7184 SourceLocation LParenLoc, RParenLoc;
7186 StartLoc = LParenLoc;
7188 if (isFunctionDeclaratorIdentifierList()) {
7190 Diag(Tok, diag::err_argument_required_after_attribute);
7192 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7196 LocalEndLoc = RParenLoc;
7201 MaybeParseCXX11Attributes(FnAttrs);
7202 ProhibitAttributes(FnAttrs);
7204 if (Tok.isNot(tok::r_paren))
7205 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7206 else if (RequiresArg)
7207 Diag(Tok, diag::err_argument_required_after_attribute);
7218 LocalEndLoc = RParenLoc;
7227 ParseTypeQualifierListOpt(
7228 DS, AR_NoAttributesParsed,
7231 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);
7238 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7239 EndLoc = RefQualifierLoc;
7241 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7242 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7259 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
7276 ESpecType = tryParseExceptionSpecification(Delayed,
7279 DynamicExceptionRanges,
7281 ExceptionSpecTokens);
7283 EndLoc = ESpecRange.
getEnd();
7287 MaybeParseCXX11Attributes(FnAttrs);
7290 LocalEndLoc = EndLoc;
7292 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7295 LocalEndLoc = Tok.getLocation();
7297 TrailingReturnType =
7299 TrailingReturnTypeLoc =
Range.getBegin();
7300 EndLoc =
Range.getEnd();
7303 MaybeParseCXX11Attributes(FnAttrs);
7311 SmallVector<NamedDecl *, 0> DeclsInPrototype;
7314 NamedDecl *ND = dyn_cast<NamedDecl>(D);
7317 DeclsInPrototype.push_back(ND);
7324 llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) {
7332 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7333 ParamInfo.size(), EllipsisLoc, RParenLoc,
7334 RefQualifierIsLValueRef, RefQualifierLoc,
7336 ESpecType, ESpecRange, DynamicExceptions.data(),
7337 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7338 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7339 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7340 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7342 std::move(FnAttrs), EndLoc);
7345bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7347 if (Tok.isOneOf(tok::amp, tok::ampamp)) {
7349 diag::warn_cxx98_compat_ref_qualifier :
7350 diag::ext_ref_qualifier);
7352 RefQualifierIsLValueRef = Tok.is(tok::amp);
7359bool Parser::isFunctionDeclaratorIdentifierList() {
7361 && Tok.is(tok::identifier)
7362 && !TryAltiVecVectorToken()
7378 && (!Tok.is(tok::eof) &&
7382void Parser::ParseFunctionDeclaratorIdentifierList(
7386 assert(!
getLangOpts().requiresStrictPrototypes() &&
7387 "Cannot parse an identifier list in C23 or C++");
7394 Diag(Tok, diag::ext_ident_list_in_param);
7397 llvm::SmallPtrSet<const IdentifierInfo *, 16> ParamsSoFar;
7401 if (Tok.isNot(tok::identifier)) {
7402 Diag(Tok, diag::err_expected) << tok::identifier;
7409 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
7412 if (Actions.getTypeName(*ParmII, Tok.getLocation(),
getCurScope()))
7413 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7416 if (!ParamsSoFar.insert(ParmII).second) {
7417 Diag(Tok, diag::err_param_redefinition) << ParmII;
7420 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7431void Parser::ParseParameterDeclarationClause(
7440 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7442 Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)
7461 IsACXXFunctionDeclaration) {
7473 DeclSpec DS(AttrFactory);
7475 ParsedAttributes ArgDeclAttrs(AttrFactory);
7476 ParsedAttributes ArgDeclSpecAttrs(AttrFactory);
7483 ArgDeclSpecAttrs.takeAllFrom(FirstArgAttrs);
7486 MaybeParseCXX11Attributes(ArgDeclAttrs);
7489 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7492 SourceLocation DSStart = Tok.getLocation();
7496 SourceLocation ThisLoc;
7500 ParsedTemplateInfo TemplateInfo;
7501 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7502 DeclSpecContext::DSC_normal,
7503 nullptr, AllowImplicitTypename);
7516 ParseDeclarator(ParmDeclarator);
7519 ParmDeclarator.SetRangeBegin(ThisLoc);
7522 MaybeParseGNUAttributes(ParmDeclarator);
7526 if (Tok.is(tok::kw_requires)) {
7531 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7537 const IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
7541 std::unique_ptr<CachedTokens> DefArgToks;
7545 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7546 ParmDeclarator.getNumTypeObjects() == 0) {
7548 Diag(DSStart, diag::err_missing_param);
7555 if (Tok.is(tok::ellipsis) &&
7557 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7558 !Actions.isUnexpandedParameterPackPermitted())) &&
7559 Actions.containsUnexpandedParameterPacks(ParmDeclarator))
7560 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7579 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7580 Tok.isNot(tok::raw_identifier) && !Tok.isAnnotation() &&
7581 Tok.getIdentifierInfo() &&
7582 Tok.getIdentifierInfo()->isKeyword(
getLangOpts())) {
7583 Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok);
7592 Diag(ParmDeclarator.getBeginLoc(),
7593 diag::err_function_parameter_limit_exceeded);
7601 Actions.ActOnParamDeclarator(
getCurScope(), ParmDeclarator, ThisLoc);
7606 if (Tok.is(tok::equal)) {
7607 SourceLocation EqualLoc = Tok.getLocation();
7617 ConsumeAndStoreInitializer(*DefArgToks,
7619 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
7627 EnterExpressionEvaluationContext Eval(
7634 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7635 DefArgResult = ParseBraceInitializer();
7637 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
7638 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7639 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7648 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7653 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
7654 DefArgResult.
get());
7659 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7660 ParmDeclarator.getIdentifierLoc(),
7661 Param, std::move(DefArgToks)));
7669 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
7676 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7678 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7679 Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {
7682 SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();
7683 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7684 << ParmEllipsis.
isValid() << ParmEllipsis;
7687 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7689 Diag(ParmDeclarator.getIdentifierLoc(),
7690 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7693 << !ParmDeclarator.hasName();
7695 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7707void Parser::ParseBracketDeclarator(
Declarator &D) {
7708 if (CheckProhibitedCXX11Attribute())
7716 if (Tok.getKind() == tok::r_square) {
7718 ParsedAttributes attrs(AttrFactory);
7719 MaybeParseCXX11Attributes(attrs);
7723 T.getOpenLocation(),
7724 T.getCloseLocation()),
7725 std::move(attrs),
T.getCloseLocation());
7727 }
else if (Tok.getKind() == tok::numeric_constant &&
7734 ParsedAttributes attrs(AttrFactory);
7735 MaybeParseCXX11Attributes(attrs);
7739 T.getOpenLocation(),
7740 T.getCloseLocation()),
7741 std::move(attrs),
T.getCloseLocation());
7743 }
else if (Tok.getKind() == tok::code_completion) {
7745 Actions.CodeCompletion().CodeCompleteBracketDeclarator(
getCurScope());
7750 SourceLocation StaticLoc;
7755 DeclSpec DS(AttrFactory);
7756 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
7764 bool isStar =
false;
7775 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7776 StaticLoc = SourceLocation();
7779 }
else if (Tok.isNot(tok::r_square)) {
7796 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7797 StaticLoc = SourceLocation();
7816 isStar, NumElements.
get(),
T.getOpenLocation(),
7817 T.getCloseLocation()),
7821void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
7822 assert(Tok.is(tok::l_square) &&
"Missing opening bracket");
7825 SourceLocation StartBracketLoc = Tok.getLocation();
7829 while (Tok.is(tok::l_square)) {
7830 ParseBracketDeclarator(TempDeclarator);
7836 if (Tok.is(tok::semi))
7839 SourceLocation SuggestParenLoc = Tok.getLocation();
7842 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7847 if (TempDeclarator.getNumTypeObjects() == 0)
7851 bool NeedParens =
false;
7870 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
7876 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
7877 const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
7878 D.
AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());
7883 if (!D.
hasName() && !NeedParens)
7886 SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();
7889 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
7890 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
7893 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7898 EndLoc, CharSourceRange(BracketRange,
true))
7901 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7904 EndLoc, CharSourceRange(BracketRange,
true))
7909void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
7910 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
7911 "Not a typeof specifier");
7913 bool IsUnqual = Tok.is(tok::kw_typeof_unqual);
7914 const IdentifierInfo *II = Tok.getIdentifierInfo();
7916 Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName();
7920 bool HasParens = Tok.is(tok::l_paren);
7928 SourceRange CastRange;
7930 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);
7946 const char *PrevSpec =
nullptr;
7953 Actions.getASTContext().getPrintingPolicy()))
7954 Diag(StartLoc, DiagID) << PrevSpec;
7965 Operand = Actions.HandleExprEvaluationContextForTypeof(
Operand.get());
7971 const char *PrevSpec =
nullptr;
7978 Actions.getASTContext().getPrintingPolicy()))
7979 Diag(StartLoc, DiagID) << PrevSpec;
7982void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
7983 assert(Tok.is(tok::kw__Atomic) &&
NextToken().
is(tok::l_paren) &&
7984 "Not an atomic specifier");
7988 if (
T.consumeOpen())
7992 if (
Result.isInvalid()) {
8000 if (
T.getCloseLocation().isInvalid())
8006 const char *PrevSpec =
nullptr;
8010 Actions.getASTContext().getPrintingPolicy()))
8011 Diag(StartLoc, DiagID) << PrevSpec;
8014bool Parser::TryAltiVecVectorTokenOutOfLine() {
8016 switch (
Next.getKind()) {
8017 default:
return false;
8020 case tok::kw_signed:
8021 case tok::kw_unsigned:
8026 case tok::kw_double:
8029 case tok::kw___bool:
8030 case tok::kw___pixel:
8031 Tok.setKind(tok::kw___vector);
8033 case tok::identifier:
8034 if (
Next.getIdentifierInfo() == Ident_pixel) {
8035 Tok.setKind(tok::kw___vector);
8038 if (
Next.getIdentifierInfo() == Ident_bool ||
8039 Next.getIdentifierInfo() == Ident_Bool) {
8040 Tok.setKind(tok::kw___vector);
8048 const char *&PrevSpec,
unsigned &DiagID,
8050 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
8051 if (Tok.getIdentifierInfo() == Ident_vector) {
8053 switch (
Next.getKind()) {
8056 case tok::kw_signed:
8057 case tok::kw_unsigned:
8062 case tok::kw_double:
8065 case tok::kw___bool:
8066 case tok::kw___pixel:
8069 case tok::identifier:
8070 if (
Next.getIdentifierInfo() == Ident_pixel) {
8074 if (
Next.getIdentifierInfo() == Ident_bool ||
8075 Next.getIdentifierInfo() == Ident_Bool) {
8084 }
else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
8088 }
else if ((Tok.getIdentifierInfo() == Ident_bool) &&
8096TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8099 SmallVector<Token, 4> Tokens;
8102 auto &SourceMgr = PP.getSourceManager();
8103 FileID FID = SourceMgr.createFileID(
8104 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8108 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8109 L.setParsingPreprocessorDirective(
true);
8115 Tokens.push_back(Tok);
8116 }
while (Tok.isNot(tok::eod));
8121 Token &EndToken = Tokens.back();
8128 Tokens.push_back(Tok);
8131 PP.EnterTokenStream(Tokens,
false,
8146 (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {
8147 Diag(Tok.getLocation(), diag::err_type_unparsed);
8152 while (Tok.isNot(tok::eof))
8156 if (Tok.is(tok::eof) && Tok.getEofData() == TypeStr.data())
8161void Parser::DiagnoseBitIntUse(
const Token &
Tok) {
8165 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8166 "expected either an _ExtInt or _BitInt token!");
8168 SourceLocation Loc = Tok.getLocation();
8169 if (Tok.is(tok::kw__ExtInt)) {
8170 Diag(Loc, diag::warn_ext_int_deprecated)
8176 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 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
void takeAttributesFrom(ParsedAttributes &attrs)
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 addAtEnd(ParsedAttr *newAttr)
void addAll(iterator B, iterator E)
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.
void takeAllFrom(ParsedAttributes &Other)
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.
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