clang: lib/Sema/SemaTemplateVariadic.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

22#include "llvm/Support/SaveAndRestore.h"

23#include

24

25using namespace clang;

26

27

28

29

30

31namespace {

32

33class CollectUnexpandedParameterPacksVisitor

36

37 bool InLambdaOrBlock = false;

38 unsigned DepthLimit = (unsigned)-1;

39

40#ifndef NDEBUG

41 bool ContainsIntermediatePacks = false;

42#endif

43

45 if (auto *VD = dyn_cast(ND)) {

46

47

48

49 auto *FD = dyn_cast(VD->getDeclContext());

50 auto *FTD = FD ? FD->getDescribedFunctionTemplate() : nullptr;

51 if (FTD && FTD->getTemplateParameters()->getDepth() >= DepthLimit)

52 return;

54 return;

55

56 Unexpanded.push_back({ND, Loc});

57 }

60 if (T->getDepth() < DepthLimit)

61 Unexpanded.push_back({T, Loc});

62 }

63

64 public:

65 explicit CollectUnexpandedParameterPacksVisitor(

67 : Unexpanded(Unexpanded) {

68 ShouldWalkTypesOfTypeLocs = false;

69

70

71 ShouldVisitImplicitCode = true;

72 }

73

74

75

76

77

78

82 return true;

83 }

84

85

86

87

88

89

91 if (T->isParameterPack())

92 addUnexpanded(T);

93

94 return true;

95 }

96

97

98

99 bool VisitDeclRefExpr(DeclRefExpr *E) override {

100 if (E->getDecl()->isParameterPack())

101 addUnexpanded(E->getDecl(), E->getLocation());

102

103 return true;

104 }

105

106

108 if (auto *TTP = dyn_cast_or_null(

110 if (TTP->isParameterPack())

111 addUnexpanded(TTP);

112 }

113

114#ifndef NDEBUG

115 ContainsIntermediatePacks |=

117#endif

118

120 }

121

122

123

126 return true;

127

128 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {

130 if (Element.isPackExpansion())

131 continue;

132

135 }

136 return true;

137 }

138

139

140

141

142

143

145 Expr *E = dyn_cast_or_null(S);

148

149 return true;

150 }

151

152

153

156 InLambdaOrBlock)

158

159 return true;

160 }

161

162

163

167 InLambdaOrBlock)

169

170 return true;

171 }

172

173

175

176

177

179 return true;

180

182 }

183

184

187 return true;

188

190 }

191

192

193

195 return true;

196 }

198 return true;

199 }

201 return true;

202 }

203 bool TraverseCXXFoldExpr(CXXFoldExpr *E) override { return true; }

206 }

209 }

212 }

213

214

215

216

217 bool

219 if (D->isPackExpansion())

220 return true;

221

222 return DynamicRecursiveASTVisitor::TraverseUnresolvedUsingValueDecl(D);

223 }

224

225

226 bool TraverseUnresolvedUsingTypenameDecl(

228 if (D->isPackExpansion())

229 return true;

230

231 return DynamicRecursiveASTVisitor::TraverseUnresolvedUsingTypenameDecl(D);

232 }

233

234

237 return true;

238

240 }

241

242

243 bool

246 return true;

247

249 }

250

251

253 if (Base.isPackExpansion())

254 return true;

255

257 }

258

259

261 if (Init->isPackExpansion())

262 return true;

263

265 }

266

267

268

269

270

271

272 bool TraverseLambdaExpr(LambdaExpr *Lambda) override {

273

274

276 return true;

277

279 unsigned OldDepthLimit = DepthLimit;

280

282 DepthLimit = TPL->getDepth();

283

284 DynamicRecursiveASTVisitor::TraverseLambdaExpr(Lambda);

285

286 DepthLimit = OldDepthLimit;

287 return true;

288 }

289

290

292 if (Block->containsUnexpandedParameterPack())

293 return true;

294

296 DynamicRecursiveASTVisitor::TraverseBlockExpr(Block);

297 return true;

298 }

299

300

303 if (C->isPackExpansion())

304 return true;

305

307 }

308

309#ifndef NDEBUG

311 ContainsIntermediatePacks = true;

312 return true;

313 }

314

315 bool TraverseSubstNonTypeTemplateParmPackExpr(

317 ContainsIntermediatePacks = true;

318 return true;

319 }

320

321 bool VisitSubstTemplateTypeParmPackType(

323 ContainsIntermediatePacks = true;

324 return true;

325 }

326

327 bool VisitSubstTemplateTypeParmPackTypeLoc(

329 ContainsIntermediatePacks = true;

330 return true;

331 }

332

333 bool containsIntermediatePacks() const { return ContainsIntermediatePacks; }

334#endif

335};

336}

337

338

339

340

341

342

343

344

347 if (isasema::LambdaScopeInfo(SI))

348 return true;

349 return false;

350}

351

352

353

354bool

358 if (Unexpanded.empty())

359 return false;

360

361

362

363

364

365

