clang: lib/Parse/ParseDeclCXX.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

31#include "llvm/ADT/SmallString.h"

32#include "llvm/Support/TimeProfiler.h"

33#include

34

35using namespace clang;

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

67 assert(Tok.is(tok::kw_namespace) && "Not a namespace!");

70

71 if (Tok.is(tok::code_completion)) {

72 cutOffParsing();

74 return nullptr;

75 }

76

79 InnerNamespaceInfoList ExtraNSs;

81

83

84 while (MaybeParseGNUAttributes(attrs) || isAllowedCXX11AttributeSpecifier()) {

85 if (isAllowedCXX11AttributeSpecifier()) {

88 ? diag::warn_cxx14_compat_ns_enum_attribute

89 : diag::ext_ns_enum_attribute)

90 << 0 ;

91 ParseCXX11Attributes(attrs);

92 }

93 }

94

95 if (Tok.is(tok::identifier)) {

97 IdentLoc = ConsumeToken();

98 while (Tok.is(tok::coloncolon) &&

99 (NextToken().is(tok::identifier) ||

100 (NextToken().is(tok::kw_inline) &&

101 GetLookAheadToken(2).is(tok::identifier)))) {

102

103 InnerNamespaceInfo Info;

105

106 if (Tok.is(tok::kw_inline)) {

108 if (FirstNestedInlineLoc.isInvalid())

109 FirstNestedInlineLoc = Info.InlineLoc;

110 }

111

114

115 ExtraNSs.push_back(Info);

116 }

117 }

118

119 DiagnoseAndSkipCXX11Attributes();

120 MaybeParseGNUAttributes(attrs);

121 DiagnoseAndSkipCXX11Attributes();

122

124

125

126 if (!ExtraNSs.empty() && attrLoc.isValid())

127 Diag(attrLoc, diag::err_unexpected_nested_namespace_attribute);

128

129 if (Tok.is(tok::equal)) {

130 if (!Ident) {

131 Diag(Tok, diag::err_expected) << tok::identifier;

132

134 return nullptr;

135 }

136 if (!ExtraNSs.empty()) {

137 Diag(ExtraNSs.front().NamespaceLoc,

138 diag::err_unexpected_qualified_namespace_alias)

139 << SourceRange(ExtraNSs.front().NamespaceLoc,

140 ExtraNSs.back().IdentLoc);

142 return nullptr;

143 }

145 Diag(attrLoc, diag::err_unexpected_namespace_attributes_alias);

147 Diag(InlineLoc, diag::err_inline_namespace_alias)

149 Decl *NSAlias = ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);

151 }

152

154 if (T.consumeOpen()) {

155 if (Ident)

156 Diag(Tok, diag::err_expected) << tok::l_brace;

157 else

158 Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;

159 return nullptr;

160 }

161

165 Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope);

167 return nullptr;

168 }

169

170 if (ExtraNSs.empty()) {

171

172 } else if (InlineLoc.isValid()) {

173 Diag(InlineLoc, diag::err_inline_nested_namespace_definition);

175 Diag(ExtraNSs[0].NamespaceLoc,

176 diag::warn_cxx14_compat_nested_namespace_definition);

177 if (FirstNestedInlineLoc.isValid())

178 Diag(FirstNestedInlineLoc,

179 diag::warn_cxx17_compat_inline_nested_namespace_definition);

181 Diag(ExtraNSs[0].NamespaceLoc,

182 diag::warn_cxx14_compat_nested_namespace_definition);

183 if (FirstNestedInlineLoc.isValid())

184 Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition);

185 } else {

186 TentativeParsingAction TPA(*this);

188 Token rBraceToken = Tok;

189 TPA.Revert();

190

191 if (!rBraceToken.is(tok::r_brace)) {

192 Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition)

193 << SourceRange(ExtraNSs.front().NamespaceLoc,

194 ExtraNSs.back().IdentLoc);

195 } else {

196 std::string NamespaceFix;

197 for (const auto &ExtraNS : ExtraNSs) {

198 NamespaceFix += " { ";

199 if (ExtraNS.InlineLoc.isValid())

200 NamespaceFix += "inline ";

201 NamespaceFix += "namespace ";

202 NamespaceFix += ExtraNS.Ident->getName();

203 }

204

205 std::string RBraces;

206 for (unsigned i = 0, e = ExtraNSs.size(); i != e; ++i)

207 RBraces += "} ";

208

209 Diag(ExtraNSs[0].NamespaceLoc, diag::ext_nested_namespace_definition)

211 SourceRange(ExtraNSs.front().NamespaceLoc,

212 ExtraNSs.back().IdentLoc),

213 NamespaceFix)

215 }

216

217

218 if (FirstNestedInlineLoc.isValid())

219 Diag(FirstNestedInlineLoc, diag::ext_inline_nested_namespace_definition);

220 }

221

222

225 ? diag::warn_cxx98_compat_inline_namespace

226 : diag::ext_inline_namespace);

227

228

230

233 getCurScope(), InlineLoc, NamespaceLoc, IdentLoc, Ident,

234 T.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl, false);

235

237 NamespaceLoc, "parsing namespace");

238

239

240

241 ParseInnerNamespace(ExtraNSs, 0, InlineLoc, attrs, T);

242

243

244 NamespaceScope.Exit();

245

246 DeclEnd = T.getCloseLocation();

248

250 ImplicitUsingDirectiveDecl);

251}

252

253

254void Parser::ParseInnerNamespace(const InnerNamespaceInfoList &InnerNSs,

258 if (index == InnerNSs.size()) {

259 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&

260 Tok.isNot(tok::eof)) {

262 MaybeParseCXX11Attributes(DeclAttrs);

264 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);

265 }

266

267

268

270

271 return;

272 }

273

274

275

276

280 getCurScope(), InnerNSs[index].InlineLoc, InnerNSs[index].NamespaceLoc,

281 InnerNSs[index].IdentLoc, InnerNSs[index].Ident,

282 Tracker.getOpenLocation(), attrs, ImplicitUsingDirectiveDecl, true);

283 assert(!ImplicitUsingDirectiveDecl &&

284 "nested namespace definition cannot define anonymous namespace");

285

286 ParseInnerNamespace(InnerNSs, ++index, InlineLoc, attrs, Tracker);

287

288 NamespaceScope.Exit();

290}

291

292

293

294

299 assert(Tok.is(tok::equal) && "Not equal token");

300

302

303 if (Tok.is(tok::code_completion)) {

304 cutOffParsing();

306 return nullptr;

307 }

308

310

311 ParseOptionalCXXScopeSpecifier(SS, nullptr,

312 false,

313 false,

314 nullptr,

315 false,

316 nullptr,

317 true);

318

319 if (Tok.isNot(tok::identifier)) {

320 Diag(Tok, diag::err_expected_namespace_name);

321

323 return nullptr;

324 }

325

327

328

330 return nullptr;

331 }

332

333

336

337

339 if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name))

341

343 Alias, SS, IdentLoc, Ident);

344}

345

346

347

348

349

350

351

352

354 assert(isTokenStringLiteral() && "Not a string literal!");

356

358 Decl *LinkageSpec =

359 Lang.isInvalid()

360 ? nullptr

364

367

368 while (MaybeParseCXX11Attributes(DeclAttrs) ||

369 MaybeParseGNUAttributes(DeclSpecAttrs))

370 ;

371

372 if (Tok.isNot(tok::l_brace)) {

373

374

377

379 ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs, &DS);

382 : nullptr;

383 }

384

386

387 ProhibitAttributes(DeclAttrs);

388

390 T.consumeOpen();

391

392 unsigned NestedModules = 0;

393 while (true) {

395 case tok::annot_module_begin:

396 ++NestedModules;

398 continue;

399

400 case tok::annot_module_end:

401 if (!NestedModules)

402 break;

403 --NestedModules;

405 continue;

406

407 case tok::annot_module_include:

409 continue;

410

411 case tok::eof:

412 break;

413

414 case tok::r_brace:

415 if (!NestedModules)

416 break;

417 [[fallthrough]];

418 default:

421 while (MaybeParseCXX11Attributes(DeclAttrs) ||

422 MaybeParseGNUAttributes(DeclSpecAttrs))

423 ;

424 ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs);

425 continue;

426 }

427

428 break;

429 }

430

431 T.consumeClose();

433 getCurScope(), LinkageSpec, T.getCloseLocation())

434 : nullptr;

435}

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451Decl *Parser::ParseExportDeclaration() {

452 assert(Tok.is(tok::kw_export));

454

455 if (Tok.is(tok::code_completion)) {

456 cutOffParsing();

461 return nullptr;

462 }

463

468

469 if (Tok.isNot(tok::l_brace)) {

470

472 MaybeParseCXX11Attributes(DeclAttrs);

474 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);

477 }

478

480 T.consumeOpen();

481

482 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&

483 Tok.isNot(tok::eof)) {

485 MaybeParseCXX11Attributes(DeclAttrs);

487 ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);

488 }

489

490 T.consumeClose();

492 T.getCloseLocation());

493}

494

495

496

498 DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,

500 assert(Tok.is(tok::kw_using) && "Not using token");

502

503

505

506 if (Tok.is(tok::code_completion)) {

507 cutOffParsing();

509 return nullptr;

510 }

511

512

513 while (Tok.is(tok::kw_template)) {

515 Diag(TemplateLoc, diag::err_unexpected_template_after_using)

517 }

518

519

520 if (Tok.is(tok::kw_namespace)) {

521

522 if (TemplateInfo.Kind) {

523 SourceRange R = TemplateInfo.getSourceRange();

524 Diag(UsingLoc, diag::err_templated_using_directive_declaration)

526 }

527

528 Decl *UsingDir = ParseUsingDirective(Context, UsingLoc, DeclEnd, Attrs);

530 }

531

532

533 return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd, Attrs,

535}

536

537

538

539

540

541

542

543

544

545

546

551 assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");

552

553

555

556 if (Tok.is(tok::code_completion)) {

557 cutOffParsing();

559 return nullptr;

560 }

561

563

564 ParseOptionalCXXScopeSpecifier(SS, nullptr,

565 false,

566 false,

567 nullptr,

568 false,

569 nullptr,

570 true);

571

574

575

576 if (Tok.isNot(tok::identifier)) {

577 Diag(Tok, diag::err_expected_namespace_name);

578

580

581 return nullptr;

582 }

583

585

586

588 return nullptr;

589 }

590

591

594

595

596 bool GNUAttr = false;

597 if (Tok.is(tok::kw___attribute)) {

598 GNUAttr = true;

599 ParseGNUAttributes(attrs);

600 }

601

602

604 if (ExpectAndConsume(tok::semi,

605 GNUAttr ? diag::err_expected_semi_after_attribute_list

606 : diag::err_expected_semi_after_namespace_name))

608

610 IdentLoc, NamespcName, attrs);

611}

612

613

614

615

616

617

619 UsingDeclarator &D) {

620 D.clear();

621

622

623

625

626 if (Tok.is(tok::kw___super)) {

627 Diag(Tok.getLocation(), diag::err_super_in_using_declaration);

628 return true;

629 }

630

631

633 if (ParseOptionalCXXScopeSpecifier(D.SS, nullptr,

634 false,

635 false,

636 nullptr,

637 false,

638 &LastII,

639 false,

640 true))

641

642 return true;

643 if (D.SS.isInvalid())

644 return true;

645

646

647

648

649

650

651

652

653

654

655

657 Tok.is(tok::identifier) &&

661 NextToken().is(tok::kw___attribute)) &&

663 D.SS.getScopeRep()->getAsNamespace() &&

664 D.SS.getScopeRep()->getAsNamespaceAlias()) {

668 D.Name.setConstructorName(Type, IdLoc, IdLoc);

669 } else {

671 D.SS, nullptr,

672 false, false,

673 true,

674

675 !(Tok.is(tok::identifier) && NextToken().is(tok::equal)),

676 false, nullptr, D.Name))

677 return true;

678 }

679

682 ? diag::warn_cxx17_compat_using_declaration_pack

683 : diag::ext_using_declaration_pack);

684

685 return false;

686}

687

688

689

690

691

692

693

694

695

696

697

698

699

700

701

702

703

704

705

706

707

708

709

710

712 DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,

718

719 if (TryConsumeToken(tok::kw_enum, UELoc) && !InInitStatement) {

720

722 ? diag::warn_cxx17_compat_using_enum_declaration

723 : diag::ext_using_enum_declaration);

724

725 DiagnoseCXX11AttributeExtension(PrefixAttrs);

726

727 if (TemplateInfo.Kind) {

728 SourceRange R = TemplateInfo.getSourceRange();

729 Diag(UsingLoc, diag::err_templated_using_directive_declaration)

732 return nullptr;

733 }

735 if (ParseOptionalCXXScopeSpecifier(SS, nullptr,

736 false,

737 false,

738 nullptr,

739 true,

740 nullptr,

741 false,

742 true)) {

744 return nullptr;

745 }

746

747 if (Tok.is(tok::code_completion)) {

748 cutOffParsing();

750 return nullptr;

751 }

752

753 Decl *UED = nullptr;

754

755

756

757 if (Tok.is(tok::identifier)) {

760

762 *IdentInfo, IdentLoc, getCurScope(), &SS, true,

763 false,

764 nullptr, false,

765 true);

766

768 getCurScope(), AS, UsingLoc, UELoc, IdentLoc, *IdentInfo, Type, &SS);

769 } else if (Tok.is(tok::annot_template_id)) {

771

774 true);

775

776 assert(Tok.is(tok::annot_typename) && "template-id -> type failed");

779 ConsumeAnnotationToken();

780

782 UELoc, Loc, *TemplateId->Name,

783 Type.get(), &SS);

784 } else {

788 }

789 } else {

790 Diag(Tok.getLocation(), diag::err_using_enum_expect_identifier)

791 << Tok.is(tok::kw_enum);

793 return nullptr;

794 }

795

796 if (!UED) {

798 return nullptr;

799 }

800

802 if (ExpectAndConsume(tok::semi, diag::err_expected_after,

803 "using-enum declaration"))

805

807 }

808

809

810

812 MaybeParseCXX11Attributes(MisplacedAttrs);

813

814 if (InInitStatement && Tok.isNot(tok::identifier))

815 return nullptr;

816

817 UsingDeclarator D;

818 bool InvalidDeclarator = ParseUsingDeclarator(Context, D);

819

821 MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);

822

823

824

825 if (MisplacedAttrs.Range.isValid()) {

826 auto *FirstAttr =

827 MisplacedAttrs.empty() ? nullptr : &MisplacedAttrs.front();

828 auto &Range = MisplacedAttrs.Range;

829 (FirstAttr && FirstAttr->isRegularKeywordAttribute()

830 ? Diag(Range.getBegin(), diag::err_keyword_not_allowed) << FirstAttr

836 }

837

838

839 if (Tok.is(tok::equal) || InInitStatement) {

840 if (InvalidDeclarator) {

842 return nullptr;

843 }

844

845 ProhibitAttributes(PrefixAttrs);

846

847 Decl *DeclFromDeclSpec = nullptr;

849 if (CurScope)

852

853 Decl *AD = ParseAliasDeclarationAfterDeclarator(

854 TemplateInfo, UsingLoc, D, DeclEnd, AS, Attrs, &DeclFromDeclSpec);

856 }

857

858 DiagnoseCXX11AttributeExtension(PrefixAttrs);

859

860

861

862

863 if (TemplateInfo.Kind) {

864 SourceRange R = TemplateInfo.getSourceRange();

865 Diag(UsingLoc, diag::err_templated_using_directive_declaration)

867

868

869

870

871 return nullptr;

872 }

873

875 while (true) {

876

877 MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);

878 DiagnoseCXX11AttributeExtension(Attrs);

879 Attrs.addAll(PrefixAttrs.begin(), PrefixAttrs.end());

880

881 if (InvalidDeclarator)

883 else {

884

885

886 if (D.TypenameLoc.isValid() &&

889 diag::err_typename_identifiers_only)

891

893 }

894

896 D.TypenameLoc, D.SS, D.Name,

897 D.EllipsisLoc, Attrs);

