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

1

2

3

4

5

6

7

8

9

10

11

12

13

17using namespace clang;

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49bool Parser::isCXXDeclarationStatement(

50 bool DisambiguatingWithExpression ) {

52

54

55 case tok::kw_asm:

56

57 case tok::kw_namespace:

58

59

60 case tok::kw_using:

61

62 case tok::kw_static_assert:

63 case tok::kw__Static_assert:

64 return true;

65 case tok::coloncolon:

66 case tok::identifier: {

67 if (DisambiguatingWithExpression) {

68 RevertingTentativeParsingAction TPA(*this);

69

71 ParseOptionalCXXScopeSpecifier(SS, nullptr,

72 false,

73 true);

74

76 case tok::identifier: {

81 isDeductionGuide) {

82 if (isConstructorDeclarator(

83 SS.isEmpty(), isDeductionGuide,

85 return true;

87

88

89

90

91

92

93

94

95 if (NextToken().is(tok::identifier))

96 return true;

97 }

98 break;

99 }

100 case tok::kw_operator:

101 return true;

102 case tok::tilde:

103 return true;

104 default:

105 break;

106 }

107 }

108 }

109 [[fallthrough]];

110

111 default:

112 return isCXXSimpleDeclaration(false);

113 }

114}

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161 bool InvalidAsDeclaration = false;

162 TPResult TPR = isCXXDeclarationSpecifier(

164 if (TPR != TPResult::Ambiguous)

165 return TPR != TPResult::False;

166

167

168

169

170

171

172

173 if (InvalidAsDeclaration)

174 return false;

175

176

177

178

179

180

181

182

183 {

184 RevertingTentativeParsingAction PA(*this);

185 TPR = TryParseSimpleDeclaration(AllowForRangeDecl);

186 }

187

188

189 if (TPR == TPResult::Error)

190 return true;

191

192

193 if (TPR == TPResult::Ambiguous)

194 TPR = TPResult::True;

195

196 assert(TPR == TPResult::True || TPR == TPResult::False);

197 return TPR == TPResult::True;

198}

199

200

201

202Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {

204 case tok::kw__Atomic:

205 if (NextToken().isNot(tok::l_paren)) {

207 break;

208 }

209 [[fallthrough]];

210 case tok::kw_typeof:

211 case tok::kw___attribute:

212#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:

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

214 {

216 if (Tok.isNot(tok::l_paren))

217 return TPResult::Error;

218 ConsumeParen();

220 return TPResult::Error;

221 break;

222 }

223

224 case tok::kw_class:

225 case tok::kw_struct:

226 case tok::kw_union:

227 case tok::kw___interface:

228 case tok::kw_enum:

229

230

231

232

233

234

235

237

238

239 if (!TrySkipAttributes())

240 return TPResult::Error;

241

243 return TPResult::Error;

244 if (Tok.is(tok::annot_cxxscope))

245 ConsumeAnnotationToken();

246 if (Tok.is(tok::identifier))

248 else if (Tok.is(tok::annot_template_id))

249 ConsumeAnnotationToken();

250 else

251 return TPResult::Error;

252 break;

253

254 case tok::annot_cxxscope:

255 ConsumeAnnotationToken();

256 [[fallthrough]];

257 default:

259

261 return TryParseProtocolQualifiers();

262 break;

263 }

264

265 return TPResult::Ambiguous;

266}

267

268

269

270

271

272

273

274

275

276Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {

277 bool DeclSpecifierIsAuto = Tok.is(tok::kw_auto);

278 if (TryConsumeDeclarationSpecifier() == TPResult::Error)

279 return TPResult::Error;

280

281

282

283

284 if (Tok.isNot(tok::l_paren)) {

286 if (TPR == TPResult::Ambiguous)

287 return TPResult::True;

288 if (TPR == TPResult::True || TPR == TPResult::Error)

289 return TPR;

290 assert(TPR == TPResult::False);

291 }

292

293 TPResult TPR = TryParseInitDeclaratorList(

294 DeclSpecifierIsAuto);

295 if (TPR != TPResult::Ambiguous)

296 return TPR;

297

298 if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))

299 return TPResult::False;

300

301 return TPResult::Ambiguous;

302}

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331Parser::TPResult

332Parser::TryParseInitDeclaratorList(bool MayHaveTrailingReturnType) {

333 while (true) {

334

335 TPResult TPR = TryParseDeclarator(

336 false,

337 true,

338 false,

339 MayHaveTrailingReturnType);

340 if (TPR != TPResult::Ambiguous)

341 return TPR;

342

343

344 if (Tok.isOneOf(tok::kw_asm, tok::kw___attribute))

345 return TPResult::True;

346

347

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

349

350 ConsumeParen();

352 return TPResult::Error;

353 } else if (Tok.is(tok::l_brace)) {

354

355

356 return TPResult::True;

357 } else if (Tok.is(tok::equal) || isTokIdentifier_in()) {

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374 return TPResult::True;

375 }

376

378 break;

379 }

380

381 return TPResult::Ambiguous;

382}

383

390

395

399 }

400

403

405

406

407

408

409 RevertingTentativeParsingAction PA(P);

411

412

413 unsigned QuestionColonDepth = 0;

414 while (true) {

415 P.SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},

417 if (P.Tok.is(tok::question))

418 ++QuestionColonDepth;

419 else if (P.Tok.is(tok::colon)) {

420 if (QuestionColonDepth)

421 --QuestionColonDepth;

422 else {

424 return;

425 }

426 } else {

428 break;

429 }

431 }

432 } else {

433

435 }

436 if (P.Tok.isNot(tok::r_paren))

438 if (P.Tok.isNot(tok::semi))

440 }

441 }

442

446 }

447

451 }

452

454 switch (IsDecl) {

455 case TPResult::True:

457 assert(resolved() && "can't continue after tentative parsing bails out");

458 break;

459 case TPResult::False:

461 break;

462 case TPResult::Ambiguous:

463 break;

464 case TPResult::Error:

467 break;

468 }

470 }

471

472 ConditionOrInitStatement result() const {

475 "result called but not yet resolved");

477 return ConditionOrInitStatement::Expression;

479 return ConditionOrInitStatement::ConditionDecl;

481 return ConditionOrInitStatement::InitStmtDecl;

483 return ConditionOrInitStatement::ForRangeDecl;

484 return ConditionOrInitStatement::Error;

485 }

486};

487