368 for (auto &Pack : Unexpanded) {

369 auto DeclaresThisPack = [&](NamedDecl *LocalPack) {

371 auto *TTPD = dyn_cast(LocalPack);

372 return TTPD && TTPD->getTypeForDecl() == TTPT;

373 }

375 };

376 if (llvm::any_of(CSI->LocalPacks, DeclaresThisPack))

377 ParamPackReferences.push_back(Pack);

378 }

379

380 if (ParamPackReferences.empty()) {

381

382

383

384

385

386

387

388

389

390

391

392 bool EnclosingStmtExpr = false;

395 if (llvm::any_of(

396 Func->CompoundScopes,

398 EnclosingStmtExpr = true;

399 break;

400 }

401

402

403 if (Func == CSI)

404 break;

405 }

406

407 if (!EnclosingStmtExpr) {

408 CSI->ContainsUnexpandedParameterPack = true;

409 return false;

410 }

411 } else {

412 Unexpanded = ParamPackReferences;

413 }

414 }

415

419

420 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {

424 Name = TTP->getIdentifier();

425 else

426 Name = cast<NamedDecl *>(Unexpanded[I].first)->getIdentifier();

427

428 if (Name && NamesKnown.insert(Name).second)

429 Names.push_back(Name);

430

431 if (Unexpanded[I].second.isValid())

432 Locations.push_back(Unexpanded[I].second);

433 }

434

435 auto DB = Diag(Loc, diag::err_unexpanded_parameter_pack)

436 << (int)UPPC << (int)Names.size();

437 for (size_t I = 0, E = std::min(Names.size(), (size_t)2); I != E; ++I)

438 DB << Names[I];

439

440 for (unsigned I = 0, N = Locations.size(); I != N; ++I)

442 return true;

443}

444

448

449

450

452 return false;

453

455 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(

456 T->getTypeLoc());

457 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");

459}

460

463

464

465

467 return false;

468

470 CollectUnexpandedParameterPacksVisitor Visitor(Unexpanded);

471 Visitor.TraverseStmt(E);

472#ifndef NDEBUG

473

474

475

476

477

478 bool LambdaReferencingOuterPacks =

480 assert((!Unexpanded.empty() || LambdaReferencingOuterPacks) &&

481 "Unable to find unexpanded parameter packs");

482#endif

484}

485

488 return false;

489

491 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(RE);

492 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");

493

494

495

499 for (auto Parm : Unexpanded)

500 if (ParmSet.contains(Parm.first.dyn_cast<NamedDecl *>()))

501 UnexpandedParms.push_back(Parm);

502 if (UnexpandedParms.empty())

503 return false;

504

506 UnexpandedParms);

507}

508

511

512

513

516 return false;

517

519 CollectUnexpandedParameterPacksVisitor(Unexpanded)

520 .TraverseNestedNameSpecifier(SS.getScopeRep());

521 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");

523 UPPC, Unexpanded);

524}

525

528

529

530

540 return false;

541

545

548

550 return false;

551

552 break;

553 }

554

556 CollectUnexpandedParameterPacksVisitor(Unexpanded)

558 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");

560}

561

565

567 return false;

568

570 CollectUnexpandedParameterPacksVisitor(Unexpanded)

571 .TraverseTemplateName(Template);

572 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");

574}

575

580 return false;

581

583 CollectUnexpandedParameterPacksVisitor(Unexpanded)

584 .TraverseTemplateArgumentLoc(Arg);

585 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");

587}

588

591 CollectUnexpandedParameterPacksVisitor(Unexpanded)

592 .TraverseTemplateArgument(Arg);

593}

594

597 CollectUnexpandedParameterPacksVisitor(Unexpanded)

598 .TraverseTemplateArgumentLoc(Arg);

599}

600

603 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);

604}

605

608 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);

609}

610

614 CollectUnexpandedParameterPacksVisitor(Unexpanded)

615 .TraverseNestedNameSpecifierLoc(NNS);

616}

617

621 CollectUnexpandedParameterPacksVisitor(Unexpanded)

622 .TraverseDeclarationNameInfo(NameInfo);

623}

624

627 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);

628}

629

634 return Arg;

635

639 if (Result.isInvalid())

641

644 }

645

648 if (Result.isInvalid())

650

653 }

654

660 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)

661 << R;

663 }

664

666 }

667 llvm_unreachable("Unhandled template argument kind?");

668}

669

674 if (!TSInfo)

675 return true;

676

679 if (!TSResult)

680 return true;

681

683}

684

687 std::optional NumExpansions) {

688

691 EllipsisLoc, NumExpansions);

693 return nullptr;

694

699

701}

702

705 std::optional NumExpansions) {

706

707

708

709

710

711

712

715 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)

716 << PatternRange;

718 }

719

721 false);

722}

723

726}

727

729 std::optional NumExpansions) {

730 if (!Pattern)

732

733

734

735

736

738 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)

742 }

743

744

747}

748