898 if (UD)

899 DeclsInGroup.push_back(UD);

900 }

901

903 break;

904

905

907 InvalidDeclarator = ParseUsingDeclarator(Context, D);

908 }

909

910 if (DeclsInGroup.size() > 1)

913 ? diag::warn_cxx17_compat_multi_using_declaration

914 : diag::ext_multi_using_declaration);

915

916

918 if (ExpectAndConsume(tok::semi, diag::err_expected_after,

919 !Attrs.empty() ? "attributes list"

920 : UELoc.isValid() ? "using-enum declaration"

921 : "using declaration"))

923

925}

926

927Decl *Parser::ParseAliasDeclarationAfterDeclarator(

928 const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc,

931 if (ExpectAndConsume(tok::equal)) {

933 return nullptr;

934 }

935

937 ? diag::warn_cxx98_compat_alias_declaration

938 : diag::ext_alias_declaration);

939

940

941 int SpecKind = -1;

942 if (TemplateInfo.Kind == ParsedTemplateInfo::Template &&

944 SpecKind = 0;

945 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization)

946 SpecKind = 1;

947 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)

948 SpecKind = 2;

949 if (SpecKind != -1) {

951 if (SpecKind == 0)

953 D.Name.TemplateId->RAngleLoc);

954 else

955 Range = TemplateInfo.getSourceRange();

956 Diag(Range.getBegin(), diag::err_alias_declaration_specialization)

957 << SpecKind << Range;

959 return nullptr;

960 }

961

962

964 Diag(D.Name.StartLocation, diag::err_alias_declaration_not_identifier);

965

967 return nullptr;

968 } else if (D.TypenameLoc.isValid())

969 Diag(D.TypenameLoc, diag::err_alias_declaration_not_identifier)

972 : D.TypenameLoc));

973 else if (D.SS.isNotEmpty())

974 Diag(D.SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)

976 if (D.EllipsisLoc.isValid())

977 Diag(D.EllipsisLoc, diag::err_alias_declaration_pack_expansion)

979

980 Decl *DeclFromDeclSpec = nullptr;

985 AS, &DeclFromDeclSpec, &Attrs);

986 if (OwnedType)

987 *OwnedType = DeclFromDeclSpec;

988

989

991 if (ExpectAndConsume(tok::semi, diag::err_expected_after,

992 !Attrs.empty() ? "attributes list"

993 : "alias declaration"))

995

998 TemplateParams ? TemplateParams->data() : nullptr,

999 TemplateParams ? TemplateParams->size() : 0);

1001 UsingLoc, D.Name, Attrs, TypeAlias,

1002 DeclFromDeclSpec);

1003}

1004

1007 if (const auto *BO = dyn_cast_or_null(AssertExpr)) {

1008 if (BO->getOpcode() == BO_LAnd &&

1009 isa(BO->getRHS()->IgnoreImpCasts()))

1011 }

1013}

1014

1015

1016

1017

1018

1019

1020

1021

1022

1023Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {

1024 assert(Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert) &&

1025 "Not a static_assert declaration");

1026

1027

1028 const char *TokName = Tok.getName();

1029

1030 if (Tok.is(tok::kw__Static_assert))

1031 diagnoseUseOfC11Keyword(Tok);

1032 else if (Tok.is(tok::kw_static_assert)) {

1035 Diag(Tok, diag::warn_c23_compat_keyword) << Tok.getName();

1036 else

1039 } else

1040 Diag(Tok, diag::warn_cxx98_compat_static_assert);

1041 }

1042

1044

1046 if (T.consumeOpen()) {

1047 Diag(Tok, diag::err_expected) << tok::l_paren;

1049 return nullptr;

1050 }

1051

1055 if (AssertExpr.isInvalid()) {

1057 return nullptr;

1058 }

1059

1061 if (Tok.is(tok::r_paren)) {

1062 unsigned DiagVal;

1064 DiagVal = diag::warn_cxx14_compat_static_assert_no_message;

1066 DiagVal = diag::ext_cxx_static_assert_no_message;

1068 DiagVal = diag::warn_c17_compat_static_assert_no_message;

1069 else

1070 DiagVal = diag::ext_c_static_assert_no_message;

1073 } else {

1074 if (ExpectAndConsume(tok::comma)) {

1076 return nullptr;

1077 }

1078

1079 bool ParseAsExpression = false;

1081 for (unsigned I = 0;; ++I) {

1082 const Token &T = GetLookAheadToken(I);

1083 if (T.is(tok::r_paren))

1084 break;

1086 ParseAsExpression = true;

1087 break;

1088 }

1089 }

1090 }

1091

1092 if (ParseAsExpression) {

1095 ? diag::warn_cxx20_compat_static_assert_user_generated_message

1096 : diag::ext_cxx_static_assert_user_generated_message);

1100 else {

1101 Diag(Tok, diag::err_expected_string_literal)

1102 << 1;

1104 return nullptr;

1105 }

1106

1107 if (AssertMessage.isInvalid()) {

1109 return nullptr;

1110 }

1111 }

1112

1113 if (T.consumeClose())

1114 return nullptr;

1115

1117 ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, TokName);

1118

1120 AssertMessage.get(),

1121 T.getCloseLocation());

1122}

1123

1124

1125

1126

1127

1128

1130 assert(Tok.isOneOf(tok::kw_decltype, tok::annot_decltype) &&

1131 "Not a decltype specifier");

1132

1136

1137 if (Tok.is(tok::annot_decltype)) {

1138 Result = getExprAnnotation(Tok);

1140

1141

1143 ConsumeAnnotationToken();

1144 if (Result.isInvalid()) {

1146 return EndLoc;

1147 }

1148 } else {

1150 Diag(Tok, diag::warn_cxx98_compat_decltype);

1151

1153

1155 if (T.expectAndConsume(diag::err_expected_lparen_after, "decltype",

1156 tok::r_paren)) {

1158 return T.getOpenLocation() == Tok.getLocation() ? StartLoc

1159 : T.getOpenLocation();

1160 }

1161

1162

1163 if (Tok.is(tok::kw_auto) && NextToken().is(tok::r_paren)) {

1164

1165

1168 ? diag::warn_cxx11_compat_decltype_auto_type_specifier

1169 : diag::ext_decltype_auto_type_specifier);

1171 } else {

1172

1173

1174

1175

1181 false,

1183 if (Result.isInvalid()) {

1186 EndLoc = ConsumeParen();

1187 } else {

1189

1193 assert(Tok.is(tok::semi));

1194 } else {

1196 }

1197 }

1198 return EndLoc;

1199 }

1200

1202 }

1203

1204

1205 T.consumeClose();

1207 if (T.getCloseLocation().isInvalid()) {

1209

1210

1211 return T.getCloseLocation();

1212 }

1213

1214 if (Result.isInvalid()) {

1216 return T.getCloseLocation();

1217 }

1218

1219 EndLoc = T.getCloseLocation();

1220 }

1221 assert(Result.isInvalid());

1222

1223 const char *PrevSpec = nullptr;

1224 unsigned DiagID;

1226

1228 PrevSpec, DiagID, Result.get(), Policy)

1230 PrevSpec, DiagID, Policy)) {

1231 Diag(StartLoc, DiagID) << PrevSpec;

1233 }

1234 return EndLoc;

1235}

1236

1237void Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,

1240

1244

1245

1246

1247

1249 }

1250 } else

1251 PP.EnterToken(Tok, true);

1252

1253 Tok.setKind(tok::annot_decltype);

1254 setExprAnnotation(Tok,

1261}

1262

1264 assert(Tok.isOneOf(tok::annot_pack_indexing_type, tok::identifier) &&

1265 "Expected an identifier");

1266

1270 const char *PrevSpec;

1271 unsigned DiagID;

1273

1274 if (Tok.is(tok::annot_pack_indexing_type)) {

1279

1280

1282 ConsumeAnnotationToken();

1283 if (Type.isInvalid()) {

1285 return EndLoc;

1286 }

1288 DiagID, Type, Policy);

1289 return EndLoc;

1290 }

1291 if (NextToken().is(tok::ellipsis) ||

1292 !GetLookAheadToken(2).is(tok::l_square)) {

1295 }

1296

1299 if (!Ty) {

1302 }

1304

1308 T.consumeOpen();

1310 T.consumeClose();

1311

1314

1315 if (!IndexExpr.isUsable()) {

1319 }

1320

1322 Policy);

1324 return T.getCloseLocation();

1325}

1326

1327void Parser::AnnotateExistingIndexedTypeNamePack(ParsedType T,

1330

1333 if (T) {

1334

1335

1336

1337

1339 }

1340 } else

1341 PP.EnterToken(Tok, true);

1342

1343 Tok.setKind(tok::annot_pack_indexing_type);

1344 setTypeAnnotation(Tok, T);

1348}

1349

1350DeclSpec::TST Parser::TypeTransformTokToDeclSpec() {

1351 switch (Tok.getKind()) {

1352#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \

1353 case tok::kw___##Trait: \

1354 return DeclSpec::TST_##Trait;

1355#include "clang/Basic/TransformTypeTraits.def"

1356 default:

1357 llvm_unreachable("passed in an unhandled type transformation built-in");

1358 }

1359}

1360

1361bool Parser::MaybeParseTypeTransformTypeSpecifier(DeclSpec &DS) {

1362 if (NextToken().is(tok::l_paren)) {

1363 Tok.setKind(tok::identifier);

1364 return false;

1365 }

1366 DeclSpec::TST TypeTransformTST = TypeTransformTokToDeclSpec();

1368

1370 if (T.expectAndConsume(diag::err_expected_lparen_after, Tok.getName(),

1371 tok::r_paren))

1372 return true;

1373

1375 if (Result.isInvalid()) {

1377 return true;

1378 }

1379

1380 T.consumeClose();

1381 if (T.getCloseLocation().isInvalid())

1382 return true;

1383

1384 const char *PrevSpec = nullptr;

1385 unsigned DiagID;

1386 if (DS.SetTypeSpecType(TypeTransformTST, StartLoc, PrevSpec, DiagID,

1389 Diag(StartLoc, DiagID) << PrevSpec;

1391 return true;

1392}

1393

1394

1395

1396

1397

1398

1399

1400

1401

1402

1403

1404

1405

1406

1407

1408

1409

1410

1411

1414

1415 if (Tok.is(tok::kw_typename)) {

1416 Diag(Tok, diag::err_expected_class_name_not_template)

1419 }

1420

1421

1423 if (ParseOptionalCXXScopeSpecifier(SS, nullptr,

1424 false,

1425 false))

1426 return true;

1427

1429

1430

1431

1432

1433 if (Tok.isOneOf(tok::kw_decltype, tok::annot_decltype)) {

1435 Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype)

1437

1439

1440 EndLocation = ParseDecltypeSpecifier(DS);

1441

1445 }

1446

1447 if (Tok.is(tok::annot_pack_indexing_type)) {

1449 ParsePackIndexingType(DS);

1453 }

1454

1455

1456

1457

1458 if (Tok.is(tok::annot_template_id)) {

1462 true);

1463

1464 assert(Tok.is(tok::annot_typename) && "template-id -> type failed");

1467 ConsumeAnnotationToken();

1468 return Type;

1469 }

1470

1471

1472 }

1473

1474 if (Tok.isNot(tok::identifier)) {

1475 Diag(Tok, diag::err_expected_class_name);

1476 return true;

1477 }

1478

1481

1482 if (Tok.is(tok::less)) {

1483

1484

1485

1486

1490 Template, TNK)) {

1491 Diag(IdLoc, diag::err_unknown_template_name) << Id;

1492 }

1493

1494

1497

1498

1499 if (AnnotateTemplateIdToken(Template, TNK, SS, SourceLocation(),

1501 return true;

1502 if (Tok.is(tok::annot_template_id) &&

1503 takeTemplateIdAnnotation(Tok)->mightBeType())

1505 true);

1506

1507

1508

1509 if (Tok.isNot(tok::annot_typename))

1510 return true;

1511

1512

1513

1516 ConsumeAnnotationToken();

1517 return Type;

1518 }

1519

1520

1523 *Id, IdLoc, getCurScope(), &SS, true, false, nullptr,

1524 false,

1525 true,

1527 &CorrectedII);

1528 if (Type) {

1529 Diag(IdLoc, diag::err_expected_class_name);

1530 return true;

1531 }

1532

1533

1534 EndLocation = IdLoc;

1535

1536

1541

1542 const char *PrevSpec = nullptr;

1543 unsigned DiagID;

1546

1550}

1551

1552void Parser::ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs) {

1553 while (Tok.isOneOf(tok::kw___single_inheritance,

1554 tok::kw___multiple_inheritance,

1555 tok::kw___virtual_inheritance)) {

1559 attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, Kind);

1560 }

1561}

1562

1563void Parser::ParseNullabilityClassAttributes(ParsedAttributes &attrs) {

1564 while (Tok.is(tok::kw__Nullable)) {

1568 attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0, Kind);

1569 }

1570}

1571

1572

1573

1574

1575bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {

1576

1577 switch (Tok.getKind()) {

1578 default:

1580 return true;

1581 break;

1582 case tok:🚛

1583 case tok:⭐

1584 case tok::amp:

1585 case tok::ampamp:

1586 case tok::identifier:

1587 case tok::r_paren:

1588 case tok::coloncolon:

1589 case tok::annot_cxxscope:

1590 case tok::annot_typename:

1591 case tok::annot_template_id:

1592 case tok::kw_decltype:

1593 case tok::l_paren:

1594 case tok::comma:

1595 case tok::kw_operator:

1596 case tok::kw___declspec:

1597 case tok::l_square:

1598 case tok::ellipsis:

1599

1600

1601 case tok::kw___attribute:

1602 case tok::annot_pragma_pack:

1603

1604 case tok::annot_pragma_ms_pragma:

1605

1606 case tok::annot_pragma_ms_vtordisp:

1607

1608 case tok::annot_pragma_ms_pointers_to_members:

1609 return true;

1610 case tok::colon:

1611 return CouldBeBitfield ||

1612 ColonIsSacred;

1613

1614 case tok::kw___cdecl:

1615 case tok::kw___fastcall:

1616 case tok::kw___stdcall:

1617 case tok::kw___thiscall:

1618 case tok::kw___vectorcall:

1619

1620

1622

1623 case tok::kw_const:

1624 case tok::kw_volatile:

1625 case tok::kw_restrict:

1626 case tok::kw__Atomic:

1627 case tok::kw___unaligned:

1628

1629

1630

1631 case tok::kw_inline:

1632 case tok::kw_virtual:

1633 case tok::kw_friend:

1634

1635 case tok::kw_static:

1636 case tok::kw_extern:

1637 case tok::kw_typedef:

1638 case tok::kw_register:

1639 case tok::kw_auto:

1640 case tok::kw_mutable:

1641 case tok::kw_thread_local:

1642 case tok::kw_constexpr:

1643 case tok::kw_consteval:

1644 case tok::kw_constinit:

1645

1646

1647

1648

1649

1650

1651

1652

1653

1654

1655

1656

1657

1658

1659

1660 if (!isKnownToBeTypeSpecifier(NextToken()))

1661 return true;

1662 break;

1663 case tok::r_brace:

1664

1666 return true;

1667 break;

1668 case tok::greater:

1669

1671 }

1672 return false;

1673}