488bool Parser::isEnumBase(bool AllowSemi) {

489 assert(Tok.is(tok::colon) && "should be looking at the ':'");

490

491 RevertingTentativeParsingAction PA(*this);

492

494

495

496 bool InvalidAsDeclSpec = false;

497

498

499

501 TPResult::True,

502 &InvalidAsDeclSpec);

503 if (R == TPResult::Ambiguous) {

504

505

506 if (TryConsumeDeclarationSpecifier() == TPResult::Error)

507 return true;

508

509

510

511 if (Tok.is(tok::l_brace) || (AllowSemi && Tok.is(tok::semi)))

512 return true;

513

514

516 &InvalidAsDeclSpec);

517 }

518

519 return R != TPResult::False;

520}

521

522

523

524

525

526

527

528

529

530

531

532

533

534

535

536

537

538

539Parser::ConditionOrInitStatement

540Parser::isCXXConditionDeclarationOrInitStatement(bool CanBeInitStatement,

541 bool CanBeForRangeDecl) {

542 ConditionDeclarationOrInitStatementState State(*this, CanBeInitStatement,

543 CanBeForRangeDecl);

544

545 if (CanBeInitStatement && Tok.is(tok::kw_using))

546 return ConditionOrInitStatement::InitStmtDecl;

548 return State.result();

549

550

551 RevertingTentativeParsingAction PA(*this);

552

553

554 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);

555 if (State.update(TryConsumeDeclarationSpecifier()))

556 return State.result();

557 assert(Tok.is(tok::l_paren) && "Expected '('");

558

559 while (true) {

560

561 if (State.update(TryParseDeclarator(

562 false,

563 true,

564 false,

565 MayHaveTrailingReturnType)))

566 return State.result();

567

568

569

570

571 if (Tok.isOneOf(tok::equal, tok::kw_asm, tok::kw___attribute) ||

573 State.markNotExpression();

574 return State.result();

575 }

576

577

578 if (State.CanBeForRangeDecl && Tok.is(tok::colon))

579 return ConditionOrInitStatement::ForRangeDecl;

580

581

582

583 if (State.markNotCondition())

584 return State.result();

585

586

587 if (State.markNotForRangeDecl())

588 return State.result();

589

590

591

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

593 ConsumeParen();

595 }

596

598 break;

599 }

600

601

602 if (State.CanBeCondition && Tok.is(tok::r_paren))

603 return ConditionOrInitStatement::ConditionDecl;

604 else if (State.CanBeInitStatement && Tok.is(tok::semi))

605 return ConditionOrInitStatement::InitStmtDecl;

606 else

607 return ConditionOrInitStatement::Expression;

608}

609

610

611

612

613

614

615

616

617

618

619

620

621

622

623

624

625

626

627bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {

628

629 isAmbiguous = false;

630

631

632

633

634

635

636

637

639 if (TPR != TPResult::Ambiguous)

640 return TPR != TPResult::False;

641

642

643

644

645

646

647

648

649 RevertingTentativeParsingAction PA(*this);

650 bool MayHaveTrailingReturnType = Tok.is(tok::kw_auto);

651

652

653 TryConsumeDeclarationSpecifier();

654 assert(Tok.is(tok::l_paren) && "Expected '('");

655

656

657 TPR = TryParseDeclarator(true , false ,

658 false,

659 MayHaveTrailingReturnType);

660

661

662 if (TPR == TPResult::Error)

663 TPR = TPResult::True;

664

665 if (TPR == TPResult::Ambiguous) {

666

667

668 if (Context == TypeIdInParens && Tok.is(tok::r_paren)) {

669 TPR = TPResult::True;

670 isAmbiguous = true;

671

672

673

674 } else if (Context == TypeIdAsGenericSelectionArgument && Tok.is(tok::comma)) {

675 TPR = TPResult::True;

676 isAmbiguous = true;

677

678

679

680

681 } else if (Context == TypeIdAsTemplateArgument &&

682 (Tok.isOneOf(tok::greater, tok::comma) ||

684 (Tok.isOneOf(tok::greatergreater,

685 tok::greatergreatergreater) ||

686 (Tok.is(tok::ellipsis) &&

688 tok::greatergreatergreater,

689 tok::comma)))))) {

690 TPR = TPResult::True;

691 isAmbiguous = true;

692

693 } else if (Context == TypeIdInTrailingReturnType) {

694 TPR = TPResult::True;

695 isAmbiguous = true;

696 } else

697 TPR = TPResult::False;

698 }

699

700 assert(TPR == TPResult::True || TPR == TPResult::False);

701 return TPR == TPResult::True;

702}

703

704

705

706

707

708

709

710

711

712

713

714

715

716

717

718

719

720

721

722

723

724

725

726

727

728

729

730

731

732

733

734

735

736

737Parser::CXX11AttributeKind

738Parser::isCXX11AttributeSpecifier(bool Disambiguate,

739 bool OuterMightBeMessageSend) {

740

742 return CAK_AttributeSpecifier;

743

745 return CAK_AttributeSpecifier;

746

747 if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square))

748 return CAK_NotAttributeSpecifier;

749

750

752 return CAK_AttributeSpecifier;

753

754

755 if (GetLookAheadToken(2).is(tok::kw_using))

756 return CAK_AttributeSpecifier;

757

758 RevertingTentativeParsingAction PA(*this);

759

760

761 ConsumeBracket();

762

764 ConsumeBracket();

765

766 bool IsAttribute = SkipUntil(tok::r_square);

767 IsAttribute &= Tok.is(tok::r_square);

768

769 return IsAttribute ? CAK_AttributeSpecifier : CAK_InvalidAttributeSpecifier;

770 }

771

772

773

774

775

776

777

778

779

780

781

782

783

784 {

785 RevertingTentativeParsingAction LambdaTPA(*this);

787 LambdaIntroducerTentativeParse Tentative;

788 if (ParseLambdaIntroducer(Intro, &Tentative)) {

789

790

791

792 return CAK_NotAttributeSpecifier;

793 }

794

795 switch (Tentative) {

796 case LambdaIntroducerTentativeParse::MessageSend:

797

798

799 return CAK_NotAttributeSpecifier;

800

801 case LambdaIntroducerTentativeParse::Success:

802 case LambdaIntroducerTentativeParse::Incomplete:

803

804 if (Tok.is(tok::r_square))

805

806 return CAK_AttributeSpecifier;

807

808 if (OuterMightBeMessageSend)

809

810 return CAK_NotAttributeSpecifier;

811

812

813 return CAK_InvalidAttributeSpecifier;

814

815 case LambdaIntroducerTentativeParse::Invalid:

816

817

818 break;

819 }

820 }