753 bool &RetainExpansion, std::optional &NumExpansions) {

754 ShouldExpand = true;

755 RetainExpansion = false;

756 std::pair<IdentifierInfo *, SourceLocation> FirstPack;

757 bool HaveFirstPack = false;

758 std::optional NumPartialExpansions;

760

762

763 unsigned Depth = 0, Index = 0;

765 bool IsVarDeclPack = false;

766

769 Depth = TTP->getDepth();

770 Index = TTP->getIndex();

771 Name = TTP->getIdentifier();

772 } else {

773 NamedDecl *ND = cast<NamedDecl *>(ParmPack.first);

774 if (isa(ND))

775 IsVarDeclPack = true;

776 else

778

780 }

781

782

783 unsigned NewPackSize, PendingPackExpansionSize = 0;

784 if (IsVarDeclPack) {

785

787

788 llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =

790 cast<NamedDecl *>(ParmPack.first));

791 if (isa<DeclArgumentPack *>(*Instantiation)) {

792

793 NewPackSize = cast<DeclArgumentPack *>(*Instantiation)->size();

794 } else {

795

796

797 ShouldExpand = false;

798 continue;

799 }

800 } else {

801

802

803

806 ShouldExpand = false;

807 continue;

808 }

809

810

812 TemplateArgs(Depth, Index).getPackAsArray();

813 NewPackSize = Pack.size();

814 PendingPackExpansionSize =

817 return false;

818

823

825 return !cast(TA.getAsExpr())

826 ->getNumExpansions();

827

829 });

830 }

831

832

833

834

835

839 unsigned PartialDepth, PartialIndex;

840 std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);

841 if (PartialDepth == Depth && PartialIndex == Index) {

842 RetainExpansion = true;

843

844 NumPartialExpansions = NewPackSize;

845 PartiallySubstitutedPackLoc = ParmPack.second;

846 continue;

847 }

848 }

849 }

850

851 if (!NumExpansions) {

852

853

854 NumExpansions = NewPackSize;

855 FirstPack.first = Name;

856 FirstPack.second = ParmPack.second;

857 HaveFirstPack = true;

858 continue;

859 }

860

861 if (NewPackSize != *NumExpansions) {

862

863

864

865

866

867

868

869

870

871

872

873

874

875

876

877

878

879

880

881

882

883 unsigned LeastNewPackSize = NewPackSize - PendingPackExpansionSize;

884 if (PendingPackExpansionSize && LeastNewPackSize <= *NumExpansions) {

885 ShouldExpand = false;

886 continue;

887 }

888

889

890

891 if (HaveFirstPack)

892 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)

893 << FirstPack.first << Name << *NumExpansions

894 << (LeastNewPackSize != NewPackSize) << LeastNewPackSize

896 else

897 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)

898 << Name << *NumExpansions << (LeastNewPackSize != NewPackSize)

899 << LeastNewPackSize << SourceRange(ParmPack.second);

900 return true;

901 }

902 }

903

904

905

906

907

908

909

910

911

912

913 if (NumPartialExpansions) {

914 if (NumExpansions && *NumExpansions < *NumPartialExpansions) {

917 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_partial)

918 << PartialPack << *NumPartialExpansions << *NumExpansions

919 << SourceRange(PartiallySubstitutedPackLoc);

920 return true;

921 }

922

923 NumExpansions = NumPartialExpansions;

924 }

925

926 return false;

927}

928

932 std::optional Result;

933 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {

934

935 unsigned Depth;

936 unsigned Index;

937

940 Depth = TTP->getDepth();

941 Index = TTP->getIndex();

942 } else {

943 NamedDecl *ND = cast<NamedDecl *>(Unexpanded[I].first);

944 if (isa(ND)) {

945

947

948 llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =

950 cast<NamedDecl *>(Unexpanded[I].first));

951 if (isa<Decl *>(*Instantiation))

952

953

954 return std::nullopt;

955

956 unsigned Size = cast<DeclArgumentPack *>(*Instantiation)->size();

957 assert((Result || *Result == Size) && "inconsistent pack sizes");

959 continue;

960 }

961

963 }

966

967

968 return std::nullopt;

969

970

971 unsigned Size = TemplateArgs(Depth, Index).pack_size();

972 assert((Result || *Result == Size) && "inconsistent pack sizes");

974 }

975

977}

978

981 QualType Pattern = cast(T)->getPattern();

983 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern);

985}

986

988 const DeclSpec &DS = D.getDeclSpec();

994#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait:

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

999 return true;

1000 break;

1001 }

1002

1009 return true;

1010 break;

1011

1042#define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t:

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

1044#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case TST_##Name:

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

1048 break;

1049 }

1050

1051 for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {

1053 switch (Chunk.Kind) {

1059

1060 break;

1061

1065 return true;

1066 break;

1068 for (unsigned i = 0, e = Chunk.Fun.NumParams; i != e; ++i) {

1071 assert(!ParamTy.isNull() && "Couldn't parse type?");

1073 }

1074

1080 return true;

1081 }

1084 return true;

1085

1089 return true;

1090 }

1091 break;

1092

1096 return true;