1674

1675

1676

1677

1678

1679

1680

1681

1682

1683

1684

1685

1686

1687

1688

1689

1690

1691

1692

1693

1694

1695

1696

1697

1698

1699

1700

1701

1702

1703

1704

1705

1706

1707

1708

1709

1710

1711

1712

1713

1714

1715void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,

1717 ParsedTemplateInfo &TemplateInfo,

1719 DeclSpecContext DSC,

1722 if (TagTokKind == tok::kw_struct)

1724 else if (TagTokKind == tok::kw___interface)

1726 else if (TagTokKind == tok::kw_class)

1728 else {

1729 assert(TagTokKind == tok::kw_union && "Not a class specifier");

1731 }

1732

1733 if (Tok.is(tok::code_completion)) {

1734

1735 cutOffParsing();

1737 return;

1738 }

1739

1740

1741

1742

1743

1744

1745

1746

1747 const bool shouldDelayDiagsInTag =

1748 (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate);

1750

1752

1753 for (;;) {

1754 MaybeParseAttributes(PAKM_CXX11 | PAKM_Declspec | PAKM_GNU, attrs);

1755

1756 if (Tok.isOneOf(tok::kw___single_inheritance,

1757 tok::kw___multiple_inheritance,

1758 tok::kw___virtual_inheritance)) {

1759 ParseMicrosoftInheritanceClassAttributes(attrs);

1760 continue;

1761 }

1762 if (Tok.is(tok::kw__Nullable)) {

1763 ParseNullabilityClassAttributes(attrs);

1764 continue;

1765 }

1766 break;

1767 }

1768

1769

1770

1772

1777#include "clang/Basic/TransformTypeTraits.def"

1778 tok::kw___is_abstract,

1779 tok::kw___is_aggregate,

1780 tok::kw___is_arithmetic,

1781 tok::kw___is_array,

1782 tok::kw___is_assignable,

1783 tok::kw___is_base_of,

1784 tok::kw___is_bounded_array,

1785 tok::kw___is_class,

1786 tok::kw___is_complete_type,

1787 tok::kw___is_compound,

1788 tok::kw___is_const,

1789 tok::kw___is_constructible,

1790 tok::kw___is_convertible,

1791 tok::kw___is_convertible_to,

1792 tok::kw___is_destructible,

1793 tok::kw___is_empty,

1794 tok::kw___is_enum,

1795 tok::kw___is_floating_point,

1796 tok::kw___is_final,

1797 tok::kw___is_function,

1798 tok::kw___is_fundamental,

1799 tok::kw___is_integral,

1800 tok::kw___is_interface_class,

1801 tok::kw___is_literal,

1802 tok::kw___is_lvalue_expr,

1803 tok::kw___is_lvalue_reference,

1804 tok::kw___is_member_function_pointer,

1805 tok::kw___is_member_object_pointer,

1806 tok::kw___is_member_pointer,

1807 tok::kw___is_nothrow_assignable,

1808 tok::kw___is_nothrow_constructible,

1809 tok::kw___is_nothrow_convertible,

1810 tok::kw___is_nothrow_destructible,

1811 tok::kw___is_object,

1812 tok::kw___is_pod,

1813 tok::kw___is_pointer,

1814 tok::kw___is_polymorphic,

1815 tok::kw___is_reference,

1816 tok::kw___is_referenceable,

1817 tok::kw___is_rvalue_expr,

1818 tok::kw___is_rvalue_reference,

1819 tok::kw___is_same,

1820 tok::kw___is_scalar,

1821 tok::kw___is_scoped_enum,

1822 tok::kw___is_sealed,

1823 tok::kw___is_signed,

1824 tok::kw___is_standard_layout,

1825 tok::kw___is_trivial,

1826 tok::kw___is_trivially_equality_comparable,

1827 tok::kw___is_trivially_assignable,

1828 tok::kw___is_trivially_constructible,

1829 tok::kw___is_trivially_copyable,

1830 tok::kw___is_unbounded_array,

1831 tok::kw___is_union,

1832 tok::kw___is_unsigned,

1833 tok::kw___is_void,

1834 tok::kw___is_volatile

1835 ))

1836

1837

1838

1839

1840

1841 TryKeywordIdentFallback(true);

1842

1843 struct PreserveAtomicIdentifierInfoRAII {

1844 PreserveAtomicIdentifierInfoRAII(Token &Tok, bool Enabled)

1845 : AtomicII(nullptr) {

1846 if (!Enabled)

1847 return;

1848 assert(Tok.is(tok::kw__Atomic));

1851 Tok.setKind(tok::identifier);

1852 }

1853 ~PreserveAtomicIdentifierInfoRAII() {

1854 if (!AtomicII)

1855 return;

1856 AtomicII->revertIdentifierToTokenID(tok::kw__Atomic);

1857 }

1859 };

1860

1861

1862

1863

1864

1865

1866 bool ShouldChangeAtomicToIdentifier = getLangOpts().MSVCCompat &&

1867 Tok.is(tok::kw__Atomic) &&

1869 PreserveAtomicIdentifierInfoRAII AtomicTokenGuard(

1870 Tok, ShouldChangeAtomicToIdentifier);

1871

1872

1875

1876

1878

1880 if (TemplateInfo.TemplateParams)

1882

1883 bool HasValidSpec = true;

1884 if (ParseOptionalCXXScopeSpecifier(Spec, nullptr,

1885 false,

1886 EnteringContext)) {

1888 HasValidSpec = false;

1889 }

1890 if (Spec.isSet())

1891 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) {

1892 Diag(Tok, diag::err_expected) << tok::identifier;

1893 HasValidSpec = false;

1894 }

1895 if (HasValidSpec)

1896 SS = Spec;

1897 }

1898

1900

1901 auto RecoverFromUndeclaredTemplateName = [&](IdentifierInfo *Name,

1904 bool KnownUndeclared) {

1905 Diag(NameLoc, diag::err_explicit_spec_non_template)

1906 << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)

1907 << TagTokKind << Name << TemplateArgRange << KnownUndeclared;

1908

1909

1910

1911 if (TemplateParams && TemplateInfo.LastParameterListWasEmpty) {

1912 if (TemplateParams->size() > 1) {

1913 TemplateParams->pop_back();

1914 } else {

1915 TemplateParams = nullptr;

1916 TemplateInfo.Kind = ParsedTemplateInfo::NonTemplate;

1917 }

1918 } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {

1919

1920 TemplateParams = nullptr;

1921 TemplateInfo.Kind = ParsedTemplateInfo::NonTemplate;

1924 }

1925 };

1926

1927

1931 if (Tok.is(tok::identifier)) {

1935

1937

1938

1939

1940 TemplateArgList TemplateArgs;

1942 if (ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs,

1943 RAngleLoc)) {

1944

1945

1947 }

1948 RecoverFromUndeclaredTemplateName(

1949 Name, NameLoc, SourceRange(LAngleLoc, RAngleLoc), false);

1950 }

1951 } else if (Tok.is(tok::annot_template_id)) {

1952 TemplateId = takeTemplateIdAnnotation(Tok);

1953 NameLoc = ConsumeAnnotationToken();

1954

1956

1960 RecoverFromUndeclaredTemplateName(

1961 Name, NameLoc,

1963 TemplateId = nullptr;

1964 }

1965 }

1966

1967 if (TemplateId && !TemplateId->mightBeType()) {

1968

1969

1970

1974

1975

1976 Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)

1977 << TemplateId->Name << static_cast<int>(TemplateId->Kind) << Range;

1978

1981 return;

1982 }

1983 }

1984

1985

1986

1987

1988

1989

1990

1991

1992

1993

1994

1995

1996

1997

1998

1999

2000

2001

2002

2003

2004

2005

2006

2007

2008

2009

2010

2011

2012 MaybeParseCXX11Attributes(Attributes);

2013

2016

2017

2018

2019

2021 Tok.isOneOf(tok::comma, tok::ellipsis))

2024 AllowDefiningTypeSpec::No ||

2025 (getLangOpts().OpenMP && OpenMPDirectiveParsing))

2027 else if (Tok.is(tok::l_brace) ||

2028 (DSC != DeclSpecContext::DSC_association &&

2030 (isClassCompatibleKeyword() &&

2033

2034

2035 Diag(Tok.getLocation(), diag::err_friend_decl_defines_type)

2037

2038

2039

2042 } else {

2043

2045 }

2046 } else if (isClassCompatibleKeyword() &&

2047 (NextToken().is(tok::l_square) ||

2048 NextToken().is(tok::kw_alignas) ||

2051

2052

2053 TentativeParsingAction PA(*this);

2054

2055

2056 while (isClassCompatibleKeyword()) {

2058 }

2059

2060

2061 while (true) {

2062 if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) {

2063 ConsumeBracket();

2065 break;

2066 } else if (Tok.is(tok::kw_alignas) && NextToken().is(tok::l_paren)) {

2068 ConsumeParen();

2070 break;

2074 if (TakesArgs) {

2076 if (T.consumeOpen())

2077 T.skipToEnd();

2078 }

2079 } else {

2080 break;

2081 }

2082 }

2083

2084 if (Tok.isOneOf(tok::l_brace, tok::colon))

2086 else

2088

2089 PA.Revert();

2090 } else if (!isTypeSpecifier(DSC) &&

2091 (Tok.is(tok::semi) ||

2092 (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) {

2094 if (Tok.isNot(tok::semi)) {

2096

2097 ExpectAndConsume(tok::semi, diag::err_expected_after,

2099 PP.EnterToken(Tok, true);

2101 }

2102 } else

2104

2105

2106

2108

2109

2110

2111

2112

2114 if (AttrRange.isValid()) {

2115 auto *FirstAttr = Attributes.empty() ? nullptr : &Attributes.front();

2117 (FirstAttr && FirstAttr->isRegularKeywordAttribute()

2118 ? Diag(Loc, diag::err_keyword_not_allowed) << FirstAttr

2119 : Diag(Loc, diag::err_attributes_not_allowed))

2120 << AttrRange

2124

2125

2126

2128 }

2129 }

2130

2131 if (!Name && !TemplateId &&

2135

2136 Diag(StartLoc, diag::err_anon_type_definition)

2138 }

2139

2140

2141

2142

2145 else

2147 return;

2148 }

2149

2150

2151 DeclResult TagOrTempResult = true;

2153

2154 bool Owned = false;

2156 if (TemplateId) {

2157

2158

2162

2163 } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&

2165

2166 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,

2167 diag::err_keyword_not_allowed,

2168 true);

2169

2171 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,

2175

2176

2177

2178

2179

2182 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {

2183 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,

2184 diag::err_keyword_not_allowed,

2185 true);

2190 } else {

2191

2192

2194 if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {

2195

2196

2197

2198

2199

2200

2201

2202

2203

2204

2205

2207 "Expected a definition here");

2208

2211 TemplateParams = nullptr;

2212 } else {

2216 diag::err_explicit_instantiation_with_definition)

2217 << SourceRange(TemplateInfo.TemplateLoc)

2219

2220

2221

2222

2224 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},

2225 LAngleLoc, nullptr));

2226 TemplateParams = &FakedParamLists;

2227 }

2228 }

2229

2230

2233 SS, *TemplateId, attrs,

2235 : nullptr,

2236 TemplateParams ? TemplateParams->size() : 0),

2237 &SkipBody);

2238 }

2239 } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&

2241

2242

2243

2244

2245

2246 ProhibitAttributes(attrs);

2247

2249 getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc,

2250 TagType, StartLoc, SS, Name, NameLoc, attrs);

2252 TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {

2253 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,

2254 diag::err_keyword_not_allowed,

2255 true);

2256

2257

2260

2261

2262

2263

2264

2265

2266

2267

2268

2269

2270 if (Tok.is(tok::comma)) {

2272 diag::err_friend_template_decl_multiple_specifiers);

2274 }

2275

2278 NameLoc, EllipsisLoc, attrs,

2280 TemplateParams ? TemplateParams->size() : 0));

2281 } else {

2283 ProhibitCXX11Attributes(attrs, diag::err_attributes_not_allowed,

2284 diag::err_keyword_not_allowed,

2285 true);

2286

2288 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {

2289

2290

2291 Diag(Tok, diag::err_template_defn_explicit_instantiation)

2293 TemplateParams = nullptr;

2294 }

2295

2296 bool IsDependent = false;

2297

2298

2299

2300

2303 TParams =

2305

2306 stripTypeAttributesOffDeclSpec(attrs, DS, TUK);

2307

2308

2309 TagOrTempResult = Actions.ActOnTag(

2310 getCurScope(), TagType, TUK, StartLoc, SS, Name, NameLoc, attrs, AS,

2313 DSC == DeclSpecContext::DSC_type_specifier,

2314 DSC == DeclSpecContext::DSC_template_param ||

2315 DSC == DeclSpecContext::DSC_template_type_arg,

2316 OffsetOfState, &SkipBody);

2317

2318

2319

2320 if (IsDependent) {

2323 Name, StartLoc, NameLoc);

2324 }

2325 }

2326

2327

2328

2329

2330 if (shouldDelayDiagsInTag) {

2331 diagsFromTag.done();

2333 TemplateInfo.Kind == ParsedTemplateInfo::Template)

2334 diagsFromTag.redelay();

2335 }

2336

2337

2339 assert(Tok.is(tok::l_brace) ||

2341 isClassCompatibleKeyword());

2343 SkipCXXMemberSpecification(StartLoc, AttrFixitLoc, TagType,

2344 TagOrTempResult.get());

2346 ParseCXXMemberSpecification(StartLoc, AttrFixitLoc, attrs, TagType,

2347 TagOrTempResult.get());

2348 else {

2351

2352 ParseStructUnionBody(StartLoc, TagType, cast(D));

2356 return;

2357 }

2358 }

2359 }

2360

2361 if (!TagOrTempResult.isInvalid())

2362

2364

2365 const char *PrevSpec = nullptr;

2366 unsigned DiagID;

2370 NameLoc.isValid() ? NameLoc : StartLoc,

2372 } else if (!TagOrTempResult.isInvalid()) {

2374 TagType, StartLoc, NameLoc.isValid() ? NameLoc : StartLoc, PrevSpec,

2375 DiagID, TagOrTempResult.get(), Owned, Policy);

2376 } else {

2378 return;

2379 }

2380

2382 Diag(StartLoc, DiagID) << PrevSpec;

2383

2384

2385

2386

2387

2388

2389

2390

2391

2392

2393

2394

2395

2398 (TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) {

2399 if (Tok.isNot(tok::semi)) {

2401 ExpectAndConsume(tok::semi, diag::err_expected_after,

2403

2404

2405

2406 PP.EnterToken(Tok, true);

2408 }

2409 }

2410}

2411

2412

2413

2414

2415

2416

2417

2418

2419void Parser::ParseBaseClause(Decl *ClassDecl) {

2420 assert(Tok.is(tok::colon) && "Not a base clause");

2422

2423

2425

2426 while (true) {

2427

2429 if (Result.isInvalid()) {

2430

2431

2433 } else {

2434

2435 BaseInfo.push_back(Result.get());

2436 }

2437

2438

2439

2441 break;

2442 }

2443

2444

2446}

2447

2448

2449

2450

2451

2452

2453

2454

2455

2456

2457

2458