821

822 ConsumeBracket();

823

824

825

826 bool IsAttribute = true;

827 while (Tok.isNot(tok::r_square)) {

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

829

830 return CAK_AttributeSpecifier;

831 }

832

833

834

835

836

837

839 if (!TryParseCXX11AttributeIdentifier(Loc)) {

840 IsAttribute = false;

841 break;

842 }

843 if (Tok.is(tok::coloncolon)) {

845 if (!TryParseCXX11AttributeIdentifier(Loc)) {

846 IsAttribute = false;

847 break;

848 }

849 }

850

851

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

853 ConsumeParen();

855 IsAttribute = false;

856 break;

857 }

858 }

859

861

863 break;

864 }

865

866

867 if (IsAttribute) {

868 if (Tok.is(tok::r_square)) {

869 ConsumeBracket();

870 IsAttribute = Tok.is(tok::r_square);

871 } else {

872 IsAttribute = false;

873 }

874 }

875

876 if (IsAttribute)

877

878 return CAK_AttributeSpecifier;

879

880

881 return CAK_NotAttributeSpecifier;

882}

883

884bool Parser::TrySkipAttributes() {

885 while (Tok.isOneOf(tok::l_square, tok::kw___attribute, tok::kw___declspec,

886 tok::kw_alignas) ||

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

889 ConsumeBracket();

890 if (Tok.isNot(tok::l_square))

891 return false;

892 ConsumeBracket();

893 if (SkipUntil(tok::r_square) || Tok.isNot(tok::r_square))

894 return false;

895

896

897 ConsumeBracket();

901 } else {

903 if (Tok.isNot(tok::l_paren))

904 return false;

905 ConsumeParen();

907 return false;

908 }

909 }

910

911 return true;

912}

913

914Parser::TPResult Parser::TryParsePtrOperatorSeq() {

915 while (true) {

917 return TPResult::Error;

918

919 if (Tok.isOneOf(tok::star, tok::amp, tok::caret, tok::ampamp) ||

920 (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) {

921

923

924

925 if (!TrySkipAttributes())

926 return TPResult::Error;

927

928 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw_restrict,

929 tok::kw__Nonnull, tok::kw__Nullable,

930 tok::kw__Nullable_result, tok::kw__Null_unspecified,

931 tok::kw__Atomic))

933 } else {

934 return TPResult::True;

935 }

936 }

937}

938

939

940

941

942

943

944

945

946

947

948

949

950

951

952

953

954

955

956

957Parser::TPResult Parser::TryParseOperatorId() {

958 assert(Tok.is(tok::kw_operator));

960

961

963 case tok::kw_new: case tok::kw_delete:

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

966 ConsumeBracket();

967 ConsumeBracket();

968 }

969 return TPResult::True;

970

971#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \

972 case tok::Token:

973#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)

974#include "clang/Basic/OperatorKinds.def"

976 return TPResult::True;

977

978 case tok::l_square:

979 if (NextToken().is(tok::r_square)) {

980 ConsumeBracket();

981 ConsumeBracket();

982 return TPResult::True;

983 }

984 break;

985

986 case tok::l_paren:

987 if (NextToken().is(tok::r_paren)) {

988 ConsumeParen();

989 ConsumeParen();

990 return TPResult::True;

991 }

992 break;

993

994 default:

995 break;

996 }

997

998

1000 bool FoundUDSuffix = false;

1001 do {

1003 ConsumeStringToken();

1004 } while (isTokenStringLiteral());

1005

1006 if (!FoundUDSuffix) {

1007 if (Tok.is(tok::identifier))

1009 else

1010 return TPResult::Error;

1011 }

1012 return TPResult::True;

1013 }

1014

1015

1016 bool AnyDeclSpecifiers = false;

1017 while (true) {

1019 if (TPR == TPResult::Error)

1020 return TPR;

1021 if (TPR == TPResult::False) {

1022 if (!AnyDeclSpecifiers)

1023 return TPResult::Error;

1024 break;

1025 }

1026 if (TryConsumeDeclarationSpecifier() == TPResult::Error)

1027 return TPResult::Error;

1028 AnyDeclSpecifiers = true;

1029 }

1030 return TryParsePtrOperatorSeq();

1031}

1032

1033

1034

1035

1036

1037

1038

1039

1040

1041

1042

1043

1044

1045

1046

1047

1048

1049

1050

1051

1052

1053

1054

1055

1056

1057

1058

1059

1060

1061

1062

1063

1064

1065

1066

1067

1068

1069

1070

1071

1072

1073

1074

1075

1076

1077

1078

1079

1080

1081

1082

1083

1084

1085

1086Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,

1087 bool mayHaveIdentifier,

1088 bool mayHaveDirectInit,

1089 bool mayHaveTrailingReturnType) {

1090

1091

1092

1093 if (TryParsePtrOperatorSeq() == TPResult::Error)

1094 return TPResult::Error;

1095

1096

1097

1098 if (Tok.is(tok::ellipsis))

1100

1101 if ((Tok.isOneOf(tok::identifier, tok::kw_operator) ||

1102 (Tok.is(tok::annot_cxxscope) && (NextToken().is(tok::identifier) ||

1103 NextToken().is(tok::kw_operator)))) &&

1104 mayHaveIdentifier) {

1105

1106 if (Tok.is(tok::annot_cxxscope)) {

1111 return TPResult::Error;

1112 ConsumeAnnotationToken();

1113 } else if (Tok.is(tok::identifier)) {

1114 TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());

1115 }

1116 if (Tok.is(tok::kw_operator)) {

1117 if (TryParseOperatorId() == TPResult::Error)

1118 return TPResult::Error;

1119 } else

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

1122 ConsumeParen();

1123 if (mayBeAbstract &&

1124 (Tok.is(tok::r_paren) ||

1125

1126 (Tok.is(tok::ellipsis) && NextToken().is(tok::r_paren)) ||

1127 isDeclarationSpecifier(

1129

1130

1131 TPResult TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);

1132 if (TPR != TPResult::Ambiguous)

1133 return TPR;

1134 } else {

1135

1136

1137

1138 if (Tok.isOneOf(tok::kw___attribute, tok::kw___declspec, tok::kw___cdecl,

1139 tok::kw___stdcall, tok::kw___fastcall, tok::kw___thiscall,

1140 tok::kw___regcall, tok::kw___vectorcall))

1141 return TPResult::True;

1142 TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);

1143 if (TPR != TPResult::Ambiguous)

1144 return TPR;

1145 if (Tok.isNot(tok::r_paren))

1146 return TPResult::False;

1147 ConsumeParen();

1148 }

1149 } else if (!mayBeAbstract) {

1150 return TPResult::False;

1151 }