1097 break;

1098 }

1099 }

1100

1101 if (Expr *TRC = D.getTrailingRequiresClause())

1102 if (TRC->containsUnexpandedParameterPack())

1103 return true;

1104

1105 return false;

1106}

1107

1108namespace {

1109

1110

1112 public:

1113 bool ValidateCandidate(const TypoCorrection &candidate) override {

1116 }

1117

1118 std::unique_ptr clone() override {

1119 return std::make_unique(*this);

1120 }

1121};

1122

1123}

1124

1130

1131

1134

1135 NamedDecl *ParameterPack = nullptr;

1139 break;

1140

1143 ParameterPackValidatorCCC CCC{};

1148 PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name,

1149 PDiag(diag::note_parameter_pack_here));

1150 ParameterPack = Corrected.getCorrectionDecl();

1151 }

1152 break;

1153 }

1156 break;

1157

1161 }

1162

1163 if (!ParameterPack || !ParameterPack->isParameterPack()) {

1164 Diag(NameLoc, diag::err_expected_name_of_pack) << &Name;

1166 }

1167

1169

1171 RParenLoc);

1172}

1173

1175 if (auto *D = dyn_cast(PackExpression); D) {

1178 }

1179 return false;

1180}

1181

1185 Expr *IndexExpr,

1191 Diag(PackExpression->getBeginLoc(), diag::err_expected_name_of_pack)

1192 << PackExpression;

1193 }

1195 }

1200 ? diag::warn_cxx23_pack_indexing

1201 : diag::ext_pack_indexing);

1202 return Res;

1203}

1204

1207 Expr *IndexExpr,

1210 bool FullySubstituted) {

1211

1212 std::optional<int64_t> Index;

1215

1220 Index = Value.getExtValue();

1221 IndexExpr = Res.get();

1222 }

1223

1224 if (Index && FullySubstituted) {

1225 if (*Index < 0 || *Index >= int64_t(ExpandedExprs.size())) {

1226 Diag(PackExpression->getBeginLoc(), diag::err_pack_index_out_of_bound)

1227 << *Index << PackExpression << ExpandedExprs.size();

1229 }

1230 }

1231

1233 PackExpression, IndexExpr, Index,

1234 ExpandedExprs, FullySubstituted);

1235}

1236

1239 std::optional &NumExpansions) const {

1242 switch (Argument.getKind()) {

1244

1245

1247 if (!ExpansionTSInfo)

1249 Ellipsis);

1253

1256

1257

1258

1259

1265 PatternTSInfo);

1266 }

1267

1270 = cast(Argument.getAsExpr());

1275 }

1276

1283

1292 }

1293

1294 llvm_unreachable("Invalid TemplateArgument Kind!");

1295}

1296

1299

1300

1301

1302

1303

1304

1306 switch (Arg.getKind()) {

1309 Pack = Subst->getArgumentPack();

1310 else

1311 return std::nullopt;

1312 break;

1313

1315 if (auto *Subst =

1316 dyn_cast(Arg.getAsExpr()))

1317 Pack = Subst->getArgumentPack();

1318 else if (auto *Subst = dyn_cast(Arg.getAsExpr())) {

1319 for (VarDecl *PD : *Subst)

1320 if (PD->isParameterPack())

1321 return std::nullopt;

1322 return Subst->getNumExpansions();

1323 } else

1324 return std::nullopt;

1325 break;

1326

1330 Pack = Subst->getArgumentPack();

1331 else

1332 return std::nullopt;

1333 break;

1334

1342 return std::nullopt;

1343 }

1344

1345

1347

1348

1349 if (Elem.isPackExpansion())

1350 return std::nullopt;

1351

1352

1353

1354

1355

1356

1357

1358

1359

1360 if (Elem.containsUnexpandedParameterPack())

1361 return std::nullopt;

1362 }

1364}

1365

1367 if (E)

1368 return;

1369

1371 auto *OCE = dyn_cast(E);

1372 if ((OCE && OCE->isInfixBinaryOp()) || isa(E) ||

1373 isa(E)) {

1374 S.Diag(E->getExprLoc(), diag::err_fold_expression_bad_operand)

1378 }

1379}

1380

1385

1386

1389

1390 auto DiscardOperands = [&] {

1393 };

1394

1395

1396

1397

1398

1399 if (LHS && RHS &&

1402 DiscardOperands();

1403 return Diag(EllipsisLoc,

1405 ? diag::err_fold_expression_packs_both_sides

1406 : diag::err_pack_expansion_without_parameter_packs)

1408 }

1409

1410

1411

1412

1413 if (!LHS || !RHS) {

1414 Expr *Pack = LHS ? LHS : RHS;

1415 assert(Pack && "fold expression with neither LHS nor RHS");

1417 DiscardOperands();

1418 return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)

1420 }

1421 }

1422

1424

1425

1427 {

1429 LookupBinOp(S, EllipsisLoc, Opc, Functions);

1430 if (!Functions.empty()) {

1436 if (Callee.isInvalid())

1438 ULE = cast(Callee.get());

1439 }

1440 }

