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;
431 Expr = ParseUnevaluatedStringInAttribute(AttrName);
433 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
434 Expr = ParseBraceInitializer();
439 if (Tok.is(tok::ellipsis))
441 else if (Tok.is(tok::code_completion)) {
457 if (Actions.DiagnoseUnexpandedParameterPack(Expr.
get())) {
462 Exprs.push_back(Expr.
get());
464 if (Tok.isNot(tok::comma))
469 checkPotentialAngleBracketDelimiter(Comma);
476unsigned Parser::ParseAttributeArgsCommon(
485 bool AttributeIsTypeArgAttr =
487 bool AttributeHasVariadicIdentifierArg =
491 if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
492 Tok.setKind(tok::identifier);
495 if (Tok.is(tok::identifier)) {
497 bool IsIdentifierArg =
498 AttributeHasVariadicIdentifierArg ||
509 IsIdentifierArg =
Next.isOneOf(tok::r_paren, tok::comma);
513 ArgExprs.push_back(ParseIdentifierLoc());
517 if (!ArgExprs.empty() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren)) {
519 if (!ArgExprs.empty())
522 if (AttributeIsTypeArgAttr) {
530 TheParsedType = T.
get();
531 }
else if (AttributeHasVariadicIdentifierArg ||
541 if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
542 Tok.setKind(tok::identifier);
545 if (Tok.is(tok::identifier)) {
546 ArgExprs.push_back(ParseIdentifierLoc());
562 ArgExprs.push_back(ArgExpr.
get());
578 ExprVector ParsedExprs;
579 ParsedAttributeArgumentsProperties ArgProperties =
582 if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties,
589 for (
size_t I = 0; I < ParsedExprs.size(); ++I) {
594 Diag(Tok.getLocation(),
595 diag::err_attribute_argument_parm_pack_not_supported)
602 llvm::append_range(ArgExprs, ParsedExprs);
606 SourceLocation RParen = Tok.getLocation();
607 if (!ExpectAndConsume(tok::r_paren)) {
608 SourceLocation AttrLoc = ScopeLoc.
isValid() ? ScopeLoc : AttrNameLoc;
610 if (AttributeIsTypeArgAttr && !TheParsedType.
get().
isNull()) {
612 AttributeScopeInfo(ScopeName, ScopeLoc),
613 TheParsedType, Form);
615 Attrs.
addNew(AttrName, SourceRange(AttrLoc, RParen),
616 AttributeScopeInfo(ScopeName, ScopeLoc), ArgExprs.data(),
617 ArgExprs.size(), Form);
624 return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.
get().
isNull());
627void Parser::ParseGNUAttributeArgs(
632 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
637 if (AttrKind == ParsedAttr::AT_Availability) {
638 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
641 }
else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
642 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
643 ScopeName, ScopeLoc, Form);
645 }
else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
646 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
647 ScopeName, ScopeLoc, Form);
649 }
else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
650 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
653 }
else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
654 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
655 ScopeName, ScopeLoc, Form);
658 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName,
661 }
else if (AttrKind == ParsedAttr::AT_CountedBy ||
662 AttrKind == ParsedAttr::AT_CountedByOrNull ||
663 AttrKind == ParsedAttr::AT_SizedBy ||
664 AttrKind == ParsedAttr::AT_SizedByOrNull) {
665 ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
668 }
else if (AttrKind == ParsedAttr::AT_CXXAssume) {
669 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
670 ScopeLoc, EndLoc, Form);
676 std::optional<ParseScope> PrototypeScope;
683 for (
unsigned i = 0; i != FTI.
NumParams; ++i)
684 Actions.ActOnReenterCXXMethodParameter(
688 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
692unsigned Parser::ParseClangAttributeArgs(
696 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
703 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
704 ScopeName, ScopeLoc, Form);
705 case ParsedAttr::AT_ExternalSourceSymbol:
706 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
707 ScopeName, ScopeLoc, Form);
709 case ParsedAttr::AT_Availability:
710 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
713 case ParsedAttr::AT_ObjCBridgeRelated:
714 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
715 ScopeName, ScopeLoc, Form);
717 case ParsedAttr::AT_SwiftNewType:
718 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
721 case ParsedAttr::AT_TypeTagForDatatype:
722 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
723 ScopeName, ScopeLoc, Form);
726 case ParsedAttr::AT_CXXAssume:
727 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
728 ScopeLoc, EndLoc, Form);
731 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
737 unsigned ExistingAttrs = Attrs.
size();
749 SourceLocation OpenParenLoc = Tok.getLocation();
751 if (
AttrName->getName() ==
"property") {
757 T.expectAndConsume(diag::err_expected_lparen_after,
758 AttrName->getNameStart(), tok::r_paren);
765 IdentifierInfo *AccessorNames[] = {
nullptr,
nullptr};
766 bool HasInvalidAccessor =
false;
771 if (!Tok.is(tok::identifier)) {
773 if (Tok.is(tok::r_paren) && !HasInvalidAccessor &&
774 AccessorNames[AK_Put] ==
nullptr &&
775 AccessorNames[AK_Get] ==
nullptr) {
776 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
780 Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor);
785 SourceLocation KindLoc = Tok.getLocation();
786 StringRef KindStr = Tok.getIdentifierInfo()->getName();
787 if (KindStr ==
"get") {
789 }
else if (KindStr ==
"put") {
793 }
else if (KindStr ==
"set") {
794 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
801 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
803 HasInvalidAccessor =
true;
804 goto next_property_accessor;
808 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
809 HasInvalidAccessor =
true;
822 Diag(Tok.getLocation(), diag::err_ms_property_expected_equal)
828 if (!Tok.is(tok::identifier)) {
829 Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name);
833 if (Kind == AK_Invalid) {
835 }
else if (AccessorNames[Kind] !=
nullptr) {
837 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
839 AccessorNames[
Kind] = Tok.getIdentifierInfo();
843 next_property_accessor:
849 if (Tok.is(tok::r_paren))
852 Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen);
857 if (!HasInvalidAccessor)
859 AccessorNames[AK_Get], AccessorNames[AK_Put],
860 ParsedAttr::Form::Declspec());
862 return !HasInvalidAccessor;
866 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
867 SourceLocation(), ParsedAttr::Form::Declspec());
872 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) <<
AttrName;
879 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
880 assert(Tok.is(tok::kw___declspec) &&
"Not a declspec!");
882 SourceLocation StartLoc = Tok.getLocation();
883 SourceLocation EndLoc = StartLoc;
885 while (Tok.is(tok::kw___declspec)) {
888 if (T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
894 while (Tok.isNot(tok::r_paren)) {
899 if (Tok.is(tok::code_completion)) {
901 Actions.CodeCompletion().CodeCompleteAttribute(
908 bool IsString = Tok.getKind() == tok::string_literal;
909 if (!IsString && Tok.getKind() != tok::identifier &&
910 Tok.getKind() != tok::kw_restrict) {
911 Diag(Tok, diag::err_ms_declspec_type);
917 SourceLocation AttrNameLoc;
919 SmallString<8> StrBuffer;
920 bool Invalid =
false;
921 StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
926 AttrName = PP.getIdentifierInfo(Str);
927 AttrNameLoc = ConsumeStringToken();
933 bool AttrHandled =
false;
936 if (Tok.is(tok::l_paren))
937 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
938 else if (
AttrName->getName() ==
"property")
940 Diag(Tok.getLocation(), diag::err_expected_lparen_after)
944 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
945 ParsedAttr::Form::Declspec());
948 EndLoc = T.getCloseLocation();
951 Attrs.
Range = SourceRange(StartLoc, EndLoc);
957 auto Kind = Tok.getKind();
959 case tok::kw___fastcall:
960 case tok::kw___stdcall:
961 case tok::kw___thiscall:
962 case tok::kw___regcall:
963 case tok::kw___cdecl:
964 case tok::kw___vectorcall:
965 case tok::kw___ptr64:
967 case tok::kw___ptr32:
969 case tok::kw___uptr: {
970 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
972 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
983 assert(Tok.is(tok::kw___funcref));
984 SourceLocation StartLoc = Tok.getLocation();
987 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
991 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
993 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr,
994 0, tok::kw___funcref);
997void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
998 SourceLocation StartLoc = Tok.getLocation();
999 SourceLocation EndLoc = SkipExtendedMicrosoftTypeAttributes();
1002 SourceRange
Range(StartLoc, EndLoc);
1003 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) <<
Range;
1008 SourceLocation EndLoc;
1011 switch (Tok.getKind()) {
1013 case tok::kw_volatile:
1014 case tok::kw___fastcall:
1015 case tok::kw___stdcall:
1016 case tok::kw___thiscall:
1017 case tok::kw___cdecl:
1018 case tok::kw___vectorcall:
1019 case tok::kw___ptr32:
1020 case tok::kw___ptr64:
1022 case tok::kw___unaligned:
1023 case tok::kw___sptr:
1024 case tok::kw___uptr:
1035 while (Tok.is(tok::kw___pascal)) {
1036 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1038 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1045 while (Tok.is(tok::kw___kernel)) {
1046 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1048 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1054 while (Tok.is(tok::kw___noinline__)) {
1055 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1057 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1058 tok::kw___noinline__);
1063 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1064 SourceLocation AttrNameLoc = Tok.getLocation();
1065 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1069bool Parser::isHLSLQualifier(
const Token &
Tok)
const {
1070 return Tok.is(tok::kw_groupshared);
1074 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1075 auto Kind = Tok.getKind();
1077 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0, Kind);
1083 auto Kind = Tok.getKind();
1085 case tok::kw__Nonnull:
1086 case tok::kw__Nullable:
1087 case tok::kw__Nullable_result:
1088 case tok::kw__Null_unspecified: {
1089 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1092 Diag(AttrNameLoc, diag::ext_nullability)
1094 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1105 return (Separator ==
'.' || Separator ==
'_');
1108VersionTuple Parser::ParseVersionTuple(
SourceRange &Range) {
1109 Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());
1111 if (!Tok.is(tok::numeric_constant)) {
1112 Diag(Tok, diag::err_expected_version);
1115 return VersionTuple();
1122 SmallString<512> Buffer;
1123 Buffer.resize(Tok.getLength()+1);
1124 const char *ThisTokBegin = &Buffer[0];
1127 bool Invalid =
false;
1128 unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);
1130 return VersionTuple();
1133 unsigned AfterMajor = 0;
1135 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
1136 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
1140 if (AfterMajor == 0) {
1141 Diag(Tok, diag::err_expected_version);
1144 return VersionTuple();
1147 if (AfterMajor == ActualLength) {
1152 Diag(Tok, diag::err_zero_version);
1153 return VersionTuple();
1156 return VersionTuple(Major);
1159 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1161 || (AfterMajor + 1 == ActualLength)) {
1162 Diag(Tok, diag::err_expected_version);
1165 return VersionTuple();
1169 unsigned AfterMinor = AfterMajor + 1;
1171 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
1172 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
1176 if (AfterMinor == ActualLength) {
1180 if (Major == 0 && Minor == 0) {
1181 Diag(Tok, diag::err_zero_version);
1182 return VersionTuple();
1185 return VersionTuple(Major, Minor);
1188 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1191 Diag(Tok, diag::err_expected_version);
1194 return VersionTuple();
1198 if (AfterMajorSeparator != AfterMinorSeparator)
1199 Diag(Tok, diag::warn_expected_consistent_version_separator);
1202 unsigned AfterSubminor = AfterMinor + 1;
1203 unsigned Subminor = 0;
1204 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
1205 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
1209 if (AfterSubminor != ActualLength) {
1210 Diag(Tok, diag::err_expected_version);
1213 return VersionTuple();
1216 return VersionTuple(Major, Minor, Subminor);
1219void Parser::ParseAvailabilityAttribute(
1223 enum { Introduced, Deprecated, Obsoleted,
Unknown };
1224 AvailabilityChange Changes[
Unknown];
1226 IdentifierLoc *EnvironmentLoc =
nullptr;
1230 if (T.consumeOpen()) {
1231 Diag(Tok, diag::err_expected) << tok::l_paren;
1236 if (Tok.isNot(tok::identifier)) {
1237 Diag(Tok, diag::err_availability_expected_platform);
1241 IdentifierLoc *Platform = ParseIdentifierLoc();
1244 if (Ident->getName().contains(
"xrOS") || Ident->getName().contains(
"xros"))
1245 Diag(Platform->
getLoc(), diag::warn_availability_unknown_platform)
1248 else if (Ident->getName() ==
"macosx")
1252 else if (Ident->getName() ==
"macosx_app_extension")
1256 AvailabilityAttr::canonicalizePlatformName(Ident->getName())));
1260 if (ExpectAndConsume(tok::comma)) {
1267 if (!Ident_introduced) {
1268 Ident_introduced = PP.getIdentifierInfo(
"introduced");
1269 Ident_deprecated = PP.getIdentifierInfo(
"deprecated");
1270 Ident_obsoleted = PP.getIdentifierInfo(
"obsoleted");
1271 Ident_unavailable = PP.getIdentifierInfo(
"unavailable");
1272 Ident_message = PP.getIdentifierInfo(
"message");
1273 Ident_strict = PP.getIdentifierInfo(
"strict");
1274 Ident_replacement = PP.getIdentifierInfo(
"replacement");
1275 Ident_environment = PP.getIdentifierInfo(
"environment");
1280 SourceLocation UnavailableLoc, StrictLoc;
1282 if (Tok.isNot(tok::identifier)) {
1283 Diag(Tok, diag::err_availability_expected_change);
1287 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1290 if (
Keyword == Ident_strict) {
1292 Diag(KeywordLoc, diag::err_availability_redundant)
1293 <<
Keyword << SourceRange(StrictLoc);
1295 StrictLoc = KeywordLoc;
1299 if (
Keyword == Ident_unavailable) {
1300 if (UnavailableLoc.
isValid()) {
1301 Diag(KeywordLoc, diag::err_availability_redundant)
1302 <<
Keyword << SourceRange(UnavailableLoc);
1304 UnavailableLoc = KeywordLoc;
1311 if (Changes[Deprecated].KeywordLoc.
isValid()) {
1312 Diag(KeywordLoc, diag::err_availability_redundant)
1314 << SourceRange(Changes[Deprecated].KeywordLoc);
1319 Changes[Deprecated].
Version = VersionTuple(1);
1323 if (
Keyword == Ident_environment) {
1324 if (EnvironmentLoc !=
nullptr) {
1325 Diag(KeywordLoc, diag::err_availability_redundant)
1330 if (Tok.isNot(tok::equal)) {
1331 Diag(Tok, diag::err_expected_after) <<
Keyword << tok::equal;
1337 if (!isTokenStringLiteral()) {
1338 Diag(Tok, diag::err_expected_string_literal)
1343 if (
Keyword == Ident_message) {
1351 if (
Keyword == Ident_environment) {
1352 if (Tok.isNot(tok::identifier)) {
1353 Diag(Tok, diag::err_availability_expected_environment);
1357 EnvironmentLoc = ParseIdentifierLoc();
1363 if ((
Keyword == Ident_introduced ||
Keyword == Ident_deprecated) &&
1364 Tok.is(tok::identifier)) {
1365 IdentifierInfo *NA = Tok.getIdentifierInfo();
1368 if (
Keyword == Ident_introduced)
1369 UnavailableLoc = KeywordLoc;
1374 SourceRange VersionRange;
1375 VersionTuple Version = ParseVersionTuple(VersionRange);
1377 if (Version.empty()) {
1383 if (
Keyword == Ident_introduced)
1385 else if (
Keyword == Ident_deprecated)
1387 else if (
Keyword == Ident_obsoleted)
1393 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1394 Diag(KeywordLoc, diag::err_availability_redundant)
1396 << SourceRange(Changes[Index].KeywordLoc,
1397 Changes[Index].VersionRange.
getEnd());
1401 Changes[Index].
Version = Version;
1404 Diag(KeywordLoc, diag::err_availability_unknown_change)
1411 if (T.consumeClose())
1415 *endLoc = T.getCloseLocation();
1419 if (UnavailableLoc.
isValid()) {
1420 bool Complained =
false;
1421 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1422 if (Changes[Index].KeywordLoc.
isValid()) {
1424 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1425 << SourceRange(Changes[Index].KeywordLoc,
1426 Changes[Index].VersionRange.
getEnd());
1431 Changes[Index] = AvailabilityChange();
1437 attrs.
addNew(&Availability,
1438 SourceRange(AvailabilityLoc, T.getCloseLocation()),
1439 AttributeScopeInfo(ScopeName, ScopeLoc), Platform,
1440 Changes[Introduced], Changes[Deprecated], Changes[Obsoleted],
1441 UnavailableLoc, MessageExpr.
get(), Form, StrictLoc,
1442 ReplacementExpr.
get(), EnvironmentLoc);
1445void Parser::ParseExternalSourceSymbolAttribute(
1451 if (T.expectAndConsume())
1455 if (!Ident_language) {
1456 Ident_language = PP.getIdentifierInfo(
"language");
1457 Ident_defined_in = PP.getIdentifierInfo(
"defined_in");
1458 Ident_generated_declaration = PP.getIdentifierInfo(
"generated_declaration");
1459 Ident_USR = PP.getIdentifierInfo(
"USR");
1463 bool HasLanguage =
false;
1465 bool HasDefinedIn =
false;
1466 IdentifierLoc *GeneratedDeclaration =
nullptr;
1468 bool HasUSR =
false;
1472 if (Tok.isNot(tok::identifier)) {
1473 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1478 SourceLocation KeywordLoc = Tok.getLocation();
1479 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1480 if (
Keyword == Ident_generated_declaration) {
1481 if (GeneratedDeclaration) {
1482 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) <<
Keyword;
1486 GeneratedDeclaration = ParseIdentifierLoc();
1492 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1498 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1504 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1506 if (
Keyword == Ident_language)
1508 else if (
Keyword == Ident_USR)
1511 HasDefinedIn =
true;
1513 if (!isTokenStringLiteral()) {
1514 Diag(Tok, diag::err_expected_string_literal)
1519 : (
Keyword == Ident_defined_in ? 1 : 2));
1523 if (
Keyword == Ident_language) {
1525 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1531 }
else if (
Keyword == Ident_USR) {
1533 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1540 assert(
Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1542 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1552 if (T.consumeClose())
1555 *EndLoc = T.getCloseLocation();
1559 Attrs.
addNew(&ExternalSourceSymbol, SourceRange(Loc, T.getCloseLocation()),
1560 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1564void Parser::ParseObjCBridgeRelatedAttribute(
1570 if (T.consumeOpen()) {
1571 Diag(Tok, diag::err_expected) << tok::l_paren;
1576 if (Tok.isNot(tok::identifier)) {
1577 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1581 IdentifierLoc *RelatedClass = ParseIdentifierLoc();
1582 if (ExpectAndConsume(tok::comma)) {
1591 if (Tok.is(tok::identifier)) {
1594 Diag(Tok, diag::err_objcbridge_related_selector_name);
1600 if (Tok.is(tok::colon))
1601 Diag(Tok, diag::err_objcbridge_related_selector_name);
1603 Diag(Tok, diag::err_expected) << tok::comma;
1611 if (Tok.is(tok::identifier))
1613 else if (Tok.isNot(tok::r_paren)) {
1614 Diag(Tok, diag::err_expected) << tok::r_paren;
1620 if (T.consumeClose())
1624 *EndLoc = T.getCloseLocation();
1627 Attrs.
addNew(&ObjCBridgeRelated,
1628 SourceRange(ObjCBridgeRelatedLoc, T.getCloseLocation()),
1629 AttributeScopeInfo(ScopeName, ScopeLoc), RelatedClass,
1630 ClassMethod, InstanceMethod, Form);
1633void Parser::ParseSwiftNewTypeAttribute(
1640 if (T.consumeOpen()) {
1641 Diag(Tok, diag::err_expected) << tok::l_paren;
1645 if (Tok.is(tok::r_paren)) {
1646 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
1650 if (Tok.isNot(tok::kw_struct) && Tok.isNot(tok::kw_enum)) {
1651 Diag(Tok, diag::warn_attribute_type_not_supported)
1652 << &
AttrName << Tok.getIdentifierInfo();
1653 if (!isTokenSpecial())
1659 auto *SwiftType =
new (Actions.Context)
1660 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
1664 if (T.consumeClose())
1667 *EndLoc = T.getCloseLocation();
1670 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc, T.getCloseLocation()),
1671 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1675void Parser::ParseTypeTagForDatatypeAttribute(
1679 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1684 if (Tok.isNot(tok::identifier)) {
1685 Diag(Tok, diag::err_expected) << tok::identifier;
1689 IdentifierLoc *ArgumentKind = ParseIdentifierLoc();
1691 if (ExpectAndConsume(tok::comma)) {
1696 SourceRange MatchingCTypeRange;
1703 bool LayoutCompatible =
false;
1704 bool MustBeNull =
false;
1706 if (Tok.isNot(tok::identifier)) {
1707 Diag(Tok, diag::err_expected) << tok::identifier;
1711 IdentifierInfo *Flag = Tok.getIdentifierInfo();
1712 if (Flag->
isStr(
"layout_compatible"))
1713 LayoutCompatible =
true;
1714 else if (Flag->
isStr(
"must_be_null"))
1717 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1724 if (!T.consumeClose()) {
1726 &AttrName, AttrNameLoc, AttributeScopeInfo(ScopeName, ScopeLoc),
1727 ArgumentKind, MatchingCType.
get(), LayoutCompatible, MustBeNull, Form);
1731 *EndLoc = T.getCloseLocation();
1734bool Parser::DiagnoseProhibitedCXX11Attribute() {
1735 assert(Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square));
1737 switch (isCXX11AttributeSpecifier(
true)) {
1743 Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1748 SourceLocation BeginLoc = ConsumeBracket();
1751 assert(Tok.is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1752 SourceLocation EndLoc = ConsumeBracket();
1753 Diag(BeginLoc, diag::err_attributes_not_allowed)
1754 << SourceRange(BeginLoc, EndLoc);
1757 llvm_unreachable(
"All cases handled above.");
1762 assert((Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square)) ||
1763 Tok.is(tok::kw_alignas) || Tok.isRegularKeywordAttribute());
1767 Tok.isRegularKeywordAttribute() ? Tok.getIdentifierInfo() :
nullptr;
1768 SourceLocation Loc = Tok.getLocation();
1769 ParseCXX11Attributes(Attrs);
1770 CharSourceRange AttrRange(SourceRange(Loc, Attrs.
Range.
getEnd()),
true);
1773 :
Diag(Loc, diag::err_attributes_not_allowed))
1778void Parser::DiagnoseProhibitedAttributes(
1781 if (CorrectLocation.
isValid()) {
1782 CharSourceRange AttrRange(Attrs.
Range,
true);
1783 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1784 ?
Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1785 :
Diag(CorrectLocation, diag::err_attributes_misplaced))
1790 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1791 ?
Diag(
Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr
1792 :
Diag(
Range.getBegin(), diag::err_attributes_not_allowed))
1798 unsigned AttrDiagID,
1799 unsigned KeywordDiagID,
1800 bool DiagnoseEmptyAttrs,
1801 bool WarnOnUnknownAttrs) {
1807 auto &
SM = PP.getSourceManager();
1811 if (FirstLSquare.
is(tok::l_square)) {
1812 std::optional<Token> SecondLSquare =
1815 if (SecondLSquare && SecondLSquare->is(tok::l_square)) {
1825 for (
const ParsedAttr &AL : Attrs) {
1826 if (AL.isRegularKeywordAttribute()) {
1827 Diag(AL.getLoc(), KeywordDiagID) << AL;
1831 if (!AL.isStandardAttributeSyntax())
1834 if (WarnOnUnknownAttrs) {
1835 Actions.DiagnoseUnknownAttribute(AL);
1839 Diag(AL.getLoc(), AttrDiagID) << AL;
1846 for (
const ParsedAttr &PA : Attrs) {
1847 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1848 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1849 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
1858 llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;
1861 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1862 AL.isDeclspecAttribute()) ||
1863 AL.isMicrosoftAttribute())
1864 ToBeMoved.push_back(&AL);
1867 for (ParsedAttr *AL : ToBeMoved) {
1881 ObjCDeclContextSwitch ObjCDC(*
this);
1883 Decl *SingleDecl =
nullptr;
1884 switch (Tok.getKind()) {
1885 case tok::kw_template:
1886 case tok::kw_export:
1887 ProhibitAttributes(DeclAttrs);
1888 ProhibitAttributes(DeclSpecAttrs);
1889 return ParseDeclarationStartingWithTemplate(Context, DeclEnd, DeclAttrs);
1890 case tok::kw_inline:
1893 ProhibitAttributes(DeclAttrs);
1894 ProhibitAttributes(DeclSpecAttrs);
1896 return ParseNamespace(Context, DeclEnd, InlineLoc);
1898 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1899 true,
nullptr, DeclSpecStart);
1901 case tok::kw_cbuffer:
1902 case tok::kw_tbuffer:
1903 SingleDecl = ParseHLSLBuffer(DeclEnd, DeclAttrs);
1905 case tok::kw_namespace:
1906 ProhibitAttributes(DeclAttrs);
1907 ProhibitAttributes(DeclSpecAttrs);
1908 return ParseNamespace(Context, DeclEnd);
1909 case tok::kw_using: {
1911 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1912 DeclEnd, DeclAttrs);
1914 case tok::kw_static_assert:
1915 case tok::kw__Static_assert:
1916 ProhibitAttributes(DeclAttrs);
1917 ProhibitAttributes(DeclSpecAttrs);
1918 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1921 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1922 true,
nullptr, DeclSpecStart);
1927 return Actions.ConvertDeclToDeclGroup(SingleDecl);
1933 bool RequireSemi, ForRangeInit *FRI,
SourceLocation *DeclSpecStart) {
1935 ParsedAttributesView OriginalDeclSpecAttrs;
1936 OriginalDeclSpecAttrs.
prepend(DeclSpecAttrs.
begin(), DeclSpecAttrs.
end());
1937 OriginalDeclSpecAttrs.
Range = DeclSpecAttrs.
Range;
1940 ParsingDeclSpec DS(*
this);
1943 ParsedTemplateInfo TemplateInfo;
1944 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
1945 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none, DSContext);
1950 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
1955 if (Tok.is(tok::semi)) {
1956 ProhibitAttributes(DeclAttrs);
1957 DeclEnd = Tok.getLocation();
1959 RecordDecl *AnonRecord =
nullptr;
1960 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
1962 Actions.ActOnDefinedDeclarationSpecifier(TheDecl);
1963 DS.complete(TheDecl);
1965 Decl* decls[] = {AnonRecord, TheDecl};
1966 return Actions.BuildDeclaratorGroup(decls);
1968 return Actions.ConvertDeclToDeclGroup(TheDecl);
1972 Actions.ActOnDefinedDeclarationSpecifier(DS.
getRepAsDecl());
1977 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
1981 switch (Tok.getKind()) {
1982 case tok::annot_cxxscope:
1983 case tok::annot_template_id:
1985 case tok::code_completion:
1986 case tok::coloncolon:
1988 case tok::kw___attribute:
1989 case tok::kw_operator:
2005 case tok::identifier:
2007 case tok::code_completion:
2008 case tok::coloncolon:
2011 case tok::equalequal:
2012 case tok::kw_alignas:
2014 case tok::kw___attribute:
2032 case tok::identifier:
2036 return Tok.isRegularKeywordAttribute();
2040 return Tok.isRegularKeywordAttribute();
2046 switch (Tok.getKind()) {
2052 if (Tok.isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
2076 case tok::kw_inline:
2080 if (Tok.isAtStartOfLine() &&
NextToken().
is(tok::kw_namespace) &&
2081 (!ParsingInObjCContainer || CurParsedObjCImpl))
2085 case tok::kw_extern:
2088 case tok::kw_namespace:
2092 if (Tok.isAtStartOfLine() &&
2093 (!ParsingInObjCContainer || CurParsedObjCImpl))
2099 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2100 ParsingInObjCContainer)
2107 if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
2112 case tok::annot_module_begin:
2113 case tok::annot_module_end:
2114 case tok::annot_module_include:
2115 case tok::annot_repl_input_end:
2129 ParsedTemplateInfo &TemplateInfo,
2131 ForRangeInit *FRI) {
2137 LocalAttrs.takeAllPrependingFrom(Attrs);
2139 if (TemplateInfo.TemplateParams)
2142 bool IsTemplateSpecOrInst =
2149 if (IsTemplateSpecOrInst)
2159 while (MaybeParseHLSLAnnotations(D))
2162 if (
Tok.is(tok::kw_requires))
2163 ParseTrailingRequiresClause(D);
2168 LateParsedAttrList LateParsedAttrs(
true);
2170 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2175 if (
Tok.is(tok::kw__Noreturn)) {
2177 const char *PrevSpec;
2183 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2184 Fixit &=
Tok.isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2186 Diag(Loc, diag::err_c11_noreturn_misplaced)
2188 << (Fixit ?
FixItHint::CreateInsertion(D.getBeginLoc(),
"_Noreturn ")
2193 if (Tok.is(tok::equal) &&
NextToken().
is(tok::code_completion)) {
2195 Actions.CodeCompletion().CodeCompleteAfterFunctionEquals(D);
2204 while (
auto Specifier = isCXX11VirtSpecifier()) {
2205 Diag(Tok, diag::err_virt_specifier_outside_class)
2213 if (!isDeclarationAfterDeclarator()) {
2219 if (isStartOfFunctionDefinition(D)) {
2229 diag::err_function_declared_typedef)
2233 Decl *TheDecl =
nullptr;
2239 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2240 TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(),
2243 SourceLocation LAngleLoc =
2244 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2246 diag::err_explicit_instantiation_with_definition)
2247 << SourceRange(TemplateInfo.TemplateLoc)
2252 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2253 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
2254 LAngleLoc,
nullptr));
2256 TheDecl = ParseFunctionDefinition(
2258 ParsedTemplateInfo(&FakedParamLists,
2265 ParseFunctionDefinition(D, TemplateInfo, &LateParsedAttrs);
2268 return Actions.ConvertDeclToDeclGroup(TheDecl);
2272 Tok.is(tok::kw_namespace)) {
2282 Diag(Tok, diag::err_expected_fn_body);
2287 if (Tok.is(tok::l_brace)) {
2288 Diag(Tok, diag::err_function_definition_not_allowed);
2296 if (ParseAsmAttributesAfterDeclarator(D))
2305 if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
2306 bool IsForRangeLoop =
false;
2308 IsForRangeLoop =
true;
2309 EnterExpressionEvaluationContext ForRangeInitContext(
2317 auto &LastRecord = Actions.currentEvaluationContext();
2318 LastRecord.InLifetimeExtendingContext =
true;
2319 LastRecord.RebuildDefaultArgOrDefaultInit =
true;
2323 Actions.OpenMP().startOpenMPCXXRangeFor();
2324 if (Tok.is(tok::l_brace))
2325 FRI->RangeExpr = ParseBraceInitializer();
2332 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
2336 FRI->LifetimeExtendTemps = std::move(
2337 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps);
2341 if (IsForRangeLoop) {
2342 Actions.ActOnCXXForRangeDecl(ThisDecl);
2345 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2346 VD->setObjCForDecl(
true);
2348 Actions.FinalizeDeclaration(ThisDecl);
2349 D.complete(ThisDecl);
2350 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, ThisDecl);
2353 SmallVector<Decl *, 8> DeclsInGroup;
2355 ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo, FRI);
2356 if (LateParsedAttrs.size() > 0)
2357 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2358 D.complete(FirstDecl);
2360 DeclsInGroup.push_back(FirstDecl);
2366 SourceLocation CommaLoc;
2368 if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2372 Diag(CommaLoc, diag::err_expected_semi_declaration)
2384 Diag(CommaLoc, diag::err_multiple_template_declarators)
2385 << TemplateInfo.Kind;
2399 MaybeParseGNUAttributes(D);
2403 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2408 MaybeParseHLSLAnnotations(D);
2415 if (Tok.is(tok::kw_requires))
2416 ParseTrailingRequiresClause(D);
2417 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D, TemplateInfo);
2418 D.complete(ThisDecl);
2420 DeclsInGroup.push_back(ThisDecl);
2425 *DeclEnd = Tok.getLocation();
2427 if (ExpectSemi && ExpectAndConsumeSemi(
2429 ? diag::err_invalid_token_after_toplevel_declarator
2430 : diag::err_expected_semi_declaration)) {
2438 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
2441bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &D) {
2443 if (Tok.is(tok::kw_asm)) {
2445 ExprResult AsmLabel(ParseSimpleAsm(
true, &Loc));
2446 if (AsmLabel.isInvalid()) {
2455 MaybeParseGNUAttributes(D);
2459Decl *Parser::ParseDeclarationAfterDeclarator(
2460 Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
2461 if (ParseAsmAttributesAfterDeclarator(D))
2464 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
2467Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2468 Declarator &D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2470 struct InitializerScopeRAII {
2476 InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl)
2477 : P(P), D(D), ThisDecl(ThisDecl), Entered(
false) {
2480 if (D.getCXXScopeSpec().isSet()) {
2482 S = P.getCurScope();
2485 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2490 ~InitializerScopeRAII() {
2506 InitKind TheInitKind;
2508 if (isTokenEqualOrEqualTypo())
2509 TheInitKind = InitKind::Equal;
2510 else if (
Tok.
is(tok::l_paren))
2511 TheInitKind = InitKind::CXXDirect;
2514 TheInitKind = InitKind::CXXBraced;
2516 TheInitKind = InitKind::Uninitialized;
2517 if (TheInitKind != InitKind::Uninitialized)
2521 Decl *ThisDecl =
nullptr;
2522 Decl *OuterDecl =
nullptr;
2523 switch (TemplateInfo.Kind) {
2525 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2530 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
2531 *TemplateInfo.TemplateParams,
2533 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2536 ThisDecl = VT->getTemplatedDecl();
2542 if (
Tok.
is(tok::semi)) {
2543 DeclResult ThisRes = Actions.ActOnExplicitInstantiation(
2544 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
2546 SkipUntil(tok::semi, StopBeforeMatch);
2549 ThisDecl = ThisRes.
get();
2557 Diag(
Tok, diag::err_template_defn_explicit_instantiation)
2559 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2562 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2564 diag::err_explicit_instantiation_with_definition)
2569 TemplateParameterLists FakedParamLists;
2570 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2572 LAngleLoc,
nullptr));
2575 Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D);
2584 switch (TheInitKind) {
2586 case InitKind::Equal: {
2589 if (
Tok.
is(tok::kw_delete)) {
2591 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2594 Diag(ConsumeToken(), diag::err_deleted_non_function);
2595 SkipDeletedFunctionBody();
2596 }
else if (
Tok.
is(tok::kw_default)) {
2598 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2601 Diag(ConsumeToken(), diag::err_default_special_members)
2602 << getLangOpts().CPlusPlus20;
2604 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2606 if (
Tok.
is(tok::code_completion)) {
2608 Actions.CodeCompletion().CodeCompleteInitializer(getCurScope(),
2610 Actions.FinalizeDeclaration(ThisDecl);
2620 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2624 FRI->ColonLoc = EqualLoc;
2626 FRI->RangeExpr =
Init;
2629 if (
Init.isInvalid()) {
2631 StopTokens.push_back(tok::comma);
2634 StopTokens.push_back(tok::r_paren);
2635 SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch);
2636 Actions.ActOnInitializerError(ThisDecl);
2638 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
2643 case InitKind::CXXDirect: {
2650 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2652 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2653 auto RunSignatureHelp = [&]() {
2655 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2656 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2657 ThisDecl->
getLocation(), Exprs, T.getOpenLocation(),
2659 CalledSignatureHelp =
true;
2660 return PreferredType;
2662 auto SetPreferredType = [&] {
2663 PreferredType.enterFunctionArgument(
Tok.
getLocation(), RunSignatureHelp);
2666 llvm::function_ref<void()> ExpressionStarts;
2672 ExpressionStarts = SetPreferredType;
2675 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2678 if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
2679 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2680 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2681 ThisDecl->
getLocation(), Exprs, T.getOpenLocation(),
2683 CalledSignatureHelp =
true;
2685 Actions.ActOnInitializerError(ThisDecl);
2686 SkipUntil(tok::r_paren, StopAtSemi);
2692 T.getCloseLocation(),
2694 Actions.AddInitializerToDecl(ThisDecl,
Initializer.get(),
2699 case InitKind::CXXBraced: {
2701 Diag(
Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2703 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2708 if (
Init.isInvalid()) {
2709 Actions.ActOnInitializerError(ThisDecl);
2711 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
true);
2714 case InitKind::Uninitialized: {
2715 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2716 Actions.ActOnUninitializedDecl(ThisDecl);
2721 Actions.FinalizeDeclaration(ThisDecl);
2722 return OuterDecl ? OuterDecl : ThisDecl;
2725void Parser::ParseSpecifierQualifierList(
2728 ParsedTemplateInfo TemplateInfo;
2732 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC,
nullptr,
2733 AllowImplicitTypename);
2738 Diag(Tok, diag::err_expected_type);
2741 Diag(Tok, diag::err_typename_requires_specqual);
2752 diag::err_typename_invalid_storageclass);
2796 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2797 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2802 ParsedTemplateInfo &TemplateInfo,
2805 assert(Tok.is(tok::identifier) &&
"should have identifier");
2807 SourceLocation Loc = Tok.getLocation();
2827 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
2845 AnnotateScopeToken(*SS,
false);
2854 if (
ParsedType T = Actions.ActOnMSVCUnknownTypeName(
2855 *Tok.getIdentifierInfo(), Tok.getLocation(),
2856 DSC == DeclSpecContext::DSC_template_type_arg)) {
2857 const char *PrevSpec;
2860 Actions.getASTContext().getPrintingPolicy());
2873 if (SS ==
nullptr) {
2874 const char *TagName =
nullptr, *FixitTagName =
nullptr;
2877 switch (Actions.isTagName(*Tok.getIdentifierInfo(),
getCurScope())) {
2880 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
2882 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
2884 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
2886 TagName=
"__interface"; FixitTagName =
"__interface ";
2887 TagKind=tok::kw___interface;
break;
2889 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
2893 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
2894 LookupResult R(Actions, TokenName, SourceLocation(),
2897 Diag(Loc, diag::err_use_of_tag_name_without_tag)
2898 << TokenName << TagName <<
getLangOpts().CPlusPlus
2904 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2905 << TokenName << TagName;
2909 if (TagKind == tok::kw_enum)
2910 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,
2911 DeclSpecContext::DSC_normal);
2913 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
2915 DeclSpecContext::DSC_normal, Attrs);
2922 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
2923 DSC == DeclSpecContext::DSC_class)) {
2927 case tok::l_paren: {
2934 TentativeParsingAction PA(*
this);
2936 TPResult TPR = TryParseDeclarator(
false);
2939 if (TPR != TPResult::False) {
2947 if (DSC == DeclSpecContext::DSC_class ||
2948 (DSC == DeclSpecContext::DSC_top_level && SS)) {
2949 IdentifierInfo *II = Tok.getIdentifierInfo();
2950 if (Actions.isCurrentClassNameTypo(II, SS)) {
2951 Diag(Loc, diag::err_constructor_bad_name)
2952 << Tok.getIdentifierInfo() << II
2954 Tok.setIdentifierInfo(II);
2972 AnnotateScopeToken(*SS,
false);
2986 IdentifierInfo *II = Tok.getIdentifierInfo();
2988 Actions.DiagnoseUnknownTypeName(II, Loc,
getCurScope(), SS, T,
2994 const char *PrevSpec;
2997 Actions.getASTContext().getPrintingPolicy());
3002 }
else if (II != Tok.getIdentifierInfo()) {
3015 if (IsTemplateName) {
3016 SourceLocation LAngle, RAngle;
3017 TemplateArgList Args;
3018 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3027Parser::DeclSpecContext
3031 return DeclSpecContext::DSC_class;
3033 return DeclSpecContext::DSC_top_level;
3035 return DeclSpecContext::DSC_template_param;
3037 return DeclSpecContext::DSC_template_arg;
3039 return DeclSpecContext::DSC_template_type_arg;
3042 return DeclSpecContext::DSC_trailing;
3045 return DeclSpecContext::DSC_alias_declaration;
3047 return DeclSpecContext::DSC_association;
3049 return DeclSpecContext::DSC_type_specifier;
3051 return DeclSpecContext::DSC_condition;
3053 return DeclSpecContext::DSC_conv_operator;
3055 return DeclSpecContext::DSC_new;
3070 return DeclSpecContext::DSC_normal;
3073 llvm_unreachable(
"Missing DeclaratorContext case");
3080 if (isTypeIdInParens()) {
3081 SourceLocation TypeLoc = Tok.getLocation();
3083 SourceRange TypeRange(Start, Tok.getLocation());
3084 if (Actions.ActOnAlignasTypeArgument(KWName, Ty, TypeLoc, TypeRange))
3101 assert(Tok.isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3102 "Not an alignment-specifier!");
3109 if (T.expectAndConsume())
3114 SourceLocation EllipsisLoc;
3116 ParseAlignArgument(PP.getSpelling(KWTok), T.getOpenLocation(),
3125 *EndLoc = T.getCloseLocation();
3132 ArgExprs.push_back(ArgExpr.
get());
3133 Attrs.
addNew(KWName, KWLoc, AttributeScopeInfo(), ArgExprs.data(), 1, Kind,
3138void Parser::DistributeCLateParsedAttrs(
Decl *Dcl,
3139 LateParsedAttrList *LateAttrs) {
3144 for (
auto *LateAttr : *LateAttrs) {
3145 if (LateAttr->Decls.empty())
3146 LateAttr->addDecl(Dcl);
3152 assert(Tok.is(tok::kw___ptrauth));
3154 IdentifierInfo *KwName = Tok.getIdentifierInfo();
3158 if (T.expectAndConsume())
3168 ArgExprs.push_back(ER.
get());
3172 SourceLocation EndLoc = T.getCloseLocation();
3174 if (ArgExprs.empty() || ArgExprs.size() > 3) {
3175 Diag(KwLoc, diag::err_ptrauth_qualifier_bad_arg_count);
3179 Attrs.
addNew(KwName, SourceRange(KwLoc, EndLoc), AttributeScopeInfo(),
3180 ArgExprs.data(), ArgExprs.size(),
3181 ParsedAttr::Form::Keyword(
false,
3191 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3196 if (Tok.is(tok::r_paren)) {
3197 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
3204 using ExpressionKind =
3206 EnterExpressionEvaluationContext EC(
3208 ExpressionKind::EK_AttrArgument);
3216 ArgExprs.push_back(ArgExpr.
get());
3219 ASTContext &Ctx = Actions.getASTContext();
3225 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
3226 AttributeScopeInfo(), ArgExprs.data(), ArgExprs.size(), Form);
3229ExprResult Parser::ParseExtIntegerArgument() {
3230 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3231 "Not an extended int type");
3235 if (T.expectAndConsume())
3244 if(T.consumeClose())
3251 DeclSpecContext DSContext,
3252 LateParsedAttrList *LateAttrs) {
3255 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3256 DSContext == DeclSpecContext::DSC_top_level);
3259 Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
3260 tok::annot_template_id) &&
3266 bool HasScope = Tok.is(tok::annot_cxxscope);
3268 Token AfterScope = HasScope ?
NextToken() : Tok;
3272 bool MightBeDeclarator =
true;
3273 if (Tok.isOneOf(tok::kw_typename, tok::annot_typename)) {
3275 MightBeDeclarator =
false;
3276 }
else if (AfterScope.
is(tok::annot_template_id)) {
3279 TemplateIdAnnotation *Annot =
3282 MightBeDeclarator =
false;
3283 }
else if (AfterScope.
is(tok::identifier)) {
3288 if (
Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3289 tok::annot_cxxscope, tok::coloncolon)) {
3291 MightBeDeclarator = false;
3292 }
else if (HasScope) {
3297 Actions.RestoreNestedNameSpecifierAnnotation(
3298 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
3300 Sema::NameClassification Classification = Actions.ClassifyName(
3303 switch (Classification.
getKind()) {
3309 llvm_unreachable(
"typo correction is not possible here");
3317 MightBeDeclarator =
false;
3332 if (MightBeDeclarator)
3335 const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
3337 diag::err_expected_after)
3348 ParsedTemplateInfo NotATemplate;
3349 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3353void Parser::ParseDeclarationSpecifiers(
3355 DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
3367 if (DSContext == DeclSpecContext::DSC_conv_operator) {
3370 DSContext = DeclSpecContext::DSC_type_specifier;
3373 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3374 DSContext == DeclSpecContext::DSC_top_level);
3375 bool AttrsLastTime =
false;
3376 ParsedAttributes attrs(AttrFactory);
3378 PrintingPolicy Policy = Actions.getPrintingPolicy();
3381 bool isStorageClass =
false;
3382 const char *PrevSpec =
nullptr;
3383 unsigned DiagID = 0;
3387 SourceLocation ConsumedEnd;
3396 if (
getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&
3399 Tok.setKind(tok::identifier);
3401 SourceLocation Loc = Tok.getLocation();
3404 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3408 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
3409 Tok.setKind(tok::identifier);
3418 bool IsTemplateSpecOrInst =
3422 switch (Tok.getKind()) {
3424 if (Tok.isRegularKeywordAttribute())
3429 ProhibitAttributes(attrs);
3432 for (
const ParsedAttr &PA : attrs) {
3433 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3434 !PA.isRegularKeywordAttribute())
3442 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3443 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3450 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3451 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3454 if (PA.getKind() == ParsedAttr::AT_LifetimeBound)
3455 Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type)
3456 << PA << PA.isRegularKeywordAttribute()
3459 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3460 << PA << PA.isRegularKeywordAttribute();
3469 DS.
Finish(Actions, Policy);
3473 case tok::kw__Alignas:
3474 diagnoseUseOfC11Keyword(Tok);
3476 case tok::kw_alignas:
3482 if (Tok.getKind() == tok::kw_alignas)
3483 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
3489 if (!isAllowedCXX11AttributeSpecifier())
3490 goto DoneWithDeclSpec;
3493 ProhibitAttributes(attrs);
3498 attrs.Range = SourceRange();
3500 ParseCXX11Attributes(attrs);
3501 AttrsLastTime =
true;
3504 case tok::code_completion: {
3508 bool AllowNonIdentifiers
3514 bool AllowNestedNameSpecifiers
3515 = DSContext == DeclSpecContext::DSC_top_level ||
3519 Actions.CodeCompletion().CodeCompleteDeclSpec(
3520 getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3526 CCC = DSContext == DeclSpecContext::DSC_class
3529 else if (DSContext == DeclSpecContext::DSC_class)
3533 else if (CurParsedObjCImpl)
3537 Actions.CodeCompletion().CodeCompleteOrdinaryName(
getCurScope(), CCC);
3541 case tok::coloncolon:
3547 goto DoneWithDeclSpec;
3549 if (Tok.is(tok::coloncolon))
3550 goto DoneWithDeclSpec;
3553 case tok::annot_cxxscope: {
3555 goto DoneWithDeclSpec;
3558 if (TemplateInfo.TemplateParams)
3560 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
3561 Tok.getAnnotationRange(),
3567 TemplateIdAnnotation *TemplateId =
Next.is(tok::annot_template_id)
3568 ? takeTemplateIdAnnotation(
Next)
3574 ConsumeAnnotationToken();
3588 if ((DSContext == DeclSpecContext::DSC_top_level ||
3589 DSContext == DeclSpecContext::DSC_class) &&
3592 isConstructorDeclarator(
false,
3599 goto DoneWithDeclSpec;
3603 ConsumeAnnotationToken();
3604 assert(Tok.is(tok::annot_template_id) &&
3605 "ParseOptionalCXXScopeSpecifier not working");
3606 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3616 ConsumeAnnotationToken();
3620 if (
Next.is(tok::annot_typename)) {
3622 ConsumeAnnotationToken();
3625 Tok.getAnnotationEndLoc(),
3626 PrevSpec, DiagID, T, Policy);
3630 ConsumeAnnotationToken();
3634 Next.is(tok::annot_template_id) &&
3635 static_cast<TemplateIdAnnotation *
>(
Next.getAnnotationValue())
3638 ConsumeAnnotationToken();
3639 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3643 if (
Next.isNot(tok::identifier))
3644 goto DoneWithDeclSpec;
3649 if ((DSContext == DeclSpecContext::DSC_top_level ||
3650 DSContext == DeclSpecContext::DSC_class) &&
3653 isConstructorDeclarator(
false,
3657 goto DoneWithDeclSpec;
3663 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3667 false,
false,
nullptr,
3670 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3672 if (IsTemplateSpecOrInst)
3680 if (TryAnnotateTypeConstraint())
3681 goto DoneWithDeclSpec;
3682 if (Tok.isNot(tok::annot_cxxscope) ||
3686 ConsumeAnnotationToken();
3687 ParsedAttributes Attrs(AttrFactory);
3688 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3689 if (!Attrs.
empty()) {
3690 AttrsLastTime =
true;
3691 attrs.takeAllAppendingFrom(Attrs);
3695 goto DoneWithDeclSpec;
3699 ConsumeAnnotationToken();
3702 DiagID, TypeRep, Policy);
3712 case tok::annot_typename: {
3716 goto DoneWithDeclSpec;
3725 ConsumeAnnotationToken();
3730 case tok::kw___is_signed:
3742 TryKeywordIdentFallback(
true);
3745 goto DoneWithDeclSpec;
3748 case tok::kw___super:
3749 case tok::kw_decltype:
3750 case tok::identifier:
3756 goto DoneWithDeclSpec;
3762 if (!
getLangOpts().DeclSpecKeyword && Tok.is(tok::identifier) &&
3763 Tok.getIdentifierInfo()->getName() ==
"__declspec") {
3764 Diag(Loc, diag::err_ms_attributes_not_enabled);
3774 if (T.consumeOpen()) {
3775 assert(
false &&
"Not a left paren?");
3790 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3794 if (IsTemplateSpecOrInst)
3798 if (IsTemplateSpecOrInst)
3801 goto DoneWithDeclSpec;
3804 if (!Tok.is(tok::identifier))
3809 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID,
isInvalid))
3815 goto DoneWithDeclSpec;
3817 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3818 isObjCInstancetype()) {
3819 ParsedType TypeRep = Actions.ObjC().ActOnObjCInstanceType(Loc);
3822 DiagID, TypeRep, Policy);
3834 Actions.isCurrentClassName(*Tok.getIdentifierInfo(),
getCurScope()) &&
3835 isConstructorDeclarator(
true,
3838 goto DoneWithDeclSpec;
3841 *Tok.getIdentifierInfo(), Tok.getLocation(),
getCurScope(),
nullptr,
3842 false,
false,
nullptr,
false,
false,
3843 isClassTemplateDeductionContext(DSContext));
3848 if (TryAnnotateTypeConstraint())
3849 goto DoneWithDeclSpec;
3850 if (Tok.isNot(tok::identifier))
3852 ParsedAttributes Attrs(AttrFactory);
3853 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
3854 if (!Attrs.
empty()) {
3855 AttrsLastTime =
true;
3856 attrs.takeAllAppendingFrom(Attrs);
3860 goto DoneWithDeclSpec;
3867 (DSContext == DeclSpecContext::DSC_class ||
3868 DSContext == DeclSpecContext::DSC_top_level) &&
3869 Actions.isDeductionGuideName(
getCurScope(), *Tok.getIdentifierInfo(),
3870 Tok.getLocation(), SS) &&
3871 isConstructorDeclarator(
true,
3873 goto DoneWithDeclSpec;
3876 DiagID, TypeRep, Policy);
3887 SourceLocation NewEndLoc;
3888 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3903 case tok::annot_template_id: {
3904 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
3915 TemplateId =
nullptr;
3923 tok::kw_volatile, tok::kw_restrict, tok::amp,
3925 Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
3929 TemplateId, Policy);
3933 goto DoneWithDeclSpec;
3935 if (TemplateId && !
isInvalid && Actions.CheckTypeConstraint(TemplateId))
3936 TemplateId =
nullptr;
3938 ConsumeAnnotationToken();
3939 SourceLocation AutoLoc = Tok.getLocation();
3942 if (Tracker.consumeOpen()) {
3944 Diag(Tok, diag::err_expected) << tok::l_paren;
3948 Tracker.skipToEnd();
3949 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
3954 Tracker.consumeClose();
3957 ConsumedEnd = Tok.getLocation();
3962 DiagID, TemplateId, Policy);
3965 TemplateId, Policy);
3974 goto DoneWithDeclSpec;
3982 isConstructorDeclarator(
true,
3985 goto DoneWithDeclSpec;
3990 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3995 case tok::kw___attribute:
3996 case tok::kw___declspec:
3997 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4001 case tok::kw___forceinline: {
4003 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
4004 SourceLocation AttrNameLoc = Tok.getLocation();
4006 nullptr, 0, tok::kw___forceinline);
4010 case tok::kw___unaligned:
4016 case tok::kw___ptrauth:
4020 case tok::kw___sptr:
4021 case tok::kw___uptr:
4022 case tok::kw___ptr64:
4023 case tok::kw___ptr32:
4025 case tok::kw___cdecl:
4026 case tok::kw___stdcall:
4027 case tok::kw___fastcall:
4028 case tok::kw___thiscall:
4029 case tok::kw___regcall:
4030 case tok::kw___vectorcall:
4034 case tok::kw___funcref:
4039 case tok::kw___pascal:
4044 case tok::kw___kernel:
4049 case tok::kw___noinline__:
4054 case tok::kw__Nonnull:
4055 case tok::kw__Nullable:
4056 case tok::kw__Nullable_result:
4057 case tok::kw__Null_unspecified:
4062 case tok::kw___kindof:
4064 AttributeScopeInfo(),
nullptr, 0,
4070 case tok::kw_typedef:
4072 PrevSpec, DiagID, Policy);
4073 isStorageClass =
true;
4075 case tok::kw_extern:
4077 Diag(Tok, diag::ext_thread_before) <<
"extern";
4079 PrevSpec, DiagID, Policy);
4080 isStorageClass =
true;
4082 case tok::kw___private_extern__:
4084 Loc, PrevSpec, DiagID, Policy);
4085 isStorageClass =
true;
4087 case tok::kw_static:
4089 Diag(Tok, diag::ext_thread_before) <<
"static";
4091 PrevSpec, DiagID, Policy);
4092 isStorageClass =
true;
4098 PrevSpec, DiagID, Policy);
4100 Diag(Tok, diag::ext_auto_storage_class)
4107 PrevSpec, DiagID, Policy);
4108 isStorageClass =
true;
4110 case tok::kw___auto_type:
4111 Diag(Tok, diag::ext_auto_type);
4115 case tok::kw_register:
4117 PrevSpec, DiagID, Policy);
4118 isStorageClass =
true;
4120 case tok::kw_mutable:
4122 PrevSpec, DiagID, Policy);
4123 isStorageClass =
true;
4125 case tok::kw___thread:
4128 isStorageClass =
true;
4130 case tok::kw_thread_local:
4132 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4141 Loc, PrevSpec, DiagID);
4142 isStorageClass =
true;
4144 case tok::kw__Thread_local:
4145 diagnoseUseOfC11Keyword(Tok);
4147 Loc, PrevSpec, DiagID);
4148 isStorageClass =
true;
4152 case tok::kw_inline:
4155 case tok::kw_virtual:
4159 !
getActions().getOpenCLOptions().isAvailableOption(
4161 DiagID = diag::err_openclcxx_virtual_function;
4162 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4165 DiagID = diag::err_hlsl_virtual_function;
4166 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4172 case tok::kw_explicit: {
4173 SourceLocation ExplicitLoc = Loc;
4174 SourceLocation CloseParenLoc;
4176 ConsumedEnd = ExplicitLoc;
4178 if (Tok.is(tok::l_paren)) {
4181 ? diag::warn_cxx17_compat_explicit_bool
4182 : diag::ext_explicit_bool);
4184 ExprResult ExplicitExpr(
static_cast<Expr *
>(
nullptr));
4186 Tracker.consumeOpen();
4188 EnterExpressionEvaluationContext ConstantEvaluated(
4192 ConsumedEnd = Tok.getLocation();
4193 if (ExplicitExpr.isUsable()) {
4194 CloseParenLoc = Tok.getLocation();
4195 Tracker.consumeClose();
4197 Actions.ActOnExplicitBoolSpecifier(ExplicitExpr.get());
4199 Tracker.skipToEnd();
4201 Diag(Tok.getLocation(), diag::warn_cxx20_compat_explicit_bool);
4205 ExplicitSpec, CloseParenLoc);
4208 case tok::kw__Noreturn:
4209 diagnoseUseOfC11Keyword(Tok);
4214 case tok::kw_friend:
4215 if (DSContext == DeclSpecContext::DSC_class) {
4222 DiagID = diag::err_friend_invalid_in_context;
4228 case tok::kw___module_private__:
4233 case tok::kw_constexpr:
4235 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4239 case tok::kw_consteval:
4243 case tok::kw_constinit:
4251 Diag(Tok, diag::err_unknown_typename) << Tok.getName();
4255 goto DoneWithDeclSpec;
4266 PrevSpec, DiagID, Policy);
4268 case tok::kw___int64:
4270 PrevSpec, DiagID, Policy);
4272 case tok::kw_signed:
4276 case tok::kw_unsigned:
4280 case tok::kw__Complex:
4282 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4286 case tok::kw__Imaginary:
4288 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4304 case tok::kw__ExtInt:
4305 case tok::kw__BitInt: {
4306 DiagnoseBitIntUse(Tok);
4311 ConsumedEnd = PrevTokLocation;
4314 case tok::kw___int128:
4322 case tok::kw___bf16:
4330 case tok::kw_double:
4334 case tok::kw__Float16:
4338 case tok::kw__Accum:
4340 "This keyword is only used when fixed point types are enabled "
4341 "with `-ffixed-point`");
4345 case tok::kw__Fract:
4347 "This keyword is only used when fixed point types are enabled "
4348 "with `-ffixed-point`");
4354 "This keyword is only used when fixed point types are enabled "
4355 "with `-ffixed-point`");
4358 case tok::kw___float128:
4362 case tok::kw___ibm128:
4366 case tok::kw_wchar_t:
4370 case tok::kw_char8_t:
4374 case tok::kw_char16_t:
4378 case tok::kw_char32_t:
4384 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4388 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4390 if (Tok.is(tok::kw_bool) &&
4394 DiagID = diag::err_bool_redeclaration;
4396 Tok.setKind(tok::identifier);
4403 case tok::kw__Decimal32:
4407 case tok::kw__Decimal64:
4411 case tok::kw__Decimal128:
4415 case tok::kw___vector:
4418 case tok::kw___pixel:
4421 case tok::kw___bool:
4426 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4429 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
4430 Tok.setKind(tok::identifier);
4431 goto DoneWithDeclSpec;
4433 DiagID = diag::err_opencl_unknown_type_specifier;
4434 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4440#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4441#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4442#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4443 case tok::kw_##ImgType##_t: \
4444 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4445 goto DoneWithDeclSpec; \
4447#include "clang/Basic/OpenCLImageTypes.def"
4448 case tok::kw___unknown_anytype:
4450 PrevSpec, DiagID, Policy);
4455 case tok::kw_struct:
4456 case tok::kw___interface:
4457 case tok::kw_union: {
4464 ParsedAttributes Attributes(AttrFactory);
4465 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
4466 EnteringContext, DSContext, Attributes);
4470 if (!Attributes.empty()) {
4471 AttrsLastTime =
true;
4472 attrs.takeAllAppendingFrom(Attributes);
4480 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
4488 case tok::kw_volatile:
4492 case tok::kw_restrict:
4496 case tok::kw___ob_wrap:
4498 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
4503 OverflowBehaviorType::OverflowBehaviorKind::Wrap, Loc, PrevSpec,
4506 case tok::kw___ob_trap:
4508 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
4513 OverflowBehaviorType::OverflowBehaviorKind::Trap, Loc, PrevSpec,
4518 case tok::kw_typename:
4521 goto DoneWithDeclSpec;
4523 if (!Tok.is(tok::kw_typename))
4528 case tok::kw_typeof:
4529 case tok::kw_typeof_unqual:
4530 ParseTypeofSpecifier(DS);
4533 case tok::annot_decltype:
4534 ParseDecltypeSpecifier(DS);
4537 case tok::annot_pack_indexing_type:
4538 ParsePackIndexingType(DS);
4541 case tok::annot_pragma_pack:
4545 case tok::annot_pragma_ms_pragma:
4546 HandlePragmaMSPragma();
4549 case tok::annot_pragma_ms_vtordisp:
4550 HandlePragmaMSVtorDisp();
4553 case tok::annot_pragma_ms_pointers_to_members:
4554 HandlePragmaMSPointersToMembers();
4557 case tok::annot_pragma_export:
4558 HandlePragmaExport();
4561#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4562#include "clang/Basic/TransformTypeTraits.def"
4566 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4567 goto ParseIdentifier;
4570 case tok::kw__Atomic:
4575 diagnoseUseOfC11Keyword(Tok);
4577 ParseAtomicSpecifier(DS);
4585 case tok::kw___generic:
4590 if (!Actions.getLangOpts().OpenCLGenericAddressSpace) {
4591 DiagID = diag::err_opencl_unknown_type_specifier;
4592 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4597 case tok::kw_private:
4601 goto DoneWithDeclSpec;
4603 case tok::kw___private:
4604 case tok::kw___global:
4605 case tok::kw___local:
4606 case tok::kw___constant:
4608 case tok::kw___read_only:
4609 case tok::kw___write_only:
4610 case tok::kw___read_write:
4614 case tok::kw_groupshared:
4622#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
4623 case tok::kw_##Name: \
4624 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4627#include "clang/Basic/HLSLIntangibleTypes.def"
4634 goto DoneWithDeclSpec;
4636 SourceLocation StartLoc = Tok.getLocation();
4637 SourceLocation EndLoc;
4639 if (
Type.isUsable()) {
4641 PrevSpec, DiagID,
Type.get(),
4642 Actions.getASTContext().getPrintingPolicy()))
4643 Diag(StartLoc, DiagID) << PrevSpec;
4659 assert(PrevSpec &&
"Method did not return previous specifier!");
4662 if (DiagID == diag::ext_duplicate_declspec ||
4663 DiagID == diag::ext_warn_duplicate_declspec ||
4664 DiagID == diag::err_duplicate_declspec)
4665 Diag(Loc, DiagID) << PrevSpec
4668 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4672 Diag(Loc, DiagID) << PrevSpec;
4675 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4679 AttrsLastTime =
false;
4691 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4694 for (
auto *I : RD->decls()) {
4695 auto *VD = dyn_cast<ValueDecl>(I);
4703 for (
const auto &DD : CAT->dependent_decls()) {
4704 if (!RD->containsDecl(DD.getDecl())) {
4705 P.
Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4706 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4707 P.
Diag(DD.getDecl()->getBeginLoc(),
4708 diag::note_flexible_array_counted_by_attr_field)
4715void Parser::ParseStructDeclaration(
4718 LateParsedAttrList *LateFieldAttrs) {
4720 if (Tok.is(tok::kw___extension__)) {
4722 ExtensionRAIIObject O(Diags);
4724 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4728 ParsedAttributes Attrs(AttrFactory);
4729 MaybeParseCXX11Attributes(Attrs);
4732 ParseSpecifierQualifierList(DS);
4736 if (Tok.is(tok::semi)) {
4741 ProhibitAttributes(Attrs);
4742 RecordDecl *AnonRecord =
nullptr;
4743 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
4745 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4751 bool FirstDeclarator =
true;
4752 SourceLocation CommaLoc;
4754 ParsingFieldDeclarator DeclaratorInfo(*
this, DS, Attrs);
4755 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4758 if (!FirstDeclarator) {
4761 DiagnoseAndSkipCXX11Attributes();
4762 MaybeParseGNUAttributes(DeclaratorInfo.D);
4763 DiagnoseAndSkipCXX11Attributes();
4768 if (Tok.isNot(tok::colon)) {
4771 ParseDeclarator(DeclaratorInfo.D);
4773 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.getLocation());
4785 DeclaratorInfo.BitfieldSize = Res.
get();
4789 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
4792 Decl *
Field = FieldsCallback(DeclaratorInfo);
4794 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
4801 FirstDeclarator =
false;
4807void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs,
bool EnterScope,
4809 assert(LAs.parseSoon() &&
4810 "Attribute list should be marked for immediate parsing.");
4811 for (
auto *LA : LAs) {
4812 ParseLexedCAttribute(*LA,
EnterScope, OutAttrs);
4818void Parser::ParseLexedCAttribute(LateParsedAttribute &LA,
bool EnterScope,
4823 AttrEnd.startToken();
4824 AttrEnd.setKind(tok::eof);
4825 AttrEnd.setLocation(Tok.getLocation());
4826 AttrEnd.setEofData(LA.Toks.data());
4827 LA.Toks.push_back(AttrEnd);
4831 LA.Toks.push_back(Tok);
4832 PP.EnterTokenStream(LA.Toks,
true,
4841 ParsedAttributes Attrs(AttrFactory);
4843 assert(LA.Decls.size() <= 1 &&
4844 "late field attribute expects to have at most one declaration.");
4847 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
nullptr,
nullptr,
4848 SourceLocation(), ParsedAttr::Form::GNU(),
nullptr);
4850 for (
auto *D : LA.Decls)
4851 Actions.ActOnFinishDelayedAttribute(
getCurScope(), D, Attrs);
4855 while (Tok.isNot(tok::eof))
4859 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
4869 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl,
RecordLoc,
4870 "parsing struct/union body");
4874 if (T.consumeOpen())
4878 Actions.ActOnTagStartDefinition(
getCurScope(), TagDecl);
4882 LateParsedAttrList LateFieldAttrs(
true,
4886 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
4887 Tok.isNot(tok::eof)) {
4891 if (Tok.is(tok::semi)) {
4897 if (Tok.isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4898 SourceLocation DeclEnd;
4899 ParseStaticAssertDeclaration(DeclEnd);
4903 if (Tok.is(tok::annot_pragma_pack)) {
4908 if (Tok.is(tok::annot_pragma_align)) {
4909 HandlePragmaAlign();
4913 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4916 ParsedAttributes Attrs(AttrFactory);
4917 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4921 if (Tok.is(tok::annot_pragma_openacc)) {
4923 ParsedAttributes Attrs(AttrFactory);
4929 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
4931 TagType, Actions.getASTContext().getPrintingPolicy());
4932 ConsumeAnnotationToken();
4936 if (!Tok.is(tok::at)) {
4937 auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
4941 FD.D.getDeclSpec().getSourceRange().getBegin(),
4942 FD.D, FD.BitfieldSize);
4948 ParsingDeclSpec DS(*
this);
4949 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
4952 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
4953 Diag(Tok, diag::err_unexpected_at);
4958 ExpectAndConsume(tok::l_paren);
4959 if (!Tok.is(tok::identifier)) {
4960 Diag(Tok, diag::err_expected) << tok::identifier;
4964 SmallVector<Decl *, 16> Fields;
4965 Actions.ObjC().ActOnDefs(
getCurScope(), TagDecl, Tok.getLocation(),
4966 Tok.getIdentifierInfo(), Fields);
4968 ExpectAndConsume(tok::r_paren);
4974 if (Tok.is(tok::r_brace)) {
4975 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
4979 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
4988 ParsedAttributes attrs(AttrFactory);
4990 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
4993 ParseLexedCAttributeList(LateFieldAttrs,
false);
4995 SmallVector<Decl *, 32> FieldDecls(TagDecl->
fields());
4998 T.getOpenLocation(), T.getCloseLocation(), attrs);
5000 Actions.ActOnTagFinishDefinition(
getCurScope(), TagDecl, T.getRange());
5004 const ParsedTemplateInfo &TemplateInfo,
5007 if (Tok.is(tok::code_completion)) {
5016 ParsedAttributes attrs(AttrFactory);
5017 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5019 SourceLocation ScopedEnumKWLoc;
5020 bool IsScopedUsingClassTag =
false;
5025 : diag::ext_scoped_enum);
5026 IsScopedUsingClassTag = Tok.is(tok::kw_class);
5031 ProhibitAttributes(attrs);
5034 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5043 bool shouldDelayDiagsInTag =
5046 SuppressAccessChecks diagsFromTag(*
this, shouldDelayDiagsInTag);
5049 AllowDefiningTypeSpec AllowEnumSpecifier =
5051 bool CanBeOpaqueEnumDeclaration =
5052 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5055 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5056 CanBeOpaqueEnumDeclaration);
5064 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5069 if (Spec.
isSet() && Tok.isNot(tok::identifier)) {
5070 Diag(Tok, diag::err_expected) << tok::identifier;
5072 if (Tok.isNot(tok::l_brace)) {
5080 SS = std::move(Spec);
5084 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
5085 Tok.isNot(tok::colon)) {
5086 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5095 IdentifierInfo *Name =
nullptr;
5096 SourceLocation NameLoc;
5097 if (Tok.is(tok::identifier)) {
5098 Name = Tok.getIdentifierInfo();
5102 if (!Name && ScopedEnumKWLoc.
isValid()) {
5105 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5106 ScopedEnumKWLoc = SourceLocation();
5107 IsScopedUsingClassTag =
false;
5112 if (shouldDelayDiagsInTag)
5113 diagsFromTag.done();
5116 SourceRange BaseRange;
5118 bool CanBeBitfield =
5122 if (Tok.is(tok::colon)) {
5147 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5151 Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
5152 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5159 DeclSpec DS(AttrFactory);
5163 DeclSpecContext::DSC_type_specifier);
5166 BaseType = Actions.ActOnTypeName(DeclaratorInfo);
5168 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5172 DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)
5175 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5179 ? diag::warn_c17_compat_enum_fixed_underlying_type
5180 : diag::ext_c23_enum_fixed_underlying_type)
5197 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5199 else if (Tok.is(tok::l_brace)) {
5201 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
5207 ScopedEnumKWLoc = SourceLocation();
5208 IsScopedUsingClassTag =
false;
5214 }
else if (!isTypeSpecifier(DSC) &&
5215 (Tok.is(tok::semi) ||
5216 (Tok.isAtStartOfLine() &&
5217 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5222 if (Tok.isNot(tok::semi)) {
5224 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5225 PP.EnterToken(Tok,
true);
5226 Tok.setKind(tok::semi);
5232 bool IsElaboratedTypeSpecifier =
5238 diagsFromTag.redelay();
5246 Diag(Tok, diag::err_enum_template);
5254 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5258 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5260 TemplateInfo.TemplateParams->size());
5265 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5281 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5283 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5284 diag::err_keyword_not_allowed,
5287 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5288 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5289 else if (ScopedEnumKWLoc.
isValid())
5290 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5294 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5296 SkipBodyInfo SkipBody;
5299 SkipBody = Actions.shouldSkipAnonEnumBody(
getCurScope(),
5304 bool IsDependent =
false;
5305 const char *PrevSpec =
nullptr;
5310 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5311 IsScopedUsingClassTag,
5312 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5313 DSC == DeclSpecContext::DSC_template_param ||
5314 DSC == DeclSpecContext::DSC_template_type_arg,
5315 OffsetOfState, &SkipBody).get();
5325 NameLoc.
isValid() ? NameLoc : StartLoc,
5326 PrevSpec, DiagID, TagDecl, Owned,
5327 Actions.getASTContext().getPrintingPolicy()))
5328 Diag(StartLoc, DiagID) << PrevSpec;
5337 Diag(Tok, diag::err_expected_type_name_after_typename);
5343 if (
Type.isInvalid()) {
5349 NameLoc.
isValid() ? NameLoc : StartLoc,
5350 PrevSpec, DiagID,
Type.get(),
5351 Actions.getASTContext().getPrintingPolicy()))
5352 Diag(StartLoc, DiagID) << PrevSpec;
5371 ParseEnumBody(StartLoc, D, &SkipBody);
5373 !Actions.ActOnDuplicateDefinition(
getCurScope(), TagDecl, SkipBody)) {
5380 NameLoc.
isValid() ? NameLoc : StartLoc,
5381 PrevSpec, DiagID, TagDecl, Owned,
5382 Actions.getASTContext().getPrintingPolicy()))
5383 Diag(StartLoc, DiagID) << PrevSpec;
5390 Actions.ActOnTagStartDefinition(
getCurScope(), EnumDecl);
5398 Diag(T.getOpenLocation(), diag::ext_ms_c_empty_enum_type)
5399 << SourceRange(T.getOpenLocation(), Tok.getLocation());
5401 Diag(Tok, diag::err_empty_enum);
5404 SmallVector<Decl *, 32> EnumConstantDecls;
5405 SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
5407 Decl *LastEnumConstDecl =
nullptr;
5410 while (Tok.isNot(tok::r_brace)) {
5413 if (Tok.isNot(tok::identifier)) {
5414 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
5420 IdentifierInfo *Ident = Tok.getIdentifierInfo();
5424 ParsedAttributes attrs(AttrFactory);
5425 MaybeParseGNUAttributes(attrs);
5426 if (isAllowedCXX11AttributeSpecifier()) {
5429 ? diag::warn_cxx14_compat_ns_enum_attribute
5430 : diag::ext_ns_enum_attribute)
5432 ParseCXX11Attributes(attrs);
5435 SourceLocation EqualLoc;
5437 EnumAvailabilityDiags.emplace_back(*
this);
5439 EnterExpressionEvaluationContext ConstantEvaluated(
5448 Decl *EnumConstDecl = Actions.ActOnEnumConstant(
5449 getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
5450 EqualLoc, AssignedVal.
get(), SkipBody);
5451 EnumAvailabilityDiags.back().done();
5453 EnumConstantDecls.push_back(EnumConstDecl);
5454 LastEnumConstDecl = EnumConstDecl;
5456 if (Tok.is(tok::identifier)) {
5459 Diag(Loc, diag::err_enumerator_list_missing_comma)
5466 SourceLocation CommaLoc;
5467 if (Tok.isNot(tok::r_brace) && !
TryConsumeToken(tok::comma, CommaLoc)) {
5469 Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
5472 Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
5482 if (Tok.is(tok::r_brace) && CommaLoc.
isValid()) {
5485 diag::ext_enumerator_list_comma_cxx :
5486 diag::ext_enumerator_list_comma_c)
5489 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5499 ParsedAttributes attrs(AttrFactory);
5500 MaybeParseGNUAttributes(attrs);
5502 Actions.ActOnEnumBody(StartLoc, T.getRange(), EnumDecl, EnumConstantDecls,
5506 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5507 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5509 EnumAvailabilityDiags[i].redelay();
5510 PD.complete(EnumConstantDecls[i]);
5514 Actions.ActOnTagFinishDefinition(
getCurScope(), EnumDecl, T.getRange());
5519 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5520 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5524 PP.EnterToken(Tok,
true);
5525 Tok.setKind(tok::semi);
5529bool Parser::isKnownToBeTypeSpecifier(
const Token &
Tok)
const {
5530 switch (Tok.getKind()) {
5531 default:
return false;
5535 case tok::kw___int64:
5536 case tok::kw___int128:
5537 case tok::kw_signed:
5538 case tok::kw_unsigned:
5539 case tok::kw__Complex:
5540 case tok::kw__Imaginary:
5543 case tok::kw_wchar_t:
5544 case tok::kw_char8_t:
5545 case tok::kw_char16_t:
5546 case tok::kw_char32_t:
5548 case tok::kw__ExtInt:
5549 case tok::kw__BitInt:
5550 case tok::kw___bf16:
5553 case tok::kw_double:
5554 case tok::kw__Accum:
5555 case tok::kw__Fract:
5556 case tok::kw__Float16:
5557 case tok::kw___float128:
5558 case tok::kw___ibm128:
5561 case tok::kw__Decimal32:
5562 case tok::kw__Decimal64:
5563 case tok::kw__Decimal128:
5564 case tok::kw___vector:
5565#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5566#include "clang/Basic/OpenCLImageTypes.def"
5567#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5568#include "clang/Basic/HLSLIntangibleTypes.def"
5572 case tok::kw_struct:
5573 case tok::kw___interface:
5579 case tok::annot_typename:
5584bool Parser::isTypeSpecifierQualifier() {
5585 switch (Tok.getKind()) {
5586 default:
return false;
5588 case tok::identifier:
5589 if (TryAltiVecVectorToken())
5592 case tok::kw_typename:
5597 if (Tok.is(tok::identifier))
5599 return isTypeSpecifierQualifier();
5601 case tok::coloncolon:
5608 return isTypeSpecifierQualifier();
5611 case tok::kw___attribute:
5613 case tok::kw_typeof:
5614 case tok::kw_typeof_unqual:
5619 case tok::kw___int64:
5620 case tok::kw___int128:
5621 case tok::kw_signed:
5622 case tok::kw_unsigned:
5623 case tok::kw__Complex:
5624 case tok::kw__Imaginary:
5627 case tok::kw_wchar_t:
5628 case tok::kw_char8_t:
5629 case tok::kw_char16_t:
5630 case tok::kw_char32_t:
5632 case tok::kw__ExtInt:
5633 case tok::kw__BitInt:
5635 case tok::kw___bf16:
5637 case tok::kw_double:
5638 case tok::kw__Accum:
5639 case tok::kw__Fract:
5640 case tok::kw__Float16:
5641 case tok::kw___float128:
5642 case tok::kw___ibm128:
5645 case tok::kw__Decimal32:
5646 case tok::kw__Decimal64:
5647 case tok::kw__Decimal128:
5648 case tok::kw___vector:
5649#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5650#include "clang/Basic/OpenCLImageTypes.def"
5651#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5652#include "clang/Basic/HLSLIntangibleTypes.def"
5656 case tok::kw_struct:
5657 case tok::kw___interface:
5664 case tok::kw_volatile:
5665 case tok::kw_restrict:
5666 case tok::kw___ob_wrap:
5667 case tok::kw___ob_trap:
5671 case tok::kw___unknown_anytype:
5674 case tok::annot_typename:
5681 case tok::kw___cdecl:
5682 case tok::kw___stdcall:
5683 case tok::kw___fastcall:
5684 case tok::kw___thiscall:
5685 case tok::kw___regcall:
5686 case tok::kw___vectorcall:
5688 case tok::kw___ptr64:
5689 case tok::kw___ptr32:
5690 case tok::kw___pascal:
5691 case tok::kw___unaligned:
5692 case tok::kw___ptrauth:
5694 case tok::kw__Nonnull:
5695 case tok::kw__Nullable:
5696 case tok::kw__Nullable_result:
5697 case tok::kw__Null_unspecified:
5699 case tok::kw___kindof:
5701 case tok::kw___private:
5702 case tok::kw___local:
5703 case tok::kw___global:
5704 case tok::kw___constant:
5705 case tok::kw___generic:
5706 case tok::kw___read_only:
5707 case tok::kw___read_write:
5708 case tok::kw___write_only:
5709 case tok::kw___funcref:
5712 case tok::kw_private:
5716 case tok::kw__Atomic:
5720 case tok::kw_groupshared:
5729 assert(PP.isIncrementalProcessingEnabled() &&
"Not in incremental mode");
5733 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5736 TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5737 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5738 Actions.ActOnFinishTopLevelStmtDecl(TLSD, R.get());
5740 R = Actions.ActOnNullStmt(Tok.getLocation());
5742 if (Tok.is(tok::annot_repl_input_end) &&
5743 Tok.getAnnotationValue() !=
nullptr) {
5744 ConsumeAnnotationToken();
5748 SmallVector<Decl *, 2> DeclsInGroup;
5749 DeclsInGroup.push_back(TLSD);
5752 for (Stmt *S : Stmts) {
5755 TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5756 Actions.ActOnFinishTopLevelStmtDecl(D, S);
5757 DeclsInGroup.push_back(D);
5760 return Actions.BuildDeclaratorGroup(DeclsInGroup);
5763bool Parser::isDeclarationSpecifier(
5765 bool DisambiguatingWithExpression) {
5766 switch (Tok.getKind()) {
5767 default:
return false;
5774 case tok::identifier:
5778 if (TryAltiVecVectorToken())
5781 case tok::kw_decltype:
5782 case tok::kw_typename:
5787 if (TryAnnotateTypeConstraint())
5789 if (Tok.is(tok::identifier))
5797 if (DisambiguatingWithExpression &&
5798 isStartOfObjCClassMessageMissingOpenBracket())
5801 return isDeclarationSpecifier(AllowImplicitTypename);
5803 case tok::coloncolon:
5817 case tok::kw_typedef:
5818 case tok::kw_extern:
5819 case tok::kw___private_extern__:
5820 case tok::kw_static:
5822 case tok::kw___auto_type:
5823 case tok::kw_register:
5824 case tok::kw___thread:
5825 case tok::kw_thread_local:
5826 case tok::kw__Thread_local:
5829 case tok::kw___module_private__:
5832 case tok::kw___unknown_anytype:
5837 case tok::kw___int64:
5838 case tok::kw___int128:
5839 case tok::kw_signed:
5840 case tok::kw_unsigned:
5841 case tok::kw__Complex:
5842 case tok::kw__Imaginary:
5845 case tok::kw_wchar_t:
5846 case tok::kw_char8_t:
5847 case tok::kw_char16_t:
5848 case tok::kw_char32_t:
5851 case tok::kw__ExtInt:
5852 case tok::kw__BitInt:
5854 case tok::kw___bf16:
5856 case tok::kw_double:
5857 case tok::kw__Accum:
5858 case tok::kw__Fract:
5859 case tok::kw__Float16:
5860 case tok::kw___float128:
5861 case tok::kw___ibm128:
5864 case tok::kw__Decimal32:
5865 case tok::kw__Decimal64:
5866 case tok::kw__Decimal128:
5867 case tok::kw___vector:
5871 case tok::kw_struct:
5873 case tok::kw___interface:
5879 case tok::kw_volatile:
5880 case tok::kw_restrict:
5881 case tok::kw___ob_wrap:
5882 case tok::kw___ob_trap:
5886 case tok::kw_inline:
5887 case tok::kw_virtual:
5888 case tok::kw_explicit:
5889 case tok::kw__Noreturn:
5892 case tok::kw__Alignas:
5895 case tok::kw_friend:
5898 case tok::kw_static_assert:
5899 case tok::kw__Static_assert:
5902 case tok::kw_typeof:
5903 case tok::kw_typeof_unqual:
5906 case tok::kw___attribute:
5909 case tok::annot_decltype:
5910 case tok::annot_pack_indexing_type:
5911 case tok::kw_constexpr:
5914 case tok::kw_consteval:
5915 case tok::kw_constinit:
5918 case tok::kw__Atomic:
5921 case tok::kw_alignas:
5931 case tok::annot_typename:
5932 return !DisambiguatingWithExpression ||
5933 !isStartOfObjCClassMessageMissingOpenBracket();
5936 case tok::annot_template_id: {
5937 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
5942 return isTypeConstraintAnnotation() &&
5946 case tok::annot_cxxscope: {
5947 TemplateIdAnnotation *TemplateId =
5955 if (
NextToken().
is(tok::identifier) && TryAnnotateTypeConstraint())
5957 return isTypeConstraintAnnotation() &&
5961 case tok::kw___declspec:
5962 case tok::kw___cdecl:
5963 case tok::kw___stdcall:
5964 case tok::kw___fastcall:
5965 case tok::kw___thiscall:
5966 case tok::kw___regcall:
5967 case tok::kw___vectorcall:
5969 case tok::kw___sptr:
5970 case tok::kw___uptr:
5971 case tok::kw___ptr64:
5972 case tok::kw___ptr32:
5973 case tok::kw___forceinline:
5974 case tok::kw___pascal:
5975 case tok::kw___unaligned:
5976 case tok::kw___ptrauth:
5978 case tok::kw__Nonnull:
5979 case tok::kw__Nullable:
5980 case tok::kw__Nullable_result:
5981 case tok::kw__Null_unspecified:
5983 case tok::kw___kindof:
5985 case tok::kw___private:
5986 case tok::kw___local:
5987 case tok::kw___global:
5988 case tok::kw___constant:
5989 case tok::kw___generic:
5990 case tok::kw___read_only:
5991 case tok::kw___read_write:
5992 case tok::kw___write_only:
5993#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5994#include "clang/Basic/OpenCLImageTypes.def"
5995#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5996#include "clang/Basic/HLSLIntangibleTypes.def"
5998 case tok::kw___funcref:
5999 case tok::kw_groupshared:
6002 case tok::kw_private:
6007bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
6009 const ParsedTemplateInfo *TemplateInfo) {
6010 RevertingTentativeParsingAction TPA(*
this);
6013 if (TemplateInfo && TemplateInfo->TemplateParams)
6016 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6023 if (Tok.is(tok::identifier)) {
6027 }
else if (Tok.is(tok::annot_template_id)) {
6028 ConsumeAnnotationToken();
6035 SkipCXX11Attributes();
6038 if (Tok.isNot(tok::l_paren)) {
6045 if (Tok.is(tok::r_paren) ||
6046 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren))) {
6052 if (isCXX11AttributeSpecifier(
false,
6059 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6061 DeclScopeObj.EnterDeclaratorScope();
6064 ParsedAttributes Attrs(AttrFactory);
6065 MaybeParseMicrosoftAttributes(Attrs);
6074 bool IsConstructor =
false;
6080 if (Tok.is(tok::kw_this)) {
6082 return isDeclarationSpecifier(ITC);
6085 if (isDeclarationSpecifier(ITC))
6086 IsConstructor =
true;
6087 else if (Tok.is(tok::identifier) ||
6088 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier))) {
6093 if (Tok.is(tok::annot_cxxscope))
6094 ConsumeAnnotationToken();
6100 switch (Tok.getKind()) {
6106 case tok::coloncolon:
6119 SkipCXX11Attributes();
6121 if (DeductionGuide) {
6123 IsConstructor = Tok.is(tok::arrow);
6126 if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
6130 IsConstructor =
true;
6132 if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {
6145 IsConstructor = IsUnqualified;
6150 IsConstructor =
true;
6154 return IsConstructor;
6157void Parser::ParseTypeQualifierListOpt(
6158 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicOrPtrauthAllowed,
6160 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6161 isAllowedCXX11AttributeSpecifier()) {
6162 ParsedAttributes Attrs(AttrFactory);
6163 ParseCXX11Attributes(Attrs);
6167 SourceLocation EndLoc;
6171 const char *PrevSpec =
nullptr;
6172 unsigned DiagID = 0;
6173 SourceLocation Loc = Tok.getLocation();
6175 switch (Tok.getKind()) {
6176 case tok::code_completion:
6178 if (CodeCompletionHandler)
6179 CodeCompletionHandler();
6181 Actions.CodeCompletion().CodeCompleteTypeQualifiers(DS);
6188 case tok::kw_volatile:
6192 case tok::kw_restrict:
6196 case tok::kw___ob_wrap:
6198 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6203 OverflowBehaviorType::OverflowBehaviorKind::Wrap, Loc, PrevSpec,
6206 case tok::kw___ob_trap:
6208 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6213 OverflowBehaviorType::OverflowBehaviorKind::Trap, Loc, PrevSpec,
6216 case tok::kw__Atomic:
6217 if (!AtomicOrPtrauthAllowed)
6218 goto DoneWithTypeQuals;
6219 diagnoseUseOfC11Keyword(Tok);
6225 case tok::kw_private:
6227 goto DoneWithTypeQuals;
6229 case tok::kw___private:
6230 case tok::kw___global:
6231 case tok::kw___local:
6232 case tok::kw___constant:
6233 case tok::kw___generic:
6234 case tok::kw___read_only:
6235 case tok::kw___write_only:
6236 case tok::kw___read_write:
6240 case tok::kw_groupshared:
6249 case tok::kw___ptrauth:
6250 if (!AtomicOrPtrauthAllowed)
6251 goto DoneWithTypeQuals;
6253 EndLoc = PrevTokLocation;
6256 case tok::kw___unaligned:
6260 case tok::kw___uptr:
6265 if (TryKeywordIdentFallback(
false))
6269 case tok::kw___sptr:
6271 case tok::kw___ptr64:
6272 case tok::kw___ptr32:
6273 case tok::kw___cdecl:
6274 case tok::kw___stdcall:
6275 case tok::kw___fastcall:
6276 case tok::kw___thiscall:
6277 case tok::kw___regcall:
6278 case tok::kw___vectorcall:
6279 if (AttrReqs & AR_DeclspecAttributesParsed) {
6283 goto DoneWithTypeQuals;
6285 case tok::kw___funcref:
6289 case tok::kw___pascal:
6290 if (AttrReqs & AR_VendorAttributesParsed) {
6294 goto DoneWithTypeQuals;
6297 case tok::kw__Nonnull:
6298 case tok::kw__Nullable:
6299 case tok::kw__Nullable_result:
6300 case tok::kw__Null_unspecified:
6305 case tok::kw___kindof:
6307 AttributeScopeInfo(),
nullptr, 0,
6312 case tok::kw___attribute:
6313 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6315 Diag(Tok, diag::err_attributes_not_allowed);
6319 if (AttrReqs & AR_GNUAttributesParsed ||
6320 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6330 DS.
Finish(Actions, Actions.getASTContext().getPrintingPolicy());
6338 assert(PrevSpec &&
"Method did not return previous specifier!");
6339 Diag(Tok, DiagID) << PrevSpec;
6348 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6349 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6355 if (Kind == tok::star || Kind == tok::caret)
6359 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6360 Lang.getOpenCLCompatibleVersion() >= 200)
6363 if (!Lang.CPlusPlus)
6366 if (Kind == tok::amp)
6374 if (Kind == tok::ampamp)
6385 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6392void Parser::ParseDeclaratorInternal(
Declarator &D,
6393 DirectDeclParseFunction DirectDeclParser) {
6394 if (Diags.hasAllExtensionsSilenced())
6401 (Tok.is(tok::coloncolon) || Tok.is(tok::kw_decltype) ||
6402 (Tok.is(tok::identifier) &&
6404 Tok.is(tok::annot_cxxscope))) {
6405 TentativeParsingAction TPA(*
this,
true);
6411 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6421 Tok.is(tok::star)) {
6425 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6426 CompoundToken::MemberPtr);
6431 DeclSpec DS(AttrFactory);
6432 ParseTypeQualifierListOpt(DS);
6436 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6437 ParseDeclaratorInternal(D, DirectDeclParser);
6451 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6461 AnnotateScopeToken(SS,
true);
6463 if (DirectDeclParser)
6464 (this->*DirectDeclParser)(D);
6472 DeclSpec DS(AttrFactory);
6473 ParseTypeQualifierListOpt(DS);
6482 if (DirectDeclParser)
6483 (this->*DirectDeclParser)(D);
6492 if (Kind == tok::star || Kind == tok::caret) {
6494 DeclSpec DS(AttrFactory);
6498 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6500 ? AR_GNUAttributesParsed
6501 : AR_GNUAttributesParsedAndRejected);
6502 ParseTypeQualifierListOpt(DS, Reqs,
true,
6507 Actions.runWithSufficientStackSpace(
6508 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6509 if (Kind == tok::star)
6524 DeclSpec DS(AttrFactory);
6528 if (Kind == tok::ampamp)
6530 diag::warn_cxx98_compat_rvalue_reference :
6531 diag::ext_rvalue_reference);
6534 ParseTypeQualifierListOpt(DS);
6543 diag::err_invalid_reference_qualifier_application) <<
"const";
6546 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6550 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6554 Actions.runWithSufficientStackSpace(
6555 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6562 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6565 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6594void Parser::ParseDirectDeclarator(
Declarator &D) {
6601 return ParseDecompositionDeclarator(D);
6615 ParseOptionalCXXScopeSpecifier(
6617 false, EnteringContext);
6632 if (Actions.ShouldEnterDeclaratorScope(
getCurScope(),
6636 DeclScopeObj.EnterDeclaratorScope();
6643 goto PastIdentifier;
6659 !Actions.containsUnexpandedParameterPacks(D) &&
6667 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6677 if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6681 bool AllowConstructorName;
6682 bool AllowDeductionGuide;
6684 AllowConstructorName =
false;
6685 AllowDeductionGuide =
false;
6689 AllowDeductionGuide =
false;
6697 SourceLocation TemplateKWLoc;
6702 true, AllowConstructorName,
6703 AllowDeductionGuide, &TemplateKWLoc,
6716 DeclScopeObj.EnterDeclaratorScope();
6723 goto PastIdentifier;
6729 diag::err_expected_unqualified_id)
6732 goto PastIdentifier;
6736 "There's a C++-specific check for tok::identifier above");
6737 assert(Tok.getIdentifierInfo() &&
"Not an identifier?");
6738 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6741 goto PastIdentifier;
6746 bool DiagnoseIdentifier =
false;
6750 DiagnoseIdentifier =
true;
6753 DiagnoseIdentifier =
6761 !isCXX11VirtSpecifier(Tok))
6763 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6764 if (DiagnoseIdentifier) {
6765 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
6769 goto PastIdentifier;
6773 if (Tok.is(tok::l_paren)) {
6778 RevertingTentativeParsingAction PA(*
this);
6783 goto PastIdentifier;
6790 ParseParenDeclarator(D);
6803 DeclScopeObj.EnterDeclaratorScope();
6814 diag::ext_abstract_pack_declarator_parens);
6816 if (Tok.getKind() == tok::annot_pragma_parser_crash)
6818 if (Tok.is(tok::l_square))
6819 return ParseMisplacedBracketDeclarator(D);
6824 !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
6825 Tok.getIdentifierInfo()->isCPlusPlusKeyword(
getLangOpts())) {
6827 diag::err_expected_member_name_or_semi_objcxx_keyword)
6828 << Tok.getIdentifierInfo()
6831 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6834 goto PastIdentifier;
6837 diag::err_expected_member_name_or_semi)
6841 if (Tok.getKind() == tok::TokenKind::kw_while) {
6842 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6844 if (Tok.isOneOf(tok::period, tok::arrow))
6845 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
6848 if (Tok.isAtStartOfLine() && Loc.
isValid())
6849 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
6853 diag::err_expected_unqualified_id)
6858 diag::err_expected_either)
6859 << tok::identifier << tok::l_paren;
6868 "Haven't past the location of the identifier yet?");
6872 MaybeParseCXX11Attributes(D);
6875 if (Tok.is(tok::l_paren)) {
6887 bool IsAmbiguous =
false;
6899 AllowImplicitTypename =
6907 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
6908 bool IsFunctionDecl =
6909 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
6910 TentativelyDeclaredIdentifiers.pop_back();
6911 if (!IsFunctionDecl)
6914 ParsedAttributes attrs(AttrFactory);
6917 if (IsFunctionDeclaration)
6918 Actions.ActOnStartFunctionDeclarationDeclarator(D,
6919 TemplateParameterDepth);
6920 ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
6921 if (IsFunctionDeclaration)
6922 Actions.ActOnFinishFunctionDeclarationDeclarator(D);
6923 PrototypeScope.Exit();
6924 }
else if (Tok.is(tok::l_square)) {
6925 ParseBracketDeclarator(D);
6926 }
else if (Tok.isRegularKeywordAttribute()) {
6928 Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();
6933 if (!T.consumeOpen())
6944 Diag(Tok, diag::err_requires_clause_inside_parens);
6958void Parser::ParseDecompositionDeclarator(
Declarator &D) {
6959 assert(Tok.is(tok::l_square));
6961 TentativeParsingAction PA(*
this);
6966 DiagnoseAndSkipCXX11Attributes();
6970 if (!(Tok.isOneOf(tok::identifier, tok::ellipsis) &&
6972 tok::identifier, tok::l_square, tok::ellipsis)) &&
6973 !(Tok.is(tok::r_square) &&
6976 return ParseMisplacedBracketDeclarator(D);
6979 SourceLocation PrevEllipsisLoc;
6980 SmallVector<DecompositionDeclarator::Binding, 32>
Bindings;
6981 while (Tok.isNot(tok::r_square)) {
6983 if (Tok.is(tok::comma))
6986 if (Tok.is(tok::identifier)) {
6988 Diag(EndLoc, diag::err_expected)
6991 Diag(Tok, diag::err_expected_comma_or_rsquare);
6994 SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis},
6996 if (Tok.is(tok::comma))
6998 else if (Tok.is(tok::r_square))
7003 if (isCXX11AttributeSpecifier() !=
7005 DiagnoseAndSkipCXX11Attributes();
7007 SourceLocation EllipsisLoc;
7009 if (Tok.is(tok::ellipsis)) {
7011 : diag::ext_cxx_binding_pack);
7012 if (PrevEllipsisLoc.
isValid()) {
7013 Diag(Tok, diag::err_binding_multiple_ellipses);
7014 Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
7017 EllipsisLoc = Tok.getLocation();
7018 PrevEllipsisLoc = EllipsisLoc;
7022 if (Tok.isNot(tok::identifier)) {
7023 Diag(Tok, diag::err_expected) << tok::identifier;
7027 IdentifierInfo *II = Tok.getIdentifierInfo();
7028 SourceLocation Loc = Tok.getLocation();
7031 if (Tok.is(tok::ellipsis) && !PrevEllipsisLoc.
isValid()) {
7032 DiagnoseMisplacedEllipsis(Tok.getLocation(), Loc, EllipsisLoc.
isValid(),
7034 EllipsisLoc = Tok.getLocation();
7038 ParsedAttributes Attrs(AttrFactory);
7039 if (isCXX11AttributeSpecifier() !=
7042 ? diag::warn_cxx23_compat_decl_attrs_on_binding
7043 : diag::ext_decl_attrs_on_binding);
7044 MaybeParseCXX11Attributes(Attrs);
7047 Bindings.push_back({II, Loc, std::move(Attrs), EllipsisLoc});
7050 if (Tok.isNot(tok::r_square))
7057 Diag(Tok.getLocation(), diag::ext_decomp_decl_empty);
7065 T.getCloseLocation());
7068void Parser::ParseParenDeclarator(
Declarator &D) {
7072 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7084 ParsedAttributes attrs(AttrFactory);
7085 bool RequiresArg =
false;
7086 if (Tok.is(tok::kw___attribute)) {
7087 ParseGNUAttributes(attrs);
7095 ParseMicrosoftTypeAttributes(attrs);
7098 if (Tok.is(tok::kw___pascal))
7099 ParseBorlandTypeAttributes(attrs);
7111 }
else if (Tok.is(tok::r_paren) ||
7113 Tok.is(tok::ellipsis) &&
7115 isDeclarationSpecifier(
7117 isCXX11AttributeSpecifier() !=
7137 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7142 std::move(attrs), T.getCloseLocation());
7148 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7166 ParseFunctionDeclarator(D, attrs, T,
false, RequiresArg);
7167 PrototypeScope.Exit();
7170void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7172 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7180 bool IsCXX11MemberFunction =
7187 Actions.CurContext->isRecord());
7188 if (!IsCXX11MemberFunction)
7208 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,
7209 IsCXX11MemberFunction);
7212void Parser::ParseFunctionDeclarator(
Declarator &D,
7217 assert(
getCurScope()->isFunctionPrototypeScope() &&
7218 "Should call from a Function scope");
7224 bool HasProto =
false;
7226 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
7228 SourceLocation EllipsisLoc;
7230 DeclSpec DS(AttrFactory);
7231 bool RefQualifierIsLValueRef =
true;
7232 SourceLocation RefQualifierLoc;
7234 SourceRange ESpecRange;
7235 SmallVector<ParsedType, 2> DynamicExceptions;
7236 SmallVector<SourceRange, 2> DynamicExceptionRanges;
7239 ParsedAttributes FnAttrs(AttrFactory);
7241 SourceLocation TrailingReturnTypeLoc;
7246 SourceLocation StartLoc, LocalEndLoc, EndLoc;
7247 SourceLocation LParenLoc, RParenLoc;
7249 StartLoc = LParenLoc;
7251 if (isFunctionDeclaratorIdentifierList()) {
7253 Diag(Tok, diag::err_argument_required_after_attribute);
7255 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7259 LocalEndLoc = RParenLoc;
7264 MaybeParseCXX11Attributes(FnAttrs);
7265 ProhibitAttributes(FnAttrs);
7267 if (Tok.isNot(tok::r_paren))
7268 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7269 else if (RequiresArg)
7270 Diag(Tok, diag::err_argument_required_after_attribute);
7281 LocalEndLoc = RParenLoc;
7290 ParseTypeQualifierListOpt(
7291 DS, AR_NoAttributesParsed,
7294 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);
7301 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7302 EndLoc = RefQualifierLoc;
7304 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7305 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7322 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
7339 ESpecType = tryParseExceptionSpecification(Delayed,
7342 DynamicExceptionRanges,
7344 ExceptionSpecTokens);
7346 EndLoc = ESpecRange.
getEnd();
7350 MaybeParseCXX11Attributes(FnAttrs);
7353 LocalEndLoc = EndLoc;
7355 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7358 LocalEndLoc = Tok.getLocation();
7360 TrailingReturnType =
7362 TrailingReturnTypeLoc =
Range.getBegin();
7363 EndLoc =
Range.getEnd();
7366 MaybeParseCXX11Attributes(FnAttrs);
7374 SmallVector<NamedDecl *, 0> DeclsInPrototype;
7377 NamedDecl *ND = dyn_cast<NamedDecl>(D);
7380 DeclsInPrototype.push_back(ND);
7387 llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) {
7395 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7396 ParamInfo.size(), EllipsisLoc, RParenLoc,
7397 RefQualifierIsLValueRef, RefQualifierLoc,
7399 ESpecType, ESpecRange, DynamicExceptions.data(),
7400 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7401 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7402 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7403 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7405 std::move(FnAttrs), EndLoc);
7408bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7410 if (Tok.isOneOf(tok::amp, tok::ampamp)) {
7412 diag::warn_cxx98_compat_ref_qualifier :
7413 diag::ext_ref_qualifier);
7415 RefQualifierIsLValueRef = Tok.is(tok::amp);
7422bool Parser::isFunctionDeclaratorIdentifierList() {
7424 && Tok.is(tok::identifier)
7425 && !TryAltiVecVectorToken()
7441 && (!Tok.is(tok::eof) &&
7445void Parser::ParseFunctionDeclaratorIdentifierList(
7449 assert(!
getLangOpts().requiresStrictPrototypes() &&
7450 "Cannot parse an identifier list in C23 or C++");
7457 Diag(Tok, diag::ext_ident_list_in_param);
7460 llvm::SmallPtrSet<const IdentifierInfo *, 16> ParamsSoFar;
7464 if (Tok.isNot(tok::identifier)) {
7465 Diag(Tok, diag::err_expected) << tok::identifier;
7472 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
7475 if (Actions.getTypeName(*ParmII, Tok.getLocation(),
getCurScope()))
7476 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7479 if (!ParamsSoFar.insert(ParmII).second) {
7480 Diag(Tok, diag::err_param_redefinition) << ParmII;
7483 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7494void Parser::ParseParameterDeclarationClause(
7503 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7505 Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)
7524 IsACXXFunctionDeclaration) {
7536 DeclSpec DS(AttrFactory);
7538 ParsedAttributes ArgDeclAttrs(AttrFactory);
7539 ParsedAttributes ArgDeclSpecAttrs(AttrFactory);
7546 ArgDeclSpecAttrs.takeAllPrependingFrom(FirstArgAttrs);
7549 MaybeParseCXX11Attributes(ArgDeclAttrs);
7552 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7555 SourceLocation DSStart = Tok.getLocation();
7559 SourceLocation ThisLoc;
7563 ParsedTemplateInfo TemplateInfo;
7564 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7565 DeclSpecContext::DSC_normal,
7566 nullptr, AllowImplicitTypename);
7579 ParseDeclarator(ParmDeclarator);
7582 ParmDeclarator.SetRangeBegin(ThisLoc);
7585 MaybeParseGNUAttributes(ParmDeclarator);
7589 if (Tok.is(tok::kw_requires)) {
7594 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7600 const IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
7604 std::unique_ptr<CachedTokens> DefArgToks;
7608 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7609 ParmDeclarator.getNumTypeObjects() == 0) {
7611 Diag(DSStart, diag::err_missing_param);
7618 if (Tok.is(tok::ellipsis) &&
7620 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7621 !Actions.isUnexpandedParameterPackPermitted())) &&
7622 Actions.containsUnexpandedParameterPacks(ParmDeclarator))
7623 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7642 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7643 Tok.isNot(tok::raw_identifier) && !Tok.isAnnotation() &&
7644 Tok.getIdentifierInfo() &&
7645 Tok.getIdentifierInfo()->isKeyword(
getLangOpts())) {
7646 Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok);
7655 Diag(ParmDeclarator.getBeginLoc(),
7656 diag::err_function_parameter_limit_exceeded);
7664 Actions.ActOnParamDeclarator(
getCurScope(), ParmDeclarator, ThisLoc);
7669 if (Tok.is(tok::equal)) {
7670 SourceLocation EqualLoc = Tok.getLocation();
7680 ConsumeAndStoreInitializer(*DefArgToks,
7682 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
7690 EnterExpressionEvaluationContext Eval(
7697 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7698 DefArgResult = ParseBraceInitializer();
7700 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
7701 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7702 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7711 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7716 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
7717 DefArgResult.
get());
7722 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7723 ParmDeclarator.getIdentifierLoc(),
7724 Param, std::move(DefArgToks)));
7732 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
7739 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7741 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7742 Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {
7745 SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();
7746 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7747 << ParmEllipsis.
isValid() << ParmEllipsis;
7750 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7752 Diag(ParmDeclarator.getIdentifierLoc(),
7753 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7756 << !ParmDeclarator.hasName();
7758 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7770void Parser::ParseBracketDeclarator(
Declarator &D) {
7771 if (CheckProhibitedCXX11Attribute())
7779 if (Tok.getKind() == tok::r_square) {
7781 ParsedAttributes attrs(AttrFactory);
7782 MaybeParseCXX11Attributes(attrs);
7786 T.getOpenLocation(),
7787 T.getCloseLocation()),
7788 std::move(attrs), T.getCloseLocation());
7790 }
else if (Tok.getKind() == tok::numeric_constant &&
7797 ParsedAttributes attrs(AttrFactory);
7798 MaybeParseCXX11Attributes(attrs);
7802 T.getOpenLocation(),
7803 T.getCloseLocation()),
7804 std::move(attrs), T.getCloseLocation());
7806 }
else if (Tok.getKind() == tok::code_completion) {
7808 Actions.CodeCompletion().CodeCompleteBracketDeclarator(
getCurScope());
7813 SourceLocation StaticLoc;
7818 DeclSpec DS(AttrFactory);
7819 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
7827 bool isStar =
false;
7838 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7839 StaticLoc = SourceLocation();
7842 }
else if (Tok.isNot(tok::r_square)) {
7859 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7860 StaticLoc = SourceLocation();
7879 isStar, NumElements.
get(), T.getOpenLocation(),
7880 T.getCloseLocation()),
7884void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
7885 assert(Tok.is(tok::l_square) &&
"Missing opening bracket");
7888 SourceLocation StartBracketLoc = Tok.getLocation();
7892 while (Tok.is(tok::l_square)) {
7893 ParseBracketDeclarator(TempDeclarator);
7899 if (Tok.is(tok::semi))
7902 SourceLocation SuggestParenLoc = Tok.getLocation();
7905 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7910 if (TempDeclarator.getNumTypeObjects() == 0)
7914 bool NeedParens =
false;
7933 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
7939 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
7940 const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
7941 D.
AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());
7946 if (!D.
hasName() && !NeedParens)
7949 SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();
7952 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
7953 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
7956 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7961 EndLoc, CharSourceRange(BracketRange,
true))
7964 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7967 EndLoc, CharSourceRange(BracketRange,
true))
7972void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
7973 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
7974 "Not a typeof specifier");
7976 bool IsUnqual = Tok.is(tok::kw_typeof_unqual);
7977 const IdentifierInfo *II = Tok.getIdentifierInfo();
7979 Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName();
7983 bool HasParens = Tok.is(tok::l_paren);
7991 SourceRange CastRange;
7993 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);
8009 const char *PrevSpec =
nullptr;
8016 Actions.getASTContext().getPrintingPolicy()))
8017 Diag(StartLoc, DiagID) << PrevSpec;
8028 Operand = Actions.HandleExprEvaluationContextForTypeof(
Operand.get());
8034 const char *PrevSpec =
nullptr;
8041 Actions.getASTContext().getPrintingPolicy()))
8042 Diag(StartLoc, DiagID) << PrevSpec;
8045void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
8046 assert(Tok.is(tok::kw__Atomic) &&
NextToken().
is(tok::l_paren) &&
8047 "Not an atomic specifier");
8051 if (T.consumeOpen())
8055 if (
Result.isInvalid()) {
8069 const char *PrevSpec =
nullptr;
8073 Actions.getASTContext().getPrintingPolicy()))
8074 Diag(StartLoc, DiagID) << PrevSpec;
8077bool Parser::TryAltiVecVectorTokenOutOfLine() {
8079 switch (
Next.getKind()) {
8080 default:
return false;
8083 case tok::kw_signed:
8084 case tok::kw_unsigned:
8089 case tok::kw_double:
8092 case tok::kw___bool:
8093 case tok::kw___pixel:
8094 Tok.setKind(tok::kw___vector);
8096 case tok::identifier:
8097 if (
Next.getIdentifierInfo() == Ident_pixel) {
8098 Tok.setKind(tok::kw___vector);
8101 if (
Next.getIdentifierInfo() == Ident_bool ||
8102 Next.getIdentifierInfo() == Ident_Bool) {
8103 Tok.setKind(tok::kw___vector);
8111 const char *&PrevSpec,
unsigned &DiagID,
8113 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
8114 if (Tok.getIdentifierInfo() == Ident_vector) {
8116 switch (
Next.getKind()) {
8119 case tok::kw_signed:
8120 case tok::kw_unsigned:
8125 case tok::kw_double:
8128 case tok::kw___bool:
8129 case tok::kw___pixel:
8132 case tok::identifier:
8133 if (
Next.getIdentifierInfo() == Ident_pixel) {
8137 if (
Next.getIdentifierInfo() == Ident_bool ||
8138 Next.getIdentifierInfo() == Ident_Bool) {
8147 }
else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
8151 }
else if ((Tok.getIdentifierInfo() == Ident_bool) &&
8159TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8162 SmallVector<Token, 4> Tokens;
8165 auto &SourceMgr = PP.getSourceManager();
8166 FileID FID = SourceMgr.createFileID(
8167 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8171 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8172 L.setParsingPreprocessorDirective(
true);
8178 Tokens.push_back(Tok);
8179 }
while (Tok.isNot(tok::eod));
8184 Token &EndToken = Tokens.back();
8191 Tokens.push_back(Tok);
8194 PP.EnterTokenStream(Tokens,
false,
8209 (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {
8210 Diag(Tok.getLocation(), diag::err_type_unparsed);
8215 while (Tok.isNot(tok::eof))
8219 if (Tok.is(tok::eof) && Tok.getEofData() == TypeStr.data())
8224void Parser::DiagnoseBitIntUse(
const Token &
Tok) {
8228 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8229 "expected either an _ExtInt or _BitInt token!");
8231 SourceLocation Loc = Tok.getLocation();
8232 if (Tok.is(tok::kw__ExtInt)) {
8233 Diag(Loc, diag::warn_ext_int_deprecated)
8239 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)
SourceLocation getOverflowBehaviorLoc() const
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceRange getSourceRange() const LLVM_READONLY
bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void SetRangeEnd(SourceLocation Loc)
bool SetBitIntType(SourceLocation KWLoc, Expr *BitWidth, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_auto_type
static const TST TST_interface
static const TST TST_double
static const TST TST_typeofExpr
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
void SetRangeStart(SourceLocation Loc)
bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getNoreturnSpecLoc() const
static const TST TST_union
static const TST TST_char
static const TST TST_bool
static const TST TST_char16
SourceLocation getExplicitSpecLoc() const
SourceLocation getFriendSpecLoc() const
SourceLocation getModulePrivateSpecLoc() const
bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void UpdateTypeRep(ParsedType Rep)
TSCS getThreadStorageClassSpec() const
bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasAttributes() const
static const TST TST_accum
static const TST TST_half
ParsedAttributes & getAttributes()
bool SetOverflowBehavior(OverflowBehaviorType::OverflowBehaviorKind Kind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getConstSpecLoc() const
static const TST TST_ibm128
void addAttributes(const ParsedAttributesView &AL)
Concatenates two attribute lists.
static const TST TST_enum
bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool isWrapSpecified() const
static const TST TST_float128
void takeAttributesAppendingingFrom(ParsedAttributes &attrs)
void Finish(Sema &S, const PrintingPolicy &Policy)
Finish - This does final analysis of the declspec, issuing diagnostics for things like "_Complex" (la...
bool isInlineSpecified() const
SourceLocation getRestrictSpecLoc() const
static const TST TST_typeof_unqualExpr
static const TST TST_class
bool hasTagDefinition() const
static const TST TST_decimal64
unsigned getParsedSpecifiers() const
Return a bitmask of which flavors of specifiers this DeclSpec includes.
void ClearFunctionSpecs()
bool SetTypeQual(TQ T, SourceLocation Loc)
static const TST TST_wchar
static const TST TST_void
bool isTypeAltiVecVector() const
void ClearConstexprSpec()
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
static const TST TST_float
static const TST TST_atomic
static const TST TST_fract
SourceLocation getThreadStorageClassSpecLoc() const
Decl * getRepAsDecl() const
static const TST TST_float16
static const TST TST_unspecified
SourceLocation getAtomicSpecLoc() const
SourceLocation getVirtualSpecLoc() const
SourceLocation getConstexprSpecLoc() const
CXXScopeSpec & getTypeSpecScope()
bool isEmpty() const
isEmpty - Return true if this declaration specifier is completely empty: no tokens were parsed in the...
SourceLocation getTypeSpecTypeLoc() const
static const TSCS TSCS_thread_local
bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal32
bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
TypeSpecifierWidth getTypeSpecWidth() const
static const TST TST_char32
bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal128
bool isTypeSpecOwned() const
SourceLocation getInlineSpecLoc() const
SourceLocation getUnalignedSpecLoc() const
static const TST TST_int128
SourceLocation getVolatileSpecLoc() const
FriendSpecified isFriendSpecified() const
bool hasExplicitSpecifier() const
bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasConstexprSpecifier() const
static const TST TST_typeofType
bool SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_auto
@ PQ_StorageClassSpecifier
ConstexprSpecKind getConstexprSpecifier() const
static const TST TST_struct
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
Information about one declarator, including the parsed type information and the identifier.
bool isFunctionDeclarator(unsigned &idx) const
isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...
bool isPastIdentifier() const
isPastIdentifier - Return true if we have parsed beyond the point where the name would appear.
void SetRangeBegin(SourceLocation Loc)
SetRangeBegin - Set the start of the source range to Loc, unless it's invalid.
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
void setCommaLoc(SourceLocation CL)
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
SourceLocation getIdentifierLoc() const
void SetIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
bool mayOmitIdentifier() const
mayOmitIdentifier - Return true if the identifier is either optional or not allowed.
SourceLocation getEndLoc() const LLVM_READONLY
bool mayBeFollowedByCXXDirectInit() const
mayBeFollowedByCXXDirectInit - Return true if the declarator can be followed by a C++ direct initiali...
bool hasGroupingParens() const
void setDecompositionBindings(SourceLocation LSquareLoc, MutableArrayRef< DecompositionDeclarator::Binding > Bindings, SourceLocation RSquareLoc)
Set the decomposition bindings for this declarator.
void setInvalidType(bool Val=true)
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
bool mayHaveIdentifier() const
mayHaveIdentifier - Return true if the identifier is either optional or required.
void setGroupingParens(bool flag)
SourceLocation getEllipsisLoc() const
DeclaratorContext getContext() const
SourceLocation getBeginLoc() const LLVM_READONLY
void setTrailingRequiresClause(Expr *TRC)
Sets a trailing requires clause for this declarator.
void setHasInitializer(bool Val=true)
UnqualifiedId & getName()
Retrieve the name specified by this declarator.
void setTemplateParameterLists(ArrayRef< TemplateParameterList * > TPLs)
Sets the template parameter lists that preceded the declarator.
bool isFirstDeclarator() const
bool hasTrailingRequiresClause() const
Determine whether a trailing requires clause was written in this declarator.
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
The template parameter lists that preceded the declarator.
bool isFunctionDeclaratorAFunctionDeclaration() const
Return true if a function declarator at this position would be a function declaration.
void clear()
Reset the contents of this Declarator.
void setAsmLabel(Expr *E)
void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &&attrs, SourceLocation EndLoc)
AddTypeInfo - Add a chunk to this declarator.
void ExtendWithDeclSpec(const DeclSpec &DS)
ExtendWithDeclSpec - Extend the declarator source range to include the given declspec,...
void SetRangeEnd(SourceLocation Loc)
SetRangeEnd - Set the end of the source range to Loc, unless it's invalid.
void setExtension(bool Val=true)
bool isInvalidType() const
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
void setEllipsisLoc(SourceLocation EL)
const IdentifierInfo * getIdentifier() const
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code from FromRange at a specific location.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
SourceLocation getLoc() const
void setIdentifierInfo(IdentifierInfo *Ident)
IdentifierInfo * getIdentifierInfo() const
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool requiresStrictPrototypes() const
Returns true if functions without prototypes or functions with an identifier list (aka K&R C function...
std::string getOpenCLVersionString() const
Return the OpenCL C or C++ for OpenCL language name and version as a string.
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static bool isAtStartOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroBegin=nullptr)
Returns true if the given MacroID location points at the first token of the macro expansion.
static bool isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroEnd=nullptr)
Returns true if the given MacroID location points at the last token of the macro expansion.
static std::optional< Token > findNextToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeComments=false)
Finds the token that comes right after the given location.
static bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, const LangOptions &LangOpts, bool IgnoreWhiteSpace=false)
Relex the token at the specified location.
UnresolvedSetImpl::iterator iterator
static constexpr unsigned getMaxFunctionScopeDepth()
ParsedAttr - Represents a syntactic attribute.
unsigned getMaxArgs() const
static const ParsedAttributesView & none()
void prepend(iterator B, iterator E)
void addAtEnd(ParsedAttr *newAttr)
void remove(ParsedAttr *ToBeRemoved)
ParsedAttributes - A collection of parsed attributes.
void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA)
ParsedAttr * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Form formUsed)
Add microsoft __delspec(property) attribute.
ParsedAttr * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ParsedType typeArg, ParsedAttr::Form formUsed, SourceLocation ellipsisLoc=SourceLocation())
Add an attribute with a single type argument.
ParsedAttr * addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, ParsedAttr::Form form)
Add type_tag_for_datatype attribute.
void takeAllAppendingFrom(ParsedAttributes &Other)
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation getEndOfPreviousToken() const
DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagId)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Sema & getActions() const
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
ExprResult ParseConstantExpressionInExprEvalContext(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
SmallVector< Stmt *, 24 > StmtVector
A SmallVector of statements.
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
friend class ColonProtectionRAIIObject
DeclGroupPtrTy ParseOpenACCDirectiveDecl(AccessSpecifier &AS, ParsedAttributes &Attrs, DeclSpec::TST TagType, Decl *TagDecl)
Parse OpenACC directive on a declaration.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
const Token & GetLookAheadToken(unsigned N)
GetLookAheadToken - This peeks ahead N tokens and returns that token without consuming any tokens.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
ExprResult ParseArrayBoundExpression()
const TargetInfo & getTargetInfo() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
void ExitScope()
ExitScope - Pop a scope off the scope stack.
const LangOptions & getLangOpts() const
friend class ParenBraceBracketBalancer
ExprResult ParseExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtCodeCompletion
Stop at code completion.
@ StopAtSemi
Stop skipping at semicolon.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
ExprResult ParseUnevaluatedStringLiteralExpression()
ObjCContainerDecl * getObjCDeclContext() const
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
friend class BalancedDelimiterTracker
SmallVector< TemplateParameterList *, 4 > TemplateParameterLists
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
A class for parsing a DeclSpec.
A class for parsing a declarator.
A class for parsing a field declarator.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
SourceManager & getSourceManager() const
const LangOptions & getLangOpts() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
void addAddressSpace(LangAS space)
static Qualifiers fromCVRUMask(unsigned CVRU)
Represents a struct/union/class.
field_range fields() const
bool isClassScope() const
isClassScope - Return true if this scope is a class/struct/union scope.
unsigned getFlags() const
getFlags - Return the flags for this scope.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ BlockScope
This is a scope that corresponds to a block/closure object.
@ FriendScope
This is a scope of friend declaration.
@ ControlScope
The controlling scope in a if/switch/while/for statement.
@ AtCatchScope
This is a scope that corresponds to the Objective-C @catch statement.
@ TemplateParamScope
This is a scope that corresponds to the template parameters of a C++ template.
@ CompoundStmtScope
This is a compound statement scope.
@ ClassScope
The scope of a struct/union/class definition.
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ EnumScope
This scope corresponds to an enum.
@ DeclScope
This is a scope that can contain a declaration.
@ CTCK_InitGlobalVar
Unknown context.
ParserCompletionContext
Describes the context in which code completion occurs.
@ PCC_LocalDeclarationSpecifiers
Code completion occurs within a sequence of declaration specifiers within a function,...
@ PCC_MemberTemplate
Code completion occurs following one or more template headers within a class.
@ PCC_Class
Code completion occurs within a class, struct, or union.
@ PCC_ObjCImplementation
Code completion occurs within an Objective-C implementation or category implementation.
@ PCC_Namespace
Code completion occurs at top-level or namespace context.
@ PCC_Template
Code completion occurs following one or more template headers.
NameClassificationKind getKind() const
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
@ PotentiallyEvaluatedIfUsed
The current expression is potentially evaluated, but any declarations referenced inside that expressi...
void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl)
ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an initializer for the declaratio...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
A RAII object used to temporarily suppress access-like checking.
Represents the declaration of a struct/union/class/enum.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
void setKind(tok::TokenKind K)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
void * getAnnotationValue() const
tok::TokenKind getKind() const
bool isOneOf(Ts... Ks) const
void setEofData(const void *D)
void setLocation(SourceLocation L)
void startToken()
Reset all flags to cleared.
void setSemiMissing(bool Missing=true)
static constexpr int FunctionTypeNumParamsLimit
SourceLocation EndLocation
The location of the last token that describes this unqualified-id.
SourceRange getSourceRange() const LLVM_READONLY
Return the source range that covers this unqualified-id.
SourceLocation StartLocation
The location of the first token that describes this unqualified-id, which will be the location of the...
UnqualifiedIdKind getKind() const
Determine what kind of name we have.
Declaration of a variable template.
static const char * getSpecifierName(Specifier VS)
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
bool InitScope(InterpState &S, CodePtr OpPC, uint32_t I)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
const char * getKeywordSpelling(TokenKind Kind) LLVM_READNONE
Determines the spelling of simple keyword and contextual keyword tokens like 'int' and 'dynamic_cast'...
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isPragmaAnnotation(TokenKind K)
Return true if this is an annotation token representing a pragma.
The JSON file list parser is used to communicate input to InstallAPI.
TypeSpecifierType
Specifies the kind of type.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
bool isa(CodeGen::Address addr)
@ NotAttributeSpecifier
This is not an attribute specifier.
@ AttributeSpecifier
This should be treated as an attribute-specifier.
@ InvalidAttributeSpecifier
The next tokens are '[[', but this is not an attribute-specifier.
@ ExpectedParameterOrImplicitObjectParameter
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
@ IK_TemplateId
A template-id, e.g., f<int>.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
ActionResult< Decl * > DeclResult
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
llvm::SmallVector< ArgsUnion, 12U > ArgsVector
Language
The language for the input, used to select and validate the language standard and possible actions.
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
@ Template
We are parsing a template declaration.
@ ExplicitSpecialization
We are parsing an explicit specialization.
@ ExplicitInstantiation
We are parsing an explicit instantiation.
@ NonTemplate
We are not parsing a template at all.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
@ FunctionTemplate
The name was classified as a function template name.
@ Keyword
The name has been typo-corrected to a keyword.
@ DependentNonType
The name denotes a member of a dependent type that could not be resolved.
@ UndeclaredTemplate
The name was classified as an ADL-only function template name.
@ NonType
The name was classified as a specific non-type, non-template declaration.
@ Unknown
This name is not a type or template in this context, but might be something else.
@ Error
Classification failed; an error has been produced.
@ Type
The name was classified as a type.
@ TypeTemplate
The name was classified as a template whose specializations are types.
@ Concept
The name was classified as a concept name.
@ OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ UndeclaredNonType
The name was classified as an ADL-only function name.
@ VarTemplate
The name was classified as a variable template name.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Dependent_template_name
The name refers to a dependent template name:
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &&Second)
Consumes the attributes from Second and concatenates them at the end of First.
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
ActionResult< Expr * > ExprResult
@ Parens
New-expression has a C++98 paren-delimited initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_None
no exception specification
ActionResult< Stmt * > StmtResult
VersionTuple Version
The version number at which the change occurred.
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
SourceRange VersionRange
The source range covering the version number.
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, SourceLocation AtomicQualLoc, SourceLocation UnalignedQualLoc, SourceLocation OverflowBehaviorLoc={}, bool OverflowBehaviorIsWrap=false)
Return a DeclaratorChunk for a pointer.
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, ArrayRef< NamedDecl * > DeclsInPrototype, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult(), SourceLocation TrailingReturnTypeLoc=SourceLocation(), DeclSpec *MethodQualifiers=nullptr)
DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
static DeclaratorChunk getPipe(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc)
Return a DeclaratorChunk for an array.
SourceLocation Loc
Loc - The place where this type was defined.
static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, unsigned TypeQuals, SourceLocation StarLoc, SourceLocation EndLoc)
enum clang::DeclaratorChunk::@340323374315200305336204205154073066142310370142 Kind
static DeclaratorChunk getParen(SourceLocation LParenLoc, SourceLocation RParenLoc)
Return a DeclaratorChunk for a paren.
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, bool lvalue)
Return a DeclaratorChunk for a reference.
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