1152

1153 if (mayHaveDirectInit)

1154 return TPResult::Ambiguous;

1155

1156 while (true) {

1157 TPResult TPR(TPResult::Ambiguous);

1158

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

1160

1161

1162

1163

1164 if (!mayBeAbstract && !isCXXFunctionDeclarator())

1165 break;

1166

1167

1168

1169 ConsumeParen();

1170 TPR = TryParseFunctionDeclarator(mayHaveTrailingReturnType);

1171 } else if (Tok.is(tok::l_square)) {

1172

1173

1174 TPR = TryParseBracketDeclarator();

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

1176

1177

1178 TPR = TPResult::True;

1179 } else {

1180 break;

1181 }

1182

1183 if (TPR != TPResult::Ambiguous)

1184 return TPR;

1185 }

1186

1187 return TPResult::Ambiguous;

1188}

1189

1190bool Parser::isTentativelyDeclared(IdentifierInfo *II) {

1191 return llvm::is_contained(TentativelyDeclaredIdentifiers, II);

1192}

1193

1194namespace {

1196public:

1197 TentativeParseCCC(const Token &Next) {

1198 WantRemainingKeywords = false;

1199 WantTypeSpecifiers =

1200 Next.isOneOf(tok::l_paren, tok::r_paren, tok::greater, tok::l_brace,

1201 tok::identifier, tok::comma);

1202 }

1203

1204 bool ValidateCandidate(const TypoCorrection &Candidate) override {

1205

1206

1208 llvm::all_of(Candidate,

1209 [](NamedDecl *ND) { return ND->isCXXInstanceMember(); }))

1210 return false;

1211

1213 }

1214

1215 std::unique_ptr clone() override {

1216 return std::make_unique(*this);

1217 }

1218};

1219}

1220

1221

1222

1223

1224

1225

1226

1227

1228

1229

1230

1231

1232

1233

1234

1235

1236

1237

1238

1239

1240

1241

1242

1243

1244

1245

1246

1247

1248

1249

1250

1251

1252

1253

1254

1255

1256

1257

1258

1259

1260

1261

1262

1263

1264

1265

1266

1267

1268

1269

1270

1271

1272

1273

1274

1275

1276

1277

1278

1279

1280

1281

1282

1283

1284

1285

1286

1287

1288

1289

1290

1291

1292

1293

1294

1295

1296

1297

1298

1299

1300

1301

1302

1303

1304

1305

1306

1307

1308

1309

1310

1311

1312

1313

1314

1315

1316

1317

1318

1319

1320

1321

1322

1323

1324

1325

1326

1327

1328

1329

1330

1331

1332Parser::TPResult

1334 Parser::TPResult BracedCastResult,

1335 bool *InvalidAsDeclSpec) {

1337 int Lookahead) {

1338

1339

1341 (GetLookAheadToken(Lookahead + 1)

1342 .isOneOf(tok::kw_auto, tok::kw_decltype,

1343

1344

1345

1346

1347 tok::identifier,

1348

1349

1350

1351

1352 tok::kw_const, tok::kw_volatile, tok::kw_restrict) ||

1353

1354

1355

1356

1357

1358

1359

1360

1361

1362 (TemplateId->NumArgs == 0 &&

1363 GetLookAheadToken(Lookahead + 1).isOneOf(tok::amp, tok::ampamp)));

1364 };

1365 switch (Tok.getKind()) {

1366 case tok::identifier: {

1367 if (GetLookAheadToken(1).is(tok::ellipsis) &&

1368 GetLookAheadToken(2).is(tok::l_square)) {

1369

1371 return TPResult::Error;

1372 if (Tok.is(tok::identifier))

1373 return TPResult::False;

1375 BracedCastResult, InvalidAsDeclSpec);

1376 }

1377

1378

1379

1380 if (TryAltiVecVectorToken())

1381 return TPResult::True;

1382

1384

1386 return TPResult::True;

1387

1388

1389

1390

1391 if (Next.is(tok::l_paren) &&

1394 return TPResult::False;

1395 }

1396

1397 if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {

1398

1399

1400

1401

1402 TentativeParseCCC CCC(Next);

1403 switch (TryAnnotateName(&CCC)) {

1404 case ANK_Error:

1405 return TPResult::Error;

1406 case ANK_TentativeDecl:

1407 return TPResult::False;

1408 case ANK_TemplateName:

1409

1410

1411

1412

1415 return TPResult::Error;

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

1417 break;

1418 }

1419

1420

1421

1422 return GreaterThanIsOperator ? TPResult::True : TPResult::False;

1423 case ANK_Unresolved:

1424 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;

1425 case ANK_Success:

1426 break;

1427 }

1428 assert(Tok.isNot(tok::identifier) &&

1429 "TryAnnotateName succeeded without producing an annotation");

1430 } else {

1431

1432

1433

1434

1436 return TPResult::Error;

1437

1438

1439

1440 if (Tok.is(tok::identifier))

1441 return TPResult::False;

1442 }

1443

1444

1445 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,

1446 InvalidAsDeclSpec);

1447 }

1448

1449 case tok::kw_typename:

1450

1451

1453 return TPResult::Error;

1455 BracedCastResult, InvalidAsDeclSpec);

1456

1457 case tok::kw_auto: {

1459 return TPResult::True;

1460 if (NextToken().is(tok::l_brace))

1461 return TPResult::False;

1462 if (NextToken().is(tok::l_paren))

1463 return TPResult::Ambiguous;

1464 return TPResult::True;

1465 }

1466

1467 case tok::coloncolon: {

1469 if (Next.isOneOf(tok::kw_new,

1470 tok::kw_delete))

1471 return TPResult::False;

1472 [[fallthrough]];

1473 }

1474 case tok::kw___super:

1475 case tok::kw_decltype:

1476

1477

1479 return TPResult::Error;

1480 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,

1481 InvalidAsDeclSpec);

1482

1483

1484

1485