1441

1442 return BuildCXXFoldExpr(ULE, LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc,

1443 std::nullopt);

1444}

1445

1451 std::optional NumExpansions) {

1454 EllipsisLoc, RHS, RParenLoc, NumExpansions);

1455}

1456

1459

1460

1461

1462

1463

1464

1465

1466

1467

1469 switch (Operator) {

1470 case BO_LOr:

1472 case BO_LAnd:

1474 case BO_Comma:

1476 break;

1477

1478 default:

1479 return Diag(EllipsisLoc, diag::err_fold_expression_empty)

1481 }

1482

1485 EllipsisLoc);

1486}

static void CheckFoldOperand(Sema &S, Expr *E)

static bool isParameterPack(Expr *PackExpression)

Defines the clang::TypeLoc interface and its subclasses.

unsigned getIntWidth(QualType T) const

DeclarationNameTable DeclarationNames

TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const

Allocate a TypeSourceInfo where all locations have been initialized to a given location,...

CanQualType getSizeType() const

Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.

QualType getPackExpansionType(QualType Pattern, std::optional< unsigned > NumExpansions, bool ExpectPackInType=true) const

Form a pack expansion type with the given pattern.

The result of parsing/analyzing an expression, statement etc.

Attr - This represents one attribute.

bool isPackExpansion() const

static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)

Retrieve the overloaded operator kind that corresponds to the given binary opcode.

StringRef getOpcodeStr() const

BlockExpr - Adaptor class for mixing a BlockDecl with expressions.

Represents a base class of a C++ class.

Represents a C++ base or member initializer.

Represents a folding of a pack over an operator.

An expression "T()" which creates an rvalue of a non-class type T.

Represents a C++ nested-name-specifier or a global scope specifier.

bool isValid() const

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

SourceRange getRange() const

SourceLocation getBeginLoc() const

NestedNameSpecifier * getScopeRep() const

Retrieve the representation of the nested-name-specifier.

const TypeClass * getTypePtr() const

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

A reference to a declared variable, function, enum, etc.

Captures information about "declaration specifiers".

TST getTypeSpecType() const

ParsedType getRepAsType() const

Expr * getRepAsExpr() const

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

bool isParameterPack() const

Whether this declaration is a parameter pack.

The name of a declaration.

@ CXXConversionFunctionName

QualType getCXXNameType() const

If this name is one of the C++ names (of a constructor, destructor, or conversion function),...

NameKind getNameKind() const

Determine what kind of name this is.

Information about one declarator, including the parsed type information and the identifier.

Recursive AST visitor that supports extension via dynamic dispatch.

virtual bool TraverseDecl(Decl *D)

Recursively visit a declaration, by dispatching to Traverse*Decl() based on the argument's dynamic ty...

virtual bool TraverseTypeLoc(TypeLoc TL)

Recursively visit a type with location, by dispatching to Traverse*TypeLoc() based on the argument ty...

virtual bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C, Expr *Init)

Recursively visit a lambda capture.

virtual bool TraverseAttr(Attr *At)

Recursively visit an attribute, by dispatching to Traverse*Attr() based on the argument's dynamic typ...

virtual bool TraverseStmt(Stmt *S)

Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...

virtual bool TraverseTemplateArgument(const TemplateArgument &Arg)

Recursively visit a template argument and dispatch to the appropriate method for the argument type.

virtual bool TraverseConstructorInitializer(CXXCtorInitializer *Init)

Recursively visit a constructor initializer.

virtual bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc)

Recursively visit a template argument location and dispatch to the appropriate method for the argumen...

virtual bool TraverseType(QualType T)

Recursively visit a type, by dispatching to Traverse*Type() based on the argument's getTypeClass() pr...

virtual bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base)

Recursively visit a base specifier.

virtual bool TraverseTemplateName(TemplateName Template)

Recursively visit a template name and dispatch to the appropriate method.

This represents one expression.

bool containsUnexpandedParameterPack() const

Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).

bool containsErrors() const

Whether this expression contains subexpressions which had errors, e.g.

bool isInstantiationDependent() const

Whether this expression is instantiation-dependent, meaning that it depends in some way on.

Expr * IgnoreImpCasts() LLVM_READONLY

Skip past any implicit casts which might surround this expression until reaching a fixed point.

SourceLocation getExprLoc() const LLVM_READONLY

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

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.

Represents a reference to a function parameter pack or init-capture pack that has been substituted bu...

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

const TypeClass * getTypePtr() const

Describes the capture of a variable or of this, or of a C++1y init-capture.

A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...

TemplateParameterList * getTemplateParameterList() const

If this is a generic lambda expression, retrieve the template parameter list associated with it,...

NamedDecl * getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs=nullptr, unsigned *NumExplicitArgs=nullptr) const

Retrieve the partially-substitued template parameter pack.

llvm::PointerUnion< Decl *, DeclArgumentPack * > * findInstantiationOf(const Decl *D)

Find the instantiation of the declaration D within the current instantiation scope.