2459BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) {

2460 bool IsVirtual = false;

2462

2464 MaybeParseCXX11Attributes(Attributes);

2465

2466

2468 IsVirtual = true;

2469

2470 CheckMisplacedCXX11Attribute(Attributes, StartLoc);

2471

2472

2474 if (Access != AS_none) {

2477 Diag(Tok.getLocation(), diag::ext_hlsl_access_specifiers);

2478 }

2479

2480 CheckMisplacedCXX11Attribute(Attributes, StartLoc);

2481

2482

2483

2484 if (Tok.is(tok::kw_virtual)) {

2486 if (IsVirtual) {

2487

2488 Diag(VirtualLoc, diag::err_dup_virtual)

2490 }

2491

2492 IsVirtual = true;

2493 }

2494

2495 CheckMisplacedCXX11Attribute(Attributes, StartLoc);

2496

2497

2498

2499

2500

2501

2502

2503 if (getLangOpts().MSVCCompat && Tok.is(tok::kw__Atomic) &&

2505 Tok.setKind(tok::identifier);

2506

2509 TypeResult BaseType = ParseBaseTypeSpecifier(BaseLoc, EndLocation);

2511 return true;

2512

2513

2514

2515

2518

2519

2521

2522

2523

2525 Access, BaseType.get(), BaseLoc,

2526 EllipsisLoc);

2527}

2528

2529

2530

2531

2532

2533

2534

2535

2536AccessSpecifier Parser::getAccessSpecifierIfPresent() const {

2537 switch (Tok.getKind()) {

2538 default:

2540 case tok::kw_private:

2542 case tok::kw_protected:

2544 case tok::kw_public:

2546 }

2547}

2548

2549

2550

2551

2552

2553void Parser::HandleMemberFunctionDeclDelays(Declarator &DeclaratorInfo,

2554 Decl *ThisDecl) {

2556

2557

2559

2560 if (!NeedLateParse) {

2561

2564 if (Param->hasUnparsedDefaultArg()) {

2565 NeedLateParse = true;

2566 break;

2567 }

2568 }

2569 }

2570

2571 if (NeedLateParse) {

2572

2573

2574 auto LateMethod = new LateParsedMethodDeclaration(this, ThisDecl);

2575 getCurrentClass().LateParsedDeclarations.push_back(LateMethod);

2576

2577

2578

2579

2580 LateMethod->DefaultArgs.reserve(FTI.NumParams);

2582 LateMethod->DefaultArgs.push_back(LateParsedDefaultArgument(

2585

2586

2590 }

2591 }

2592}

2593

2594

2595

2596

2597

2598

2599

2600

2604

2606

2607

2608 if (!Ident_final) {

2615 }

2617 }

2618

2619 if (II == Ident_override)

2621

2622 if (II == Ident_sealed)

2624

2625 if (II == Ident_abstract)

2627

2628 if (II == Ident_final)

2630

2631 if (II == Ident_GNU_final)

2633

2635}

2636

2637

2638

2639

2640

2641

2642void Parser::ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS,

2643 bool IsInterface,

2645 while (true) {

2648 return;

2649

2650 if (FriendLoc.isValid()) {

2656 continue;

2657 }

2658

2659

2660

2661 const char *PrevSpec = nullptr;

2663 Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier)

2665

2668 Diag(Tok.getLocation(), diag::err_override_control_interface)

2676 } else {

2679 ? diag::warn_cxx98_compat_override_control_keyword

2680 : diag::ext_override_control_keyword)

2682 }

2684 }

2685}

2686

2687

2688

2689bool Parser::isCXX11FinalKeyword() const {

2694}

2695

2696

2697

2698bool Parser::isClassCompatibleKeyword() const {

2704}

2705

2706

2707

2708bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(

2710 LateParsedAttrList &LateParsedAttrs) {

2711

2712

2713

2714

2715

2716

2717

2718

2719

2720

2721 if (Tok.isNot(tok::colon))

2722 ParseDeclarator(DeclaratorInfo);

2723 else

2725

2727 MaybeParseHLSLAnnotations(DeclaratorInfo, nullptr,

2728 true);

2729

2732 "don't know where identifier would go yet?");

2736 } else if (Tok.is(tok::kw_requires)) {

2737 ParseTrailingRequiresClause(DeclaratorInfo);

2738 } else {

2739 ParseOptionalCXX11VirtSpecifierSeq(

2740 VS, getCurrentClass().IsInterface,

2743 MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo,

2744 VS);

2745 }

2746

2747

2748 if (Tok.is(tok::kw_asm)) {

2750 ExprResult AsmLabel(ParseSimpleAsm( true, &Loc));

2751 if (AsmLabel.isInvalid())

2753

2754 DeclaratorInfo.setAsmLabel(AsmLabel.get());

2756 }

2757

2758

2759

2760

2761 DiagnoseAndSkipCXX11Attributes();

2762 MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);

2763 DiagnoseAndSkipCXX11Attributes();

2764

2765

2766

2768 ParseOptionalCXX11VirtSpecifierSeq(

2769 VS, getCurrentClass().IsInterface,

2772

2773

2775 if (AL.isKnownToGCC() && !AL.isCXX11Attribute())

2776 Diag(AL.getLoc(), diag::warn_gcc_attribute_location);

2777

2778 MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(DeclaratorInfo,

2779 VS);

2780 }

2781 }

2782

2783

2784

2785 if (!DeclaratorInfo.hasName() && BitfieldSize.isUnset()) {

2786

2788 return true;

2789 }

2790 return false;

2791}

2792

2793

2794

2795void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(

2798

2799

2800

2801 ParseTypeQualifierListOpt(

2802 DS, AR_NoAttributesParsed, false,

2803 false, llvm::function_ref<void()>([&]() {

2804 Actions.CodeCompletion().CodeCompleteFunctionQualifiers(DS, D, &VS);

2805 }));

2806 D.ExtendWithDeclSpec(DS);

2807

2808 if (D.isFunctionDeclarator()) {

2809 auto &Function = D.getFunctionTypeInfo();

2811 auto DeclSpecCheck = [&](DeclSpec::TQ TypeQual, StringRef FixItName,

2814 auto &MQ = Function.getOrCreateMethodQualifiers();

2815 if (!(MQ.getTypeQualifiers() & TypeQual)) {

2816 std::string Name(FixItName.data());

2817 Name += " ";

2819 MQ.SetTypeQual(TypeQual, SpecLoc);

2820 }

2821 Diag(SpecLoc, diag::err_declspec_after_virtspec)

2822 << FixItName

2825 };

2827 }

2828

2829

2830 bool RefQualifierIsLValueRef = true;

2832 if (ParseRefQualifier(RefQualifierIsLValueRef, RefQualifierLoc)) {

2833 const char *Name = (RefQualifierIsLValueRef ? "& " : "&& ");

2836 Function.RefQualifierIsLValueRef = RefQualifierIsLValueRef;

2837 Function.RefQualifierLoc = RefQualifierLoc;

2838

2839 Diag(RefQualifierLoc, diag::err_declspec_after_virtspec)

2840 << (RefQualifierIsLValueRef ? "&" : "&&")

2843 D.SetRangeEnd(RefQualifierLoc);

2844 }

2845 }

2846}

2847

2848

2849

2850

2851

2852

2853

2854

2855

2856

2857

2858

2859

2860

2861

2862

2863

2864

2865

2866

2867

2868

2869

2870

2871

2872

2873

2874

2875

2876

2877

2878

2879

2880

2881

2882

2883

2884

2885

2886

2887

2888

2889

2890

2891

2892

2893

2894

2895

2896

2897

2902 "ParseCXXClassMemberDeclaration should only be called in C++ mode");

2903 if (Tok.is(tok::at)) {

2905 Diag(Tok, diag::err_at_defs_cxx);

2906 else

2907 Diag(Tok, diag::err_at_in_class);

2908

2911 return nullptr;

2912 }

2913

2914

2915

2916

2917

2918

2919

2921

2922

2923 bool MalformedTypeSpec = false;

2924 if (!TemplateInfo.Kind &&

2925 Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw___super)) {

2927 MalformedTypeSpec = true;

2928

2929 bool isAccessDecl;

2930 if (Tok.isNot(tok::annot_cxxscope))

2931 isAccessDecl = false;

2932 else if (NextToken().is(tok::identifier))

2933 isAccessDecl = GetLookAheadToken(2).is(tok::semi);

2934 else

2935 isAccessDecl = NextToken().is(tok::kw_operator);

2936

2937 if (isAccessDecl) {

2938

2940 ParseOptionalCXXScopeSpecifier(SS, nullptr,

2941 false,

2942 false);

2943

2946 return nullptr;

2947 }

2948

2949

2953 false, false, true, true,

2954 false, &TemplateKWLoc, Name)) {

2956 return nullptr;

2957 }

2958

2959

2960 if (ExpectAndConsume(tok::semi, diag::err_expected_after,

2961 "access declaration")) {

2963 return nullptr;

2964 }

2965

2966

2972 }

2973 }

2974

2975

2976

2977 if (!TemplateInfo.Kind &&

2978 Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert)) {

2981 DeclGroupRef(ParseStaticAssertDeclaration(DeclEnd)));

2982 }

2983

2984 if (Tok.is(tok::kw_template)) {

2985 assert(!TemplateInfo.TemplateParams &&

2986 "Nested template improperly parsed?");

2990 DeclEnd, AccessAttrs, AS);

2991 }

2992

2993

2994 if (Tok.is(tok::kw___extension__)) {

2995

2998 return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,

2999 TemplateDiags);

3000 }

3001

3003

3004 MaybeParseCXX11Attributes(DeclAttrs);

3005

3006

3007

3008

3009 if (Tok.is(tok::annot_attr_openmp))

3010 return ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, DeclAttrs);

3011

3012 if (Tok.is(tok::kw_using)) {

3013

3015

3016

3017 while (Tok.is(tok::kw_template)) {

3019 Diag(TemplateLoc, diag::err_unexpected_template_after_using)

3021 }

3022

3023 if (Tok.is(tok::kw_namespace)) {

3024 Diag(UsingLoc, diag::err_using_namespace_in_class);

3026 return nullptr;

3027 }

3029

3031 UsingLoc, DeclEnd, DeclAttrs, AS);

3032 }

3033

3035 MaybeParseMicrosoftAttributes(DeclSpecAttrs);

3036

3037

3038 LateParsedAttrList CommonLateParsedAttrs;

3039

3040

3041

3044

3045 if (MalformedTypeSpec)

3047

3048

3049

3050

3051

3052

3053 bool IsTemplateSpecOrInst =

3054 (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation ||

3055 TemplateInfo.Kind == ParsedTemplateInfo::ExplicitSpecialization);

3057

3058 ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DeclSpecContext::DSC_class,

3059 &CommonLateParsedAttrs);

3060

3061 if (IsTemplateSpecOrInst)

3062 diagsFromTag.done();

3063

3064

3065 X.restore();

3066

3067

3068

3070 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate &&

3071 DiagnoseMissingSemiAfterTagDefinition(DS, AS, DeclSpecContext::DSC_class,

3072 &CommonLateParsedAttrs))

3073 return nullptr;

3074

3076 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data()

3077 : nullptr,

3078 TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);

3079

3082 ProhibitAttributes(DeclAttrs);

3083

3086 getCurScope(), AS, DS, DeclAttrs, TemplateParams, false, AnonRecord);

3088 DS.complete(TheDecl);

3089 if (AnonRecord) {

3090 Decl *decls[] = {AnonRecord, TheDecl};

3092 }

3094 }

3095

3098

3099

3100

3103 ? diag::warn_cxx23_variadic_friends

3104 : diag::ext_variadic_friends);

3105

3108

3109

3113

3117 AnonRecord, VariadicLoc);

3119 if (D) {

3120 SkipUntil(tok::semi, tok::r_brace);

3121 return true;

3122 }

3123

3124 Decls.push_back(D);

3125 return false;

3126 };

3127

3128 if (ParsedFriendDecl(DS))

3129 return nullptr;

3130

3133 const char *PrevSpec = nullptr;

3134 unsigned DiagId = 0;

3136 ParseDeclarationSpecifiers(DeclSpec, TemplateInfo, AS,

3137 DeclSpecContext::DSC_class, nullptr);

3138 if (ParsedFriendDecl(DeclSpec))

3139 return nullptr;

3140 }

3141

3142 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt,

3143 "friend declaration");

3144

3146 }

3147

3148

3149

3150

3151 if (Tok.is(tok::kw_concept)) {

3155 ? llvm::to_underlying(diag::err_friend_concept)

3156 : llvm::to_underlying(

3157 diag::

3158 err_concept_decls_may_only_appear_in_global_namespace_scope));

3160 return nullptr;

3161 }

3162

3165 if (TemplateInfo.TemplateParams)

3168

3169

3170 LateParsedAttrList LateParsedAttrs;

3171

3174

3175 auto TryConsumePureSpecifier = [&](bool AllowDefinition) {

3176 if (Tok.isNot(tok::equal))

3177 return false;

3178

3181 if (Zero.isNot(tok::numeric_constant) ||

3183 return false;

3184

3185 auto &After = GetLookAheadToken(2);

3186 if (After.isOneOf(tok::semi, tok::comma) &&

3187 !(AllowDefinition &&

3188 After.isOneOf(tok::l_brace, tok::colon, tok::kw_try)))

3189 return false;

3190

3193 return true;

3194 };

3195

3199 bool ExpectSemi = true;

3200

3201

3202

3203

3205

3206

3207 if (ParseCXXMemberDeclaratorBeforeInitializer(

3208 DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs)) {

3210 return nullptr;

3211 }

3212

3213 if (IsTemplateSpecOrInst)

3214 SAC.done();

3215

3216

3217 if (BitfieldSize.isUnset()) {

3218

3219

3221 TryConsumePureSpecifier( true);

3222

3224

3225

3226

3227

3228

3232 if (Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try)) {

3234 } else if (Tok.is(tok::equal)) {

3236 if (KW.is(tok::kw_default))

3238 else if (KW.is(tok::kw_delete))

3240 else if (KW.is(tok::code_completion)) {

3241 cutOffParsing();

3243 DeclaratorInfo);

3244 return nullptr;

3245 }

3246 }

3247 }

3249

3250

3251

3255

3256

3257 ProhibitAttributes(DeclAttrs);

3258 }

3259

3263 ConsumeBrace();

3265

3266

3268

3269 return nullptr;

3270 }

3271

3274 diag::err_function_declared_typedef);

3275

3276

3278 }

3279

3280 Decl *FunDecl = ParseCXXInlineMethodDef(AS, AccessAttrs, DeclaratorInfo,

3281 TemplateInfo, VS, PureSpecLoc);

3282

3283 if (FunDecl) {

3284 for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i) {

3285 CommonLateParsedAttrs[i]->addDecl(FunDecl);

3286 }

3287 for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {

3288 LateParsedAttrs[i]->addDecl(FunDecl);

3289 }

3290 }

3291 LateParsedAttrs.clear();

3292

3293

3294 if (Tok.is(tok::semi))

3295 ConsumeExtraSemi(AfterMemberFunctionDefinition);

3296

3298 }

3299 }

3300

3301

3302

3303

3304

3305 while (true) {

3307 bool HasStaticInitializer = false;

3308 if (Tok.isOneOf(tok::equal, tok::l_brace) && PureSpecLoc.isInvalid()) {

3309

3310 if (BitfieldSize.isUsable() && !DeclaratorInfo.hasName()) {

3311

3312 Diag(Tok, diag::err_anon_bitfield_member_init);

3315

3316 if (!TryConsumePureSpecifier( false))

3317

3318 HasStaticInitializer = true;

3324 TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate) {

3325

3326 if (BitfieldSize.get())

3328 ? diag::warn_cxx17_compat_bitfield_member_init

3329 : diag::ext_bitfield_member_init);

3331 } else {

3332 HasStaticInitializer = true;

3333 }

3334 }