1486

1487

1488

1489

1490 case tok::kw_friend:

1491 case tok::kw_typedef:

1492 case tok::kw_constexpr:

1493 case tok::kw_consteval:

1494 case tok::kw_constinit:

1495

1496 case tok::kw_register:

1497 case tok::kw_static:

1498 case tok::kw_extern:

1499 case tok::kw_mutable:

1500 case tok::kw___thread:

1501 case tok::kw_thread_local:

1502 case tok::kw__Thread_local:

1503

1504 case tok::kw_inline:

1505 case tok::kw_virtual:

1506 case tok::kw_explicit:

1507

1508

1509 case tok::kw___module_private__:

1510

1511

1512 case tok::kw___unknown_anytype:

1513

1514

1515

1516

1517

1518

1519

1520

1521

1522

1523

1524 case tok::kw_class:

1525 case tok::kw_struct:

1526 case tok::kw_union:

1527 case tok::kw___interface:

1528

1529 case tok::kw_enum:

1530

1531 case tok::kw_const:

1532 case tok::kw_volatile:

1533 return TPResult::True;

1534

1535

1536 case tok::kw_private:

1538 return TPResult::False;

1539 [[fallthrough]];

1540 case tok::kw___private:

1541 case tok::kw___local:

1542 case tok::kw___global:

1543 case tok::kw___constant:

1544 case tok::kw___generic:

1545

1546 case tok::kw___read_only:

1547 case tok::kw___write_only:

1548 case tok::kw___read_write:

1549

1550 case tok::kw_pipe:

1551

1552

1553 case tok::kw_groupshared:

1554 case tok::kw_in:

1555 case tok::kw_inout:

1556 case tok::kw_out:

1557

1558

1559 case tok::kw_restrict:

1560 case tok::kw__Complex:

1561 case tok::kw___attribute:

1562 case tok::kw___auto_type:

1563 return TPResult::True;

1564

1565

1566 case tok::kw___declspec:

1567 case tok::kw___cdecl:

1568 case tok::kw___stdcall:

1569 case tok::kw___fastcall:

1570 case tok::kw___thiscall:

1571 case tok::kw___regcall:

1572 case tok::kw___vectorcall:

1573 case tok::kw___w64:

1574 case tok::kw___sptr:

1575 case tok::kw___uptr:

1576 case tok::kw___ptr64:

1577 case tok::kw___ptr32:

1578 case tok::kw___forceinline:

1579 case tok::kw___unaligned:

1580 case tok::kw__Nonnull:

1581 case tok::kw__Nullable:

1582 case tok::kw__Nullable_result:

1583 case tok::kw__Null_unspecified:

1584 case tok::kw___kindof:

1585 return TPResult::True;

1586

1587

1588 case tok::kw___funcref:

1589 return TPResult::True;

1590

1591

1592 case tok::kw___pascal:

1593 return TPResult::True;

1594

1595

1596 case tok::kw___vector:

1597 return TPResult::True;

1598

1599 case tok::kw_this: {

1600

1601

1603 RevertingTentativeParsingAction PA(*this);

1605 return isCXXDeclarationSpecifier(AllowImplicitTypename, BracedCastResult,

1606 InvalidAsDeclSpec);

1607 }

1608 return TPResult::False;

1609 }

1610 case tok::annot_template_id: {

1612

1613

1616 InvalidAsDeclSpec) {

1617

1618

1619

1620

1621 *InvalidAsDeclSpec = NextToken().is(tok::l_paren);

1622 return TPResult::Ambiguous;

1623 }

1625 return TPResult::Error;

1626 if (IsPlaceholderSpecifier(TemplateId, 0))

1627 return TPResult::True;

1629 return TPResult::False;

1631 AnnotateTemplateIdTokenAsType(SS, AllowImplicitTypename);

1632 assert(Tok.is(tok::annot_typename));

1633 goto case_typename;

1634 }

1635

1636 case tok::annot_cxxscope:

1637

1639 return TPResult::Error;

1640 if (!Tok.is(tok::annot_typename)) {

1641 if (Tok.is(tok::annot_cxxscope) &&

1642 NextToken().is(tok::annot_template_id)) {

1644 takeTemplateIdAnnotation(NextToken());

1646 if (InvalidAsDeclSpec) {

1647 *InvalidAsDeclSpec = NextToken().is(tok::l_paren);

1648 return TPResult::Ambiguous;

1649 }

1650 return TPResult::Error;

1651 }

1652 if (IsPlaceholderSpecifier(TemplateId, 1))

1653 return TPResult::True;

1654 }

1655

1656

1657 if (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier)) {

1661 SS);

1663 RevertingTentativeParsingAction PA(*this);

1664 ConsumeAnnotationToken();

1666 bool isIdentifier = Tok.is(tok::identifier);

1667 TPResult TPR = TPResult::False;

1668 if (!isIdentifier)

1669 TPR = isCXXDeclarationSpecifier(

1670 AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec);

1671

1672 if (isIdentifier ||

1673 TPR == TPResult::True || TPR == TPResult::Error)

1674 return TPResult::Error;

1675

1676 if (InvalidAsDeclSpec) {

1677

1678

1679 *InvalidAsDeclSpec = true;

1680 return TPResult::Ambiguous;

1681 } else {

1682

1683

1684

1686 if (((Tok.is(tok::amp) || Tok.is(tok::star)) &&

1687 (NextToken().is(tok::r_paren) ||

1688 NextToken().is(tok::greater))) ||

1689 (Tok.is(tok::ampamp) && NextToken().is(tok::greater)))

1690 return TPResult::True;

1691 }

1692 }

1693 } else {

1694

1695

1696 switch (TryAnnotateName(nullptr, AllowImplicitTypename)) {

1697 case ANK_Error:

1698 return TPResult::Error;

1699 case ANK_TentativeDecl:

1700 return TPResult::False;

1701 case ANK_TemplateName:

1702

1703

1706 return TPResult::Error;

1707

1708

1709

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

1711 break;

1712 }

1713

1714

1715

1716

1718 ? TPResult::True

1719 : TPResult::False;

1720 case ANK_Unresolved:

1721 return InvalidAsDeclSpec ? TPResult::Ambiguous : TPResult::False;

1722 case ANK_Success:

1723 break;

1724 }

1725

1726

1727 assert(Tok.isNot(tok::annot_cxxscope) ||

1728 NextToken().isNot(tok::identifier));