Represents the results of name lookup.

@ FoundOverloaded

Name lookup found a set of overloaded functions that met the criteria.

@ FoundUnresolvedValue

Name lookup found an unresolvable value declaration and cannot yet complete.

@ Ambiguous

Name lookup results in an ambiguity; use getAmbiguityKind to figure out what kind of ambiguity we hav...

@ NotFound

No entity found met the criteria.

@ NotFoundInCurrentInstantiation

No entity found met the criteria within the current instantiation,, but there were dependent base cla...

@ Found

Name lookup found a single declaration that met the criteria.

NamedDecl * getFoundDecl() const

Fetch the unique decl found by this lookup.

Sema::LookupNameKind getLookupKind() const

Gets the kind of lookup to perform.

LookupResultKind getResultKind() const

const DeclarationNameInfo & getLookupNameInfo() const

Gets the name info to look up.

Data structure that captures multiple levels of template argument lists for use in template instantia...

bool hasTemplateArgument(unsigned Depth, unsigned Index) const

Determine whether there is a non-NULL template argument at the given depth and index.

unsigned getNumLevels() const

Determine the number of levels in this template argument list.

This represents a decl that may have a name.

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

A C++ nested-name-specifier augmented with source location information.

bool containsUnexpandedParameterPack() const

Whether this nested-name-specifier contains an unexpanded parameter pack (for C++11 variadic template...

ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...

Represents a C++11 pack expansion that produces a sequence of expressions.

Expr * getPattern()

Retrieve the pattern of the pack expansion.

std::optional< unsigned > getNumExpansions() const

Determine the number of expansions that will be produced when this pack expansion is instantiated,...

SourceLocation getEllipsisLoc() const

Retrieve the location of the ellipsis that describes this pack expansion.

void setEllipsisLoc(SourceLocation Loc)

SourceLocation getEllipsisLoc() const

TypeLoc getPatternLoc() const

Represents a pack expansion of types.

std::optional< unsigned > getNumExpansions() const

Retrieve the number of expansions that this pack expansion will generate, if known.

static PackIndexingExpr * Create(ASTContext &Context, SourceLocation EllipsisLoc, SourceLocation RSquareLoc, Expr *PackIdExpr, Expr *IndexExpr, std::optional< int64_t > Index, ArrayRef< Expr * > SubstitutedExprs={}, bool FullySubstituted=false)

Expr * getIndexExpr() const

Represents a parameter to a function.

Represents the parsed form of a C++ template argument.

KindType getKind() const

Determine what kind of template argument we have.

SourceLocation getLocation() const

Retrieve the location of the template argument.

ParsedTemplateTy getAsTemplate() const

Retrieve the template template argument's template name.

ParsedTemplateArgument getTemplatePackExpansion(SourceLocation EllipsisLoc) const

Retrieve a pack expansion of the given template template argument.

ParsedType getAsType() const

Retrieve the template type argument's type.

@ Type

A template type parameter, stored as a type.

@ Template

A template template argument, stored as a template name.

@ NonType

A non-type template parameter, stored as an expression.

bool isInvalid() const

Determine whether the given template argument is invalid.

Expr * getAsExpr() const

Retrieve the non-type template argument's expression.

const CXXScopeSpec & getScopeSpec() const

Retrieve the nested-name-specifier that precedes the template name in a template template argument.

A (possibly-)qualified type.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...

SourceLocation getBeginLoc() const LLVM_READONLY

ArrayRef< ParmVarDecl * > getLocalParameters() const

Scope - A scope is a transient data structure that is used while parsing the program.

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)

Emit a diagnostic.

PartialDiagnostic PDiag(unsigned DiagID=0)

Build a partial diagnostic.

Sema - This implements semantic analysis and AST building for C.

ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)

Package the given type and TSI into a ParsedType.

LocalInstantiationScope * CurrentInstantiationScope

The current instantiation scope used to store local variables.

sema::CapturingScopeInfo * getEnclosingLambdaOrBlock() const

Get the innermost lambda or block enclosing the current location, if any.

bool containsUnexpandedParameterPacks(Declarator &D)

Determine whether the given declarator contains any unexpanded parameter packs.

bool CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, SourceRange PatternRange, ArrayRef< UnexpandedParameterPack > Unexpanded, const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand, bool &RetainExpansion, std::optional< unsigned > &NumExpansions)

Determine whether we could expand a pack expansion with the given set of parameter packs into separat...

@ LookupOrdinaryName

Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....

SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes

Stack containing information about each of the nested function, block, and method scopes that are cur...

TypeSourceInfo * CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, std::optional< unsigned > NumExpansions)

Construct a pack expansion type from the pattern of the pack expansion.

ExprResult BuildPackIndexingExpr(Expr *PackExpression, SourceLocation EllipsisLoc, Expr *IndexExpr, SourceLocation RSquareLoc, ArrayRef< Expr * > ExpandedExprs={}, bool FullySubstituted=false)

ASTContext & getASTContext() const

bool DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE)