3335

3336

3337

3338

3339

3342

3343

3344

3345

3346

3348 if (AL.isCXX11Attribute() || AL.isRegularKeywordAttribute()) {

3349 auto Loc = AL.getRange().getBegin();

3350 (AL.isRegularKeywordAttribute()

3351 ? Diag(Loc, diag::err_keyword_not_allowed) << AL

3352 : Diag(Loc, diag::err_attributes_not_allowed))

3353 << AL.getRange();

3354 }

3355

3357 TemplateParams);

3358 } else {

3360 getCurScope(), AS, DeclaratorInfo, TemplateParams, BitfieldSize.get(),

3361 VS, HasInClassInit);

3362

3364 ThisDecl ? dyn_cast(ThisDecl) : nullptr)

3365

3366

3367 ThisDecl = VT->getTemplatedDecl();

3368

3369 if (ThisDecl)

3371 }

3372

3373

3374

3376 DeclaratorInfo.getDeclSpec().getStorageClassSpec() ==

3379 HasStaticInitializer = true;

3380 }

3381

3383 Diag(PureSpecLoc, diag::err_duplicate_virt_specifier) << "abstract";

3384 }

3385 if (ThisDecl && PureSpecLoc.isValid())

3389

3390

3392

3394 ? diag::warn_cxx98_compat_nonstatic_member_init

3395 : diag::ext_nonstatic_member_init);

3396

3397 if (DeclaratorInfo.isArrayOfUnknownBound()) {

3398

3399

3400

3401

3402

3403 Diag(Tok, diag::err_incomplete_array_member_init);

3405

3406

3407 if (ThisDecl)

3409 } else

3410 ParseCXXNonStaticMemberInitializer(ThisDecl);

3411 } else if (HasStaticInitializer) {

3412

3414 ThisDecl, DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);

3415

3416 if (Init.isInvalid()) {

3417 if (ThisDecl)

3420 } else if (ThisDecl)

3423 } else if (ThisDecl && DeclaratorInfo.isStaticMember())

3424

3426

3427 if (ThisDecl) {

3429

3430 for (unsigned i = 0, ni = CommonLateParsedAttrs.size(); i < ni; ++i)

3431 CommonLateParsedAttrs[i]->addDecl(ThisDecl);

3432

3433 for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i)

3434 LateParsedAttrs[i]->addDecl(ThisDecl);

3435 }

3437 DeclsInGroup.push_back(ThisDecl);

3438

3439 if (DeclaratorInfo.isFunctionDeclarator() &&

3440 DeclaratorInfo.getDeclSpec().getStorageClassSpec() !=

3442 HandleMemberFunctionDeclDelays(DeclaratorInfo, ThisDecl);

3443 }

3444 LateParsedAttrs.clear();

3445

3446 DeclaratorInfo.complete(ThisDecl);

3447

3448

3449

3452 break;

3453

3456

3457

3458

3459 Diag(CommaLoc, diag::err_expected_semi_declaration)

3461 ExpectSemi = false;

3462 break;

3463 }

3464

3465

3466

3467

3468

3469 if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&

3470 DeclaratorInfo.isFirstDeclarator()) {

3471 Diag(CommaLoc, diag::err_multiple_template_declarators)

3472 << TemplateInfo.Kind;

3473 }

3474

3475

3476 DeclaratorInfo.clear();

3478 BitfieldSize = ExprResult(false);

3480 DeclaratorInfo.setCommaLoc(CommaLoc);

3481

3482

3483

3484

3485 DiagnoseAndSkipCXX11Attributes();

3486 MaybeParseGNUAttributes(DeclaratorInfo);

3487 DiagnoseAndSkipCXX11Attributes();

3488

3489 if (ParseCXXMemberDeclaratorBeforeInitializer(

3490 DeclaratorInfo, VS, BitfieldSize, LateParsedAttrs))

3491 break;

3492 }

3493

3494 if (ExpectSemi &&

3495 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {

3496

3498

3500 return nullptr;

3501 }

3502

3504}

3505

3506

3507

3508

3509

3510

3511

3512

3513

3514

3515

3516

3517

3518

3519

3520

3521

3522

3523

3524

3525

3526ExprResult Parser::ParseCXXMemberInitializer(Decl *D, bool IsFunction,

3528 assert(Tok.isOneOf(tok::equal, tok::l_brace) &&

3529 "Data member initializer not starting with '=' or '{'");

3530

3531 bool IsFieldInitialization = isa_and_present(D);

3532

3534 Actions,

3535 IsFieldInitialization

3538 D);

3539

3540

3541

3542

3543 Actions.ExprEvalContexts.back().InImmediateEscalatingFunctionContext =

3544 IsFieldInitialization;

3545

3547 if (Tok.is(tok::kw_delete)) {

3548

3549

3550

3551

3552

3554 if (IsFunction || Next.isOneOf(tok::semi, tok::comma, tok::eof)) {

3555 if (IsFunction)

3556 Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)

3557 << 1 ;

3558 else

3560 SkipDeletedFunctionBody();

3562 }

3563 } else if (Tok.is(tok::kw_default)) {

3564 if (IsFunction)

3565 Diag(Tok, diag::err_default_delete_in_multiple_declaration)

3566 << 0 ;

3567 else

3571 }

3572 }

3573 if (const auto *PD = dyn_cast_or_null(D)) {

3574 Diag(Tok, diag::err_ms_property_initializer) << PD;

3576 }

3577 return ParseInitializer();

3578}

3579

3583

3585 assert(isCXX11FinalKeyword() && "not a class definition");

3587

3588

3589

3591 CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);

3592

3593

3594

3595

3596 if (Tok.isNot(tok::colon) && Tok.isNot(tok::l_brace))

3597 return;

3598 }

3599

3600

3601

3602

3603 if (Tok.is(tok::colon)) {

3604

3606 ParsingClassDefinition ParsingDef(*this, TagDecl, true,

3608 auto OldContext =

3610

3611

3612 ParseBaseClause(nullptr);

3613

3615

3616 if (!Tok.is(tok::l_brace)) {

3618 diag::err_expected_lbrace_after_base_specifiers);

3619 return;

3620 }

3621 }

3622

3623

3624 assert(Tok.is(tok::l_brace));

3626 T.consumeOpen();

3627 T.skipToEnd();

3628

3629

3630 if (Tok.is(tok::kw___attribute)) {

3632 MaybeParseGNUAttributes(Attrs);

3633 }

3634}

3635

3640

3641 switch (Tok.getKind()) {

3642 case tok::kw___if_exists:

3643 case tok::kw___if_not_exists:

3644 ParseMicrosoftIfExistsClassDeclaration(TagType, AccessAttrs, AS);

3645 return nullptr;

3646

3647 case tok:🚛

3648

3649 ConsumeExtraSemi(InsideStruct, TagType);

3650 return nullptr;

3651

3652

3653 case tok::annot_pragma_vis:

3654 HandlePragmaVisibility();

3655 return nullptr;

3656 case tok::annot_pragma_pack:

3657 HandlePragmaPack();

3658 return nullptr;

3659 case tok::annot_pragma_align:

3660 HandlePragmaAlign();

3661 return nullptr;

3662 case tok::annot_pragma_ms_pointers_to_members:

3663 HandlePragmaMSPointersToMembers();

3664 return nullptr;

3665 case tok::annot_pragma_ms_pragma:

3666 HandlePragmaMSPragma();

3667 return nullptr;

3668 case tok::annot_pragma_ms_vtordisp:

3669 HandlePragmaMSVtorDisp();

3670 return nullptr;

3671 case tok::annot_pragma_dump:

3672 HandlePragmaDump();

3673 return nullptr;

3674

3675 case tok::kw_namespace:

3676

3677 DiagnoseUnexpectedNamespace(cast(TagDecl));

3678 return nullptr;

3679

3680 case tok::kw_private:

3681

3682

3684 ParsedTemplateInfo TemplateInfo;

3685 return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo);

3686 }

3687 [[fallthrough]];

3688 case tok::kw_public:

3689 case tok::kw_protected: {

3691 Diag(Tok.getLocation(), diag::ext_hlsl_access_specifiers);

3693 assert(NewAS != AS_none);

3694

3695 AS = NewAS;

3697 unsigned TokLength = Tok.getLength();

3699 AccessAttrs.clear();

3700 MaybeParseGNUAttributes(AccessAttrs);

3701

3705 Diag(EndLoc, diag::err_expected)

3707 } else {

3709 Diag(EndLoc, diag::err_expected)

3711 }

3712

3713

3714

3716 Diag(ASLoc, diag::err_access_specifier_interface) << (AS == AS_protected);

3717 }

3718

3720

3721 AccessAttrs.clear();

3722 }

3723

3724 return nullptr;

3725 }

3726

3727 case tok::annot_attr_openmp:

3728 case tok::annot_pragma_openmp:

3729 return ParseOpenMPDeclarativeDirectiveWithExtDecl(

3730 AS, AccessAttrs, true, TagType, TagDecl);

3731 case tok::annot_pragma_openacc:

3733

3734 default:

3736 Diag(Tok.getLocation(), diag::err_pragma_misplaced_in_decl)

3739 ConsumeAnnotationToken();

3740 return nullptr;

3741 }

3742 ParsedTemplateInfo TemplateInfo;

3743 return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo);

3744 }

3745}

3746

3747

3748

3749

3750

3751

3752

3760 "Invalid TagType!");

3761

3762 llvm::TimeTraceScope TimeScope("ParseClass", [&]() {

3763 if (auto *TD = dyn_cast_or_null(TagDecl))

3764 return TD->getQualifiedNameAsString();

3765 return std::string("");

3766 });

3767

3769 "parsing struct/union/class body");

3770

3771

3772

3773 bool NonNestedClass = true;

3774 if (!ClassStack.empty()) {

3775 for (const Scope *S = getCurScope(); S; S = S->getParent()) {

3776 if (S->isClassScope()) {

3777

3778 NonNestedClass = false;

3779

3780

3781 if (getCurrentClass().IsInterface) {

3782 Diag(RecordLoc, diag::err_invalid_member_in_interface)

3783 << 6

3784 << (isa(TagDecl)

3785 ? cast(TagDecl)->getQualifiedNameAsString()

3786 : "(anonymous)");

3787 }

3788 break;

3789 }

3790

3791 if (S->isFunctionScope())

3792

3793

3794 break;

3795 }

3796 }

3797

3798

3800

3801

3802 ParsingClassDefinition ParsingDef(*this, TagDecl, NonNestedClass,

3804

3807

3810 bool IsFinalSpelledSealed = false;

3811 bool IsAbstract = false;

3812

3813

3815 while (true) {

3818 break;

3819 if (isCXX11FinalKeyword()) {

3820 if (FinalLoc.isValid()) {

3822 Diag(Skipped, diag::err_duplicate_class_virt_specifier)

3824 } else {

3827 IsFinalSpelledSealed = true;

3828 }

3829 } else {

3830 if (AbstractLoc.isValid()) {

3832 Diag(Skipped, diag::err_duplicate_class_virt_specifier)

3834 } else {

3836 IsAbstract = true;

3837 }

3838 }

3840 Diag(FinalLoc, diag::err_override_control_interface)

3844 ? diag::warn_cxx98_compat_override_control_keyword

3845 : diag::ext_override_control_keyword)

3848 Diag(FinalLoc, diag::ext_ms_sealed_keyword);

3850 Diag(AbstractLoc, diag::ext_ms_abstract_keyword);

3852 Diag(FinalLoc, diag::ext_warn_gnu_final);

3853 }

3854 assert((FinalLoc.isValid() || AbstractLoc.isValid()) &&

3855 "not a class definition");

3856

3857

3858

3859

3860

3861 CheckMisplacedCXX11Attribute(Attrs, AttrFixitLoc);

3862

3863

3864

3865

3866

3867

3868

3869

3870 if (!Tok.is(tok::colon) && !Tok.is(tok::l_brace)) {

3873 return;

3874 }

3875 }

3876

3877 if (Tok.is(tok::colon)) {

3878 ParseScope InheritanceScope(this, getCurScope()->getFlags() |

3880

3881 ParseBaseClause(TagDecl);

3882 if (!Tok.is(tok::l_brace)) {

3883 bool SuggestFixIt = false;

3886 switch (Tok.getKind()) {

3887 case tok::kw_private:

3888 case tok::kw_protected:

3889 case tok::kw_public:

3891 break;

3892 case tok::kw_static_assert:

3893 case tok::r_brace:

3894 case tok::kw_using:

3895

3896 case tok::kw_template:

3897 SuggestFixIt = true;

3898 break;

3899 case tok::identifier:

3900 SuggestFixIt = isConstructorDeclarator(true);

3901 break;

3902 default:

3903 SuggestFixIt = isCXXSimpleDeclaration(false);

3904 break;

3905 }

3906 }

3908 Diag(BraceLoc, diag::err_expected_lbrace_after_base_specifiers);

3909 if (SuggestFixIt) {

3911

3912 PP.EnterToken(Tok, true);

3913 Tok.setKind(tok::l_brace);

3914 } else {

3917 return;

3918 }

3919 }

3920 }

3921

3922 assert(Tok.is(tok::l_brace));

3924 T.consumeOpen();

3925

3928 IsFinalSpelledSealed, IsAbstract,

3929 T.getOpenLocation());

3930

3931

3932

3933

3934

3938 else

3941

3943

3944 while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&

3945 Tok.isNot(tok::eof)) {

3946

3947 ParseCXXClassMemberDeclarationWithPragmas(

3949 MaybeDestroyTemplateIds();

3950 }

3951 T.consumeClose();

3952 } else {

3954 }

3955

3956

3958 MaybeParseGNUAttributes(attrs);

3959

3962 T.getOpenLocation(),

3963 T.getCloseLocation(), attrs);

3964

3965

3966

3967

3968

3969

3970 if (TagDecl && NonNestedClass) {

3971

3972

3973

3974

3975

3976 SourceLocation SavedPrevTokLocation = PrevTokLocation;

3977 ParseLexedPragmas(getCurrentClass());

3978 ParseLexedAttributes(getCurrentClass());

3979 ParseLexedMethodDeclarations(getCurrentClass());

3980

3981

3983

3984 ParseLexedMemberInitializers(getCurrentClass());

3985 ParseLexedMethodDefs(getCurrentClass());

3986 PrevTokLocation = SavedPrevTokLocation;

3987

3988

3989

3991 }

3992

3995

3996

3997 ParsingDef.Pop();

3998 ClassScope.Exit();

3999}

4000

4001void Parser::DiagnoseUnexpectedNamespace(NamedDecl *D) {

4002 assert(Tok.is(tok::kw_namespace));

4003

4004

4005

4006 Diag(D->getLocation(), diag::err_missing_end_of_definition) << D;

4007 Diag(Tok.getLocation(), diag::note_missing_end_of_definition_before) << D;

4008

4009

4010 PP.EnterToken(Tok, true);

4011

4015 PP.EnterToken(Tok, true);

4016

4017 Tok.setKind(tok::r_brace);

4018}

4019

4020

4021

4022

4023

4024

4025

4026

4027

4028

4029

4030

4031

4032

4033

4034

4035

4036

4037

4038

4039

4040