1729 return isCXXDeclarationSpecifier(AllowImplicitTypename,

1730 BracedCastResult, InvalidAsDeclSpec);

1731 }

1732 }

1733 return TPResult::False;

1734 }

1735

1736 [[fallthrough]];

1737

1738

1739

1740

1741

1742

1743

1744

1745

1746

1747

1748

1749

1750

1751

1752

1753

1754

1755

1756 case tok::annot_typename:

1757 case_typename:

1758

1760

1761 RevertingTentativeParsingAction PA(*this);

1763

1764 TPResult TPR = TryParseProtocolQualifiers();

1765 bool isFollowedByParen = Tok.is(tok::l_paren);

1766 bool isFollowedByBrace = Tok.is(tok::l_brace);

1767

1768 if (TPR == TPResult::Error)

1769 return TPResult::Error;

1770

1771 if (isFollowedByParen)

1772 return TPResult::Ambiguous;

1773

1775 return BracedCastResult;

1776

1777 return TPResult::True;

1778 }

1779

1780 [[fallthrough]];

1781

1782 case tok::kw_char:

1783 case tok::kw_wchar_t:

1784 case tok::kw_char8_t:

1785 case tok::kw_char16_t:

1786 case tok::kw_char32_t:

1787 case tok::kw_bool:

1788 case tok::kw_short:

1789 case tok::kw_int:

1790 case tok::kw_long:

1791 case tok::kw___int64:

1792 case tok::kw___int128:

1793 case tok::kw_signed:

1794 case tok::kw_unsigned:

1795 case tok::kw_half:

1796 case tok::kw_float:

1797 case tok::kw_double:

1798 case tok::kw___bf16:

1799 case tok::kw__Float16:

1800 case tok::kw___float128:

1801 case tok::kw___ibm128:

1802 case tok::kw_void:

1803 case tok::annot_decltype:

1804 case tok::kw__Accum:

1805 case tok::kw__Fract:

1806 case tok::kw__Sat:

1807 case tok::annot_pack_indexing_type:

1808#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:

1809#include "clang/Basic/OpenCLImageTypes.def"

1810#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:

1811#include "clang/Basic/HLSLIntangibleTypes.def"

1812 if (NextToken().is(tok::l_paren))

1813 return TPResult::Ambiguous;

1814

1815

1816

1817

1818

1819

1820

1822 return BracedCastResult;

1823

1824 if (isStartOfObjCClassMessageMissingOpenBracket())

1825 return TPResult::False;

1826

1827 return TPResult::True;

1828

1829

1830 case tok::kw_typeof: {

1831 if (NextToken().isNot(tok::l_paren))

1832 return TPResult::True;

1833

1834 RevertingTentativeParsingAction PA(*this);

1835

1836 TPResult TPR = TryParseTypeofSpecifier();

1837 bool isFollowedByParen = Tok.is(tok::l_paren);

1838 bool isFollowedByBrace = Tok.is(tok::l_brace);

1839

1840 if (TPR == TPResult::Error)

1841 return TPResult::Error;

1842

1843 if (isFollowedByParen)

1844 return TPResult::Ambiguous;

1845

1847 return BracedCastResult;

1848

1849 return TPResult::True;

1850 }

1851

1852#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:

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

1854 return TPResult::True;

1855

1856

1857 case tok::kw__Alignas:

1858 return TPResult::True;

1859

1860 case tok::kw__Atomic:

1861 return TPResult::True;

1862

1863 case tok::kw__BitInt:

1864 case tok::kw__ExtInt: {

1865 if (NextToken().isNot(tok::l_paren))

1866 return TPResult::Error;

1867 RevertingTentativeParsingAction PA(*this);

1869 ConsumeParen();

1870

1872 return TPResult::Error;

1873

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

1875 return TPResult::Ambiguous;

1876

1878 return BracedCastResult;

1879

1880 return TPResult::True;

1881 }

1882 default:

1883 return TPResult::False;

1884 }

1885}

1886

1887bool Parser::isCXXDeclarationSpecifierAType() {

1888 switch (Tok.getKind()) {

1889

1890 case tok::annot_decltype:

1891 case tok::annot_pack_indexing_type:

1892 case tok::annot_template_id:

1893 case tok::annot_typename:

1894 case tok::kw_typeof:

1895#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:

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

1897 return true;

1898

1899

1900 case tok::kw_class:

1901 case tok::kw_struct:

1902 case tok::kw_union:

1903 case tok::kw___interface:

1904 case tok::kw_enum:

1905 return true;

1906

1907

1908 case tok::kw_char:

1909 case tok::kw_wchar_t:

1910 case tok::kw_char8_t:

1911 case tok::kw_char16_t:

1912 case tok::kw_char32_t:

1913 case tok::kw_bool:

1914 case tok::kw_short:

1915 case tok::kw_int:

1916 case tok::kw__ExtInt:

1917 case tok::kw__BitInt:

1918 case tok::kw_long:

1919 case tok::kw___int64:

1920 case tok::kw___int128:

1921 case tok::kw_signed:

1922 case tok::kw_unsigned:

1923 case tok::kw_half:

1924 case tok::kw_float:

1925 case tok::kw_double:

1926 case tok::kw___bf16:

1927 case tok::kw__Float16:

1928 case tok::kw___float128:

1929 case tok::kw___ibm128:

1930 case tok::kw_void:

1931 case tok::kw___unknown_anytype:

1932 case tok::kw___auto_type:

1933 case tok::kw__Accum:

1934 case tok::kw__Fract:

1935 case tok::kw__Sat:

1936#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:

1937#include "clang/Basic/OpenCLImageTypes.def"

1938#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case tok::kw_##Name:

1939#include "clang/Basic/HLSLIntangibleTypes.def"

1940 return true;

1941

1942 case tok::kw_auto:

1944

1945 case tok::kw__Atomic:

1946

1948

1949 default:

1950 return false;

1951 }

1952}

1953

1954

1955

1956

1957

1958Parser::TPResult Parser::TryParseTypeofSpecifier() {

1959 assert(Tok.is(tok::kw_typeof) && "Expected 'typeof'!");

1961

1962 assert(Tok.is(tok::l_paren) && "Expected '('");

1963

1964 ConsumeParen();

1966 return TPResult::Error;

1967

1968 return TPResult::Ambiguous;

1969}

1970

1971

1972