If the given requirees-expression contains an unexpanded reference to one of its own parameter packs,...

void LookupBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, UnresolvedSetImpl &Functions)

TemplateArgumentLoc getTemplateArgumentPackExpansionPattern(TemplateArgumentLoc OrigLoc, SourceLocation &Ellipsis, std::optional< unsigned > &NumExpansions) const

Returns the pattern of the pack expansion for a template argument.

ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, llvm::APSInt &Value, CCEKind CCE)

std::optional< unsigned > getNumArgumentsInExpansionFromUnexpanded(llvm::ArrayRef< UnexpandedParameterPack > Unexpanded, const MultiLevelTemplateArgumentList &TemplateArgs)

UnexpandedParameterPackContext

The context in which an unexpanded parameter pack is being diagnosed.

const LangOptions & getLangOpts() const

TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)

Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...

bool isUnexpandedParameterPackPermitted()

Determine whether an unexpanded parameter pack might be permitted in this location.

ExprResult BuildCXXFoldExpr(UnresolvedLookupExpr *Callee, SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Operator, SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc, std::optional< unsigned > NumExpansions)

void collectUnexpandedParameterPacks(TemplateArgument Arg, SmallVectorImpl< UnexpandedParameterPack > &Unexpanded)

Collect the set of unexpanded parameter packs within the given template argument.

bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, UnexpandedParameterPackContext UPPC)

If the given type contains an unexpanded parameter pack, diagnose the error.

ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind)

ActOnCXXBoolLiteral - Parse {true,false} literals.

void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse)

Perform marking for a reference to an arbitrary declaration.

std::optional< unsigned > getNumArgumentsInExpansion(QualType T, const MultiLevelTemplateArgumentList &TemplateArgs)

Determine the number of arguments in the given pack expansion type.

std::optional< unsigned > getFullyPackExpandedSize(TemplateArgument Arg)

Given a template argument that contains an unexpanded parameter pack, but which has already been subs...

ExprResult ActOnPackIndexingExpr(Scope *S, Expr *PackExpression, SourceLocation EllipsisLoc, SourceLocation LSquareLoc, Expr *IndexExpr, SourceLocation RSquareLoc)

ExprResult CreateUnresolvedLookupExpr(CXXRecordDecl *NamingClass, NestedNameSpecifierLoc NNSLoc, DeclarationNameInfo DNI, const UnresolvedSetImpl &Fns, bool PerformADL=true)

ParsedTemplateArgument ActOnPackExpansion(const ParsedTemplateArgument &Arg, SourceLocation EllipsisLoc)

Invoked when parsing a template argument followed by an ellipsis, which creates a pack expansion.

@ CCEK_ArrayBound

Array bound in array declarator or new-expression.

void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)

void DiagnoseAmbiguousLookup(LookupResult &Result)

Produce a diagnostic describing the ambiguity that resulted from name lookup.

ExprResult ActOnSizeofParameterPackExpr(Scope *S, SourceLocation OpLoc, IdentifierInfo &Name, SourceLocation NameLoc, SourceLocation RParenLoc)

Called when an expression computing the size of a parameter pack is parsed.

ExprResult BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, BinaryOperatorKind Operator)

ExprResult ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS, tok::TokenKind Operator, SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc)

Handle a C++1z fold-expression: ( expr op ... op expr ).

bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)

Perform unqualified name lookup starting from a given scope.

static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)

bool DiagnoseUnexpandedParameterPacks(SourceLocation Loc, UnexpandedParameterPackContext UPPC, ArrayRef< UnexpandedParameterPack > Unexpanded)

Diagnose unexpanded parameter packs.

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

static SizeOfPackExpr * Create(ASTContext &Context, SourceLocation OperatorLoc, NamedDecl *Pack, SourceLocation PackLoc, SourceLocation RParenLoc, std::optional< unsigned > Length=std::nullopt, ArrayRef< TemplateArgument > PartialArgs={})

Encodes a location in the source.

A trivial tuple used to represent a source range.

void setBegin(SourceLocation b)

SourceLocation getBegin() const

Stmt - This represents one statement.

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

Represents a reference to a non-type template parameter pack that has been substituted with a non-tem...

A structure for storing an already-substituted template template parameter pack.

Wrapper for substituted template type parameters.

Represents the result of substituting a set of types for a template type parameter pack.

Location wrapper for a TemplateArgument.

SourceLocation getLocation() const

SourceLocation getTemplateEllipsisLoc() const

const TemplateArgument & getArgument() const

SourceLocation getTemplateNameLoc() const

TypeSourceInfo * getTypeSourceInfo() const

NestedNameSpecifierLoc getTemplateQualifierLoc() const

Represents a template argument.

Expr * getAsExpr() const

Retrieve the template argument as an expression.

std::optional< unsigned > getNumTemplateExpansions() const

Retrieve the number of expansions that a template template argument expansion will produce,...

QualType getAsType() const

Retrieve the type for a type template argument.

TemplateName getAsTemplate() const

Retrieve the template name for a template name argument.

bool containsUnexpandedParameterPack() const

