30#include "llvm/ADT/SmallString.h"
31#include "llvm/Support/TimeProfiler.h"
66 assert(Tok.
is(tok::kw_namespace) &&
"Not a namespace!");
70 if (Tok.
is(tok::code_completion)) {
78 InnerNamespaceInfoList ExtraNSs;
83 auto ReadAttributes = [&] {
87 if (Tok.
is(tok::kw___attribute)) {
88 ParseGNUAttributes(attrs);
93 ? diag::warn_cxx14_compat_ns_enum_attribute
94 : diag::ext_ns_enum_attribute)
96 ParseCXX11Attributes(attrs);
99 }
while (MoreToParse);
104 if (Tok.
is(tok::identifier)) {
107 while (Tok.
is(tok::coloncolon) &&
110 GetLookAheadToken(2).is(tok::identifier)))) {
112 InnerNamespaceInfo Info;
115 if (Tok.
is(tok::kw_inline)) {
118 FirstNestedInlineLoc = Info.InlineLoc;
124 ExtraNSs.push_back(Info);
133 if (!ExtraNSs.empty() && attrLoc.
isValid())
134 Diag(attrLoc, diag::err_unexpected_nested_namespace_attribute);
136 if (Tok.
is(tok::equal)) {
138 Diag(Tok, diag::err_expected) << tok::identifier;
144 Diag(attrLoc, diag::err_unexpected_namespace_attributes_alias);
146 Diag(InlineLoc, diag::err_inline_namespace_alias)
148 Decl *NSAlias = ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
153 if (T.consumeOpen()) {
155 Diag(Tok, diag::err_expected) << tok::l_brace;
157 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
164 Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope);
169 if (ExtraNSs.empty()) {
171 }
else if (InlineLoc.
isValid()) {
172 Diag(InlineLoc, diag::err_inline_nested_namespace_definition);
174 Diag(ExtraNSs[0].NamespaceLoc,
175 diag::warn_cxx14_compat_nested_namespace_definition);
176 if (FirstNestedInlineLoc.
isValid())
177 Diag(FirstNestedInlineLoc,
178 diag::warn_cxx17_compat_inline_nested_namespace_definition);
180 Diag(ExtraNSs[0].NamespaceLoc,
181 diag::warn_cxx14_compat_nested_namespace_definition);
182 if (FirstNestedInlineLoc.
isValid())
183 Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition);
185 TentativeParsingAction TPA(*
this);
187 Token rBraceToken = Tok;
190 if (!rBraceToken.
is(tok::r_brace)) {
191 Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition)
193 ExtraNSs.back().IdentLoc);
195 std::string NamespaceFix;
196 for (
const auto &ExtraNS : ExtraNSs) {
197 NamespaceFix +=
" { ";
198 if (ExtraNS.InlineLoc.isValid())
199 NamespaceFix +=
"inline ";
200 NamespaceFix +=
"namespace ";
201 NamespaceFix += ExtraNS.Ident->getName();
205 for (
unsigned i = 0, e = ExtraNSs.size(); i != e; ++i)
208 Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition)
211 ExtraNSs.back().IdentLoc),
217 if (FirstNestedInlineLoc.
isValid())
218 Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition);
224 ? diag::warn_cxx98_compat_inline_namespace
225 : diag::ext_inline_namespace);
232 getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident,
233 T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl,
false);
236 NamespaceLoc,
"parsing namespace");
240 ParseInnerNamespace(ExtraNSs, 0, InlineLoc, attrs, T);
243 NamespaceScope.Exit();
245 DeclEnd = T.getCloseLocation();
249 ImplicitUsingDirectiveDecl);
253void Parser::ParseInnerNamespace(
const InnerNamespaceInfoList &InnerNSs,
257 if (index == InnerNSs.size()) {
258 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
259 Tok.
isNot(tok::eof)) {
261 MaybeParseCXX11Attributes(DeclAttrs);
263 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
279 getCurScope(), InnerNSs[index].InlineLoc, InnerNSs[index].NamespaceLoc,
280 InnerNSs[index].IdentLoc, InnerNSs[index].Ident,
282 assert(!ImplicitUsingDirectiveDecl &&
283 "nested namespace definition cannot define anonymous namespace");
285 ParseInnerNamespace(InnerNSs, ++index, InlineLoc, attrs, Tracker);
287 NamespaceScope.Exit();
298 assert(Tok.
is(tok::equal) &&
"Not equal token");
302 if (Tok.
is(tok::code_completion)) {
310 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
318 if (Tok.
isNot(tok::identifier)) {
319 Diag(Tok, diag::err_expected_namespace_name);
338 if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name))
342 Alias, SS, IdentLoc, Ident);
353 assert(isTokenStringLiteral() &&
"Not a string literal!");
367 while (MaybeParseCXX11Attributes(DeclAttrs) ||
368 MaybeParseGNUAttributes(DeclSpecAttrs))
371 if (Tok.
isNot(tok::l_brace)) {
378 ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs, &DS);
386 ProhibitAttributes(DeclAttrs);
391 unsigned NestedModules = 0;
394 case tok::annot_module_begin:
399 case tok::annot_module_end:
406 case tok::annot_module_include:
419 MaybeParseCXX11Attributes(DeclAttrs);
420 ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs);
439Decl *Parser::ParseExportDeclaration() {
440 assert(Tok.
is(tok::kw_export));
448 if (Tok.
isNot(tok::l_brace)) {
451 MaybeParseCXX11Attributes(DeclAttrs);
453 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
461 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
462 Tok.
isNot(tok::eof)) {
464 MaybeParseCXX11Attributes(DeclAttrs);
466 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
471 T.getCloseLocation());
479 assert(Tok.
is(tok::kw_using) &&
"Not using token");
485 if (Tok.
is(tok::code_completion)) {
492 while (Tok.
is(tok::kw_template)) {
494 Diag(TemplateLoc, diag::err_unexpected_template_after_using)
499 if (Tok.
is(tok::kw_namespace)) {
501 if (TemplateInfo.Kind) {
503 Diag(UsingLoc, diag::err_templated_using_directive_declaration)
507 Decl *UsingDir = ParseUsingDirective(Context, UsingLoc, DeclEnd, Attrs);
512 return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd, Attrs,
530 assert(Tok.
is(tok::kw_namespace) &&
"Not 'namespace' token");
535 if (Tok.
is(tok::code_completion)) {
543 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
555 if (Tok.
isNot(tok::identifier)) {
556 Diag(Tok, diag::err_expected_namespace_name);
575 bool GNUAttr =
false;
576 if (Tok.
is(tok::kw___attribute)) {
578 ParseGNUAttributes(attrs);
583 if (ExpectAndConsume(tok::semi,
584 GNUAttr ? diag::err_expected_semi_after_attribute_list
585 : diag::err_expected_semi_after_namespace_name))
589 IdentLoc, NamespcName, attrs);
598 UsingDeclarator &D) {
605 if (Tok.
is(tok::kw___super)) {
612 if (ParseOptionalCXXScopeSpecifier(D.SS,
nullptr,
622 if (D.SS.isInvalid())
636 Tok.
is(tok::identifier) &&
642 !D.SS.getScopeRep()->getAsNamespace() &&
643 !D.SS.getScopeRep()->getAsNamespaceAlias()) {
647 D.Name.setConstructorName(
Type, IdLoc, IdLoc);
654 !(Tok.
is(tok::identifier) &&
NextToken().is(tok::equal)),
655 false,
nullptr, D.Name))
661 ? diag::warn_cxx17_compat_using_declaration_pack
662 : diag::ext_using_declaration_pack);
701 ? diag::warn_cxx17_compat_using_enum_declaration
702 : diag::ext_using_enum_declaration);
704 DiagnoseCXX11AttributeExtension(PrefixAttrs);
706 if (TemplateInfo.Kind) {
708 Diag(UsingLoc, diag::err_templated_using_directive_declaration)
714 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
726 if (Tok.
is(tok::code_completion)) {
732 if (!Tok.
is(tok::identifier)) {
734 << Tok.
is(tok::kw_enum);
741 getCurScope(), AS, UsingLoc, UELoc, IdentLoc, *IdentInfo, &SS);
748 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
749 "using-enum declaration"))
758 MaybeParseCXX11Attributes(MisplacedAttrs);
760 if (InInitStatement && Tok.
isNot(tok::identifier))
764 bool InvalidDeclarator = ParseUsingDeclarator(Context, D);
767 MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);
771 if (MisplacedAttrs.Range.isValid()) {
773 MisplacedAttrs.empty() ? nullptr : &MisplacedAttrs.front();
774 auto &
Range = MisplacedAttrs.Range;
775 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
776 ?
Diag(
Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr
777 :
Diag(
Range.getBegin(), diag::err_attributes_not_allowed))
785 if (Tok.
is(tok::equal) || InInitStatement) {
786 if (InvalidDeclarator) {
791 ProhibitAttributes(PrefixAttrs);
793 Decl *DeclFromDeclSpec =
nullptr;
794 Decl *AD = ParseAliasDeclarationAfterDeclarator(
795 TemplateInfo, UsingLoc, D, DeclEnd, AS, Attrs, &DeclFromDeclSpec);
799 DiagnoseCXX11AttributeExtension(PrefixAttrs);
804 if (TemplateInfo.Kind) {
806 Diag(UsingLoc, diag::err_templated_using_directive_declaration)
818 MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);
819 DiagnoseCXX11AttributeExtension(Attrs);
822 if (InvalidDeclarator)
827 if (D.TypenameLoc.isValid() &&
829 Diag(D.Name.getSourceRange().getBegin(),
830 diag::err_typename_identifiers_only)
837 D.TypenameLoc, D.SS, D.Name,
838 D.EllipsisLoc, Attrs);
840 DeclsInGroup.push_back(UD);
848 InvalidDeclarator = ParseUsingDeclarator(Context, D);
851 if (DeclsInGroup.size() > 1)
854 ? diag::warn_cxx17_compat_multi_using_declaration
855 : diag::ext_multi_using_declaration);
859 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
860 !Attrs.
empty() ?
"attributes list"
861 : UELoc.
isValid() ?
"using-enum declaration"
862 :
"using declaration"))
868Decl *Parser::ParseAliasDeclarationAfterDeclarator(
872 if (ExpectAndConsume(tok::equal)) {
878 ? diag::warn_cxx98_compat_alias_declaration
879 : diag::ext_alias_declaration);
883 if (TemplateInfo.Kind == ParsedTemplateInfo::Template &&
886 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization)
888 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
890 if (SpecKind != -1) {
894 D.Name.TemplateId->RAngleLoc);
896 Range = TemplateInfo.getSourceRange();
897 Diag(
Range.getBegin(), diag::err_alias_declaration_specialization)
898 << SpecKind <<
Range;
905 Diag(D.Name.StartLocation, diag::err_alias_declaration_not_identifier);
909 }
else if (D.TypenameLoc.isValid())
910 Diag(D.TypenameLoc, diag::err_alias_declaration_not_identifier)
912 SourceRange(D.TypenameLoc, D.SS.isNotEmpty() ? D.SS.getEndLoc()
914 else if (D.SS.isNotEmpty())
915 Diag(D.SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)
917 if (D.EllipsisLoc.isValid())
918 Diag(D.EllipsisLoc, diag::err_alias_declaration_pack_expansion)
921 Decl *DeclFromDeclSpec =
nullptr;
926 AS, &DeclFromDeclSpec, &Attrs);
928 *OwnedType = DeclFromDeclSpec;
932 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
933 !Attrs.
empty() ?
"attributes list"
934 :
"alias declaration"))
939 TemplateParams ? TemplateParams->data() :
nullptr,
940 TemplateParams ? TemplateParams->size() : 0);
942 UsingLoc, D.Name, Attrs, TypeAlias,
948 if (
const auto *BO = dyn_cast_or_null<BinaryOperator>(AssertExpr)) {
949 if (BO->getOpcode() == BO_LAnd &&
950 isa<StringLiteral>(BO->getRHS()->IgnoreImpCasts()))
965 assert(Tok.
isOneOf(tok::kw_static_assert, tok::kw__Static_assert) &&
966 "Not a static_assert declaration");
969 const char *TokName = Tok.
getName();
973 if (Tok.
is(tok::kw_static_assert)) {
976 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
981 Diag(Tok, diag::warn_cxx98_compat_static_assert);
987 if (T.consumeOpen()) {
988 Diag(Tok, diag::err_expected) << tok::l_paren;
996 if (AssertExpr.isInvalid()) {
1002 if (Tok.
is(tok::r_paren)) {
1005 DiagVal = diag::warn_cxx14_compat_static_assert_no_message;
1007 DiagVal = diag::ext_cxx_static_assert_no_message;
1009 DiagVal = diag::warn_c17_compat_static_assert_no_message;
1011 DiagVal = diag::ext_c_static_assert_no_message;
1015 if (ExpectAndConsume(tok::comma)) {
1020 bool ParseAsExpression =
false;
1022 for (
unsigned I = 0;; ++I) {
1023 const Token &T = GetLookAheadToken(I);
1024 if (T.
is(tok::r_paren))
1027 ParseAsExpression =
true;
1033 if (ParseAsExpression)
1038 Diag(Tok, diag::err_expected_string_literal)
1053 ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, TokName);
1056 AssertMessage.
get(),
1057 T.getCloseLocation());
1066 assert(Tok.
isOneOf(tok::kw_decltype, tok::annot_decltype) &&
1067 "Not a decltype specifier");
1073 if (Tok.
is(tok::annot_decltype)) {
1074 Result = getExprAnnotation(Tok);
1079 ConsumeAnnotationToken();
1080 if (
Result.isInvalid()) {
1086 Diag(Tok, diag::warn_cxx98_compat_decltype);
1091 if (T.expectAndConsume(diag::err_expected_lparen_after,
"decltype",
1094 return T.getOpenLocation() == Tok.
getLocation() ? StartLoc
1095 : T.getOpenLocation();
1099 if (Tok.
is(tok::kw_auto) &&
NextToken().is(tok::r_paren)) {
1104 ? diag::warn_cxx11_compat_decltype_auto_type_specifier
1105 : diag::ext_decltype_auto_type_specifier);
1119 if (
Result.isInvalid()) {
1122 EndLoc = ConsumeParen();
1129 assert(Tok.
is(tok::semi));
1143 if (T.getCloseLocation().isInvalid()) {
1147 return T.getCloseLocation();
1150 if (
Result.isInvalid()) {
1152 return T.getCloseLocation();
1155 EndLoc = T.getCloseLocation();
1157 assert(!
Result.isInvalid());
1159 const char *PrevSpec =
nullptr;
1164 PrevSpec, DiagID,
Result.get(), Policy)
1166 PrevSpec, DiagID, Policy)) {
1167 Diag(StartLoc, DiagID) << PrevSpec;
1173void Parser::AnnotateExistingDecltypeSpecifier(
const DeclSpec &DS,
1189 Tok.
setKind(tok::annot_decltype);
1190 setExprAnnotation(Tok,
1201#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
1202 case tok::kw___##Trait: \
1203 return DeclSpec::TST_##Trait;
1204#include "clang/Basic/TransformTypeTraits.def"
1206 llvm_unreachable(
"passed in an unhandled type transformation built-in");
1210bool Parser::MaybeParseTypeTransformTypeSpecifier(
DeclSpec &DS) {
1215 DeclSpec::TST TypeTransformTST = TypeTransformTokToDeclSpec();
1219 if (T.expectAndConsume(diag::err_expected_lparen_after, Tok.
getName(),
1224 if (
Result.isInvalid()) {
1230 if (T.getCloseLocation().isInvalid())
1233 const char *PrevSpec =
nullptr;
1238 Diag(StartLoc, DiagID) << PrevSpec;
1264 if (Tok.
is(tok::kw_typename)) {
1265 Diag(Tok, diag::err_expected_class_name_not_template)
1272 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
1282 if (Tok.
isOneOf(tok::kw_decltype, tok::annot_decltype)) {
1289 EndLocation = ParseDecltypeSpecifier(DS);
1297 if (Tok.
is(tok::annot_template_id)) {
1303 assert(Tok.
is(tok::annot_typename) &&
"template-id -> type failed");
1306 ConsumeAnnotationToken();
1313 if (Tok.
isNot(tok::identifier)) {
1314 Diag(Tok, diag::err_expected_class_name);
1321 if (Tok.
is(tok::less)) {
1330 Diag(IdLoc, diag::err_unknown_template_name) <<
Id;
1341 if (Tok.
is(tok::annot_template_id) &&
1342 takeTemplateIdAnnotation(Tok)->mightBeType())
1348 if (Tok.
isNot(tok::annot_typename))
1355 ConsumeAnnotationToken();
1368 Diag(IdLoc, diag::err_expected_class_name);
1373 EndLocation = IdLoc;
1381 const char *PrevSpec =
nullptr;
1391void Parser::ParseMicrosoftInheritanceClassAttributes(
ParsedAttributes &attrs) {
1392 while (Tok.
isOneOf(tok::kw___single_inheritance,
1393 tok::kw___multiple_inheritance,
1394 tok::kw___virtual_inheritance)) {
1398 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0, Kind);
1405bool Parser::isValidAfterTypeSpecifier(
bool CouldBeBitfield) {
1416 case tok::identifier:
1418 case tok::coloncolon:
1419 case tok::annot_cxxscope:
1420 case tok::annot_typename:
1421 case tok::annot_template_id:
1422 case tok::kw_decltype:
1425 case tok::kw_operator:
1426 case tok::kw___declspec:
1431 case tok::kw___attribute:
1432 case tok::annot_pragma_pack:
1434 case tok::annot_pragma_ms_pragma:
1436 case tok::annot_pragma_ms_vtordisp:
1438 case tok::annot_pragma_ms_pointers_to_members:
1441 return CouldBeBitfield ||
1444 case tok::kw___cdecl:
1445 case tok::kw___fastcall:
1446 case tok::kw___stdcall:
1447 case tok::kw___thiscall:
1448 case tok::kw___vectorcall:
1454 case tok::kw_volatile:
1455 case tok::kw_restrict:
1456 case tok::kw__Atomic:
1457 case tok::kw___unaligned:
1461 case tok::kw_inline:
1462 case tok::kw_virtual:
1463 case tok::kw_friend:
1465 case tok::kw_static:
1466 case tok::kw_extern:
1467 case tok::kw_typedef:
1468 case tok::kw_register:
1470 case tok::kw_mutable:
1471 case tok::kw_thread_local:
1472 case tok::kw_constexpr:
1473 case tok::kw_consteval:
1474 case tok::kw_constinit:
1490 if (!isKnownToBeTypeSpecifier(
NextToken()))
1547 const ParsedTemplateInfo &TemplateInfo,
1549 DeclSpecContext DSC,
1552 if (TagTokKind == tok::kw_struct)
1554 else if (TagTokKind == tok::kw___interface)
1556 else if (TagTokKind == tok::kw_class)
1559 assert(TagTokKind == tok::kw_union &&
"Not a class specifier");
1563 if (Tok.
is(tok::code_completion)) {
1577 const bool shouldDelayDiagsInTag =
1578 (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate);
1583 MaybeParseAttributes(PAKM_CXX11 | PAKM_Declspec | PAKM_GNU, attrs);
1586 if (Tok.
isOneOf(tok::kw___single_inheritance, tok::kw___multiple_inheritance,
1587 tok::kw___virtual_inheritance))
1588 ParseMicrosoftInheritanceClassAttributes(attrs);
1591 MaybeParseAttributes(PAKM_CXX11 | PAKM_Declspec | PAKM_GNU, attrs);
1601#include
"clang/Basic/TransformTypeTraits.def"
1602 tok::kw___is_abstract,
1603 tok::kw___is_aggregate,
1604 tok::kw___is_arithmetic,
1606 tok::kw___is_assignable,
1607 tok::kw___is_base_of,
1608 tok::kw___is_bounded_array,
1610 tok::kw___is_complete_type,
1611 tok::kw___is_compound,
1613 tok::kw___is_constructible,
1614 tok::kw___is_convertible,
1615 tok::kw___is_convertible_to,
1616 tok::kw___is_destructible,
1619 tok::kw___is_floating_point,
1621 tok::kw___is_function,
1622 tok::kw___is_fundamental,
1623 tok::kw___is_integral,
1624 tok::kw___is_interface_class,
1625 tok::kw___is_literal,
1626 tok::kw___is_lvalue_expr,
1627 tok::kw___is_lvalue_reference,
1628 tok::kw___is_member_function_pointer,
1629 tok::kw___is_member_object_pointer,
1630 tok::kw___is_member_pointer,
1631 tok::kw___is_nothrow_assignable,
1632 tok::kw___is_nothrow_constructible,
1633 tok::kw___is_nothrow_destructible,
1634 tok::kw___is_nullptr,
1635 tok::kw___is_object,
1637 tok::kw___is_pointer,
1638 tok::kw___is_polymorphic,
1639 tok::kw___is_reference,
1640 tok::kw___is_referenceable,
1641 tok::kw___is_rvalue_expr,
1642 tok::kw___is_rvalue_reference,
1644 tok::kw___is_scalar,
1645 tok::kw___is_scoped_enum,
1646 tok::kw___is_sealed,
1647 tok::kw___is_signed,
1648 tok::kw___is_standard_layout,
1649 tok::kw___is_trivial,
1650 tok::kw___is_trivially_equality_comparable,
1651 tok::kw___is_trivially_assignable,
1652 tok::kw___is_trivially_constructible,
1653 tok::kw___is_trivially_copyable,
1654 tok::kw___is_unbounded_array,
1656 tok::kw___is_unsigned,
1658 tok::kw___is_volatile,
1659 tok::kw___reference_binds_to_temporary,
1660 tok::kw___reference_constructs_from_temporary))
1666 TryKeywordIdentFallback(
true);
1668 struct PreserveAtomicIdentifierInfoRAII {
1669 PreserveAtomicIdentifierInfoRAII(
Token &Tok,
bool Enabled)
1670 : AtomicII(nullptr) {
1673 assert(Tok.
is(tok::kw__Atomic));
1678 ~PreserveAtomicIdentifierInfoRAII() {
1681 AtomicII->revertIdentifierToTokenID(tok::kw__Atomic);
1691 bool ShouldChangeAtomicToIdentifier =
getLangOpts().MSVCCompat &&
1692 Tok.
is(tok::kw__Atomic) &&
1694 PreserveAtomicIdentifierInfoRAII AtomicTokenGuard(
1695 Tok, ShouldChangeAtomicToIdentifier);
1705 if (TemplateInfo.TemplateParams)
1708 bool HasValidSpec =
true;
1709 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
1713 HasValidSpec =
false;
1716 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::annot_template_id)) {
1717 Diag(Tok, diag::err_expected) << tok::identifier;
1718 HasValidSpec =
false;
1726 auto RecoverFromUndeclaredTemplateName = [&](
IdentifierInfo *Name,
1729 bool KnownUndeclared) {
1730 Diag(NameLoc, diag::err_explicit_spec_non_template)
1731 << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
1732 << TagTokKind << Name << TemplateArgRange << KnownUndeclared;
1736 if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {
1737 if (TemplateParams->size() > 1) {
1738 TemplateParams->pop_back();
1740 TemplateParams =
nullptr;
1741 const_cast<ParsedTemplateInfo &
>(TemplateInfo).Kind =
1742 ParsedTemplateInfo::NonTemplate;
1744 }
else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
1746 TemplateParams =
nullptr;
1747 const_cast<ParsedTemplateInfo &
>(TemplateInfo).Kind =
1748 ParsedTemplateInfo::NonTemplate;
1749 const_cast<ParsedTemplateInfo &
>(TemplateInfo).TemplateLoc =
1751 const_cast<ParsedTemplateInfo &
>(TemplateInfo).ExternLoc =
1760 if (Tok.
is(tok::identifier)) {
1768 TemplateArgList TemplateArgs;
1770 if (ParseTemplateIdAfterTemplateName(
true, LAngleLoc, TemplateArgs,
1776 RecoverFromUndeclaredTemplateName(
1777 Name, NameLoc,
SourceRange(LAngleLoc, RAngleLoc),
false);
1779 }
else if (Tok.
is(tok::annot_template_id)) {
1780 TemplateId = takeTemplateIdAnnotation(Tok);
1781 NameLoc = ConsumeAnnotationToken();
1788 RecoverFromUndeclaredTemplateName(
1791 TemplateId =
nullptr;
1804 Diag(TemplateId->
LAngleLoc, diag::err_template_spec_syntax_non_template)
1805 << TemplateId->
Name <<
static_cast<int>(TemplateId->
Kind) << Range;
1840 MaybeParseCXX11Attributes(Attributes);
1845 AllowDefiningTypeSpec::No ||
1848 else if (Tok.
is(tok::l_brace) ||
1849 (DSC != DeclSpecContext::DSC_association &&
1851 (isClassCompatibleKeyword() &&
1867 }
else if (isClassCompatibleKeyword() &&
1874 TentativeParsingAction PA(*
this);
1877 while (isClassCompatibleKeyword()) {
1883 if (Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square)) {
1887 }
else if (Tok.
is(tok::kw_alignas) &&
NextToken().is(tok::l_paren)) {
1899 if (Tok.
isOneOf(tok::l_brace, tok::colon))
1905 }
else if (!isTypeSpecifier(DSC) &&
1906 (Tok.
is(tok::semi) ||
1909 if (Tok.
isNot(tok::semi)) {
1912 ExpectAndConsume(tok::semi, diag::err_expected_after,
1930 auto *FirstAttr = Attributes.
empty() ? nullptr : &Attributes.
front();
1932 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1933 ?
Diag(Loc, diag::err_keyword_not_allowed) << FirstAttr
1934 :
Diag(Loc, diag::err_attributes_not_allowed))
1946 if (!Name && !TemplateId &&
1951 Diag(StartLoc, diag::err_anon_type_definition)
1978 }
else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1981 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
1982 diag::err_keyword_not_allowed,
1986 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
1997 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
1998 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
1999 diag::err_keyword_not_allowed,
2009 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
2022 "Expected a definition here");
2026 TemplateParams =
nullptr;
2031 diag::err_explicit_instantiation_with_definition)
2040 std::nullopt, LAngleLoc,
nullptr));
2041 TemplateParams = &FakedParamLists;
2048 SS, *TemplateId, attrs,
2051 TemplateParams ? TemplateParams->size() : 0),
2054 }
else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
2061 ProhibitAttributes(attrs);
2064 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
2065 TagType, StartLoc, SS, Name, NameLoc, attrs);
2067 TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
2068 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
2069 diag::err_keyword_not_allowed,
2076 TemplateParams ? TemplateParams->size() : 0));
2079 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
2080 diag::err_keyword_not_allowed,
2084 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
2087 Diag(Tok, diag::err_template_defn_explicit_instantiation)
2089 TemplateParams =
nullptr;
2092 bool IsDependent =
false;
2102 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
2105 TagOrTempResult = Actions.
ActOnTag(
2109 DSC == DeclSpecContext::DSC_type_specifier,
2110 DSC == DeclSpecContext::DSC_template_param ||
2111 DSC == DeclSpecContext::DSC_template_type_arg,
2112 OffsetOfState, &SkipBody);
2119 Name, StartLoc, NameLoc);
2126 if (shouldDelayDiagsInTag) {
2127 diagsFromTag.done();
2129 TemplateInfo.Kind == ParsedTemplateInfo::Template)
2130 diagsFromTag.redelay();
2135 assert(Tok.
is(tok::l_brace) ||
2137 isClassCompatibleKeyword());
2139 SkipCXXMemberSpecification(StartLoc, AttrFixitLoc,
TagType,
2140 TagOrTempResult.
get());
2142 ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs,
TagType,
2143 TagOrTempResult.
get());
2148 ParseStructUnionBody(StartLoc,
TagType, cast<RecordDecl>(D));
2161 const char *PrevSpec =
nullptr;
2166 NameLoc.
isValid() ? NameLoc : StartLoc,
2168 }
else if (!TagOrTempResult.
isInvalid()) {
2170 TagType, StartLoc, NameLoc.
isValid() ? NameLoc : StartLoc, PrevSpec,
2171 DiagID, TagOrTempResult.
get(), Owned, Policy);
2178 Diag(StartLoc, DiagID) << PrevSpec;
2194 (TemplateInfo.Kind || !isValidAfterTypeSpecifier(
false))) {
2195 if (Tok.
isNot(tok::semi)) {
2197 ExpectAndConsume(tok::semi, diag::err_expected_after,
2215void Parser::ParseBaseClause(
Decl *ClassDecl) {
2216 assert(Tok.
is(tok::colon) &&
"Not a base clause");
2225 if (
Result.isInvalid()) {
2231 BaseInfo.push_back(
Result.get());
2256 bool IsVirtual =
false;
2260 MaybeParseCXX11Attributes(Attributes);
2266 CheckMisplacedCXX11Attribute(Attributes, StartLoc);
2276 CheckMisplacedCXX11Attribute(Attributes, StartLoc);
2280 if (Tok.
is(tok::kw_virtual)) {
2284 Diag(VirtualLoc, diag::err_dup_virtual)
2291 CheckMisplacedCXX11Attribute(Attributes, StartLoc);
2305 TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation);
2321 Access, BaseType.
get(), BaseLoc,
2336 case tok::kw_private:
2338 case tok::kw_protected:
2340 case tok::kw_public:
2349void Parser::HandleMemberFunctionDeclDelays(
Declarator &DeclaratorInfo,
2356 if (!NeedLateParse) {
2360 if (Param->hasUnparsedDefaultArg()) {
2361 NeedLateParse =
true;
2367 if (NeedLateParse) {
2370 auto LateMethod =
new LateParsedMethodDeclaration(
this, ThisDecl);
2371 getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
2376 LateMethod->DefaultArgs.reserve(FTI.
NumParams);
2378 LateMethod->DefaultArgs.push_back(LateParsedDefaultArgument(
2415 if (II == Ident_override)
2418 if (II == Ident_sealed)
2421 if (II == Ident_abstract)
2424 if (II == Ident_final)
2427 if (II == Ident_GNU_final)
2438void Parser::ParseOptionalCXX11VirtSpecifierSeq(
VirtSpecifiers &VS,
2457 const char *PrevSpec =
nullptr;
2475 ? diag::warn_cxx98_compat_override_control_keyword
2476 : diag::ext_override_control_keyword)
2485bool Parser::isCXX11FinalKeyword()
const {
2494bool Parser::isClassCompatibleKeyword()
const {
2504bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
2506 LateParsedAttrList &LateParsedAttrs) {
2517 if (Tok.
isNot(tok::colon))
2518 ParseDeclarator(DeclaratorInfo);
2524 "don't know where identifier would go yet?");
2528 }
else if (Tok.
is(tok::kw_requires)) {
2529 ParseTrailingRequiresClause(DeclaratorInfo);
2531 ParseOptionalCXX11VirtSpecifierSeq(
2532 VS, getCurrentClass().IsInterface,
2535 MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo,
2540 if (Tok.
is(tok::kw_asm)) {
2542 ExprResult AsmLabel(ParseSimpleAsm(
true, &Loc));
2543 if (AsmLabel.isInvalid())
2553 DiagnoseAndSkipCXX11Attributes();
2554 MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
2555 DiagnoseAndSkipCXX11Attributes();
2560 ParseOptionalCXX11VirtSpecifierSeq(
2561 VS, getCurrentClass().IsInterface,
2567 if (AL.isKnownToGCC() && !AL.isCXX11Attribute())
2568 Diag(AL.getLoc(), diag::warn_gcc_attribute_location);
2570 MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo,
2587void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
2593 ParseTypeQualifierListOpt(
2594 DS, AR_NoAttributesParsed,
false,
2595 false, llvm::function_ref<
void()>([&]() {
2603 auto DeclSpecCheck = [&](
DeclSpec::TQ TypeQual, StringRef FixItName,
2606 auto &MQ =
Function.getOrCreateMethodQualifiers();
2607 if (!(MQ.getTypeQualifiers() & TypeQual)) {
2608 std::string Name(FixItName.data());
2611 MQ.SetTypeQual(TypeQual, SpecLoc);
2613 Diag(SpecLoc, diag::err_declspec_after_virtspec)
2622 bool RefQualifierIsLValueRef =
true;
2624 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc)) {
2625 const char *Name = (RefQualifierIsLValueRef ?
"& " :
"&& ");
2628 Function.RefQualifierIsLValueRef = RefQualifierIsLValueRef;
2629 Function.RefQualifierLoc = RefQualifierLoc;
2631 Diag(RefQualifierLoc, diag::err_declspec_after_virtspec)
2632 << (RefQualifierIsLValueRef ?
"&" :
"&&")
2680 const ParsedTemplateInfo &TemplateInfo,
2682 if (Tok.
is(tok::at)) {
2684 Diag(Tok, diag::err_at_defs_cxx);
2686 Diag(Tok, diag::err_at_in_class);
2702 bool MalformedTypeSpec =
false;
2703 if (!TemplateInfo.Kind &&
2704 Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw___super)) {
2706 MalformedTypeSpec =
true;
2709 if (Tok.
isNot(tok::annot_cxxscope))
2710 isAccessDecl =
false;
2711 else if (
NextToken().is(tok::identifier))
2712 isAccessDecl = GetLookAheadToken(2).
is(tok::semi);
2719 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
2732 false,
false,
true,
true,
2733 false, &TemplateKWLoc, Name)) {
2739 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
2740 "access declaration")) {
2756 if (!TemplateInfo.Kind &&
2757 Tok.
isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
2763 if (Tok.
is(tok::kw_template)) {
2764 assert(!TemplateInfo.TemplateParams &&
2765 "Nested template improperly parsed?");
2774 if (Tok.
is(tok::kw___extension__)) {
2778 return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,
2784 MaybeParseCXX11Attributes(DeclAttrs);
2789 if (Tok.
is(tok::annot_attr_openmp))
2790 return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, DeclAttrs);
2792 if (Tok.
is(tok::kw_using)) {
2797 while (Tok.
is(tok::kw_template)) {
2799 Diag(TemplateLoc, diag::err_unexpected_template_after_using)
2803 if (Tok.
is(tok::kw_namespace)) {
2804 Diag(UsingLoc, diag::err_using_namespace_in_class);
2811 UsingLoc, DeclEnd, DeclAttrs, AS);
2815 MaybeParseMicrosoftAttributes(DeclSpecAttrs);
2818 LateParsedAttrList CommonLateParsedAttrs;
2825 if (MalformedTypeSpec)
2833 bool IsTemplateSpecOrInst =
2834 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
2835 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
2838 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DeclSpecContext::DSC_class,
2839 &CommonLateParsedAttrs);
2841 if (IsTemplateSpecOrInst)
2842 diagsFromTag.done();
2850 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate &&
2851 DiagnoseMissingSemiAfterTagDefinition(DS, AS, DeclSpecContext::DSC_class,
2852 &CommonLateParsedAttrs))
2856 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data()
2858 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
2862 ProhibitAttributes(DeclAttrs);
2866 getCurScope(), AS, DS, DeclAttrs, TemplateParams,
false, AnonRecord);
2868 DS.complete(TheDecl);
2870 Decl *decls[] = {AnonRecord, TheDecl};
2881 if (TemplateInfo.TemplateParams)
2886 LateParsedAttrList LateParsedAttrs;
2891 auto TryConsumePureSpecifier = [&](
bool AllowDefinition) {
2892 if (Tok.
isNot(tok::equal))
2897 if (
Zero.isNot(tok::numeric_constant) ||
2901 auto &
After = GetLookAheadToken(2);
2902 if (!
After.isOneOf(tok::semi, tok::comma) &&
2903 !(AllowDefinition &&
2904 After.isOneOf(tok::l_brace, tok::colon, tok::kw_try)))
2915 bool ExpectSemi =
true;
2923 if (ParseCXXMemberDeclaratorBeforeInitializer(
2924 DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs)) {
2929 if (IsTemplateSpecOrInst)
2937 TryConsumePureSpecifier(
true);
2948 if (Tok.
isOneOf(tok::l_brace, tok::colon, tok::kw_try)) {
2950 }
else if (Tok.
is(tok::equal)) {
2952 if (KW.
is(tok::kw_default))
2954 else if (KW.
is(tok::kw_delete))
2956 else if (KW.
is(tok::code_completion)) {
2972 ProhibitAttributes(DeclAttrs);
2989 diag::err_function_declared_typedef);
2995 Decl *FunDecl = ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo,
2996 TemplateInfo, VS, PureSpecLoc);
2999 for (
unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
3000 CommonLateParsedAttrs[i]->addDecl(FunDecl);
3002 for (
unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
3003 LateParsedAttrs[i]->addDecl(FunDecl);
3006 LateParsedAttrs.clear();
3009 if (Tok.
is(tok::semi))
3010 ConsumeExtraSemi(AfterMemberFunctionDefinition);
3022 bool HasStaticInitializer =
false;
3027 Diag(Tok, diag::err_anon_bitfield_member_init);
3031 if (!TryConsumePureSpecifier(
false))
3033 HasStaticInitializer =
true;
3040 if (BitfieldSize.
get())
3042 ? diag::warn_cxx17_compat_bitfield_member_init
3043 : diag::ext_bitfield_member_init);
3046 HasStaticInitializer =
true;
3062 if (AL.isCXX11Attribute() || AL.isRegularKeywordAttribute()) {
3063 auto Loc = AL.getRange().getBegin();
3064 (AL.isRegularKeywordAttribute()
3065 ?
Diag(Loc, diag::err_keyword_not_allowed) << AL
3066 :
Diag(Loc, diag::err_attributes_not_allowed))
3074 getCurScope(), AS, DeclaratorInfo, TemplateParams, BitfieldSize.
get(),
3075 VS, HasInClassInit);
3078 ThisDecl ? dyn_cast<VarTemplateDecl>(ThisDecl) :
nullptr)
3081 ThisDecl = VT->getTemplatedDecl();
3090 DeclaratorInfo.getDeclSpec().getStorageClassSpec() ==
3093 HasStaticInitializer =
true;
3097 Diag(PureSpecLoc, diag::err_duplicate_virt_specifier) <<
"abstract";
3099 if (ThisDecl && PureSpecLoc.
isValid())
3108 ? diag::warn_cxx98_compat_nonstatic_member_init
3109 : diag::ext_nonstatic_member_init);
3111 if (DeclaratorInfo.isArrayOfUnknownBound()) {
3117 Diag(Tok, diag::err_incomplete_array_member_init);
3124 ParseCXXNonStaticMemberInitializer(ThisDecl);
3125 }
else if (HasStaticInitializer) {
3128 ThisDecl, DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
3130 if (
Init.isInvalid()) {
3134 }
else if (ThisDecl)
3144 for (
unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i)
3145 CommonLateParsedAttrs[i]->addDecl(ThisDecl);
3147 for (
unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i)
3148 LateParsedAttrs[i]->addDecl(ThisDecl);
3151 DeclsInGroup.push_back(ThisDecl);
3153 if (DeclaratorInfo.isFunctionDeclarator() &&
3154 DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
3156 HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);
3158 LateParsedAttrs.clear();
3160 DeclaratorInfo.complete(ThisDecl);
3173 Diag(CommaLoc, diag::err_expected_semi_declaration)
3180 DeclaratorInfo.clear();
3184 DeclaratorInfo.setCommaLoc(CommaLoc);
3189 DiagnoseAndSkipCXX11Attributes();
3190 MaybeParseGNUAttributes(DeclaratorInfo);
3191 DiagnoseAndSkipCXX11Attributes();
3193 if (ParseCXXMemberDeclaratorBeforeInitializer(
3194 DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs))
3199 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
3230ExprResult Parser::ParseCXXMemberInitializer(
Decl *D,
bool IsFunction,
3232 assert(Tok.
isOneOf(tok::equal, tok::l_brace) &&
3233 "Data member initializer not starting with '=' or '{'");
3235 bool IsFieldInitialization = isa_and_present<FieldDecl>(D);
3239 IsFieldInitialization
3248 IsFieldInitialization;
3251 if (Tok.
is(tok::kw_delete)) {
3258 if (IsFunction || Next.isOneOf(tok::semi, tok::comma, tok::eof)) {
3266 }
else if (Tok.
is(tok::kw_default)) {
3268 Diag(Tok, diag::err_default_delete_in_multiple_declaration)
3276 if (
const auto *PD = dyn_cast_or_null<MSPropertyDecl>(D)) {
3277 Diag(Tok, diag::err_ms_property_initializer) << PD;
3280 return ParseInitializer();
3288 assert(isCXX11FinalKeyword() &&
"not a class definition");
3294 CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);
3299 if (Tok.
isNot(tok::colon) && Tok.
isNot(tok::l_brace))
3306 if (Tok.
is(tok::colon)) {
3309 ParsingClassDefinition ParsingDef(*
this,
TagDecl,
true,
3315 ParseBaseClause(
nullptr);
3319 if (!Tok.
is(tok::l_brace)) {
3321 diag::err_expected_lbrace_after_base_specifiers);
3327 assert(Tok.
is(tok::l_brace));
3333 if (Tok.
is(tok::kw___attribute)) {
3335 MaybeParseGNUAttributes(Attrs);
3345 case tok::kw___if_exists:
3346 case tok::kw___if_not_exists:
3347 ParseMicrosoftIfExistsClassDeclaration(
TagType, AccessAttrs, AS);
3352 ConsumeExtraSemi(InsideStruct,
TagType);
3356 case tok::annot_pragma_vis:
3357 HandlePragmaVisibility();
3359 case tok::annot_pragma_pack:
3362 case tok::annot_pragma_align:
3363 HandlePragmaAlign();
3365 case tok::annot_pragma_ms_pointers_to_members:
3366 HandlePragmaMSPointersToMembers();
3368 case tok::annot_pragma_ms_pragma:
3369 HandlePragmaMSPragma();
3371 case tok::annot_pragma_ms_vtordisp:
3372 HandlePragmaMSVtorDisp();
3374 case tok::annot_pragma_dump:
3378 case tok::kw_namespace:
3380 DiagnoseUnexpectedNamespace(cast<NamedDecl>(
TagDecl));
3383 case tok::kw_private:
3387 return ParseCXXClassMemberDeclaration(AS, AccessAttrs);
3389 case tok::kw_public:
3390 case tok::kw_protected: {
3400 AccessAttrs.
clear();
3401 MaybeParseGNUAttributes(AccessAttrs);
3406 Diag(EndLoc, diag::err_expected)
3410 Diag(EndLoc, diag::err_expected)
3422 AccessAttrs.
clear();
3428 case tok::annot_attr_openmp:
3429 case tok::annot_pragma_openmp:
3430 return ParseOpenMPDeclarativeDirectiveWithExtDecl(
3432 case tok::annot_pragma_openacc:
3440 ConsumeAnnotationToken();
3443 return ParseCXXClassMemberDeclaration(AS, AccessAttrs);
3453void Parser::ParseCXXMemberSpecification(
SourceLocation RecordLoc,
3460 "Invalid TagType!");
3462 llvm::TimeTraceScope TimeScope(
"ParseClass", [&]() {
3463 if (
auto *TD = dyn_cast_or_null<NamedDecl>(
TagDecl))
3464 return TD->getQualifiedNameAsString();
3465 return std::string(
"<anonymous>");
3469 "parsing struct/union/class body");
3473 bool NonNestedClass =
true;
3474 if (!ClassStack.empty()) {
3476 if (S->isClassScope()) {
3478 NonNestedClass =
false;
3481 if (getCurrentClass().IsInterface) {
3482 Diag(RecordLoc, diag::err_invalid_member_in_interface)
3485 ? cast<NamedDecl>(
TagDecl)->getQualifiedNameAsString()
3491 if (S->isFunctionScope())
3502 ParsingClassDefinition ParsingDef(*
this,
TagDecl, NonNestedClass,
3510 bool IsFinalSpelledSealed =
false;
3511 bool IsAbstract =
false;
3519 if (isCXX11FinalKeyword()) {
3522 Diag(Skipped, diag::err_duplicate_class_virt_specifier)
3527 IsFinalSpelledSealed =
true;
3532 Diag(Skipped, diag::err_duplicate_class_virt_specifier)
3540 Diag(FinalLoc, diag::err_override_control_interface)
3544 ? diag::warn_cxx98_compat_override_control_keyword
3545 : diag::ext_override_control_keyword)
3548 Diag(FinalLoc, diag::ext_ms_sealed_keyword);
3550 Diag(AbstractLoc, diag::ext_ms_abstract_keyword);
3552 Diag(FinalLoc, diag::ext_warn_gnu_final);
3555 "not a class definition");
3561 CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);
3570 if (!Tok.
is(tok::colon) && !Tok.
is(tok::l_brace)) {
3577 if (Tok.
is(tok::colon)) {
3578 ParseScope InheritanceScope(
this,
getCurScope()->getFlags() |
3582 if (!Tok.
is(tok::l_brace)) {
3583 bool SuggestFixIt =
false;
3587 case tok::kw_private:
3588 case tok::kw_protected:
3589 case tok::kw_public:
3592 case tok::kw_static_assert:
3596 case tok::kw_template:
3597 SuggestFixIt =
true;
3599 case tok::identifier:
3600 SuggestFixIt = isConstructorDeclarator(
true);
3603 SuggestFixIt = isCXXSimpleDeclaration(
false);
3608 Diag(BraceLoc, diag::err_expected_lbrace_after_base_specifiers);
3622 assert(Tok.
is(tok::l_brace));
3628 IsFinalSpelledSealed, IsAbstract,
3629 T.getOpenLocation());
3644 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
3645 Tok.
isNot(tok::eof)) {
3647 ParseCXXClassMemberDeclarationWithPragmas(
3649 MaybeDestroyTemplateIds();
3658 MaybeParseGNUAttributes(attrs);
3662 T.getOpenLocation(),
3663 T.getCloseLocation(), attrs);
3670 if (
TagDecl && NonNestedClass) {
3677 ParseLexedPragmas(getCurrentClass());
3678 ParseLexedAttributes(getCurrentClass());
3679 ParseLexedMethodDeclarations(getCurrentClass());
3684 ParseLexedMemberInitializers(getCurrentClass());
3685 ParseLexedMethodDefs(getCurrentClass());
3686 PrevTokLocation = SavedPrevTokLocation;
3701void Parser::DiagnoseUnexpectedNamespace(
NamedDecl *D) {
3702 assert(Tok.
is(tok::kw_namespace));
3707 Diag(Tok.
getLocation(), diag::note_missing_end_of_definition_before) << D;
3741void Parser::ParseConstructorInitializer(
Decl *ConstructorDecl) {
3742 assert(Tok.
is(tok::colon) &&
3743 "Constructor initializer always starts with ':'");
3751 bool AnyErrors =
false;
3754 if (Tok.
is(tok::code_completion)) {
3761 MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
3763 MemInitializers.push_back(MemInit.
get());
3767 if (Tok.
is(tok::comma))
3769 else if (Tok.
is(tok::l_brace))
3774 Tok.
isOneOf(tok::identifier, tok::coloncolon)) {
3776 Diag(Loc, diag::err_ctor_init_missing_comma)
3782 << tok::l_brace << tok::comma;
3807 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
3820 if (Tok.
is(tok::identifier)) {
3825 }
else if (Tok.
is(tok::annot_decltype)) {
3830 ParseDecltypeSpecifier(DS);
3833 ? takeTemplateIdAnnotation(Tok)
3838 assert(Tok.
is(tok::annot_typename) &&
"template-id -> type failed");
3840 ConsumeAnnotationToken();
3842 Diag(Tok, diag::err_expected_member_or_base_name);
3849 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3852 ExprResult InitList = ParseBraceInitializer();
3862 TemplateTypeTy.
get(), DS, IdLoc,
3863 InitList.
get(), EllipsisLoc);
3864 }
else if (Tok.
is(tok::l_paren)) {
3869 ExprVector ArgExprs;
3870 auto RunSignatureHelp = [&] {
3874 ConstructorDecl, SS, TemplateTypeTy.
get(), ArgExprs, II,
3875 T.getOpenLocation(),
false);
3876 CalledSignatureHelp =
true;
3877 return PreferredType;
3879 if (Tok.
isNot(tok::r_paren) && ParseExpressionList(ArgExprs, [&] {
3880 PreferredType.enterFunctionArgument(Tok.
getLocation(),
3897 ConstructorDecl,
getCurScope(), SS, II, TemplateTypeTy.
get(), DS, IdLoc,
3898 T.getOpenLocation(), ArgExprs, T.getCloseLocation(), EllipsisLoc);
3905 return Diag(Tok, diag::err_expected_either) << tok::l_paren << tok::l_brace;
3907 return Diag(Tok, diag::err_expected) << tok::l_paren;
3925 ExceptionSpecTokens =
nullptr;
3929 if (Tok.
isNot(tok::kw_throw) && Tok.
isNot(tok::kw_noexcept))
3933 bool IsNoexcept = Tok.
is(tok::kw_noexcept);
3934 Token StartTok = Tok;
3938 if (!Tok.
is(tok::l_paren)) {
3941 Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
3942 NoexceptExpr =
nullptr;
3946 Diag(Tok, diag::err_expected_lparen_after) <<
"throw";
3952 ExceptionSpecTokens->push_back(StartTok);
3953 ExceptionSpecTokens->push_back(Tok);
3954 SpecificationRange.
setEnd(ConsumeParen());
3956 ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens,
3959 SpecificationRange.
setEnd(ExceptionSpecTokens->back().getLocation());
3965 if (Tok.
is(tok::kw_throw)) {
3966 Result = ParseDynamicExceptionSpecification(
3967 SpecificationRange, DynamicExceptions, DynamicExceptionRanges);
3968 assert(DynamicExceptions.size() == DynamicExceptionRanges.size() &&
3969 "Produced different number of exception types and ranges.");
3973 if (Tok.
isNot(tok::kw_noexcept))
3976 Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
3984 if (Tok.
is(tok::l_paren)) {
3997 NoexceptRange =
SourceRange(KeywordLoc, T.getCloseLocation());
4004 NoexceptRange =
SourceRange(KeywordLoc, KeywordLoc);
4008 SpecificationRange = NoexceptRange;
4013 if (Tok.
is(tok::kw_throw)) {
4014 Diag(Tok.
getLocation(), diag::err_dynamic_and_noexcept_specification);
4015 ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions,
4016 DynamicExceptionRanges);
4019 Diag(Tok.
getLocation(), diag::err_dynamic_and_noexcept_specification);
4027 if (
P.getLangOpts().CPlusPlus11) {
4028 const char *Replacement = IsNoexcept ?
"noexcept" :
"noexcept(false)";
4029 P.Diag(Range.getBegin(),
P.getLangOpts().CPlusPlus17 && !IsNoexcept
4030 ? diag::ext_dynamic_exception_spec
4031 : diag::warn_exception_spec_deprecated)
4033 P.Diag(Range.getBegin(), diag::note_exception_spec_deprecated)
4052 assert(Tok.
is(tok::kw_throw) &&
"expected throw");
4056 if (T.consumeOpen()) {
4057 Diag(Tok, diag::err_expected_lparen_after) <<
"throw";
4064 if (Tok.
is(tok::ellipsis)) {
4067 Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
4069 SpecificationRange.
setEnd(T.getCloseLocation());
4076 while (Tok.
isNot(tok::r_paren)) {
4079 if (Tok.
is(tok::ellipsis)) {
4084 Range.setEnd(Ellipsis);
4085 if (!Res.isInvalid())
4089 if (!Res.isInvalid()) {
4090 Exceptions.push_back(Res.get());
4091 Ranges.push_back(Range);
4099 SpecificationRange.
setEnd(T.getCloseLocation());
4101 Exceptions.empty());
4108 bool MayBeFollowedByDirectInit) {
4109 assert(Tok.
is(tok::arrow) &&
"expected arrow");
4119void Parser::ParseTrailingRequiresClause(
Declarator &D) {
4120 assert(Tok.
is(tok::kw_requires) &&
"expected requires");
4131 std::optional<Sema::CXXThisScopeRAII> ThisScope;
4132 InitCXXThisScopeForDeclaratorIfRelevant(D, D.
getDeclSpec(), ThisScope);
4134 TrailingRequiresClause =
4137 TrailingRequiresClause =
4142 diag::err_requires_clause_on_declarator_not_declaring_a_function);
4147 SkipUntil({tok::l_brace, tok::arrow, tok::kw_try, tok::comma, tok::colon},
4158 ParseTrailingReturnType(Range,
false);
4162 diag::err_requires_clause_must_appear_after_trailing_return)
4166 FunctionChunk.TrailingReturnType = TrailingReturnType.
get();
4167 FunctionChunk.TrailingReturnTypeLoc =
Range.getBegin();
4169 SkipUntil({tok::equal, tok::l_brace, tok::arrow, tok::kw_try, tok::comma},
4178 bool NonNestedClass,
4180 assert((NonNestedClass || !ClassStack.empty()) &&
4181 "Nested class without outer class");
4182 ClassStack.push(
new ParsingClass(ClassDecl, NonNestedClass, IsInterface));
4188void Parser::DeallocateParsedClasses(Parser::ParsingClass *
Class) {
4189 for (
unsigned I = 0, N =
Class->LateParsedDeclarations.size(); I != N; ++I)
4190 delete Class->LateParsedDeclarations[I];
4201 assert(!ClassStack.empty() &&
"Mismatched push/pop for class parsing");
4205 ParsingClass *Victim = ClassStack.top();
4207 if (Victim->TopLevelClass) {
4210 DeallocateParsedClasses(Victim);
4213 assert(!ClassStack.empty() &&
"Missing top-level class?");
4215 if (Victim->LateParsedDeclarations.empty()) {
4220 DeallocateParsedClasses(Victim);
4228 "Nested class outside of class scope?");
4229 ClassStack.top()->LateParsedDeclarations.push_back(
4230 new LateParsedClass(
this, Victim));
4257 case tok::code_completion:
4264 case tok::numeric_constant: {
4272 StringRef Spelling = PP.
getSpelling(ExpansionLoc, ExpansionBuf);
4273 if (Spelling ==
"__clang__") {
4277 Diag(Tok, diag::warn_wrong_clang_attr_namespace)
4293 case tok::pipeequal:
4294 case tok::caretequal:
4296 case tok::exclaimequal:
4302 StringRef Spelling = PP.
getSpelling(SpellingLoc, SpellingBuf);
4311void Parser::ParseOpenMPAttributeArgs(
const IdentifierInfo *AttrName,
4316 if (T.consumeOpen()) {
4317 Diag(Tok, diag::err_expected) << tok::l_paren;
4321 if (AttrName->
isStr(
"directive")) {
4327 OMPBeginTok.
setKind(tok::annot_attr_openmp);
4329 OpenMPTokens.push_back(OMPBeginTok);
4331 ConsumeAndStoreUntil(tok::r_paren, OpenMPTokens,
false,
4335 OMPEndTok.
setKind(tok::annot_pragma_openmp_end);
4337 OpenMPTokens.push_back(OMPEndTok);
4339 assert(AttrName->
isStr(
"sequence") &&
4340 "Expected either 'directive' or 'sequence'");
4349 const IdentifierInfo *Ident = TryParseCXX11AttributeIdentifier(IdentLoc);
4353 if (Ident && Ident->
isStr(
"omp") && !ExpectAndConsume(tok::coloncolon))
4354 Ident = TryParseCXX11AttributeIdentifier(IdentLoc);
4358 if (!Ident || (!Ident->
isStr(
"directive") && !Ident->
isStr(
"sequence"))) {
4365 ParseOpenMPAttributeArgs(Ident, OpenMPTokens);
4379 case ParsedAttr::AT_CarriesDependency:
4380 case ParsedAttr::AT_Deprecated:
4381 case ParsedAttr::AT_FallThrough:
4382 case ParsedAttr::AT_CXX11NoReturn:
4383 case ParsedAttr::AT_NoUniqueAddress:
4384 case ParsedAttr::AT_Likely:
4385 case ParsedAttr::AT_Unlikely:
4387 case ParsedAttr::AT_WarnUnusedResult:
4388 return !ScopeName && AttrName->
getName().equals(
"nodiscard");
4389 case ParsedAttr::AT_Unused:
4390 return !ScopeName && AttrName->
getName().equals(
"maybe_unused");
4410bool Parser::ParseCXX11AttributeArgs(
4414 assert(Tok.
is(tok::l_paren) &&
"Not a C++11 attribute argument list");
4418 LO.CPlusPlus ? ParsedAttr::Form::CXX11() :
ParsedAttr::Form::
C23();
4424 Form = ParsedAttr::Form::Microsoft();
4439 if (ScopeName && (ScopeName->
isStr(
"gnu") || ScopeName->
isStr(
"__gnu__"))) {
4442 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
4443 ScopeLoc, Form,
nullptr);
4447 if (ScopeName && ScopeName->
isStr(
"omp")) {
4449 ? diag::warn_omp51_compat_attributes
4450 : diag::ext_omp_attributes);
4452 ParseOpenMPAttributeArgs(AttrName, OpenMPTokens);
4461 if (ScopeName && (ScopeName->
isStr(
"clang") || ScopeName->
isStr(
"_Clang")))
4462 NumArgs = ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc,
4463 ScopeName, ScopeLoc, Form);
4465 NumArgs = ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
4466 ScopeName, ScopeLoc, Form);
4468 if (!Attrs.
empty() &&
4474 Diag(LParenLoc, diag::warn_unknown_attribute_ignored) << AttrName;
4475 Attr.setInvalid(
true);
4483 if (
Attr.getMaxArgs() && !NumArgs) {
4486 Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;
4487 Attr.setInvalid(
true);
4488 }
else if (!
Attr.getMaxArgs()) {
4492 Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
4495 Attr.setInvalid(
true);
4528 if (Tok.
is(tok::kw_alignas)) {
4530 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.
getName();
4533 ParseAlignmentSpecifier(Attrs, EndLoc);
4540 Attrs.
addNew(AttrName, Loc,
nullptr, Loc,
nullptr, 0, Tok.
getKind());
4545 assert(Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square) &&
4546 "Not a double square bracket attribute list");
4551 : diag::warn_ext_cxx11_attributes);
4554 : diag::warn_ext_c23_attributes);
4558 checkCompoundToken(OpenLoc, tok::l_square, CompoundToken::AttrBegin);
4563 if (Tok.
is(tok::kw_using)) {
4565 ? diag::warn_cxx14_compat_using_attribute_ns
4566 : diag::ext_using_attribute_ns);
4569 CommonScopeName = TryParseCXX11AttributeIdentifier(
4571 if (!CommonScopeName) {
4579 bool AttrParsed =
false;
4580 while (!Tok.
isOneOf(tok::r_square, tok::semi, tok::eof)) {
4584 if (ExpectAndConsume(tok::comma)) {
4598 AttrName = TryParseCXX11AttributeIdentifier(
4606 ScopeName = AttrName;
4609 AttrName = TryParseCXX11AttributeIdentifier(
4618 if (CommonScopeName) {
4620 Diag(ScopeLoc, diag::err_using_attribute_ns_conflict)
4623 ScopeName = CommonScopeName;
4624 ScopeLoc = CommonScopeLoc;
4629 if (Tok.
is(tok::l_paren))
4630 AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc,
4631 ScopeName, ScopeLoc, OpenMPTokens);
4637 ScopeName, ScopeLoc,
nullptr, 0,
4639 : ParsedAttr::Form::C23());
4644 Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) << AttrName;
4649 if (Tok.
is(tok::semi)) {
4655 if (ExpectAndConsume(tok::r_square))
4657 else if (Tok.
is(tok::r_square))
4658 checkCompoundToken(CloseLoc, tok::r_square, CompoundToken::AttrEnd);
4661 if (ExpectAndConsume(tok::r_square))
4674 ParseCXX11AttributeSpecifier(Attrs, &EndLoc);
4675 }
while (isAllowedCXX11AttributeSpecifier());
4680void Parser::DiagnoseAndSkipCXX11Attributes() {
4689 (Keyword ?
Diag(StartLoc, diag::err_keyword_not_allowed) << Keyword
4690 :
Diag(StartLoc, diag::err_attributes_not_allowed))
4698 if (!isCXX11AttributeSpecifier())
4702 if (Tok.
is(tok::l_square)) {
4706 EndLoc = T.getCloseLocation();
4711 assert(Tok.
is(tok::kw_alignas) &&
"not an attribute specifier");
4714 if (!T.consumeOpen())
4716 EndLoc = T.getCloseLocation();
4718 }
while (isCXX11AttributeSpecifier());
4725 assert(Tok.
is(tok::identifier) &&
"Not a Microsoft attribute list");
4727 assert(UuidIdent->
getName() ==
"uuid" &&
"Not a Microsoft attribute list");
4734 if (T.consumeOpen()) {
4735 Diag(Tok, diag::err_expected) << tok::l_paren;
4740 if (isTokenStringLiteral()) {
4745 ArgExprs.push_back(StringResult.
get());
4762 while (Tok.
isNot(tok::r_paren)) {
4764 Diag(Tok, diag::err_attribute_uuid_malformed_guid);
4769 SpellingBuffer.resize(Tok.
getLength() + 1);
4771 StringRef TokSpelling = PP.
getSpelling(Tok, SpellingBuffer, &Invalid);
4776 StrBuffer += TokSpelling;
4782 Diag(Tok, diag::err_attribute_uuid_malformed_guid);
4792 Toks[0].
setKind(tok::string_literal);
4798 ArgExprs.push_back(UuidString);
4801 if (!T.consumeClose()) {
4804 ParsedAttr::Form::Microsoft());
4817 assert(Tok.
is(tok::l_square) &&
"Not a Microsoft attribute list");
4828 SkipUntil(tok::r_square, tok::identifier,
4830 if (Tok.
is(tok::code_completion)) {
4837 if (Tok.
isNot(tok::identifier))
4840 ParseMicrosoftUuidAttributeArgs(Attrs);
4850 bool AttrParsed =
false;
4851 if (Tok.
is(tok::l_paren)) {
4854 ParseCXX11AttributeArgs(II, NameLoc, Attrs, &EndLoc,
nullptr,
4856 ReplayOpenMPAttributeTokens(OpenMPTokens);
4860 ParsedAttr::Form::Microsoft());
4867 EndLoc = T.getCloseLocation();
4868 }
while (Tok.
is(tok::l_square));
4873void Parser::ParseMicrosoftIfExistsClassDeclaration(
4876 IfExistsCondition
Result;
4877 if (ParseMicrosoftIfExistsCondition(
Result))
4881 if (Braces.consumeOpen()) {
4882 Diag(Tok, diag::err_expected) << tok::l_brace;
4886 switch (
Result.Behavior) {
4892 Diag(
Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
4902 while (Tok.
isNot(tok::r_brace) && !isEofOrEom()) {
4904 if (Tok.
isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) {
4905 ParseMicrosoftIfExistsClassDeclaration(
TagType, AccessAttrs, CurAS);
4910 if (Tok.
is(tok::semi)) {
4911 ConsumeExtraSemi(InsideStruct,
TagType);
4921 if (Tok.
is(tok::colon))
4925 Diag(Tok, diag::err_expected) << tok::colon;
4931 ParseCXXClassMemberDeclaration(CurAS, AccessAttrs);
4934 Braces.consumeClose();
Defines the clang::ASTContext interface.
Defines the C++ template declaration subclasses.
Defines an enumeration for C++ overloaded operators.
static void diagnoseDynamicExceptionSpecification(Parser &P, SourceRange Range, bool IsNoexcept)
static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName, IdentifierInfo *ScopeName)
static FixItHint getStaticAssertNoMessageFixIt(const Expr *AssertExpr, SourceLocation EndExprLoc)
Defines the clang::TokenKind enum and support functions.
#define TRANSFORM_TYPE_TRAIT_DEF(Enum, _)
const NestedNameSpecifier * Specifier
const clang::PrintingPolicy & getPrintingPolicy() const
Attr - This represents one attribute.
@ AS_Microsoft
[uuid("...")] class Foo
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.
SourceRange getRange() const
SourceLocation getBeginLoc() const
bool isSet() const
Deprecated.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
void setTemplateParamLists(ArrayRef< TemplateParameterList * > L)
Represents a character-granular source range.
static CharSourceRange getTokenRange(SourceRange R)
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed.
Captures information about "declaration specifiers".
void setTypeArgumentRange(SourceRange range)
static const TST TST_typename
void ClearStorageClassSpecs()
TST getTypeSpecType() const
SCS getStorageClassSpec() const
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
SourceRange getSourceRange() const LLVM_READONLY
void SetRangeEnd(SourceLocation Loc)
static const TST TST_interface
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
void SetRangeStart(SourceLocation Loc)
static const TST TST_union
SourceLocation getFriendSpecLoc() const
SourceLocation getModulePrivateSpecLoc() const
Expr * getRepAsExpr() const
static const TST TST_decltype
static const TST TST_class
bool hasTagDefinition() const
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
Decl * getRepAsDecl() const
CXXScopeSpec & getTypeSpecScope()
static const TST TST_decltype_auto
void setExternInLinkageSpec(bool Value)
static const TST TST_error
void forEachQualifier(llvm::function_ref< void(TQ, StringRef, SourceLocation)> Handle)
This method calls the passed in handler on each qual being set.
FriendSpecified isFriendSpecified() const
void takeAttributesFrom(ParsedAttributes &attrs)
static const TST TST_struct
Decl - This represents one declaration (or definition), e.g.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
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 SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
bool isDeclarationOfFunction() const
Determine whether the declaration that will be produced from this declaration will be a function.
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
const ParsedAttributes & getAttributes() const
SourceLocation getIdentifierLoc() const
void setTrailingRequiresClause(Expr *TRC)
Sets a trailing requires clause for this declarator.
void setTemplateParameterLists(ArrayRef< TemplateParameterList * > TPLs)
Sets the template parameter lists that preceded the declarator.
void setFunctionDefinitionKind(FunctionDefinitionKind Val)
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
void setAsmLabel(Expr *E)
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.
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
A little helper class used to produce diagnostics.
RAII object that enters a new expression evaluation context.
Represents a standard C++ module export declaration.
This represents one expression.
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
ExtensionRAIIObject - This saves the state of extension warnings when constructed and disables them.
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.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
void revertTokenIDToIdentifier()
Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2 compatibility.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
This represents a decl that may have a name.
Wrapper for void* pointer.
static OpaquePtr make(PtrTy P)
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...
ParsedAttr - Represents a syntactic attribute.
static const ParsedAttributesView & none()
void addAll(iterator B, iterator E)
ParsedAttributes - A collection of parsed attributes.
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
void takeAllFrom(ParsedAttributes &Other)
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 type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
DeclGroupPtrTy ParseOpenACCDirectiveDecl()
Placeholder for now, should just ignore the directives after emitting a diagnostic.
static TypeResult getTypeAnnotation(const Token &Tok)
getTypeAnnotation - Read a parsed type out of an annotation token.
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)
Parse a constraint-logical-or-expression.
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.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
ExprResult ParseConstantExpression()
bool TryConsumeToken(tok::TokenKind Expected)
Scope * getCurScope() const
const TargetInfo & getTargetInfo() const
OpaquePtr< TemplateName > TemplateTy
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...
friend class ObjCDeclContextSwitch
ExprResult ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast=NotTypeCast)
const LangOptions & getLangOpts() const
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
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()
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
SmallVector< TemplateParameterList *, 4 > TemplateParameterLists
bool TryAnnotateCXXScopeToken(bool EnteringContext=false)
TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...
RAII object used to inform the actions that we're currently parsing a declaration.
A class for parsing a DeclSpec.
A class for parsing a declarator.
void EnterToken(const Token &Tok, bool IsReinject)
Enters a token in the token stream to be lexed next.
void AnnotateCachedTokens(const Token &Tok)
We notify the Preprocessor that if it is caching tokens (because backtrack is enabled) it should repl...
SourceManager & getSourceManager() const
bool isBacktrackEnabled() const
True if EnableBacktrackAtThisPos() was called and caching of tokens is on.
void RevertCachedTokens(unsigned N)
When backtracking is enabled and tokens are cached, this allows to revert a specific number of tokens...
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
IdentifierTable & getIdentifierTable()
bool isCodeCompletionReached() const
Returns true if code-completion is enabled and we have hit the code-completion point.
SourceLocation getLastCachedTokenLocation() const
Get the location of the last cached token, suitable for setting the end location of an annotation tok...
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Computes the source location just past the end of the token at this source location.
PrettyDeclStackTraceEntry - If a crash occurs in the parser while parsing something related to a decl...
A (possibly-)qualified type.
Represents a struct/union/class.
Scope - A scope is a transient data structure that is used while parsing the program.
@ FunctionPrototypeScope
This is a scope that corresponds to the parameters within a function prototype.
@ ClassInheritanceScope
We are between inheritance colon and the real class/struct definition 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...
@ DeclScope
This is a scope that can contain a declaration.
DeclResult ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, SourceLocation ModulePrivateLoc, CXXScopeSpec &SS, TemplateIdAnnotation &TemplateId, const ParsedAttributesView &Attr, MultiTemplateParamsArg TemplateParameterLists, SkipBodyInfo *SkipBody=nullptr)
Decl * ActOnAliasDeclaration(Scope *CurScope, AccessSpecifier AS, MultiTemplateParamsArg TemplateParams, SourceLocation UsingLoc, UnqualifiedId &Name, const ParsedAttributesView &AttrList, TypeResult Type, Decl *DeclFromDeclSpec)
void PopParsingClass(ParsingClassState state)
void CodeCompleteTag(Scope *S, unsigned TagSpec)
void CodeCompleteUsing(Scope *S)
void ActOnDefinedDeclarationSpecifier(Decl *D)
Called once it is known whether a tag declaration is an anonymous union or struct.
void ActOnFinishCXXNonNestedClass()
TemplateParameterList * ActOnTemplateParameterList(unsigned Depth, SourceLocation ExportLoc, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
ActOnTemplateParameterList - Builds a TemplateParameterList, optionally constrained by RequiresClause...
void ActOnTagDefinitionError(Scope *S, Decl *TagDecl)
ActOnTagDefinitionError - Invoked when there was an unrecoverable error parsing the definition of a t...
void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl, SourceRange BraceRange)
ActOnTagFinishDefinition - Invoked once we have finished parsing the definition of a tag (enumeration...
bool ActOnAccessSpecifier(AccessSpecifier Access, SourceLocation ASLoc, SourceLocation ColonLoc, const ParsedAttributesView &Attrs)
ActOnAccessSpecifier - Parsed an access specifier followed by a colon.
Decl * ActOnNamespaceAliasDef(Scope *CurScope, SourceLocation NamespaceLoc, SourceLocation AliasLoc, IdentifierInfo *Alias, CXXScopeSpec &SS, SourceLocation IdentLoc, IdentifierInfo *Ident)
ParsedType getInheritingConstructorName(CXXScopeSpec &SS, SourceLocation NameLoc, IdentifierInfo &Name)
Handle the result of the special case name lookup for inheriting constructor declarations.
NamedDecl * ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, MultiTemplateParamsArg TemplateParameterLists, Expr *BitfieldWidth, const VirtSpecifiers &VS, InClassInitStyle InitStyle)
ActOnCXXMemberDeclarator - This is invoked when a C++ class member declarator is parsed.
TypeResult ActOnTypeName(Scope *S, Declarator &D)
BaseResult ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange, const ParsedAttributesView &Attrs, bool Virtual, AccessSpecifier Access, ParsedType basetype, SourceLocation BaseLoc, SourceLocation EllipsisLoc)
ActOnBaseSpecifier - Parsed a base specifier.
bool DiagnoseUnknownTemplateName(const IdentifierInfo &II, SourceLocation IILoc, Scope *S, const CXXScopeSpec *SS, TemplateTy &SuggestedTemplate, TemplateNameKind &SuggestedKind)