29#include "llvm/ADT/SmallString.h"
30#include "llvm/Support/TimeProfiler.h"
65 assert(Tok.
is(tok::kw_namespace) &&
"Not a namespace!");
69 if (Tok.
is(tok::code_completion)) {
77 InnerNamespaceInfoList ExtraNSs;
82 auto ReadAttributes = [&] {
86 if (Tok.
is(tok::kw___attribute)) {
87 ParseGNUAttributes(attrs);
92 ? diag::warn_cxx14_compat_ns_enum_attribute
93 : diag::ext_ns_enum_attribute)
95 ParseCXX11Attributes(attrs);
98 }
while (MoreToParse);
103 if (Tok.
is(tok::identifier)) {
106 while (Tok.
is(tok::coloncolon) &&
109 GetLookAheadToken(2).is(tok::identifier)))) {
111 InnerNamespaceInfo Info;
114 if (Tok.
is(tok::kw_inline)) {
117 FirstNestedInlineLoc = Info.InlineLoc;
123 ExtraNSs.push_back(Info);
132 if (!ExtraNSs.empty() && attrLoc.
isValid())
133 Diag(attrLoc, diag::err_unexpected_nested_namespace_attribute);
135 if (Tok.
is(tok::equal)) {
137 Diag(Tok, diag::err_expected) << tok::identifier;
143 Diag(attrLoc, diag::err_unexpected_namespace_attributes_alias);
145 Diag(InlineLoc, diag::err_inline_namespace_alias)
147 Decl *NSAlias = ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
152 if (T.consumeOpen()) {
154 Diag(Tok, diag::err_expected) << tok::l_brace;
156 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
163 Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope);
168 if (ExtraNSs.empty()) {
170 }
else if (InlineLoc.
isValid()) {
171 Diag(InlineLoc, diag::err_inline_nested_namespace_definition);
173 Diag(ExtraNSs[0].NamespaceLoc,
174 diag::warn_cxx14_compat_nested_namespace_definition);
175 if (FirstNestedInlineLoc.
isValid())
176 Diag(FirstNestedInlineLoc,
177 diag::warn_cxx17_compat_inline_nested_namespace_definition);
179 Diag(ExtraNSs[0].NamespaceLoc,
180 diag::warn_cxx14_compat_nested_namespace_definition);
181 if (FirstNestedInlineLoc.
isValid())
182 Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition);
184 TentativeParsingAction TPA(*
this);
186 Token rBraceToken = Tok;
189 if (!rBraceToken.
is(tok::r_brace)) {
190 Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition)
192 ExtraNSs.back().IdentLoc);
194 std::string NamespaceFix;
195 for (
const auto &ExtraNS : ExtraNSs) {
196 NamespaceFix +=
" { ";
197 if (ExtraNS.InlineLoc.isValid())
198 NamespaceFix +=
"inline ";
199 NamespaceFix +=
"namespace ";
200 NamespaceFix += ExtraNS.Ident->getName();
204 for (
unsigned i = 0, e = ExtraNSs.size(); i != e; ++i)
207 Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition)
210 ExtraNSs.back().IdentLoc),
216 if (FirstNestedInlineLoc.
isValid())
217 Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition);
223 ? diag::warn_cxx98_compat_inline_namespace
224 : diag::ext_inline_namespace);
231 getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident,
232 T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl,
false);
235 NamespaceLoc,
"parsing namespace");
239 ParseInnerNamespace(ExtraNSs, 0, InlineLoc, attrs, T);
242 NamespaceScope.Exit();
244 DeclEnd = T.getCloseLocation();
248 ImplicitUsingDirectiveDecl);
252void Parser::ParseInnerNamespace(
const InnerNamespaceInfoList &InnerNSs,
256 if (index == InnerNSs.size()) {
257 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
258 Tok.
isNot(tok::eof)) {
260 MaybeParseCXX11Attributes(DeclAttrs);
262 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
278 getCurScope(), InnerNSs[index].InlineLoc, InnerNSs[index].NamespaceLoc,
279 InnerNSs[index].IdentLoc, InnerNSs[index].Ident,
281 assert(!ImplicitUsingDirectiveDecl &&
282 "nested namespace definition cannot define anonymous namespace");
284 ParseInnerNamespace(InnerNSs, ++index, InlineLoc, attrs, Tracker);
286 NamespaceScope.Exit();
297 assert(Tok.
is(tok::equal) &&
"Not equal token");
301 if (Tok.
is(tok::code_completion)) {
309 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
317 if (Tok.
isNot(tok::identifier)) {
318 Diag(Tok, diag::err_expected_namespace_name);
337 if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name))
341 Alias, SS, IdentLoc, Ident);
352 assert(isTokenStringLiteral() &&
"Not a string literal!");
366 while (MaybeParseCXX11Attributes(DeclAttrs) ||
367 MaybeParseGNUAttributes(DeclSpecAttrs))
370 if (Tok.
isNot(tok::l_brace)) {
377 ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs, &DS);
385 ProhibitAttributes(DeclAttrs);
390 unsigned NestedModules = 0;
393 case tok::annot_module_begin:
398 case tok::annot_module_end:
405 case tok::annot_module_include:
418 MaybeParseCXX11Attributes(DeclAttrs);
419 ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs);
438Decl *Parser::ParseExportDeclaration() {
439 assert(Tok.
is(tok::kw_export));
447 if (Tok.
isNot(tok::l_brace)) {
450 MaybeParseCXX11Attributes(DeclAttrs);
452 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
460 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
461 Tok.
isNot(tok::eof)) {
463 MaybeParseCXX11Attributes(DeclAttrs);
465 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
470 T.getCloseLocation());
478 assert(Tok.
is(tok::kw_using) &&
"Not using token");
484 if (Tok.
is(tok::code_completion)) {
491 while (Tok.
is(tok::kw_template)) {
493 Diag(TemplateLoc, diag::err_unexpected_template_after_using)
498 if (Tok.
is(tok::kw_namespace)) {
500 if (TemplateInfo.Kind) {
502 Diag(UsingLoc, diag::err_templated_using_directive_declaration)
506 Decl *UsingDir = ParseUsingDirective(Context, UsingLoc, DeclEnd, Attrs);
511 return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd, Attrs,
529 assert(Tok.
is(tok::kw_namespace) &&
"Not 'namespace' token");
534 if (Tok.
is(tok::code_completion)) {
542 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
554 if (Tok.
isNot(tok::identifier)) {
555 Diag(Tok, diag::err_expected_namespace_name);
574 bool GNUAttr =
false;
575 if (Tok.
is(tok::kw___attribute)) {
577 ParseGNUAttributes(attrs);
582 if (ExpectAndConsume(tok::semi,
583 GNUAttr ? diag::err_expected_semi_after_attribute_list
584 : diag::err_expected_semi_after_namespace_name))
588 IdentLoc, NamespcName, attrs);
597 UsingDeclarator &D) {
604 if (Tok.
is(tok::kw___super)) {
611 if (ParseOptionalCXXScopeSpecifier(D.SS,
nullptr,
621 if (D.SS.isInvalid())
635 Tok.
is(tok::identifier) &&
641 !D.SS.getScopeRep()->getAsNamespace() &&
642 !D.SS.getScopeRep()->getAsNamespaceAlias()) {
646 D.Name.setConstructorName(
Type, IdLoc, IdLoc);
653 !(Tok.
is(tok::identifier) &&
NextToken().is(tok::equal)),
654 false,
nullptr, D.Name))
660 ? diag::warn_cxx17_compat_using_declaration_pack
661 : diag::ext_using_declaration_pack);
700 ? diag::warn_cxx17_compat_using_enum_declaration
701 : diag::ext_using_enum_declaration);
703 DiagnoseCXX11AttributeExtension(PrefixAttrs);
705 if (TemplateInfo.Kind) {
707 Diag(UsingLoc, diag::err_templated_using_directive_declaration)
713 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
725 if (Tok.
is(tok::code_completion)) {
731 if (!Tok.
is(tok::identifier)) {
733 << Tok.
is(tok::kw_enum);
740 getCurScope(), AS, UsingLoc, UELoc, IdentLoc, *IdentInfo, &SS);
747 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
748 "using-enum declaration"))
757 MaybeParseCXX11Attributes(MisplacedAttrs);
759 if (InInitStatement && Tok.
isNot(tok::identifier))
763 bool InvalidDeclarator = ParseUsingDeclarator(Context, D);
766 MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);
770 if (MisplacedAttrs.Range.isValid()) {
772 MisplacedAttrs.empty() ? nullptr : &MisplacedAttrs.front();
773 auto &
Range = MisplacedAttrs.Range;
774 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
775 ?
Diag(
Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr
776 :
Diag(
Range.getBegin(), diag::err_attributes_not_allowed))
784 if (Tok.
is(tok::equal) || InInitStatement) {
785 if (InvalidDeclarator) {
790 ProhibitAttributes(PrefixAttrs);
792 Decl *DeclFromDeclSpec =
nullptr;
793 Decl *AD = ParseAliasDeclarationAfterDeclarator(
794 TemplateInfo, UsingLoc, D, DeclEnd, AS, Attrs, &DeclFromDeclSpec);
798 DiagnoseCXX11AttributeExtension(PrefixAttrs);
803 if (TemplateInfo.Kind) {
805 Diag(UsingLoc, diag::err_templated_using_directive_declaration)
817 MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);
818 DiagnoseCXX11AttributeExtension(Attrs);
821 if (InvalidDeclarator)
826 if (D.TypenameLoc.isValid() &&
828 Diag(D.Name.getSourceRange().getBegin(),
829 diag::err_typename_identifiers_only)
836 D.TypenameLoc, D.SS, D.Name,
837 D.EllipsisLoc, Attrs);
839 DeclsInGroup.push_back(UD);
847 InvalidDeclarator = ParseUsingDeclarator(Context, D);
850 if (DeclsInGroup.size() > 1)
853 ? diag::warn_cxx17_compat_multi_using_declaration
854 : diag::ext_multi_using_declaration);
858 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
859 !Attrs.
empty() ?
"attributes list"
860 : UELoc.
isValid() ?
"using-enum declaration"
861 :
"using declaration"))
867Decl *Parser::ParseAliasDeclarationAfterDeclarator(
871 if (ExpectAndConsume(tok::equal)) {
877 ? diag::warn_cxx98_compat_alias_declaration
878 : diag::ext_alias_declaration);
882 if (TemplateInfo.Kind == ParsedTemplateInfo::Template &&
885 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization)
887 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
889 if (SpecKind != -1) {
893 D.Name.TemplateId->RAngleLoc);
895 Range = TemplateInfo.getSourceRange();
896 Diag(
Range.getBegin(), diag::err_alias_declaration_specialization)
897 << SpecKind <<
Range;
904 Diag(D.Name.StartLocation, diag::err_alias_declaration_not_identifier);
908 }
else if (D.TypenameLoc.isValid())
909 Diag(D.TypenameLoc, diag::err_alias_declaration_not_identifier)
911 SourceRange(D.TypenameLoc, D.SS.isNotEmpty() ? D.SS.getEndLoc()
913 else if (D.SS.isNotEmpty())
914 Diag(D.SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)
916 if (D.EllipsisLoc.isValid())
917 Diag(D.EllipsisLoc, diag::err_alias_declaration_pack_expansion)
920 Decl *DeclFromDeclSpec =
nullptr;
925 AS, &DeclFromDeclSpec, &Attrs);
927 *OwnedType = DeclFromDeclSpec;
931 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
932 !Attrs.
empty() ?
"attributes list"
933 :
"alias declaration"))
938 TemplateParams ? TemplateParams->data() :
nullptr,
939 TemplateParams ? TemplateParams->size() : 0);
941 UsingLoc, D.Name, Attrs, TypeAlias,
947 if (
const auto *BO = dyn_cast_or_null<BinaryOperator>(AssertExpr)) {
948 if (BO->getOpcode() == BO_LAnd &&
949 isa<StringLiteral>(BO->getRHS()->IgnoreImpCasts()))
964 assert(Tok.
isOneOf(tok::kw_static_assert, tok::kw__Static_assert) &&
965 "Not a static_assert declaration");
968 const char *TokName = Tok.
getName();
972 if (Tok.
is(tok::kw_static_assert)) {
975 Diag(Tok, diag::warn_c2x_compat_keyword) << Tok.
getName();
980 Diag(Tok, diag::warn_cxx98_compat_static_assert);
986 if (T.consumeOpen()) {
987 Diag(Tok, diag::err_expected) << tok::l_paren;
995 if (AssertExpr.isInvalid()) {
1001 if (Tok.
is(tok::r_paren)) {
1004 DiagVal = diag::warn_cxx14_compat_static_assert_no_message;
1006 DiagVal = diag::ext_cxx_static_assert_no_message;
1008 DiagVal = diag::warn_c17_compat_static_assert_no_message;
1010 DiagVal = diag::ext_c_static_assert_no_message;
1014 if (ExpectAndConsume(tok::comma)) {
1019 if (!isTokenStringLiteral()) {
1020 Diag(Tok, diag::err_expected_string_literal)
1036 ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, TokName);
1039 AssertMessage.
get(),
1040 T.getCloseLocation());
1049 assert(Tok.
isOneOf(tok::kw_decltype, tok::annot_decltype) &&
1050 "Not a decltype specifier");
1056 if (Tok.
is(tok::annot_decltype)) {
1057 Result = getExprAnnotation(Tok);
1062 ConsumeAnnotationToken();
1063 if (
Result.isInvalid()) {
1069 Diag(Tok, diag::warn_cxx98_compat_decltype);
1074 if (T.expectAndConsume(diag::err_expected_lparen_after,
"decltype",
1077 return T.getOpenLocation() == Tok.
getLocation() ? StartLoc
1078 : T.getOpenLocation();
1082 if (Tok.
is(tok::kw_auto) &&
NextToken().is(tok::r_paren)) {
1087 ? diag::warn_cxx11_compat_decltype_auto_type_specifier
1088 : diag::ext_decltype_auto_type_specifier);
1102 if (
Result.isInvalid()) {
1105 EndLoc = ConsumeParen();
1112 assert(Tok.
is(tok::semi));
1126 if (T.getCloseLocation().isInvalid()) {
1130 return T.getCloseLocation();
1133 if (
Result.isInvalid()) {
1135 return T.getCloseLocation();
1138 EndLoc = T.getCloseLocation();
1140 assert(!
Result.isInvalid());
1142 const char *PrevSpec =
nullptr;
1147 PrevSpec, DiagID,
Result.get(), Policy)
1149 PrevSpec, DiagID, Policy)) {
1150 Diag(StartLoc, DiagID) << PrevSpec;
1156void Parser::AnnotateExistingDecltypeSpecifier(
const DeclSpec &DS,
1172 Tok.
setKind(tok::annot_decltype);
1173 setExprAnnotation(Tok,
1184#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
1185 case tok::kw___##Trait: \
1186 return DeclSpec::TST_##Trait;
1187#include "clang/Basic/TransformTypeTraits.def"
1189 llvm_unreachable(
"passed in an unhandled type transformation built-in");
1193bool Parser::MaybeParseTypeTransformTypeSpecifier(
DeclSpec &DS) {
1198 DeclSpec::TST TypeTransformTST = TypeTransformTokToDeclSpec();
1202 if (T.expectAndConsume(diag::err_expected_lparen_after, Tok.
getName(),
1207 if (
Result.isInvalid()) {
1213 if (T.getCloseLocation().isInvalid())
1216 const char *PrevSpec =
nullptr;
1221 Diag(StartLoc, DiagID) << PrevSpec;
1247 if (Tok.
is(tok::kw_typename)) {
1248 Diag(Tok, diag::err_expected_class_name_not_template)
1255 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
1265 if (Tok.
isOneOf(tok::kw_decltype, tok::annot_decltype)) {
1272 EndLocation = ParseDecltypeSpecifier(DS);
1280 if (Tok.
is(tok::annot_template_id)) {
1286 assert(Tok.
is(tok::annot_typename) &&
"template-id -> type failed");
1289 ConsumeAnnotationToken();
1296 if (Tok.
isNot(tok::identifier)) {
1297 Diag(Tok, diag::err_expected_class_name);
1304 if (Tok.
is(tok::less)) {
1313 Diag(IdLoc, diag::err_unknown_template_name) <<
Id;
1324 if (Tok.
is(tok::annot_template_id) &&
1325 takeTemplateIdAnnotation(Tok)->mightBeType())
1331 if (Tok.
isNot(tok::annot_typename))
1338 ConsumeAnnotationToken();
1351 Diag(IdLoc, diag::err_expected_class_name);
1356 EndLocation = IdLoc;
1364 const char *PrevSpec =
nullptr;
1374void Parser::ParseMicrosoftInheritanceClassAttributes(
ParsedAttributes &attrs) {
1375 while (Tok.
isOneOf(tok::kw___single_inheritance,
1376 tok::kw___multiple_inheritance,
1377 tok::kw___virtual_inheritance)) {
1381 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0, Kind);
1388bool Parser::isValidAfterTypeSpecifier(
bool CouldBeBitfield) {
1399 case tok::identifier:
1401 case tok::coloncolon:
1402 case tok::annot_cxxscope:
1403 case tok::annot_typename:
1404 case tok::annot_template_id:
1405 case tok::kw_decltype:
1408 case tok::kw_operator:
1409 case tok::kw___declspec:
1414 case tok::kw___attribute:
1415 case tok::annot_pragma_pack:
1417 case tok::annot_pragma_ms_pragma:
1419 case tok::annot_pragma_ms_vtordisp:
1421 case tok::annot_pragma_ms_pointers_to_members:
1424 return CouldBeBitfield ||
1427 case tok::kw___cdecl:
1428 case tok::kw___fastcall:
1429 case tok::kw___stdcall:
1430 case tok::kw___thiscall:
1431 case tok::kw___vectorcall:
1437 case tok::kw_volatile:
1438 case tok::kw_restrict:
1439 case tok::kw__Atomic:
1440 case tok::kw___unaligned:
1444 case tok::kw_inline:
1445 case tok::kw_virtual:
1446 case tok::kw_friend:
1448 case tok::kw_static:
1449 case tok::kw_extern:
1450 case tok::kw_typedef:
1451 case tok::kw_register:
1453 case tok::kw_mutable:
1454 case tok::kw_thread_local:
1455 case tok::kw_constexpr:
1456 case tok::kw_consteval:
1457 case tok::kw_constinit:
1473 if (!isKnownToBeTypeSpecifier(
NextToken()))
1530 const ParsedTemplateInfo &TemplateInfo,
1532 DeclSpecContext DSC,
1535 if (TagTokKind == tok::kw_struct)
1537 else if (TagTokKind == tok::kw___interface)
1539 else if (TagTokKind == tok::kw_class)
1542 assert(TagTokKind == tok::kw_union &&
"Not a class specifier");
1546 if (Tok.
is(tok::code_completion)) {
1560 const bool shouldDelayDiagsInTag =
1561 (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate);
1566 MaybeParseAttributes(PAKM_CXX11 | PAKM_Declspec | PAKM_GNU, attrs);
1569 if (Tok.
isOneOf(tok::kw___single_inheritance, tok::kw___multiple_inheritance,
1570 tok::kw___virtual_inheritance))
1571 ParseMicrosoftInheritanceClassAttributes(attrs);
1574 MaybeParseAttributes(PAKM_CXX11 | PAKM_Declspec | PAKM_GNU, attrs);
1584#include
"clang/Basic/TransformTypeTraits.def"
1585 tok::kw___is_abstract,
1586 tok::kw___is_aggregate,
1587 tok::kw___is_arithmetic,
1589 tok::kw___is_assignable,
1590 tok::kw___is_base_of,
1591 tok::kw___is_bounded_array,
1593 tok::kw___is_complete_type,
1594 tok::kw___is_compound,
1596 tok::kw___is_constructible,
1597 tok::kw___is_convertible,
1598 tok::kw___is_convertible_to,
1599 tok::kw___is_destructible,
1602 tok::kw___is_floating_point,
1604 tok::kw___is_function,
1605 tok::kw___is_fundamental,
1606 tok::kw___is_integral,
1607 tok::kw___is_interface_class,
1608 tok::kw___is_literal,
1609 tok::kw___is_lvalue_expr,
1610 tok::kw___is_lvalue_reference,
1611 tok::kw___is_member_function_pointer,
1612 tok::kw___is_member_object_pointer,
1613 tok::kw___is_member_pointer,
1614 tok::kw___is_nothrow_assignable,
1615 tok::kw___is_nothrow_constructible,
1616 tok::kw___is_nothrow_destructible,
1617 tok::kw___is_nullptr,
1618 tok::kw___is_object,
1620 tok::kw___is_pointer,
1621 tok::kw___is_polymorphic,
1622 tok::kw___is_reference,
1623 tok::kw___is_referenceable,
1624 tok::kw___is_rvalue_expr,
1625 tok::kw___is_rvalue_reference,
1627 tok::kw___is_scalar,
1628 tok::kw___is_scoped_enum,
1629 tok::kw___is_sealed,
1630 tok::kw___is_signed,
1631 tok::kw___is_standard_layout,
1632 tok::kw___is_trivial,
1633 tok::kw___is_trivially_equality_comparable,
1634 tok::kw___is_trivially_assignable,
1635 tok::kw___is_trivially_constructible,
1636 tok::kw___is_trivially_copyable,
1637 tok::kw___is_unbounded_array,
1639 tok::kw___is_unsigned,
1641 tok::kw___is_volatile))
1647 TryKeywordIdentFallback(
true);
1649 struct PreserveAtomicIdentifierInfoRAII {
1650 PreserveAtomicIdentifierInfoRAII(
Token &Tok,
bool Enabled)
1651 : AtomicII(nullptr) {
1654 assert(Tok.
is(tok::kw__Atomic));
1659 ~PreserveAtomicIdentifierInfoRAII() {
1662 AtomicII->revertIdentifierToTokenID(tok::kw__Atomic);
1672 bool ShouldChangeAtomicToIdentifier =
getLangOpts().MSVCCompat &&
1673 Tok.
is(tok::kw__Atomic) &&
1675 PreserveAtomicIdentifierInfoRAII AtomicTokenGuard(
1676 Tok, ShouldChangeAtomicToIdentifier);
1686 if (TemplateInfo.TemplateParams)
1689 bool HasValidSpec =
true;
1690 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
1694 HasValidSpec =
false;
1697 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::annot_template_id)) {
1698 Diag(Tok, diag::err_expected) << tok::identifier;
1699 HasValidSpec =
false;
1707 auto RecoverFromUndeclaredTemplateName = [&](
IdentifierInfo *Name,
1710 bool KnownUndeclared) {
1711 Diag(NameLoc, diag::err_explicit_spec_non_template)
1712 << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
1713 << TagTokKind << Name << TemplateArgRange << KnownUndeclared;
1717 if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {
1718 if (TemplateParams->size() > 1) {
1719 TemplateParams->pop_back();
1721 TemplateParams =
nullptr;
1722 const_cast<ParsedTemplateInfo &
>(TemplateInfo).Kind =
1723 ParsedTemplateInfo::NonTemplate;
1725 }
else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
1727 TemplateParams =
nullptr;
1728 const_cast<ParsedTemplateInfo &
>(TemplateInfo).Kind =
1729 ParsedTemplateInfo::NonTemplate;
1730 const_cast<ParsedTemplateInfo &
>(TemplateInfo).TemplateLoc =
1732 const_cast<ParsedTemplateInfo &
>(TemplateInfo).ExternLoc =
1741 if (Tok.
is(tok::identifier)) {
1749 TemplateArgList TemplateArgs;
1751 if (ParseTemplateIdAfterTemplateName(
true, LAngleLoc, TemplateArgs,
1757 RecoverFromUndeclaredTemplateName(
1758 Name, NameLoc,
SourceRange(LAngleLoc, RAngleLoc),
false);
1760 }
else if (Tok.
is(tok::annot_template_id)) {
1761 TemplateId = takeTemplateIdAnnotation(Tok);
1762 NameLoc = ConsumeAnnotationToken();
1769 RecoverFromUndeclaredTemplateName(
1772 TemplateId =
nullptr;
1785 Diag(TemplateId->
LAngleLoc, diag::err_template_spec_syntax_non_template)
1786 << TemplateId->
Name <<
static_cast<int>(TemplateId->
Kind) << Range;
1821 MaybeParseCXX11Attributes(Attributes);
1826 AllowDefiningTypeSpec::No ||
1829 else if (Tok.
is(tok::l_brace) ||
1830 (DSC != DeclSpecContext::DSC_association &&
1832 (isClassCompatibleKeyword() &&
1848 }
else if (isClassCompatibleKeyword() &&
1855 TentativeParsingAction PA(*
this);
1858 while (isClassCompatibleKeyword()) {
1864 if (Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square)) {
1868 }
else if (Tok.
is(tok::kw_alignas) &&
NextToken().is(tok::l_paren)) {
1880 if (Tok.
isOneOf(tok::l_brace, tok::colon))
1886 }
else if (!isTypeSpecifier(DSC) &&
1887 (Tok.
is(tok::semi) ||
1890 if (Tok.
isNot(tok::semi)) {
1893 ExpectAndConsume(tok::semi, diag::err_expected_after,
1911 auto *FirstAttr = Attributes.
empty() ? nullptr : &Attributes.
front();
1913 (FirstAttr && FirstAttr->isRegularKeywordAttribute()
1914 ?
Diag(Loc, diag::err_keyword_not_allowed) << FirstAttr
1915 :
Diag(Loc, diag::err_attributes_not_allowed))
1927 if (!Name && !TemplateId &&
1932 Diag(StartLoc, diag::err_anon_type_definition)
1959 }
else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1962 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
1963 diag::err_keyword_not_allowed,
1967 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
1978 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
1979 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
1980 diag::err_keyword_not_allowed,
1990 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
2003 "Expected a definition here");
2007 TemplateParams =
nullptr;
2012 diag::err_explicit_instantiation_with_definition)
2021 std::nullopt, LAngleLoc,
nullptr));
2022 TemplateParams = &FakedParamLists;
2029 SS, *TemplateId, attrs,
2032 TemplateParams ? TemplateParams->size() : 0),
2035 }
else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
2042 ProhibitAttributes(attrs);
2045 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
2046 TagType, StartLoc, SS, Name, NameLoc, attrs);
2048 TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
2049 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
2050 diag::err_keyword_not_allowed,
2057 TemplateParams ? TemplateParams->size() : 0));
2060 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
2061 diag::err_keyword_not_allowed,
2065 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
2068 Diag(Tok, diag::err_template_defn_explicit_instantiation)
2070 TemplateParams =
nullptr;
2073 bool IsDependent =
false;
2083 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
2086 TagOrTempResult = Actions.
ActOnTag(
2090 DSC == DeclSpecContext::DSC_type_specifier,
2091 DSC == DeclSpecContext::DSC_template_param ||
2092 DSC == DeclSpecContext::DSC_template_type_arg,
2093 OffsetOfState, &SkipBody);
2100 Name, StartLoc, NameLoc);
2107 if (shouldDelayDiagsInTag) {
2108 diagsFromTag.done();
2110 TemplateInfo.Kind == ParsedTemplateInfo::Template)
2111 diagsFromTag.redelay();
2116 assert(Tok.
is(tok::l_brace) ||
2118 isClassCompatibleKeyword());
2120 SkipCXXMemberSpecification(StartLoc, AttrFixitLoc,
TagType,
2121 TagOrTempResult.
get());
2123 ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs,
TagType,
2124 TagOrTempResult.
get());
2129 ParseStructUnionBody(StartLoc,
TagType, cast<RecordDecl>(D));
2142 const char *PrevSpec =
nullptr;
2147 NameLoc.
isValid() ? NameLoc : StartLoc,
2149 }
else if (!TagOrTempResult.
isInvalid()) {
2151 TagType, StartLoc, NameLoc.
isValid() ? NameLoc : StartLoc, PrevSpec,
2152 DiagID, TagOrTempResult.
get(), Owned, Policy);
2159 Diag(StartLoc, DiagID) << PrevSpec;
2175 (TemplateInfo.Kind || !isValidAfterTypeSpecifier(
false))) {
2176 if (Tok.
isNot(tok::semi)) {
2178 ExpectAndConsume(tok::semi, diag::err_expected_after,
2196void Parser::ParseBaseClause(
Decl *ClassDecl) {
2197 assert(Tok.
is(tok::colon) &&
"Not a base clause");
2206 if (
Result.isInvalid()) {
2212 BaseInfo.push_back(
Result.get());
2237 bool IsVirtual =
false;
2241 MaybeParseCXX11Attributes(Attributes);
2247 CheckMisplacedCXX11Attribute(Attributes, StartLoc);
2257 CheckMisplacedCXX11Attribute(Attributes, StartLoc);
2261 if (Tok.
is(tok::kw_virtual)) {
2265 Diag(VirtualLoc, diag::err_dup_virtual)
2272 CheckMisplacedCXX11Attribute(Attributes, StartLoc);
2286 TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation);
2302 Access, BaseType.
get(), BaseLoc,
2317 case tok::kw_private:
2319 case tok::kw_protected:
2321 case tok::kw_public:
2330void Parser::HandleMemberFunctionDeclDelays(
Declarator &DeclaratorInfo,
2337 if (!NeedLateParse) {
2341 if (Param->hasUnparsedDefaultArg()) {
2342 NeedLateParse =
true;
2348 if (NeedLateParse) {
2351 auto LateMethod =
new LateParsedMethodDeclaration(
this, ThisDecl);
2352 getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
2357 LateMethod->DefaultArgs.reserve(FTI.
NumParams);
2359 LateMethod->DefaultArgs.push_back(LateParsedDefaultArgument(
2396 if (II == Ident_override)
2399 if (II == Ident_sealed)
2402 if (II == Ident_abstract)
2405 if (II == Ident_final)
2408 if (II == Ident_GNU_final)
2419void Parser::ParseOptionalCXX11VirtSpecifierSeq(
VirtSpecifiers &VS,
2438 const char *PrevSpec =
nullptr;
2456 ? diag::warn_cxx98_compat_override_control_keyword
2457 : diag::ext_override_control_keyword)
2466bool Parser::isCXX11FinalKeyword()
const {
2475bool Parser::isClassCompatibleKeyword()
const {
2485bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
2487 LateParsedAttrList &LateParsedAttrs) {
2498 if (Tok.
isNot(tok::colon))
2499 ParseDeclarator(DeclaratorInfo);
2505 "don't know where identifier would go yet?");
2509 }
else if (Tok.
is(tok::kw_requires)) {
2510 ParseTrailingRequiresClause(DeclaratorInfo);
2512 ParseOptionalCXX11VirtSpecifierSeq(
2513 VS, getCurrentClass().IsInterface,
2516 MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo,
2521 if (Tok.
is(tok::kw_asm)) {
2523 ExprResult AsmLabel(ParseSimpleAsm(
true, &Loc));
2524 if (AsmLabel.isInvalid())
2534 DiagnoseAndSkipCXX11Attributes();
2535 MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
2536 DiagnoseAndSkipCXX11Attributes();
2541 ParseOptionalCXX11VirtSpecifierSeq(
2542 VS, getCurrentClass().IsInterface,
2548 if (AL.isKnownToGCC() && !AL.isCXX11Attribute())
2549 Diag(AL.getLoc(), diag::warn_gcc_attribute_location);
2551 MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo,
2568void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
2574 ParseTypeQualifierListOpt(
2575 DS, AR_NoAttributesParsed,
false,
2576 false, llvm::function_ref<
void()>([&]() {
2584 auto DeclSpecCheck = [&](
DeclSpec::TQ TypeQual, StringRef FixItName,
2587 auto &MQ =
Function.getOrCreateMethodQualifiers();
2588 if (!(MQ.getTypeQualifiers() & TypeQual)) {
2589 std::string Name(FixItName.data());
2592 MQ.SetTypeQual(TypeQual, SpecLoc);
2594 Diag(SpecLoc, diag::err_declspec_after_virtspec)
2603 bool RefQualifierIsLValueRef =
true;
2605 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc)) {
2606 const char *Name = (RefQualifierIsLValueRef ?
"& " :
"&& ");
2609 Function.RefQualifierIsLValueRef = RefQualifierIsLValueRef;
2610 Function.RefQualifierLoc = RefQualifierLoc;
2612 Diag(RefQualifierLoc, diag::err_declspec_after_virtspec)
2613 << (RefQualifierIsLValueRef ?
"&" :
"&&")
2661 const ParsedTemplateInfo &TemplateInfo,
2663 if (Tok.
is(tok::at)) {
2665 Diag(Tok, diag::err_at_defs_cxx);
2667 Diag(Tok, diag::err_at_in_class);
2683 bool MalformedTypeSpec =
false;
2684 if (!TemplateInfo.Kind &&
2685 Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw___super)) {
2687 MalformedTypeSpec =
true;
2690 if (Tok.
isNot(tok::annot_cxxscope))
2691 isAccessDecl =
false;
2692 else if (
NextToken().is(tok::identifier))
2693 isAccessDecl = GetLookAheadToken(2).
is(tok::semi);
2700 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
2713 false,
false,
true,
true,
2714 false, &TemplateKWLoc, Name)) {
2720 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
2721 "access declaration")) {
2737 if (!TemplateInfo.Kind &&
2738 Tok.
isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
2744 if (Tok.
is(tok::kw_template)) {
2745 assert(!TemplateInfo.TemplateParams &&
2746 "Nested template improperly parsed?");
2755 if (Tok.
is(tok::kw___extension__)) {
2759 return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,
2765 MaybeParseCXX11Attributes(DeclAttrs);
2770 if (Tok.
is(tok::annot_attr_openmp))
2771 return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, DeclAttrs);
2773 if (Tok.
is(tok::kw_using)) {
2778 while (Tok.
is(tok::kw_template)) {
2780 Diag(TemplateLoc, diag::err_unexpected_template_after_using)
2784 if (Tok.
is(tok::kw_namespace)) {
2785 Diag(UsingLoc, diag::err_using_namespace_in_class);
2792 UsingLoc, DeclEnd, DeclAttrs, AS);
2796 MaybeParseMicrosoftAttributes(DeclSpecAttrs);
2799 LateParsedAttrList CommonLateParsedAttrs;
2806 if (MalformedTypeSpec)
2814 bool IsTemplateSpecOrInst =
2815 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
2816 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
2819 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DeclSpecContext::DSC_class,
2820 &CommonLateParsedAttrs);
2822 if (IsTemplateSpecOrInst)
2823 diagsFromTag.done();
2831 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate &&
2832 DiagnoseMissingSemiAfterTagDefinition(DS, AS, DeclSpecContext::DSC_class,
2833 &CommonLateParsedAttrs))
2837 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data()
2839 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
2843 ProhibitAttributes(DeclAttrs);
2847 getCurScope(), AS, DS, DeclAttrs, TemplateParams,
false, AnonRecord);
2848 DS.complete(TheDecl);
2850 Decl *decls[] = {AnonRecord, TheDecl};
2858 if (TemplateInfo.TemplateParams)
2863 LateParsedAttrList LateParsedAttrs;
2868 auto TryConsumePureSpecifier = [&](
bool AllowDefinition) {
2869 if (Tok.
isNot(tok::equal))
2874 if (
Zero.isNot(tok::numeric_constant) ||
2878 auto &
After = GetLookAheadToken(2);
2879 if (!
After.isOneOf(tok::semi, tok::comma) &&
2880 !(AllowDefinition &&
2881 After.isOneOf(tok::l_brace, tok::colon, tok::kw_try)))
2892 bool ExpectSemi =
true;
2900 if (ParseCXXMemberDeclaratorBeforeInitializer(
2901 DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs)) {
2906 if (IsTemplateSpecOrInst)
2914 TryConsumePureSpecifier(
true);
2925 if (Tok.
isOneOf(tok::l_brace, tok::colon, tok::kw_try)) {
2927 }
else if (Tok.
is(tok::equal)) {
2929 if (KW.
is(tok::kw_default))
2931 else if (KW.
is(tok::kw_delete))
2933 else if (KW.
is(tok::code_completion)) {
2949 ProhibitAttributes(DeclAttrs);
2966 diag::err_function_declared_typedef);
2972 Decl *FunDecl = ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo,
2973 TemplateInfo, VS, PureSpecLoc);
2976 for (
unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
2977 CommonLateParsedAttrs[i]->addDecl(FunDecl);
2979 for (
unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
2980 LateParsedAttrs[i]->addDecl(FunDecl);
2983 LateParsedAttrs.clear();
2986 if (Tok.
is(tok::semi))
2987 ConsumeExtraSemi(AfterMemberFunctionDefinition);
2999 bool HasStaticInitializer =
false;
3004 Diag(Tok, diag::err_anon_bitfield_member_init);
3008 if (!TryConsumePureSpecifier(
false))
3010 HasStaticInitializer =
true;
3017 if (BitfieldSize.
get())
3019 ? diag::warn_cxx17_compat_bitfield_member_init
3020 : diag::ext_bitfield_member_init);
3023 HasStaticInitializer =
true;
3039 if (AL.isCXX11Attribute() || AL.isRegularKeywordAttribute()) {
3040 auto Loc = AL.getRange().getBegin();
3041 (AL.isRegularKeywordAttribute()
3042 ?
Diag(Loc, diag::err_keyword_not_allowed) << AL
3043 :
Diag(Loc, diag::err_attributes_not_allowed))
3051 getCurScope(), AS, DeclaratorInfo, TemplateParams, BitfieldSize.
get(),
3052 VS, HasInClassInit);
3055 ThisDecl ? dyn_cast<VarTemplateDecl>(ThisDecl) :
nullptr)
3058 ThisDecl = VT->getTemplatedDecl();
3067 DeclaratorInfo.getDeclSpec().getStorageClassSpec() ==
3070 HasStaticInitializer =
true;
3074 Diag(PureSpecLoc, diag::err_duplicate_virt_specifier) <<
"abstract";
3076 if (ThisDecl && PureSpecLoc.
isValid())
3085 ? diag::warn_cxx98_compat_nonstatic_member_init
3086 : diag::ext_nonstatic_member_init);
3088 if (DeclaratorInfo.isArrayOfUnknownBound()) {
3094 Diag(Tok, diag::err_incomplete_array_member_init);
3101 ParseCXXNonStaticMemberInitializer(ThisDecl);
3102 }
else if (HasStaticInitializer) {
3105 ThisDecl, DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
3107 if (Init.isInvalid()) {
3111 }
else if (ThisDecl)
3121 for (
unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i)
3122 CommonLateParsedAttrs[i]->addDecl(ThisDecl);
3124 for (
unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i)
3125 LateParsedAttrs[i]->addDecl(ThisDecl);
3128 DeclsInGroup.push_back(ThisDecl);
3130 if (DeclaratorInfo.isFunctionDeclarator() &&
3131 DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=
3133 HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);
3135 LateParsedAttrs.clear();
3137 DeclaratorInfo.complete(ThisDecl);
3150 Diag(CommaLoc, diag::err_expected_semi_declaration)
3157 DeclaratorInfo.clear();
3161 DeclaratorInfo.setCommaLoc(CommaLoc);
3166 DiagnoseAndSkipCXX11Attributes();
3167 MaybeParseGNUAttributes(DeclaratorInfo);
3168 DiagnoseAndSkipCXX11Attributes();
3170 if (ParseCXXMemberDeclaratorBeforeInitializer(
3171 DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs))
3176 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
3207ExprResult Parser::ParseCXXMemberInitializer(
Decl *D,
bool IsFunction,
3209 assert(Tok.
isOneOf(tok::equal, tok::l_brace) &&
3210 "Data member initializer not starting with '=' or '{'");
3214 isa_and_present<FieldDecl>(D)
3219 if (Tok.
is(tok::kw_delete)) {
3226 if (IsFunction || Next.isOneOf(tok::semi, tok::comma, tok::eof)) {
3234 }
else if (Tok.
is(tok::kw_default)) {
3236 Diag(Tok, diag::err_default_delete_in_multiple_declaration)
3244 if (
const auto *PD = dyn_cast_or_null<MSPropertyDecl>(D)) {
3245 Diag(Tok, diag::err_ms_property_initializer) << PD;
3248 return ParseInitializer();
3256 assert(isCXX11FinalKeyword() &&
"not a class definition");
3262 CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);
3267 if (Tok.
isNot(tok::colon) && Tok.
isNot(tok::l_brace))
3274 if (Tok.
is(tok::colon)) {
3277 ParsingClassDefinition ParsingDef(*
this,
TagDecl,
true,
3283 ParseBaseClause(
nullptr);
3287 if (!Tok.
is(tok::l_brace)) {
3289 diag::err_expected_lbrace_after_base_specifiers);
3295 assert(Tok.
is(tok::l_brace));
3301 if (Tok.
is(tok::kw___attribute)) {
3303 MaybeParseGNUAttributes(Attrs);
3313 case tok::kw___if_exists:
3314 case tok::kw___if_not_exists:
3315 ParseMicrosoftIfExistsClassDeclaration(
TagType, AccessAttrs, AS);
3320 ConsumeExtraSemi(InsideStruct,
TagType);
3324 case tok::annot_pragma_vis:
3325 HandlePragmaVisibility();
3327 case tok::annot_pragma_pack:
3330 case tok::annot_pragma_align:
3331 HandlePragmaAlign();
3333 case tok::annot_pragma_ms_pointers_to_members:
3334 HandlePragmaMSPointersToMembers();
3336 case tok::annot_pragma_ms_pragma:
3337 HandlePragmaMSPragma();
3339 case tok::annot_pragma_ms_vtordisp:
3340 HandlePragmaMSVtorDisp();
3342 case tok::annot_pragma_dump:
3346 case tok::kw_namespace:
3348 DiagnoseUnexpectedNamespace(cast<NamedDecl>(
TagDecl));
3351 case tok::kw_private:
3355 return ParseCXXClassMemberDeclaration(AS, AccessAttrs);
3357 case tok::kw_public:
3358 case tok::kw_protected: {
3368 AccessAttrs.
clear();
3369 MaybeParseGNUAttributes(AccessAttrs);
3374 Diag(EndLoc, diag::err_expected)
3378 Diag(EndLoc, diag::err_expected)
3390 AccessAttrs.
clear();
3396 case tok::annot_attr_openmp:
3397 case tok::annot_pragma_openmp:
3398 return ParseOpenMPDeclarativeDirectiveWithExtDecl(
3406 ConsumeAnnotationToken();
3409 return ParseCXXClassMemberDeclaration(AS, AccessAttrs);
3419void Parser::ParseCXXMemberSpecification(
SourceLocation RecordLoc,
3426 "Invalid TagType!");
3428 llvm::TimeTraceScope TimeScope(
"ParseClass", [&]() {
3429 if (
auto *TD = dyn_cast_or_null<NamedDecl>(
TagDecl))
3430 return TD->getQualifiedNameAsString();
3431 return std::string(
"<anonymous>");
3435 "parsing struct/union/class body");
3439 bool NonNestedClass =
true;
3440 if (!ClassStack.empty()) {
3442 if (S->isClassScope()) {
3444 NonNestedClass =
false;
3447 if (getCurrentClass().IsInterface) {
3448 Diag(RecordLoc, diag::err_invalid_member_in_interface)
3451 ? cast<NamedDecl>(
TagDecl)->getQualifiedNameAsString()
3457 if (S->isFunctionScope())
3468 ParsingClassDefinition ParsingDef(*
this,
TagDecl, NonNestedClass,
3476 bool IsFinalSpelledSealed =
false;
3477 bool IsAbstract =
false;
3485 if (isCXX11FinalKeyword()) {
3488 Diag(Skipped, diag::err_duplicate_class_virt_specifier)
3493 IsFinalSpelledSealed =
true;
3498 Diag(Skipped, diag::err_duplicate_class_virt_specifier)
3506 Diag(FinalLoc, diag::err_override_control_interface)
3510 ? diag::warn_cxx98_compat_override_control_keyword
3511 : diag::ext_override_control_keyword)
3514 Diag(FinalLoc, diag::ext_ms_sealed_keyword);
3516 Diag(AbstractLoc, diag::ext_ms_abstract_keyword);
3518 Diag(FinalLoc, diag::ext_warn_gnu_final);
3521 "not a class definition");
3527 CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);
3536 if (!Tok.
is(tok::colon) && !Tok.
is(tok::l_brace)) {
3543 if (Tok.
is(tok::colon)) {
3544 ParseScope InheritanceScope(
this,
getCurScope()->getFlags() |
3548 if (!Tok.
is(tok::l_brace)) {
3549 bool SuggestFixIt =
false;
3553 case tok::kw_private:
3554 case tok::kw_protected:
3555 case tok::kw_public:
3558 case tok::kw_static_assert:
3562 case tok::kw_template:
3563 SuggestFixIt =
true;
3565 case tok::identifier:
3566 SuggestFixIt = isConstructorDeclarator(
true);
3569 SuggestFixIt = isCXXSimpleDeclaration(
false);
3574 Diag(BraceLoc, diag::err_expected_lbrace_after_base_specifiers);
3588 assert(Tok.
is(tok::l_brace));
3594 IsFinalSpelledSealed, IsAbstract,
3595 T.getOpenLocation());
3610 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
3611 Tok.
isNot(tok::eof)) {
3613 ParseCXXClassMemberDeclarationWithPragmas(
3615 MaybeDestroyTemplateIds();
3624 MaybeParseGNUAttributes(attrs);
3628 T.getOpenLocation(),
3629 T.getCloseLocation(), attrs);
3636 if (
TagDecl && NonNestedClass) {
3643 ParseLexedPragmas(getCurrentClass());
3644 ParseLexedAttributes(getCurrentClass());
3645 ParseLexedMethodDeclarations(getCurrentClass());
3650 ParseLexedMemberInitializers(getCurrentClass());
3651 ParseLexedMethodDefs(getCurrentClass());
3652 PrevTokLocation = SavedPrevTokLocation;
3667void Parser::DiagnoseUnexpectedNamespace(
NamedDecl *D) {
3668 assert(Tok.
is(tok::kw_namespace));
3673 Diag(Tok.
getLocation(), diag::note_missing_end_of_definition_before) << D;
3707void Parser::ParseConstructorInitializer(
Decl *ConstructorDecl) {
3708 assert(Tok.
is(tok::colon) &&
3709 "Constructor initializer always starts with ':'");
3717 bool AnyErrors =
false;
3720 if (Tok.
is(tok::code_completion)) {
3727 MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
3729 MemInitializers.push_back(MemInit.
get());
3733 if (Tok.
is(tok::comma))
3735 else if (Tok.
is(tok::l_brace))
3740 Tok.
isOneOf(tok::identifier, tok::coloncolon)) {
3742 Diag(Loc, diag::err_ctor_init_missing_comma)
3748 << tok::l_brace << tok::comma;
3773 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
3786 if (Tok.
is(tok::identifier)) {
3791 }
else if (Tok.
is(tok::annot_decltype)) {
3796 ParseDecltypeSpecifier(DS);
3799 ? takeTemplateIdAnnotation(Tok)
3804 assert(Tok.
is(tok::annot_typename) &&
"template-id -> type failed");
3806 ConsumeAnnotationToken();
3808 Diag(Tok, diag::err_expected_member_or_base_name);
3815 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3818 ExprResult InitList = ParseBraceInitializer();
3828 TemplateTypeTy.
get(), DS, IdLoc,
3829 InitList.
get(), EllipsisLoc);
3830 }
else if (Tok.
is(tok::l_paren)) {
3835 ExprVector ArgExprs;
3836 auto RunSignatureHelp = [&] {
3840 ConstructorDecl, SS, TemplateTypeTy.
get(), ArgExprs, II,
3841 T.getOpenLocation(),
false);
3842 CalledSignatureHelp =
true;
3843 return PreferredType;
3845 if (Tok.
isNot(tok::r_paren) && ParseExpressionList(ArgExprs, [&] {
3846 PreferredType.enterFunctionArgument(Tok.
getLocation(),
3863 ConstructorDecl,
getCurScope(), SS, II, TemplateTypeTy.
get(), DS, IdLoc,
3864 T.getOpenLocation(), ArgExprs, T.getCloseLocation(), EllipsisLoc);
3871 return Diag(Tok, diag::err_expected_either) << tok::l_paren << tok::l_brace;
3873 return Diag(Tok, diag::err_expected) << tok::l_paren;
3891 ExceptionSpecTokens =
nullptr;
3895 if (Tok.
isNot(tok::kw_throw) && Tok.
isNot(tok::kw_noexcept))
3899 bool IsNoexcept = Tok.
is(tok::kw_noexcept);
3900 Token StartTok = Tok;
3904 if (!Tok.
is(tok::l_paren)) {
3907 Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
3908 NoexceptExpr =
nullptr;
3912 Diag(Tok, diag::err_expected_lparen_after) <<
"throw";
3918 ExceptionSpecTokens->push_back(StartTok);
3919 ExceptionSpecTokens->push_back(Tok);
3920 SpecificationRange.
setEnd(ConsumeParen());
3922 ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens,
3925 SpecificationRange.
setEnd(ExceptionSpecTokens->back().getLocation());
3931 if (Tok.
is(tok::kw_throw)) {
3932 Result = ParseDynamicExceptionSpecification(
3933 SpecificationRange, DynamicExceptions, DynamicExceptionRanges);
3934 assert(DynamicExceptions.size() == DynamicExceptionRanges.size() &&
3935 "Produced different number of exception types and ranges.");
3939 if (Tok.
isNot(tok::kw_noexcept))
3942 Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
3950 if (Tok.
is(tok::l_paren)) {
3959 NoexceptRange =
SourceRange(KeywordLoc, T.getCloseLocation());
3966 NoexceptRange =
SourceRange(KeywordLoc, KeywordLoc);
3970 SpecificationRange = NoexceptRange;
3975 if (Tok.
is(tok::kw_throw)) {
3976 Diag(Tok.
getLocation(), diag::err_dynamic_and_noexcept_specification);
3977 ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions,
3978 DynamicExceptionRanges);
3981 Diag(Tok.
getLocation(), diag::err_dynamic_and_noexcept_specification);
3989 if (
P.getLangOpts().CPlusPlus11) {
3990 const char *Replacement = IsNoexcept ?
"noexcept" :
"noexcept(false)";
3991 P.Diag(Range.getBegin(),
P.getLangOpts().CPlusPlus17 && !IsNoexcept
3992 ? diag::ext_dynamic_exception_spec
3993 : diag::warn_exception_spec_deprecated)
3995 P.Diag(Range.getBegin(), diag::note_exception_spec_deprecated)
4014 assert(Tok.
is(tok::kw_throw) &&
"expected throw");
4018 if (T.consumeOpen()) {
4019 Diag(Tok, diag::err_expected_lparen_after) <<
"throw";
4026 if (Tok.
is(tok::ellipsis)) {
4029 Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
4031 SpecificationRange.
setEnd(T.getCloseLocation());
4038 while (Tok.
isNot(tok::r_paren)) {
4041 if (Tok.
is(tok::ellipsis)) {
4046 Range.setEnd(Ellipsis);
4047 if (!Res.isInvalid())
4051 if (!Res.isInvalid()) {
4052 Exceptions.push_back(Res.get());
4053 Ranges.push_back(Range);
4061 SpecificationRange.
setEnd(T.getCloseLocation());
4063 Exceptions.empty());
4070 bool MayBeFollowedByDirectInit) {
4071 assert(Tok.
is(tok::arrow) &&
"expected arrow");
4081void Parser::ParseTrailingRequiresClause(
Declarator &D) {
4082 assert(Tok.
is(tok::kw_requires) &&
"expected requires");
4093 std::optional<Sema::CXXThisScopeRAII> ThisScope;
4094 InitCXXThisScopeForDeclaratorIfRelevant(D, D.
getDeclSpec(), ThisScope);
4096 TrailingRequiresClause =
4099 TrailingRequiresClause =
4104 diag::err_requires_clause_on_declarator_not_declaring_a_function);
4109 SkipUntil({tok::l_brace, tok::arrow, tok::kw_try, tok::comma, tok::colon},
4120 ParseTrailingReturnType(Range,
false);
4124 diag::err_requires_clause_must_appear_after_trailing_return)
4128 FunctionChunk.TrailingReturnType = TrailingReturnType.
get();
4129 FunctionChunk.TrailingReturnTypeLoc =
Range.getBegin();
4131 SkipUntil({tok::equal, tok::l_brace, tok::arrow, tok::kw_try, tok::comma},
4140 bool NonNestedClass,
4142 assert((NonNestedClass || !ClassStack.empty()) &&
4143 "Nested class without outer class");
4144 ClassStack.push(
new ParsingClass(ClassDecl, NonNestedClass, IsInterface));
4150void Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
4151 for (
unsigned I = 0, N =
Class->LateParsedDeclarations.size(); I != N; ++I)
4152 delete Class->LateParsedDeclarations[I];
4163 assert(!ClassStack.empty() &&
"Mismatched push/pop for class parsing");
4167 ParsingClass *Victim = ClassStack.top();
4169 if (Victim->TopLevelClass) {
4172 DeallocateParsedClasses(Victim);
4175 assert(!ClassStack.empty() &&
"Missing top-level class?");
4177 if (Victim->LateParsedDeclarations.empty()) {
4182 DeallocateParsedClasses(Victim);
4190 "Nested class outside of class scope?");
4191 ClassStack.top()->LateParsedDeclarations.push_back(
4192 new LateParsedClass(
this, Victim));
4219 case tok::code_completion:
4226 case tok::numeric_constant: {
4234 StringRef Spelling = PP.
getSpelling(ExpansionLoc, ExpansionBuf);
4235 if (Spelling ==
"__clang__") {
4239 Diag(Tok, diag::warn_wrong_clang_attr_namespace)
4255 case tok::pipeequal:
4256 case tok::caretequal:
4258 case tok::exclaimequal:
4264 StringRef Spelling = PP.
getSpelling(SpellingLoc, SpellingBuf);
4278 if (T.consumeOpen()) {
4279 Diag(Tok, diag::err_expected) << tok::l_paren;
4283 if (AttrName->
isStr(
"directive")) {
4289 OMPBeginTok.
setKind(tok::annot_attr_openmp);
4291 OpenMPTokens.push_back(OMPBeginTok);
4293 ConsumeAndStoreUntil(tok::r_paren, OpenMPTokens,
false,
4297 OMPEndTok.
setKind(tok::annot_pragma_openmp_end);
4299 OpenMPTokens.push_back(OMPEndTok);
4301 assert(AttrName->
isStr(
"sequence") &&
4302 "Expected either 'directive' or 'sequence'");
4311 IdentifierInfo *Ident = TryParseCXX11AttributeIdentifier(IdentLoc);
4315 if (Ident && Ident->
isStr(
"omp") && !ExpectAndConsume(tok::coloncolon))
4316 Ident = TryParseCXX11AttributeIdentifier(IdentLoc);
4320 if (!Ident || (!Ident->
isStr(
"directive") && !Ident->
isStr(
"sequence"))) {
4327 ParseOpenMPAttributeArgs(Ident, OpenMPTokens);
4341 case ParsedAttr::AT_CarriesDependency:
4342 case ParsedAttr::AT_Deprecated:
4343 case ParsedAttr::AT_FallThrough:
4344 case ParsedAttr::AT_CXX11NoReturn:
4345 case ParsedAttr::AT_NoUniqueAddress:
4346 case ParsedAttr::AT_Likely:
4347 case ParsedAttr::AT_Unlikely:
4349 case ParsedAttr::AT_WarnUnusedResult:
4350 return !ScopeName && AttrName->
getName().equals(
"nodiscard");
4351 case ParsedAttr::AT_Unused:
4352 return !ScopeName && AttrName->
getName().equals(
"maybe_unused");
4372bool Parser::ParseCXX11AttributeArgs(
4376 assert(Tok.
is(tok::l_paren) &&
"Not a C++11 attribute argument list");
4380 LO.CPlusPlus ? ParsedAttr::Form::CXX11() :
ParsedAttr::Form::
C2x();
4386 Form = ParsedAttr::Form::Microsoft();
4403 if (ScopeName && (ScopeName->
isStr(
"gnu") || ScopeName->
isStr(
"__gnu__"))) {
4406 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
4407 ScopeLoc, Form,
nullptr);
4411 if (ScopeName && ScopeName->
isStr(
"omp")) {
4413 ? diag::warn_omp51_compat_attributes
4414 : diag::ext_omp_attributes);
4416 ParseOpenMPAttributeArgs(AttrName, OpenMPTokens);
4425 if (ScopeName && (ScopeName->
isStr(
"clang") || ScopeName->
isStr(
"_Clang")))
4426 NumArgs = ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc,
4427 ScopeName, ScopeLoc, Form);
4429 NumArgs = ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
4430 ScopeName, ScopeLoc, Form);
4432 if (!Attrs.
empty() &&
4439 if (
Attr.getMaxArgs() && !NumArgs) {
4442 Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;
4443 Attr.setInvalid(
true);
4444 }
else if (!
Attr.getMaxArgs()) {
4448 Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
4451 Attr.setInvalid(
true);
4484 if (Tok.
is(tok::kw_alignas)) {
4486 Diag(Tok, diag::warn_c2x_compat_keyword) << Tok.
getName();
4489 ParseAlignmentSpecifier(Attrs, EndLoc);
4496 Attrs.
addNew(AttrName, Loc,
nullptr, Loc,
nullptr, 0, Tok.
getKind());
4501 assert(Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square) &&
4502 "Not a double square bracket attribute list");
4505 Diag(OpenLoc, diag::warn_cxx98_compat_attribute);
4508 checkCompoundToken(OpenLoc, tok::l_square, CompoundToken::AttrBegin);
4513 if (Tok.
is(tok::kw_using)) {
4515 ? diag::warn_cxx14_compat_using_attribute_ns
4516 : diag::ext_using_attribute_ns);
4519 CommonScopeName = TryParseCXX11AttributeIdentifier(
4521 if (!CommonScopeName) {
4529 bool AttrParsed =
false;
4530 while (!Tok.
isOneOf(tok::r_square, tok::semi, tok::eof)) {
4534 if (ExpectAndConsume(tok::comma)) {
4548 AttrName = TryParseCXX11AttributeIdentifier(
4556 ScopeName = AttrName;
4559 AttrName = TryParseCXX11AttributeIdentifier(
4568 if (CommonScopeName) {
4570 Diag(ScopeLoc, diag::err_using_attribute_ns_conflict)
4573 ScopeName = CommonScopeName;
4574 ScopeLoc = CommonScopeLoc;
4579 if (Tok.
is(tok::l_paren))
4580 AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc,
4581 ScopeName, ScopeLoc, OpenMPTokens);
4587 ScopeName, ScopeLoc,
nullptr, 0,
4589 : ParsedAttr::Form::C2x());
4594 Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) << AttrName;
4599 if (Tok.
is(tok::semi)) {
4605 if (ExpectAndConsume(tok::r_square))
4607 else if (Tok.
is(tok::r_square))
4608 checkCompoundToken(CloseLoc, tok::r_square, CompoundToken::AttrEnd);
4611 if (ExpectAndConsume(tok::r_square))
4626 ParseCXX11AttributeSpecifier(Attrs, &EndLoc);
4627 }
while (isAllowedCXX11AttributeSpecifier());
4632void Parser::DiagnoseAndSkipCXX11Attributes() {
4641 (Keyword ?
Diag(StartLoc, diag::err_keyword_not_allowed) << Keyword
4642 :
Diag(StartLoc, diag::err_attributes_not_allowed))
4650 if (!isCXX11AttributeSpecifier())
4654 if (Tok.
is(tok::l_square)) {
4658 EndLoc = T.getCloseLocation();
4663 assert(Tok.
is(tok::kw_alignas) &&
"not an attribute specifier");
4666 if (!T.consumeOpen())
4668 EndLoc = T.getCloseLocation();
4670 }
while (isCXX11AttributeSpecifier());
4677 assert(Tok.
is(tok::identifier) &&
"Not a Microsoft attribute list");
4679 assert(UuidIdent->
getName() ==
"uuid" &&
"Not a Microsoft attribute list");
4686 if (T.consumeOpen()) {
4687 Diag(Tok, diag::err_expected) << tok::l_paren;
4692 if (Tok.
is(tok::string_literal)) {
4697 ArgExprs.push_back(StringResult.
get());
4714 while (Tok.
isNot(tok::r_paren)) {
4716 Diag(Tok, diag::err_attribute_uuid_malformed_guid);
4721 SpellingBuffer.resize(Tok.
getLength() + 1);
4723 StringRef TokSpelling = PP.
getSpelling(Tok, SpellingBuffer, &Invalid);
4728 StrBuffer += TokSpelling;
4734 Diag(Tok, diag::err_attribute_uuid_malformed_guid);
4744 Toks[0].
setKind(tok::string_literal);
4750 ArgExprs.push_back(UuidString);
4753 if (!T.consumeClose()) {
4756 ParsedAttr::Form::Microsoft());
4769 assert(Tok.
is(tok::l_square) &&
"Not a Microsoft attribute list");
4780 SkipUntil(tok::r_square, tok::identifier,
4782 if (Tok.
is(tok::code_completion)) {
4789 if (Tok.
isNot(tok::identifier))
4792 ParseMicrosoftUuidAttributeArgs(Attrs);
4802 bool AttrParsed =
false;
4803 if (Tok.
is(tok::l_paren)) {
4806 ParseCXX11AttributeArgs(II, NameLoc, Attrs, &EndLoc,
nullptr,
4808 ReplayOpenMPAttributeTokens(OpenMPTokens);
4812 ParsedAttr::Form::Microsoft());
4819 EndLoc = T.getCloseLocation();
4820 }
while (Tok.
is(tok::l_square));
4825void Parser::ParseMicrosoftIfExistsClassDeclaration(
4828 IfExistsCondition
Result;
4829 if (ParseMicrosoftIfExistsCondition(
Result))
4833 if (Braces.consumeOpen()) {
4834 Diag(Tok, diag::err_expected) << tok::l_brace;
4838 switch (
Result.Behavior) {
4844 Diag(
Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
4854 while (Tok.
isNot(tok::r_brace) && !isEofOrEom()) {
4856 if (Tok.
isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) {
4857 ParseMicrosoftIfExistsClassDeclaration(
TagType, AccessAttrs, CurAS);
4862 if (Tok.
is(tok::semi)) {
4863 ConsumeExtraSemi(InsideStruct,
TagType);
4873 if (Tok.
is(tok::colon))
4877 Diag(Tok, diag::err_expected) << tok::colon;
4883 ParseCXXClassMemberDeclaration(CurAS, AccessAttrs);
4886 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".
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.
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 ParseStringLiteralExpression(bool AllowUserDefinedLiteral=false)
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 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)
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
Decl * ActOnUsingEnumDeclaration(Scope *CurScope, AccessSpecifier AS, SourceLocation UsingLoc, SourceLocation EnumLoc, SourceLocation IdentLoc, IdentifierInfo &II, CXXScopeSpec *SS=nullptr)
NamedDecl * ActOnFriendFunctionDecl(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParams)
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
TypeResult ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, const CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation TagLoc, SourceLocation NameLoc)
ASTContext & getASTContext() const
Decl * ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, SourceLocation LBraceLoc)
We have parsed the start of an export declaration, including the '{' (if present).
ParsingClassState PushParsingClass()
void CodeCompleteUsingDirective(Scope *S)
Decl * ActOnStartNamespaceDef(Scope *S, SourceLocation InlineLoc, SourceLocation NamespaceLoc, SourceLocation IdentLoc, IdentifierInfo *Ident, SourceLocation LBrace, const ParsedAttributesView &AttrList, UsingDirectiveDecl *&UsingDecl, bool IsNested)
ActOnStartNamespaceDef - This is called at the start of a namespace definition.
void ActOnBaseSpecifiers(Decl *ClassDecl, MutableArrayRef< CXXBaseSpecifier * > Bases)
ActOnBaseSpecifiers - Attach the given base specifiers to the class, after checking whether there are...
ExprResult ActOnNoexceptSpec(Expr *NoexceptExpr, ExceptionSpecificationType &EST)
Check the given noexcept-specifier, convert its expression, and compute the appropriate ExceptionSpec...
void CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D, const VirtSpecifiers *VS=nullptr)
void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AttrList, const ProcessDeclAttributeOptions &Options=ProcessDeclAttributeOptions())
ProcessDeclAttributeList - Apply all the decl attributes in the specified attribute list to the speci...
void CodeCompleteNamespaceDecl(Scope *S)
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
void ProcessDeclAttributeDelayed(Decl *D, const ParsedAttributesView &AttrList)
ExprResult ActOnFinishTrailingRequiresClause(ExprResult ConstraintExpr)
void CodeCompleteNamespaceAliasDecl(Scope *S)
void ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagDecl, SourceLocation FinalLoc, bool IsFinalSpelledSealed, bool IsAbstract, SourceLocation LBraceLoc)
ActOnStartCXXMemberDeclarations - Invoked when we have parsed a C++ record definition's base-specifie...
void CodeCompleteAttribute(AttributeCommonInfo::Syntax Syntax, AttributeCompletion Completion=AttributeCompletion::Attribute, const IdentifierInfo *Scope=nullptr)
bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody)
Perform ODR-like check for C/ObjC when merging tag types from modules.