1973Parser::TPResult Parser::TryParseProtocolQualifiers() {

1974 assert(Tok.is(tok::less) && "Expected '<' for qualifier list");

1976 do {

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

1978 return TPResult::Error;

1980

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

1983 continue;

1984 }

1985

1986 if (Tok.is(tok::greater)) {

1988 return TPResult::Ambiguous;

1989 }

1990 } while (false);

1991

1992 return TPResult::Error;

1993}

1994

1995

1996

1997

1998

1999

2000

2001

2002

2003

2004

2005bool Parser::isCXXFunctionDeclarator(

2007

2008

2009

2010

2011

2012

2013

2014

2015

2016

2017 RevertingTentativeParsingAction PA(*this);

2018

2019 ConsumeParen();

2020 bool InvalidAsDeclaration = false;

2021 TPResult TPR = TryParseParameterDeclarationClause(

2022 &InvalidAsDeclaration, false,

2023 AllowImplicitTypename);

2024 if (TPR == TPResult::Ambiguous) {

2025 if (Tok.isNot(tok::r_paren))

2026 TPR = TPResult::False;

2027 else {

2029 if (Next.isOneOf(tok::amp, tok::ampamp, tok::kw_const, tok::kw_volatile,

2030 tok::kw_throw, tok::kw_noexcept, tok::l_square,

2031 tok::l_brace, tok::kw_try, tok::equal, tok::arrow) ||

2032 isCXX11VirtSpecifier(Next))

2033

2034

2035

2036 TPR = TPResult::True;

2037 else if (InvalidAsDeclaration)

2038

2039 TPR = TPResult::False;

2040 }

2041 }

2042

2043 if (IsAmbiguous && TPR == TPResult::Ambiguous)

2044 *IsAmbiguous = true;

2045

2046

2047 return TPR != TPResult::False;

2048}

2049

2050

2051

2052

2053

2054

2055

2056

2057

2058

2059

2060

2061

2062

2063

2064

2065

2066

2067Parser::TPResult Parser::TryParseParameterDeclarationClause(

2068 bool *InvalidAsDeclaration, bool VersusTemplateArgument,

2070

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

2072 return TPResult::Ambiguous;

2073

2074

2075

2076

2077

2078

2079

2080

2081 while (true) {

2082

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

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

2086 return TPResult::True;

2087 else

2088 return TPResult::False;

2089 }

2090

2091

2092 if (isCXX11AttributeSpecifier(false,

2093 true))

2094 return TPResult::True;

2095

2097 MaybeParseMicrosoftAttributes(attrs);

2098

2099

2100

2101

2102 TPResult TPR = isCXXDeclarationSpecifier(

2103 AllowImplicitTypename, TPResult::False, InvalidAsDeclaration);

2104

2105

2106 if (TPR != TPResult::Ambiguous &&

2107 !(VersusTemplateArgument && TPR == TPResult::True))

2108 return TPR;

2109

2110 bool SeenType = false;

2111 bool DeclarationSpecifierIsAuto = Tok.is(tok::kw_auto);

2112 do {

2113 SeenType |= isCXXDeclarationSpecifierAType();

2114 if (TryConsumeDeclarationSpecifier() == TPResult::Error)

2115 return TPResult::Error;

2116

2117

2118 if (SeenType && Tok.is(tok::identifier))

2119 return TPResult::True;

2120

2121 TPR = isCXXDeclarationSpecifier(AllowImplicitTypename, TPResult::False,

2122 InvalidAsDeclaration);

2123 if (TPR == TPResult::Error)

2124 return TPR;

2125

2126

2127 if (TPR == TPResult::True && !VersusTemplateArgument)

2128 return TPR;

2129 } while (TPR != TPResult::False);

2130

2131

2132

2133 TPR = TryParseDeclarator(

2134 true,

2135 true,

2136 false,

2137 DeclarationSpecifierIsAuto);

2138 if (TPR != TPResult::Ambiguous)

2139 return TPR;

2140

2141

2142 if (Tok.is(tok::kw___attribute))

2143 return TPResult::True;

2144

2145

2146

2147

2148

2149

2150

2151

2152

2153

2154 if (VersusTemplateArgument)

2155 return Tok.is(tok::equal) ? TPResult::True : TPResult::False;

2156

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

2158

2159

2161 return TPResult::Error;

2162 }

2163

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

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

2167 return TPResult::True;

2168 else

2169 return TPResult::False;

2170 }

2171

2173 break;

2174 }

2175

2176 return TPResult::Ambiguous;

2177}

2178

2179

2180

2181

2182

2183

2184

2185

2186

2187

2188

2189

2190

2191Parser::TPResult

2192Parser::TryParseFunctionDeclarator(bool MayHaveTrailingReturnType) {

2193

2194

2195 TPResult TPR = TryParseParameterDeclarationClause();

2196 if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))

2197 TPR = TPResult::False;

2198

2199 if (TPR == TPResult::False || TPR == TPResult::Error)

2200 return TPR;

2201

2202

2204 return TPResult::Error;

2205

2206

2207 while (Tok.isOneOf(tok::kw_const, tok::kw_volatile, tok::kw___unaligned,

2208 tok::kw_restrict))

2210

2211

2212 if (Tok.isOneOf(tok::amp, tok::ampamp))

2214

2215

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

2218 if (Tok.isNot(tok::l_paren))

2219 return TPResult::Error;

2220

2221

2222 ConsumeParen();

2224 return TPResult::Error;

2225 }

2226 if (Tok.is(tok::kw_noexcept)) {

2228

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

2230

2231 ConsumeParen();

2233 return TPResult::Error;

2234 }

2235 }

2236

2237

2238 if (!TrySkipAttributes())

2239 return TPResult::Ambiguous;

2240

2241

2242 if (Tok.is(tok::arrow) && MayHaveTrailingReturnType) {

2243 if (TPR == TPResult::True)

2244 return TPR;

2246 if (Tok.is(tok::identifier) && NameAfterArrowIsNonType()) {

2247 return TPResult::False;

2248 }

2249 if (isCXXTypeId(TentativeCXXTypeIdContext::TypeIdInTrailingReturnType))

2250 return TPResult::True;

2251 }

2252

2253 return TPResult::Ambiguous;

2254}

2255

2256

2257

2258

2259

2260bool Parser::NameAfterArrowIsNonType() {

2261 assert(Tok.is(tok::identifier));

2263 if (Next.is(tok::coloncolon))

2264 return false;

2268 TentativeParseCCC CCC(Next);

2271 switch (Classification.getKind()) {

2276 return true;

2277 default:

2278 break;

2279 }

2280 return false;

2281}

