34#include "llvm/ADT/SmallSet.h"
35#include "llvm/ADT/StringSwitch.h"
47 DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
48 if (DSC == DeclSpecContext::DSC_normal)
49 DSC = DeclSpecContext::DSC_type_specifier;
55 ParseSpecifierQualifierList(DS, AS, DSC);
63 if (AL.isDeclspecAttribute())
64 ToBeMoved.push_back(&AL);
73 ParseDeclarator(DeclaratorInfo);
80 return Actions.ActOnTypeName(DeclaratorInfo);
85 if (Name.size() >= 4 && Name.starts_with(
"__") && Name.ends_with(
"__"))
86 return Name.drop_front(2).drop_back(2);
93#define CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
95#include "clang/Parse/AttrParserStringSwitches.inc"
97#undef CLANG_ATTR_LATE_PARSED_EXPERIMENTAL_EXT_LIST
103#define CLANG_ATTR_LATE_PARSED_LIST
105#include "clang/Parse/AttrParserStringSwitches.inc"
107#undef CLANG_ATTR_LATE_PARSED_LIST
117 if (
SM.getFileID(StartLoc) !=
SM.getFileID(EndLoc))
120 bool AttrStartIsInMacro =
122 bool AttrEndIsInMacro =
124 return AttrStartIsInMacro && AttrEndIsInMacro;
127void Parser::ParseAttributes(
unsigned WhichAttrKinds,
ParsedAttributes &Attrs,
128 LateParsedAttrList *LateAttrs) {
134 if (WhichAttrKinds & PAKM_CXX11)
135 MoreToParse |= MaybeParseCXX11Attributes(Attrs);
136 if (WhichAttrKinds & PAKM_GNU)
137 MoreToParse |= MaybeParseGNUAttributes(Attrs, LateAttrs);
138 if (WhichAttrKinds & PAKM_Declspec)
139 MoreToParse |= MaybeParseMicrosoftDeclSpecs(Attrs);
140 }
while (MoreToParse);
145 LateParsedAttrList *LateAttrs,
147 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
153 if (Tok.isNot(tok::l_paren)) {
154 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
155 ParsedAttr::Form::GNU());
159 bool LateParse =
false;
162 else if (LateAttrs->lateAttrParseExperimentalExtOnly()) {
166 LateParse =
getLangOpts().ExperimentalLateParseAttributes &&
179 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, &EndLoc,
nullptr,
180 SourceLocation(), ParsedAttr::Form::GNU(), D);
185 LateParsedAttribute *LA =
186 new LateParsedAttribute(
this, *AttrName, AttrNameLoc);
187 LateAttrs->push_back(LA);
191 if (!ClassStack.empty() && !LateAttrs->parseSoon())
192 getCurrentClass().LateParsedDeclarations.push_back(LA);
196 LA->Toks.push_back(Tok);
199 ConsumeAndStoreUntil(tok::r_paren, LA->Toks,
true);
204 LA->Toks.push_back(Eof);
210 LateParsedAttrList *LateAttrs,
Declarator *D) {
211 assert(Tok.is(tok::kw___attribute) &&
"Not a GNU attribute list!");
213 SourceLocation StartLoc = Tok.getLocation();
214 SourceLocation EndLoc = StartLoc;
216 while (Tok.is(tok::kw___attribute)) {
218 unsigned OldNumAttrs = Attrs.
size();
219 unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
221 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
226 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
"(")) {
237 if (Tok.isAnnotation())
239 if (Tok.is(tok::code_completion)) {
241 Actions.CodeCompletion().CodeCompleteAttribute(
246 if (ParseSingleGNUAttribute(Attrs, EndLoc, LateAttrs, D))
248 }
while (Tok.is(tok::comma));
250 if (ExpectAndConsume(tok::r_paren))
252 SourceLocation Loc = Tok.getLocation();
253 if (ExpectAndConsume(tok::r_paren))
259 auto &
SM = PP.getSourceManager();
260 if (!
SM.isWrittenInBuiltinFile(
SM.getSpellingLoc(AttrTokLoc)) &&
262 CharSourceRange ExpansionRange =
SM.getExpansionRange(AttrTokLoc);
263 StringRef FoundName =
265 IdentifierInfo *MacroII = PP.getIdentifierInfo(FoundName);
267 for (
unsigned i = OldNumAttrs; i < Attrs.
size(); ++i)
268 Attrs[i].setMacroIdentifier(MacroII, ExpansionRange.
getBegin());
271 for (
unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
272 (*LateAttrs)[i]->MacroII = MacroII;
277 Attrs.
Range = SourceRange(StartLoc, EndLoc);
285#define CLANG_ATTR_IDENTIFIER_ARG_LIST
287#include "clang/Parse/AttrParserStringSwitches.inc"
289#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
297#define CLANG_ATTR_STRING_LITERAL_ARG_LIST
299#include "clang/Parse/AttrParserStringSwitches.inc"
301#undef CLANG_ATTR_STRING_LITERAL_ARG_LIST
308#define CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
310#include "clang/Parse/AttrParserStringSwitches.inc"
312#undef CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST
319#define CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
321#include "clang/Parse/AttrParserStringSwitches.inc"
323#undef CLANG_ATTR_THIS_ISA_IDENTIFIER_ARG_LIST
330#define CLANG_ATTR_ACCEPTS_EXPR_PACK
332#include "clang/Parse/AttrParserStringSwitches.inc"
334#undef CLANG_ATTR_ACCEPTS_EXPR_PACK
341#define CLANG_ATTR_TYPE_ARG_LIST
343#include "clang/Parse/AttrParserStringSwitches.inc"
345#undef CLANG_ATTR_TYPE_ARG_LIST
352#define CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
354#include "clang/Parse/AttrParserStringSwitches.inc"
356#undef CLANG_ATTR_STRICT_IDENTIFIER_ARG_LIST
364#define CLANG_ATTR_ARG_CONTEXT_LIST
366#include "clang/Parse/AttrParserStringSwitches.inc"
368#undef CLANG_ATTR_ARG_CONTEXT_LIST
372 assert(Tok.is(tok::identifier) &&
"expected an identifier");
373 IdentifierLoc *IL =
new (Actions.Context)
374 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
389 if (Tok.isNot(tok::r_paren))
392 if (
Parens.consumeClose())
400 &AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
401 AttributeScopeInfo(ScopeName, ScopeLoc), T.
get(), Form);
403 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
404 AttributeScopeInfo(ScopeName, ScopeLoc),
nullptr, 0, Form);
408Parser::ParseUnevaluatedStringInAttribute(
const IdentifierInfo &AttrName) {
409 if (Tok.is(tok::l_paren)) {
412 ExprResult Res = ParseUnevaluatedStringInAttribute(AttrName);
413 Paren.consumeClose();
416 if (!isTokenStringLiteral()) {
417 Diag(Tok.getLocation(), diag::err_expected_string_literal)
424bool Parser::ParseAttributeArgumentList(
427 bool SawError =
false;
431 Expr = ParseUnevaluatedStringInAttribute(AttrName);
433 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
434 Expr = ParseBraceInitializer();
439 if (Tok.is(tok::ellipsis))
441 else if (Tok.is(tok::code_completion)) {
457 if (Actions.DiagnoseUnexpandedParameterPack(Expr.
get())) {
462 Exprs.push_back(Expr.
get());
464 if (Tok.isNot(tok::comma))
469 checkPotentialAngleBracketDelimiter(Comma);
476unsigned Parser::ParseAttributeArgsCommon(
485 bool AttributeIsTypeArgAttr =
487 bool AttributeHasVariadicIdentifierArg =
491 if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
492 Tok.setKind(tok::identifier);
495 if (Tok.is(tok::identifier)) {
497 bool IsIdentifierArg =
498 AttributeHasVariadicIdentifierArg ||
509 IsIdentifierArg =
Next.isOneOf(tok::r_paren, tok::comma);
513 ArgExprs.push_back(ParseIdentifierLoc());
517 if (!ArgExprs.empty() ? Tok.is(tok::comma) : Tok.isNot(tok::r_paren)) {
519 if (!ArgExprs.empty())
522 if (AttributeIsTypeArgAttr) {
530 TheParsedType = T.
get();
531 }
else if (AttributeHasVariadicIdentifierArg ||
541 if (ChangeKWThisToIdent && Tok.is(tok::kw_this))
542 Tok.setKind(tok::identifier);
545 if (Tok.is(tok::identifier)) {
546 ArgExprs.push_back(ParseIdentifierLoc());
562 ArgExprs.push_back(ArgExpr.
get());
578 ExprVector ParsedExprs;
579 ParsedAttributeArgumentsProperties ArgProperties =
582 if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties,
589 for (
size_t I = 0; I < ParsedExprs.size(); ++I) {
594 Diag(Tok.getLocation(),
595 diag::err_attribute_argument_parm_pack_not_supported)
602 llvm::append_range(ArgExprs, ParsedExprs);
606 SourceLocation RParen = Tok.getLocation();
607 if (!ExpectAndConsume(tok::r_paren)) {
608 SourceLocation AttrLoc = ScopeLoc.
isValid() ? ScopeLoc : AttrNameLoc;
610 if (AttributeIsTypeArgAttr && !TheParsedType.
get().
isNull()) {
612 AttributeScopeInfo(ScopeName, ScopeLoc),
613 TheParsedType, Form);
615 Attrs.
addNew(AttrName, SourceRange(AttrLoc, RParen),
616 AttributeScopeInfo(ScopeName, ScopeLoc), ArgExprs.data(),
617 ArgExprs.size(), Form);
624 return static_cast<unsigned>(ArgExprs.size() + !TheParsedType.
get().
isNull());
627void Parser::ParseGNUAttributeArgs(
632 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
637 if (AttrKind == ParsedAttr::AT_Availability) {
638 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
641 }
else if (AttrKind == ParsedAttr::AT_ExternalSourceSymbol) {
642 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
643 ScopeName, ScopeLoc, Form);
645 }
else if (AttrKind == ParsedAttr::AT_ObjCBridgeRelated) {
646 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
647 ScopeName, ScopeLoc, Form);
649 }
else if (AttrKind == ParsedAttr::AT_SwiftNewType) {
650 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
653 }
else if (AttrKind == ParsedAttr::AT_TypeTagForDatatype) {
654 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
655 ScopeName, ScopeLoc, Form);
658 ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, ScopeName,
661 }
else if (AttrKind == ParsedAttr::AT_CountedBy ||
662 AttrKind == ParsedAttr::AT_CountedByOrNull ||
663 AttrKind == ParsedAttr::AT_SizedBy ||
664 AttrKind == ParsedAttr::AT_SizedByOrNull) {
665 ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
668 }
else if (AttrKind == ParsedAttr::AT_CXXAssume) {
669 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
670 ScopeLoc, EndLoc, Form);
676 std::optional<ParseScope> PrototypeScope;
683 for (
unsigned i = 0; i != FTI.
NumParams; ++i)
684 Actions.ActOnReenterCXXMethodParameter(
688 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
692unsigned Parser::ParseClangAttributeArgs(
696 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
703 return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
704 ScopeName, ScopeLoc, Form);
705 case ParsedAttr::AT_ExternalSourceSymbol:
706 ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
707 ScopeName, ScopeLoc, Form);
709 case ParsedAttr::AT_Availability:
710 ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
713 case ParsedAttr::AT_ObjCBridgeRelated:
714 ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
715 ScopeName, ScopeLoc, Form);
717 case ParsedAttr::AT_SwiftNewType:
718 ParseSwiftNewTypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
721 case ParsedAttr::AT_TypeTagForDatatype:
722 ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
723 ScopeName, ScopeLoc, Form);
726 case ParsedAttr::AT_CXXAssume:
727 ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, ScopeName,
728 ScopeLoc, EndLoc, Form);
731 return !Attrs.
empty() ? Attrs.
begin()->getNumArgs() : 0;
737 unsigned ExistingAttrs = Attrs.
size();
749 SourceLocation OpenParenLoc = Tok.getLocation();
751 if (
AttrName->getName() ==
"property") {
757 T.expectAndConsume(diag::err_expected_lparen_after,
758 AttrName->getNameStart(), tok::r_paren);
765 IdentifierInfo *AccessorNames[] = {
nullptr,
nullptr};
766 bool HasInvalidAccessor =
false;
771 if (!Tok.is(tok::identifier)) {
773 if (Tok.is(tok::r_paren) && !HasInvalidAccessor &&
774 AccessorNames[AK_Put] ==
nullptr &&
775 AccessorNames[AK_Get] ==
nullptr) {
776 Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
780 Diag(Tok.getLocation(), diag::err_ms_property_unknown_accessor);
785 SourceLocation KindLoc = Tok.getLocation();
786 StringRef KindStr = Tok.getIdentifierInfo()->getName();
787 if (KindStr ==
"get") {
789 }
else if (KindStr ==
"put") {
793 }
else if (KindStr ==
"set") {
794 Diag(KindLoc, diag::err_ms_property_has_set_accessor)
801 Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
803 HasInvalidAccessor =
true;
804 goto next_property_accessor;
808 Diag(KindLoc, diag::err_ms_property_unknown_accessor);
809 HasInvalidAccessor =
true;
822 Diag(Tok.getLocation(), diag::err_ms_property_expected_equal)
828 if (!Tok.is(tok::identifier)) {
829 Diag(Tok.getLocation(), diag::err_ms_property_expected_accessor_name);
833 if (Kind == AK_Invalid) {
835 }
else if (AccessorNames[Kind] !=
nullptr) {
837 Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
839 AccessorNames[
Kind] = Tok.getIdentifierInfo();
843 next_property_accessor:
849 if (Tok.is(tok::r_paren))
852 Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen);
857 if (!HasInvalidAccessor)
859 AccessorNames[AK_Get], AccessorNames[AK_Put],
860 ParsedAttr::Form::Declspec());
862 return !HasInvalidAccessor;
866 ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs,
nullptr,
nullptr,
867 SourceLocation(), ParsedAttr::Form::Declspec());
872 Diag(OpenParenLoc, diag::err_attribute_requires_arguments) <<
AttrName;
879 assert(
getLangOpts().DeclSpecKeyword &&
"__declspec keyword is not enabled");
880 assert(Tok.is(tok::kw___declspec) &&
"Not a declspec!");
882 SourceLocation StartLoc = Tok.getLocation();
883 SourceLocation EndLoc = StartLoc;
885 while (Tok.is(tok::kw___declspec)) {
888 if (T.expectAndConsume(diag::err_expected_lparen_after,
"__declspec",
894 while (Tok.isNot(tok::r_paren)) {
899 if (Tok.is(tok::code_completion)) {
901 Actions.CodeCompletion().CodeCompleteAttribute(
908 bool IsString = Tok.getKind() == tok::string_literal;
909 if (!IsString && Tok.getKind() != tok::identifier &&
910 Tok.getKind() != tok::kw_restrict) {
911 Diag(Tok, diag::err_ms_declspec_type);
917 SourceLocation AttrNameLoc;
919 SmallString<8> StrBuffer;
920 bool Invalid =
false;
921 StringRef Str = PP.getSpelling(Tok, StrBuffer, &Invalid);
926 AttrName = PP.getIdentifierInfo(Str);
927 AttrNameLoc = ConsumeStringToken();
933 bool AttrHandled =
false;
936 if (Tok.is(tok::l_paren))
937 AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
938 else if (
AttrName->getName() ==
"property")
940 Diag(Tok.getLocation(), diag::err_expected_lparen_after)
944 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
945 ParsedAttr::Form::Declspec());
948 EndLoc = T.getCloseLocation();
951 Attrs.
Range = SourceRange(StartLoc, EndLoc);
957 auto Kind = Tok.getKind();
959 case tok::kw___fastcall:
960 case tok::kw___stdcall:
961 case tok::kw___thiscall:
962 case tok::kw___regcall:
963 case tok::kw___cdecl:
964 case tok::kw___vectorcall:
965 case tok::kw___ptr64:
967 case tok::kw___ptr32:
969 case tok::kw___uptr: {
970 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
972 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
983 assert(Tok.is(tok::kw___funcref));
984 SourceLocation StartLoc = Tok.getLocation();
987 Diag(StartLoc, diag::err_wasm_funcref_not_wasm);
991 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
993 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr,
994 0, tok::kw___funcref);
997void Parser::DiagnoseAndSkipExtendedMicrosoftTypeAttributes() {
998 SourceLocation StartLoc = Tok.getLocation();
999 SourceLocation EndLoc = SkipExtendedMicrosoftTypeAttributes();
1002 SourceRange
Range(StartLoc, EndLoc);
1003 Diag(StartLoc, diag::warn_microsoft_qualifiers_ignored) <<
Range;
1008 SourceLocation EndLoc;
1011 switch (Tok.getKind()) {
1013 case tok::kw_volatile:
1014 case tok::kw___fastcall:
1015 case tok::kw___stdcall:
1016 case tok::kw___thiscall:
1017 case tok::kw___cdecl:
1018 case tok::kw___vectorcall:
1019 case tok::kw___ptr32:
1020 case tok::kw___ptr64:
1022 case tok::kw___unaligned:
1023 case tok::kw___sptr:
1024 case tok::kw___uptr:
1035 while (Tok.is(tok::kw___pascal)) {
1036 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1038 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1045 while (Tok.is(tok::kw___kernel)) {
1046 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1048 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1054 while (Tok.is(tok::kw___noinline__)) {
1055 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1057 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1058 tok::kw___noinline__);
1063 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1064 SourceLocation AttrNameLoc = Tok.getLocation();
1065 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1069bool Parser::isHLSLQualifier(
const Token &
Tok)
const {
1070 return Tok.is(tok::kw_groupshared);
1074 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1075 auto Kind = Tok.getKind();
1077 Attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0, Kind);
1083 auto Kind = Tok.getKind();
1085 case tok::kw__Nonnull:
1086 case tok::kw__Nullable:
1087 case tok::kw__Nullable_result:
1088 case tok::kw__Null_unspecified: {
1089 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
1092 Diag(AttrNameLoc, diag::ext_nullability)
1094 attrs.
addNew(AttrName, AttrNameLoc, AttributeScopeInfo(),
nullptr, 0,
1105 return (Separator ==
'.' || Separator ==
'_');
1108VersionTuple Parser::ParseVersionTuple(
SourceRange &Range) {
1109 Range = SourceRange(Tok.getLocation(), Tok.getEndLoc());
1111 if (!Tok.is(tok::numeric_constant)) {
1112 Diag(Tok, diag::err_expected_version);
1115 return VersionTuple();
1122 SmallString<512> Buffer;
1123 Buffer.resize(Tok.getLength()+1);
1124 const char *ThisTokBegin = &Buffer[0];
1127 bool Invalid =
false;
1128 unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin, &Invalid);
1130 return VersionTuple();
1133 unsigned AfterMajor = 0;
1135 while (AfterMajor < ActualLength &&
isDigit(ThisTokBegin[AfterMajor])) {
1136 Major = Major * 10 + ThisTokBegin[AfterMajor] -
'0';
1140 if (AfterMajor == 0) {
1141 Diag(Tok, diag::err_expected_version);
1144 return VersionTuple();
1147 if (AfterMajor == ActualLength) {
1152 Diag(Tok, diag::err_zero_version);
1153 return VersionTuple();
1156 return VersionTuple(Major);
1159 const char AfterMajorSeparator = ThisTokBegin[AfterMajor];
1161 || (AfterMajor + 1 == ActualLength)) {
1162 Diag(Tok, diag::err_expected_version);
1165 return VersionTuple();
1169 unsigned AfterMinor = AfterMajor + 1;
1171 while (AfterMinor < ActualLength &&
isDigit(ThisTokBegin[AfterMinor])) {
1172 Minor = Minor * 10 + ThisTokBegin[AfterMinor] -
'0';
1176 if (AfterMinor == ActualLength) {
1180 if (Major == 0 && Minor == 0) {
1181 Diag(Tok, diag::err_zero_version);
1182 return VersionTuple();
1185 return VersionTuple(Major, Minor);
1188 const char AfterMinorSeparator = ThisTokBegin[AfterMinor];
1191 Diag(Tok, diag::err_expected_version);
1194 return VersionTuple();
1198 if (AfterMajorSeparator != AfterMinorSeparator)
1199 Diag(Tok, diag::warn_expected_consistent_version_separator);
1202 unsigned AfterSubminor = AfterMinor + 1;
1203 unsigned Subminor = 0;
1204 while (AfterSubminor < ActualLength &&
isDigit(ThisTokBegin[AfterSubminor])) {
1205 Subminor = Subminor * 10 + ThisTokBegin[AfterSubminor] -
'0';
1209 if (AfterSubminor != ActualLength) {
1210 Diag(Tok, diag::err_expected_version);
1213 return VersionTuple();
1216 return VersionTuple(Major, Minor, Subminor);
1219void Parser::ParseAvailabilityAttribute(
1223 enum { Introduced, Deprecated, Obsoleted,
Unknown };
1224 AvailabilityChange Changes[
Unknown];
1226 IdentifierLoc *EnvironmentLoc =
nullptr;
1230 if (T.consumeOpen()) {
1231 Diag(Tok, diag::err_expected) << tok::l_paren;
1236 if (Tok.isNot(tok::identifier)) {
1237 Diag(Tok, diag::err_availability_expected_platform);
1241 IdentifierLoc *Platform = ParseIdentifierLoc();
1244 if (Ident->getName().contains(
"xrOS") || Ident->getName().contains(
"xros"))
1245 Diag(Platform->
getLoc(), diag::warn_availability_unknown_platform)
1248 else if (Ident->getName() ==
"macosx")
1252 else if (Ident->getName() ==
"macosx_app_extension")
1256 AvailabilityAttr::canonicalizePlatformName(Ident->getName())));
1260 if (ExpectAndConsume(tok::comma)) {
1267 if (!Ident_introduced) {
1268 Ident_introduced = PP.getIdentifierInfo(
"introduced");
1269 Ident_deprecated = PP.getIdentifierInfo(
"deprecated");
1270 Ident_obsoleted = PP.getIdentifierInfo(
"obsoleted");
1271 Ident_unavailable = PP.getIdentifierInfo(
"unavailable");
1272 Ident_message = PP.getIdentifierInfo(
"message");
1273 Ident_strict = PP.getIdentifierInfo(
"strict");
1274 Ident_replacement = PP.getIdentifierInfo(
"replacement");
1275 Ident_environment = PP.getIdentifierInfo(
"environment");
1280 SourceLocation UnavailableLoc, StrictLoc;
1282 if (Tok.isNot(tok::identifier)) {
1283 Diag(Tok, diag::err_availability_expected_change);
1287 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1290 if (
Keyword == Ident_strict) {
1292 Diag(KeywordLoc, diag::err_availability_redundant)
1293 <<
Keyword << SourceRange(StrictLoc);
1295 StrictLoc = KeywordLoc;
1299 if (
Keyword == Ident_unavailable) {
1300 if (UnavailableLoc.
isValid()) {
1301 Diag(KeywordLoc, diag::err_availability_redundant)
1302 <<
Keyword << SourceRange(UnavailableLoc);
1304 UnavailableLoc = KeywordLoc;
1311 if (Changes[Deprecated].KeywordLoc.
isValid()) {
1312 Diag(KeywordLoc, diag::err_availability_redundant)
1314 << SourceRange(Changes[Deprecated].KeywordLoc);
1319 Changes[Deprecated].
Version = VersionTuple(1);
1323 if (
Keyword == Ident_environment) {
1324 if (EnvironmentLoc !=
nullptr) {
1325 Diag(KeywordLoc, diag::err_availability_redundant)
1330 if (Tok.isNot(tok::equal)) {
1331 Diag(Tok, diag::err_expected_after) <<
Keyword << tok::equal;
1337 if (!isTokenStringLiteral()) {
1338 Diag(Tok, diag::err_expected_string_literal)
1343 if (
Keyword == Ident_message) {
1351 if (
Keyword == Ident_environment) {
1352 if (Tok.isNot(tok::identifier)) {
1353 Diag(Tok, diag::err_availability_expected_environment);
1357 EnvironmentLoc = ParseIdentifierLoc();
1363 if ((
Keyword == Ident_introduced ||
Keyword == Ident_deprecated) &&
1364 Tok.is(tok::identifier)) {
1365 IdentifierInfo *NA = Tok.getIdentifierInfo();
1368 if (
Keyword == Ident_introduced)
1369 UnavailableLoc = KeywordLoc;
1374 SourceRange VersionRange;
1375 VersionTuple Version = ParseVersionTuple(VersionRange);
1377 if (Version.empty()) {
1383 if (
Keyword == Ident_introduced)
1385 else if (
Keyword == Ident_deprecated)
1387 else if (
Keyword == Ident_obsoleted)
1393 if (!Changes[Index].KeywordLoc.
isInvalid()) {
1394 Diag(KeywordLoc, diag::err_availability_redundant)
1396 << SourceRange(Changes[Index].KeywordLoc,
1397 Changes[Index].VersionRange.
getEnd());
1401 Changes[Index].
Version = Version;
1404 Diag(KeywordLoc, diag::err_availability_unknown_change)
1411 if (T.consumeClose())
1415 *endLoc = T.getCloseLocation();
1419 if (UnavailableLoc.
isValid()) {
1420 bool Complained =
false;
1421 for (
unsigned Index = Introduced; Index !=
Unknown; ++Index) {
1422 if (Changes[Index].KeywordLoc.
isValid()) {
1424 Diag(UnavailableLoc, diag::warn_availability_and_unavailable)
1425 << SourceRange(Changes[Index].KeywordLoc,
1426 Changes[Index].VersionRange.
getEnd());
1431 Changes[Index] = AvailabilityChange();
1437 attrs.
addNew(&Availability,
1438 SourceRange(AvailabilityLoc, T.getCloseLocation()),
1439 AttributeScopeInfo(ScopeName, ScopeLoc), Platform,
1440 Changes[Introduced], Changes[Deprecated], Changes[Obsoleted],
1441 UnavailableLoc, MessageExpr.
get(), Form, StrictLoc,
1442 ReplacementExpr.
get(), EnvironmentLoc);
1445void Parser::ParseExternalSourceSymbolAttribute(
1451 if (T.expectAndConsume())
1455 if (!Ident_language) {
1456 Ident_language = PP.getIdentifierInfo(
"language");
1457 Ident_defined_in = PP.getIdentifierInfo(
"defined_in");
1458 Ident_generated_declaration = PP.getIdentifierInfo(
"generated_declaration");
1459 Ident_USR = PP.getIdentifierInfo(
"USR");
1463 bool HasLanguage =
false;
1465 bool HasDefinedIn =
false;
1466 IdentifierLoc *GeneratedDeclaration =
nullptr;
1468 bool HasUSR =
false;
1472 if (Tok.isNot(tok::identifier)) {
1473 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1478 SourceLocation KeywordLoc = Tok.getLocation();
1479 IdentifierInfo *
Keyword = Tok.getIdentifierInfo();
1480 if (
Keyword == Ident_generated_declaration) {
1481 if (GeneratedDeclaration) {
1482 Diag(Tok, diag::err_external_source_symbol_duplicate_clause) <<
Keyword;
1486 GeneratedDeclaration = ParseIdentifierLoc();
1492 Diag(Tok, diag::err_external_source_symbol_expected_keyword);
1498 if (ExpectAndConsume(tok::equal, diag::err_expected_after,
1504 bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn,
1506 if (
Keyword == Ident_language)
1508 else if (
Keyword == Ident_USR)
1511 HasDefinedIn =
true;
1513 if (!isTokenStringLiteral()) {
1514 Diag(Tok, diag::err_expected_string_literal)
1519 : (
Keyword == Ident_defined_in ? 1 : 2));
1523 if (
Keyword == Ident_language) {
1525 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1531 }
else if (
Keyword == Ident_USR) {
1533 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1540 assert(
Keyword == Ident_defined_in &&
"Invalid clause keyword!");
1542 Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
1552 if (T.consumeClose())
1555 *EndLoc = T.getCloseLocation();
1559 Attrs.
addNew(&ExternalSourceSymbol, SourceRange(Loc, T.getCloseLocation()),
1560 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1564void Parser::ParseObjCBridgeRelatedAttribute(
1570 if (T.consumeOpen()) {
1571 Diag(Tok, diag::err_expected) << tok::l_paren;
1576 if (Tok.isNot(tok::identifier)) {
1577 Diag(Tok, diag::err_objcbridge_related_expected_related_class);
1581 IdentifierLoc *RelatedClass = ParseIdentifierLoc();
1582 if (ExpectAndConsume(tok::comma)) {
1591 if (Tok.is(tok::identifier)) {
1594 Diag(Tok, diag::err_objcbridge_related_selector_name);
1600 if (Tok.is(tok::colon))
1601 Diag(Tok, diag::err_objcbridge_related_selector_name);
1603 Diag(Tok, diag::err_expected) << tok::comma;
1611 if (Tok.is(tok::identifier))
1613 else if (Tok.isNot(tok::r_paren)) {
1614 Diag(Tok, diag::err_expected) << tok::r_paren;
1620 if (T.consumeClose())
1624 *EndLoc = T.getCloseLocation();
1627 Attrs.
addNew(&ObjCBridgeRelated,
1628 SourceRange(ObjCBridgeRelatedLoc, T.getCloseLocation()),
1629 AttributeScopeInfo(ScopeName, ScopeLoc), RelatedClass,
1630 ClassMethod, InstanceMethod, Form);
1633void Parser::ParseSwiftNewTypeAttribute(
1640 if (T.consumeOpen()) {
1641 Diag(Tok, diag::err_expected) << tok::l_paren;
1645 if (Tok.is(tok::r_paren)) {
1646 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
1650 if (Tok.isNot(tok::kw_struct) && Tok.isNot(tok::kw_enum)) {
1651 Diag(Tok, diag::warn_attribute_type_not_supported)
1652 << &
AttrName << Tok.getIdentifierInfo();
1653 if (!isTokenSpecial())
1659 auto *SwiftType =
new (Actions.Context)
1660 IdentifierLoc(Tok.getLocation(), Tok.getIdentifierInfo());
1664 if (T.consumeClose())
1667 *EndLoc = T.getCloseLocation();
1670 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc, T.getCloseLocation()),
1671 AttributeScopeInfo(ScopeName, ScopeLoc), Args, std::size(Args),
1675void Parser::ParseTypeTagForDatatypeAttribute(
1679 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
1684 if (Tok.isNot(tok::identifier)) {
1685 Diag(Tok, diag::err_expected) << tok::identifier;
1689 IdentifierLoc *ArgumentKind = ParseIdentifierLoc();
1691 if (ExpectAndConsume(tok::comma)) {
1696 SourceRange MatchingCTypeRange;
1703 bool LayoutCompatible =
false;
1704 bool MustBeNull =
false;
1706 if (Tok.isNot(tok::identifier)) {
1707 Diag(Tok, diag::err_expected) << tok::identifier;
1711 IdentifierInfo *Flag = Tok.getIdentifierInfo();
1712 if (Flag->
isStr(
"layout_compatible"))
1713 LayoutCompatible =
true;
1714 else if (Flag->
isStr(
"must_be_null"))
1717 Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
1724 if (!T.consumeClose()) {
1726 &AttrName, AttrNameLoc, AttributeScopeInfo(ScopeName, ScopeLoc),
1727 ArgumentKind, MatchingCType.
get(), LayoutCompatible, MustBeNull, Form);
1731 *EndLoc = T.getCloseLocation();
1734bool Parser::DiagnoseProhibitedCXX11Attribute() {
1735 assert(Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square));
1737 switch (isCXX11AttributeSpecifier(
true)) {
1743 Diag(Tok.getLocation(), diag::err_l_square_l_square_not_attribute);
1748 SourceLocation BeginLoc = ConsumeBracket();
1751 assert(Tok.is(tok::r_square) &&
"isCXX11AttributeSpecifier lied");
1752 SourceLocation EndLoc = ConsumeBracket();
1753 Diag(BeginLoc, diag::err_attributes_not_allowed)
1754 << SourceRange(BeginLoc, EndLoc);
1757 llvm_unreachable(
"All cases handled above.");
1762 assert((Tok.is(tok::l_square) &&
NextToken().
is(tok::l_square)) ||
1763 Tok.is(tok::kw_alignas) || Tok.isRegularKeywordAttribute());
1767 Tok.isRegularKeywordAttribute() ? Tok.getIdentifierInfo() :
nullptr;
1768 SourceLocation Loc = Tok.getLocation();
1769 ParseCXX11Attributes(Attrs);
1770 CharSourceRange AttrRange(SourceRange(Loc, Attrs.
Range.
getEnd()),
true);
1773 :
Diag(Loc, diag::err_attributes_not_allowed))
1778void Parser::DiagnoseProhibitedAttributes(
1781 if (CorrectLocation.
isValid()) {
1782 CharSourceRange AttrRange(Attrs.
Range,
true);
1783 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1784 ?
Diag(CorrectLocation, diag::err_keyword_misplaced) << FirstAttr
1785 :
Diag(CorrectLocation, diag::err_attributes_misplaced))
1790 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1791 ?
Diag(
Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr
1792 :
Diag(
Range.getBegin(), diag::err_attributes_not_allowed))
1798 unsigned AttrDiagID,
1799 unsigned KeywordDiagID,
1800 bool DiagnoseEmptyAttrs,
1801 bool WarnOnUnknownAttrs) {
1807 auto &
SM = PP.getSourceManager();
1811 if (FirstLSquare.
is(tok::l_square)) {
1812 std::optional<Token> SecondLSquare =
1815 if (SecondLSquare && SecondLSquare->is(tok::l_square)) {
1825 for (
const ParsedAttr &AL : Attrs) {
1826 if (AL.isRegularKeywordAttribute()) {
1827 Diag(AL.getLoc(), KeywordDiagID) << AL;
1831 if (!AL.isStandardAttributeSyntax())
1834 if (WarnOnUnknownAttrs) {
1835 Actions.DiagnoseUnknownAttribute(AL);
1839 Diag(AL.getLoc(), AttrDiagID) << AL;
1846 for (
const ParsedAttr &PA : Attrs) {
1847 if (PA.isStandardAttributeSyntax() || PA.isRegularKeywordAttribute())
1848 Diag(PA.getLoc(), diag::ext_cxx11_attr_placement)
1849 << PA << PA.isRegularKeywordAttribute() << PA.getRange();
1858 llvm::SmallVector<ParsedAttr *, 1> ToBeMoved;
1861 if ((AL.getKind() == ParsedAttr::AT_Aligned &&
1862 AL.isDeclspecAttribute()) ||
1863 AL.isMicrosoftAttribute())
1864 ToBeMoved.push_back(&AL);
1867 for (ParsedAttr *AL : ToBeMoved) {
1881 ObjCDeclContextSwitch ObjCDC(*
this);
1883 Decl *SingleDecl =
nullptr;
1884 switch (Tok.getKind()) {
1885 case tok::kw_template:
1886 case tok::kw_export:
1887 ProhibitAttributes(DeclAttrs);
1888 ProhibitAttributes(DeclSpecAttrs);
1889 return ParseDeclarationStartingWithTemplate(Context, DeclEnd, DeclAttrs);
1890 case tok::kw_inline:
1893 ProhibitAttributes(DeclAttrs);
1894 ProhibitAttributes(DeclSpecAttrs);
1896 return ParseNamespace(Context, DeclEnd, InlineLoc);
1898 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1899 true,
nullptr, DeclSpecStart);
1901 case tok::kw_cbuffer:
1902 case tok::kw_tbuffer:
1903 SingleDecl = ParseHLSLBuffer(DeclEnd, DeclAttrs);
1905 case tok::kw_namespace:
1906 ProhibitAttributes(DeclAttrs);
1907 ProhibitAttributes(DeclSpecAttrs);
1908 return ParseNamespace(Context, DeclEnd);
1909 case tok::kw_using: {
1911 return ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
1912 DeclEnd, DeclAttrs);
1914 case tok::kw_static_assert:
1915 case tok::kw__Static_assert:
1916 ProhibitAttributes(DeclAttrs);
1917 ProhibitAttributes(DeclSpecAttrs);
1918 SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
1921 return ParseSimpleDeclaration(Context, DeclEnd, DeclAttrs, DeclSpecAttrs,
1922 true,
nullptr, DeclSpecStart);
1927 return Actions.ConvertDeclToDeclGroup(SingleDecl);
1933 bool RequireSemi, ForRangeInit *FRI,
SourceLocation *DeclSpecStart) {
1935 ParsedAttributesView OriginalDeclSpecAttrs;
1936 OriginalDeclSpecAttrs.
prepend(DeclSpecAttrs.
begin(), DeclSpecAttrs.
end());
1937 OriginalDeclSpecAttrs.
Range = DeclSpecAttrs.
Range;
1940 ParsingDeclSpec DS(*
this);
1943 ParsedTemplateInfo TemplateInfo;
1944 DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
1945 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none, DSContext);
1950 DiagnoseMissingSemiAfterTagDefinition(DS,
AS_none, DSContext))
1955 if (Tok.is(tok::semi)) {
1956 ProhibitAttributes(DeclAttrs);
1957 DeclEnd = Tok.getLocation();
1959 RecordDecl *AnonRecord =
nullptr;
1960 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
1962 Actions.ActOnDefinedDeclarationSpecifier(TheDecl);
1963 DS.complete(TheDecl);
1965 Decl* decls[] = {AnonRecord, TheDecl};
1966 return Actions.BuildDeclaratorGroup(decls);
1968 return Actions.ConvertDeclToDeclGroup(TheDecl);
1972 Actions.ActOnDefinedDeclarationSpecifier(DS.
getRepAsDecl());
1977 return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd, FRI);
1981 switch (Tok.getKind()) {
1982 case tok::annot_cxxscope:
1983 case tok::annot_template_id:
1985 case tok::code_completion:
1986 case tok::coloncolon:
1988 case tok::kw___attribute:
1989 case tok::kw_operator:
2005 case tok::identifier:
2007 case tok::code_completion:
2008 case tok::coloncolon:
2011 case tok::equalequal:
2012 case tok::kw_alignas:
2014 case tok::kw___attribute:
2032 case tok::identifier:
2036 return Tok.isRegularKeywordAttribute();
2040 return Tok.isRegularKeywordAttribute();
2046 switch (Tok.getKind()) {
2052 if (Tok.isOneOf(tok::comma, tok::l_brace, tok::kw_try)) {
2076 case tok::kw_inline:
2080 if (Tok.isAtStartOfLine() &&
NextToken().
is(tok::kw_namespace) &&
2081 (!ParsingInObjCContainer || CurParsedObjCImpl))
2085 case tok::kw_extern:
2088 case tok::kw_namespace:
2092 if (Tok.isAtStartOfLine() &&
2093 (!ParsingInObjCContainer || CurParsedObjCImpl))
2099 if (
NextToken().isObjCAtKeyword(tok::objc_end) &&
2100 ParsingInObjCContainer)
2107 if (Tok.isAtStartOfLine() && ParsingInObjCContainer)
2112 case tok::annot_module_begin:
2113 case tok::annot_module_end:
2114 case tok::annot_module_include:
2115 case tok::annot_repl_input_end:
2129 ParsedTemplateInfo &TemplateInfo,
2131 ForRangeInit *FRI) {
2137 LocalAttrs.takeAllPrependingFrom(Attrs);
2139 if (TemplateInfo.TemplateParams)
2142 bool IsTemplateSpecOrInst =
2149 if (IsTemplateSpecOrInst)
2159 while (MaybeParseHLSLAnnotations(D))
2162 if (
Tok.is(tok::kw_requires))
2163 ParseTrailingRequiresClause(D);
2168 LateParsedAttrList LateParsedAttrs(
true);
2170 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2175 if (
Tok.is(tok::kw__Noreturn)) {
2177 const char *PrevSpec;
2183 MaybeParseGNUAttributes(D, &LateParsedAttrs);
2184 Fixit &=
Tok.isOneOf(tok::semi, tok::l_brace, tok::kw_try);
2186 Diag(Loc, diag::err_c11_noreturn_misplaced)
2188 << (Fixit ?
FixItHint::CreateInsertion(D.getBeginLoc(),
"_Noreturn ")
2193 if (Tok.is(tok::equal) &&
NextToken().
is(tok::code_completion)) {
2195 Actions.CodeCompletion().CodeCompleteAfterFunctionEquals(D);
2204 while (
auto Specifier = isCXX11VirtSpecifier()) {
2205 Diag(Tok, diag::err_virt_specifier_outside_class)
2213 if (!isDeclarationAfterDeclarator()) {
2219 if (isStartOfFunctionDefinition(D)) {
2229 diag::err_function_declared_typedef)
2233 Decl *TheDecl =
nullptr;
2239 Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
2240 TheDecl = ParseFunctionDefinition(D, ParsedTemplateInfo(),
2243 SourceLocation LAngleLoc =
2244 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2246 diag::err_explicit_instantiation_with_definition)
2247 << SourceRange(TemplateInfo.TemplateLoc)
2252 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2253 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
2254 LAngleLoc,
nullptr));
2256 TheDecl = ParseFunctionDefinition(
2258 ParsedTemplateInfo(&FakedParamLists,
2265 ParseFunctionDefinition(D, TemplateInfo, &LateParsedAttrs);
2268 return Actions.ConvertDeclToDeclGroup(TheDecl);
2272 Tok.is(tok::kw_namespace)) {
2282 Diag(Tok, diag::err_expected_fn_body);
2287 if (Tok.is(tok::l_brace)) {
2288 Diag(Tok, diag::err_function_definition_not_allowed);
2296 if (ParseAsmAttributesAfterDeclarator(D))
2305 if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
2306 bool IsForRangeLoop =
false;
2308 IsForRangeLoop =
true;
2309 EnterExpressionEvaluationContext ForRangeInitContext(
2317 auto &LastRecord = Actions.currentEvaluationContext();
2318 LastRecord.InLifetimeExtendingContext =
true;
2319 LastRecord.RebuildDefaultArgOrDefaultInit =
true;
2323 Actions.OpenMP().startOpenMPCXXRangeFor();
2324 if (Tok.is(tok::l_brace))
2325 FRI->RangeExpr = ParseBraceInitializer();
2332 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
2336 FRI->LifetimeExtendTemps = std::move(
2337 Actions.ExprEvalContexts.back().ForRangeLifetimeExtendTemps);
2341 if (IsForRangeLoop) {
2342 Actions.ActOnCXXForRangeDecl(ThisDecl);
2345 if (
auto *VD = dyn_cast_or_null<VarDecl>(ThisDecl))
2346 VD->setObjCForDecl(
true);
2348 Actions.FinalizeDeclaration(ThisDecl);
2349 D.complete(ThisDecl);
2350 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, ThisDecl);
2353 SmallVector<Decl *, 8> DeclsInGroup;
2355 ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo, FRI);
2356 if (LateParsedAttrs.size() > 0)
2357 ParseLexedAttributeList(LateParsedAttrs, FirstDecl,
true,
false);
2358 D.complete(FirstDecl);
2360 DeclsInGroup.push_back(FirstDecl);
2366 SourceLocation CommaLoc;
2368 if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
2372 Diag(CommaLoc, diag::err_expected_semi_declaration)
2384 Diag(CommaLoc, diag::err_multiple_template_declarators)
2385 << TemplateInfo.Kind;
2399 MaybeParseGNUAttributes(D);
2403 DiagnoseAndSkipExtendedMicrosoftTypeAttributes();
2408 MaybeParseHLSLAnnotations(D);
2415 if (Tok.is(tok::kw_requires))
2416 ParseTrailingRequiresClause(D);
2417 Decl *ThisDecl = ParseDeclarationAfterDeclarator(D, TemplateInfo);
2418 D.complete(ThisDecl);
2420 DeclsInGroup.push_back(ThisDecl);
2425 *DeclEnd = Tok.getLocation();
2427 if (ExpectSemi && ExpectAndConsumeSemi(
2429 ? diag::err_invalid_token_after_toplevel_declarator
2430 : diag::err_expected_semi_declaration)) {
2438 return Actions.FinalizeDeclaratorGroup(
getCurScope(), DS, DeclsInGroup);
2441bool Parser::ParseAsmAttributesAfterDeclarator(
Declarator &D) {
2443 if (Tok.is(tok::kw_asm)) {
2445 ExprResult AsmLabel(ParseSimpleAsm(
true, &Loc));
2446 if (AsmLabel.isInvalid()) {
2455 MaybeParseGNUAttributes(D);
2459Decl *Parser::ParseDeclarationAfterDeclarator(
2460 Declarator &D,
const ParsedTemplateInfo &TemplateInfo) {
2461 if (ParseAsmAttributesAfterDeclarator(D))
2464 return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
2467Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
2468 Declarator &D,
const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
2470 struct InitializerScopeRAII {
2476 InitializerScopeRAII(Parser &P, Declarator &D, Decl *ThisDecl)
2477 : P(P), D(D), ThisDecl(ThisDecl), Entered(
false) {
2480 if (D.getCXXScopeSpec().isSet()) {
2482 S = P.getCurScope();
2485 P.Actions.ActOnCXXEnterDeclInitializer(S, ThisDecl);
2490 ~InitializerScopeRAII() {
2506 InitKind TheInitKind;
2508 if (isTokenEqualOrEqualTypo())
2509 TheInitKind = InitKind::Equal;
2510 else if (
Tok.
is(tok::l_paren))
2511 TheInitKind = InitKind::CXXDirect;
2514 TheInitKind = InitKind::CXXBraced;
2516 TheInitKind = InitKind::Uninitialized;
2517 if (TheInitKind != InitKind::Uninitialized)
2521 Decl *ThisDecl =
nullptr;
2522 Decl *OuterDecl =
nullptr;
2523 switch (TemplateInfo.Kind) {
2525 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2530 ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(),
2531 *TemplateInfo.TemplateParams,
2533 if (
VarTemplateDecl *VT = dyn_cast_or_null<VarTemplateDecl>(ThisDecl)) {
2536 ThisDecl = VT->getTemplatedDecl();
2542 if (
Tok.
is(tok::semi)) {
2543 DeclResult ThisRes = Actions.ActOnExplicitInstantiation(
2544 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
2546 SkipUntil(tok::semi, StopBeforeMatch);
2549 ThisDecl = ThisRes.
get();
2557 Diag(
Tok, diag::err_template_defn_explicit_instantiation)
2559 ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
2562 PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
2564 diag::err_explicit_instantiation_with_definition)
2569 TemplateParameterLists FakedParamLists;
2570 FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
2572 LAngleLoc,
nullptr));
2575 Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D);
2584 switch (TheInitKind) {
2586 case InitKind::Equal: {
2589 if (
Tok.
is(tok::kw_delete)) {
2591 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2594 Diag(ConsumeToken(), diag::err_deleted_non_function);
2595 SkipDeletedFunctionBody();
2596 }
else if (
Tok.
is(tok::kw_default)) {
2598 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
2601 Diag(ConsumeToken(), diag::err_default_special_members)
2602 << getLangOpts().CPlusPlus20;
2604 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2606 if (
Tok.
is(tok::code_completion)) {
2608 Actions.CodeCompletion().CodeCompleteInitializer(getCurScope(),
2610 Actions.FinalizeDeclaration(ThisDecl);
2620 Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
2624 FRI->ColonLoc = EqualLoc;
2626 FRI->RangeExpr =
Init;
2629 if (
Init.isInvalid()) {
2631 StopTokens.push_back(tok::comma);
2634 StopTokens.push_back(tok::r_paren);
2635 SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch);
2636 Actions.ActOnInitializerError(ThisDecl);
2638 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
2643 case InitKind::CXXDirect: {
2650 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2652 auto ThisVarDecl = dyn_cast_or_null<VarDecl>(ThisDecl);
2653 auto RunSignatureHelp = [&]() {
2655 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2656 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2657 ThisDecl->
getLocation(), Exprs, T.getOpenLocation(),
2659 CalledSignatureHelp =
true;
2660 return PreferredType;
2662 auto SetPreferredType = [&] {
2663 PreferredType.enterFunctionArgument(
Tok.
getLocation(), RunSignatureHelp);
2666 llvm::function_ref<void()> ExpressionStarts;
2672 ExpressionStarts = SetPreferredType;
2675 bool SawError = ParseExpressionList(Exprs, ExpressionStarts);
2678 if (ThisVarDecl && PP.isCodeCompletionReached() && !CalledSignatureHelp) {
2679 Actions.CodeCompletion().ProduceConstructorSignatureHelp(
2680 ThisVarDecl->getType()->getCanonicalTypeInternal(),
2681 ThisDecl->
getLocation(), Exprs, T.getOpenLocation(),
2683 CalledSignatureHelp =
true;
2685 Actions.ActOnInitializerError(ThisDecl);
2686 SkipUntil(tok::r_paren, StopAtSemi);
2692 T.getCloseLocation(),
2694 Actions.AddInitializerToDecl(ThisDecl,
Initializer.get(),
2699 case InitKind::CXXBraced: {
2701 Diag(
Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
2703 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2708 if (
Init.isInvalid()) {
2709 Actions.ActOnInitializerError(ThisDecl);
2711 Actions.AddInitializerToDecl(ThisDecl,
Init.get(),
true);
2714 case InitKind::Uninitialized: {
2715 InitializerScopeRAII
InitScope(*
this, D, ThisDecl);
2716 Actions.ActOnUninitializedDecl(ThisDecl);
2721 Actions.FinalizeDeclaration(ThisDecl);
2722 return OuterDecl ? OuterDecl : ThisDecl;
2725void Parser::ParseSpecifierQualifierList(
2728 ParsedTemplateInfo TemplateInfo;
2732 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC,
nullptr,
2733 AllowImplicitTypename);
2738 Diag(Tok, diag::err_expected_type);
2741 Diag(Tok, diag::err_typename_requires_specqual);
2752 diag::err_typename_invalid_storageclass);
2796 return T.isOneOf(tok::l_square, tok::l_paren, tok::r_paren, tok::semi,
2797 tok::comma, tok::equal, tok::kw_asm, tok::l_brace,
2802 ParsedTemplateInfo &TemplateInfo,
2805 assert(Tok.is(tok::identifier) &&
"should have identifier");
2807 SourceLocation Loc = Tok.getLocation();
2827 if (!isTypeSpecifier(DSC) &&
getLangOpts().isImplicitIntAllowed() &&
2845 AnnotateScopeToken(*SS,
false);
2854 if (
ParsedType T = Actions.ActOnMSVCUnknownTypeName(
2855 *Tok.getIdentifierInfo(), Tok.getLocation(),
2856 DSC == DeclSpecContext::DSC_template_type_arg)) {
2857 const char *PrevSpec;
2860 Actions.getASTContext().getPrintingPolicy());
2873 if (SS ==
nullptr) {
2874 const char *TagName =
nullptr, *FixitTagName =
nullptr;
2877 switch (Actions.isTagName(*Tok.getIdentifierInfo(),
getCurScope())) {
2880 TagName=
"enum" ; FixitTagName =
"enum " ; TagKind=tok::kw_enum ;
break;
2882 TagName=
"union" ; FixitTagName =
"union " ;TagKind=tok::kw_union ;
break;
2884 TagName=
"struct"; FixitTagName =
"struct ";TagKind=tok::kw_struct;
break;
2886 TagName=
"__interface"; FixitTagName =
"__interface ";
2887 TagKind=tok::kw___interface;
break;
2889 TagName=
"class" ; FixitTagName =
"class " ;TagKind=tok::kw_class ;
break;
2893 IdentifierInfo *TokenName = Tok.getIdentifierInfo();
2894 LookupResult
R(Actions, TokenName, SourceLocation(),
2897 Diag(Loc, diag::err_use_of_tag_name_without_tag)
2898 << TokenName << TagName <<
getLangOpts().CPlusPlus
2904 Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type)
2905 << TokenName << TagName;
2909 if (TagKind == tok::kw_enum)
2910 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS,
2911 DeclSpecContext::DSC_normal);
2913 ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
2915 DeclSpecContext::DSC_normal, Attrs);
2922 if (!isTypeSpecifier(DSC) && (!SS || DSC == DeclSpecContext::DSC_top_level ||
2923 DSC == DeclSpecContext::DSC_class)) {
2927 case tok::l_paren: {
2934 TentativeParsingAction PA(*
this);
2936 TPResult TPR = TryParseDeclarator(
false);
2939 if (TPR != TPResult::False) {
2947 if (DSC == DeclSpecContext::DSC_class ||
2948 (DSC == DeclSpecContext::DSC_top_level && SS)) {
2949 IdentifierInfo *II = Tok.getIdentifierInfo();
2950 if (Actions.isCurrentClassNameTypo(II, SS)) {
2951 Diag(Loc, diag::err_constructor_bad_name)
2952 << Tok.getIdentifierInfo() << II
2954 Tok.setIdentifierInfo(II);
2972 AnnotateScopeToken(*SS,
false);
2986 IdentifierInfo *II = Tok.getIdentifierInfo();
2988 Actions.DiagnoseUnknownTypeName(II, Loc,
getCurScope(), SS, T,
2994 const char *PrevSpec;
2997 Actions.getASTContext().getPrintingPolicy());
3002 }
else if (II != Tok.getIdentifierInfo()) {
3015 if (IsTemplateName) {
3016 SourceLocation LAngle, RAngle;
3017 TemplateArgList Args;
3018 ParseTemplateIdAfterTemplateName(
true, LAngle, Args, RAngle);
3027Parser::DeclSpecContext
3031 return DeclSpecContext::DSC_class;
3033 return DeclSpecContext::DSC_top_level;
3035 return DeclSpecContext::DSC_template_param;
3037 return DeclSpecContext::DSC_template_arg;
3039 return DeclSpecContext::DSC_template_type_arg;
3042 return DeclSpecContext::DSC_trailing;
3045 return DeclSpecContext::DSC_alias_declaration;
3047 return DeclSpecContext::DSC_association;
3049 return DeclSpecContext::DSC_type_specifier;
3051 return DeclSpecContext::DSC_condition;
3053 return DeclSpecContext::DSC_conv_operator;
3055 return DeclSpecContext::DSC_new;
3070 return DeclSpecContext::DSC_normal;
3073 llvm_unreachable(
"Missing DeclaratorContext case");
3080 if (isTypeIdInParens()) {
3081 SourceLocation TypeLoc = Tok.getLocation();
3083 SourceRange TypeRange(Start, Tok.getLocation());
3084 if (Actions.ActOnAlignasTypeArgument(KWName, Ty, TypeLoc, TypeRange))
3101 assert(Tok.isOneOf(tok::kw_alignas, tok::kw__Alignas) &&
3102 "Not an alignment-specifier!");
3109 if (T.expectAndConsume())
3114 SourceLocation EllipsisLoc;
3116 ParseAlignArgument(PP.getSpelling(KWTok), T.getOpenLocation(),
3125 *EndLoc = T.getCloseLocation();
3132 ArgExprs.push_back(ArgExpr.
get());
3133 Attrs.
addNew(KWName, KWLoc, AttributeScopeInfo(), ArgExprs.data(), 1, Kind,
3138void Parser::DistributeCLateParsedAttrs(
Decl *Dcl,
3139 LateParsedAttrList *LateAttrs) {
3144 for (
auto *LateAttr : *LateAttrs) {
3145 if (LateAttr->Decls.empty())
3146 LateAttr->addDecl(Dcl);
3152 assert(Tok.is(tok::kw___ptrauth));
3154 IdentifierInfo *KwName = Tok.getIdentifierInfo();
3158 if (T.expectAndConsume())
3168 ArgExprs.push_back(ER.
get());
3172 SourceLocation EndLoc = T.getCloseLocation();
3174 if (ArgExprs.empty() || ArgExprs.size() > 3) {
3175 Diag(KwLoc, diag::err_ptrauth_qualifier_bad_arg_count);
3179 Attrs.
addNew(KwName, SourceRange(KwLoc, EndLoc), AttributeScopeInfo(),
3180 ArgExprs.data(), ArgExprs.size(),
3181 ParsedAttr::Form::Keyword(
false,
3191 assert(Tok.is(tok::l_paren) &&
"Attribute arg list not starting with '('");
3196 if (Tok.is(tok::r_paren)) {
3197 Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
3204 using ExpressionKind =
3206 EnterExpressionEvaluationContext EC(
3208 ExpressionKind::EK_AttrArgument);
3216 ArgExprs.push_back(ArgExpr.
get());
3219 ASTContext &Ctx = Actions.getASTContext();
3225 Attrs.
addNew(&AttrName, SourceRange(AttrNameLoc,
Parens.getCloseLocation()),
3226 AttributeScopeInfo(), ArgExprs.data(), ArgExprs.size(), Form);
3229ExprResult Parser::ParseExtIntegerArgument() {
3230 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
3231 "Not an extended int type");
3235 if (T.expectAndConsume())
3244 if(T.consumeClose())
3251 DeclSpecContext DSContext,
3252 LateParsedAttrList *LateAttrs) {
3255 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3256 DSContext == DeclSpecContext::DSC_top_level);
3259 Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype,
3260 tok::annot_template_id) &&
3266 bool HasScope = Tok.is(tok::annot_cxxscope);
3268 Token AfterScope = HasScope ?
NextToken() : Tok;
3272 bool MightBeDeclarator =
true;
3273 if (Tok.isOneOf(tok::kw_typename, tok::annot_typename)) {
3275 MightBeDeclarator =
false;
3276 }
else if (AfterScope.
is(tok::annot_template_id)) {
3279 TemplateIdAnnotation *Annot =
3282 MightBeDeclarator =
false;
3283 }
else if (AfterScope.
is(tok::identifier)) {
3288 if (
Next.isOneOf(tok::star, tok::amp, tok::ampamp, tok::identifier,
3289 tok::annot_cxxscope, tok::coloncolon)) {
3291 MightBeDeclarator = false;
3292 }
else if (HasScope) {
3297 Actions.RestoreNestedNameSpecifierAnnotation(
3298 Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
3300 Sema::NameClassification Classification = Actions.ClassifyName(
3303 switch (Classification.
getKind()) {
3309 llvm_unreachable(
"typo correction is not possible here");
3317 MightBeDeclarator =
false;
3332 if (MightBeDeclarator)
3335 const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
3337 diag::err_expected_after)
3348 ParsedTemplateInfo NotATemplate;
3349 ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
3353void Parser::ParseDeclarationSpecifiers(
3355 DeclSpecContext DSContext, LateParsedAttrList *LateAttrs,
3367 if (DSContext == DeclSpecContext::DSC_conv_operator) {
3370 DSContext = DeclSpecContext::DSC_type_specifier;
3373 bool EnteringContext = (DSContext == DeclSpecContext::DSC_class ||
3374 DSContext == DeclSpecContext::DSC_top_level);
3375 bool AttrsLastTime =
false;
3376 ParsedAttributes attrs(AttrFactory);
3378 PrintingPolicy Policy = Actions.getPrintingPolicy();
3381 bool isStorageClass =
false;
3382 const char *PrevSpec =
nullptr;
3383 unsigned DiagID = 0;
3387 SourceLocation ConsumedEnd;
3396 if (
getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&
3399 Tok.setKind(tok::identifier);
3401 SourceLocation Loc = Tok.getLocation();
3404 auto handleOpenCLImageKW = [&] (StringRef Ext,
TypeSpecifierType ImageTypeSpec) {
3408 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
3409 Tok.setKind(tok::identifier);
3418 bool IsTemplateSpecOrInst =
3422 switch (Tok.getKind()) {
3424 if (Tok.isRegularKeywordAttribute())
3429 ProhibitAttributes(attrs);
3432 for (
const ParsedAttr &PA : attrs) {
3433 if (!PA.isCXX11Attribute() && !PA.isC23Attribute() &&
3434 !PA.isRegularKeywordAttribute())
3442 if (PA.getKind() == ParsedAttr::AT_VectorSize) {
3443 Diag(PA.getLoc(), diag::warn_attribute_ignored) << PA;
3450 if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3451 PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3454 if (PA.getKind() == ParsedAttr::AT_LifetimeBound)
3455 Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type)
3456 << PA << PA.isRegularKeywordAttribute()
3459 Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
3460 << PA << PA.isRegularKeywordAttribute();
3469 DS.
Finish(Actions, Policy);
3473 case tok::kw__Alignas:
3474 diagnoseUseOfC11Keyword(Tok);
3476 case tok::kw_alignas:
3482 if (Tok.getKind() == tok::kw_alignas)
3483 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
3489 if (!isAllowedCXX11AttributeSpecifier())
3490 goto DoneWithDeclSpec;
3493 ProhibitAttributes(attrs);
3498 attrs.Range = SourceRange();
3500 ParseCXX11Attributes(attrs);
3501 AttrsLastTime =
true;
3504 case tok::code_completion: {
3508 bool AllowNonIdentifiers
3514 bool AllowNestedNameSpecifiers
3515 = DSContext == DeclSpecContext::DSC_top_level ||
3519 Actions.CodeCompletion().CodeCompleteDeclSpec(
3520 getCurScope(), DS, AllowNonIdentifiers, AllowNestedNameSpecifiers);
3526 CCC = DSContext == DeclSpecContext::DSC_class
3529 else if (DSContext == DeclSpecContext::DSC_class)
3533 else if (CurParsedObjCImpl)
3537 Actions.CodeCompletion().CodeCompleteOrdinaryName(
getCurScope(), CCC);
3541 case tok::coloncolon:
3547 goto DoneWithDeclSpec;
3549 if (Tok.is(tok::coloncolon))
3550 goto DoneWithDeclSpec;
3553 case tok::annot_cxxscope: {
3555 goto DoneWithDeclSpec;
3558 if (TemplateInfo.TemplateParams)
3560 Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
3561 Tok.getAnnotationRange(),
3567 TemplateIdAnnotation *TemplateId =
Next.is(tok::annot_template_id)
3568 ? takeTemplateIdAnnotation(
Next)
3574 ConsumeAnnotationToken();
3588 if ((DSContext == DeclSpecContext::DSC_top_level ||
3589 DSContext == DeclSpecContext::DSC_class) &&
3592 isConstructorDeclarator(
false,
3599 goto DoneWithDeclSpec;
3603 ConsumeAnnotationToken();
3604 assert(Tok.is(tok::annot_template_id) &&
3605 "ParseOptionalCXXScopeSpecifier not working");
3606 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3616 ConsumeAnnotationToken();
3620 if (
Next.is(tok::annot_typename)) {
3622 ConsumeAnnotationToken();
3625 Tok.getAnnotationEndLoc(),
3626 PrevSpec, DiagID, T, Policy);
3630 ConsumeAnnotationToken();
3634 Next.is(tok::annot_template_id) &&
3635 static_cast<TemplateIdAnnotation *
>(
Next.getAnnotationValue())
3638 ConsumeAnnotationToken();
3639 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3643 if (
Next.isNot(tok::identifier))
3644 goto DoneWithDeclSpec;
3649 if ((DSContext == DeclSpecContext::DSC_top_level ||
3650 DSContext == DeclSpecContext::DSC_class) &&
3653 isConstructorDeclarator(
false,
3657 goto DoneWithDeclSpec;
3663 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3667 false,
false,
nullptr,
3670 isClassTemplateDeductionContext(DSContext), AllowImplicitTypename);
3672 if (IsTemplateSpecOrInst)
3680 if (TryAnnotateTypeConstraint())
3681 goto DoneWithDeclSpec;
3682 if (Tok.isNot(tok::annot_cxxscope) ||
3686 ConsumeAnnotationToken();
3687 ParsedAttributes Attrs(AttrFactory);
3688 if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext, Attrs)) {
3689 if (!Attrs.
empty()) {
3690 AttrsLastTime =
true;
3691 attrs.takeAllAppendingFrom(Attrs);
3695 goto DoneWithDeclSpec;
3699 ConsumeAnnotationToken();
3702 DiagID, TypeRep, Policy);
3712 case tok::annot_typename: {
3716 goto DoneWithDeclSpec;
3725 ConsumeAnnotationToken();
3730 case tok::kw___is_signed:
3742 TryKeywordIdentFallback(
true);
3745 goto DoneWithDeclSpec;
3748 case tok::kw___super:
3749 case tok::kw_decltype:
3750 case tok::identifier:
3756 goto DoneWithDeclSpec;
3762 if (!
getLangOpts().DeclSpecKeyword && Tok.is(tok::identifier) &&
3763 Tok.getIdentifierInfo()->getName() ==
"__declspec") {
3764 Diag(Loc, diag::err_ms_attributes_not_enabled);
3774 if (T.consumeOpen()) {
3775 assert(
false &&
"Not a left paren?");
3790 SuppressAccessChecks SAC(*
this, IsTemplateSpecOrInst);
3794 if (IsTemplateSpecOrInst)
3798 if (IsTemplateSpecOrInst)
3801 goto DoneWithDeclSpec;
3804 if (!Tok.is(tok::identifier))
3809 if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID,
isInvalid))
3815 goto DoneWithDeclSpec;
3817 if (DSContext == DeclSpecContext::DSC_objc_method_result &&
3818 isObjCInstancetype()) {
3819 ParsedType TypeRep = Actions.ObjC().ActOnObjCInstanceType(Loc);
3822 DiagID, TypeRep, Policy);
3834 Actions.isCurrentClassName(*Tok.getIdentifierInfo(),
getCurScope()) &&
3835 isConstructorDeclarator(
true,
3838 goto DoneWithDeclSpec;
3841 *Tok.getIdentifierInfo(), Tok.getLocation(),
getCurScope(),
nullptr,
3842 false,
false,
nullptr,
false,
false,
3843 isClassTemplateDeductionContext(DSContext));
3848 if (TryAnnotateTypeConstraint())
3849 goto DoneWithDeclSpec;
3850 if (Tok.isNot(tok::identifier))
3852 ParsedAttributes Attrs(AttrFactory);
3853 if (ParseImplicitInt(DS,
nullptr, TemplateInfo, AS, DSContext, Attrs)) {
3854 if (!Attrs.
empty()) {
3855 AttrsLastTime =
true;
3856 attrs.takeAllAppendingFrom(Attrs);
3860 goto DoneWithDeclSpec;
3867 (DSContext == DeclSpecContext::DSC_class ||
3868 DSContext == DeclSpecContext::DSC_top_level) &&
3869 Actions.isDeductionGuideName(
getCurScope(), *Tok.getIdentifierInfo(),
3870 Tok.getLocation(), SS) &&
3871 isConstructorDeclarator(
true,
3873 goto DoneWithDeclSpec;
3876 DiagID, TypeRep, Policy);
3887 SourceLocation NewEndLoc;
3888 TypeResult NewTypeRep = parseObjCTypeArgsAndProtocolQualifiers(
3903 case tok::annot_template_id: {
3904 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
3915 TemplateId =
nullptr;
3923 tok::kw_volatile, tok::kw_restrict, tok::amp,
3925 Diag(Loc, diag::err_placeholder_expected_auto_or_decltype_auto)
3929 TemplateId, Policy);
3933 goto DoneWithDeclSpec;
3935 if (TemplateId && !
isInvalid && Actions.CheckTypeConstraint(TemplateId))
3936 TemplateId =
nullptr;
3938 ConsumeAnnotationToken();
3939 SourceLocation AutoLoc = Tok.getLocation();
3942 if (Tracker.consumeOpen()) {
3944 Diag(Tok, diag::err_expected) << tok::l_paren;
3948 Tracker.skipToEnd();
3949 Diag(Tok, diag::err_placeholder_expected_auto_or_decltype_auto)
3954 Tracker.consumeClose();
3957 ConsumedEnd = Tok.getLocation();
3962 DiagID, TemplateId, Policy);
3965 TemplateId, Policy);
3974 goto DoneWithDeclSpec;
3982 isConstructorDeclarator(
true,
3985 goto DoneWithDeclSpec;
3990 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);
3995 case tok::kw___attribute:
3996 case tok::kw___declspec:
3997 ParseAttributes(PAKM_GNU | PAKM_Declspec, DS.
getAttributes(), LateAttrs);
4001 case tok::kw___forceinline: {
4003 IdentifierInfo *
AttrName = Tok.getIdentifierInfo();
4004 SourceLocation AttrNameLoc = Tok.getLocation();
4006 nullptr, 0, tok::kw___forceinline);
4010 case tok::kw___unaligned:
4016 case tok::kw___ptrauth:
4020 case tok::kw___sptr:
4021 case tok::kw___uptr:
4022 case tok::kw___ptr64:
4023 case tok::kw___ptr32:
4025 case tok::kw___cdecl:
4026 case tok::kw___stdcall:
4027 case tok::kw___fastcall:
4028 case tok::kw___thiscall:
4029 case tok::kw___regcall:
4030 case tok::kw___vectorcall:
4034 case tok::kw___funcref:
4039 case tok::kw___pascal:
4044 case tok::kw___kernel:
4049 case tok::kw___noinline__:
4054 case tok::kw__Nonnull:
4055 case tok::kw__Nullable:
4056 case tok::kw__Nullable_result:
4057 case tok::kw__Null_unspecified:
4062 case tok::kw___kindof:
4064 AttributeScopeInfo(),
nullptr, 0,
4070 case tok::kw_typedef:
4072 PrevSpec, DiagID, Policy);
4073 isStorageClass =
true;
4075 case tok::kw_extern:
4077 Diag(Tok, diag::ext_thread_before) <<
"extern";
4079 PrevSpec, DiagID, Policy);
4080 isStorageClass =
true;
4082 case tok::kw___private_extern__:
4084 Loc, PrevSpec, DiagID, Policy);
4085 isStorageClass =
true;
4087 case tok::kw_static:
4089 Diag(Tok, diag::ext_thread_before) <<
"static";
4091 PrevSpec, DiagID, Policy);
4092 isStorageClass =
true;
4096 auto MayBeTypeSpecifier = [&]() {
4107 if (isKnownToBeTypeSpecifier(T))
4117 if (MayBeTypeSpecifier()) {
4119 PrevSpec, DiagID, Policy);
4121 Diag(Tok, diag::ext_auto_storage_class)
4128 PrevSpec, DiagID, Policy);
4129 isStorageClass =
true;
4131 case tok::kw___auto_type:
4132 Diag(Tok, diag::ext_auto_type);
4136 case tok::kw_register:
4138 PrevSpec, DiagID, Policy);
4139 isStorageClass =
true;
4141 case tok::kw_mutable:
4143 PrevSpec, DiagID, Policy);
4144 isStorageClass =
true;
4146 case tok::kw___thread:
4149 isStorageClass =
true;
4151 case tok::kw_thread_local:
4153 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4162 Loc, PrevSpec, DiagID);
4163 isStorageClass =
true;
4165 case tok::kw__Thread_local:
4166 diagnoseUseOfC11Keyword(Tok);
4168 Loc, PrevSpec, DiagID);
4169 isStorageClass =
true;
4173 case tok::kw_inline:
4176 case tok::kw_virtual:
4180 !
getActions().getOpenCLOptions().isAvailableOption(
4182 DiagID = diag::err_openclcxx_virtual_function;
4183 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4186 DiagID = diag::err_hlsl_virtual_function;
4187 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4193 case tok::kw_explicit: {
4194 SourceLocation ExplicitLoc = Loc;
4195 SourceLocation CloseParenLoc;
4197 ConsumedEnd = ExplicitLoc;
4199 if (Tok.is(tok::l_paren)) {
4202 ? diag::warn_cxx17_compat_explicit_bool
4203 : diag::ext_explicit_bool);
4205 ExprResult ExplicitExpr(
static_cast<Expr *
>(
nullptr));
4207 Tracker.consumeOpen();
4209 EnterExpressionEvaluationContext ConstantEvaluated(
4213 ConsumedEnd = Tok.getLocation();
4214 if (ExplicitExpr.isUsable()) {
4215 CloseParenLoc = Tok.getLocation();
4216 Tracker.consumeClose();
4218 Actions.ActOnExplicitBoolSpecifier(ExplicitExpr.get());
4220 Tracker.skipToEnd();
4222 Diag(Tok.getLocation(), diag::warn_cxx20_compat_explicit_bool);
4226 ExplicitSpec, CloseParenLoc);
4229 case tok::kw__Noreturn:
4230 diagnoseUseOfC11Keyword(Tok);
4235 case tok::kw_friend:
4236 if (DSContext == DeclSpecContext::DSC_class) {
4243 DiagID = diag::err_friend_invalid_in_context;
4249 case tok::kw___module_private__:
4254 case tok::kw_constexpr:
4256 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4260 case tok::kw_consteval:
4264 case tok::kw_constinit:
4272 Diag(Tok, diag::err_unknown_typename) << Tok.getName();
4276 goto DoneWithDeclSpec;
4287 PrevSpec, DiagID, Policy);
4289 case tok::kw___int64:
4291 PrevSpec, DiagID, Policy);
4293 case tok::kw_signed:
4297 case tok::kw_unsigned:
4301 case tok::kw__Complex:
4303 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4307 case tok::kw__Imaginary:
4309 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4325 case tok::kw__ExtInt:
4326 case tok::kw__BitInt: {
4327 DiagnoseBitIntUse(Tok);
4332 ConsumedEnd = PrevTokLocation;
4335 case tok::kw___int128:
4343 case tok::kw___bf16:
4351 case tok::kw_double:
4355 case tok::kw__Float16:
4359 case tok::kw__Accum:
4361 "This keyword is only used when fixed point types are enabled "
4362 "with `-ffixed-point`");
4366 case tok::kw__Fract:
4368 "This keyword is only used when fixed point types are enabled "
4369 "with `-ffixed-point`");
4375 "This keyword is only used when fixed point types are enabled "
4376 "with `-ffixed-point`");
4379 case tok::kw___float128:
4383 case tok::kw___ibm128:
4387 case tok::kw_wchar_t:
4391 case tok::kw_char8_t:
4395 case tok::kw_char16_t:
4399 case tok::kw_char32_t:
4405 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();
4409 Diag(Tok, diag::ext_c99_feature) << Tok.getName();
4411 if (Tok.is(tok::kw_bool) &&
4415 DiagID = diag::err_bool_redeclaration;
4417 Tok.setKind(tok::identifier);
4424 case tok::kw__Decimal32:
4428 case tok::kw__Decimal64:
4432 case tok::kw__Decimal128:
4436 case tok::kw___vector:
4439 case tok::kw___pixel:
4442 case tok::kw___bool:
4447 getLangOpts().getOpenCLCompatibleVersion() < 200) {
4450 Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
4451 Tok.setKind(tok::identifier);
4452 goto DoneWithDeclSpec;
4454 DiagID = diag::err_opencl_unknown_type_specifier;
4455 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4461#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
4462#define IMAGE_WRITE_TYPE(Type, Id, Ext)
4463#define IMAGE_READ_TYPE(ImgType, Id, Ext) \
4464 case tok::kw_##ImgType##_t: \
4465 if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \
4466 goto DoneWithDeclSpec; \
4468#include "clang/Basic/OpenCLImageTypes.def"
4469 case tok::kw___unknown_anytype:
4471 PrevSpec, DiagID, Policy);
4476 case tok::kw_struct:
4477 case tok::kw___interface:
4478 case tok::kw_union: {
4485 ParsedAttributes Attributes(AttrFactory);
4486 ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
4487 EnteringContext, DSContext, Attributes);
4491 if (!Attributes.empty()) {
4492 AttrsLastTime =
true;
4493 attrs.takeAllAppendingFrom(Attributes);
4501 ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
4509 case tok::kw_volatile:
4513 case tok::kw_restrict:
4517 case tok::kw___ob_wrap:
4519 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
4524 OverflowBehaviorType::OverflowBehaviorKind::Wrap, Loc, PrevSpec,
4527 case tok::kw___ob_trap:
4529 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
4534 OverflowBehaviorType::OverflowBehaviorKind::Trap, Loc, PrevSpec,
4539 case tok::kw_typename:
4542 goto DoneWithDeclSpec;
4544 if (!Tok.is(tok::kw_typename))
4549 case tok::kw_typeof:
4550 case tok::kw_typeof_unqual:
4551 ParseTypeofSpecifier(DS);
4554 case tok::annot_decltype:
4555 ParseDecltypeSpecifier(DS);
4558 case tok::annot_pack_indexing_type:
4559 ParsePackIndexingType(DS);
4562 case tok::annot_pragma_pack:
4566 case tok::annot_pragma_ms_pragma:
4567 HandlePragmaMSPragma();
4570 case tok::annot_pragma_ms_vtordisp:
4571 HandlePragmaMSVtorDisp();
4574 case tok::annot_pragma_ms_pointers_to_members:
4575 HandlePragmaMSPointersToMembers();
4578 case tok::annot_pragma_export:
4579 HandlePragmaExport();
4582#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
4583#include "clang/Basic/TransformTypeTraits.def"
4587 if (!MaybeParseTypeTransformTypeSpecifier(DS))
4588 goto ParseIdentifier;
4591 case tok::kw__Atomic:
4596 diagnoseUseOfC11Keyword(Tok);
4598 ParseAtomicSpecifier(DS);
4606 case tok::kw___generic:
4611 if (!Actions.getLangOpts().OpenCLGenericAddressSpace) {
4612 DiagID = diag::err_opencl_unknown_type_specifier;
4613 PrevSpec = Tok.getIdentifierInfo()->getNameStart();
4618 case tok::kw_private:
4622 goto DoneWithDeclSpec;
4624 case tok::kw___private:
4625 case tok::kw___global:
4626 case tok::kw___local:
4627 case tok::kw___constant:
4629 case tok::kw___read_only:
4630 case tok::kw___write_only:
4631 case tok::kw___read_write:
4635 case tok::kw_groupshared:
4643#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
4644 case tok::kw_##Name: \
4645 isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##Name, Loc, PrevSpec, \
4648#include "clang/Basic/HLSLIntangibleTypes.def"
4655 goto DoneWithDeclSpec;
4657 SourceLocation StartLoc = Tok.getLocation();
4658 SourceLocation EndLoc;
4660 if (
Type.isUsable()) {
4662 PrevSpec, DiagID,
Type.get(),
4663 Actions.getASTContext().getPrintingPolicy()))
4664 Diag(StartLoc, DiagID) << PrevSpec;
4680 assert(PrevSpec &&
"Method did not return previous specifier!");
4683 if (DiagID == diag::ext_duplicate_declspec ||
4684 DiagID == diag::ext_warn_duplicate_declspec ||
4685 DiagID == diag::err_duplicate_declspec)
4686 Diag(Loc, DiagID) << PrevSpec
4689 else if (DiagID == diag::err_opencl_unknown_type_specifier) {
4693 Diag(Loc, DiagID) << PrevSpec;
4696 if (DiagID != diag::err_bool_redeclaration && ConsumedEnd.
isInvalid())
4700 AttrsLastTime =
false;
4712 if (!RD || !RD->getName().empty() || RD->isAnonymousStructOrUnion())
4715 for (
auto *I : RD->decls()) {
4716 auto *VD = dyn_cast<ValueDecl>(I);
4724 for (
const auto &DD : CAT->dependent_decls()) {
4725 if (!RD->containsDecl(DD.getDecl())) {
4726 P.
Diag(VD->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
4727 << DD.getDecl() << CAT->getKind() << CAT->isArrayType();
4728 P.
Diag(DD.getDecl()->getBeginLoc(),
4729 diag::note_flexible_array_counted_by_attr_field)
4736void Parser::ParseStructDeclaration(
4739 LateParsedAttrList *LateFieldAttrs) {
4741 if (Tok.is(tok::kw___extension__)) {
4743 ExtensionRAIIObject O(Diags);
4745 return ParseStructDeclaration(DS, FieldsCallback, LateFieldAttrs);
4749 ParsedAttributes Attrs(AttrFactory);
4750 MaybeParseCXX11Attributes(Attrs);
4753 ParseSpecifierQualifierList(DS);
4757 if (Tok.is(tok::semi)) {
4762 ProhibitAttributes(Attrs);
4763 RecordDecl *AnonRecord =
nullptr;
4764 Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(
4766 assert(!AnonRecord &&
"Did not expect anonymous struct or union here");
4772 bool FirstDeclarator =
true;
4773 SourceLocation CommaLoc;
4775 ParsingFieldDeclarator DeclaratorInfo(*
this, DS, Attrs);
4776 DeclaratorInfo.D.setCommaLoc(CommaLoc);
4779 if (!FirstDeclarator) {
4782 DiagnoseAndSkipCXX11Attributes();
4783 MaybeParseGNUAttributes(DeclaratorInfo.D);
4784 DiagnoseAndSkipCXX11Attributes();
4789 if (Tok.isNot(tok::colon)) {
4792 ParseDeclarator(DeclaratorInfo.D);
4794 DeclaratorInfo.D.SetIdentifier(
nullptr, Tok.getLocation());
4806 DeclaratorInfo.BitfieldSize = Res.
get();
4810 MaybeParseGNUAttributes(DeclaratorInfo.D, LateFieldAttrs);
4813 Decl *
Field = FieldsCallback(DeclaratorInfo);
4815 DistributeCLateParsedAttrs(Field, LateFieldAttrs);
4822 FirstDeclarator =
false;
4828void Parser::ParseLexedCAttributeList(LateParsedAttrList &LAs,
bool EnterScope,
4830 assert(LAs.parseSoon() &&
4831 "Attribute list should be marked for immediate parsing.");
4832 for (
auto *LA : LAs) {
4833 ParseLexedCAttribute(*LA,
EnterScope, OutAttrs);
4839void Parser::ParseLexedCAttribute(LateParsedAttribute &LA,
bool EnterScope,
4844 AttrEnd.startToken();
4845 AttrEnd.setKind(tok::eof);
4846 AttrEnd.setLocation(Tok.getLocation());
4847 AttrEnd.setEofData(LA.Toks.data());
4848 LA.Toks.push_back(AttrEnd);
4852 LA.Toks.push_back(Tok);
4853 PP.EnterTokenStream(LA.Toks,
true,
4862 ParsedAttributes Attrs(AttrFactory);
4864 assert(LA.Decls.size() <= 1 &&
4865 "late field attribute expects to have at most one declaration.");
4868 ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs,
nullptr,
nullptr,
4869 SourceLocation(), ParsedAttr::Form::GNU(),
nullptr);
4871 for (
auto *D : LA.Decls)
4872 Actions.ActOnFinishDelayedAttribute(
getCurScope(), D, Attrs);
4876 while (Tok.isNot(tok::eof))
4880 if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
4890 PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl,
RecordLoc,
4891 "parsing struct/union body");
4895 if (T.consumeOpen())
4899 Actions.ActOnTagStartDefinition(
getCurScope(), TagDecl);
4903 LateParsedAttrList LateFieldAttrs(
true,
4907 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
4908 Tok.isNot(tok::eof)) {
4912 if (Tok.is(tok::semi)) {
4918 if (Tok.isOneOf(tok::kw__Static_assert, tok::kw_static_assert)) {
4919 SourceLocation DeclEnd;
4920 ParseStaticAssertDeclaration(DeclEnd);
4924 if (Tok.is(tok::annot_pragma_pack)) {
4929 if (Tok.is(tok::annot_pragma_align)) {
4930 HandlePragmaAlign();
4934 if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
4937 ParsedAttributes Attrs(AttrFactory);
4938 (void)ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs);
4942 if (Tok.is(tok::annot_pragma_openacc)) {
4944 ParsedAttributes Attrs(AttrFactory);
4950 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)
4952 TagType, Actions.getASTContext().getPrintingPolicy());
4953 ConsumeAnnotationToken();
4957 if (!Tok.is(tok::at)) {
4958 auto CFieldCallback = [&](ParsingFieldDeclarator &FD) -> Decl * {
4962 FD.D.getDeclSpec().getSourceRange().getBegin(),
4963 FD.D, FD.BitfieldSize);
4969 ParsingDeclSpec DS(*
this);
4970 ParseStructDeclaration(DS, CFieldCallback, &LateFieldAttrs);
4973 if (!Tok.isObjCAtKeyword(tok::objc_defs)) {
4974 Diag(Tok, diag::err_unexpected_at);
4979 ExpectAndConsume(tok::l_paren);
4980 if (!Tok.is(tok::identifier)) {
4981 Diag(Tok, diag::err_expected) << tok::identifier;
4985 SmallVector<Decl *, 16> Fields;
4986 Actions.ObjC().ActOnDefs(
getCurScope(), TagDecl, Tok.getLocation(),
4987 Tok.getIdentifierInfo(), Fields);
4989 ExpectAndConsume(tok::r_paren);
4995 if (Tok.is(tok::r_brace)) {
4996 ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
5000 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
5009 ParsedAttributes attrs(AttrFactory);
5011 MaybeParseGNUAttributes(attrs, &LateFieldAttrs);
5014 ParseLexedCAttributeList(LateFieldAttrs,
false);
5016 SmallVector<Decl *, 32> FieldDecls(TagDecl->
fields());
5019 T.getOpenLocation(), T.getCloseLocation(), attrs);
5021 Actions.ActOnTagFinishDefinition(
getCurScope(), TagDecl, T.getRange());
5025 const ParsedTemplateInfo &TemplateInfo,
5028 if (Tok.is(tok::code_completion)) {
5037 ParsedAttributes attrs(AttrFactory);
5038 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5040 SourceLocation ScopedEnumKWLoc;
5041 bool IsScopedUsingClassTag =
false;
5046 : diag::ext_scoped_enum);
5047 IsScopedUsingClassTag = Tok.is(tok::kw_class);
5052 ProhibitAttributes(attrs);
5055 MaybeParseAttributes(PAKM_GNU | PAKM_Declspec | PAKM_CXX11, attrs);
5064 bool shouldDelayDiagsInTag =
5067 SuppressAccessChecks diagsFromTag(*
this, shouldDelayDiagsInTag);
5070 AllowDefiningTypeSpec AllowEnumSpecifier =
5072 bool CanBeOpaqueEnumDeclaration =
5073 DS.
isEmpty() && isOpaqueEnumDeclarationContext(DSC);
5076 (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes ||
5077 CanBeOpaqueEnumDeclaration);
5085 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
5090 if (Spec.
isSet() && Tok.isNot(tok::identifier)) {
5091 Diag(Tok, diag::err_expected) << tok::identifier;
5093 if (Tok.isNot(tok::l_brace)) {
5101 SS = std::move(Spec);
5105 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
5106 Tok.isNot(tok::colon)) {
5107 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
5116 IdentifierInfo *Name =
nullptr;
5117 SourceLocation NameLoc;
5118 if (Tok.is(tok::identifier)) {
5119 Name = Tok.getIdentifierInfo();
5123 if (!Name && ScopedEnumKWLoc.
isValid()) {
5126 Diag(Tok, diag::err_scoped_enum_missing_identifier);
5127 ScopedEnumKWLoc = SourceLocation();
5128 IsScopedUsingClassTag =
false;
5133 if (shouldDelayDiagsInTag)
5134 diagsFromTag.done();
5137 SourceRange BaseRange;
5139 bool CanBeBitfield =
5143 if (Tok.is(tok::colon)) {
5168 if (CanBeBitfield && !isEnumBase(CanBeOpaqueEnumDeclaration)) {
5172 Diag(Tok.getLocation(), diag::err_anonymous_enum_bitfield);
5173 }
else if (CanHaveEnumBase || !ColonIsSacred) {
5180 DeclSpec DS(AttrFactory);
5184 DeclSpecContext::DSC_type_specifier);
5187 BaseType = Actions.ActOnTypeName(DeclaratorInfo);
5189 BaseRange = SourceRange(ColonLoc, DeclaratorInfo.getSourceRange().getEnd());
5193 DiagCompat(ColonLoc, diag_compat::enum_fixed_underlying_type)
5196 Diag(ColonLoc, diag::ext_ms_c_enum_fixed_underlying_type)
5200 ? diag::warn_c17_compat_enum_fixed_underlying_type
5201 : diag::ext_c23_enum_fixed_underlying_type)
5218 if (AllowEnumSpecifier == AllowDefiningTypeSpec::No)
5220 else if (Tok.is(tok::l_brace)) {
5222 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)
5228 ScopedEnumKWLoc = SourceLocation();
5229 IsScopedUsingClassTag =
false;
5235 }
else if (!isTypeSpecifier(DSC) &&
5236 (Tok.is(tok::semi) ||
5237 (Tok.isAtStartOfLine() &&
5238 !isValidAfterTypeSpecifier(CanBeBitfield)))) {
5243 if (Tok.isNot(tok::semi)) {
5245 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5246 PP.EnterToken(Tok,
true);
5247 Tok.setKind(tok::semi);
5253 bool IsElaboratedTypeSpecifier =
5259 diagsFromTag.redelay();
5267 Diag(Tok, diag::err_enum_template);
5275 Diag(StartLoc, diag::err_explicit_instantiation_enum);
5279 assert(TemplateInfo.TemplateParams &&
"no template parameters");
5281 TemplateInfo.TemplateParams->size());
5286 Diag(Tok, diag::err_enumerator_unnamed_no_def);
5302 if (IsElaboratedTypeSpecifier && !
getLangOpts().MicrosoftExt &&
5304 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
5305 diag::err_keyword_not_allowed,
5308 Diag(BaseRange.
getBegin(), diag::ext_enum_base_in_type_specifier)
5309 << (AllowEnumSpecifier == AllowDefiningTypeSpec::Yes) << BaseRange;
5310 else if (ScopedEnumKWLoc.
isValid())
5311 Diag(ScopedEnumKWLoc, diag::ext_elaborated_enum_class)
5315 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
5317 SkipBodyInfo SkipBody;
5320 SkipBody = Actions.shouldSkipAnonEnumBody(
getCurScope(),
5325 bool IsDependent =
false;
5326 const char *PrevSpec =
nullptr;
5331 TParams, Owned, IsDependent, ScopedEnumKWLoc,
5332 IsScopedUsingClassTag,
5333 BaseType, DSC == DeclSpecContext::DSC_type_specifier,
5334 DSC == DeclSpecContext::DSC_template_param ||
5335 DSC == DeclSpecContext::DSC_template_type_arg,
5336 OffsetOfState, &SkipBody).get();
5346 NameLoc.
isValid() ? NameLoc : StartLoc,
5347 PrevSpec, DiagID, TagDecl, Owned,
5348 Actions.getASTContext().getPrintingPolicy()))
5349 Diag(StartLoc, DiagID) << PrevSpec;
5358 Diag(Tok, diag::err_expected_type_name_after_typename);
5364 if (
Type.isInvalid()) {
5370 NameLoc.
isValid() ? NameLoc : StartLoc,
5371 PrevSpec, DiagID,
Type.get(),
5372 Actions.getASTContext().getPrintingPolicy()))
5373 Diag(StartLoc, DiagID) << PrevSpec;
5392 ParseEnumBody(StartLoc, D, &SkipBody);
5394 !Actions.ActOnDuplicateDefinition(
getCurScope(), TagDecl, SkipBody)) {
5401 NameLoc.
isValid() ? NameLoc : StartLoc,
5402 PrevSpec, DiagID, TagDecl, Owned,
5403 Actions.getASTContext().getPrintingPolicy()))
5404 Diag(StartLoc, DiagID) << PrevSpec;
5411 Actions.ActOnTagStartDefinition(
getCurScope(), EnumDecl);
5419 Diag(T.getOpenLocation(), diag::ext_ms_c_empty_enum_type)
5420 << SourceRange(T.getOpenLocation(), Tok.
getLocation());
5422 Diag(Tok, diag::err_empty_enum);
5425 SmallVector<Decl *, 32> EnumConstantDecls;
5426 SmallVector<SuppressAccessChecks, 32> EnumAvailabilityDiags;
5428 Decl *LastEnumConstDecl =
nullptr;
5431 while (Tok.isNot(tok::r_brace)) {
5434 if (Tok.isNot(tok::identifier)) {
5435 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
5441 IdentifierInfo *Ident = Tok.getIdentifierInfo();
5445 ParsedAttributes attrs(AttrFactory);
5446 MaybeParseGNUAttributes(attrs);
5447 if (isAllowedCXX11AttributeSpecifier()) {
5450 ? diag::warn_cxx14_compat_ns_enum_attribute
5451 : diag::ext_ns_enum_attribute)
5453 ParseCXX11Attributes(attrs);
5456 SourceLocation EqualLoc;
5458 EnumAvailabilityDiags.emplace_back(*
this);
5460 EnterExpressionEvaluationContext ConstantEvaluated(
5469 Decl *EnumConstDecl = Actions.ActOnEnumConstant(
5470 getCurScope(), EnumDecl, LastEnumConstDecl, IdentLoc, Ident, attrs,
5471 EqualLoc, AssignedVal.
get(), SkipBody);
5472 EnumAvailabilityDiags.back().done();
5474 EnumConstantDecls.push_back(EnumConstDecl);
5475 LastEnumConstDecl = EnumConstDecl;
5477 if (Tok.is(tok::identifier)) {
5480 Diag(Loc, diag::err_enumerator_list_missing_comma)
5487 SourceLocation CommaLoc;
5488 if (Tok.isNot(tok::r_brace) && !
TryConsumeToken(tok::comma, CommaLoc)) {
5490 Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
5493 Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
5503 if (Tok.is(tok::r_brace) && CommaLoc.
isValid()) {
5506 diag::ext_enumerator_list_comma_cxx :
5507 diag::ext_enumerator_list_comma_c)
5510 Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
5520 ParsedAttributes attrs(AttrFactory);
5521 MaybeParseGNUAttributes(attrs);
5523 Actions.ActOnEnumBody(StartLoc, T.getRange(), EnumDecl, EnumConstantDecls,
5527 assert(EnumConstantDecls.size() == EnumAvailabilityDiags.size());
5528 for (
size_t i = 0, e = EnumConstantDecls.size(); i != e; ++i) {
5530 EnumAvailabilityDiags[i].redelay();
5531 PD.complete(EnumConstantDecls[i]);
5535 Actions.ActOnTagFinishDefinition(
getCurScope(), EnumDecl, T.getRange());
5540 if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
5541 ExpectAndConsume(tok::semi, diag::err_expected_after,
"enum");
5545 PP.EnterToken(Tok,
true);
5546 Tok.setKind(tok::semi);
5550bool Parser::isKnownToBeTypeSpecifier(
const Token &
Tok)
const {
5551 switch (Tok.getKind()) {
5552 default:
return false;
5556 case tok::kw___int64:
5557 case tok::kw___int128:
5558 case tok::kw_signed:
5559 case tok::kw_unsigned:
5560 case tok::kw__Complex:
5561 case tok::kw__Imaginary:
5564 case tok::kw_wchar_t:
5565 case tok::kw_char8_t:
5566 case tok::kw_char16_t:
5567 case tok::kw_char32_t:
5569 case tok::kw__ExtInt:
5570 case tok::kw__BitInt:
5571 case tok::kw___bf16:
5574 case tok::kw_double:
5575 case tok::kw__Accum:
5576 case tok::kw__Fract:
5577 case tok::kw__Float16:
5578 case tok::kw___float128:
5579 case tok::kw___ibm128:
5582 case tok::kw__Decimal32:
5583 case tok::kw__Decimal64:
5584 case tok::kw__Decimal128:
5585 case tok::kw___vector:
5586#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5587#include "clang/Basic/OpenCLImageTypes.def"
5588#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5589#include "clang/Basic/HLSLIntangibleTypes.def"
5593 case tok::kw_struct:
5594 case tok::kw___interface:
5599 case tok::kw_typeof:
5600 case tok::kw_typeof_unqual:
5603 case tok::kw__Atomic:
5606 case tok::annot_typename:
5611bool Parser::isTypeSpecifierQualifier(
const Token &
Tok) {
5612 switch (Tok.getKind()) {
5613 default:
return false;
5615 case tok::identifier:
5616 if (TryAltiVecVectorToken())
5619 case tok::kw_typename:
5628 case tok::coloncolon:
5638 case tok::kw___attribute:
5640 case tok::kw_typeof:
5641 case tok::kw_typeof_unqual:
5646 case tok::kw___int64:
5647 case tok::kw___int128:
5648 case tok::kw_signed:
5649 case tok::kw_unsigned:
5650 case tok::kw__Complex:
5651 case tok::kw__Imaginary:
5654 case tok::kw_wchar_t:
5655 case tok::kw_char8_t:
5656 case tok::kw_char16_t:
5657 case tok::kw_char32_t:
5659 case tok::kw__ExtInt:
5660 case tok::kw__BitInt:
5662 case tok::kw___bf16:
5664 case tok::kw_double:
5665 case tok::kw__Accum:
5666 case tok::kw__Fract:
5667 case tok::kw__Float16:
5668 case tok::kw___float128:
5669 case tok::kw___ibm128:
5672 case tok::kw__Decimal32:
5673 case tok::kw__Decimal64:
5674 case tok::kw__Decimal128:
5675 case tok::kw___vector:
5676#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
5677#include "clang/Basic/OpenCLImageTypes.def"
5678#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
5679#include "clang/Basic/HLSLIntangibleTypes.def"
5683 case tok::kw_struct:
5684 case tok::kw___interface:
5691 case tok::kw_volatile:
5692 case tok::kw_restrict:
5693 case tok::kw___ob_wrap:
5694 case tok::kw___ob_trap:
5698 case tok::kw___unknown_anytype:
5701 case tok::annot_typename:
5708 case tok::kw___cdecl:
5709 case tok::kw___stdcall:
5710 case tok::kw___fastcall:
5711 case tok::kw___thiscall:
5712 case tok::kw___regcall:
5713 case tok::kw___vectorcall:
5715 case tok::kw___ptr64:
5716 case tok::kw___ptr32:
5717 case tok::kw___pascal:
5718 case tok::kw___unaligned:
5719 case tok::kw___ptrauth:
5721 case tok::kw__Nonnull:
5722 case tok::kw__Nullable:
5723 case tok::kw__Nullable_result:
5724 case tok::kw__Null_unspecified:
5726 case tok::kw___kindof:
5728 case tok::kw___private:
5729 case tok::kw___local:
5730 case tok::kw___global:
5731 case tok::kw___constant:
5732 case tok::kw___generic:
5733 case tok::kw___read_only:
5734 case tok::kw___read_write:
5735 case tok::kw___write_only:
5736 case tok::kw___funcref:
5739 case tok::kw_private:
5743 case tok::kw__Atomic:
5747 case tok::kw_groupshared:
5756 assert(PP.isIncrementalProcessingEnabled() &&
"Not in incremental mode");
5760 ParsedStmtContext SubStmtCtx = ParsedStmtContext();
5763 TopLevelStmtDecl *TLSD = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5764 StmtResult R = ParseStatementOrDeclaration(Stmts, SubStmtCtx);
5765 Actions.ActOnFinishTopLevelStmtDecl(TLSD,
R.get());
5767 R = Actions.ActOnNullStmt(Tok.getLocation());
5769 if (Tok.is(tok::annot_repl_input_end) &&
5770 Tok.getAnnotationValue() !=
nullptr) {
5771 ConsumeAnnotationToken();
5775 SmallVector<Decl *, 2> DeclsInGroup;
5776 DeclsInGroup.push_back(TLSD);
5779 for (Stmt *S : Stmts) {
5782 TopLevelStmtDecl *D = Actions.ActOnStartTopLevelStmtDecl(
getCurScope());
5783 Actions.ActOnFinishTopLevelStmtDecl(D, S);
5784 DeclsInGroup.push_back(D);
5787 return Actions.BuildDeclaratorGroup(DeclsInGroup);
5790bool Parser::isDeclarationSpecifier(
5792 bool DisambiguatingWithExpression) {
5793 switch (Tok.getKind()) {
5794 default:
return false;
5801 case tok::identifier:
5805 if (TryAltiVecVectorToken())
5808 case tok::kw_decltype:
5809 case tok::kw_typename:
5814 if (TryAnnotateTypeConstraint())
5816 if (Tok.is(tok::identifier))
5824 if (DisambiguatingWithExpression &&
5825 isStartOfObjCClassMessageMissingOpenBracket())
5828 return isDeclarationSpecifier(AllowImplicitTypename);
5830 case tok::coloncolon:
5844 case tok::kw_typedef:
5845 case tok::kw_extern:
5846 case tok::kw___private_extern__:
5847 case tok::kw_static:
5849 case tok::kw___auto_type:
5850 case tok::kw_register:
5851 case tok::kw___thread:
5852 case tok::kw_thread_local:
5853 case tok::kw__Thread_local:
5856 case tok::kw___module_private__:
5859 case tok::kw___unknown_anytype:
5864 case tok::kw___int64:
5865 case tok::kw___int128:
5866 case tok::kw_signed:
5867 case tok::kw_unsigned:
5868 case tok::kw__Complex:
5869 case tok::kw__Imaginary:
5872 case tok::kw_wchar_t:
5873 case tok::kw_char8_t:
5874 case tok::kw_char16_t:
5875 case tok::kw_char32_t:
5878 case tok::kw__ExtInt:
5879 case tok::kw__BitInt:
5881 case tok::kw___bf16:
5883 case tok::kw_double:
5884 case tok::kw__Accum:
5885 case tok::kw__Fract:
5886 case tok::kw__Float16:
5887 case tok::kw___float128:
5888 case tok::kw___ibm128:
5891 case tok::kw__Decimal32:
5892 case tok::kw__Decimal64:
5893 case tok::kw__Decimal128:
5894 case tok::kw___vector:
5898 case tok::kw_struct:
5900 case tok::kw___interface:
5906 case tok::kw_volatile:
5907 case tok::kw_restrict:
5908 case tok::kw___ob_wrap:
5909 case tok::kw___ob_trap:
5913 case tok::kw_inline:
5914 case tok::kw_virtual:
5915 case tok::kw_explicit:
5916 case tok::kw__Noreturn:
5919 case tok::kw__Alignas:
5922 case tok::kw_friend:
5925 case tok::kw_static_assert:
5926 case tok::kw__Static_assert:
5929 case tok::kw_typeof:
5930 case tok::kw_typeof_unqual:
5933 case tok::kw___attribute:
5936 case tok::annot_decltype:
5937 case tok::annot_pack_indexing_type:
5938 case tok::kw_constexpr:
5941 case tok::kw_consteval:
5942 case tok::kw_constinit:
5945 case tok::kw__Atomic:
5948 case tok::kw_alignas:
5958 case tok::annot_typename:
5959 return !DisambiguatingWithExpression ||
5960 !isStartOfObjCClassMessageMissingOpenBracket();
5963 case tok::annot_template_id: {
5964 TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
5969 return isTypeConstraintAnnotation() &&
5973 case tok::annot_cxxscope: {
5974 TemplateIdAnnotation *TemplateId =
5982 if (
NextToken().
is(tok::identifier) && TryAnnotateTypeConstraint())
5984 return isTypeConstraintAnnotation() &&
5988 case tok::kw___declspec:
5989 case tok::kw___cdecl:
5990 case tok::kw___stdcall:
5991 case tok::kw___fastcall:
5992 case tok::kw___thiscall:
5993 case tok::kw___regcall:
5994 case tok::kw___vectorcall:
5996 case tok::kw___sptr:
5997 case tok::kw___uptr:
5998 case tok::kw___ptr64:
5999 case tok::kw___ptr32:
6000 case tok::kw___forceinline:
6001 case tok::kw___pascal:
6002 case tok::kw___unaligned:
6003 case tok::kw___ptrauth:
6005 case tok::kw__Nonnull:
6006 case tok::kw__Nullable:
6007 case tok::kw__Nullable_result:
6008 case tok::kw__Null_unspecified:
6010 case tok::kw___kindof:
6012 case tok::kw___private:
6013 case tok::kw___local:
6014 case tok::kw___global:
6015 case tok::kw___constant:
6016 case tok::kw___generic:
6017 case tok::kw___read_only:
6018 case tok::kw___read_write:
6019 case tok::kw___write_only:
6020#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
6021#include "clang/Basic/OpenCLImageTypes.def"
6022#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:
6023#include "clang/Basic/HLSLIntangibleTypes.def"
6025 case tok::kw___funcref:
6026 case tok::kw_groupshared:
6029 case tok::kw_private:
6034bool Parser::isConstructorDeclarator(
bool IsUnqualified,
bool DeductionGuide,
6036 const ParsedTemplateInfo *TemplateInfo) {
6037 RevertingTentativeParsingAction TPA(*
this);
6040 if (TemplateInfo && TemplateInfo->TemplateParams)
6043 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6050 if (Tok.is(tok::identifier)) {
6054 }
else if (Tok.is(tok::annot_template_id)) {
6055 ConsumeAnnotationToken();
6062 SkipCXX11Attributes();
6065 if (Tok.isNot(tok::l_paren)) {
6072 if (Tok.is(tok::r_paren) ||
6073 (Tok.is(tok::ellipsis) &&
NextToken().
is(tok::r_paren))) {
6079 if (isCXX11AttributeSpecifier(
false,
6086 DeclaratorScopeObj DeclScopeObj(*
this, SS);
6088 DeclScopeObj.EnterDeclaratorScope();
6091 ParsedAttributes Attrs(AttrFactory);
6092 MaybeParseMicrosoftAttributes(Attrs);
6101 bool IsConstructor =
false;
6107 if (Tok.is(tok::kw_this)) {
6109 return isDeclarationSpecifier(ITC);
6112 if (isDeclarationSpecifier(ITC))
6113 IsConstructor =
true;
6114 else if (Tok.is(tok::identifier) ||
6115 (Tok.is(tok::annot_cxxscope) &&
NextToken().
is(tok::identifier))) {
6120 if (Tok.is(tok::annot_cxxscope))
6121 ConsumeAnnotationToken();
6127 switch (Tok.getKind()) {
6133 case tok::coloncolon:
6146 SkipCXX11Attributes();
6148 if (DeductionGuide) {
6150 IsConstructor = Tok.is(tok::arrow);
6153 if (Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
6157 IsConstructor =
true;
6159 if (Tok.is(tok::semi) || Tok.is(tok::l_brace)) {
6172 IsConstructor = IsUnqualified;
6177 IsConstructor =
true;
6181 return IsConstructor;
6184void Parser::ParseTypeQualifierListOpt(
6185 DeclSpec &DS,
unsigned AttrReqs,
bool AtomicOrPtrauthAllowed,
6187 if ((AttrReqs & AR_CXX11AttributesParsed) &&
6188 isAllowedCXX11AttributeSpecifier()) {
6189 ParsedAttributes Attrs(AttrFactory);
6190 ParseCXX11Attributes(Attrs);
6194 SourceLocation EndLoc;
6198 const char *PrevSpec =
nullptr;
6199 unsigned DiagID = 0;
6200 SourceLocation Loc = Tok.getLocation();
6202 switch (Tok.getKind()) {
6203 case tok::code_completion:
6205 if (CodeCompletionHandler)
6206 CodeCompletionHandler();
6208 Actions.CodeCompletion().CodeCompleteTypeQualifiers(DS);
6215 case tok::kw_volatile:
6219 case tok::kw_restrict:
6223 case tok::kw___ob_wrap:
6225 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6230 OverflowBehaviorType::OverflowBehaviorKind::Wrap, Loc, PrevSpec,
6233 case tok::kw___ob_trap:
6235 Diag(Loc, diag::warn_overflow_behavior_keyword_disabled)
6240 OverflowBehaviorType::OverflowBehaviorKind::Trap, Loc, PrevSpec,
6243 case tok::kw__Atomic:
6244 if (!AtomicOrPtrauthAllowed)
6245 goto DoneWithTypeQuals;
6246 diagnoseUseOfC11Keyword(Tok);
6252 case tok::kw_private:
6254 goto DoneWithTypeQuals;
6256 case tok::kw___private:
6257 case tok::kw___global:
6258 case tok::kw___local:
6259 case tok::kw___constant:
6260 case tok::kw___generic:
6261 case tok::kw___read_only:
6262 case tok::kw___write_only:
6263 case tok::kw___read_write:
6267 case tok::kw_groupshared:
6276 case tok::kw___ptrauth:
6277 if (!AtomicOrPtrauthAllowed)
6278 goto DoneWithTypeQuals;
6280 EndLoc = PrevTokLocation;
6283 case tok::kw___unaligned:
6287 case tok::kw___uptr:
6292 if (TryKeywordIdentFallback(
false))
6296 case tok::kw___sptr:
6298 case tok::kw___ptr64:
6299 case tok::kw___ptr32:
6300 case tok::kw___cdecl:
6301 case tok::kw___stdcall:
6302 case tok::kw___fastcall:
6303 case tok::kw___thiscall:
6304 case tok::kw___regcall:
6305 case tok::kw___vectorcall:
6306 if (AttrReqs & AR_DeclspecAttributesParsed) {
6310 goto DoneWithTypeQuals;
6312 case tok::kw___funcref:
6316 case tok::kw___pascal:
6317 if (AttrReqs & AR_VendorAttributesParsed) {
6321 goto DoneWithTypeQuals;
6324 case tok::kw__Nonnull:
6325 case tok::kw__Nullable:
6326 case tok::kw__Nullable_result:
6327 case tok::kw__Null_unspecified:
6332 case tok::kw___kindof:
6334 AttributeScopeInfo(),
nullptr, 0,
6339 case tok::kw___attribute:
6340 if (AttrReqs & AR_GNUAttributesParsedAndRejected)
6342 Diag(Tok, diag::err_attributes_not_allowed);
6346 if (AttrReqs & AR_GNUAttributesParsed ||
6347 AttrReqs & AR_GNUAttributesParsedAndRejected) {
6357 DS.
Finish(Actions, Actions.getASTContext().getPrintingPolicy());
6365 assert(PrevSpec &&
"Method did not return previous specifier!");
6366 Diag(Tok, DiagID) << PrevSpec;
6375 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6376 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
6382 if (Kind == tok::star || Kind == tok::caret)
6386 if (Kind == tok::kw_pipe && Lang.OpenCL &&
6387 Lang.getOpenCLCompatibleVersion() >= 200)
6390 if (!Lang.CPlusPlus)
6393 if (Kind == tok::amp)
6401 if (Kind == tok::ampamp)
6412 for (
unsigned Idx = 0; Idx != NumTypes; ++Idx)
6419void Parser::ParseDeclaratorInternal(
Declarator &D,
6420 DirectDeclParseFunction DirectDeclParser) {
6421 if (Diags.hasAllExtensionsSilenced())
6428 (Tok.is(tok::coloncolon) || Tok.is(tok::kw_decltype) ||
6429 (Tok.is(tok::identifier) &&
6431 Tok.is(tok::annot_cxxscope))) {
6432 TentativeParsingAction TPA(*
this,
true);
6438 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6450 Tok.is(tok::star)) {
6454 checkCompoundToken(SS.
getEndLoc(), tok::coloncolon,
6455 CompoundToken::MemberPtr);
6460 DeclSpec DS(AttrFactory);
6461 ParseTypeQualifierListOpt(DS);
6465 Actions.runWithSufficientStackSpace(D.
getBeginLoc(), [&] {
6466 ParseDeclaratorInternal(D, DirectDeclParser);
6480 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
6490 AnnotateScopeToken(SS,
true);
6492 if (DirectDeclParser)
6493 (this->*DirectDeclParser)(D);
6501 DeclSpec DS(AttrFactory);
6502 ParseTypeQualifierListOpt(DS);
6511 if (DirectDeclParser)
6512 (this->*DirectDeclParser)(D);
6521 if (Kind == tok::star || Kind == tok::caret) {
6523 DeclSpec DS(AttrFactory);
6527 unsigned Reqs = AR_CXX11AttributesParsed | AR_DeclspecAttributesParsed |
6529 ? AR_GNUAttributesParsed
6530 : AR_GNUAttributesParsedAndRejected);
6531 ParseTypeQualifierListOpt(DS, Reqs,
true,
6536 Actions.runWithSufficientStackSpace(
6537 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6538 if (Kind == tok::star)
6553 DeclSpec DS(AttrFactory);
6557 if (Kind == tok::ampamp)
6559 diag::warn_cxx98_compat_rvalue_reference :
6560 diag::ext_rvalue_reference);
6563 ParseTypeQualifierListOpt(DS);
6572 diag::err_invalid_reference_qualifier_application) <<
"const";
6575 diag::err_invalid_reference_qualifier_application) <<
"volatile";
6579 diag::err_invalid_reference_qualifier_application) <<
"_Atomic";
6583 Actions.runWithSufficientStackSpace(
6584 D.
getBeginLoc(), [&] { ParseDeclaratorInternal(D, DirectDeclParser); });
6591 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6594 Diag(InnerChunk.
Loc, diag::err_illegal_decl_reference_to_reference)
6623void Parser::ParseDirectDeclarator(
Declarator &D) {
6630 return ParseDecompositionDeclarator(D);
6644 ParseOptionalCXXScopeSpecifier(
6646 false, EnteringContext);
6661 if (Actions.ShouldEnterDeclaratorScope(
getCurScope(),
6665 DeclScopeObj.EnterDeclaratorScope();
6672 goto PastIdentifier;
6688 !Actions.containsUnexpandedParameterPacks(D) &&
6696 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
6706 if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::annot_template_id,
6710 bool AllowConstructorName;
6711 bool AllowDeductionGuide;
6713 AllowConstructorName =
false;
6714 AllowDeductionGuide =
false;
6718 AllowDeductionGuide =
false;
6726 SourceLocation TemplateKWLoc;
6731 true, AllowConstructorName,
6732 AllowDeductionGuide, &TemplateKWLoc,
6745 DeclScopeObj.EnterDeclaratorScope();
6752 goto PastIdentifier;
6758 diag::err_expected_unqualified_id)
6761 goto PastIdentifier;
6765 "There's a C++-specific check for tok::identifier above");
6766 assert(Tok.getIdentifierInfo() &&
"Not an identifier?");
6767 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6770 goto PastIdentifier;
6775 bool DiagnoseIdentifier =
false;
6779 DiagnoseIdentifier =
true;
6782 DiagnoseIdentifier =
6790 !isCXX11VirtSpecifier(Tok))
6792 tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
6793 if (DiagnoseIdentifier) {
6794 Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
6798 goto PastIdentifier;
6802 if (Tok.is(tok::l_paren)) {
6807 RevertingTentativeParsingAction PA(*
this);
6812 goto PastIdentifier;
6819 ParseParenDeclarator(D);
6832 DeclScopeObj.EnterDeclaratorScope();
6843 diag::ext_abstract_pack_declarator_parens);
6845 if (Tok.getKind() == tok::annot_pragma_parser_crash)
6847 if (Tok.is(tok::l_square))
6848 return ParseMisplacedBracketDeclarator(D);
6853 !Tok.isAnnotation() && Tok.getIdentifierInfo() &&
6854 Tok.getIdentifierInfo()->isCPlusPlusKeyword(
getLangOpts())) {
6856 diag::err_expected_member_name_or_semi_objcxx_keyword)
6857 << Tok.getIdentifierInfo()
6860 D.
SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
6863 goto PastIdentifier;
6866 diag::err_expected_member_name_or_semi)
6870 if (Tok.getKind() == tok::TokenKind::kw_while) {
6871 Diag(Tok, diag::err_while_loop_outside_of_a_function);
6873 if (Tok.isOneOf(tok::period, tok::arrow))
6874 Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
6877 if (Tok.isAtStartOfLine() && Loc.
isValid())
6878 Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
6882 diag::err_expected_unqualified_id)
6887 diag::err_expected_either)
6888 << tok::identifier << tok::l_paren;
6897 "Haven't past the location of the identifier yet?");
6901 MaybeParseCXX11Attributes(D);
6904 if (Tok.is(tok::l_paren)) {
6916 bool IsAmbiguous =
false;
6928 AllowImplicitTypename =
6936 TentativelyDeclaredIdentifiers.push_back(D.
getIdentifier());
6937 bool IsFunctionDecl =
6938 isCXXFunctionDeclarator(&IsAmbiguous, AllowImplicitTypename);
6939 TentativelyDeclaredIdentifiers.pop_back();
6940 if (!IsFunctionDecl)
6943 ParsedAttributes attrs(AttrFactory);
6946 if (IsFunctionDeclaration)
6947 Actions.ActOnStartFunctionDeclarationDeclarator(D,
6948 TemplateParameterDepth);
6949 ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
6950 if (IsFunctionDeclaration)
6951 Actions.ActOnFinishFunctionDeclarationDeclarator(D);
6952 PrototypeScope.Exit();
6953 }
else if (Tok.is(tok::l_square)) {
6954 ParseBracketDeclarator(D);
6955 }
else if (Tok.isRegularKeywordAttribute()) {
6957 Diag(Tok, diag::err_keyword_not_allowed) << Tok.getIdentifierInfo();
6962 if (!T.consumeOpen())
6973 Diag(Tok, diag::err_requires_clause_inside_parens);
6987void Parser::ParseDecompositionDeclarator(
Declarator &D) {
6988 assert(Tok.is(tok::l_square));
6990 TentativeParsingAction PA(*
this);
6995 DiagnoseAndSkipCXX11Attributes();
6999 if (!(Tok.isOneOf(tok::identifier, tok::ellipsis) &&
7001 tok::identifier, tok::l_square, tok::ellipsis)) &&
7002 !(Tok.is(tok::r_square) &&
7005 return ParseMisplacedBracketDeclarator(D);
7008 SourceLocation PrevEllipsisLoc;
7009 SmallVector<DecompositionDeclarator::Binding, 32>
Bindings;
7010 while (Tok.isNot(tok::r_square)) {
7012 if (Tok.is(tok::comma))
7015 if (Tok.is(tok::identifier)) {
7017 Diag(EndLoc, diag::err_expected)
7020 Diag(Tok, diag::err_expected_comma_or_rsquare);
7023 SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis},
7025 if (Tok.is(tok::comma))
7027 else if (Tok.is(tok::r_square))
7032 if (isCXX11AttributeSpecifier() !=
7034 DiagnoseAndSkipCXX11Attributes();
7036 SourceLocation EllipsisLoc;
7038 if (Tok.is(tok::ellipsis)) {
7040 : diag::ext_cxx_binding_pack);
7041 if (PrevEllipsisLoc.
isValid()) {
7042 Diag(Tok, diag::err_binding_multiple_ellipses);
7043 Diag(PrevEllipsisLoc, diag::note_previous_ellipsis);
7046 EllipsisLoc = Tok.getLocation();
7047 PrevEllipsisLoc = EllipsisLoc;
7051 if (Tok.isNot(tok::identifier)) {
7052 Diag(Tok, diag::err_expected) << tok::identifier;
7056 IdentifierInfo *II = Tok.getIdentifierInfo();
7057 SourceLocation Loc = Tok.getLocation();
7060 if (Tok.is(tok::ellipsis) && !PrevEllipsisLoc.
isValid()) {
7061 DiagnoseMisplacedEllipsis(Tok.getLocation(), Loc, EllipsisLoc.
isValid(),
7063 EllipsisLoc = Tok.getLocation();
7067 ParsedAttributes Attrs(AttrFactory);
7068 if (isCXX11AttributeSpecifier() !=
7071 ? diag::warn_cxx23_compat_decl_attrs_on_binding
7072 : diag::ext_decl_attrs_on_binding);
7073 MaybeParseCXX11Attributes(Attrs);
7076 Bindings.push_back({II, Loc, std::move(Attrs), EllipsisLoc});
7079 if (Tok.isNot(tok::r_square))
7086 Diag(Tok.getLocation(), diag::ext_decomp_decl_empty);
7094 T.getCloseLocation());
7097void Parser::ParseParenDeclarator(
Declarator &D) {
7101 assert(!D.
isPastIdentifier() &&
"Should be called before passing identifier");
7113 ParsedAttributes attrs(AttrFactory);
7114 bool RequiresArg =
false;
7115 if (Tok.is(tok::kw___attribute)) {
7116 ParseGNUAttributes(attrs);
7124 ParseMicrosoftTypeAttributes(attrs);
7127 if (Tok.is(tok::kw___pascal))
7128 ParseBorlandTypeAttributes(attrs);
7140 }
else if (Tok.is(tok::r_paren) ||
7142 Tok.is(tok::ellipsis) &&
7144 isDeclarationSpecifier(
7146 isCXX11AttributeSpecifier() !=
7166 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7171 std::move(attrs), T.getCloseLocation());
7177 DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
7195 ParseFunctionDeclarator(D, attrs, T,
false, RequiresArg);
7196 PrototypeScope.Exit();
7199void Parser::InitCXXThisScopeForDeclaratorIfRelevant(
7201 std::optional<Sema::CXXThisScopeRAII> &ThisScope) {
7209 bool IsCXX11MemberFunction =
7216 Actions.CurContext->isRecord());
7217 if (!IsCXX11MemberFunction)
7237 ThisScope.emplace(Actions, dyn_cast<CXXRecordDecl>(Actions.CurContext), Q,
7238 IsCXX11MemberFunction);
7241void Parser::ParseFunctionDeclarator(
Declarator &D,
7246 assert(
getCurScope()->isFunctionPrototypeScope() &&
7247 "Should call from a Function scope");
7253 bool HasProto =
false;
7255 SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
7257 SourceLocation EllipsisLoc;
7259 DeclSpec DS(AttrFactory);
7260 bool RefQualifierIsLValueRef =
true;
7261 SourceLocation RefQualifierLoc;
7263 SourceRange ESpecRange;
7264 SmallVector<ParsedType, 2> DynamicExceptions;
7265 SmallVector<SourceRange, 2> DynamicExceptionRanges;
7268 ParsedAttributes FnAttrs(AttrFactory);
7270 SourceLocation TrailingReturnTypeLoc;
7275 SourceLocation StartLoc, LocalEndLoc, EndLoc;
7276 SourceLocation LParenLoc, RParenLoc;
7278 StartLoc = LParenLoc;
7280 if (isFunctionDeclaratorIdentifierList()) {
7282 Diag(Tok, diag::err_argument_required_after_attribute);
7284 ParseFunctionDeclaratorIdentifierList(D, ParamInfo);
7288 LocalEndLoc = RParenLoc;
7293 MaybeParseCXX11Attributes(FnAttrs);
7294 ProhibitAttributes(FnAttrs);
7296 if (Tok.isNot(tok::r_paren))
7297 ParseParameterDeclarationClause(D, FirstArgAttrs, ParamInfo, EllipsisLoc);
7298 else if (RequiresArg)
7299 Diag(Tok, diag::err_argument_required_after_attribute);
7310 LocalEndLoc = RParenLoc;
7319 ParseTypeQualifierListOpt(
7320 DS, AR_NoAttributesParsed,
7323 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D);
7330 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc))
7331 EndLoc = RefQualifierLoc;
7333 std::optional<Sema::CXXThisScopeRAII> ThisScope;
7334 InitCXXThisScopeForDeclaratorIfRelevant(D, DS, ThisScope);
7351 if (Delayed && Actions.isLibstdcxxEagerExceptionSpecHack(D) &&
7368 ESpecType = tryParseExceptionSpecification(Delayed,
7371 DynamicExceptionRanges,
7373 ExceptionSpecTokens);
7375 EndLoc = ESpecRange.
getEnd();
7379 MaybeParseCXX11Attributes(FnAttrs);
7382 LocalEndLoc = EndLoc;
7384 Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
7387 LocalEndLoc = Tok.getLocation();
7389 TrailingReturnType =
7391 TrailingReturnTypeLoc =
Range.getBegin();
7392 EndLoc =
Range.getEnd();
7395 MaybeParseCXX11Attributes(FnAttrs);
7403 SmallVector<NamedDecl *, 0> DeclsInPrototype;
7406 NamedDecl *ND = dyn_cast<NamedDecl>(D);
7409 DeclsInPrototype.push_back(ND);
7416 llvm::sort(DeclsInPrototype, [](Decl *D1, Decl *D2) {
7424 HasProto, IsAmbiguous, LParenLoc, ParamInfo.data(),
7425 ParamInfo.size(), EllipsisLoc, RParenLoc,
7426 RefQualifierIsLValueRef, RefQualifierLoc,
7428 ESpecType, ESpecRange, DynamicExceptions.data(),
7429 DynamicExceptionRanges.data(), DynamicExceptions.size(),
7430 NoexceptExpr.
isUsable() ? NoexceptExpr.
get() :
nullptr,
7431 ExceptionSpecTokens, DeclsInPrototype, StartLoc,
7432 LocalEndLoc, D, TrailingReturnType, TrailingReturnTypeLoc,
7434 std::move(FnAttrs), EndLoc);
7437bool Parser::ParseRefQualifier(
bool &RefQualifierIsLValueRef,
7439 if (Tok.isOneOf(tok::amp, tok::ampamp)) {
7441 diag::warn_cxx98_compat_ref_qualifier :
7442 diag::ext_ref_qualifier);
7444 RefQualifierIsLValueRef = Tok.is(tok::amp);
7451bool Parser::isFunctionDeclaratorIdentifierList() {
7453 && Tok.is(tok::identifier)
7454 && !TryAltiVecVectorToken()
7470 && (!Tok.is(tok::eof) &&
7474void Parser::ParseFunctionDeclaratorIdentifierList(
7478 assert(!
getLangOpts().requiresStrictPrototypes() &&
7479 "Cannot parse an identifier list in C23 or C++");
7486 Diag(Tok, diag::ext_ident_list_in_param);
7489 llvm::SmallPtrSet<const IdentifierInfo *, 16> ParamsSoFar;
7493 if (Tok.isNot(tok::identifier)) {
7494 Diag(Tok, diag::err_expected) << tok::identifier;
7501 IdentifierInfo *ParmII = Tok.getIdentifierInfo();
7504 if (Actions.getTypeName(*ParmII, Tok.getLocation(),
getCurScope()))
7505 Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII;
7508 if (!ParamsSoFar.insert(ParmII).second) {
7509 Diag(Tok, diag::err_param_redefinition) << ParmII;
7512 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7523void Parser::ParseParameterDeclarationClause(
7532 if (
getCurScope()->getFunctionPrototypeDepth() - 1 >
7534 Diag(Tok.getLocation(), diag::err_function_scope_depth_exceeded)
7553 IsACXXFunctionDeclaration) {
7565 DeclSpec DS(AttrFactory);
7567 ParsedAttributes ArgDeclAttrs(AttrFactory);
7568 ParsedAttributes ArgDeclSpecAttrs(AttrFactory);
7575 ArgDeclSpecAttrs.takeAllPrependingFrom(FirstArgAttrs);
7578 MaybeParseCXX11Attributes(ArgDeclAttrs);
7581 MaybeParseMicrosoftAttributes(ArgDeclSpecAttrs);
7584 SourceLocation DSStart = Tok.getLocation();
7588 SourceLocation ThisLoc;
7592 ParsedTemplateInfo TemplateInfo;
7593 ParseDeclarationSpecifiers(DS, TemplateInfo,
AS_none,
7594 DeclSpecContext::DSC_normal,
7595 nullptr, AllowImplicitTypename);
7608 ParseDeclarator(ParmDeclarator);
7611 ParmDeclarator.SetRangeBegin(ThisLoc);
7614 MaybeParseGNUAttributes(ParmDeclarator);
7618 if (Tok.is(tok::kw_requires)) {
7623 diag::err_requires_clause_on_declarator_not_declaring_a_function);
7629 const IdentifierInfo *ParmII = ParmDeclarator.getIdentifier();
7633 std::unique_ptr<CachedTokens> DefArgToks;
7637 if (DS.
isEmpty() && ParmDeclarator.getIdentifier() ==
nullptr &&
7638 ParmDeclarator.getNumTypeObjects() == 0) {
7640 Diag(DSStart, diag::err_missing_param);
7647 if (Tok.is(tok::ellipsis) &&
7649 (!ParmDeclarator.getEllipsisLoc().isValid() &&
7650 !Actions.isUnexpandedParameterPackPermitted())) &&
7651 Actions.containsUnexpandedParameterPacks(ParmDeclarator))
7652 DiagnoseMisplacedEllipsisInDeclarator(
ConsumeToken(), ParmDeclarator);
7671 if (!ParmDeclarator.isInvalidType() && !ParmDeclarator.hasName() &&
7672 Tok.isNot(tok::raw_identifier) && !Tok.isAnnotation() &&
7673 Tok.getIdentifierInfo() &&
7674 Tok.getIdentifierInfo()->isKeyword(
getLangOpts())) {
7675 Diag(Tok, diag::err_keyword_as_parameter) << PP.getSpelling(Tok);
7684 Diag(ParmDeclarator.getBeginLoc(),
7685 diag::err_function_parameter_limit_exceeded);
7693 Actions.ActOnParamDeclarator(
getCurScope(), ParmDeclarator, ThisLoc);
7698 if (Tok.is(tok::equal)) {
7699 SourceLocation EqualLoc = Tok.getLocation();
7709 ConsumeAndStoreInitializer(*DefArgToks,
7711 Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc,
7719 EnterExpressionEvaluationContext Eval(
7726 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
7727 DefArgResult = ParseBraceInitializer();
7729 if (Tok.is(tok::l_paren) &&
NextToken().
is(tok::l_brace)) {
7730 Diag(Tok, diag::err_stmt_expr_in_default_arg) << 0;
7731 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7740 Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
7745 Actions.ActOnParamDefaultArgument(Param, EqualLoc,
7746 DefArgResult.
get());
7751 ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
7752 ParmDeclarator.getIdentifierLoc(),
7753 Param, std::move(DefArgToks)));
7761 Diag(EllipsisLoc, diag::warn_deprecated_missing_comma_before_ellipsis)
7768 Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
7770 }
else if (ParmDeclarator.getEllipsisLoc().isValid() ||
7771 Actions.containsUnexpandedParameterPacks(ParmDeclarator)) {
7774 SourceLocation ParmEllipsis = ParmDeclarator.getEllipsisLoc();
7775 Diag(EllipsisLoc, diag::warn_misplaced_ellipsis_vararg)
7776 << ParmEllipsis.
isValid() << ParmEllipsis;
7779 diag::note_misplaced_ellipsis_vararg_existing_ellipsis);
7781 Diag(ParmDeclarator.getIdentifierLoc(),
7782 diag::note_misplaced_ellipsis_vararg_add_ellipsis)
7785 << !ParmDeclarator.hasName();
7787 Diag(EllipsisLoc, diag::note_misplaced_ellipsis_vararg_add_comma)
7799void Parser::ParseBracketDeclarator(
Declarator &D) {
7800 if (CheckProhibitedCXX11Attribute())
7808 if (Tok.getKind() == tok::r_square) {
7810 ParsedAttributes attrs(AttrFactory);
7811 MaybeParseCXX11Attributes(attrs);
7815 T.getOpenLocation(),
7816 T.getCloseLocation()),
7817 std::move(attrs), T.getCloseLocation());
7819 }
else if (Tok.getKind() == tok::numeric_constant &&
7826 ParsedAttributes attrs(AttrFactory);
7827 MaybeParseCXX11Attributes(attrs);
7831 T.getOpenLocation(),
7832 T.getCloseLocation()),
7833 std::move(attrs), T.getCloseLocation());
7835 }
else if (Tok.getKind() == tok::code_completion) {
7837 Actions.CodeCompletion().CodeCompleteBracketDeclarator(
getCurScope());
7842 SourceLocation StaticLoc;
7847 DeclSpec DS(AttrFactory);
7848 ParseTypeQualifierListOpt(DS, AR_CXX11AttributesParsed);
7856 bool isStar =
false;
7867 Diag(StaticLoc, diag::err_unspecified_vla_size_with_static);
7868 StaticLoc = SourceLocation();
7871 }
else if (Tok.isNot(tok::r_square)) {
7888 Diag(StaticLoc, diag::err_unspecified_size_with_static);
7889 StaticLoc = SourceLocation();
7908 isStar, NumElements.
get(), T.getOpenLocation(),
7909 T.getCloseLocation()),
7913void Parser::ParseMisplacedBracketDeclarator(
Declarator &D) {
7914 assert(Tok.is(tok::l_square) &&
"Missing opening bracket");
7917 SourceLocation StartBracketLoc = Tok.getLocation();
7921 while (Tok.is(tok::l_square)) {
7922 ParseBracketDeclarator(TempDeclarator);
7928 if (Tok.is(tok::semi))
7931 SourceLocation SuggestParenLoc = Tok.getLocation();
7934 ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
7939 if (TempDeclarator.getNumTypeObjects() == 0)
7943 bool NeedParens =
false;
7962 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
7968 for (
unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
7969 const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
7970 D.
AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());
7975 if (!D.
hasName() && !NeedParens)
7978 SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();
7981 SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
7982 SourceLocation EndLoc = PP.getLocForEndOfToken(D.
getEndLoc());
7985 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7990 EndLoc, CharSourceRange(BracketRange,
true))
7993 Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
7996 EndLoc, CharSourceRange(BracketRange,
true))
8001void Parser::ParseTypeofSpecifier(
DeclSpec &DS) {
8002 assert(Tok.isOneOf(tok::kw_typeof, tok::kw_typeof_unqual) &&
8003 "Not a typeof specifier");
8005 bool IsUnqual = Tok.is(tok::kw_typeof_unqual);
8006 const IdentifierInfo *II = Tok.getIdentifierInfo();
8008 Diag(Tok.getLocation(), diag::warn_c23_compat_keyword) << Tok.getName();
8012 bool HasParens = Tok.is(tok::l_paren);
8020 SourceRange CastRange;
8022 ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange);
8038 const char *PrevSpec =
nullptr;
8045 Actions.getASTContext().getPrintingPolicy()))
8046 Diag(StartLoc, DiagID) << PrevSpec;
8057 Operand = Actions.HandleExprEvaluationContextForTypeof(
Operand.get());
8063 const char *PrevSpec =
nullptr;
8070 Actions.getASTContext().getPrintingPolicy()))
8071 Diag(StartLoc, DiagID) << PrevSpec;
8074void Parser::ParseAtomicSpecifier(
DeclSpec &DS) {
8075 assert(Tok.is(tok::kw__Atomic) &&
NextToken().
is(tok::l_paren) &&
8076 "Not an atomic specifier");
8080 if (T.consumeOpen())
8084 if (
Result.isInvalid()) {
8092 if (T.getCloseLocation().isInvalid())
8098 const char *PrevSpec =
nullptr;
8102 Actions.getASTContext().getPrintingPolicy()))
8103 Diag(StartLoc, DiagID) << PrevSpec;
8106bool Parser::TryAltiVecVectorTokenOutOfLine() {
8108 switch (
Next.getKind()) {
8109 default:
return false;
8112 case tok::kw_signed:
8113 case tok::kw_unsigned:
8118 case tok::kw_double:
8121 case tok::kw___bool:
8122 case tok::kw___pixel:
8123 Tok.setKind(tok::kw___vector);
8125 case tok::identifier:
8126 if (
Next.getIdentifierInfo() == Ident_pixel) {
8127 Tok.setKind(tok::kw___vector);
8130 if (
Next.getIdentifierInfo() == Ident_bool ||
8131 Next.getIdentifierInfo() == Ident_Bool) {
8132 Tok.setKind(tok::kw___vector);
8140 const char *&PrevSpec,
unsigned &DiagID,
8142 const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
8143 if (Tok.getIdentifierInfo() == Ident_vector) {
8145 switch (
Next.getKind()) {
8148 case tok::kw_signed:
8149 case tok::kw_unsigned:
8154 case tok::kw_double:
8157 case tok::kw___bool:
8158 case tok::kw___pixel:
8161 case tok::identifier:
8162 if (
Next.getIdentifierInfo() == Ident_pixel) {
8166 if (
Next.getIdentifierInfo() == Ident_bool ||
8167 Next.getIdentifierInfo() == Ident_Bool) {
8176 }
else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
8180 }
else if ((Tok.getIdentifierInfo() == Ident_bool) &&
8188TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
8191 SmallVector<Token, 4> Tokens;
8194 auto &SourceMgr = PP.getSourceManager();
8195 FileID FID = SourceMgr.createFileID(
8196 llvm::MemoryBuffer::getMemBufferCopy(TypeStr, Context),
SrcMgr::C_User,
8200 Lexer L(FID, SourceMgr.getBufferOrFake(FID), PP);
8201 L.setParsingPreprocessorDirective(
true);
8207 Tokens.push_back(Tok);
8208 }
while (Tok.isNot(tok::eod));
8213 Token &EndToken = Tokens.back();
8220 Tokens.push_back(Tok);
8223 PP.EnterTokenStream(Tokens,
false,
8238 (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {
8239 Diag(Tok.getLocation(), diag::err_type_unparsed);
8244 while (Tok.isNot(tok::eof))
8248 if (Tok.is(tok::eof) && Tok.getEofData() == TypeStr.data())
8253void Parser::DiagnoseBitIntUse(
const Token &
Tok) {
8257 assert(Tok.isOneOf(tok::kw__ExtInt, tok::kw__BitInt) &&
8258 "expected either an _ExtInt or _BitInt token!");
8260 SourceLocation Loc = Tok.getLocation();
8261 if (Tok.is(tok::kw__ExtInt)) {
8262 Diag(Loc, diag::warn_ext_int_deprecated)
8268 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 StringRef getTriple(const Command &Job)
static bool IsAttributeLateParsedExperimentalExt(const IdentifierInfo &II)
returns true iff attribute is annotated with LateAttrParseExperimentalExt in Attr....
static bool FindLocsWithCommonFileID(Preprocessor &PP, SourceLocation StartLoc, SourceLocation EndLoc)
Check if the a start and end source location expand to the same macro.
static bool IsAttributeLateParsedStandard(const IdentifierInfo &II)
returns true iff attribute is annotated with LateAttrParseStandard in Attr.td.
static ParsedAttributeArgumentsProperties attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has string arguments.
static bool attributeHasStrictIdentifierArgs(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute takes a strict identifier argument.
static bool attributeIsTypeArgAttr(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute parses a type argument.
static bool attributeTreatsKeywordThisAsIdentifier(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute treats kw_this as an identifier.
static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute requires parsing its arguments in an unevaluated context or not...
static bool attributeHasIdentifierArg(const llvm::Triple &T, const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has an identifier argument.
static bool isValidAfterIdentifierInDeclarator(const Token &T)
isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the specified token is valid after t...
static bool attributeHasVariadicIdentifierArg(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine whether the given attribute has a variadic identifier argument.
static bool isPipeDeclarator(const Declarator &D)
static SourceLocation getMissingDeclaratorIdLoc(Declarator &D, SourceLocation Loc)
static bool attributeAcceptsExprPack(const IdentifierInfo &II, ParsedAttr::Syntax Syntax, IdentifierInfo *ScopeName)
Determine if an attribute accepts parameter packs.
static void DiagnoseCountAttributedTypeInUnnamedAnon(ParsingDeclSpec &DS, Parser &P)
static bool VersionNumberSeparator(const char Separator)
static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, DeclaratorContext TheContext)
llvm::SmallVector< std::pair< const MemRegion *, SVal >, 4 > Bindings
static constexpr bool isOneOf()
This file declares semantic analysis for CUDA constructs.
This file declares facilities that support code completion.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenMP constructs and clauses.
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the clang::TokenKind enum and support functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Syntax
The style used to specify an attribute.
@ AS_Declspec
__declspec(...)
Kind getParsedKind() const
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
SourceLocation getOpenLocation() const
SourceLocation getCloseLocation() const
Represents a C++ nested-name-specifier or a global scope specifier.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
SourceLocation getEndLoc() const
bool isSet() const
Deprecated.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
void setTemplateParamLists(ArrayRef< TemplateParameterList * > L)
bool isEmpty() const
No scope specifier.
SourceLocation getBegin() const
Callback handler that receives notifications when performing code completion within the preprocessor.
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Captures information about "declaration specifiers".
bool isVirtualSpecified() const
bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, ExplicitSpecifier ExplicitSpec, SourceLocation CloseParenLoc)
bool isTypeSpecPipe() const
static const TSCS TSCS___thread
static const TST TST_typeof_unqualType
void setTypeArgumentRange(SourceRange range)
bool SetTypePipe(bool isPipe, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
SourceLocation getPipeLoc() const
static const TST TST_typename
SourceLocation getEndLoc() const LLVM_READONLY
bool hasTypeSpecifier() const
Return true if any type-specifier has been found.
bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec and return false if there was no error.
static const TST TST_char8
static const TST TST_BFloat16
void ClearStorageClassSpecs()
bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TSCS TSCS__Thread_local
bool SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec, but return true and ignore the request if ...
bool isNoreturnSpecified() const
TST getTypeSpecType() const
SourceLocation getStorageClassSpecLoc() const
SCS getStorageClassSpec() const
bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getOverflowBehaviorLoc() const
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceRange getSourceRange() const LLVM_READONLY
bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void SetRangeEnd(SourceLocation Loc)
bool SetBitIntType(SourceLocation KWLoc, Expr *BitWidth, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
static const TST TST_auto_type
static const TST TST_interface
static const TST TST_double
static const TST TST_typeofExpr
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
void SetRangeStart(SourceLocation Loc)
bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getNoreturnSpecLoc() const
static const TST TST_union
static const TST TST_char
static const TST TST_bool
static const TST TST_char16
SourceLocation getExplicitSpecLoc() const
SourceLocation getFriendSpecLoc() const
SourceLocation getModulePrivateSpecLoc() const
bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
void UpdateTypeRep(ParsedType Rep)
TSCS getThreadStorageClassSpec() const
bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasAttributes() const
static const TST TST_accum
static const TST TST_half
ParsedAttributes & getAttributes()
bool SetOverflowBehavior(OverflowBehaviorType::OverflowBehaviorKind Kind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
SourceLocation getConstSpecLoc() const
static const TST TST_ibm128
void addAttributes(const ParsedAttributesView &AL)
Concatenates two attribute lists.
static const TST TST_enum
bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
bool isWrapSpecified() const
static const TST TST_float128
void takeAttributesAppendingingFrom(ParsedAttributes &attrs)
void Finish(Sema &S, const PrintingPolicy &Policy)
Finish - This does final analysis of the declspec, issuing diagnostics for things like "_Complex" (la...
bool isInlineSpecified() const
SourceLocation getRestrictSpecLoc() const
static const TST TST_typeof_unqualExpr
static const TST TST_class
bool hasTagDefinition() const
static const TST TST_decimal64
unsigned getParsedSpecifiers() const
Return a bitmask of which flavors of specifiers this DeclSpec includes.
void ClearFunctionSpecs()
bool SetTypeQual(TQ T, SourceLocation Loc)
static const TST TST_wchar
static const TST TST_void
bool isTypeAltiVecVector() const
void ClearConstexprSpec()
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
static const TST TST_float
static const TST TST_atomic
static const TST TST_fract
SourceLocation getThreadStorageClassSpecLoc() const
Decl * getRepAsDecl() const
static const TST TST_float16
static const TST TST_unspecified
SourceLocation getAtomicSpecLoc() const
SourceLocation getVirtualSpecLoc() const
SourceLocation getConstexprSpecLoc() const
CXXScopeSpec & getTypeSpecScope()
bool isEmpty() const
isEmpty - Return true if this declaration specifier is completely empty: no tokens were parsed in the...
SourceLocation getTypeSpecTypeLoc() const
static const TSCS TSCS_thread_local
bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal32
bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
TypeSpecifierWidth getTypeSpecWidth() const
static const TST TST_char32
bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_decimal128
bool isTypeSpecOwned() const
SourceLocation getInlineSpecLoc() const
SourceLocation getUnalignedSpecLoc() const
static const TST TST_int128
SourceLocation getVolatileSpecLoc() const
FriendSpecified isFriendSpecified() const
bool hasExplicitSpecifier() const
bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
bool hasConstexprSpecifier() const
static const TST TST_typeofType
bool SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
static const TST TST_auto
@ PQ_StorageClassSpecifier
ConstexprSpecKind getConstexprSpecifier() const
static const TST TST_struct
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
Information about one declarator, including the parsed type information and the identifier.
bool isFunctionDeclarator(unsigned &idx) const
isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...
bool isPastIdentifier() const
isPastIdentifier - Return true if we have parsed beyond the point where the name would appear.
void SetRangeBegin(SourceLocation Loc)
SetRangeBegin - Set the start of the source range to Loc, unless it's invalid.
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
void setCommaLoc(SourceLocation CL)
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
SourceLocation getIdentifierLoc() const
void SetIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
bool mayOmitIdentifier() const
mayOmitIdentifier - Return true if the identifier is either optional or not allowed.
SourceLocation getEndLoc() const LLVM_READONLY
bool mayBeFollowedByCXXDirectInit() const
mayBeFollowedByCXXDirectInit - Return true if the declarator can be followed by a C++ direct initiali...
bool hasGroupingParens() const
void setDecompositionBindings(SourceLocation LSquareLoc, MutableArrayRef< DecompositionDeclarator::Binding > Bindings, SourceLocation RSquareLoc)
Set the decomposition bindings for this declarator.
void setInvalidType(bool Val=true)
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
bool mayHaveIdentifier() const
mayHaveIdentifier - Return true if the identifier is either optional or required.
void setGroupingParens(bool flag)
SourceLocation getEllipsisLoc() const
DeclaratorContext getContext() const
SourceLocation getBeginLoc() const LLVM_READONLY
void setTrailingRequiresClause(Expr *TRC)
Sets a trailing requires clause for this declarator.
void setHasInitializer(bool Val=true)
UnqualifiedId & getName()
Retrieve the name specified by this declarator.
void setTemplateParameterLists(ArrayRef< TemplateParameterList * > TPLs)
Sets the template parameter lists that preceded the declarator.
bool isFirstDeclarator() const
bool hasTrailingRequiresClause() const
Determine whether a trailing requires clause was written in this declarator.
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
The template parameter lists that preceded the declarator.
bool isFunctionDeclaratorAFunctionDeclaration() const
Return true if a function declarator at this position would be a function declaration.
void clear()
Reset the contents of this Declarator.
void setAsmLabel(Expr *E)
void AddTypeInfo(const DeclaratorChunk &TI, ParsedAttributes &&attrs, SourceLocation EndLoc)
AddTypeInfo - Add a chunk to this declarator.
void ExtendWithDeclSpec(const DeclSpec &DS)
ExtendWithDeclSpec - Extend the declarator source range to include the given declspec,...
void SetRangeEnd(SourceLocation Loc)
SetRangeEnd - Set the end of the source range to Loc, unless it's invalid.
void setExtension(bool Val=true)
bool isInvalidType() const
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
void setEllipsisLoc(SourceLocation EL)
const IdentifierInfo * getIdentifier() const
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code from FromRange at a specific location.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
tok::TokenKind getTokenID() const
If this is a source-language token (e.g.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
SourceLocation getLoc() const
void setIdentifierInfo(IdentifierInfo *Ident)
IdentifierInfo * getIdentifierInfo() const
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool requiresStrictPrototypes() const
Returns true if functions without prototypes or functions with an identifier list (aka K&R C function...
std::string getOpenCLVersionString() const
Return the OpenCL C or C++ for OpenCL language name and version as a string.
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static bool isAtStartOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroBegin=nullptr)
Returns true if the given MacroID location points at the first token of the macro expansion.
static bool isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroEnd=nullptr)
Returns true if the given MacroID location points at the last token of the macro expansion.
static std::optional< Token > findNextToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeComments=false)
Finds the token that comes right after the given location.
static bool getRawToken(SourceLocation Loc, Token &Result, const SourceManager &SM, const LangOptions &LangOpts, bool IgnoreWhiteSpace=false)
Relex the token at the specified location.
UnresolvedSetImpl::iterator iterator
static constexpr unsigned getMaxFunctionScopeDepth()
ParsedAttr - Represents a syntactic attribute.
unsigned getMaxArgs() const
static const ParsedAttributesView & none()
void prepend(iterator B, iterator E)
void addAtEnd(ParsedAttr *newAttr)
void remove(ParsedAttr *ToBeRemoved)
ParsedAttributes - A collection of parsed attributes.
void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA)
ParsedAttr * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Form formUsed)
Add microsoft __delspec(property) attribute.
ParsedAttr * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ParsedType typeArg, ParsedAttr::Form formUsed, SourceLocation ellipsisLoc=SourceLocation())
Add an attribute with a single type argument.
ParsedAttr * addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, ParsedAttr::Form form)
Add type_tag_for_datatype attribute.
void takeAllAppendingFrom(ParsedAttributes &Other)
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, AttributeScopeInfo scope, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
ParseScope - Introduces a new scope for parsing.
Parser - This implements a parser for the C family of languages.
TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)
ParseTypeName.
bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, bool IsAddressOfOperand=false)
TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...
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...
const Token & getCurToken() const
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.
ExprResult ParseUnevaluatedStringLiteralExpression()
ObjCContainerDecl * getObjCDeclContext() const
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
ExprResult ParseAssignmentExpression(TypoCorrectionTypeBehavior CorrectionBehavior=TypoCorrectionTypeBehavior::AllowNonTypes)
Parse an expr that doesn't include (top-level) commas.
friend class BalancedDelimiterTracker
SmallVector< TemplateParameterList *, 4 > TemplateParameterLists
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
A class for parsing a DeclSpec.
A class for parsing a declarator.
A class for parsing a field declarator.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
SourceManager & getSourceManager() const
const LangOptions & getLangOpts() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
void addAddressSpace(LangAS space)
static Qualifiers fromCVRUMask(unsigned CVRU)
Represents a struct/union/class.
field_range fields() const
bool isClassScope() const
isClassScope - Return true if this scope is a class/struct/union scope.
unsigned getFlags() const
getFlags - Return the flags for this scope.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ BlockScope
This is a scope that corresponds to a block/closure object.
@ FriendScope
This is a scope of friend declaration.
@ ControlScope
The controlling scope in a if/switch/while/for statement.
@ AtCatchScope
This is a scope that corresponds to the Objective-C @catch statement.
@ TemplateParamScope
This is a scope that corresponds to the template parameters of a C++ template.
@ CompoundStmtScope
This is a compound statement scope.
@ ClassScope
The scope of a struct/union/class definition.
@ FunctionDeclarationScope
This is a scope that corresponds to the parameters within a function prototype for a function declara...
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ EnumScope
This scope corresponds to an enum.
@ DeclScope
This is a scope that can contain a declaration.
@ CTCK_InitGlobalVar
Unknown context.
ParserCompletionContext
Describes the context in which code completion occurs.
@ PCC_LocalDeclarationSpecifiers
Code completion occurs within a sequence of declaration specifiers within a function,...
@ PCC_MemberTemplate
Code completion occurs following one or more template headers within a class.
@ PCC_Class
Code completion occurs within a class, struct, or union.
@ PCC_ObjCImplementation
Code completion occurs within an Objective-C implementation or category implementation.
@ PCC_Namespace
Code completion occurs at top-level or namespace context.
@ PCC_Template
Code completion occurs following one or more template headers.
NameClassificationKind getKind() const
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
@ PotentiallyEvaluatedIfUsed
The current expression is potentially evaluated, but any declarations referenced inside that expressi...
void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl)
ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an initializer for the declaratio...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
A RAII object used to temporarily suppress access-like checking.
Represents the declaration of a struct/union/class/enum.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
void setKind(tok::TokenKind K)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
void * getAnnotationValue() const
tok::TokenKind getKind() const
bool isOneOf(Ts... Ks) const
void setEofData(const void *D)
void setLocation(SourceLocation L)
void startToken()
Reset all flags to cleared.
void setSemiMissing(bool Missing=true)
static constexpr int FunctionTypeNumParamsLimit
SourceLocation EndLocation
The location of the last token that describes this unqualified-id.
SourceRange getSourceRange() const LLVM_READONLY
Return the source range that covers this unqualified-id.
SourceLocation StartLocation
The location of the first token that describes this unqualified-id, which will be the location of the...
UnqualifiedIdKind getKind() const
Determine what kind of name we have.
Declaration of a variable template.
static const char * getSpecifierName(Specifier VS)
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
bool InitScope(InterpState &S, CodePtr OpPC, uint32_t I)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
const char * getKeywordSpelling(TokenKind Kind) LLVM_READNONE
Determines the spelling of simple keyword and contextual keyword tokens like 'int' and 'dynamic_cast'...
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
bool isPragmaAnnotation(TokenKind K)
Return true if this is an annotation token representing a pragma.
The JSON file list parser is used to communicate input to InstallAPI.
TypeSpecifierType
Specifies the kind of type.
bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)
bool isa(CodeGen::Address addr)
@ NotAttributeSpecifier
This is not an attribute specifier.
@ AttributeSpecifier
This should be treated as an attribute-specifier.
@ InvalidAttributeSpecifier
The next tokens are '[[', but this is not an attribute-specifier.
@ ExpectedParameterOrImplicitObjectParameter
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
int hasAttribute(AttributeCommonInfo::Syntax Syntax, llvm::StringRef ScopeName, llvm::StringRef AttrName, const TargetInfo &Target, const LangOptions &LangOpts, bool CheckPlugins)
Return the version number associated with the attribute if we recognize and implement the attribute s...
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
@ IK_TemplateId
A template-id, e.g., f<int>.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
ActionResult< Decl * > DeclResult
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
llvm::SmallVector< ArgsUnion, 12U > ArgsVector
Language
The language for the input, used to select and validate the language standard and possible actions.
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
@ Template
We are parsing a template declaration.
@ ExplicitSpecialization
We are parsing an explicit specialization.
@ ExplicitInstantiation
We are parsing an explicit instantiation.
@ NonTemplate
We are not parsing a template at all.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
@ FunctionTemplate
The name was classified as a function template name.
@ Keyword
The name has been typo-corrected to a keyword.
@ DependentNonType
The name denotes a member of a dependent type that could not be resolved.
@ UndeclaredTemplate
The name was classified as an ADL-only function template name.
@ NonType
The name was classified as a specific non-type, non-template declaration.
@ Unknown
This name is not a type or template in this context, but might be something else.
@ Error
Classification failed; an error has been produced.
@ Type
The name was classified as a type.
@ TypeTemplate
The name was classified as a template whose specializations are types.
@ Concept
The name was classified as a concept name.
@ OverloadSet
The name was classified as an overload set, and an expression representing that overload set has been...
@ UndeclaredNonType
The name was classified as an ADL-only function name.
@ VarTemplate
The name was classified as a variable template name.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ TNK_Type_template
The name refers to a template whose specialization produces a type.
@ TNK_Dependent_template_name
The name refers to a dependent template name:
@ TNK_Concept_template
The name refers to a concept.
@ TNK_Undeclared_template
Lookup for the name failed, but we're assuming it was a template name anyway.
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &&Second)
Consumes the attributes from Second and concatenates them at the end of First.
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
ActionResult< Expr * > ExprResult
@ Parens
New-expression has a C++98 paren-delimited initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_None
no exception specification
ActionResult< Stmt * > StmtResult
VersionTuple Version
The version number at which the change occurred.
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
SourceRange VersionRange
The source range covering the version number.
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, SourceLocation AtomicQualLoc, SourceLocation UnalignedQualLoc, SourceLocation OverflowBehaviorLoc={}, bool OverflowBehaviorIsWrap=false)
Return a DeclaratorChunk for a pointer.
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, ArrayRef< NamedDecl * > DeclsInPrototype, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult(), SourceLocation TrailingReturnTypeLoc=SourceLocation(), DeclSpec *MethodQualifiers=nullptr)
DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
static DeclaratorChunk getPipe(unsigned TypeQuals, SourceLocation Loc)
Return a DeclaratorChunk for a block.
static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic, bool isStar, Expr *NumElts, SourceLocation LBLoc, SourceLocation RBLoc)
Return a DeclaratorChunk for an array.
SourceLocation Loc
Loc - The place where this type was defined.
static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, unsigned TypeQuals, SourceLocation StarLoc, SourceLocation EndLoc)
enum clang::DeclaratorChunk::@340323374315200305336204205154073066142310370142 Kind
static DeclaratorChunk getParen(SourceLocation LParenLoc, SourceLocation RParenLoc)
Return a DeclaratorChunk for a paren.
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, bool lvalue)
Return a DeclaratorChunk for a reference.
bool isStringLiteralArg(unsigned I) const
ExpressionKind
Describes whether we are in an expression constext which we have to handle differently.
bool hasInvalidName() const
const IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
TemplateNameKind Kind
The kind of template that Template refers to.
bool hasInvalidArgs() const