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(),
2659 CalledSignatureHelp =
true;
2660 return PreferredType;
2662 auto SetPreferredType = [&] {
2663 PreferredType.enterFunctionArgument(
Tok.
getLocation(), RunSignatureHelp);
2666 llvm::function_ref<void()> ExpressionStarts;
2672 ExpressionStarts = SetPreferredType;
2675 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2678 if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
2679 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2680 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2683 CalledSignatureHelp =
true;
2685 Actions.ActOnInitializerError(ThisDecl);
2686 SkipUntil(tok::r_paren, StopAtSemi);
2692 T.getCloseLocation(),
2694 Actions.AddInitializerToDecl(ThisDecl,
Initializer.get(),
2699 case InitKind::CXXBraced: {
2701 Diag(
Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2703 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2708 if (
Init.isInvalid()) {
2709 Actions.ActOnInitializerError(ThisDecl);
2711 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
true);
2714 case InitKind::Uninitialized: {
2715 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2716 Actions.ActOnUninitializedDecl(ThisDecl);
2721 Actions.FinalizeDeclaration(ThisDecl);
2722 return OuterDecl ? OuterDecl : ThisDecl;
2725void Parser::ParseSpecifierQualifierList(
2728 ParsedTemplateInfo TemplateInfo;
2732 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC,
nullptr,
2733 AllowImplicitTypename);
2738 Diag(Tok, diag::err_expected_type);
2741 Diag(Tok, diag::err_typename_requires_specqual);
2752 diag::err_typename_invalid_storageclass);
2796 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2797 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2802 ParsedTemplateInfo &TemplateInfo,
2805 assert(Tok.is(tok::identifier) &&
"should have identifier");
2807 SourceLocation Loc = Tok.getLocation();
2827 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
2845 AnnotateScopeToken(*SS,
false);
2854 if (
ParsedType T = Actions.ActOnMSVCUnknownTypeName(
2855 *Tok.getIdentifierInfo(), Tok.getLocation(),
2856 DSC == DeclSpecContext::DSC_template_type_arg)) {
2857 const char *PrevSpec;
2860 Actions.getASTContext().getPrintingPolicy());
2873 if (SS ==
nullptr) {
2874 const char *TagName =
nullptr, *FixitTagName =
nullptr;
2877 switch (Actions.isTagName(*Tok.getIdentifierInfo(),
getCurScope())) {
2880 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
2882 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
2884 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
2886 TagName=
"__interface"; FixitTagName =
"__interface ";
2887 TagKind=tok::kw___interface;
break;
2889 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
2893 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
2894 LookupResult R(Actions, TokenName, SourceLocation(),
2897 Diag(Loc, diag::err_use_of_tag_name_without_tag)
2898 << TokenName << TagName <<
getLangOpts().CPlusPlus
2904 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2905 << TokenName << TagName;
2909 if (TagKind == tok::kw_enum)
2910 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,
2911 DeclSpecContext::DSC_normal);
2913 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
2915 DeclSpecContext::DSC_normal, Attrs);
2922 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
2923 DSC == DeclSpecContext::DSC_class)) {
2927 case tok::l_paren: {
2934 TentativeParsingAction PA(*
this);
2936 TPResult TPR = TryParseDeclarator(
false);
2939 if (TPR != TPResult::False) {
2947 if (DSC == DeclSpecContext::DSC_class ||
2948 (DSC == DeclSpecContext::DSC_top_level && SS)) {
2949 IdentifierInfo *II = Tok.getIdentifierInfo();
2950 if (Actions.isCurrentClassNameTypo(II, SS)) {
2951 Diag(Loc, diag::err_constructor_bad_name)
2952 << Tok.getIdentifierInfo() << II
2954 Tok.setIdentifierInfo(II);
2972 AnnotateScopeToken(*SS,
false);
2986 IdentifierInfo *II = Tok.getIdentifierInfo();
2988 Actions.DiagnoseUnknownTypeName(II, Loc,
getCurScope(), SS,
T,
2994 const char *PrevSpec;
2997 Actions.getASTContext().getPrintingPolicy());
3002 }
else if (II != Tok.getIdentifierInfo()) {
3015 if (IsTemplateName) {
3016 SourceLocation LAngle, RAngle;
3017 TemplateArgList Args;
3018 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3027Parser::DeclSpecContext
3031 return DeclSpecContext::DSC_class;
3033 return DeclSpecContext::DSC_top_level;
3035 return DeclSpecContext::DSC_template_param;
3037 return DeclSpecContext::DSC_template_arg;
3039 return DeclSpecContext::DSC_template_type_arg;
3042 return DeclSpecContext::DSC_trailing;
3045 return DeclSpecContext::DSC_alias_declaration;
3047 return DeclSpecContext::DSC_association;
3049 return DeclSpecContext::DSC_type_specifier;
3051 return DeclSpecContext::DSC_condition;
3053 return DeclSpecContext::DSC_conv_operator;
3055 return DeclSpecContext::DSC_new;
3070 return DeclSpecContext::DSC_normal;
3073 llvm_unreachable(
"Missing DeclaratorContext case");
3080 if (isTypeIdInParens()) {
3081 SourceLocation TypeLoc = Tok.getLocation();
3083 SourceRange TypeRange(Start, Tok.getLocation());
3084 if (Actions.ActOnAlignasTypeArgument(KWName, Ty, TypeLoc, TypeRange))
3101 assert(Tok.isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3102 "Not an alignment-specifier!");
3109 if (
T.expectAndConsume())
3114 SourceLocation EllipsisLoc;
3116 ParseAlignArgument(PP.getSpelling(KWTok),
T.getOpenLocation(),
3125 *EndLoc =
T.getCloseLocation();
3132 ArgExprs.push_back(ArgExpr.
get());
3133 Attrs.
addNew(KWName, KWLoc, AttributeScopeInfo(), ArgExprs.data(), 1, Kind,
3138void Parser::DistributeCLateParsedAttrs(
Decl *Dcl,
3139 LateParsedAttrList *LateAttrs) {
3144 for (
auto *LateAttr : *LateAttrs) {
3145 if (LateAttr->Decls.empty())
3146 LateAttr->addDecl(Dcl);
3152 assert(Tok.is(tok::kw___ptrauth));
3154 IdentifierInfo *KwName = Tok.getIdentifierInfo();
3158 if (
T.expectAndConsume())
3168 ArgExprs.push_back(ER.
get());
3172 SourceLocation EndLoc =
T.getCloseLocation();
3174 if (ArgExprs.empty() || ArgExprs.size() > 3) {
3175 Diag(KwLoc, diag::err_ptrauth_qualifier_bad_arg_count);
3179 Attrs.
addNew(KwName, SourceRange(KwLoc, EndLoc), AttributeScopeInfo(),
3180 ArgExprs.data(), ArgExprs.size(),
3181 ParsedAttr::Form::Keyword(
false,
3191 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3196 if (Tok.is(tok::r_paren)) {
3197 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
3204 using ExpressionKind =
3206 EnterExpressionEvaluationContext EC(
3208 ExpressionKind::EK_AttrArgument);
3216 ArgExprs.push_back(ArgExpr.
get());
3219 ASTContext &Ctx = Actions.getASTContext();
3225 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
3226 AttributeScopeInfo(), ArgExprs.data(), ArgExprs.size(), Form);
3229ExprResult Parser::ParseExtIntegerArgument() {
3230 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3231 "Not an extended int type");
3235 if (
T.expectAndConsume())
3244 if(
T.consumeClose())
3251 DeclSpecContext DSContext,
3252 LateParsedAttrList *LateAttrs) {
3255 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3256 DSContext == DeclSpecContext::DSC_top_level);
3259 Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
3260 tok::annot_template_id) &&
3266 bool HasScope = Tok.is(tok::annot_cxxscope);
3268 Token AfterScope = HasScope ?
NextToken() : Tok;
3272 bool MightBeDeclarator =
true;
3273 if (Tok.isOneOf(tok::kw_typename, tok::annot_typename)) {
3275 MightBeDeclarator =
false;
3276 }
else if (AfterScope.
is(tok::annot_template_id)) {
3279 TemplateIdAnnotation *Annot =
3282 MightBeDeclarator =
false;
3283 }
else if (AfterScope.
is(tok::identifier)) {
3288 if (
Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3289 tok::annot_cxxscope, tok::coloncolon)) {
3291 MightBeDeclarator = false;
3292 }
else if (HasScope) {
3297 Actions.RestoreNestedNameSpecifierAnnotation(
3298 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
3300 Sema::NameClassification Classification = Actions.ClassifyName(
3303 switch (Classification.
getKind()) {
3309 llvm_unreachable(
"typo correction is not possible here");
3317 MightBeDeclarator =
false;
3332 if (MightBeDeclarator)
3335 const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
3337 diag::err_expected_after)
3348 ParsedTemplateInfo NotATemplate;
3349 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3353void Parser::ParseDeclarationSpecifiers(
3355 DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
3367 if (DSContext == DeclSpecContext::DSC_conv_operator) {
3370 DSContext = DeclSpecContext::DSC_type_specifier;
3373 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3374 DSContext == DeclSpecContext::DSC_top_level);
3375 bool AttrsLastTime =
false;
3376 ParsedAttributes attrs(AttrFactory);
3378 PrintingPolicy Policy = Actions.getPrintingPolicy();
3381 bool isStorageClass =
false;
3382 const char *PrevSpec =
nullptr;
3383 unsigned DiagID = 0;
3387 SourceLocation ConsumedEnd;
3396 if (
getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&
3399 Tok.setKind(tok::identifier);
3401 SourceLocation Loc = Tok.getLocation();
3404 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3408 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
3409 Tok.setKind(tok::identifier);
3418 bool IsTemplateSpecOrInst =
3422 switch (Tok.getKind()) {
3424 if (Tok.isRegularKeywordAttribute())
3429 ProhibitAttributes(attrs);
3432 for (
const ParsedAttr &PA : attrs) {
3433 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3434 !PA.isRegularKeywordAttribute())
3442 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3443 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3450 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3451 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3454 if (PA.getKind() == ParsedAttr::AT_LifetimeBound)
3455 Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type)
3456 << PA << PA.isRegularKeywordAttribute()
3459 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3460 << PA << PA.isRegularKeywordAttribute();
3469 DS.
Finish(Actions, Policy);
3473 case tok::kw__Alignas:
3474 diagnoseUseOfC11Keyword(Tok);
3476 case tok::kw_alignas:
3482 if (Tok.getKind() == tok::kw_alignas)
3483 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
3489 if (!isAllowedCXX11AttributeSpecifier())
3490 goto DoneWithDeclSpec;
3493 ProhibitAttributes(attrs);
3498 attrs.Range = SourceRange();
3500 ParseCXX11Attributes(attrs);
3501 AttrsLastTime =
true;
3504 case tok::code_completion: {
3508 bool AllowNonIdentifiers
3514 bool AllowNestedNameSpecifiers
3515 = DSContext == DeclSpecContext::DSC_top_level ||
3519 Actions.CodeCompletion().CodeCompleteDeclSpec(
3520 getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3526 CCC = DSContext == DeclSpecContext::DSC_class
3529 else if (DSContext == DeclSpecContext::DSC_class)
3533 else if (CurParsedObjCImpl)
3537 Actions.CodeCompletion().CodeCompleteOrdinaryName(
getCurScope(), CCC);
3541 case tok::coloncolon:
3547 goto DoneWithDeclSpec;
3549 if (Tok.is(tok::coloncolon))
3550 goto DoneWithDeclSpec;
3553 case tok::annot_cxxscope: {
3555 goto DoneWithDeclSpec;
3558 if (TemplateInfo.TemplateParams)
3560 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
3561 Tok.getAnnotationRange(),
3567 TemplateIdAnnotation *TemplateId =
Next.is(tok::annot_template_id)
3568 ? takeTemplateIdAnnotation(
Next)
3574 ConsumeAnnotationToken();
3588 if ((DSContext == DeclSpecContext::DSC_top_level ||
3589 DSContext == DeclSpecContext::DSC_class) &&
3592 isConstructorDeclarator(
false,
3599 goto DoneWithDeclSpec;
3603 ConsumeAnnotationToken();
3604 assert(Tok.is(tok::annot_template_id) &&
3605 "ParseOptionalCXXScopeSpecifier not working");
3606 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3616 ConsumeAnnotationToken();
3620 if (
Next.is(tok::annot_typename)) {
3622 ConsumeAnnotationToken();
3625 Tok.getAnnotationEndLoc(),
3626 PrevSpec, DiagID,
T, Policy);
3630 ConsumeAnnotationToken();
3634 Next.is(tok::annot_template_id) &&
3635 static_cast<TemplateIdAnnotation *
>(
Next.getAnnotationValue())
3638 ConsumeAnnotationToken();
3639 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3643 if (
Next.isNot(tok::identifier))
3644 goto DoneWithDeclSpec;
3649 if ((DSContext == DeclSpecContext::DSC_top_level ||
3650 DSContext == DeclSpecContext::DSC_class) &&
3653 isConstructorDeclarator(
false,
3657 goto DoneWithDeclSpec;
3663 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3667 false,
false,
nullptr,
3670 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3672 if (IsTemplateSpecOrInst)
3680 if (TryAnnotateTypeConstraint())
3681 goto DoneWithDeclSpec;
3682 if (Tok.isNot(tok::annot_cxxscope) ||
3686 ConsumeAnnotationToken();
3687 ParsedAttributes Attrs(AttrFactory);
3688 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3689 if (!Attrs.
empty()) {
3690 AttrsLastTime =
true;
3691 attrs.takeAllAppendingFrom(Attrs);
3695 goto DoneWithDeclSpec;
3699 ConsumeAnnotationToken();
3702 DiagID, TypeRep, Policy);
3712 case tok::annot_typename: {
3716 goto DoneWithDeclSpec;
3725 ConsumeAnnotationToken();
3730 case tok::kw___is_signed:
3742 TryKeywordIdentFallback(
true);
3745 goto DoneWithDeclSpec;
3748 case tok::kw___super:
3749 case tok::kw_decltype:
3750 case tok::identifier:
3756 goto DoneWithDeclSpec;
3762 if (!
getLangOpts().DeclSpecKeyword && Tok.is(tok::identifier) &&
3763 Tok.getIdentifierInfo()->getName() ==
"__declspec") {
3764 Diag(Loc, diag::err_ms_attributes_not_enabled);
3774 if (
T.consumeOpen()) {
3775 assert(
false &&
"Not a left paren?");
3790 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3794 if (IsTemplateSpecOrInst)
3798 if (IsTemplateSpecOrInst)
3801 goto DoneWithDeclSpec;
3804 if (!Tok.is(tok::identifier))
3809 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID,
isInvalid))
3815 goto DoneWithDeclSpec;
3817 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3818 isObjCInstancetype()) {
3819 ParsedType TypeRep = Actions.ObjC().ActOnObjCInstanceType(Loc);
3822 DiagID, TypeRep, Policy);
3834 Actions.isCurrentClassName(*Tok.getIdentifierInfo(),
getCurScope()) &&
3835 isConstructorDeclarator(
true,
3838 goto DoneWithDeclSpec;
3841 *Tok.getIdentifierInfo(), Tok.getLocation(),
getCurScope(),
nullptr,
3842 false,
false,
nullptr,
false,
false,
3843 isClassTemplateDeductionContext(DSContext));
3848 if (TryAnnotateTypeConstraint())
3849 goto DoneWithDeclSpec;
3850 if (Tok.isNot(tok::identifier))
3852 ParsedAttributes Attrs(AttrFactory);
3853 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
3854 if (!Attrs.
empty()) {
3855 AttrsLastTime =
true;
3856 attrs.takeAllAppendingFrom(Attrs);
3860 goto DoneWithDeclSpec;
3867 (DSContext == DeclSpecContext::DSC_class ||
3868 DSContext == DeclSpecContext::DSC_top_level) &&
3869 Actions.isDeductionGuideName(
getCurScope(), *Tok.getIdentifierInfo(),
3870 Tok.getLocation(), SS) &&
3871 isConstructorDeclarator(
true,
3873 goto DoneWithDeclSpec;
3876 DiagID, TypeRep, Policy);
3887 SourceLocation NewEndLoc;
3888 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3903 case tok::annot_template_id: {
3904 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
3915 TemplateId =
nullptr;
3923 tok::kw_volatile, tok::kw_restrict, tok::amp,
3925 Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
3929 TemplateId, Policy);
3933 goto DoneWithDeclSpec;
3935 if (TemplateId && !
isInvalid && Actions.CheckTypeConstraint(TemplateId))
3936 TemplateId =
nullptr;
3938 ConsumeAnnotationToken();
3939 SourceLocation AutoLoc = Tok.getLocation();
3942 if (Tracker.consumeOpen()) {
3944 Diag(Tok, diag::err_expected) << tok::l_paren;
3948 Tracker.skipToEnd();
3949 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
3954 Tracker.consumeClose();
3957 ConsumedEnd = Tok.getLocation();
3962 DiagID, TemplateId, Policy);
3965 TemplateId, Policy);
3974 goto DoneWithDeclSpec;
3982 isConstructorDeclarator(
true,
3985 goto DoneWithDeclSpec;
3990 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3995 case tok::kw___attribute:
3996 case tok::kw___declspec:
3997 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4001 case tok::kw___forceinline: {
4003 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
4004 SourceLocation AttrNameLoc = Tok.getLocation();
4006 nullptr, 0, tok::kw___forceinline);
4010 case tok::kw___unaligned:
4016 case tok::kw___ptrauth:
4020 case tok::kw___sptr:
4021 case tok::kw___uptr:
4022 case tok::kw___ptr64:
4023 case tok::kw___ptr32:
4025 case tok::kw___cdecl:
4026 case tok::kw___stdcall:
4027 case tok::kw___fastcall:
4028 case tok::kw___thiscall:
4029 case tok::kw___regcall:
4030 case tok::kw___vectorcall:
4034 case tok::kw___funcref:
4039 case tok::kw___pascal:
4044 case tok::kw___kernel:
4049 case tok::kw___noinline__:
4054 case tok::kw__Nonnull:
4055 case tok::kw__Nullable:
4056 case tok::kw__Nullable_result:
4057 case tok::kw__Null_unspecified:
4062 case tok::kw___kindof:
4064 AttributeScopeInfo(),
nullptr, 0,
4070 case tok::kw_typedef:
4072 PrevSpec, DiagID, Policy);
4073 isStorageClass =
true;
4075 case tok::kw_extern:
4077 Diag(Tok, diag::ext_thread_before) <<
"extern";
4079 PrevSpec, DiagID, Policy);
4080 isStorageClass =
true;
4082 case tok::kw___private_extern__:
4084 Loc, PrevSpec, DiagID, Policy);
4085 isStorageClass =
true;
4087 case tok::kw_static:
4089 Diag(Tok, diag::ext_thread_before) <<
"static";
4091 PrevSpec, DiagID, Policy);
4092 isStorageClass =
true;
4098 PrevSpec, DiagID, Policy);
4100 Diag(Tok, diag::ext_auto_storage_class)
4107 PrevSpec, DiagID, Policy);
4108 isStorageClass =
true;
4110 case tok::kw___auto_type:
4111 Diag(Tok, diag::ext_auto_type);
4115 case tok::kw_register:
4117 PrevSpec, DiagID, Policy);
4118 isStorageClass =
true;
4120 case tok::kw_mutable:
4122 PrevSpec, DiagID, Policy);
4123 isStorageClass =
true;
4125 case tok::kw___thread:
4128 isStorageClass =
true;
4130 case tok::kw_thread_local:
4132 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4141 Loc, PrevSpec, DiagID);
4142 isStorageClass =
true;
4144 case tok::kw__Thread_local:
4145 diagnoseUseOfC11Keyword(Tok);
4147 Loc, PrevSpec, DiagID);
4148 isStorageClass =
true;
4152 case tok::kw_inline:
4155 case tok::kw_virtual:
4159 !
getActions().getOpenCLOptions().isAvailableOption(
4161 DiagID = diag::err_openclcxx_virtual_function;
4162 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4165 DiagID = diag::err_hlsl_virtual_function;
4166 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4172 case tok::kw_explicit: {
4173 SourceLocation ExplicitLoc = Loc;
4174 SourceLocation CloseParenLoc;
4176 ConsumedEnd = ExplicitLoc;
4178 if (Tok.is(tok::l_paren)) {
4181 ? diag::warn_cxx17_compat_explicit_bool
4182 : diag::ext_explicit_bool);
4184 ExprResult ExplicitExpr(
static_cast<Expr *
>(
nullptr));
4186 Tracker.consumeOpen();
4188 EnterExpressionEvaluationContext ConstantEvaluated(
4192 ConsumedEnd = Tok.getLocation();
4193 if (ExplicitExpr.isUsable()) {
4194 CloseParenLoc = Tok.getLocation();
4195 Tracker.consumeClose();
4197 Actions.ActOnExplicitBoolSpecifier(ExplicitExpr.get());
4199 Tracker.skipToEnd();
4201 Diag(Tok.getLocation(), diag::warn_cxx20_compat_explicit_bool);
4205 ExplicitSpec, CloseParenLoc);
4208 case tok::kw__Noreturn:
4209 diagnoseUseOfC11Keyword(Tok);
4214 case tok::kw_friend:
4215 if (DSContext == DeclSpecContext::DSC_class) {
4222 DiagID = diag::err_friend_invalid_in_context;
4228 case tok::kw___module_private__:
4233 case tok::kw_constexpr:
4235 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4239 case tok::kw_consteval:
4243 case tok::kw_constinit:
4251 Diag(Tok, diag::err_unknown_typename) << Tok.getName();
4255 goto DoneWithDeclSpec;
4266 PrevSpec, DiagID, Policy);
4268 case tok::kw___int64:
4270 PrevSpec, DiagID, Policy);
4272 case tok::kw_signed:
4276 case tok::kw_unsigned:
4280 case tok::kw__Complex:
4282 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4286 case tok::kw__Imaginary:
4288 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4304 case tok::kw__ExtInt:
4305 case tok::kw__BitInt: {
4306 DiagnoseBitIntUse(Tok);
4311 ConsumedEnd = PrevTokLocation;
4314 case tok::kw___int128:
4322 case tok::kw___bf16:
4330 case tok::kw_double:
4334 case tok::kw__Float16:
4338 case tok::kw__Accum:
4340 "This keyword is only used when fixed point types are enabled "
4341 "with `-ffixed-point`");
4345 case tok::kw__Fract:
4347 "This keyword is only used when fixed point types are enabled "
4348 "with `-ffixed-point`");
4354 "This keyword is only used when fixed point types are enabled "
4355 "with `-ffixed-point`");
4358 case tok::kw___float128:
4362 case tok::kw___ibm128:
4366 case tok::kw_wchar_t:
4370 case tok::kw_char8_t:
4374 case tok::kw_char16_t:
4378 case tok::kw_char32_t:
4384 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4388 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4390 if (Tok.is(tok::kw_bool) &&
4394 DiagID = diag::err_bool_redeclaration;
4396 Tok.setKind(tok::identifier);
4403 case tok::kw__Decimal32:
4407 case tok::kw__Decimal64:
4411 case tok::kw__Decimal128:
4415 case tok::kw___vector:
4418 case tok::kw___pixel:
4421 case tok::kw___bool:
4426 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4429 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
4430 Tok.setKind(tok::identifier);
4431 goto DoneWithDeclSpec;
4433 DiagID = diag::err_opencl_unknown_type_specifier;
4434 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4440#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4441#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4442#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4443 case tok::kw_##ImgType##_t: \
4444 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4445 goto DoneWithDeclSpec; \
4447#include "clang/Basic/OpenCLImageTypes.def"
4448 case tok::kw___unknown_anytype:
4450 PrevSpec, DiagID, Policy);
4455 case tok::kw_struct:
4456 case tok::kw___interface:
4457 case tok::kw_union: {
4464 ParsedAttributes Attributes(AttrFactory);
4465 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
4466 EnteringContext, DSContext, Attributes);
4470 if (!Attributes.empty()) {
4471 AttrsLastTime =
true;
4472 attrs.takeAllAppendingFrom(Attributes);
4480 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
4488 case tok::kw_volatile:
4492 case tok::kw_restrict:
4498 case tok::kw_typename:
4501 goto DoneWithDeclSpec;
4503 if (!Tok.is(tok::kw_typename))
4508 case tok::kw_typeof:
4509 case tok::kw_typeof_unqual:
4510 ParseTypeofSpecifier(DS);
4513 case tok::annot_decltype:
4514 ParseDecltypeSpecifier(DS);
4517 case tok::annot_pack_indexing_type:
4518 ParsePackIndexingType(DS);
4521 case tok::annot_pragma_pack:
4525 case tok::annot_pragma_ms_pragma:
4526 HandlePragmaMSPragma();
4529 case tok::annot_pragma_ms_vtordisp:
4530 HandlePragmaMSVtorDisp();
4533 case tok::annot_pragma_ms_pointers_to_members:
4534 HandlePragmaMSPointersToMembers();
4537 case tok::annot_pragma_export:
4538 HandlePragmaExport();
4541#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4542#include "clang/Basic/TransformTypeTraits.def"
4546 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4547 goto ParseIdentifier;
4550 case tok::kw__Atomic:
4555 diagnoseUseOfC11Keyword(Tok);
4557 ParseAtomicSpecifier(DS);
4565 case tok::kw___generic:
4570 if (!Actions.getLangOpts().OpenCLGenericAddressSpace) {
4571 DiagID = diag::err_opencl_unknown_type_specifier;
4572 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4577 case tok::kw_private:
4581 goto DoneWithDeclSpec;
4583 case tok::kw___private:
4584 case tok::kw___global:
4585 case tok::kw___local:
4586 case tok::kw___constant:
4588 case tok::kw___read_only:
4589 case tok::kw___write_only:
4590 case tok::kw___read_write:
4594 case tok::kw_groupshared:
4602#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
4603 case tok::kw_##Name: \
4604 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4607#include "clang/Basic/HLSLIntangibleTypes.def"
4614 goto DoneWithDeclSpec;
4616 SourceLocation StartLoc = Tok.getLocation();
4617 SourceLocation EndLoc;
4619 if (
Type.isUsable()) {
4621 PrevSpec, DiagID,
Type.get(),
4622 Actions.getASTContext().getPrintingPolicy()))
4623 Diag(StartLoc, DiagID) << PrevSpec;
4639 assert(PrevSpec &&
"Method did not return previous specifier!");
4642 if (DiagID == diag::ext_duplicate_declspec ||
4643 DiagID == diag::ext_warn_duplicate_declspec ||
4644 DiagID == diag::err_duplicate_declspec)
4645 Diag(Loc, DiagID) << PrevSpec
4648 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4652 Diag(Loc, DiagID) << PrevSpec;
4655 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4659 AttrsLastTime =
false;
4671 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4674 for (
auto *I : RD->decls()) {
4675 auto *VD = dyn_cast<ValueDecl>(I);
4683 for (
const auto &DD : CAT->dependent_decls()) {
4684 if (!RD->containsDecl(DD.getDecl())) {
4685 P.
Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4686 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4687 P.
Diag(DD.getDecl()->getBeginLoc(),
4688 diag::note_flexible_array_counted_by_attr_field)
4695void Parser::ParseStructDeclaration(
4698 LateParsedAttrList *LateFieldAttrs) {
4700 if (Tok.is(tok::kw___extension__)) {
4702 ExtensionRAIIObject O(Diags);
4704 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4708 ParsedAttributes Attrs(AttrFactory);
4709 MaybeParseCXX11Attributes(Attrs);
4712 ParseSpecifierQualifierList(DS);
4716 if (Tok.is(tok::semi)) {
4721 ProhibitAttributes(Attrs);
4722 RecordDecl *AnonRecord =
nullptr;
4723 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
4725 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4731 bool FirstDeclarator =
true;
4732 SourceLocation CommaLoc;
4734 ParsingFieldDeclarator DeclaratorInfo(*
this, DS, Attrs);
4735 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4738 if (!FirstDeclarator) {
4741 DiagnoseAndSkipCXX11Attributes();
4742 MaybeParseGNUAttributes(DeclaratorInfo.D);
4743 DiagnoseAndSkipCXX11Attributes();
4748 if (Tok.isNot(tok::colon)) {
4751 ParseDeclarator(DeclaratorInfo.D);
4753 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.getLocation());
4765 DeclaratorInfo.BitfieldSize = Res.
get();
4769 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
4772 Decl *
Field = FieldsCallback(DeclaratorInfo);
4774 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
4781 FirstDeclarator =
false;
4787void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs,
bool EnterScope,
4789 assert(LAs.parseSoon() &&
4790 "Attribute list should be marked for immediate parsing.");
4791 for (
auto *LA : LAs) {
4792 ParseLexedCAttribute(*LA,
EnterScope, OutAttrs);
4798void Parser::ParseLexedCAttribute(LateParsedAttribute &LA,
bool EnterScope,
4803 AttrEnd.startToken();
4804 AttrEnd.setKind(tok::eof);
4805 AttrEnd.setLocation(Tok.getLocation());
4806 AttrEnd.setEofData(LA.Toks.data());
4807 LA.Toks.push_back(AttrEnd);
4811 LA.Toks.push_back(Tok);
4812 PP.EnterTokenStream(LA.Toks,
true,
4821 ParsedAttributes Attrs(AttrFactory);
4823 assert(LA.Decls.size() <= 1 &&
4824 "late field attribute expects to have at most one declaration.");
4827 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
nullptr,
nullptr,
4828 SourceLocation(), ParsedAttr::Form::GNU(),
nullptr);
4830 for (
auto *D : LA.Decls)
4831 Actions.ActOnFinishDelayedAttribute(
getCurScope(), D, Attrs);
4835 while (Tok.isNot(tok::eof))
4839 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
4849 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl,
RecordLoc,
4850 "parsing struct/union body");
4854 if (
T.consumeOpen())
4858 Actions.ActOnTagStartDefinition(
getCurScope(), TagDecl);
4862 LateParsedAttrList LateFieldAttrs(
true,
4866 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
4867 Tok.isNot(tok::eof)) {
4871 if (Tok.is(tok::semi)) {
4877 if (Tok.isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4878 SourceLocation DeclEnd;
4879 ParseStaticAssertDeclaration(DeclEnd);
4883 if (Tok.is(tok::annot_pragma_pack)) {
4888 if (Tok.is(tok::annot_pragma_align)) {
4889 HandlePragmaAlign();
4893 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4896 ParsedAttributes Attrs(AttrFactory);
4897 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4901 if (Tok.is(tok::annot_pragma_openacc)) {
4903 ParsedAttributes Attrs(AttrFactory);
4909 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
4911 TagType, Actions.getASTContext().getPrintingPolicy());
4912 ConsumeAnnotationToken();
4916 if (!Tok.is(tok::at)) {
4917 auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
4921 FD.D.getDeclSpec().getSourceRange().getBegin(),
4922 FD.D, FD.BitfieldSize);
4928 ParsingDeclSpec DS(*
this);
4929 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
4932 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
4933 Diag(Tok, diag::err_unexpected_at);
4938 ExpectAndConsume(tok::l_paren);
4939 if (!Tok.is(tok::identifier)) {
4940 Diag(Tok, diag::err_expected) << tok::identifier;
4944 SmallVector<Decl *, 16> Fields;
4945 Actions.ObjC().ActOnDefs(
getCurScope(), TagDecl, Tok.getLocation(),
4946 Tok.getIdentifierInfo(), Fields);
4948 ExpectAndConsume(tok::r_paren);
4954 if (Tok.is(tok::r_brace)) {
4955 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
4959 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
4968 ParsedAttributes attrs(AttrFactory);
4970 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
4973 ParseLexedCAttributeList(LateFieldAttrs,
false);
4975 SmallVector<Decl *, 32> FieldDecls(TagDecl->
fields());
4978 T.getOpenLocation(),
T.getCloseLocation(), attrs);
4980 Actions.ActOnTagFinishDefinition(
getCurScope(), TagDecl,
T.getRange());
4984 const ParsedTemplateInfo &TemplateInfo,
4987 if (Tok.is(tok::code_completion)) {
4996 ParsedAttributes attrs(AttrFactory);
4997 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
4999 SourceLocation ScopedEnumKWLoc;
5000 bool IsScopedUsingClassTag =
false;
5005 : diag::ext_scoped_enum);
5006 IsScopedUsingClassTag = Tok.is(tok::kw_class);
5011 ProhibitAttributes(attrs);
5014 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5023 bool shouldDelayDiagsInTag =
5026 SuppressAccessChecks diagsFromTag(*
this, shouldDelayDiagsInTag);
5029 AllowDefiningTypeSpec AllowEnumSpecifier =
5031 bool CanBeOpaqueEnumDeclaration =
5032 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5035 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5036 CanBeOpaqueEnumDeclaration);
5044 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5049 if (Spec.
isSet() && Tok.isNot(tok::identifier)) {
5050 Diag(Tok, diag::err_expected) << tok::identifier;
5052 if (Tok.isNot(tok::l_brace)) {
5064 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
5065 Tok.isNot(tok::colon)) {
5066 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5075 IdentifierInfo *Name =
nullptr;
5076 SourceLocation NameLoc;
5077 if (Tok.is(tok::identifier)) {
5078 Name = Tok.getIdentifierInfo();
5082 if (!Name && ScopedEnumKWLoc.
isValid()) {
5085 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5086 ScopedEnumKWLoc = SourceLocation();
5087 IsScopedUsingClassTag =
false;
5092 if (shouldDelayDiagsInTag)
5093 diagsFromTag.done();
5096 SourceRange BaseRange;
5098 bool CanBeBitfield =
5102 if (Tok.is(tok::colon)) {
5127 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5131 Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
5132 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5139 DeclSpec DS(AttrFactory);
5143 DeclSpecContext::DSC_type_specifier);
5146 BaseType = Actions.ActOnTypeName(DeclaratorInfo);
5148 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5152 DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)
5155 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5159 ? diag::warn_c17_compat_enum_fixed_underlying_type
5160 : diag::ext_c23_enum_fixed_underlying_type)
5177 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5179 else if (Tok.is(tok::l_brace)) {
5181 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
5187 ScopedEnumKWLoc = SourceLocation();
5188 IsScopedUsingClassTag =
false;
5194 }
else if (!isTypeSpecifier(DSC) &&
5195 (Tok.is(tok::semi) ||
5196 (Tok.isAtStartOfLine() &&
5197 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5202 if (Tok.isNot(tok::semi)) {
5204 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5205 PP.EnterToken(Tok,
true);
5206 Tok.setKind(tok::semi);
5212 bool IsElaboratedTypeSpecifier =
5218 diagsFromTag.redelay();
5226 Diag(Tok, diag::err_enum_template);
5234 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5238 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5240 TemplateInfo.TemplateParams->size());
5245 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5261 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5263 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5264 diag::err_keyword_not_allowed,
5267 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5268 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5269 else if (ScopedEnumKWLoc.
isValid())
5270 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5274 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5276 SkipBodyInfo SkipBody;
5279 SkipBody = Actions.shouldSkipAnonEnumBody(
getCurScope(),
5284 bool IsDependent =
false;
5285 const char *PrevSpec =
nullptr;
5290 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5291 IsScopedUsingClassTag,
5292 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5293 DSC == DeclSpecContext::DSC_template_param ||
5294 DSC == DeclSpecContext::DSC_template_type_arg,
5295 OffsetOfState, &SkipBody).get();
5305 NameLoc.
isValid() ? NameLoc : StartLoc,
5306 PrevSpec, DiagID, TagDecl, Owned,
5307 Actions.getASTContext().getPrintingPolicy()))
5308 Diag(StartLoc, DiagID) << PrevSpec;
5317 Diag(Tok, diag::err_expected_type_name_after_typename);
5323 if (
Type.isInvalid()) {
5329 NameLoc.
isValid() ? NameLoc : StartLoc,
5330 PrevSpec, DiagID,
Type.get(),
5331 Actions.getASTContext().getPrintingPolicy()))
5332 Diag(StartLoc, DiagID) << PrevSpec;
5351 ParseEnumBody(StartLoc, D, &SkipBody);
5353 !Actions.ActOnDuplicateDefinition(
getCurScope(), TagDecl, SkipBody)) {
5360 NameLoc.
isValid() ? NameLoc : StartLoc,
5361 PrevSpec, DiagID, TagDecl, Owned,
5362 Actions.getASTContext().getPrintingPolicy()))
5363 Diag(StartLoc, DiagID) << PrevSpec;
5370 Actions.ActOnTagStartDefinition(
getCurScope(), EnumDecl);
5378 Diag(
T.getOpenLocation(), diag::ext_ms_c_empty_enum_type)
5379 << SourceRange(
T.getOpenLocation(), Tok.getLocation());
5381 Diag(Tok, diag::err_empty_enum);
5384 SmallVector<Decl *, 32> EnumConstantDecls;
5385 SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
5387 Decl *LastEnumConstDecl =
nullptr;
5390 while (Tok.isNot(tok::r_brace)) {
5393 if (Tok.isNot(tok::identifier)) {
5394 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
5400 IdentifierInfo *Ident = Tok.getIdentifierInfo();
5404 ParsedAttributes attrs(AttrFactory);
5405 MaybeParseGNUAttributes(attrs);
5406 if (isAllowedCXX11AttributeSpecifier()) {
5409 ? diag::warn_cxx14_compat_ns_enum_attribute
5410 : diag::ext_ns_enum_attribute)
5412 ParseCXX11Attributes(attrs);
5415 SourceLocation EqualLoc;
5417 EnumAvailabilityDiags.emplace_back(*
this);
5419 EnterExpressionEvaluationContext ConstantEvaluated(
5428 Decl *EnumConstDecl = Actions.ActOnEnumConstant(
5429 getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
5430 EqualLoc, AssignedVal.
get(), SkipBody);
5431 EnumAvailabilityDiags.back().done();
5433 EnumConstantDecls.push_back(EnumConstDecl);
5434 LastEnumConstDecl = EnumConstDecl;
5436 if (Tok.is(tok::identifier)) {
5439 Diag(Loc, diag::err_enumerator_list_missing_comma)
5446 SourceLocation CommaLoc;
5447 if (Tok.isNot(tok::r_brace) && !
TryConsumeToken(tok::comma, CommaLoc)) {
5449 Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
5452 Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
5462 if (Tok.is(tok::r_brace) && CommaLoc.
isValid()) {
5465 diag::ext_enumerator_list_comma_cxx :
5466 diag::ext_enumerator_list_comma_c)
5469 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5479 ParsedAttributes attrs(AttrFactory);
5480 MaybeParseGNUAttributes(attrs);
5482 Actions.ActOnEnumBody(StartLoc,
T.getRange(), EnumDecl, EnumConstantDecls,
5486 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5487 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5489 EnumAvailabilityDiags[i].redelay();
5490 PD.complete(EnumConstantDecls[i]);
5494 Actions.ActOnTagFinishDefinition(
getCurScope(), EnumDecl,
T.getRange());
5499 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5500 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5504 PP.EnterToken(Tok,
true);
5505 Tok.setKind(tok::semi);
5509bool Parser::isKnownToBeTypeSpecifier(
const Token &
Tok)
const {
5510 switch (Tok.getKind()) {
5511 default:
return false;
5515 case tok::kw___int64:
5516 case tok::kw___int128:
5517 case tok::kw_signed:
5518 case tok::kw_unsigned:
5519 case tok::kw__Complex:
5520 case tok::kw__Imaginary:
5523 case tok::kw_wchar_t:
5524 case tok::kw_char8_t:
5525 case tok::kw_char16_t:
5526 case tok::kw_char32_t:
5528 case tok::kw__ExtInt:
5529 case tok::kw__BitInt:
5530 case tok::kw___bf16:
5533 case tok::kw_double:
5534 case tok::kw__Accum:
5535 case tok::kw__Fract:
5536 case tok::kw__Float16:
5537 case tok::kw___float128:
5538 case tok::kw___ibm128:
5541 case tok::kw__Decimal32:
5542 case tok::kw__Decimal64:
5543 case tok::kw__Decimal128:
5544 case tok::kw___vector:
5545#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5546#include "clang/Basic/OpenCLImageTypes.def"
5547#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5548#include "clang/Basic/HLSLIntangibleTypes.def"
5552 case tok::kw_struct:
5553 case tok::kw___interface:
5559 case tok::annot_typename:
5564bool Parser::isTypeSpecifierQualifier() {
5565 switch (Tok.getKind()) {
5566 default:
return false;
5568 case tok::identifier:
5569 if (TryAltiVecVectorToken())
5572 case tok::kw_typename:
5577 if (Tok.is(tok::identifier))
5579 return isTypeSpecifierQualifier();
5581 case tok::coloncolon:
5588 return isTypeSpecifierQualifier();
5591 case tok::kw___attribute:
5593 case tok::kw_typeof:
5594 case tok::kw_typeof_unqual:
5599 case tok::kw___int64:
5600 case tok::kw___int128:
5601 case tok::kw_signed:
5602 case tok::kw_unsigned:
5603 case tok::kw__Complex:
5604 case tok::kw__Imaginary:
5607 case tok::kw_wchar_t:
5608 case tok::kw_char8_t:
5609 case tok::kw_char16_t:
5610 case tok::kw_char32_t:
5612 case tok::kw__ExtInt:
5613 case tok::kw__BitInt:
5615 case tok::kw___bf16:
5617 case tok::kw_double:
5618 case tok::kw__Accum:
5619 case tok::kw__Fract:
5620 case tok::kw__Float16:
5621 case tok::kw___float128:
5622 case tok::kw___ibm128:
5625 case tok::kw__Decimal32:
5626 case tok::kw__Decimal64:
5627 case tok::kw__Decimal128:
5628 case tok::kw___vector:
5629#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5630#include "clang/Basic/OpenCLImageTypes.def"
5631#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5632#include "clang/Basic/HLSLIntangibleTypes.def"
5636 case tok::kw_struct:
5637 case tok::kw___interface:
5644 case tok::kw_volatile:
5645 case tok::kw_restrict:
5649 case tok::kw___unknown_anytype:
5652 case tok::annot_typename:
5659 case tok::kw___cdecl:
5660 case tok::kw___stdcall:
5661 case tok::kw___fastcall:
5662 case tok::kw___thiscall:
5663 case tok::kw___regcall:
5664 case tok::kw___vectorcall:
5666 case tok::kw___ptr64:
5667 case tok::kw___ptr32:
5668 case tok::kw___pascal:
5669 case tok::kw___unaligned:
5670 case tok::kw___ptrauth:
5672 case tok::kw__Nonnull:
5673 case tok::kw__Nullable:
5674 case tok::kw__Nullable_result:
5675 case tok::kw__Null_unspecified:
5677 case tok::kw___kindof:
5679 case tok::kw___private:
5680 case tok::kw___local:
5681 case tok::kw___global:
5682 case tok::kw___constant:
5683 case tok::kw___generic:
5684 case tok::kw___read_only:
5685 case tok::kw___read_write:
5686 case tok::kw___write_only:
5687 case tok::kw___funcref:
5690 case tok::kw_private:
5694 case tok::kw__Atomic:
5698 case tok::kw_groupshared:
5707 assert(PP.isIncrementalProcessingEnabled() &&
"Not in incremental mode");
5711 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5714 TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5715 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5716 Actions.ActOnFinishTopLevelStmtDecl(TLSD, R.get());
5718 R = Actions.ActOnNullStmt(Tok.getLocation());
5720 if (Tok.is(tok::annot_repl_input_end) &&
5721 Tok.getAnnotationValue() !=
nullptr) {
5722 ConsumeAnnotationToken();
5726 SmallVector<Decl *, 2> DeclsInGroup;
5727 DeclsInGroup.push_back(TLSD);
5730 for (Stmt *S : Stmts) {
5733 TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5734 Actions.ActOnFinishTopLevelStmtDecl(D, S);
5735 DeclsInGroup.push_back(D);
5738 return Actions.BuildDeclaratorGroup(DeclsInGroup);
5741bool Parser::isDeclarationSpecifier(
5743 bool DisambiguatingWithExpression) {
5744 switch (Tok.getKind()) {
5745 default:
return false;
5752 case tok::identifier:
5756 if (TryAltiVecVectorToken())
5759 case tok::kw_decltype:
5760 case tok::kw_typename:
5765 if (TryAnnotateTypeConstraint())
5767 if (Tok.is(tok::identifier))
5775 if (DisambiguatingWithExpression &&
5776 isStartOfObjCClassMessageMissingOpenBracket())
5779 return isDeclarationSpecifier(AllowImplicitTypename);
5781 case tok::coloncolon:
5795 case tok::kw_typedef:
5796 case tok::kw_extern:
5797 case tok::kw___private_extern__:
5798 case tok::kw_static:
5800 case tok::kw___auto_type:
5801 case tok::kw_register:
5802 case tok::kw___thread:
5803 case tok::kw_thread_local:
5804 case tok::kw__Thread_local:
5807 case tok::kw___module_private__:
5810 case tok::kw___unknown_anytype:
5815 case tok::kw___int64:
5816 case tok::kw___int128:
5817 case tok::kw_signed:
5818 case tok::kw_unsigned:
5819 case tok::kw__Complex:
5820 case tok::kw__Imaginary:
5823 case tok::kw_wchar_t:
5824 case tok::kw_char8_t:
5825 case tok::kw_char16_t:
5826 case tok::kw_char32_t:
5829 case tok::kw__ExtInt:
5830 case tok::kw__BitInt:
5832 case tok::kw___bf16:
5834 case tok::kw_double:
5835 case tok::kw__Accum:
5836 case tok::kw__Fract:
5837 case tok::kw__Float16:
5838 case tok::kw___float128:
5839 case tok::kw___ibm128:
5842 case tok::kw__Decimal32:
5843 case tok::kw__Decimal64:
5844 case tok::kw__Decimal128:
5845 case tok::kw___vector:
5849 case tok::kw_struct:
5851 case tok::kw___interface:
5857 case tok::kw_volatile:
5858 case tok::kw_restrict:
5862 case tok::kw_inline:
5863 case tok::kw_virtual:
5864 case tok::kw_explicit:
5865 case tok::kw__Noreturn:
5868 case tok::kw__Alignas:
5871 case tok::kw_friend:
5874 case tok::kw_static_assert:
5875 case tok::kw__Static_assert:
5878 case tok::kw_typeof:
5879 case tok::kw_typeof_unqual:
5882 case tok::kw___attribute:
5885 case tok::annot_decltype:
5886 case tok::annot_pack_indexing_type:
5887 case tok::kw_constexpr:
5890 case tok::kw_consteval:
5891 case tok::kw_constinit:
5894 case tok::kw__Atomic:
5897 case tok::kw_alignas:
5907 case tok::annot_typename:
5908 return !DisambiguatingWithExpression ||
5909 !isStartOfObjCClassMessageMissingOpenBracket();
5912 case tok::annot_template_id: {
5913 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
5918 return isTypeConstraintAnnotation() &&
5922 case tok::annot_cxxscope: {
5923 TemplateIdAnnotation *TemplateId =
5931 if (
NextToken().
is(tok::identifier) && TryAnnotateTypeConstraint())
5933 return isTypeConstraintAnnotation() &&
5937 case tok::kw___declspec:
5938 case tok::kw___cdecl:
5939 case tok::kw___stdcall:
5940 case tok::kw___fastcall:
5941 case tok::kw___thiscall:
5942 case tok::kw___regcall:
5943 case tok::kw___vectorcall:
5945 case tok::kw___sptr:
5946 case tok::kw___uptr:
5947 case tok::kw___ptr64:
5948 case tok::kw___ptr32:
5949 case tok::kw___forceinline:
5950 case tok::kw___pascal:
5951 case tok::kw___unaligned:
5952 case tok::kw___ptrauth:
5954 case tok::kw__Nonnull:
5955 case tok::kw__Nullable:
5956 case tok::kw__Nullable_result:
5957 case tok::kw__Null_unspecified:
5959 case tok::kw___kindof:
5961 case tok::kw___private:
5962 case tok::kw___local:
5963 case tok::kw___global:
5964 case tok::kw___constant:
5965 case tok::kw___generic:
5966 case tok::kw___read_only:
5967 case tok::kw___read_write:
5968 case tok::kw___write_only:
5969#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5970#include "clang/Basic/OpenCLImageTypes.def"
5971#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5972#include "clang/Basic/HLSLIntangibleTypes.def"
5974 case tok::kw___funcref:
5975 case tok::kw_groupshared:
5978 case tok::kw_private:
5983bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
5985 const ParsedTemplateInfo *TemplateInfo) {
5986 RevertingTentativeParsingAction TPA(*
this);
5989 if (TemplateInfo && TemplateInfo->TemplateParams)
5992 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
5999 if (Tok.is(tok::identifier)) {
6003 }
else if (Tok.is(tok::annot_template_id)) {
6004 ConsumeAnnotationToken();
6011 SkipCXX11Attributes();
6014 if (Tok.isNot(tok::l_paren)) {
6021 if (Tok.is(tok::r_paren) ||
6022 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren))) {
6028 if (isCXX11AttributeSpecifier(
false,
6035 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6037 DeclScopeObj.EnterDeclaratorScope();
6040 ParsedAttributes Attrs(AttrFactory);
6041 MaybeParseMicrosoftAttributes(Attrs);
6050 bool IsConstructor =
false;
6056 if (Tok.is(tok::kw_this)) {
6058 return isDeclarationSpecifier(ITC);
6061 if (isDeclarationSpecifier(ITC))
6062 IsConstructor =
true;
6063 else if (Tok.is(tok::identifier) ||
6064 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier))) {
6069 if (Tok.is(tok::annot_cxxscope))
6070 ConsumeAnnotationToken();
6076 switch (Tok.getKind()) {
6082 case tok::coloncolon:
6095 SkipCXX11Attributes();
6097 if (DeductionGuide) {
6099 IsConstructor = Tok.is(tok::arrow);
6102 if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
6106 IsConstructor =
true;
6108 if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {
6121 IsConstructor = IsUnqualified;
6126 IsConstructor =
true;
6130 return IsConstructor;
6133void Parser::ParseTypeQualifierListOpt(
6134 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicOrPtrauthAllowed,
6136 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6137 isAllowedCXX11AttributeSpecifier()) {
6138 ParsedAttributes Attrs(AttrFactory);
6139 ParseCXX11Attributes(Attrs);
6143 SourceLocation EndLoc;
6147 const char *PrevSpec =
nullptr;
6148 unsigned DiagID = 0;
6149 SourceLocation Loc = Tok.getLocation();
6151 switch (Tok.getKind()) {
6152 case tok::code_completion:
6154 if (CodeCompletionHandler)
6155 CodeCompletionHandler();
6157 Actions.CodeCompletion().CodeCompleteTypeQualifiers(DS);
6164 case tok::kw_volatile:
6168 case tok::kw_restrict:
6172 case tok::kw__Atomic:
6173 if (!AtomicOrPtrauthAllowed)
6174 goto DoneWithTypeQuals;
6175 diagnoseUseOfC11Keyword(Tok);
6181 case tok::kw_private:
6183 goto DoneWithTypeQuals;
6185 case tok::kw___private:
6186 case tok::kw___global:
6187 case tok::kw___local:
6188 case tok::kw___constant:
6189 case tok::kw___generic:
6190 case tok::kw___read_only:
6191 case tok::kw___write_only:
6192 case tok::kw___read_write:
6196 case tok::kw_groupshared:
6205 case tok::kw___ptrauth:
6206 if (!AtomicOrPtrauthAllowed)
6207 goto DoneWithTypeQuals;
6209 EndLoc = PrevTokLocation;
6212 case tok::kw___unaligned:
6216 case tok::kw___uptr:
6221 if (TryKeywordIdentFallback(
false))
6225 case tok::kw___sptr:
6227 case tok::kw___ptr64:
6228 case tok::kw___ptr32:
6229 case tok::kw___cdecl:
6230 case tok::kw___stdcall:
6231 case tok::kw___fastcall:
6232 case tok::kw___thiscall:
6233 case tok::kw___regcall:
6234 case tok::kw___vectorcall:
6235 if (AttrReqs & AR_DeclspecAttributesParsed) {
6239 goto DoneWithTypeQuals;
6241 case tok::kw___funcref:
6245 case tok::kw___pascal:
6246 if (AttrReqs & AR_VendorAttributesParsed) {
6250 goto DoneWithTypeQuals;
6253 case tok::kw__Nonnull:
6254 case tok::kw__Nullable:
6255 case tok::kw__Nullable_result:
6256 case tok::kw__Null_unspecified:
6261 case tok::kw___kindof:
6263 AttributeScopeInfo(),
nullptr, 0,
6268 case tok::kw___attribute:
6269 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6271 Diag(Tok, diag::err_attributes_not_allowed);
6275 if (AttrReqs & AR_GNUAttributesParsed ||
6276 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6286 DS.
Finish(Actions, Actions.getASTContext().getPrintingPolicy());
6294 assert(PrevSpec &&
"Method did not return previous specifier!");
6295 Diag(Tok, DiagID) << PrevSpec;
6304 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6305 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6311 if (Kind == tok::star || Kind == tok::caret)
6315 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6316 Lang.getOpenCLCompatibleVersion() >= 200)
6319 if (!Lang.CPlusPlus)
6322 if (Kind == tok::amp)
6330 if (Kind == tok::ampamp)
6341 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6348void Parser::ParseDeclaratorInternal(
Declarator &D,
6349 DirectDeclParseFunction DirectDeclParser) {
6350 if (Diags.hasAllExtensionsSilenced())
6357 (Tok.is(tok::coloncolon) || Tok.is(tok::kw_decltype) ||
6358 (Tok.is(tok::identifier) &&
6360 Tok.is(tok::annot_cxxscope))) {
6361 TentativeParsingAction TPA(*
this,
true);
6367 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6377 Tok.is(tok::star)) {
6381 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6382 CompoundToken::MemberPtr);
6387 DeclSpec DS(AttrFactory);
6388 ParseTypeQualifierListOpt(DS);
6392 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6393 ParseDeclaratorInternal(D, DirectDeclParser);
6407 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6417 AnnotateScopeToken(SS,
true);
6419 if (DirectDeclParser)
6420 (this->*DirectDeclParser)(D);
6428 DeclSpec DS(AttrFactory);
6429 ParseTypeQualifierListOpt(DS);
6438 if (DirectDeclParser)
6439 (this->*DirectDeclParser)(D);
6448 if (Kind == tok::star || Kind == tok::caret) {
6450 DeclSpec DS(AttrFactory);
6454 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6456 ? AR_GNUAttributesParsed
6457 : AR_GNUAttributesParsedAndRejected);
6458 ParseTypeQualifierListOpt(DS, Reqs,
true,
6463 Actions.runWithSufficientStackSpace(
6464 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6465 if (Kind == tok::star)
6479 DeclSpec DS(AttrFactory);
6483 if (Kind == tok::ampamp)
6485 diag::warn_cxx98_compat_rvalue_reference :
6486 diag::ext_rvalue_reference);
6489 ParseTypeQualifierListOpt(DS);
6498 diag::err_invalid_reference_qualifier_application) <<
"const";
6501 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6505 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6509 Actions.runWithSufficientStackSpace(
6510 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6517 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6520 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6549void Parser::ParseDirectDeclarator(
Declarator &D) {
6556 return ParseDecompositionDeclarator(D);
6570 ParseOptionalCXXScopeSpecifier(
6572 false, EnteringContext);
6587 if (Actions.ShouldEnterDeclaratorScope(
getCurScope(),
6591 DeclScopeObj.EnterDeclaratorScope();
6598 goto PastIdentifier;
6614 !Actions.containsUnexpandedParameterPacks(D) &&
6622 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6632 if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6636 bool AllowConstructorName;
6637 bool AllowDeductionGuide;
6639 AllowConstructorName =
false;
6640 AllowDeductionGuide =
false;
6644 AllowDeductionGuide =
false;
6652 SourceLocation TemplateKWLoc;
6657 true, AllowConstructorName,
6658 AllowDeductionGuide, &TemplateKWLoc,
6671 DeclScopeObj.EnterDeclaratorScope();
6678 goto PastIdentifier;
6684 diag::err_expected_unqualified_id)
6687 goto PastIdentifier;
6691 "There's a C++-specific check for tok::identifier above");
6692 assert(Tok.getIdentifierInfo() &&
"Not an identifier?");
6693 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6696 goto PastIdentifier;
6701 bool DiagnoseIdentifier =
false;
6705 DiagnoseIdentifier =
true;
6708 DiagnoseIdentifier =
6716 !isCXX11VirtSpecifier(Tok))
6718 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6719 if (DiagnoseIdentifier) {
6720 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
6724 goto PastIdentifier;
6728 if (Tok.is(tok::l_paren)) {
6733 RevertingTentativeParsingAction PA(*
this);
6738 goto PastIdentifier;
6745 ParseParenDeclarator(D);
6758 DeclScopeObj.EnterDeclaratorScope();
6769 diag::ext_abstract_pack_declarator_parens);
6771 if (Tok.getKind() == tok::annot_pragma_parser_crash)
6773 if (Tok.is(tok::l_square))
6774 return ParseMisplacedBracketDeclarator(D);
6779 !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
6780 Tok.getIdentifierInfo()->isCPlusPlusKeyword(
getLangOpts())) {
6782 diag::err_expected_member_name_or_semi_objcxx_keyword)
6783 << Tok.getIdentifierInfo()
6786 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6789 goto PastIdentifier;
6792 diag::err_expected_member_name_or_semi)
6796 if (Tok.getKind() == tok::TokenKind::kw_while) {
6797 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6799 if (Tok.isOneOf(tok::period, tok::arrow))
6800 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
6803 if (Tok.isAtStartOfLine() && Loc.
isValid())
6804 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
6808 diag::err_expected_unqualified_id)
6813 diag::err_expected_either)
6814 << tok::identifier << tok::l_paren;
6823 "Haven't past the location of the identifier yet?");
6827 MaybeParseCXX11Attributes(D);
6830 if (Tok.is(tok::l_paren)) {
6842 bool IsAmbiguous =
false;
6854 AllowImplicitTypename =
6862 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
6863 bool IsFunctionDecl =
6864 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
6865 TentativelyDeclaredIdentifiers.pop_back();
6866 if (!IsFunctionDecl)
6869 ParsedAttributes attrs(AttrFactory);
6872 if (IsFunctionDeclaration)
6873 Actions.ActOnStartFunctionDeclarationDeclarator(D,
6874 TemplateParameterDepth);
6875 ParseFunctionDeclarator(D, attrs,
T, IsAmbiguous);
6876 if (IsFunctionDeclaration)
6877 Actions.ActOnFinishFunctionDeclarationDeclarator(D);
6878 PrototypeScope.Exit();
6879 }
else if (Tok.is(tok::l_square)) {
6880 ParseBracketDeclarator(D);
6881 }
else if (Tok.isRegularKeywordAttribute()) {
6883 Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();
6888 if (!
T.consumeOpen())
6899 Diag(Tok, diag::err_requires_clause_inside_parens);
6913void Parser::ParseDecompositionDeclarator(
Declarator &D) {
6914 assert(Tok.is(tok::l_square));
6916 TentativeParsingAction PA(*
this);
6921 DiagnoseAndSkipCXX11Attributes();
6925 if (!(Tok.isOneOf(tok::identifier, tok::ellipsis) &&
6927 tok::identifier, tok::l_square, tok::ellipsis)) &&
6928 !(Tok.is(tok::r_square) &&
6931 return ParseMisplacedBracketDeclarator(D);
6934 SourceLocation PrevEllipsisLoc;
6935 SmallVector<DecompositionDeclarator::Binding, 32>
Bindings;
6936 while (Tok.isNot(tok::r_square)) {
6938 if (Tok.is(tok::comma))
6941 if (Tok.is(tok::identifier)) {
6943 Diag(EndLoc, diag::err_expected)
6946 Diag(Tok, diag::err_expected_comma_or_rsquare);
6949 SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis},
6951 if (Tok.is(tok::comma))
6953 else if (Tok.is(tok::r_square))
6958 if (isCXX11AttributeSpecifier() !=
6960 DiagnoseAndSkipCXX11Attributes();
6962 SourceLocation EllipsisLoc;
6964 if (Tok.is(tok::ellipsis)) {
6966 : diag::ext_cxx_binding_pack);
6967 if (PrevEllipsisLoc.
isValid()) {
6968 Diag(Tok, diag::err_binding_multiple_ellipses);
6969 Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
6972 EllipsisLoc = Tok.getLocation();
6973 PrevEllipsisLoc = EllipsisLoc;
6977 if (Tok.isNot(tok::identifier)) {
6978 Diag(Tok, diag::err_expected) << tok::identifier;
6982 IdentifierInfo *II = Tok.getIdentifierInfo();
6983 SourceLocation Loc = Tok.getLocation();
6986 if (Tok.is(tok::ellipsis) && !PrevEllipsisLoc.
isValid()) {
6987 DiagnoseMisplacedEllipsis(Tok.getLocation(), Loc, EllipsisLoc.
isValid(),
6989 EllipsisLoc = Tok.getLocation();
6993 ParsedAttributes Attrs(AttrFactory);
6994 if (isCXX11AttributeSpecifier() !=
6997 ? diag::warn_cxx23_compat_decl_attrs_on_binding
6998 : diag::ext_decl_attrs_on_binding);
6999 MaybeParseCXX11Attributes(Attrs);
7002 Bindings.push_back({II, Loc, std::move(Attrs), EllipsisLoc});
7005 if (Tok.isNot(tok::r_square))
7012 Diag(Tok.getLocation(), diag::ext_decomp_decl_empty);
7020 T.getCloseLocation());
7023void Parser::ParseParenDeclarator(
Declarator &D) {
7027 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7039 ParsedAttributes attrs(AttrFactory);
7040 bool RequiresArg =
false;
7041 if (Tok.is(tok::kw___attribute)) {
7042 ParseGNUAttributes(attrs);
7050 ParseMicrosoftTypeAttributes(attrs);
7053 if (Tok.is(tok::kw___pascal))
7054 ParseBorlandTypeAttributes(attrs);
7066 }
else if (Tok.is(tok::r_paren) ||
7068 Tok.is(tok::ellipsis) &&
7070 isDeclarationSpecifier(
7072 isCXX11AttributeSpecifier() !=
7092 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7097 std::move(attrs),
T.getCloseLocation());
7103 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7121 ParseFunctionDeclarator(D, attrs,
T,
false, RequiresArg);
7122 PrototypeScope.Exit();
7125void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7127 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7135 bool IsCXX11MemberFunction =
7142 Actions.CurContext->isRecord());
7143 if (!IsCXX11MemberFunction)
7163 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,
7164 IsCXX11MemberFunction);
7167void Parser::ParseFunctionDeclarator(
Declarator &D,
7172 assert(
getCurScope()->isFunctionPrototypeScope() &&
7173 "Should call from a Function scope");
7179 bool HasProto =
false;
7181 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
7183 SourceLocation EllipsisLoc;
7185 DeclSpec DS(AttrFactory);
7186 bool RefQualifierIsLValueRef =
true;
7187 SourceLocation RefQualifierLoc;
7189 SourceRange ESpecRange;
7190 SmallVector<ParsedType, 2> DynamicExceptions;
7191 SmallVector<SourceRange, 2> DynamicExceptionRanges;
7194 ParsedAttributes FnAttrs(AttrFactory);
7196 SourceLocation TrailingReturnTypeLoc;
7201 SourceLocation StartLoc, LocalEndLoc, EndLoc;
7202 SourceLocation LParenLoc, RParenLoc;
7204 StartLoc = LParenLoc;
7206 if (isFunctionDeclaratorIdentifierList()) {
7208 Diag(Tok, diag::err_argument_required_after_attribute);
7210 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7214 LocalEndLoc = RParenLoc;
7219 MaybeParseCXX11Attributes(FnAttrs);
7220 ProhibitAttributes(FnAttrs);
7222 if (Tok.isNot(tok::r_paren))
7223 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7224 else if (RequiresArg)
7225 Diag(Tok, diag::err_argument_required_after_attribute);
7236 LocalEndLoc = RParenLoc;
7245 ParseTypeQualifierListOpt(
7246 DS, AR_NoAttributesParsed,
7249 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);
7256 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7257 EndLoc = RefQualifierLoc;
7259 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7260 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7277 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
7294 ESpecType = tryParseExceptionSpecification(Delayed,
7297 DynamicExceptionRanges,
7299 ExceptionSpecTokens);
7301 EndLoc = ESpecRange.
getEnd();
7305 MaybeParseCXX11Attributes(FnAttrs);
7308 LocalEndLoc = EndLoc;
7310 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7313 LocalEndLoc = Tok.getLocation();
7315 TrailingReturnType =
7317 TrailingReturnTypeLoc =
Range.getBegin();
7318 EndLoc =
Range.getEnd();
7321 MaybeParseCXX11Attributes(FnAttrs);
7329 SmallVector<NamedDecl *, 0> DeclsInPrototype;
7332 NamedDecl *ND = dyn_cast<NamedDecl>(D);
7335 DeclsInPrototype.push_back(ND);
7342 llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) {
7350 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7351 ParamInfo.size(), EllipsisLoc, RParenLoc,
7352 RefQualifierIsLValueRef, RefQualifierLoc,
7354 ESpecType, ESpecRange, DynamicExceptions.data(),
7355 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7356 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7357 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7358 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7360 std::move(FnAttrs), EndLoc);
7363bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7365 if (Tok.isOneOf(tok::amp, tok::ampamp)) {
7367 diag::warn_cxx98_compat_ref_qualifier :
7368 diag::ext_ref_qualifier);
7370 RefQualifierIsLValueRef = Tok.is(tok::amp);
7377bool Parser::isFunctionDeclaratorIdentifierList() {
7379 && Tok.is(tok::identifier)
7380 && !TryAltiVecVectorToken()
7396 && (!Tok.is(tok::eof) &&
7400void Parser::ParseFunctionDeclaratorIdentifierList(
7404 assert(!
getLangOpts().requiresStrictPrototypes() &&
7405 "Cannot parse an identifier list in C23 or C++");
7412 Diag(Tok, diag::ext_ident_list_in_param);
7415 llvm::SmallPtrSet<const IdentifierInfo *, 16> ParamsSoFar;
7419 if (Tok.isNot(tok::identifier)) {
7420 Diag(Tok, diag::err_expected) << tok::identifier;
7427 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
7430 if (Actions.getTypeName(*ParmII, Tok.getLocation(),
getCurScope()))
7431 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7434 if (!ParamsSoFar.insert(ParmII).second) {
7435 Diag(Tok, diag::err_param_redefinition) << ParmII;
7438 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7449void Parser::ParseParameterDeclarationClause(
7458 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7460 Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)
7479 IsACXXFunctionDeclaration) {
7491 DeclSpec DS(AttrFactory);
7493 ParsedAttributes ArgDeclAttrs(AttrFactory);
7494 ParsedAttributes ArgDeclSpecAttrs(AttrFactory);
7501 ArgDeclSpecAttrs.takeAllPrependingFrom(FirstArgAttrs);
7504 MaybeParseCXX11Attributes(ArgDeclAttrs);
7507 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7510 SourceLocation DSStart = Tok.getLocation();
7514 SourceLocation ThisLoc;
7518 ParsedTemplateInfo TemplateInfo;
7519 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7520 DeclSpecContext::DSC_normal,
7521 nullptr, AllowImplicitTypename);
7534 ParseDeclarator(ParmDeclarator);
7537 ParmDeclarator.SetRangeBegin(ThisLoc);
7540 MaybeParseGNUAttributes(ParmDeclarator);
7544 if (Tok.is(tok::kw_requires)) {
7549 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7555 const IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
7559 std::unique_ptr<CachedTokens> DefArgToks;
7563 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7564 ParmDeclarator.getNumTypeObjects() == 0) {
7566 Diag(DSStart, diag::err_missing_param);
7573 if (Tok.is(tok::ellipsis) &&
7575 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7576 !Actions.isUnexpandedParameterPackPermitted())) &&
7577 Actions.containsUnexpandedParameterPacks(ParmDeclarator))
7578 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7597 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7598 Tok.isNot(tok::raw_identifier) && !Tok.isAnnotation() &&
7599 Tok.getIdentifierInfo() &&
7600 Tok.getIdentifierInfo()->isKeyword(
getLangOpts())) {
7601 Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok);
7610 Diag(ParmDeclarator.getBeginLoc(),
7611 diag::err_function_parameter_limit_exceeded);
7619 Actions.ActOnParamDeclarator(
getCurScope(), ParmDeclarator, ThisLoc);
7624 if (Tok.is(tok::equal)) {
7625 SourceLocation EqualLoc = Tok.getLocation();
7635 ConsumeAndStoreInitializer(*DefArgToks,
7637 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
7645 EnterExpressionEvaluationContext Eval(
7652 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7653 DefArgResult = ParseBraceInitializer();
7655 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
7656 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7657 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7666 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7671 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
7672 DefArgResult.
get());
7677 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7678 ParmDeclarator.getIdentifierLoc(),
7679 Param, std::move(DefArgToks)));
7687 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
7694 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7696 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7697 Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {
7700 SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();
7701 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7702 << ParmEllipsis.
isValid() << ParmEllipsis;
7705 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7707 Diag(ParmDeclarator.getIdentifierLoc(),
7708 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7711 << !ParmDeclarator.hasName();
7713 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7725void Parser::ParseBracketDeclarator(
Declarator &D) {
7726 if (CheckProhibitedCXX11Attribute())
7734 if (Tok.getKind() == tok::r_square) {
7736 ParsedAttributes attrs(AttrFactory);
7737 MaybeParseCXX11Attributes(attrs);
7741 T.getOpenLocation(),
7742 T.getCloseLocation()),
7743 std::move(attrs),
T.getCloseLocation());
7745 }
else if (Tok.getKind() == tok::numeric_constant &&
7752 ParsedAttributes attrs(AttrFactory);
7753 MaybeParseCXX11Attributes(attrs);
7757 T.getOpenLocation(),
7758 T.getCloseLocation()),
7759 std::move(attrs),
T.getCloseLocation());
7761 }
else if (Tok.getKind() == tok::code_completion) {
7763 Actions.CodeCompletion().CodeCompleteBracketDeclarator(
getCurScope());
7768 SourceLocation StaticLoc;
7773 DeclSpec DS(AttrFactory);
7774 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
7782 bool isStar =
false;
7793 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7794 StaticLoc = SourceLocation();
7797 }
else if (Tok.isNot(tok::r_square)) {
7814 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7815 StaticLoc = SourceLocation();
7834 isStar, NumElements.
get(),
T.getOpenLocation(),
7835 T.getCloseLocation()),
7839void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
7840 assert(Tok.is(tok::l_square) &&
"Missing opening bracket");
7843 SourceLocation StartBracketLoc = Tok.getLocation();
7847 while (Tok.is(tok::l_square)) {
7848 ParseBracketDeclarator(TempDeclarator);
7854 if (Tok.is(tok::semi))
7857 SourceLocation SuggestParenLoc = Tok.getLocation();
7860 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7865 if (TempDeclarator.getNumTypeObjects() == 0)
7869 bool NeedParens =
false;
7888 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
7894 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
7895 const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
7896 D.
AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());
7901 if (!D.
hasName() && !NeedParens)
7904 SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();
7907 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
7908 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
7911 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7916 EndLoc, CharSourceRange(BracketRange,
true))
7919 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7922 EndLoc, CharSourceRange(BracketRange,
true))
7927void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
7928 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
7929 "Not a typeof specifier");
7931 bool IsUnqual = Tok.is(tok::kw_typeof_unqual);
7932 const IdentifierInfo *II = Tok.getIdentifierInfo();
7934 Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName();
7938 bool HasParens = Tok.is(tok::l_paren);
7946 SourceRange CastRange;
7948 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);
7964 const char *PrevSpec =
nullptr;
7971 Actions.getASTContext().getPrintingPolicy()))
7972 Diag(StartLoc, DiagID) << PrevSpec;
7983 Operand = Actions.HandleExprEvaluationContextForTypeof(
Operand.get());
7989 const char *PrevSpec =
nullptr;
7996 Actions.getASTContext().getPrintingPolicy()))
7997 Diag(StartLoc, DiagID) << PrevSpec;
8000void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
8001 assert(Tok.is(tok::kw__Atomic) &&
NextToken().
is(tok::l_paren) &&
8002 "Not an atomic specifier");
8006 if (
T.consumeOpen())
8010 if (
Result.isInvalid()) {
8018 if (
T.getCloseLocation().isInvalid())
8024 const char *PrevSpec =
nullptr;
8028 Actions.getASTContext().getPrintingPolicy()))
8029 Diag(StartLoc, DiagID) << PrevSpec;
8032bool Parser::TryAltiVecVectorTokenOutOfLine() {
8034 switch (
Next.getKind()) {
8035 default:
return false;
8038 case tok::kw_signed:
8039 case tok::kw_unsigned:
8044 case tok::kw_double:
8047 case tok::kw___bool:
8048 case tok::kw___pixel:
8049 Tok.setKind(tok::kw___vector);
8051 case tok::identifier:
8052 if (
Next.getIdentifierInfo() == Ident_pixel) {
8053 Tok.setKind(tok::kw___vector);
8056 if (
Next.getIdentifierInfo() == Ident_bool ||
8057 Next.getIdentifierInfo() == Ident_Bool) {
8058 Tok.setKind(tok::kw___vector);
8066 const char *&PrevSpec,
unsigned &DiagID,
8068 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
8069 if (Tok.getIdentifierInfo() == Ident_vector) {
8071 switch (
Next.getKind()) {
8074 case tok::kw_signed:
8075 case tok::kw_unsigned:
8080 case tok::kw_double:
8083 case tok::kw___bool:
8084 case tok::kw___pixel:
8087 case tok::identifier:
8088 if (
Next.getIdentifierInfo() == Ident_pixel) {
8092 if (
Next.getIdentifierInfo() == Ident_bool ||
8093 Next.getIdentifierInfo() == Ident_Bool) {
8102 }
else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
8106 }
else if ((Tok.getIdentifierInfo() == Ident_bool) &&
8114TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8117 SmallVector<Token, 4> Tokens;
8120 auto &SourceMgr = PP.getSourceManager();
8121 FileID FID = SourceMgr.createFileID(
8122 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8126 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8127 L.setParsingPreprocessorDirective(
true);
8133 Tokens.push_back(Tok);
8134 }
while (Tok.isNot(tok::eod));
8139 Token &EndToken = Tokens.back();
8146 Tokens.push_back(Tok);
8149 PP.EnterTokenStream(Tokens,
false,
8164 (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {
8165 Diag(Tok.getLocation(), diag::err_type_unparsed);
8170 while (Tok.isNot(tok::eof))
8174 if (Tok.is(tok::eof) && Tok.getEofData() == TypeStr.data())
8179void Parser::DiagnoseBitIntUse(
const Token &
Tok) {
8183 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8184 "expected either an _ExtInt or _BitInt token!");
8186 SourceLocation Loc = Tok.getLocation();
8187 if (Tok.is(tok::kw__ExtInt)) {
8188 Diag(Loc, diag::warn_ext_int_deprecated)
8194 Diag(Loc, diag::warn_c23_compat_keyword) << Tok.getName();
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
static StringRef normalizeAttrName(StringRef AttrName, StringRef NormalizedScopeName, AttributeCommonInfo::Syntax SyntaxUsed)
static Decl::Kind getKind(const Decl *D)
Defines the C++ template declaration subclasses.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::RecordLoc RecordLoc
static bool IsAttributeLateParsedExperimentalExt(const IdentifierInfo &II)
returns true iff attribute is annotated with LateAttrParseExperimentalExt in Attr....
static bool FindLocsWithCommonFileID(Preprocessor &PP, SourceLocation StartLoc, SourceLocation EndLoc)
Check if the a start and end source location expand to the same macro.
static bool IsAttributeLateParsedStandard(const IdentifierInfo &II)
returns true iff attribute is annotated with LateAttrParseStandard in Attr.td.
static ParsedAttributeArgumentsProperties attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has string arguments.
static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute takes a strict identifier argument.
static bool attributeIsTypeArgAttr(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute parses a type argument.
static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute treats kw_this as an identifier.
static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute requires parsing its arguments in an unevaluated context or not...
static bool attributeHasIdentifierArg(const llvm::Triple &T, const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has an identifier argument.
static bool isValidAfterIdentifierInDeclarator(const Token &T)
isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the specified token is valid after t...
static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has a variadic identifier argument.
static bool isPipeDeclarator(const Declarator &D)
static SourceLocation getMissingDeclaratorIdLoc(Declarator &D, SourceLocation Loc)
static bool attributeAcceptsExprPack(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine if an attribute accepts parameter packs.
static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS, Parser &P)
static bool VersionNumberSeparator(const char Separator)
static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, DeclaratorContext TheContext)
llvm::SmallVector< std::pair< const MemRegion *, SVal >, 4 > Bindings
static constexpr bool isOneOf()
This file declares semantic analysis for CUDA constructs.
This file declares facilities that support code completion.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenMP constructs and clauses.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the clang::TokenKind enum and support functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Syntax
The style used to specify an attribute.
@ AS_Declspec
__declspec(...)
Kind getParsedKind() const
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
SourceLocation getOpenLocation() const
SourceLocation getCloseLocation() const
Represents a C++ nested-name-specifier or a global scope specifier.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
SourceLocation getEndLoc() const
bool isSet() const
Deprecated.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
void setTemplateParamLists(ArrayRef< TemplateParameterList * > L)
bool isEmpty() const
No scope specifier.
SourceLocation getBegin() const
Callback handler that receives notifications when performing code completion within the preprocessor.
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Captures information about "declaration specifiers".
bool isVirtualSpecified() const
bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, ExplicitSpecifier ExplicitSpec, SourceLocation CloseParenLoc)
bool isTypeSpecPipe() const
static const TSCS TSCS___thread
static const TST TST_typeof_unqualType
void setTypeArgumentRange(SourceRange range)
bool SetTypePipe(bool isPipe, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
SourceLocation getPipeLoc() const
static const TST TST_typename
SourceLocation getEndLoc() const LLVM_READONLY
bool hasTypeSpecifier() const
Return true if any type-specifier has been found.
bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec and return false if there was no error.
static const TST TST_char8
static const TST TST_BFloat16
void ClearStorageClassSpecs()
bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TSCS TSCS__Thread_local
bool SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec, but return true and ignore the request if ...
bool isNoreturnSpecified() const
TST getTypeSpecType() const
SourceLocation getStorageClassSpecLoc() const
SCS getStorageClassSpec() const
bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceRange getSourceRange() const LLVM_READONLY
bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void SetRangeEnd(SourceLocation Loc)
bool SetBitIntType(SourceLocation KWLoc, Expr *BitWidth, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_auto_type
static const TST TST_interface
static const TST TST_double
static const TST TST_typeofExpr
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
void SetRangeStart(SourceLocation Loc)
bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getNoreturnSpecLoc() const
static const TST TST_union
static const TST TST_char
static const TST TST_bool
static const TST TST_char16
SourceLocation getExplicitSpecLoc() const
SourceLocation getFriendSpecLoc() const
SourceLocation getModulePrivateSpecLoc() const
bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void UpdateTypeRep(ParsedType Rep)
TSCS getThreadStorageClassSpec() const
bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasAttributes() const
static const TST TST_accum
static const TST TST_half
ParsedAttributes & getAttributes()
SourceLocation getConstSpecLoc() const
static const TST TST_ibm128
void addAttributes(const ParsedAttributesView &AL)
Concatenates two attribute lists.
static const TST TST_enum
bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_float128
void takeAttributesAppendingingFrom(ParsedAttributes &attrs)
void Finish(Sema &S, const PrintingPolicy &Policy)
Finish - This does final analysis of the declspec, issuing diagnostics for things like "_Complex" (la...
bool isInlineSpecified() const
SourceLocation getRestrictSpecLoc() const
static const TST TST_typeof_unqualExpr
static const TST TST_class
bool hasTagDefinition() const
static const TST TST_decimal64
unsigned getParsedSpecifiers() const
Return a bitmask of which flavors of specifiers this DeclSpec includes.
void ClearFunctionSpecs()
bool SetTypeQual(TQ T, SourceLocation Loc)
static const TST TST_wchar
static const TST TST_void
bool isTypeAltiVecVector() const
void ClearConstexprSpec()
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
static const TST TST_float
static const TST TST_atomic
static const TST TST_fract
SourceLocation getThreadStorageClassSpecLoc() const
Decl * getRepAsDecl() const
static const TST TST_float16
static const TST TST_unspecified
SourceLocation getAtomicSpecLoc() const
SourceLocation getVirtualSpecLoc() const
SourceLocation getConstexprSpecLoc() const
CXXScopeSpec & getTypeSpecScope()
bool isEmpty() const
isEmpty - Return true if this declaration specifier is completely empty: no tokens were parsed in the...
SourceLocation getTypeSpecTypeLoc() const
static const TSCS TSCS_thread_local
bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal32
bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
TypeSpecifierWidth getTypeSpecWidth() const
static const TST TST_char32
bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal128
bool isTypeSpecOwned() const
SourceLocation getInlineSpecLoc() const
SourceLocation getUnalignedSpecLoc() const
static const TST TST_int128
SourceLocation getVolatileSpecLoc() const
FriendSpecified isFriendSpecified() const
bool hasExplicitSpecifier() const
bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasConstexprSpecifier() const
static const TST TST_typeofType
bool SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_auto
@ PQ_StorageClassSpecifier
ConstexprSpecKind getConstexprSpecifier() const
static const TST TST_struct
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
Information about one declarator, including the parsed type information and the identifier.
bool isFunctionDeclarator(unsigned &idx) const
isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...
bool isPastIdentifier() const
isPastIdentifier - Return true if we have parsed beyond the point where the name would appear.
void SetRangeBegin(SourceLocation Loc)
SetRangeBegin - Set the start of the source range to Loc, unless it's invalid.
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
void setCommaLoc(SourceLocation CL)
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
SourceLocation getIdentifierLoc() const
void SetIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
bool mayOmitIdentifier() const
mayOmitIdentifier - Return true if the identifier is either optional or not allowed.
SourceLocation getEndLoc() const LLVM_READONLY
bool mayBeFollowedByCXXDirectInit() const
mayBeFollowedByCXXDirectInit - Return true if the declarator can be followed by a C++ direct initiali...
bool hasGroupingParens() const
void setDecompositionBindings(SourceLocation LSquareLoc, MutableArrayRef< DecompositionDeclarator::Binding > Bindings, SourceLocation RSquareLoc)
Set the decomposition bindings for this declarator.
void setInvalidType(bool Val=true)
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
bool mayHaveIdentifier() const
mayHaveIdentifier - Return true if the identifier is either optional or required.
void setGroupingParens(bool flag)
SourceLocation getEllipsisLoc() const
DeclaratorContext getContext() const
SourceLocation getBeginLoc() const LLVM_READONLY
void setTrailingRequiresClause(Expr *TRC)
Sets a trailing requires clause for this declarator.
void setHasInitializer(bool Val=true)
UnqualifiedId & getName()
Retrieve the name specified by this declarator.
void setTemplateParameterLists(ArrayRef< TemplateParameterList * > TPLs)
Sets the template parameter lists that preceded the declarator.
bool isFirstDeclarator() const
bool hasTrailingRequiresClause() const
Determine whether a trailing requires clause was written in this declarator.
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
The template parameter lists that preceded the declarator.
bool isFunctionDeclaratorAFunctionDeclaration() const
Return true if a function declarator at this position would be a function declaration.
void clear()
Reset the contents of this Declarator.
void setAsmLabel(Expr *E)
void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &&attrs, SourceLocation EndLoc)
AddTypeInfo - Add a chunk to this declarator.
void ExtendWithDeclSpec(const DeclSpec &DS)
ExtendWithDeclSpec - Extend the declarator source range to include the given declspec,...
void SetRangeEnd(SourceLocation Loc)
SetRangeEnd - Set the end of the source range to Loc, unless it's invalid.
void setExtension(bool Val=true)
bool isInvalidType() const
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
void setEllipsisLoc(SourceLocation EL)
const IdentifierInfo * getIdentifier() const
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code from FromRange at a specific location.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
SourceLocation getLoc() const
void setIdentifierInfo(IdentifierInfo *Ident)
IdentifierInfo * getIdentifierInfo() const
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool requiresStrictPrototypes() const
Returns true if functions without prototypes or functions with an identifier list (aka K&R C function...
std::string getOpenCLVersionString() const
Return the OpenCL C or C++ for OpenCL language name and version as a string.
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static bool isAtStartOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroBegin=nullptr)
Returns true if the given MacroID location points at the first token of the macro expansion.
static bool isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroEnd=nullptr)
Returns true if the given MacroID location points at the last token of the macro expansion.
static std::optional< Token > findNextToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeComments=false)
Finds the token that comes right after the given location.
static bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, const LangOptions &LangOpts, bool IgnoreWhiteSpace=false)
Relex the token at the specified location.
UnresolvedSetImpl::iterator iterator
static constexpr unsigned getMaxFunctionScopeDepth()
ParsedAttr - Represents a syntactic attribute.
unsigned getMaxArgs() const
static const ParsedAttributesView & none()
void prepend(iterator B, iterator E)
void addAtEnd(ParsedAttr *newAttr)
void remove(ParsedAttr *ToBeRemoved)
ParsedAttributes - A collection of parsed attributes.
void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA)
ParsedAttr * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Form formUsed)
Add microsoft __delspec(property) attribute.
ParsedAttr * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ParsedType typeArg, ParsedAttr::Form formUsed, SourceLocation ellipsisLoc=SourceLocation())
Add an attribute with a single type argument.
ParsedAttr * addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, ParsedAttr::Form form)
Add type_tag_for_datatype attribute.
void takeAllAppendingFrom(ParsedAttributes &Other)
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation getEndOfPreviousToken() const
DiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagId)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Sema & getActions() const
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
void EnterScope(unsigned ScopeFlags)
EnterScope - Start a new scope.
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
ExprResult ParseConstantExpressionInExprEvalContext(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
SmallVector< Stmt *, 24 > StmtVector
A SmallVector of statements.
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
friend class ColonProtectionRAIIObject
DeclGroupPtrTy ParseOpenACCDirectiveDecl(AccessSpecifier &AS, ParsedAttributes &Attrs, DeclSpec::TST TagType, Decl *TagDecl)
Parse OpenACC directive on a declaration.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
const Token & GetLookAheadToken(unsigned N)
GetLookAheadToken - This peeks ahead N tokens and returns that token without consuming any tokens.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Scope * getCurScope() const
ExprResult ParseArrayBoundExpression()
const TargetInfo & getTargetInfo() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
void SkipMalformedDecl()
SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...
void ExitScope()
ExitScope - Pop a scope off the scope stack.
const LangOptions & getLangOpts() const
friend class ParenBraceBracketBalancer
ExprResult ParseExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Simple precedence-based parser for binary/ternary operators.
@ StopBeforeMatch
Stop skipping at specified token, but don't skip the token itself.
@ StopAtCodeCompletion
Stop at code completion.
@ StopAtSemi
Stop skipping at semicolon.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
ExprResult ParseUnevaluatedStringLiteralExpression()
ObjCContainerDecl * getObjCDeclContext() const
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
friend class BalancedDelimiterTracker
SmallVector< TemplateParameterList *, 4 > TemplateParameterLists
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
A class for parsing a DeclSpec.
A class for parsing a declarator.
A class for parsing a field declarator.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
SourceManager & getSourceManager() const
const LangOptions & getLangOpts() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
void addAddressSpace(LangAS space)
static Qualifiers fromCVRUMask(unsigned CVRU)
Represents a struct/union/class.
field_range fields() const
bool isClassScope() const
isClassScope - Return true if this scope is a class/struct/union scope.
unsigned getFlags() const
getFlags - Return the flags for this scope.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ BlockScope
This is a scope that corresponds to a block/closure object.
@ FriendScope
This is a scope of friend declaration.
@ ControlScope
The controlling scope in a if/switch/while/for statement.
@ AtCatchScope
This is a scope that corresponds to the Objective-C @catch statement.
@ TemplateParamScope
This is a scope that corresponds to the template parameters of a C++ template.
@ CompoundStmtScope
This is a compound statement scope.
@ ClassScope
The scope of a struct/union/class definition.
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ EnumScope
This scope corresponds to an enum.
@ DeclScope
This is a scope that can contain a declaration.
@ CTCK_InitGlobalVar
Unknown context.
ParserCompletionContext
Describes the context in which code completion occurs.
@ PCC_LocalDeclarationSpecifiers
Code completion occurs within a sequence of declaration specifiers within a function,...
@ PCC_MemberTemplate
Code completion occurs following one or more template headers within a class.
@ PCC_Class
Code completion occurs within a class, struct, or union.
@ PCC_ObjCImplementation
Code completion occurs within an Objective-C implementation or category implementation.
@ PCC_Namespace
Code completion occurs at top-level or namespace context.
@ PCC_Template
Code completion occurs following one or more template headers.
NameClassificationKind getKind() const
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
@ PotentiallyEvaluatedIfUsed
The current expression is potentially evaluated, but any declarations referenced inside that expressi...
void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl)
ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an initializer for the declaratio...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
A RAII object used to temporarily suppress access-like checking.
Represents the declaration of a struct/union/class/enum.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
void setKind(tok::TokenKind K)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
void * getAnnotationValue() const
tok::TokenKind getKind() const
bool isOneOf(Ts... Ks) const
void setEofData(const void *D)
void setLocation(SourceLocation L)
void startToken()
Reset all flags to cleared.
void setSemiMissing(bool Missing=true)
static constexpr int FunctionTypeNumParamsLimit
SourceLocation EndLocation
The location of the last token that describes this unqualified-id.
SourceRange getSourceRange() const LLVM_READONLY
Return the source range that covers this unqualified-id.
SourceLocation StartLocation
The location of the first token that describes this unqualified-id, which will be the location of the...
UnqualifiedIdKind getKind() const
Determine what kind of name we have.
Declaration of a variable template.
static const char * getSpecifierName(Specifier VS)
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
bool InitScope(InterpState &S, CodePtr OpPC, uint32_t I)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isPragmaAnnotation(TokenKind K)
Return true if this is an annotation token representing a pragma.
The JSON file list parser is used to communicate input to InstallAPI.
TypeSpecifierType
Specifies the kind of type.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
bool isa(CodeGen::Address addr)
@ NotAttributeSpecifier
This is not an attribute specifier.
@ AttributeSpecifier
This should be treated as an attribute-specifier.
@ InvalidAttributeSpecifier
The next tokens are '[[', but this is not an attribute-specifier.
@ ExpectedParameterOrImplicitObjectParameter
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
@ IK_TemplateId
A template-id, e.g., f<int>.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
ActionResult< Decl * > DeclResult
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
llvm::SmallVector< ArgsUnion, 12U > ArgsVector
Language
The language for the input, used to select and validate the language standard and possible actions.
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
@ ExplicitSpecialization
We are parsing an explicit specialization.
@ ExplicitInstantiation
We are parsing an explicit instantiation.
@ NonTemplate
We are not parsing a template at all.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
@ FunctionTemplate
The name was classified as a function template name.
@ Keyword
The name has been typo-corrected to a keyword.
@ DependentNonType
The name denotes a member of a dependent type that could not be resolved.
@ UndeclaredTemplate
The name was classified as an ADL-only function template name.
@ NonType
The name was classified as a specific non-type, non-template declaration.
@ Unknown
This name is not a type or template in this context, but might be something else.
@ Error
Classification failed; an error has been produced.
@ Type
The name was classified as a type.
@ TypeTemplate
The name was classified as a template whose specializations are types.
@ Concept
The name was classified as a concept name.
@ OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ UndeclaredNonType
The name was classified as an ADL-only function name.
@ VarTemplate
The name was classified as a variable template name.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Dependent_template_name
The name refers to a dependent template name:
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &&Second)
Consumes the attributes from Second and concatenates them at the end of First.
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
ActionResult< Expr * > ExprResult
@ Parens
New-expression has a C++98 paren-delimited initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_None
no exception specification
ActionResult< Stmt * > StmtResult
VersionTuple Version
The version number at which the change occurred.
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
SourceRange VersionRange
The source range covering the version number.
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, ArrayRef< NamedDecl * > DeclsInPrototype, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult(), SourceLocation TrailingReturnTypeLoc=SourceLocation(), DeclSpec *MethodQualifiers=nullptr)
DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
static DeclaratorChunk getPipe(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc)
Return a DeclaratorChunk for an array.
SourceLocation Loc
Loc - The place where this type was defined.
static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, unsigned TypeQuals, SourceLocation StarLoc, SourceLocation EndLoc)
enum clang::DeclaratorChunk::@340323374315200305336204205154073066142310370142 Kind
static DeclaratorChunk getParen(SourceLocation LParenLoc, SourceLocation RParenLoc)
Return a DeclaratorChunk for a paren.
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, SourceLocation AtomicQualLoc, SourceLocation UnalignedQualLoc)
Return a DeclaratorChunk for a pointer.
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, bool lvalue)
Return a DeclaratorChunk for a reference.
bool isStringLiteralArg(unsigned I) const
ExpressionKind
Describes whether we are in an expression constext which we have to handle differently.
bool hasInvalidName() const
const IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
TemplateNameKind Kind
The kind of template that Template refers to.
bool hasInvalidArgs() const