2282

2283

2284

2285Parser::TPResult Parser::TryParseBracketDeclarator() {

2286 ConsumeBracket();

2287

2288

2289

2290 if (Tok.is(tok::l_brace))

2291 return TPResult::False;

2292

2294 return TPResult::Error;

2295

2296

2297

2298 if (Tok.isNot(tok::r_square))

2299 return TPResult::False;

2300

2301 ConsumeBracket();

2302 return TPResult::Ambiguous;

2303}

2304

2305

2306

2307

2308

2309Parser::TPResult Parser::isTemplateArgumentList(unsigned TokensToSkip) {

2310 if (!TokensToSkip) {

2311 if (Tok.isNot(tok::less))

2312 return TPResult::False;

2313 if (NextToken().is(tok::greater))

2314 return TPResult::True;

2315 }

2316

2317 RevertingTentativeParsingAction PA(*this);

2318

2319 while (TokensToSkip) {

2321 --TokensToSkip;

2322 }

2323

2325 return TPResult::False;

2326

2327

2328

2329

2330 bool InvalidAsTemplateArgumentList = false;

2332 &InvalidAsTemplateArgumentList) ==

2333 TPResult::True)

2334 return TPResult::True;

2335 if (InvalidAsTemplateArgumentList)

2336 return TPResult::False;

2337

2338

2339

2340

2341

2342

2343

2344

2345

2346

2347

2348

2349

2350 if (SkipUntil({tok::greater, tok::greatergreater, tok::greatergreatergreater},

2352 return TPResult::Ambiguous;

2353 return TPResult::False;

2354}

2355

2356

2357

2358Parser::TPResult Parser::isExplicitBool() {

2359 assert(Tok.is(tok::l_paren) && "expected to be looking at a '(' token");

2360

2361 RevertingTentativeParsingAction PA(*this);

2362 ConsumeParen();

2363

2364

2365

2366

2367

2368

2369 while (Tok.is(tok::l_paren))

2370 ConsumeParen();

2371

2373 return TPResult::Error;

2374

2375

2376

2378 if (Tok.is(tok::annot_cxxscope)) {

2381 SS);

2382 ConsumeAnnotationToken();

2383 }

2384

2385

2386

2387 if (Tok.is(tok::kw_operator))

2388 return TPResult::Ambiguous;

2389

2390

2391 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))

2392 return TPResult::True;

2395 : *takeTemplateIdAnnotation(Tok)->Name,

2397 return TPResult::True;

2398

2399

2400

2401

2402 if (NextToken().is(tok::r_paren) &&

2403 !isConstructorDeclarator(SS.isEmpty(),

2404 false))

2405 return TPResult::True;

2406

2407

2408 return TPResult::Ambiguous;

2409}

static constexpr bool isOneOf()

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.

NestedNameSpecifier * getScopeRep() const

Retrieve the representation of the nested-name-specifier.

bool isInvalid() const

An error occurred during parsing of the scope specifier.

bool isEmpty() const

No scope specifier.

Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...

virtual bool ValidateCandidate(const TypoCorrection &candidate)

Simple predicate used by the default RankCandidate to determine whether to return an edit distance of...

One of these records is kept for each identifier that is lexed.

bool hasRevertedTokenIDToIdentifier() const

True if revertTokenIDToIdentifier() was called.

This represents a decl that may have a name.

bool isDependent() const

Whether this nested name specifier refers to a dependent type or not.

ParsedAttributes - A collection of parsed attributes.

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

SourceLocation ConsumeToken()

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

bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext=false)

SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)

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

bool TryConsumeToken(tok::TokenKind Expected)

Scope * getCurScope() const

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

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

const LangOptions & getLangOpts() const

@ StopBeforeMatch

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

@ StopAtSemi

Stop skipping at semicolon.

bool TryAnnotateTypeOrScopeToken(ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)

TryAnnotateTypeOrScopeToken - If the current token position is on a typename (possibly qualified in C...

const Token & NextToken()

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

NameClassificationKind getKind() const

bool isCurrentClassName(const IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS=nullptr)

isCurrentClassName - Determine whether the identifier II is the name of the class type currently bein...

@ NC_VarTemplate

The name was classified as a variable template name.

@ NC_NonType

The name was classified as a specific non-type, non-template declaration.

@ NC_FunctionTemplate

The name was classified as a function template name.

@ NC_OverloadSet

The name was classified as an overload set, and an expression representing that overload set has been...

NameClassification ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name, SourceLocation NameLoc, const Token &NextToken, CorrectionCandidateCallback *CCC=nullptr)

Perform name lookup on the given name, classifying it based on the results of name lookup and the fol...

void RestoreNestedNameSpecifierAnnotation(void *Annotation, SourceRange AnnotationRange, CXXScopeSpec &SS)

Given an annotation pointer for a nested-name-specifier, restore the nested-name-specifier structure.

bool isDeductionGuideName(Scope *S, const IdentifierInfo &Name, SourceLocation NameLoc, CXXScopeSpec &SS, ParsedTemplateTy *Template=nullptr)

Determine whether a particular identifier might be the name in a C++1z deduction-guide declaration.

Encodes a location in the source.

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

IdentifierInfo * getIdentifierInfo() const

SourceLocation getLocation() const

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

bool is(tok::TokenKind K) const

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

void * getAnnotationValue() const

tok::TokenKind getKind() const

bool isRegularKeywordAttribute() const

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

SourceRange getAnnotationRange() const

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

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

bool isNot(tok::TokenKind K) const

bool hasUDSuffix() const

Return true if this token is a string or character literal which has a ud-suffix.

Simple class containing the result of Sema::CorrectTypo.

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

bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind)

@ TNK_Type_template

The name refers to a template whose specialization produces a type.

@ TNK_Concept_template

The name refers to a concept.

@ TNK_Undeclared_template

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

bool markNotForRangeDecl()

ConditionDeclarationOrInitStatementState(Parser &P, bool CanBeInitStatement, bool CanBeForRangeDecl)

bool update(TPResult IsDecl)

ConditionOrInitStatement result() const

Represents a complete lambda introducer.

Information about a template-id annotation token.

bool hasInvalidName() const

TemplateNameKind Kind

The kind of template that Template refers to.

unsigned NumArgs

NumArgs - The number of template arguments.