4041void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) {

4042 assert(Tok.is(tok::colon) &&

4043 "Constructor initializer always starts with ':'");

4044

4045

4046

4049

4051 bool AnyErrors = false;

4052

4053 do {

4054 if (Tok.is(tok::code_completion)) {

4055 cutOffParsing();

4057 ConstructorDecl, MemInitializers);

4058 return;

4059 }

4060

4061 MemInitResult MemInit = ParseMemInitializer(ConstructorDecl);

4063 MemInitializers.push_back(MemInit.get());

4064 else

4065 AnyErrors = true;

4066

4067 if (Tok.is(tok::comma))

4069 else if (Tok.is(tok::l_brace))

4070 break;

4071

4072

4073 else if (!MemInit.isInvalid() &&

4074 Tok.isOneOf(tok::identifier, tok::coloncolon)) {

4076 Diag(Loc, diag::err_ctor_init_missing_comma)

4078 } else {

4079

4082 << tok::l_brace << tok::comma;

4084 break;

4085 }

4086 } while (true);

4087

4089 AnyErrors);

4090}

4091

4092

4093

4094

4095

4096

4097

4098

4099

4100

4101

4102

4103

4104MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) {

4105

4107 if (ParseOptionalCXXScopeSpecifier(SS, nullptr,

4108 false,

4109 false))

4110 return true;

4111

4112

4115

4117

4119

4120 if (Tok.is(tok::identifier)) {

4121

4122

4125 } else if (Tok.is(tok::annot_decltype)) {

4126

4127

4128

4129

4130 ParseDecltypeSpecifier(DS);

4131 } else if (Tok.is(tok::annot_pack_indexing_type)) {

4132

4133

4134 ParsePackIndexingType(DS);

4135 } else {

4137 ? takeTemplateIdAnnotation(Tok)

4138 : nullptr;

4139 if (TemplateId && TemplateId->mightBeType()) {

4141 true);

4142 assert(Tok.is(tok::annot_typename) && "template-id -> type failed");

4144 ConsumeAnnotationToken();

4145 } else {

4146 Diag(Tok, diag::err_expected_member_or_base_name);

4147 return true;

4148 }

4149 }

4150

4151

4153 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);

4154

4155

4156 ExprResult InitList = ParseBraceInitializer();

4158 return true;

4159

4162

4164 return true;

4166 TemplateTypeTy.get(), DS, IdLoc,

4167 InitList.get(), EllipsisLoc);

4168 } else if (Tok.is(tok::l_paren)) {

4170 T.consumeOpen();

4171

4172

4173 ExprVector ArgExprs;

4174 auto RunSignatureHelp = [&] {

4179 ConstructorDecl, SS, TemplateTypeTy.get(), ArgExprs, II,

4180 T.getOpenLocation(), false);

4181 CalledSignatureHelp = true;

4182 return PreferredType;

4183 };

4184 if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, [&] {

4185 PreferredType.enterFunctionArgument(Tok.getLocation(),

4186 RunSignatureHelp);

4187 })) {

4189 RunSignatureHelp();

4191 return true;

4192 }

4193

4194 T.consumeClose();

4195

4198

4200 return true;

4202 ConstructorDecl, getCurScope(), SS, II, TemplateTypeTy.get(), DS, IdLoc,

4203 T.getOpenLocation(), ArgExprs, T.getCloseLocation(), EllipsisLoc);

4204 }

4205

4207 return true;

4208

4210 return Diag(Tok, diag::err_expected_either) << tok::l_paren << tok::l_brace;

4211 else

4212 return Diag(Tok, diag::err_expected) << tok::l_paren;

4213}

4214

4215

4216

4217

4218

4219

4220

4221

4222

4223

4225 bool Delayed, SourceRange &SpecificationRange,

4230 ExceptionSpecTokens = nullptr;

4231

4232

4233 if (Delayed) {

4234 if (Tok.isNot(tok::kw_throw) && Tok.isNot(tok::kw_noexcept))

4236

4237

4238 bool IsNoexcept = Tok.is(tok::kw_noexcept);

4239 Token StartTok = Tok;

4241

4242

4243 if (!Tok.is(tok::l_paren)) {

4244

4245 if (IsNoexcept) {

4246 Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);

4247 NoexceptExpr = nullptr;

4249 }

4250

4251 Diag(Tok, diag::err_expected_lparen_after) << "throw";

4253 }

4254

4255

4257 ExceptionSpecTokens->push_back(StartTok);

4258 ExceptionSpecTokens->push_back(Tok);

4259 SpecificationRange.setEnd(ConsumeParen());

4260

4261 ConsumeAndStoreUntil(tok::r_paren, *ExceptionSpecTokens,

4262 true,

4263 true);

4264 SpecificationRange.setEnd(ExceptionSpecTokens->back().getLocation());

4265

4267 }

4268

4269

4270 if (Tok.is(tok::kw_throw)) {

4271 Result = ParseDynamicExceptionSpecification(

4272 SpecificationRange, DynamicExceptions, DynamicExceptionRanges);

4273 assert(DynamicExceptions.size() == DynamicExceptionRanges.size() &&

4274 "Produced different number of exception types and ranges.");

4275 }

4276

4277

4278 if (Tok.isNot(tok::kw_noexcept))

4280

4281 Diag(Tok, diag::warn_cxx98_compat_noexcept_decl);

4282

4283

4284

4287

4289 if (Tok.is(tok::l_paren)) {

4290

4292 T.consumeOpen();

4293

4297

4298 T.consumeClose();

4299 if (!NoexceptExpr.isInvalid()) {

4300 NoexceptExpr =

4302 NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation());

4303 } else {

4305 }

4306 } else {

4307

4309 NoexceptRange = SourceRange(KeywordLoc, KeywordLoc);

4310 }

4311

4313 SpecificationRange = NoexceptRange;

4314 Result = NoexceptType;

4315

4316

4317

4318 if (Tok.is(tok::kw_throw)) {

4319 Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);

4320 ParseDynamicExceptionSpecification(NoexceptRange, DynamicExceptions,

4321 DynamicExceptionRanges);

4322 }

4323 } else {

4324 Diag(Tok.getLocation(), diag::err_dynamic_and_noexcept_specification);

4325 }

4326

4328}

4329

4331 bool IsNoexcept) {

4332 if (P.getLangOpts().CPlusPlus11) {

4333 const char *Replacement = IsNoexcept ? "noexcept" : "noexcept(false)";

4334 P.Diag(Range.getBegin(), P.getLangOpts().CPlusPlus17 && !IsNoexcept

4335 ? diag::ext_dynamic_exception_spec

4336 : diag::warn_exception_spec_deprecated)

4338 P.Diag(Range.getBegin(), diag::note_exception_spec_deprecated)

4340 }

4341}

4342

4343

4344

4345

4346

4347

4348

4349

4350

4351

4352

4353

4357 assert(Tok.is(tok::kw_throw) && "expected throw");

4358

4361 if (T.consumeOpen()) {

4362 Diag(Tok, diag::err_expected_lparen_after) << "throw";

4363 SpecificationRange.setEnd(SpecificationRange.getBegin());

4365 }

4366

4367

4368

4369 if (Tok.is(tok::ellipsis)) {

4372 Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);

4373 T.consumeClose();

4374 SpecificationRange.setEnd(T.getCloseLocation());

4377 }

4378

4379

4381 while (Tok.isNot(tok::r_paren)) {

4383

4384 if (Tok.is(tok::ellipsis)) {

4385

4386

4387

4390 if (!Res.isInvalid())

4392 }

4393

4394 if (!Res.isInvalid()) {

4395 Exceptions.push_back(Res.get());

4396 Ranges.push_back(Range);

4397 }

4398

4400 break;

4401 }

4402

4403 T.consumeClose();

4404 SpecificationRange.setEnd(T.getCloseLocation());

4406 Exceptions.empty());

4408}

4409

4410

4411

4413 bool MayBeFollowedByDirectInit) {

4414 assert(Tok.is(tok::arrow) && "expected arrow");

4415

4417

4421}

4422

4423

4424void Parser::ParseTrailingRequiresClause(Declarator &D) {

4425 assert(Tok.is(tok::kw_requires) && "expected requires");

4426

4428

4429

4430

4431

4432

4433

4434

4435

4436

4437

4438

4439

4440

4441

4443 DeclaratorScopeObj DeclScopeObj(*this, SS);

4445 DeclScopeObj.EnterDeclaratorScope();

4446

4451

4453

4454 std::optionalSema::CXXThisScopeRAII ThisScope;

4455 InitCXXThisScopeForDeclaratorIfRelevant(D, D.getDeclSpec(), ThisScope);

4456

4457 TrailingRequiresClause =

4459

4460 TrailingRequiresClause =

4462

4463 if (D.isDeclarationOfFunction()) {

4464 Diag(RequiresKWLoc,

4465 diag::err_requires_clause_on_declarator_not_declaring_a_function);

4466 return;

4467 }

4468

4469 if (TrailingRequiresClause.isInvalid())

4470 SkipUntil({tok::l_brace, tok::arrow, tok::kw_try, tok::comma, tok::colon},

4472 else

4473 D.setTrailingRequiresClause(TrailingRequiresClause.get());

4474

4475

4476 if (D.isFunctionDeclarator() && Tok.is(tok::arrow) &&

4477 D.getDeclSpec().getTypeSpecType() == TST_auto) {

4481 ParseTrailingReturnType(Range, false);

4482

4483 if (!TrailingReturnType.isInvalid()) {

4484 Diag(ArrowLoc,

4485 diag::err_requires_clause_must_appear_after_trailing_return)

4487 auto &FunctionChunk = D.getFunctionTypeInfo();

4488 FunctionChunk.HasTrailingReturnType = TrailingReturnType.isUsable();

4489 FunctionChunk.TrailingReturnType = TrailingReturnType.get();

4490 FunctionChunk.TrailingReturnTypeLoc = Range.getBegin();

4491 } else

4492 SkipUntil({tok::equal, tok::l_brace, tok::arrow, tok::kw_try, tok::comma},

4494 }

4495}

4496

4497

4498

4499

4501 bool NonNestedClass,

4502 bool IsInterface) {

4503 assert((NonNestedClass || !ClassStack.empty()) &&

4504 "Nested class without outer class");

4505 ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass, IsInterface));

4507}

4508

4509

4510

4511void Parser::DeallocateParsedClasses(Parser::ParsingClass *Class) {

4512 for (unsigned I = 0, N = Class->LateParsedDeclarations.size(); I != N; ++I)

4513 delete Class->LateParsedDeclarations[I];

4515}

4516

4517

4518

4519

4520

4521

4522

4524 assert(!ClassStack.empty() && "Mismatched push/pop for class parsing");

4525

4527

4528 ParsingClass *Victim = ClassStack.top();

4529 ClassStack.pop();

4530 if (Victim->TopLevelClass) {

4531

4532

4533 DeallocateParsedClasses(Victim);

4534 return;

4535 }

4536 assert(!ClassStack.empty() && "Missing top-level class?");

4537

4538 if (Victim->LateParsedDeclarations.empty()) {

4539

4540

4541

4542

4543 DeallocateParsedClasses(Victim);

4544 return;

4545 }

4546

4547

4548

4549

4551 "Nested class outside of class scope?");

4552 ClassStack.top()->LateParsedDeclarations.push_back(

4553 new LateParsedClass(this, Victim));

4554}

4555

4556

4557

4558

4559

4560

4561

4562

4563

4564

4565IdentifierInfo *Parser::TryParseCXX11AttributeIdentifier(

4568 switch (Tok.getKind()) {

4569 default:

4570

4574 return II;

4575 }

4576 }

4577 return nullptr;

4578

4579 case tok::code_completion:

4580 cutOffParsing();

4583 Completion, Scope);

4584 return nullptr;

4585

4586 case tok::numeric_constant: {

4587

4588

4589

4594 StringRef Spelling = PP.getSpelling(ExpansionLoc, ExpansionBuf);

4595 if (Spelling == "__clang__") {

4597 ExpansionLoc,

4599 Diag(Tok, diag::warn_wrong_clang_attr_namespace)

4603 }

4604 }

4605 return nullptr;

4606 }

4607

4608 case tok::ampamp:

4609 case tok::pipe:

4610 case tok::pipepipe:

4611 case tok::caret:

4612 case tok::tilde:

4613 case tok::amp:

4614 case tok::ampequal:

4615 case tok::pipeequal:

4616 case tok::caretequal:

4617 case tok::exclaim:

4618 case tok::exclaimequal:

4619

4620

4624 StringRef Spelling = PP.getSpelling(SpellingLoc, SpellingBuf);

4625 if (isLetter(Spelling[0])) {

4628 }

4629 return nullptr;

4630 }

4631}

4632

4633void Parser::ParseOpenMPAttributeArgs(const IdentifierInfo *AttrName,

4635

4636

4638 if (T.consumeOpen()) {

4639 Diag(Tok, diag::err_expected) << tok::l_paren;

4640 return;

4641 }

4642

4643 if (AttrName->isStr("directive")) {

4644

4645

4646

4647 Token OMPBeginTok;

4649 OMPBeginTok.setKind(tok::annot_attr_openmp);

4651 OpenMPTokens.push_back(OMPBeginTok);

4652

4653 ConsumeAndStoreUntil(tok::r_paren, OpenMPTokens, false,

4654 false);

4655 Token OMPEndTok;

4657 OMPEndTok.setKind(tok::annot_pragma_openmp_end);

4659 OpenMPTokens.push_back(OMPEndTok);

4660 } else {

4661 assert(AttrName->isStr("sequence") &&

4662 "Expected either 'directive' or 'sequence'");

4663

4664

4665

4666 do {

4667

4668

4669

4671 const IdentifierInfo *Ident = TryParseCXX11AttributeIdentifier(IdentLoc);

4672

4673

4674

4675 if (Ident && Ident->isStr("omp") && !ExpectAndConsume(tok::coloncolon))

4676 Ident = TryParseCXX11AttributeIdentifier(IdentLoc);

4677

4678

4679

4680 if (!Ident || (!Ident->isStr("directive") && !Ident->isStr("sequence"))) {

4681 Diag(Tok.getLocation(), diag::err_expected_sequence_or_directive);

4683 continue;

4684 }

4685

4686

4687 ParseOpenMPAttributeArgs(Ident, OpenMPTokens);

4688

4689

4690

4692 }

4693

4694 T.consumeClose();

4695}

4696

4699 switch (

4701 case ParsedAttr::AT_CarriesDependency:

4702 case ParsedAttr::AT_Deprecated:

4703 case ParsedAttr::AT_FallThrough:

4704 case ParsedAttr::AT_CXX11NoReturn:

4705 case ParsedAttr::AT_NoUniqueAddress:

4706 case ParsedAttr::AT_Likely:

4707 case ParsedAttr::AT_Unlikely:

4708 return true;

4709 case ParsedAttr::AT_WarnUnusedResult:

4710 return !ScopeName && AttrName->getName() == "nodiscard";

4711 case ParsedAttr::AT_Unused:

4712 return !ScopeName && AttrName->getName() == "maybe_unused";

4713 default:

4714 return false;

4715 }

4716}

4717

4718

4719bool Parser::ParseCXXAssumeAttributeArg(ParsedAttributes &Attrs,

4724 assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list");

4726 T.consumeOpen();

4727

4728

4731

4732 TentativeParsingAction TPA(*this);

4735 if (Res.isInvalid()) {

4736 TPA.Commit();

4738 if (Tok.is(tok::r_paren))

4739 T.consumeClose();

4740 return true;

4741 }

4742

4743 if (!Tok.isOneOf(tok::r_paren, tok::r_square)) {

4744

4745

4746 TPA.Revert();

4748 if (!Res.isInvalid()) {

4749 auto *E = Res.get();

4750 Diag(E->getExprLoc(), diag::err_assume_attr_expects_cond_expr)

4753 ")")

4755 }

4756

4757 T.consumeClose();

4758 return true;

4759 }