Whether this template argument contains an unexpanded parameter pack.

TemplateArgument getPackExpansionPattern() const

When the template argument is a pack expansion, returns the pattern of the pack expansion.

bool isNull() const

Determine whether this template argument has no value.

unsigned pack_size() const

The number of template arguments in the given template argument pack.

ArrayRef< TemplateArgument > pack_elements() const

Iterator range referencing all of the elements of a template argument pack.

@ Declaration

The template argument is a declaration that was provided for a pointer, reference,...

@ Template

The template argument is a template name that was provided for a template template parameter.

@ StructuralValue

The template argument is a non-type template argument that can't be represented by the special-case D...

@ Pack

The template argument is actually a parameter pack.

@ TemplateExpansion

The template argument is a pack expansion of a template name that was provided for a template templat...

@ NullPtr

The template argument is a null pointer or null pointer to member that was provided for a non-type te...

@ Type

The template argument is a type.

@ Null

Represents an empty template argument, e.g., one that has not been deduced.

@ Integral

The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...

@ Expression

The template argument is an expression, and we've not resolved it to one of the other forms yet,...

ArgKind getKind() const

Return the kind of stored template argument.

bool isPackExpansion() const

Determine whether this template argument is a pack expansion.

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

TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const

Retrieve the underlying template declaration that this template name refers to, if known.

bool isNull() const

Determine whether this template name is NULL.

bool containsUnexpandedParameterPack() const

Determines whether this template name contains an unexpanded parameter pack (for C++0x variadic templ...

SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack() const

Retrieve the substituted template template parameter pack, if known.

Wrapper for template type parameters.

bool isParameterPack() const

TyLocType push(QualType T)

Pushes space for a new TypeLoc of the given type.

void pushFullCopy(TypeLoc L)

Pushes a copy of the given TypeLoc onto this builder.

TypeSourceInfo * getTypeSourceInfo(ASTContext &Context, QualType T)

Creates a TypeSourceInfo for the given type.

Base wrapper for a particular "section" of type source info.

QualType getType() const

Get the type for which this source info wrapper provides information.

T castAs() const

Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type.

SourceRange getSourceRange() const LLVM_READONLY

Get the full source range.

A container of type source information.

TypeLoc getTypeLoc() const

Return the TypeLoc wrapper for the type source info.

QualType getType() const

Return the type wrapped by this type source info.

SourceLocation getNameLoc() const

The base class of the type hierarchy.

DeducedType * getContainedDeducedType() const

Get the DeducedType whose type will be deduced for a variable with an initializer of this type.

bool containsUnexpandedParameterPack() const

Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...

const T * getAs() const

Member-template getAs'.

Simple class containing the result of Sema::CorrectTypo.

NamedDecl * getCorrectionDecl() const

Gets the pointer to the declaration of the typo correction.

A reference to a name which we were able to look up during parsing but could not resolve to a specifi...

A set of unresolved declarations.

Represents a dependent using declaration which was marked with typename.

Represents a dependent using declaration which was not marked with typename.

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

Represents a variable declaration or definition.

Contains information about the compound statement currently being parsed.

Retains information about a function, method, or block that is currently being parsed.

TokenKind

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

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

@ TST_typename_pack_indexing

if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))

@ Result

The result type of a method or function.

std::pair< unsigned, unsigned > getDepthAndIndex(const NamedDecl *ND)

Retrieve the depth and index of a template parameter.

bool isComputedNoexcept(ExceptionSpecificationType ESpecType)

const FunctionProtoType * T

bool declaresSameEntity(const Decl *D1, const Decl *D2)

Determine whether two declarations declare the same entity.

std::pair< llvm::PointerUnion< const TemplateTypeParmType *, NamedDecl * >, SourceLocation > UnexpandedParameterPack

@ EST_Dynamic

throw(T1, T2)

DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...

SourceLocation getLoc() const

getLoc - Returns the main location of the declaration name.

DeclarationName getName() const

getName - Returns the embedded declaration name.

TypeSourceInfo * getNamedTypeInfo() const

getNamedTypeInfo - Returns the source type info associated to the name.

Expr * NumElts

This is the size of the array, or null if [] or [*] was specified.

bool hasTrailingReturnType() const

Determine whether this function declarator had a trailing-return-type.

TypeAndRange * Exceptions

Pointer to a new[]'d array of TypeAndRange objects that contain the types in the function's dynamic e...

ParamInfo * Params

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

ParsedType getTrailingReturnType() const

Get the trailing-return-type for this function declarator.

unsigned NumParams

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

unsigned getNumExceptions() const

Get the number of dynamic exception specifications.

ExceptionSpecificationType getExceptionSpecType() const

Get the type of exception specification this function has.

Expr * NoexceptExpr

Pointer to the expression in the noexcept-specifier of this function, if it has one.

One instance of this struct is used for each type in a declarator that is parsed.

enum clang::DeclaratorChunk::@225 Kind

MemberPointerTypeInfo Mem

An element in an Objective-C dictionary literal.