28#include "llvm/ADT/SmallString.h"
29#include "llvm/Support/TimeProfiler.h"
64 assert(Tok.
is(tok::kw_namespace) &&
"Not a namespace!");
68 if (Tok.
is(tok::code_completion)) {
76 InnerNamespaceInfoList ExtraNSs;
81 auto ReadAttributes = [&] {
85 if (Tok.
is(tok::kw___attribute)) {
86 ParseGNUAttributes(attrs);
91 ? diag::warn_cxx14_compat_ns_enum_attribute
92 : diag::ext_ns_enum_attribute)
94 ParseCXX11Attributes(attrs);
97 }
while (MoreToParse);
102 if (Tok.
is(tok::identifier)) {
105 while (Tok.
is(tok::coloncolon) &&
108 GetLookAheadToken(2).is(tok::identifier)))) {
110 InnerNamespaceInfo Info;
113 if (Tok.
is(tok::kw_inline)) {
116 FirstNestedInlineLoc = Info.InlineLoc;
122 ExtraNSs.push_back(Info);
131 if (!ExtraNSs.empty() && attrLoc.
isValid())
132 Diag(attrLoc, diag::err_unexpected_nested_namespace_attribute);
134 if (Tok.
is(tok::equal)) {
136 Diag(Tok, diag::err_expected) << tok::identifier;
142 Diag(attrLoc, diag::err_unexpected_namespace_attributes_alias);
144 Diag(InlineLoc, diag::err_inline_namespace_alias)
146 Decl *NSAlias = ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
151 if (T.consumeOpen()) {
153 Diag(Tok, diag::err_expected) << tok::l_brace;
155 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
162 Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope);
167 if (ExtraNSs.empty()) {
169 }
else if (InlineLoc.
isValid()) {
170 Diag(InlineLoc, diag::err_inline_nested_namespace_definition);
172 Diag(ExtraNSs[0].NamespaceLoc,
173 diag::warn_cxx14_compat_nested_namespace_definition);
174 if (FirstNestedInlineLoc.
isValid())
175 Diag(FirstNestedInlineLoc,
176 diag::warn_cxx17_compat_inline_nested_namespace_definition);
178 Diag(ExtraNSs[0].NamespaceLoc,
179 diag::warn_cxx14_compat_nested_namespace_definition);
180 if (FirstNestedInlineLoc.
isValid())
181 Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition);
183 TentativeParsingAction TPA(*
this);
185 Token rBraceToken = Tok;
188 if (!rBraceToken.
is(tok::r_brace)) {
189 Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition)
191 ExtraNSs.back().IdentLoc);
193 std::string NamespaceFix;
194 for (
const auto &ExtraNS : ExtraNSs) {
195 NamespaceFix +=
" { ";
196 if (ExtraNS.InlineLoc.isValid())
197 NamespaceFix +=
"inline ";
198 NamespaceFix +=
"namespace ";
199 NamespaceFix += ExtraNS.Ident->getName();
203 for (
unsigned i = 0, e = ExtraNSs.size(); i != e; ++i)
206 Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition)
209 ExtraNSs.back().IdentLoc),
215 if (FirstNestedInlineLoc.
isValid())
216 Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition);
222 ? diag::warn_cxx98_compat_inline_namespace
223 : diag::ext_inline_namespace);
230 getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident,
231 T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl,
false);
234 NamespaceLoc,
"parsing namespace");
238 ParseInnerNamespace(ExtraNSs, 0, InlineLoc, attrs, T);
241 NamespaceScope.Exit();
243 DeclEnd = T.getCloseLocation();
247 ImplicitUsingDirectiveDecl);
251void Parser::ParseInnerNamespace(
const InnerNamespaceInfoList &InnerNSs,
255 if (index == InnerNSs.size()) {
256 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
257 Tok.
isNot(tok::eof)) {
259 MaybeParseCXX11Attributes(DeclAttrs);
261 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
277 getCurScope(), InnerNSs[index].InlineLoc, InnerNSs[index].NamespaceLoc,
278 InnerNSs[index].IdentLoc, InnerNSs[index].Ident,
280 assert(!ImplicitUsingDirectiveDecl &&
281 "nested namespace definition cannot define anonymous namespace");
283 ParseInnerNamespace(InnerNSs, ++index, InlineLoc, attrs, Tracker);
285 NamespaceScope.Exit();
296 assert(Tok.
is(tok::equal) &&
"Not equal token");
300 if (Tok.
is(tok::code_completion)) {
308 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
316 if (Tok.
isNot(tok::identifier)) {
317 Diag(Tok, diag::err_expected_namespace_name);
336 if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name))
340 Alias, SS, IdentLoc, Ident);
351 assert(isTokenStringLiteral() &&
"Not a string literal!");
365 while (MaybeParseCXX11Attributes(DeclAttrs) ||
366 MaybeParseGNUAttributes(DeclSpecAttrs))
369 if (Tok.
isNot(tok::l_brace)) {
376 ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs, &DS);
384 ProhibitAttributes(DeclAttrs);
389 unsigned NestedModules = 0;
392 case tok::annot_module_begin:
397 case tok::annot_module_end:
404 case tok::annot_module_include:
417 MaybeParseCXX11Attributes(DeclAttrs);
418 ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs);
437Decl *Parser::ParseExportDeclaration() {
438 assert(Tok.
is(tok::kw_export));
446 if (Tok.
isNot(tok::l_brace)) {
449 MaybeParseCXX11Attributes(DeclAttrs);
451 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
462 Diag(ExportLoc, diag::err_export_empty)
466 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
467 Tok.
isNot(tok::eof)) {
469 MaybeParseCXX11Attributes(DeclAttrs);
471 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
476 T.getCloseLocation());
484 assert(Tok.
is(tok::kw_using) &&
"Not using token");
490 if (Tok.
is(tok::code_completion)) {
497 while (Tok.
is(tok::kw_template)) {
499 Diag(TemplateLoc, diag::err_unexpected_template_after_using)
504 if (Tok.
is(tok::kw_namespace)) {
506 if (TemplateInfo.Kind) {
508 Diag(UsingLoc, diag::err_templated_using_directive_declaration)
512 Decl *UsingDir = ParseUsingDirective(Context, UsingLoc, DeclEnd, Attrs);
517 return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd, Attrs,
535 assert(Tok.
is(tok::kw_namespace) &&
"Not 'namespace' token");
540 if (Tok.
is(tok::code_completion)) {
548 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
560 if (Tok.
isNot(tok::identifier)) {
561 Diag(Tok, diag::err_expected_namespace_name);
580 bool GNUAttr =
false;
581 if (Tok.
is(tok::kw___attribute)) {
583 ParseGNUAttributes(attrs);
588 if (ExpectAndConsume(tok::semi,
589 GNUAttr ? diag::err_expected_semi_after_attribute_list
590 : diag::err_expected_semi_after_namespace_name))
594 IdentLoc, NamespcName, attrs);
603 UsingDeclarator &D) {
610 if (Tok.
is(tok::kw___super)) {
617 if (ParseOptionalCXXScopeSpecifier(D.SS,
nullptr,
627 if (D.SS.isInvalid())
641 Tok.
is(tok::identifier) &&
646 !D.SS.getScopeRep()->getAsNamespace() &&
647 !D.SS.getScopeRep()->getAsNamespaceAlias()) {
651 D.Name.setConstructorName(
Type, IdLoc, IdLoc);
658 !(Tok.
is(tok::identifier) &&
NextToken().is(tok::equal)),
659 false,
nullptr, D.Name))
665 ? diag::warn_cxx17_compat_using_declaration_pack
666 : diag::ext_using_declaration_pack);
705 ? diag::warn_cxx17_compat_using_enum_declaration
706 : diag::ext_using_enum_declaration);
708 DiagnoseCXX11AttributeExtension(PrefixAttrs);
710 if (TemplateInfo.Kind) {
712 Diag(UsingLoc, diag::err_templated_using_directive_declaration)
718 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
730 if (Tok.
is(tok::code_completion)) {
736 if (!Tok.
is(tok::identifier)) {
738 << Tok.
is(tok::kw_enum);
745 getCurScope(), AS, UsingLoc, UELoc, IdentLoc, *IdentInfo, &SS);
752 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
753 "using-enum declaration"))
762 MaybeParseCXX11Attributes(MisplacedAttrs);
764 if (InInitStatement && Tok.
isNot(tok::identifier))
768 bool InvalidDeclarator = ParseUsingDeclarator(Context, D);
771 MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);
775 if (MisplacedAttrs.Range.isValid()) {
776 Diag(MisplacedAttrs.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 Token SavedTok = Tok;
973 if (Tok.
is(tok::kw_static_assert)) {
979 Diag(Tok, diag::warn_cxx98_compat_static_assert);
985 if (T.consumeOpen()) {
986 Diag(Tok, diag::err_expected) << tok::l_paren;
994 if (AssertExpr.isInvalid()) {
1000 if (Tok.
is(tok::r_paren)) {
1003 DiagVal = diag::warn_cxx14_compat_static_assert_no_message;
1005 DiagVal = diag::ext_cxx_static_assert_no_message;
1007 DiagVal = diag::warn_c17_compat_static_assert_no_message;
1009 DiagVal = diag::ext_c_static_assert_no_message;
1013 if (ExpectAndConsume(tok::comma)) {
1018 if (!isTokenStringLiteral()) {
1019 Diag(Tok, diag::err_expected_string_literal)
1036 ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert,
1040 AssertMessage.
get(),
1041 T.getCloseLocation());
1050 assert(Tok.
isOneOf(tok::kw_decltype, tok::annot_decltype) &&
1051 "Not a decltype specifier");
1057 if (Tok.
is(tok::annot_decltype)) {
1058 Result = getExprAnnotation(Tok);
1063 ConsumeAnnotationToken();
1064 if (
Result.isInvalid()) {
1070 Diag(Tok, diag::warn_cxx98_compat_decltype);
1075 if (T.expectAndConsume(diag::err_expected_lparen_after,
"decltype",
1078 return T.getOpenLocation() == Tok.
getLocation() ? StartLoc
1079 : T.getOpenLocation();
1083 if (Tok.
is(tok::kw_auto) &&
NextToken().is(tok::r_paren)) {
1088 ? diag::warn_cxx11_compat_decltype_auto_type_specifier
1089 : diag::ext_decltype_auto_type_specifier);
1103 if (
Result.isInvalid()) {
1106 EndLoc = ConsumeParen();
1113 assert(Tok.
is(tok::semi));
1127 if (T.getCloseLocation().isInvalid()) {
1131 return T.getCloseLocation();
1134 if (
Result.isInvalid()) {
1136 return T.getCloseLocation();
1139 EndLoc = T.getCloseLocation();
1141 assert(!
Result.isInvalid());
1143 const char *PrevSpec =
nullptr;
1148 PrevSpec, DiagID,
Result.get(), Policy)
1150 PrevSpec, DiagID, Policy)) {
1151 Diag(StartLoc, DiagID) << PrevSpec;
1157void Parser::AnnotateExistingDecltypeSpecifier(
const DeclSpec &DS,
1173 Tok.
setKind(tok::annot_decltype);
1174 setExprAnnotation(Tok,
1185#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
1186 case tok::kw___##Trait: \
1187 return DeclSpec::TST_##Trait;
1188#include "clang/Basic/TransformTypeTraits.def"
1190 llvm_unreachable(
"passed in an unhandled type transformation built-in");
1194bool Parser::MaybeParseTypeTransformTypeSpecifier(
DeclSpec &DS) {
1199 DeclSpec::TST TypeTransformTST = TypeTransformTokToDeclSpec();
1203 if (T.expectAndConsume(diag::err_expected_lparen_after, Tok.
getName(),
1208 if (
Result.isInvalid()) {
1214 if (T.getCloseLocation().isInvalid())
1217 const char *PrevSpec =
nullptr;
1222 Diag(StartLoc, DiagID) << PrevSpec;
1248 if (Tok.
is(tok::kw_typename)) {
1249 Diag(Tok, diag::err_expected_class_name_not_template)
1256 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
1266 if (Tok.
isOneOf(tok::kw_decltype, tok::annot_decltype)) {
1273 EndLocation = ParseDecltypeSpecifier(DS);
1281 if (Tok.
is(tok::annot_template_id)) {
1287 assert(Tok.
is(tok::annot_typename) &&
"template-id -> type failed");
1290 ConsumeAnnotationToken();
1297 if (Tok.
isNot(tok::identifier)) {
1298 Diag(Tok, diag::err_expected_class_name);
1305 if (Tok.
is(tok::less)) {
1314 Diag(IdLoc, diag::err_unknown_template_name) <<
Id;
1325 if (Tok.
is(tok::annot_template_id) &&
1326 takeTemplateIdAnnotation(Tok)->mightBeType())
1332 if (Tok.
isNot(tok::annot_typename))
1339 ConsumeAnnotationToken();
1352 Diag(IdLoc, diag::err_expected_class_name);
1357 EndLocation = IdLoc;
1365 const char *PrevSpec =
nullptr;
1375void Parser::ParseMicrosoftInheritanceClassAttributes(
ParsedAttributes &attrs) {
1376 while (Tok.
isOneOf(tok::kw___single_inheritance,
1377 tok::kw___multiple_inheritance,
1378 tok::kw___virtual_inheritance)) {
1381 attrs.
addNew(AttrName, AttrNameLoc,
nullptr, AttrNameLoc,
nullptr, 0,
1389bool Parser::isValidAfterTypeSpecifier(
bool CouldBeBitfield) {
1398 case tok::identifier:
1400 case tok::coloncolon:
1401 case tok::annot_cxxscope:
1402 case tok::annot_typename:
1403 case tok::annot_template_id:
1404 case tok::kw_decltype:
1407 case tok::kw_operator:
1408 case tok::kw___declspec:
1413 case tok::kw___attribute:
1414 case tok::annot_pragma_pack:
1416 case tok::annot_pragma_ms_pragma:
1418 case tok::annot_pragma_ms_vtordisp:
1420 case tok::annot_pragma_ms_pointers_to_members:
1423 return CouldBeBitfield ||
1426 case tok::kw___cdecl:
1427 case tok::kw___fastcall:
1428 case tok::kw___stdcall:
1429 case tok::kw___thiscall:
1430 case tok::kw___vectorcall:
1436 case tok::kw_volatile:
1437 case tok::kw_restrict:
1438 case tok::kw__Atomic:
1439 case tok::kw___unaligned:
1443 case tok::kw_inline:
1444 case tok::kw_virtual:
1445 case tok::kw_friend:
1447 case tok::kw_static:
1448 case tok::kw_extern:
1449 case tok::kw_typedef:
1450 case tok::kw_register:
1452 case tok::kw_mutable:
1453 case tok::kw_thread_local:
1454 case tok::kw_constexpr:
1455 case tok::kw_consteval:
1456 case tok::kw_constinit:
1472 if (!isKnownToBeTypeSpecifier(
NextToken()))
1529 const ParsedTemplateInfo &TemplateInfo,
1531 DeclSpecContext DSC,
1534 if (TagTokKind == tok::kw_struct)
1536 else if (TagTokKind == tok::kw___interface)
1538 else if (TagTokKind == tok::kw_class)
1541 assert(TagTokKind == tok::kw_union &&
"Not a class specifier");
1545 if (Tok.
is(tok::code_completion)) {
1559 const bool shouldDelayDiagsInTag =
1560 (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate);
1565 MaybeParseAttributes(PAKM_CXX11 | PAKM_Declspec | PAKM_GNU, attrs);
1568 if (Tok.
isOneOf(tok::kw___single_inheritance, tok::kw___multiple_inheritance,
1569 tok::kw___virtual_inheritance))
1570 ParseMicrosoftInheritanceClassAttributes(attrs);
1573 MaybeParseAttributes(PAKM_CXX11 | PAKM_Declspec | PAKM_GNU, attrs);
1583#include
"clang/Basic/TransformTypeTraits.def"
1584 tok::kw___is_abstract,
1585 tok::kw___is_aggregate,
1586 tok::kw___is_arithmetic,
1588 tok::kw___is_assignable,
1589 tok::kw___is_base_of,
1590 tok::kw___is_bounded_array,
1592 tok::kw___is_complete_type,
1593 tok::kw___is_compound,
1595 tok::kw___is_constructible,
1596 tok::kw___is_convertible,
1597 tok::kw___is_convertible_to,
1598 tok::kw___is_destructible,
1601 tok::kw___is_floating_point,
1603 tok::kw___is_function,
1604 tok::kw___is_fundamental,
1605 tok::kw___is_integral,
1606 tok::kw___is_interface_class,
1607 tok::kw___is_literal,
1608 tok::kw___is_lvalue_expr,
1609 tok::kw___is_lvalue_reference,
1610 tok::kw___is_member_function_pointer,
1611 tok::kw___is_member_object_pointer,
1612 tok::kw___is_member_pointer,
1613 tok::kw___is_nothrow_assignable,
1614 tok::kw___is_nothrow_constructible,
1615 tok::kw___is_nothrow_destructible,
1616 tok::kw___is_nullptr,
1617 tok::kw___is_object,
1619 tok::kw___is_pointer,
1620 tok::kw___is_polymorphic,
1621 tok::kw___is_reference,
1622 tok::kw___is_referenceable,
1623 tok::kw___is_rvalue_expr,
1624 tok::kw___is_rvalue_reference,
1626 tok::kw___is_scalar,
1627 tok::kw___is_scoped_enum,
1628 tok::kw___is_sealed,
1629 tok::kw___is_signed,
1630 tok::kw___is_standard_layout,
1631 tok::kw___is_trivial,
1632 tok::kw___is_trivially_assignable,
1633 tok::kw___is_trivially_constructible,
1634 tok::kw___is_trivially_copyable,
1635 tok::kw___is_unbounded_array,
1637 tok::kw___is_unsigned,
1639 tok::kw___is_volatile))
1645 TryKeywordIdentFallback(
true);
1647 struct PreserveAtomicIdentifierInfoRAII {
1648 PreserveAtomicIdentifierInfoRAII(
Token &Tok,
bool Enabled)
1649 : AtomicII(nullptr) {
1652 assert(Tok.
is(tok::kw__Atomic));
1657 ~PreserveAtomicIdentifierInfoRAII() {
1660 AtomicII->revertIdentifierToTokenID(tok::kw__Atomic);
1670 bool ShouldChangeAtomicToIdentifier =
getLangOpts().MSVCCompat &&
1671 Tok.
is(tok::kw__Atomic) &&
1673 PreserveAtomicIdentifierInfoRAII AtomicTokenGuard(
1674 Tok, ShouldChangeAtomicToIdentifier);
1684 bool HasValidSpec =
true;
1685 if (ParseOptionalCXXScopeSpecifier(Spec,
nullptr,
1689 HasValidSpec =
false;
1692 if (Tok.
isNot(tok::identifier) && Tok.
isNot(tok::annot_template_id)) {
1693 Diag(Tok, diag::err_expected) << tok::identifier;
1694 HasValidSpec =
false;
1702 auto RecoverFromUndeclaredTemplateName = [&](
IdentifierInfo *Name,
1705 bool KnownUndeclared) {
1706 Diag(NameLoc, diag::err_explicit_spec_non_template)
1707 << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
1708 << TagTokKind << Name << TemplateArgRange << KnownUndeclared;
1712 if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {
1713 if (TemplateParams->size() > 1) {
1714 TemplateParams->pop_back();
1716 TemplateParams =
nullptr;
1717 const_cast<ParsedTemplateInfo &
>(TemplateInfo).Kind =
1718 ParsedTemplateInfo::NonTemplate;
1720 }
else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
1722 TemplateParams =
nullptr;
1723 const_cast<ParsedTemplateInfo &
>(TemplateInfo).Kind =
1724 ParsedTemplateInfo::NonTemplate;
1725 const_cast<ParsedTemplateInfo &
>(TemplateInfo).TemplateLoc =
1727 const_cast<ParsedTemplateInfo &
>(TemplateInfo).ExternLoc =
1736 if (Tok.
is(tok::identifier)) {
1744 TemplateArgList TemplateArgs;
1746 if (ParseTemplateIdAfterTemplateName(
true, LAngleLoc, TemplateArgs,
1752 RecoverFromUndeclaredTemplateName(
1753 Name, NameLoc,
SourceRange(LAngleLoc, RAngleLoc),
false);
1755 }
else if (Tok.
is(tok::annot_template_id)) {
1756 TemplateId = takeTemplateIdAnnotation(Tok);
1757 NameLoc = ConsumeAnnotationToken();
1764 RecoverFromUndeclaredTemplateName(
1767 TemplateId =
nullptr;
1780 Diag(TemplateId->
LAngleLoc, diag::err_template_spec_syntax_non_template)
1781 << TemplateId->
Name <<
static_cast<int>(TemplateId->
Kind) << Range;
1816 MaybeParseCXX11Attributes(Attributes);
1821 AllowDefiningTypeSpec::No ||
1824 else if (Tok.
is(tok::l_brace) ||
1825 (DSC != DeclSpecContext::DSC_association &&
1827 (isClassCompatibleKeyword() &&
1843 }
else if (isClassCompatibleKeyword() &&
1849 TentativeParsingAction PA(*
this);
1852 while (isClassCompatibleKeyword()) {
1858 if (Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square)) {
1862 }
else if (Tok.
is(tok::kw_alignas) &&
NextToken().is(tok::l_paren)) {
1872 if (Tok.
isOneOf(tok::l_brace, tok::colon))
1878 }
else if (!isTypeSpecifier(DSC) &&
1879 (Tok.
is(tok::semi) ||
1882 if (Tok.
isNot(tok::semi)) {
1885 ExpectAndConsume(tok::semi, diag::err_expected_after,
1903 Diag(AttrRange.
getBegin(), diag::err_attributes_not_allowed)
1915 if (!Name && !TemplateId &&
1920 Diag(StartLoc, diag::err_anon_type_definition)
1947 }
else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
1950 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
1954 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
1965 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
1966 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
1976 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
1989 "Expected a definition here");
1993 TemplateParams =
nullptr;
1998 diag::err_explicit_instantiation_with_definition)
2007 std::nullopt, LAngleLoc,
nullptr));
2008 TemplateParams = &FakedParamLists;
2015 SS, *TemplateId, attrs,
2018 TemplateParams ? TemplateParams->size() : 0),
2021 }
else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
2028 ProhibitAttributes(attrs);
2031 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,
2032 TagType, StartLoc, SS, Name, NameLoc, attrs);
2034 TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
2035 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
2042 TemplateParams ? TemplateParams->size() : 0));
2045 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,
2049 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
2052 Diag(Tok, diag::err_template_defn_explicit_instantiation)
2054 TemplateParams =
nullptr;
2057 bool IsDependent =
false;
2067 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);
2070 TagOrTempResult = Actions.
ActOnTag(
2074 DSC == DeclSpecContext::DSC_type_specifier,
2075 DSC == DeclSpecContext::DSC_template_param ||
2076 DSC == DeclSpecContext::DSC_template_type_arg,
2077 OffsetOfState, &SkipBody);
2084 Name, StartLoc, NameLoc);
2091 if (shouldDelayDiagsInTag) {
2092 diagsFromTag.done();
2094 TemplateInfo.Kind == ParsedTemplateInfo::Template)
2095 diagsFromTag.redelay();
2100 assert(Tok.
is(tok::l_brace) ||
2102 isClassCompatibleKeyword());
2104 SkipCXXMemberSpecification(StartLoc, AttrFixitLoc,
TagType,
2105 TagOrTempResult.
get());
2107 ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs,
TagType,
2108 TagOrTempResult.
get());
2113 ParseStructUnionBody(StartLoc,
TagType, cast<RecordDecl>(D));
2126 const char *PrevSpec =
nullptr;
2131 NameLoc.
isValid() ? NameLoc : StartLoc,
2133 }
else if (!TagOrTempResult.
isInvalid()) {
2135 TagType, StartLoc, NameLoc.
isValid() ? NameLoc : StartLoc, PrevSpec,
2136 DiagID, TagOrTempResult.
get(), Owned, Policy);
2143 Diag(StartLoc, DiagID) << PrevSpec;
2159 (TemplateInfo.Kind || !isValidAfterTypeSpecifier(
false))) {
2160 if (Tok.
isNot(tok::semi)) {
2162 ExpectAndConsume(tok::semi, diag::err_expected_after,
2180void Parser::ParseBaseClause(
Decl *ClassDecl) {
2181 assert(Tok.
is(tok::colon) &&
"Not a base clause");
2190 if (
Result.isInvalid()) {
2196 BaseInfo.push_back(
Result.get());
2221 bool IsVirtual =
false;
2225 MaybeParseCXX11Attributes(Attributes);
2231 CheckMisplacedCXX11Attribute(Attributes, StartLoc);
2241 CheckMisplacedCXX11Attribute(Attributes, StartLoc);
2245 if (Tok.
is(tok::kw_virtual)) {
2249 Diag(VirtualLoc, diag::err_dup_virtual)
2256 CheckMisplacedCXX11Attribute(Attributes, StartLoc);
2270 TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation);
2286 Access, BaseType.
get(), BaseLoc,
2301 case tok::kw_private:
2303 case tok::kw_protected:
2305 case tok::kw_public:
2314void Parser::HandleMemberFunctionDeclDelays(
Declarator &DeclaratorInfo,
2321 if (!NeedLateParse) {
2325 if (Param->hasUnparsedDefaultArg()) {
2326 NeedLateParse =
true;
2332 if (NeedLateParse) {
2335 auto LateMethod =
new LateParsedMethodDeclaration(
this, ThisDecl);
2336 getCurrentClass().LateParsedDeclarations.push_back(LateMethod);
2341 LateMethod->DefaultArgs.reserve(FTI.
NumParams);
2343 LateMethod->DefaultArgs.push_back(LateParsedDefaultArgument(
2380 if (II == Ident_override)
2383 if (II == Ident_sealed)
2386 if (II == Ident_abstract)
2389 if (II == Ident_final)
2392 if (II == Ident_GNU_final)
2403void Parser::ParseOptionalCXX11VirtSpecifierSeq(
VirtSpecifiers &VS,
2422 const char *PrevSpec =
nullptr;
2440 ? diag::warn_cxx98_compat_override_control_keyword
2441 : diag::ext_override_control_keyword)
2450bool Parser::isCXX11FinalKeyword()
const {
2459bool Parser::isClassCompatibleKeyword()
const {
2469bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
2471 LateParsedAttrList &LateParsedAttrs) {
2482 if (Tok.
isNot(tok::colon))
2483 ParseDeclarator(DeclaratorInfo);
2489 "don't know where identifier would go yet?");
2493 }
else if (Tok.
is(tok::kw_requires)) {
2494 ParseTrailingRequiresClause(DeclaratorInfo);
2496 ParseOptionalCXX11VirtSpecifierSeq(
2497 VS, getCurrentClass().IsInterface,
2500 MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo,
2505 if (Tok.
is(tok::kw_asm)) {
2507 ExprResult AsmLabel(ParseSimpleAsm(
true, &Loc));
2508 if (AsmLabel.isInvalid())
2518 DiagnoseAndSkipCXX11Attributes();
2519 MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
2520 DiagnoseAndSkipCXX11Attributes();
2525 ParseOptionalCXX11VirtSpecifierSeq(
2526 VS, getCurrentClass().IsInterface,
2532 if (AL.isKnownToGCC() && !AL.isCXX11Attribute())
2533 Diag(AL.getLoc(), diag::warn_gcc_attribute_location);
2535 MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo,
2552void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
2558 ParseTypeQualifierListOpt(
2559 DS, AR_NoAttributesParsed,
false,
2560 false, llvm::function_ref<
void()>([&]() {
2568 auto DeclSpecCheck = [&](
DeclSpec::TQ TypeQual, StringRef FixItName,
2571 auto &MQ =
Function.getOrCreateMethodQualifiers();
2572 if (!(MQ.getTypeQualifiers() & TypeQual)) {
2573 std::string Name(FixItName.data());
2576 MQ.SetTypeQual(TypeQual, SpecLoc);
2578 Diag(SpecLoc, diag::err_declspec_after_virtspec)
2587 bool RefQualifierIsLValueRef =
true;
2589 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc)) {
2590 const char *Name = (RefQualifierIsLValueRef ?
"& " :
"&& ");
2593 Function.RefQualifierIsLValueRef = RefQualifierIsLValueRef;
2594 Function.RefQualifierLoc = RefQualifierLoc;
2596 Diag(RefQualifierLoc, diag::err_declspec_after_virtspec)
2597 << (RefQualifierIsLValueRef ?
"&" :
"&&")
2645 const ParsedTemplateInfo &TemplateInfo,
2647 if (Tok.
is(tok::at)) {
2649 Diag(Tok, diag::err_at_defs_cxx);
2651 Diag(Tok, diag::err_at_in_class);
2667 bool MalformedTypeSpec =
false;
2668 if (!TemplateInfo.Kind &&
2669 Tok.
isOneOf(tok::identifier, tok::coloncolon, tok::kw___super)) {
2671 MalformedTypeSpec =
true;
2674 if (Tok.
isNot(tok::annot_cxxscope))
2675 isAccessDecl =
false;
2676 else if (
NextToken().is(tok::identifier))
2677 isAccessDecl = GetLookAheadToken(2).
is(tok::semi);
2684 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
2697 false,
false,
true,
true,
2698 false, &TemplateKWLoc, Name)) {
2704 if (ExpectAndConsume(tok::semi, diag::err_expected_after,
2705 "access declaration")) {
2721 if (!TemplateInfo.Kind &&
2722 Tok.
isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {
2728 if (Tok.
is(tok::kw_template)) {
2729 assert(!TemplateInfo.TemplateParams &&
2730 "Nested template improperly parsed?");
2739 if (Tok.
is(tok::kw___extension__)) {
2743 return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,
2749 MaybeParseCXX11Attributes(DeclAttrs);
2754 if (Tok.
is(tok::annot_attr_openmp))
2755 return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, DeclAttrs);
2757 if (Tok.
is(tok::kw_using)) {
2762 while (Tok.
is(tok::kw_template)) {
2764 Diag(TemplateLoc, diag::err_unexpected_template_after_using)
2768 if (Tok.
is(tok::kw_namespace)) {
2769 Diag(UsingLoc, diag::err_using_namespace_in_class);
2776 UsingLoc, DeclEnd, DeclAttrs, AS);
2780 MaybeParseMicrosoftAttributes(DeclSpecAttrs);
2783 LateParsedAttrList CommonLateParsedAttrs;
2790 if (MalformedTypeSpec)
2798 bool IsTemplateSpecOrInst =
2799 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||
2800 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);
2803 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DeclSpecContext::DSC_class,
2804 &CommonLateParsedAttrs);
2806 if (IsTemplateSpecOrInst)
2807 diagsFromTag.done();
2815 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate &&
2816 DiagnoseMissingSemiAfterTagDefinition(DS, AS, DeclSpecContext::DSC_class,
2817 &CommonLateParsedAttrs))
2821 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data()
2823 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
2827 ProhibitAttributes(DeclAttrs);
2831 getCurScope(), AS, DS, DeclAttrs, TemplateParams,
false, AnonRecord);
2832 DS.complete(TheDecl);
2834 Decl *decls[] = {AnonRecord, TheDecl};
2842 if (TemplateInfo.TemplateParams)
2847 LateParsedAttrList LateParsedAttrs;
2852 auto TryConsumePureSpecifier = [&](
bool AllowDefinition) {
2853 if (Tok.
isNot(tok::equal))
2858 if (
Zero.isNot(tok::numeric_constant) ||
2862 auto &
After = GetLookAheadToken(2);
2863 if (!
After.isOneOf(tok::semi, tok::comma) &&
2864 !(AllowDefinition &&
2865 After.isOneOf(tok::l_brace, tok::colon, tok::kw_try)))
2876 bool ExpectSemi =
true;
2884 if (ParseCXXMemberDeclaratorBeforeInitializer(
2885 DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs)) {
2890 if (IsTemplateSpecOrInst)
2898 TryConsumePureSpecifier(
true);
2909 if (Tok.
isOneOf(tok::l_brace, tok::colon, tok::kw_try)) {
2911 }
else if (Tok.
is(tok::equal)) {
2913 if (KW.
is(tok::kw_default))
2915 else if (KW.
is(tok::kw_delete))
2917 else if (KW.
is(tok::code_completion)) {
2933 ProhibitAttributes(DeclAttrs);
2950 diag::err_function_declared_typedef);
2956 Decl *FunDecl = ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo,
2957 TemplateInfo, VS, PureSpecLoc);
2960 for (
unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {
2961 CommonLateParsedAttrs[i]->addDecl(FunDecl);
2963 for (
unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
2964 LateParsedAttrs[i]->addDecl(FunDecl);
2967 LateParsedAttrs.clear();
2970 if (Tok.
is(tok::semi))
2971 ConsumeExtraSemi(AfterMemberFunctionDefinition);
2983 bool HasStaticInitializer =
false;
2988 Diag(Tok, diag::err_anon_bitfield_member_init);
2992 if (!TryConsumePureSpecifier(
false))
2994 HasStaticInitializer =
true;
3001 if (BitfieldSize.
get())
3003 ? diag::warn_cxx17_compat_bitfield_member_init
3004 : diag::ext_bitfield_member_init);
3007 HasStaticInitializer =
true;
3027 Diag((*I).getBegin(), diag::err_attributes_not_allowed) << *I;
3033 getCurScope(), AS, DeclaratorInfo, TemplateParams, BitfieldSize.
get(),
3034 VS, HasInClassInit);
3037 ThisDecl ? dyn_cast<VarTemplateDecl>(ThisDecl) :
nullptr)
3040 ThisDecl = VT->getTemplatedDecl();
3052 HasStaticInitializer =
true;
3056 Diag(PureSpecLoc, diag::err_duplicate_virt_specifier) <<
"abstract";
3058 if (ThisDecl && PureSpecLoc.
isValid())
3067 ? diag::warn_cxx98_compat_nonstatic_member_init
3068 : diag::ext_nonstatic_member_init);
3076 Diag(Tok, diag::err_incomplete_array_member_init);
3083 ParseCXXNonStaticMemberInitializer(ThisDecl);
3084 }
else if (HasStaticInitializer) {
3089 if (Init.isInvalid()) {
3093 }
else if (ThisDecl)
3103 for (
unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i)
3104 CommonLateParsedAttrs[i]->addDecl(ThisDecl);
3106 for (
unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i)
3107 LateParsedAttrs[i]->addDecl(ThisDecl);
3110 DeclsInGroup.push_back(ThisDecl);
3115 HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);
3117 LateParsedAttrs.clear();
3119 DeclaratorInfo.complete(ThisDecl);
3132 Diag(CommaLoc, diag::err_expected_semi_declaration)
3139 DeclaratorInfo.
clear();
3148 DiagnoseAndSkipCXX11Attributes();
3149 MaybeParseGNUAttributes(DeclaratorInfo);
3150 DiagnoseAndSkipCXX11Attributes();
3152 if (ParseCXXMemberDeclaratorBeforeInitializer(
3153 DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs))
3158 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
3189ExprResult Parser::ParseCXXMemberInitializer(
Decl *D,
bool IsFunction,
3191 assert(Tok.
isOneOf(tok::equal, tok::l_brace) &&
3192 "Data member initializer not starting with '=' or '{'");
3196 isa_and_present<FieldDecl>(D)
3201 if (Tok.
is(tok::kw_delete)) {
3208 if (IsFunction || Next.isOneOf(tok::semi, tok::comma, tok::eof)) {
3216 }
else if (Tok.
is(tok::kw_default)) {
3218 Diag(Tok, diag::err_default_delete_in_multiple_declaration)
3226 if (
const auto *PD = dyn_cast_or_null<MSPropertyDecl>(D)) {
3227 Diag(Tok, diag::err_ms_property_initializer) << PD;
3230 return ParseInitializer();
3238 assert(isCXX11FinalKeyword() &&
"not a class definition");
3244 CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);
3249 if (Tok.
isNot(tok::colon) && Tok.
isNot(tok::l_brace))
3256 if (Tok.
is(tok::colon)) {
3259 ParsingClassDefinition ParsingDef(*
this,
TagDecl,
true,
3265 ParseBaseClause(
nullptr);
3269 if (!Tok.
is(tok::l_brace)) {
3271 diag::err_expected_lbrace_after_base_specifiers);
3277 assert(Tok.
is(tok::l_brace));
3283 if (Tok.
is(tok::kw___attribute)) {
3285 MaybeParseGNUAttributes(Attrs);
3295 case tok::kw___if_exists:
3296 case tok::kw___if_not_exists:
3297 ParseMicrosoftIfExistsClassDeclaration(
TagType, AccessAttrs, AS);
3302 ConsumeExtraSemi(InsideStruct,
TagType);
3306 case tok::annot_pragma_vis:
3307 HandlePragmaVisibility();
3309 case tok::annot_pragma_pack:
3312 case tok::annot_pragma_align:
3313 HandlePragmaAlign();
3315 case tok::annot_pragma_ms_pointers_to_members:
3316 HandlePragmaMSPointersToMembers();
3318 case tok::annot_pragma_ms_pragma:
3319 HandlePragmaMSPragma();
3321 case tok::annot_pragma_ms_vtordisp:
3322 HandlePragmaMSVtorDisp();
3324 case tok::annot_pragma_dump:
3328 case tok::kw_namespace:
3330 DiagnoseUnexpectedNamespace(cast<NamedDecl>(
TagDecl));
3333 case tok::kw_private:
3337 return ParseCXXClassMemberDeclaration(AS, AccessAttrs);
3339 case tok::kw_public:
3340 case tok::kw_protected: {
3350 AccessAttrs.
clear();
3351 MaybeParseGNUAttributes(AccessAttrs);
3356 Diag(EndLoc, diag::err_expected)
3360 Diag(EndLoc, diag::err_expected)
3372 AccessAttrs.
clear();
3378 case tok::annot_attr_openmp:
3379 case tok::annot_pragma_openmp:
3380 return ParseOpenMPDeclarativeDirectiveWithExtDecl(
3388 ConsumeAnnotationToken();
3391 return ParseCXXClassMemberDeclaration(AS, AccessAttrs);
3401void Parser::ParseCXXMemberSpecification(
SourceLocation RecordLoc,
3408 "Invalid TagType!");
3410 llvm::TimeTraceScope TimeScope(
"ParseClass", [&]() {
3411 if (
auto *TD = dyn_cast_or_null<NamedDecl>(
TagDecl))
3412 return TD->getQualifiedNameAsString();
3413 return std::string(
"<anonymous>");
3417 "parsing struct/union/class body");
3421 bool NonNestedClass =
true;
3422 if (!ClassStack.empty()) {
3424 if (S->isClassScope()) {
3426 NonNestedClass =
false;
3429 if (getCurrentClass().IsInterface) {
3430 Diag(RecordLoc, diag::err_invalid_member_in_interface)
3433 ? cast<NamedDecl>(
TagDecl)->getQualifiedNameAsString()
3439 if (S->isFunctionScope())
3450 ParsingClassDefinition ParsingDef(*
this,
TagDecl, NonNestedClass,
3458 bool IsFinalSpelledSealed =
false;
3459 bool IsAbstract =
false;
3467 if (isCXX11FinalKeyword()) {
3470 Diag(Skipped, diag::err_duplicate_class_virt_specifier)
3475 IsFinalSpelledSealed =
true;
3480 Diag(Skipped, diag::err_duplicate_class_virt_specifier)
3488 Diag(FinalLoc, diag::err_override_control_interface)
3492 ? diag::warn_cxx98_compat_override_control_keyword
3493 : diag::ext_override_control_keyword)
3496 Diag(FinalLoc, diag::ext_ms_sealed_keyword);
3498 Diag(AbstractLoc, diag::ext_ms_abstract_keyword);
3500 Diag(FinalLoc, diag::ext_warn_gnu_final);
3503 "not a class definition");
3509 CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);
3518 if (!Tok.
is(tok::colon) && !Tok.
is(tok::l_brace)) {
3525 if (Tok.
is(tok::colon)) {
3526 ParseScope InheritanceScope(
this,
getCurScope()->getFlags() |
3530 if (!Tok.
is(tok::l_brace)) {
3531 bool SuggestFixIt =
false;
3535 case tok::kw_private:
3536 case tok::kw_protected:
3537 case tok::kw_public:
3540 case tok::kw_static_assert:
3544 case tok::kw_template:
3545 SuggestFixIt =
true;
3547 case tok::identifier:
3548 SuggestFixIt = isConstructorDeclarator(
true);
3551 SuggestFixIt = isCXXSimpleDeclaration(
false);
3556 Diag(BraceLoc, diag::err_expected_lbrace_after_base_specifiers);
3570 assert(Tok.
is(tok::l_brace));
3576 IsFinalSpelledSealed, IsAbstract,
3577 T.getOpenLocation());
3592 while (!tryParseMisplacedModuleImport() && Tok.
isNot(tok::r_brace) &&
3593 Tok.
isNot(tok::eof)) {
3595 ParseCXXClassMemberDeclarationWithPragmas(
3597 MaybeDestroyTemplateIds();
3606 MaybeParseGNUAttributes(attrs);
3610 T.getOpenLocation(),
3611 T.getCloseLocation(), attrs);
3618 if (
TagDecl && NonNestedClass) {
3625 ParseLexedPragmas(getCurrentClass());
3626 ParseLexedAttributes(getCurrentClass());
3627 ParseLexedMethodDeclarations(getCurrentClass());
3632 ParseLexedMemberInitializers(getCurrentClass());
3633 ParseLexedMethodDefs(getCurrentClass());
3634 PrevTokLocation = SavedPrevTokLocation;
3649void Parser::DiagnoseUnexpectedNamespace(
NamedDecl *D) {
3650 assert(Tok.
is(tok::kw_namespace));
3655 Diag(Tok.
getLocation(), diag::note_missing_end_of_definition_before) << D;
3689void Parser::ParseConstructorInitializer(
Decl *ConstructorDecl) {
3690 assert(Tok.
is(tok::colon) &&
3691 "Constructor initializer always starts with ':'");
3699 bool AnyErrors =
false;
3702 if (Tok.
is(tok::code_completion)) {
3709 MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);
3711 MemInitializers.push_back(MemInit.
get());
3715 if (Tok.
is(tok::comma))
3717 else if (Tok.
is(tok::l_brace))
3722 Tok.
isOneOf(tok::identifier, tok::coloncolon)) {
3724 Diag(Loc, diag::err_ctor_init_missing_comma)
3730 << tok::l_brace << tok::comma;
3755 if (ParseOptionalCXXScopeSpecifier(SS,
nullptr,
3768 if (Tok.
is(tok::identifier)) {
3773 }
else if (Tok.
is(tok::annot_decltype)) {
3778 ParseDecltypeSpecifier(DS);
3781 ? takeTemplateIdAnnotation(Tok)
3786 assert(Tok.
is(tok::annot_typename) &&
"template-id -> type failed");
3788 ConsumeAnnotationToken();
3790 Diag(Tok, diag::err_expected_member_or_base_name);
3797 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
3800 ExprResult InitList = ParseBraceInitializer();
3810 TemplateTypeTy.
get(), DS, IdLoc,
3811 InitList.
get(), EllipsisLoc);
3812 }
else if (Tok.
is(tok::l_paren)) {
3817 ExprVector ArgExprs;
3818 auto RunSignatureHelp = [&] {
3822 ConstructorDecl, SS, TemplateTypeTy.
get(), ArgExprs, II,
3823 T.getOpenLocation(),
false);
3824 CalledSignatureHelp =
true;
3825 return PreferredType;
3827 if (Tok.
isNot(tok::r_paren) && ParseExpressionList(ArgExprs, [&] {
3828 PreferredType.enterFunctionArgument(Tok.
getLocation(),
3845 ConstructorDecl,
getCurScope(), SS, II, TemplateTypeTy.
get(), DS, IdLoc,
3846 T.getOpenLocation(), ArgExprs, T.getCloseLocation(), EllipsisLoc);
3853 return Diag(Tok, diag::err_expected_either) << tok::l_paren << tok::l_brace;
3855 return Diag(Tok, diag::err_expected) << tok::l_paren;
3873 ExceptionSpecTokens =
nullptr;
3877 if (Tok.
isNot(tok::kw_throw) && Tok.
isNot(tok::kw_noexcept))
3881 bool IsNoexcept = Tok.
is(tok::kw_noexcept);
3882 Token StartTok = Tok;
3886 if (!Tok.
is(tok::l_paren)) {
3889 Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
3890 NoexceptExpr =
nullptr;
3894 Diag(Tok, diag::err_expected_lparen_after) <<
"throw";
3900 ExceptionSpecTokens->push_back(StartTok);
3901 ExceptionSpecTokens->push_back(Tok);
3902 SpecificationRange.
setEnd(ConsumeParen());
3904 ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens,
3907 SpecificationRange.
setEnd(ExceptionSpecTokens->back().getLocation());
3913 if (Tok.
is(tok::kw_throw)) {
3914 Result = ParseDynamicExceptionSpecification(
3915 SpecificationRange, DynamicExceptions, DynamicExceptionRanges);
3916 assert(DynamicExceptions.size() == DynamicExceptionRanges.size() &&
3917 "Produced different number of exception types and ranges.");
3921 if (Tok.
isNot(tok::kw_noexcept))
3924 Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);
3932 if (Tok.
is(tok::l_paren)) {
3941 NoexceptRange =
SourceRange(KeywordLoc, T.getCloseLocation());
3948 NoexceptRange =
SourceRange(KeywordLoc, KeywordLoc);
3952 SpecificationRange = NoexceptRange;
3957 if (Tok.
is(tok::kw_throw)) {
3958 Diag(Tok.
getLocation(), diag::err_dynamic_and_noexcept_specification);
3959 ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions,
3960 DynamicExceptionRanges);
3963 Diag(Tok.
getLocation(), diag::err_dynamic_and_noexcept_specification);
3971 if (
P.getLangOpts().CPlusPlus11) {
3972 const char *Replacement = IsNoexcept ?
"noexcept" :
"noexcept(false)";
3973 P.Diag(Range.getBegin(),
P.getLangOpts().CPlusPlus17 && !IsNoexcept
3974 ? diag::ext_dynamic_exception_spec
3975 : diag::warn_exception_spec_deprecated)
3977 P.Diag(Range.getBegin(), diag::note_exception_spec_deprecated)
3996 assert(Tok.
is(tok::kw_throw) &&
"expected throw");
4000 if (T.consumeOpen()) {
4001 Diag(Tok, diag::err_expected_lparen_after) <<
"throw";
4008 if (Tok.
is(tok::ellipsis)) {
4011 Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
4013 SpecificationRange.
setEnd(T.getCloseLocation());
4020 while (Tok.
isNot(tok::r_paren)) {
4023 if (Tok.
is(tok::ellipsis)) {
4028 Range.setEnd(Ellipsis);
4029 if (!Res.isInvalid())
4033 if (!Res.isInvalid()) {
4034 Exceptions.push_back(Res.get());
4035 Ranges.push_back(Range);
4043 SpecificationRange.
setEnd(T.getCloseLocation());
4045 Exceptions.empty());
4052 bool MayBeFollowedByDirectInit) {
4053 assert(Tok.
is(tok::arrow) &&
"expected arrow");
4063void Parser::ParseTrailingRequiresClause(
Declarator &D) {
4064 assert(Tok.
is(tok::kw_requires) &&
"expected requires");
4075 std::optional<Sema::CXXThisScopeRAII> ThisScope;
4076 InitCXXThisScopeForDeclaratorIfRelevant(D, D.
getDeclSpec(), ThisScope);
4078 TrailingRequiresClause =
4081 TrailingRequiresClause =
4086 diag::err_requires_clause_on_declarator_not_declaring_a_function);
4091 SkipUntil({tok::l_brace, tok::arrow, tok::kw_try, tok::comma, tok::colon},
4102 ParseTrailingReturnType(Range,
false);
4106 diag::err_requires_clause_must_appear_after_trailing_return)
4110 FunctionChunk.TrailingReturnType = TrailingReturnType.
get();
4111 FunctionChunk.TrailingReturnTypeLoc =
Range.getBegin();
4113 SkipUntil({tok::equal, tok::l_brace, tok::arrow, tok::kw_try, tok::comma},
4122 bool NonNestedClass,
4124 assert((NonNestedClass || !ClassStack.empty()) &&
4125 "Nested class without outer class");
4126 ClassStack.push(
new ParsingClass(ClassDecl, NonNestedClass, IsInterface));
4132void Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {
4133 for (
unsigned I = 0, N =
Class->LateParsedDeclarations.size(); I != N; ++I)
4134 delete Class->LateParsedDeclarations[I];
4145 assert(!ClassStack.empty() &&
"Mismatched push/pop for class parsing");
4149 ParsingClass *Victim = ClassStack.top();
4151 if (Victim->TopLevelClass) {
4154 DeallocateParsedClasses(Victim);
4157 assert(!ClassStack.empty() &&
"Missing top-level class?");
4159 if (Victim->LateParsedDeclarations.empty()) {
4164 DeallocateParsedClasses(Victim);
4172 "Nested class outside of class scope?");
4173 ClassStack.top()->LateParsedDeclarations.push_back(
4174 new LateParsedClass(
this, Victim));
4201 case tok::code_completion:
4208 case tok::numeric_constant: {
4216 StringRef Spelling = PP.
getSpelling(ExpansionLoc, ExpansionBuf);
4217 if (Spelling ==
"__clang__") {
4221 Diag(Tok, diag::warn_wrong_clang_attr_namespace)
4237 case tok::pipeequal:
4238 case tok::caretequal:
4240 case tok::exclaimequal:
4246 StringRef Spelling = PP.
getSpelling(SpellingLoc, SpellingBuf);
4260 if (T.consumeOpen()) {
4261 Diag(Tok, diag::err_expected) << tok::l_paren;
4265 if (AttrName->
isStr(
"directive")) {
4271 OMPBeginTok.
setKind(tok::annot_attr_openmp);
4273 OpenMPTokens.push_back(OMPBeginTok);
4275 ConsumeAndStoreUntil(tok::r_paren, OpenMPTokens,
false,
4279 OMPEndTok.
setKind(tok::annot_pragma_openmp_end);
4281 OpenMPTokens.push_back(OMPEndTok);
4283 assert(AttrName->
isStr(
"sequence") &&
4284 "Expected either 'directive' or 'sequence'");
4293 IdentifierInfo *Ident = TryParseCXX11AttributeIdentifier(IdentLoc);
4297 if (Ident && Ident->
isStr(
"omp") && !ExpectAndConsume(tok::coloncolon))
4298 Ident = TryParseCXX11AttributeIdentifier(IdentLoc);
4302 if (!Ident || (!Ident->
isStr(
"directive") && !Ident->
isStr(
"sequence"))) {
4309 ParseOpenMPAttributeArgs(Ident, OpenMPTokens);
4323 case ParsedAttr::AT_CarriesDependency:
4324 case ParsedAttr::AT_Deprecated:
4325 case ParsedAttr::AT_FallThrough:
4326 case ParsedAttr::AT_CXX11NoReturn:
4327 case ParsedAttr::AT_NoUniqueAddress:
4328 case ParsedAttr::AT_Likely:
4329 case ParsedAttr::AT_Unlikely:
4331 case ParsedAttr::AT_WarnUnusedResult:
4332 return !ScopeName && AttrName->
getName().equals(
"nodiscard");
4333 case ParsedAttr::AT_Unused:
4334 return !ScopeName && AttrName->
getName().equals(
"maybe_unused");
4354bool Parser::ParseCXX11AttributeArgs(
4358 assert(Tok.
is(tok::l_paren) &&
"Not a C++11 attribute argument list");
4385 if (ScopeName && (ScopeName->
isStr(
"gnu") || ScopeName->
isStr(
"__gnu__"))) {
4388 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
4389 ScopeLoc, Syntax,
nullptr);
4393 if (ScopeName && ScopeName->
isStr(
"omp")) {
4395 ? diag::warn_omp51_compat_attributes
4396 : diag::ext_omp_attributes);
4398 ParseOpenMPAttributeArgs(AttrName, OpenMPTokens);
4407 if (ScopeName && (ScopeName->
isStr(
"clang") || ScopeName->
isStr(
"_Clang")))
4408 NumArgs = ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc,
4409 ScopeName, ScopeLoc, Syntax);
4411 NumArgs = ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
4412 ScopeName, ScopeLoc, Syntax);
4414 if (!Attrs.
empty() &&
4421 if (
Attr.getMaxArgs() && !NumArgs) {
4424 Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;
4425 Attr.setInvalid(
true);
4426 }
else if (!
Attr.getMaxArgs()) {
4430 Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
4433 Attr.setInvalid(
true);
4466 if (Tok.
is(tok::kw_alignas)) {
4468 ParseAlignmentSpecifier(Attrs, EndLoc);
4472 assert(Tok.
is(tok::l_square) &&
NextToken().is(tok::l_square) &&
4473 "Not a double square bracket attribute list");
4476 Diag(OpenLoc, diag::warn_cxx98_compat_attribute);
4479 checkCompoundToken(OpenLoc, tok::l_square, CompoundToken::AttrBegin);
4484 if (Tok.
is(tok::kw_using)) {
4486 ? diag::warn_cxx14_compat_using_attribute_ns
4487 : diag::ext_using_attribute_ns);
4490 CommonScopeName = TryParseCXX11AttributeIdentifier(
4492 if (!CommonScopeName) {
4500 bool AttrParsed =
false;
4501 while (!Tok.
isOneOf(tok::r_square, tok::semi, tok::eof)) {
4505 if (ExpectAndConsume(tok::comma)) {
4519 AttrName = TryParseCXX11AttributeIdentifier(
4527 ScopeName = AttrName;
4530 AttrName = TryParseCXX11AttributeIdentifier(
4539 if (CommonScopeName) {
4541 Diag(ScopeLoc, diag::err_using_attribute_ns_conflict)
4544 ScopeName = CommonScopeName;
4545 ScopeLoc = CommonScopeLoc;
4550 if (Tok.
is(tok::l_paren))
4551 AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc,
4552 ScopeName, ScopeLoc, OpenMPTokens);
4558 ScopeName, ScopeLoc,
nullptr, 0,
4564 Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) << AttrName;
4569 if (Tok.
is(tok::semi)) {
4575 if (ExpectAndConsume(tok::r_square))
4577 else if (Tok.
is(tok::r_square))
4578 checkCompoundToken(CloseLoc, tok::r_square, CompoundToken::AttrEnd);
4581 if (ExpectAndConsume(tok::r_square))
4590 assert(standardAttributesAllowed());
4596 ParseCXX11AttributeSpecifier(Attrs, &EndLoc);
4597 }
while (isCXX11AttributeSpecifier());
4602void Parser::DiagnoseAndSkipCXX11Attributes() {
4609 Diag(StartLoc, diag::err_attributes_not_allowed) <<
Range;
4616 if (!isCXX11AttributeSpecifier())
4620 if (Tok.
is(tok::l_square)) {
4624 EndLoc = T.getCloseLocation();
4626 assert(Tok.
is(tok::kw_alignas) &&
"not an attribute specifier");
4629 if (!T.consumeOpen())
4631 EndLoc = T.getCloseLocation();
4633 }
while (isCXX11AttributeSpecifier());
4640 assert(Tok.
is(tok::identifier) &&
"Not a Microsoft attribute list");
4642 assert(UuidIdent->
getName() ==
"uuid" &&
"Not a Microsoft attribute list");
4649 if (T.consumeOpen()) {
4650 Diag(Tok, diag::err_expected) << tok::l_paren;
4655 if (Tok.
is(tok::string_literal)) {
4660 ArgExprs.push_back(StringResult.
get());
4677 while (Tok.
isNot(tok::r_paren)) {
4679 Diag(Tok, diag::err_attribute_uuid_malformed_guid);
4684 SpellingBuffer.resize(Tok.
getLength() + 1);
4686 StringRef TokSpelling = PP.
getSpelling(Tok, SpellingBuffer, &Invalid);
4691 StrBuffer += TokSpelling;
4697 Diag(Tok, diag::err_attribute_uuid_malformed_guid);
4707 Toks[0].
setKind(tok::string_literal);
4713 ArgExprs.push_back(UuidString);
4716 if (!T.consumeClose()) {
4732 assert(Tok.
is(tok::l_square) &&
"Not a Microsoft attribute list");
4743 SkipUntil(tok::r_square, tok::identifier,
4745 if (Tok.
is(tok::code_completion)) {
4752 if (Tok.
isNot(tok::identifier))
4755 ParseMicrosoftUuidAttributeArgs(Attrs);
4765 bool AttrParsed =
false;
4766 if (Tok.
is(tok::l_paren)) {
4769 ParseCXX11AttributeArgs(II, NameLoc, Attrs, &EndLoc,
nullptr,
4771 ReplayOpenMPAttributeTokens(OpenMPTokens);
4782 EndLoc = T.getCloseLocation();
4783 }
while (Tok.
is(tok::l_square));
4788void Parser::ParseMicrosoftIfExistsClassDeclaration(
4791 IfExistsCondition
Result;
4792 if (ParseMicrosoftIfExistsCondition(
Result))
4796 if (Braces.consumeOpen()) {
4797 Diag(Tok, diag::err_expected) << tok::l_brace;
4801 switch (
Result.Behavior) {
4807 Diag(
Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
4817 while (Tok.
isNot(tok::r_brace) && !isEofOrEom()) {
4819 if (Tok.
isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) {
4820 ParseMicrosoftIfExistsClassDeclaration(
TagType, AccessAttrs, CurAS);
4825 if (Tok.
is(tok::semi)) {
4826 ConsumeExtraSemi(InsideStruct,
TagType);
4836 if (Tok.
is(tok::colon))
4840 Diag(Tok, diag::err_expected) << tok::colon;
4846 ParseCXXClassMemberDeclaration(CurAS, AccessAttrs);
4849 Braces.consumeClose();
Defines the clang::ASTContext interface.
static CompilationDatabasePluginRegistry::Add< FixedCompilationDatabasePlugin > X("fixed-compilation-database", "Reads plain-text flags file")
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.
Syntax
The style used to specify an attribute.
@ AS_Keyword
__ptr16, alignas(...), etc.
@ 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.
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.
bool isArrayOfUnknownBound() const
isArrayOfUnknownBound - This method returns true if the declarator is a declarator for an array of un...
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.
void setCommaLoc(SourceLocation CL)
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 clear()
Reset the contents of this Declarator.
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).
void getCXX11AttributeRanges(SmallVectorImpl< SourceRange > &Ranges)
Return a source range list of C++11 attributes associated with the declarator.
A little helper class used to produce diagnostics.
RAII object that enters a new expression evaluation context.
Represents a C++ Modules TS 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.
void takeAllFrom(ParsedAttributes &Other)
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
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.
QualType ProduceCtorInitMemberSignatureHelp(Decl *ConstructorDecl, CXXScopeSpec SS, ParsedType TemplateTypeTy, ArrayRef< Expr * > ArgExprs, IdentifierInfo *II, SourceLocation OpenParLoc, bool Braced)
Decl * ActOnStartLinkageSpecification(Scope *S, SourceLocation ExternLoc, Expr *LangStr, SourceLocation LBraceLoc)
ActOnStartLinkageSpecification - Parsed the beginning of a C++ linkage specification,...
void ActOnTagStartDefinition(Scope *S, Decl *TagDecl)
ActOnTagStartDefinition - Invoked when we have entered the scope of a tag's definition (e....
void ActOnMemInitializers(Decl *ConstructorDecl, SourceLocation ColonLoc, ArrayRef< CXXCtorInitializer * > MemInits, bool AnyErrors)
ActOnMemInitializers - Handle the member initializers for a constructor.
void ActOnFinishCXXMemberSpecification(Scope *S, SourceLocation RLoc, Decl *TagDecl, SourceLocation LBrac, SourceLocation RBrac, const ParsedAttributesView &AttrList)
ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)
Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion.
void ActOnUndeclaredTypeTemplateName(Scope *S, TemplateTy &Name, TemplateNameKind &TNK, SourceLocation NameLoc, IdentifierInfo *&II)
Try to resolve an undeclared template name as a type template.
Decl * ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc, Expr *AssertExpr, Expr *AssertMessageExpr, SourceLocation RParenLoc)
ExprResult ActOnStringLiteral(ArrayRef< Token > StringToks, Scope *UDLScope=nullptr)
ActOnStringLiteral - The specified tokens were lexed as pasted string fragments (e....
DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, ArrayRef< Decl * > Group)
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type.