4760

4761 TPA.Commit();

4762 ArgsUnion Assumption = Res.get();

4764 T.consumeClose();

4765 Attrs.addNew(AttrName, SourceRange(AttrNameLoc, RParen), nullptr,

4767

4768 if (EndLoc)

4769 *EndLoc = RParen;

4770

4771 return false;

4772}

4773

4774

4775

4776

4777

4778

4779

4780

4781

4782

4783

4784

4785

4786

4787

4788bool Parser::ParseCXX11AttributeArgs(

4792 assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list");

4796 LO.CPlusPlus ? ParsedAttr::Form::CXX11() : ParsedAttr::Form::C23();

4797

4798

4802 Form = ParsedAttr::Form::Microsoft();

4803 }

4804

4805

4806

4811

4812 ConsumeParen();

4814 return false;

4815 }

4816

4817 if (ScopeName && (ScopeName->isStr("gnu") || ScopeName->isStr("__gnu__"))) {

4818

4819

4820 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,

4821 ScopeLoc, Form, nullptr);

4822 return true;

4823 }

4824

4825

4826 if (ScopeName && ScopeName->isStr("omp") &&

4827 (AttrName->isStr("directive") || AttrName->isStr("sequence"))) {

4829 ? diag::warn_omp51_compat_attributes

4830 : diag::ext_omp_attributes);

4831

4832 ParseOpenMPAttributeArgs(AttrName, OpenMPTokens);

4833

4834

4835

4836 return true;

4837 }

4838

4839 unsigned NumArgs;

4840

4841 if (ScopeName && (ScopeName->isStr("clang") || ScopeName->isStr("_Clang")))

4842 NumArgs = ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc,

4843 ScopeName, ScopeLoc, Form);

4844

4845 else if (!ScopeName && AttrName->isStr("assume")) {

4846 if (ParseCXXAssumeAttributeArg(Attrs, AttrName, AttrNameLoc, EndLoc, Form))

4847 return true;

4848 NumArgs = 1;

4849 } else

4850 NumArgs = ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,

4851 ScopeName, ScopeLoc, Form);

4852

4853 if (!Attrs.empty() &&

4856

4857

4859 Diag(LParenLoc, diag::warn_unknown_attribute_ignored) << AttrName;

4860 Attr.setInvalid(true);

4861 return true;

4862 }

4863

4864

4865

4866

4867

4868 if (Attr.getMaxArgs() && !NumArgs) {

4869

4870

4871 Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;

4872 Attr.setInvalid(true);

4873 } else if (Attr.getMaxArgs()) {

4874

4875

4876

4877 Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)

4878 << AttrName

4880 Attr.setInvalid(true);

4881 }

4882 }

4883 return true;

4884}

4885

4886

4887

4888

4889

4890

4891

4892

4893

4894

4895

4896

4897

4898

4899

4900

4901

4902

4903

4904

4905

4906

4907

4908

4909

4910void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,

4913 if (Tok.is(tok::kw_alignas)) {

4914

4915

4916

4917

4919 Diag(Tok.getLocation(), diag::warn_cxx98_compat_alignas);

4920 ParseAlignmentSpecifier(Attrs, EndLoc);

4921 return;

4922 }

4923

4930 if (TakesArgs) {

4931 if (!Tok.is(tok::l_paren))

4932 Diag(Tok.getLocation(), diag::err_expected_lparen_after) << AttrName;

4933 else

4934 ParseAttributeArgsCommon(AttrName, Loc, Attrs, EndLoc,

4935 nullptr,

4936 Loc, Form);

4937 } else

4938 Attrs.addNew(AttrName, Loc, nullptr, Loc, nullptr, 0, Form);

4939 return;

4940 }

4941

4942 assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square) &&

4943 "Not a double square bracket attribute list");

4944

4948 : diag::warn_ext_cxx11_attributes);

4949 } else {

4950 Diag(OpenLoc, getLangOpts().C23 ? diag::warn_pre_c23_compat_attributes

4951 : diag::warn_ext_c23_attributes);

4952 }

4953

4954 ConsumeBracket();

4955 checkCompoundToken(OpenLoc, tok::l_square, CompoundToken::AttrBegin);

4956 ConsumeBracket();

4957

4960 if (Tok.is(tok::kw_using)) {

4962 ? diag::warn_cxx14_compat_using_attribute_ns

4963 : diag::ext_using_attribute_ns);

4965

4966 CommonScopeName = TryParseCXX11AttributeIdentifier(

4968 if (!CommonScopeName) {

4969 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;

4971 }

4973 Diag(Tok.getLocation(), diag::err_expected) << tok::colon;

4974 }

4975

4976 bool AttrParsed = false;

4977 while (!Tok.isOneOf(tok::r_square, tok::semi, tok::eof)) {

4978 if (AttrParsed) {

4979

4980

4981 if (ExpectAndConsume(tok::comma)) {

4983 continue;

4984 }

4985 AttrParsed = false;

4986 }

4987

4988

4990 ;

4991

4993 IdentifierInfo *ScopeName = nullptr, *AttrName = nullptr;

4994

4995 AttrName = TryParseCXX11AttributeIdentifier(

4997 CommonScopeName);

4998 if (!AttrName)

4999

5000 break;

5001

5002

5004 ScopeName = AttrName;

5005 ScopeLoc = AttrLoc;

5006

5007 AttrName = TryParseCXX11AttributeIdentifier(

5009 ScopeName);

5010 if (!AttrName) {

5011 Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;

5013 continue;

5014 }

5015 }

5016

5017 if (CommonScopeName) {

5018 if (ScopeName) {

5019 Diag(ScopeLoc, diag::err_using_attribute_ns_conflict)

5021 } else {

5022 ScopeName = CommonScopeName;

5023 ScopeLoc = CommonScopeLoc;

5024 }

5025 }

5026

5027

5028 if (Tok.is(tok::l_paren))

5029 AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, Attrs, EndLoc,

5030 ScopeName, ScopeLoc, OpenMPTokens);

5031

5032 if (!AttrParsed) {

5034 AttrName,

5036 ScopeName, ScopeLoc, nullptr, 0,

5038 : ParsedAttr::Form::C23());

5039 AttrParsed = true;

5040 }

5041

5043 Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis) << AttrName;

5044 }

5045

5046

5047

5048 if (Tok.is(tok::semi)) {

5050 return;

5051 }

5052

5054 if (ExpectAndConsume(tok::r_square))

5056 else if (Tok.is(tok::r_square))

5057 checkCompoundToken(CloseLoc, tok::r_square, CompoundToken::AttrEnd);

5058 if (EndLoc)

5060 if (ExpectAndConsume(tok::r_square))

5062}

5063

5064

5065

5066

5067

5071

5072 do {

5073 ParseCXX11AttributeSpecifier(Attrs, &EndLoc);

5074 } while (isAllowedCXX11AttributeSpecifier());

5075

5077}

5078

5079void Parser::DiagnoseAndSkipCXX11Attributes() {

5080 auto Keyword =

5082

5085

5088 (Keyword ? Diag(StartLoc, diag::err_keyword_not_allowed) << Keyword

5089 : Diag(StartLoc, diag::err_attributes_not_allowed))

5091 }

5092}

5093

5096

5097 if (!isCXX11AttributeSpecifier())

5098 return EndLoc;

5099

5100 do {

5101 if (Tok.is(tok::l_square)) {

5103 T.consumeOpen();

5104 T.skipToEnd();

5105 EndLoc = T.getCloseLocation();

5110 } else {

5112 "not an attribute specifier");

5115 if (T.consumeOpen())

5116 T.skipToEnd();

5117 EndLoc = T.getCloseLocation();

5118 }

5119 } while (isCXX11AttributeSpecifier());

5120

5121 return EndLoc;

5122}

5123

5124

5125void Parser::ParseMicrosoftUuidAttributeArgs(ParsedAttributes &Attrs) {

5126 assert(Tok.is(tok::identifier) && "Not a Microsoft attribute list");

5128 assert(UuidIdent->getName() == "uuid" && "Not a Microsoft attribute list");

5129

5132

5133

5135 if (T.consumeOpen()) {

5136 Diag(Tok, diag::err_expected) << tok::l_paren;

5137 return;

5138 }

5139

5141 if (isTokenStringLiteral()) {

5142

5145 return;

5146 ArgExprs.push_back(StringResult.get());

5147 } else {

5148

5149

5150

5151

5152 SmallString<42> StrBuffer;

5153 StrBuffer += "\"";

5154

5155

5156

5157

5158

5159

5160

5161

5163 while (Tok.isNot(tok::r_paren)) {

5165 Diag(Tok, diag::err_attribute_uuid_malformed_guid);

5167 return;

5168 }

5170 SpellingBuffer.resize(Tok.getLength() + 1);

5172 StringRef TokSpelling = PP.getSpelling(Tok, SpellingBuffer, &Invalid);

5173 if (Invalid) {

5175 return;

5176 }

5177 StrBuffer += TokSpelling;

5179 }

5180 StrBuffer += "\"";

5181

5183 Diag(Tok, diag::err_attribute_uuid_malformed_guid);

5184 ConsumeParen();

5185 return;

5186 }

5187

5188

5189

5190

5193 Toks[0].setKind(tok::string_literal);

5196 Toks[0].setLength(StrBuffer.size());

5199 ArgExprs.push_back(UuidString);

5200 }

5201

5202 if (T.consumeClose()) {

5203 Attrs.addNew(UuidIdent, SourceRange(UuidLoc, T.getCloseLocation()), nullptr,

5205 ParsedAttr::Form::Microsoft());

5206 }

5207}

5208

5209

5210

5211

5212

5213

5214

5215

5216

5217void Parser::ParseMicrosoftAttributes(ParsedAttributes &Attrs) {

5218 assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");

5219

5222 do {

5223

5225 T.consumeOpen();

5226

5227

5228 while (true) {

5229 SkipUntil(tok::r_square, tok::identifier,

5231 if (Tok.is(tok::code_completion)) {

5232 cutOffParsing();

5236 nullptr);

5237 break;

5238 }

5239 if (Tok.isNot(tok::identifier))

5240 break;

5242 ParseMicrosoftUuidAttributeArgs(Attrs);

5243 else {

5249

5250

5252 bool AttrParsed = false;

5253 if (Tok.is(tok::l_paren)) {

5255 AttrParsed =

5256 ParseCXX11AttributeArgs(II, NameLoc, Attrs, &EndLoc, nullptr,

5258 ReplayOpenMPAttributeTokens(OpenMPTokens);

5259 }

5260 if (!AttrParsed) {

5262 ParsedAttr::Form::Microsoft());

5263 }

5264 }

5265 }

5266 }

5267

5268 T.consumeClose();

5269 EndLoc = T.getCloseLocation();

5270 } while (Tok.is(tok::l_square));

5271

5273}

5274

5275void Parser::ParseMicrosoftIfExistsClassDeclaration(

5278 IfExistsCondition Result;

5279 if (ParseMicrosoftIfExistsCondition(Result))

5280 return;

5281

5283 if (Braces.consumeOpen()) {

5284 Diag(Tok, diag::err_expected) << tok::l_brace;

5285 return;

5286 }

5287

5288 switch (Result.Behavior) {

5289 case IEB_Parse:

5290

5291 break;

5292

5293 case IEB_Dependent:

5294 Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)

5295 << Result.IsIfExists;

5296

5297 [[fallthrough]];

5298

5299 case IEB_Skip:

5301 return;

5302 }

5303

5304 while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {

5305

5306 if (Tok.isOneOf(tok::kw___if_exists, tok::kw___if_not_exists)) {

5307 ParseMicrosoftIfExistsClassDeclaration(TagType, AccessAttrs, CurAS);

5308 continue;

5309 }

5310

5311

5312 if (Tok.is(tok::semi)) {

5313 ConsumeExtraSemi(InsideStruct, TagType);

5314 continue;

5315 }

5316

5319

5320 CurAS = AS;

5323 if (Tok.is(tok::colon))

5326 else

5327 Diag(Tok, diag::err_expected) << tok::colon;

5329 continue;

5330 }

5331

5332 ParsedTemplateInfo TemplateInfo;

5333

5334 ParseCXXClassMemberDeclaration(CurAS, AccessAttrs, TemplateInfo);

5335 }

5336

5337 Braces.consumeClose();

5338}

Defines the clang::ASTContext interface.

Defines the C++ template declaration subclasses.

llvm::MachO::RecordLoc RecordLoc

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)

This file declares facilities that support code completion.

Defines the clang::TokenKind enum and support functions.

#define TRANSFORM_TYPE_TRAIT_DEF(Enum, _)

const NestedNameSpecifier * Specifier

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

const clang::PrintingPolicy & getPrintingPolicy() const

Attr - This represents one attribute.

Combines information about the source-code form of an attribute, including its syntax and spelling.

@ 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.

bool isValid() const

A scope specifier is present, and it refers to a real scope.

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 SetPackIndexingExpr(SourceLocation EllipsisLoc, Expr *Pack)

void SetRangeEnd(SourceLocation Loc)

static const TST TST_interface

unsigned getTypeQualifiers() const

getTypeQualifiers - Return a set of TQs.

void SetRangeStart(SourceLocation Loc)

bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)

static const TST TST_union

static const TST TST_typename_pack_indexing

SourceLocation getFriendSpecLoc() const

SourceLocation getModulePrivateSpecLoc() const

bool isFriendSpecifiedFirst() const

Expr * getRepAsExpr() const

static const TST TST_decltype

static const TST TST_class

bool hasTagDefinition() const

static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)

Turn a type-specifier-type into a string like "_Bool" or "union".

Decl * getRepAsDecl() const

CXXScopeSpec & getTypeSpecScope()

static const TST TST_decltype_auto

void setExternInLinkageSpec(bool Value)

static const TST TST_error

void forEachQualifier(llvm::function_ref< void(TQ, StringRef, SourceLocation)> Handle)

This method calls the passed in handler on each qual being set.

FriendSpecified isFriendSpecified() const

void takeAttributesFrom(ParsedAttributes &attrs)

static const TST TST_struct

Decl - This represents one declaration (or definition), e.g.

SourceLocation getEndLoc() const LLVM_READONLY

void setInvalidDecl(bool Invalid=true)

setInvalidDecl - Indicates the Decl had a semantic error.

bool isInvalidDecl() const

SourceLocation getLocation() const

SourceLocation getBeginLoc() const LLVM_READONLY

virtual SourceRange getSourceRange() const LLVM_READONLY

Source range that this declaration covers.

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 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 SetIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)

Set the name of this declarator to be the given identifier.

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 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.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

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.

static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)

Returns a new integer literal with value 'V' and type 'type'.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

This represents a decl that may have a name.

Wrapper for void* pointer.

static OpaquePtr make(PtrTy P)

A single parameter index whose accessors require each use to make explicit the parameter index encodi...

RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing,...

ParsedAttr - Represents a syntactic attribute.

static const ParsedAttributesView & none()

void addAll(iterator B, iterator E)

ParsedAttributes - A collection of parsed attributes.

ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form, SourceLocation ellipsisLoc=SourceLocation())

Add attribute with expression arguments.

void takeAllFrom(ParsedAttributes &Other)

Parser - This implements a parser for the C family of languages.

TypeResult ParseTypeName(SourceRange *Range=nullptr, DeclaratorContext Context=DeclaratorContext::TypeName, AccessSpecifier AS=AS_none, Decl **OwnedType=nullptr, ParsedAttributes *Attrs=nullptr)

ParseTypeName type-name: [C99 6.7.6] specifier-qualifier-list abstract-declarator[opt].

DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)

SourceLocation ConsumeToken()

ConsumeToken - Consume the current 'peek token' and lex the next one.

DeclGroupPtrTy ParseOpenACCDirectiveDecl()

Placeholder for now, should just ignore the directives after emitting a diagnostic.

static TypeResult getTypeAnnotation(const Token &Tok)

getTypeAnnotation - Read a parsed type out of an annotation token.

ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause)

Parse a constraint-logical-or-expression.

bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)

Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.

SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)

ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.

ExprResult ParseConstantExpression()

ExprResult ParseConditionalExpression()

bool TryConsumeToken(tok::TokenKind Expected)

Scope * getCurScope() const

const TargetInfo & getTargetInfo() const

OpaquePtr< TemplateName > TemplateTy

bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))

SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...

void SkipMalformedDecl()

SkipMalformedDecl - Read tokens until we get to some likely good stopping point for skipping past a s...

friend class ObjCDeclContextSwitch

ExprResult ParseConstantExpressionInExprEvalContext(TypeCastState isTypeCast=NotTypeCast)

const LangOptions & getLangOpts() const

ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)

Simple precedence-based parser for binary/ternary operators.

@ StopBeforeMatch

Stop skipping at specified token, but don't skip the token itself.

@ StopAtCodeCompletion

Stop at code completion.

@ StopAtSemi

Stop skipping at semicolon.

ExprResult ParseUnevaluatedStringLiteralExpression()

const Token & NextToken()

NextToken - This peeks ahead one token and returns it without consuming it.

SmallVector< TemplateParameterList *, 4 > TemplateParameterLists

bool TryAnnotateCXXScopeToken(bool EnteringContext=false)

TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only annotates C++ scope specifiers and ...

RAII object used to inform the actions that we're currently parsing a declaration.

A class for parsing a DeclSpec.

A class for parsing a declarator.

bool isIncrementalProcessingEnabled() const

Returns true if incremental processing is enabled.

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.

unsigned getFlags() const

getFlags - Return the flags for this scope.

@ FunctionPrototypeScope

This is a scope that corresponds to the parameters within a function prototype.

@ TypeAliasScope

This is a scope of type alias declaration.

@ 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.

void CodeCompleteAttribute(AttributeCommonInfo::Syntax Syntax, AttributeCompletion Completion=AttributeCompletion::Attribute, const IdentifierInfo *Scope=nullptr)

QualType ProduceCtorInitMemberSignatureHelp(Decl *ConstructorDecl, CXXScopeSpec SS, ParsedType TemplateTypeTy, ArrayRef< Expr * > ArgExprs, IdentifierInfo *II, SourceLocation OpenParLoc, bool Braced)

void CodeCompleteNamespaceAliasDecl(Scope *S)

void CodeCompleteUsing(Scope *S)

void CodeCompleteUsingDirective(Scope *S)

@ PCC_TopLevelOrExpression

Code completion occurs at top-level in a REPL session.

@ PCC_Namespace

Code completion occurs at top-level or namespace context.

void CodeCompleteAfterFunctionEquals(Declarator &D)

void CodeCompleteConstructorInitializer(Decl *Constructor, ArrayRef< CXXCtorInitializer * > Initializers)

void CodeCompleteOrdinaryName(Scope *S, ParserCompletionContext CompletionContext)

void CodeCompleteNamespaceDecl(Scope *S)

void CodeCompleteTag(Scope *S, unsigned TagSpec)

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 ActOnDefinedDeclarationSpecifier(Decl *D)

Called once it is known whether a tag declaration is an anonymous union or struct.

Decl * ActOnUsingEnumDeclaration(Scope *CurScope, AccessSpecifier AS, SourceLocation UsingLoc, SourceLocation EnumLoc, SourceRange TyLoc, const IdentifierInfo &II, ParsedType Ty, CXXScopeSpec *SS=nullptr)

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.

TypeResult ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, const CXXScopeSpec &SS, const IdentifierInfo *Name, SourceLocation TagLoc, SourceLocation NameLoc)

Decl * ActOnNamespaceAliasDef(Scope *CurScope, SourceLocation NamespaceLoc, SourceLocation AliasLoc, IdentifierInfo *Alias, CXXScopeSpec &SS, SourceLocation IdentLoc, IdentifierInfo *Ident)

DeclResult ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, unsigned TagSpec, SourceLocation TagLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, SourceLocation EllipsisLoc, const ParsedAttributesView &Attr, MultiTemplateParamsArg TempParamLists)

Handle a friend tag declaration where the scope specifier was templated.

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.

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...

NamedDecl * ActOnFriendFunctionDecl(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParams)

DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)

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()

ExprResult ActOnUnevaluatedStringLiteral(ArrayRef< Token > StringToks)

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.

SemaCodeCompletion & CodeCompletion()

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...

bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS)

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...

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)

Helper for delayed processing TransparentUnion or BPFPreserveAccessIndexAttr attribute.

ExprResult ActOnFinishTrailingRequiresClause(ExprResult ConstraintExpr)

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...

bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody)

Perform ODR-like check for C/ObjC when merging tag types from modules.

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.

TypeResult ActOnTypeName(Declarator &D)

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.

ParsedType getInheritingConstructorName(CXXScopeSpec &SS, SourceLocation NameLoc, const IdentifierInfo &Name)

Handle the result of the special case name lookup for inheriting constructor declarations.

Decl * ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc, Expr *AssertExpr, Expr *AssertMessageExpr, SourceLocation RParenLoc)

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.

void ActOnFinishCXXMemberDecls()

Perform any semantic analysis which needs to be delayed until all pending class member declarations h...

Decl * ActOnFinishLinkageSpecification(Scope *S, Decl *LinkageSpec, SourceLocation RBraceLoc)

ActOnFinishLinkageSpecification - Complete the definition of the C++ linkage specification LinkageSpe...

DeclResult ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc, SourceLocation TemplateLoc, unsigned TagSpec, SourceLocation KWLoc, const CXXScopeSpec &SS, TemplateTy Template, SourceLocation TemplateNameLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, const ParsedAttributesView &Attr)

@ ConstantEvaluated

The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...

@ PotentiallyEvaluated

The current expression is potentially evaluated at run time, which means that code may be generated t...

@ Unevaluated

The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...

@ PotentiallyEvaluatedIfUsed

The current expression is potentially evaluated, but any declarations referenced inside that expressi...

DeclResult ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, const ParsedAttributesView &Attr, AccessSpecifier AS, SourceLocation ModulePrivateLoc, MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl, bool &IsDependent, SourceLocation ScopedEnumKWLoc, bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, bool IsTypeSpecifier, bool IsTemplateParamOrArg, OffsetOfKind OOK, SkipBodyInfo *SkipBody=nullptr)

This is invoked when we see 'struct foo' or 'struct {'.

Decl * ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, const ParsedAttributesView &DeclAttrs, RecordDecl *&AnonRecord)

ParsedFreeStandingDeclSpec - This method is invoked when a declspec with no declarator (e....

void ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace)

ActOnFinishNamespaceDef - This callback is called after a namespace is exited.

void ActOnTagFinishSkippedDefinition(SkippedDefinitionContext Context)

SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts

A stack of expression evaluation contexts.

MemInitResult ActOnMemInitializer(Decl *ConstructorD, Scope *S, CXXScopeSpec &SS, IdentifierInfo *MemberOrBase, ParsedType TemplateTypeTy, const DeclSpec &DS, SourceLocation IdLoc, SourceLocation LParenLoc, ArrayRef< Expr * > Args, SourceLocation RParenLoc, SourceLocation EllipsisLoc)

Handle a C++ member initializer using parentheses syntax.

void ActOnUninitializedDecl(Decl *dcl)

void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)

AddInitializerToDecl - Adds the initializer Init to the declaration dcl.

Decl * ActOnFinishExportDecl(Scope *S, Decl *ExportDecl, SourceLocation RBraceLoc)

Complete the definition of an export declaration.

void ActOnPureSpecifier(Decl *D, SourceLocation PureSpecLoc)

SkippedDefinitionContext ActOnTagStartSkippedDefinition(Scope *S, Decl *TD)

Invoked when we enter a tag definition that we're skipping.

Decl * ActOnUsingDirective(Scope *CurScope, SourceLocation UsingLoc, SourceLocation NamespcLoc, CXXScopeSpec &SS, SourceLocation IdentLoc, IdentifierInfo *NamespcName, const ParsedAttributesView &AttrList)

void ActOnStartTrailingRequiresClause(Scope *S, Declarator &D)

TypeResult ActOnTagTemplateIdType(TagUseKind TUK, TypeSpecifierType TagSpec, SourceLocation TagLoc, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, TemplateTy TemplateD, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgsIn, SourceLocation RAngleLoc)

Parsed an elaborated-type-specifier that refers to a template-id, such as class T::template apply.

Decl * ActOnUsingDeclaration(Scope *CurScope, AccessSpecifier AS, SourceLocation UsingLoc, SourceLocation TypenameLoc, CXXScopeSpec &SS, UnqualifiedId &Name, SourceLocation EllipsisLoc, const ParsedAttributesView &AttrList)

ExprResult ActOnDecltypeExpression(Expr *E)

Process the expression contained within a decltype.

ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})

Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

SourceLocation getLocWithOffset(IntTy Offset) const

Return a source location with the specified offset from this SourceLocation.

SourceLocation getSpellingLoc(SourceLocation Loc) const

Given a SourceLocation object, return the spelling location referenced by the ID.

SourceLocation getExpansionLoc(SourceLocation Loc) const

Given a SourceLocation object Loc, return the expansion location referenced by the ID.

A trivial tuple used to represent a source range.

void setBegin(SourceLocation b)

SourceLocation getBegin() const

void setEnd(SourceLocation e)

SourceLocation getEndLoc() const LLVM_READONLY

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

SourceLocation getBeginLoc() const LLVM_READONLY

StringLiteral - This represents a string literal expression, e.g.

A RAII object used to temporarily suppress access-like checking.

Represents the declaration of a struct/union/class/enum.

Represents a C++ template name within the type system.

Token - This structure provides full information about a lexed token.

IdentifierInfo * getIdentifierInfo() const

void setLiteralData(const char *Ptr)

SourceLocation getEndLoc() const

void setAnnotationEndLoc(SourceLocation L)

SourceLocation getLocation() const

Return a source location identifier for the specified offset in the current file.

const char * getName() const

unsigned getLength() const

void setLength(unsigned Len)

void setKind(tok::TokenKind K)

SourceLocation getAnnotationEndLoc() const

bool is(tok::TokenKind K) const

is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....

tok::TokenKind getKind() const

bool isRegularKeywordAttribute() const

Return true if the token is a keyword that is parsed in the same position as a standard attribute,...

bool isAtStartOfLine() const

isAtStartOfLine - Return true if this token is at the start of a line.

bool hasLeadingSpace() const

Return true if this token has whitespace before it.

SourceRange getAnnotationRange() const

SourceRange of the group of tokens that this annotation token represents.

void setLocation(SourceLocation L)

bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const

bool isNot(tok::TokenKind K) const

bool isAnnotation() const

Return true if this is any of tok::annot_* kind tokens.

void startToken()

Reset all flags to cleared.

The base class of the type hierarchy.

Represents a C++ unqualified-id that has been parsed.

Represents C++ using-directive.

Declaration of a variable template.

Represents a C++11 virt-specifier-seq.

Specifier getLastSpecifier() const

SourceLocation getFirstLocation() const

SourceLocation getAbstractLoc() const

static const char * getSpecifierName(Specifier VS)

bool SetSpecifier(Specifier VS, SourceLocation Loc, const char *&PrevSpec)

Defines the clang::TargetInfo interface.

@ After

Like System, but searched after the system directories.

bool Zero(InterpState &S, CodePtr OpPC)

TokenKind

Provides a simple uniform namespace for tokens from all C languages.

constexpr bool isRegularKeywordAttribute(TokenKind K)

bool isPragmaAnnotation(TokenKind K)

Return true if this is an annotation token representing a pragma.

The JSON file list parser is used to communicate input to InstallAPI.

TypeSpecifierType

Specifies the kind of type.

bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)

FunctionDefinitionKind

Described the kind of function definition (if any) provided for a function.

InClassInitStyle

In-class initialization styles for non-static data members.

@ ICIS_CopyInit

Copy initialization.

@ ICIS_ListInit

Direct list-initialization.

@ ICIS_NoInit

No in-class initializer.

bool tokenIsLikeStringLiteral(const Token &Tok, const LangOptions &LO)

Return true if the token is a string literal, or a function local predefined macro,...

llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion

A union of the various pointer types that can be passed to an ParsedAttr as an argument.

@ IK_TemplateId

A template-id, e.g., f.

@ IK_Identifier

An identifier.

LLVM_READONLY bool isLetter(unsigned char c)

Return true if this character is an ASCII letter: [a-zA-Z].

@ Result

The result type of a method or function.

ActionResult< Expr * > ExprResult

MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg

int hasAttribute(AttributeCommonInfo::Syntax Syntax, const IdentifierInfo *Scope, const IdentifierInfo *Attr, const TargetInfo &Target, const LangOptions &LangOpts)

Return the version number associated with the attribute if we recognize and implement the attribute s...

TemplateNameKind

Specifies the kind of template name that an identifier refers to.

@ TNK_Non_template

The name does not refer to a template.

@ TNK_Undeclared_template

Lookup for the name failed, but we're assuming it was a template name anyway.

const FunctionProtoType * T

SmallVector< Token, 4 > CachedTokens

A set of tokens that has been cached for later parsing.

@ Class

The "class" keyword introduces the elaborated-type-specifier.

@ Braces

New-expression has a C++11 list-initializer.

ExceptionSpecificationType

The various types of exception specifications that exist in C++11.

@ EST_Unparsed

not parsed yet

@ EST_None

no exception specification

@ EST_MSAny

Microsoft throw(...) extension.

@ EST_BasicNoexcept

noexcept

@ EST_Dynamic

throw(T1, T2)

AccessSpecifier

A C++ access specifier (public, private, protected), plus the special value "none" which means differ...

CachedTokens * ExceptionSpecTokens

Pointer to the cached tokens for an exception-specification that has not yet been parsed.

ParamInfo * Params

Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...

unsigned NumParams

NumParams - This is the number of formal parameters specified by the declarator.

ExceptionSpecificationType getExceptionSpecType() const

Get the type of exception specification this function has.

std::unique_ptr< CachedTokens > DefaultArgTokens

DefaultArgTokens - When the parameter's default argument cannot be parsed immediately (because it occ...

Describes how types, statements, expressions, and declarations should be printed.

Information about a template-id annotation token.

const IdentifierInfo * Name

FIXME: Temporarily stores the name of a specialization.

TemplateNameKind Kind

The kind of template that Template refers to.

unsigned NumArgs

NumArgs - The number of template arguments.

SourceLocation TemplateNameLoc

TemplateNameLoc - The location of the template name within the source.

ParsedTemplateArgument * getTemplateArgs()

Retrieves a pointer to the template arguments.

SourceLocation RAngleLoc

The location of the '>' after the template argument list.

SourceLocation LAngleLoc

The location of the '<' before the template argument list.

SourceLocation TemplateKWLoc

TemplateKWLoc - The location of the template keyword.

bool mightBeType() const

Determine whether this might be a type template.

ParsedTemplateTy Template

The declaration of the template corresponding to the template-name.