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

1

2

3

4

5

6

7

8

9

10

11

12

13

44#include "llvm/ADT/ArrayRef.h"

45#include "llvm/ADT/STLExtras.h"

46#include "llvm/ADT/SmallVector.h"

47#include "llvm/Support/Casting.h"

48#include "llvm/Support/ErrorHandling.h"

49#include

50#include

51#include

52

53using namespace clang;

54using namespace sema;

55

56namespace {

57

58

59static bool HaveSameAssociatedConstraints(

62 if (OldACs.size() != NewACs.size())

63 return false;

64 if (OldACs.empty())

65 return true;

66

67

69 for (size_t I = 0, E = OldACs.size(); I != E; ++I)

71 Old, OldACs[I].ConstraintExpr, NewInfo, NewACs[I].ConstraintExpr))

72 return false;

73

74 return true;

75}

76

77

78

79class ExtractTypeForDeductionGuide

80 : public TreeTransform {

81 llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs;

82 ClassTemplateDecl *NestedPattern;

83 const MultiLevelTemplateArgumentList *OuterInstantiationArgs;

84 std::optional TypedefNameInstantiator;

85

86public:

87 typedef TreeTransform Base;

88 ExtractTypeForDeductionGuide(

89 Sema &SemaRef,

90 llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs,

91 ClassTemplateDecl *NestedPattern = nullptr,

92 const MultiLevelTemplateArgumentList *OuterInstantiationArgs = nullptr)

93 : Base(SemaRef), MaterializedTypedefs(MaterializedTypedefs),

94 NestedPattern(NestedPattern),

95 OuterInstantiationArgs(OuterInstantiationArgs) {

96 if (OuterInstantiationArgs)

97 TypedefNameInstantiator.emplace(

99 *OuterInstantiationArgs);

100 }

101

102 TypeSourceInfo *transform(TypeSourceInfo *TSI) { return TransformType(TSI); }

103

104

105

106 bool mightReferToOuterTemplateParameters(TypedefNameDecl *Typedef) {

107 if (!NestedPattern)

108 return false;

109

110 static auto WalkUp = [](DeclContext *DC, DeclContext *TargetDC) {

111 if (DC->Equals(TargetDC))

112 return true;

114 if (DC->Equals(TargetDC))

115 return true;

117 }

118 return false;

119 };

120

121 if (WalkUp(Typedef->getDeclContext(), NestedPattern->getTemplatedDecl()))

122 return true;

123 if (WalkUp(NestedPattern->getTemplatedDecl(), Typedef->getDeclContext()))

124 return true;

125 return false;

126 }

127

128 QualType RebuildTemplateSpecializationType(

130 SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {

131 if (!OuterInstantiationArgs ||

132 !isa_and_present(Template.getAsTemplateDecl()))

135

137 auto *Pattern = TATD;

138 while (Pattern->getInstantiatedFromMemberTemplate())

139 Pattern = Pattern->getInstantiatedFromMemberTemplate();

140 if (!mightReferToOuterTemplateParameters(Pattern->getTemplatedDecl()))

143

145 TypedefNameInstantiator->InstantiateTypeAliasTemplateDecl(TATD);

146 if (!NewD)

147 return QualType();

148

150 MaterializedTypedefs.push_back(NewTATD->getTemplatedDecl());

151

154 }

155

156 QualType TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) {

158 TypedefNameDecl *OrigDecl = TL.getDecl();

159 TypedefNameDecl *Decl = OrigDecl;

161

162

164

165

166

167

168

169

170

171

172

173

174

175

176

177 if (OuterInstantiationArgs && InDependentContext &&

179 Decl = cast_if_present(

180 TypedefNameInstantiator->InstantiateTypedefNameDecl(

182 if (!Decl)

183 return QualType();

184 MaterializedTypedefs.push_back(Decl);

185 } else if (InDependentContext) {

186 TypeLocBuilder InnerTLB;

187 QualType Transformed =

189 TypeSourceInfo *TSI = InnerTLB.getTypeSourceInfo(Context, Transformed);

194 else {

195 assert(isa(OrigDecl) && "Not a Type alias or typedef");

199 }

200 MaterializedTypedefs.push_back(Decl);

201 }

202

203 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();

204 if (QualifierLoc) {

205 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);

206 if (!QualifierLoc)

207 return QualType();

208 }

209

214 return TDTy;

215 }

216};

217

218

219

220

221

222

224buildDeductionGuide(Sema &SemaRef, TemplateDecl *OriginalTemplate,

232 auto DeductionGuideName =

234 OriginalTemplate);

235

239

240

242

243

244

245 if (IsImplicit && Ctor && SemaRef.getLangOpts().CUDA) {

248

249 for (NamedDecl *Existing : DC->lookup(DeductionGuideName)) {

250 auto *ExistingFT = dyn_cast(Existing);

251 auto *ExistingGuide =

252 ExistingFT

253 ? dyn_cast(ExistingFT->getTemplatedDecl())

255 if (!ExistingGuide)

256 continue;

257

258

260 if (!ExistingCtor)

261 continue;

262

263

264

265 if (SemaRef.IsOverload(Ctor, ExistingCtor,

266 false,

267 false))

268 continue;

269

270

271

272

273

275 ExistingCtor->getAssociatedConstraints(ExistingACs);

276

277 if (HaveSameAssociatedConstraints(SemaRef, ExistingCtor, ExistingACs,

278 Ctor, NewACs))

279 return Existing;

280 }

281 }

282

284 SemaRef.Context, DC, LocStart, ES, Name, GuideType, TInfo, LocEnd, Ctor,

286 Guide->setImplicit(IsImplicit);

287 Guide->setParams(Params);

288

289 for (auto *Param : Params)

290 Param->setDeclContext(Guide);

291 for (auto *TD : MaterializedTypedefs)

292 TD->setDeclContext(Guide);

295

296 if (!TemplateParams) {

298 return Guide;

299 }

300

302 SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide);

303 GuideTemplate->setImplicit(IsImplicit);

304 Guide->setDescribedFunctionTemplate(GuideTemplate);

305

307 GuideTemplate->setAccess(AS_public);

308

309 DC->addDecl(GuideTemplate);

310 return GuideTemplate;

311}

312

313

317 bool EvaluateConstraint) {

318

319

327 EvaluateConstraint);

333 NewTTP->setDefaultArgument(SemaRef.Context, InstantiatedDefaultArg);

334 }

336 return NewTTP;

337}

338

339template

340NonTypeTemplateOrTemplateTemplateParmDecl *

342 NonTypeTemplateOrTemplateTemplateParmDecl *OldParam,

344 unsigned NewDepth) {

345

346

348 SemaRef.SubstDecl(OldParam, DC, Args));

349 NewParam->setPosition(NewIndex);

350 NewParam->setDepth(NewDepth);

351 return NewParam;

352}

353

357 unsigned NewIndex, unsigned NewDepth,

358 bool EvaluateConstraint = true) {

359 if (auto *TTP = dyn_cast(TemplateParam))

360 return transformTemplateTypeParam(

361 SemaRef, DC, TTP, Args, NewDepth, NewIndex,

362 EvaluateConstraint);

363 if (auto *TTP = dyn_cast(TemplateParam))

364 return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex, NewDepth);

365 if (auto *NTTP = dyn_cast(TemplateParam))

366 return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex, NewDepth);

367 llvm_unreachable("Unhandled template parameter types");

368}

369

370

371

372struct ConvertConstructorToDeductionGuideTransform {

373 ConvertConstructorToDeductionGuideTransform(Sema &S,

374 ClassTemplateDecl *Template)

375 : SemaRef(S), Template(Template) {

376

377

378 ClassTemplateDecl *Pattern = Template;

380 if (Pattern->isMemberSpecialization())

381 break;

382 Pattern = Pattern->getInstantiatedFromMemberTemplate();

383 NestedPattern = Pattern;

384 }

385

386 if (NestedPattern)

387 OuterInstantiationArgs = SemaRef.getTemplateInstantiationArgs(Template);

388 }

389

390 Sema &SemaRef;

391 ClassTemplateDecl *Template;

392 ClassTemplateDecl *NestedPattern = nullptr;

393

394 DeclContext *DC = Template->getDeclContext();

395 CXXRecordDecl *Primary = Template->getTemplatedDecl();

396 DeclarationName DeductionGuideName =

397 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(Template);

398

399 QualType DeducedType = SemaRef.Context.getCanonicalTagType(Primary);

400

401

402

403 unsigned Depth1IndexAdjustment = Template->getTemplateParameters()->size();

404

405

406

407 MultiLevelTemplateArgumentList OuterInstantiationArgs;

408

409

410 NamedDecl *transformConstructor(FunctionTemplateDecl *FTD,

411 CXXConstructorDecl *CD) {

412 SmallVector<TemplateArgument, 16> SubstArgs;

413

414 LocalInstantiationScope Scope(SemaRef);

415

416

417

418

419

420

421

422

423 TemplateParameterList *TemplateParams =

424 SemaRef.GetTemplateParameterList(Template);

425 SmallVector<TemplateArgument, 16> Depth1Args;

426 AssociatedConstraint OuterRC(TemplateParams->getRequiresClause());

427 if (FTD) {

429 SmallVector<NamedDecl *, 16> AllParams;

430 AllParams.reserve(TemplateParams->size() + InnerParams->size());

431 AllParams.insert(AllParams.begin(), TemplateParams->begin(),

432 TemplateParams->end());

433 SubstArgs.reserve(InnerParams->size());

434 Depth1Args.reserve(InnerParams->size());

435

436

437

438 for (NamedDecl *Param : *InnerParams) {

439 MultiLevelTemplateArgumentList Args;

440 Args.setKind(TemplateSubstitutionKind::Rewrite);

443 if (NestedPattern)

446

447

448

449

450 NamedDecl *NewParam = transformTemplateParameter(

451 SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment,

452 Depth ? Depth - 1 : 0);

453 if (!NewParam)

454 return nullptr;

455

456

457 Depth1Args.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));

458

459 if (NestedPattern) {

461 NewParam = transformTemplateParameter(

462 SemaRef, DC, NewParam, OuterInstantiationArgs, Index,

463 Depth - OuterInstantiationArgs.getNumSubstitutedLevels(),

464 false);

465 }

466

468 "Unexpected template parameter depth");

469

470 AllParams.push_back(NewParam);

471 SubstArgs.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));

472 }

473

474

475 Expr *RequiresClause = nullptr;

476 if (Expr *InnerRC = InnerParams->getRequiresClause()) {

477 MultiLevelTemplateArgumentList Args;

478 Args.setKind(TemplateSubstitutionKind::Rewrite);

481 if (NestedPattern)

484 SemaRef.SubstConstraintExprWithoutSatisfaction(InnerRC, Args);

486 return nullptr;

487 RequiresClause = E.get();

488 }

489

490 TemplateParams = TemplateParameterList::Create(

491 SemaRef.Context, InnerParams->getTemplateLoc(),

492 InnerParams->getLAngleLoc(), AllParams, InnerParams->getRAngleLoc(),

493 RequiresClause);

494 }

495

496

497

498

499 MultiLevelTemplateArgumentList Args;

500 Args.setKind(TemplateSubstitutionKind::Rewrite);

501 if (FTD) {

504 }

505

509 assert(FPTL && "no prototype for constructor declaration");

510

511

512

513

514 TypeLocBuilder TLB;

515 SmallVector<ParmVarDecl *, 8> Params;

516 SmallVector<TypedefNameDecl *, 4> MaterializedTypedefs;

517 QualType NewType = transformFunctionProtoType(TLB, FPTL, Params, Args,

518 MaterializedTypedefs);

519 if (NewType.isNull())

520 return nullptr;

521 TypeSourceInfo *NewTInfo = TLB.getTypeSourceInfo(SemaRef.Context, NewType);

522

523

524

525

526 AssociatedConstraint FunctionTrailingRC;

528 MultiLevelTemplateArgumentList Args;

529 Args.setKind(TemplateSubstitutionKind::Rewrite);

532 if (NestedPattern)

534 ExprResult E = SemaRef.SubstConstraintExprWithoutSatisfaction(

535 const_cast<Expr *>(RC.ConstraintExpr), Args);

537 return nullptr;

538 FunctionTrailingRC = AssociatedConstraint(E.get(), RC.ArgPackSubstIndex);

539 }

540

541

542

543

544

545

546

547

548 if (OuterRC) {

549

550

551

552

553 if (!FunctionTrailingRC)

554 FunctionTrailingRC = OuterRC;

555 else

556 FunctionTrailingRC = AssociatedConstraint(

558 SemaRef.Context,

559 const_cast<Expr *>(OuterRC.ConstraintExpr),

560 const_cast<Expr *>(FunctionTrailingRC.ConstraintExpr),

562 TemplateParams->getTemplateLoc(), FPOptionsOverride()),

564 }

565

566 return buildDeductionGuide(

569 true, MaterializedTypedefs, FunctionTrailingRC);

570 }

571

572

573 NamedDecl *buildSimpleDeductionGuide(MutableArrayRef ParamTypes) {

574 SourceLocation Loc = Template->getLocation();

575

576

577 FunctionProtoType::ExtProtoInfo EPI;

579 QualType Result = SemaRef.BuildFunctionType(DeducedType, ParamTypes, Loc,

580 DeductionGuideName, EPI);

581 TypeSourceInfo *TSI = SemaRef.Context.getTrivialTypeSourceInfo(Result, Loc);

582 if (NestedPattern)

583 TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,

584 DeductionGuideName);

585

586 if (!TSI)

587 return nullptr;

588

589 FunctionProtoTypeLoc FPTL =

591

592

593 SmallVector<ParmVarDecl *, 4> Params;

594 for (auto T : ParamTypes) {

595 auto *TSI = SemaRef.Context.getTrivialTypeSourceInfo(T, Loc);

596 if (NestedPattern)

597 TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,

598 DeclarationName());

599 if (!TSI)

600 return nullptr;

601

602 ParmVarDecl *NewParam =

606 FPTL.setParam(Params.size(), NewParam);

607 Params.push_back(NewParam);

608 }

609

610 return buildDeductionGuide(

611 SemaRef, Template, SemaRef.GetTemplateParameterList(Template), nullptr,

612 ExplicitSpecifier(), TSI, Loc, Loc, Loc, true);

613 }

614

615private:

616 QualType transformFunctionProtoType(

617 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL,

618 SmallVectorImpl<ParmVarDecl *> &Params,

619 MultiLevelTemplateArgumentList &Args,

620 SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs) {

621 SmallVector<QualType, 4> ParamTypes;

622 const FunctionProtoType *T = TL.getTypePtr();

623

624

625 for (auto *OldParam : TL.getParams()) {

626 ParmVarDecl *NewParam = OldParam;

627

628

629

630

631

632

633

634

635

636 if (NestedPattern) {

637 NewParam = transformFunctionTypeParam(

638 NewParam, OuterInstantiationArgs, MaterializedTypedefs,

639 true);

640 if (!NewParam)

641 return QualType();

642 }

643

644

645

646 NewParam =

647 transformFunctionTypeParam(NewParam, Args, MaterializedTypedefs,

648 false);

649 if (!NewParam)

650 return QualType();

651 ParamTypes.push_back(NewParam->getType());

652 Params.push_back(NewParam);

653 }

654

655

656

657

658

659

660

661

662

663

664 QualType ReturnType = DeducedType;

665 auto TTL = TLB.push(ReturnType);

666 TTL.setElaboratedKeywordLoc(SourceLocation());

667 TTL.setQualifierLoc(NestedNameSpecifierLoc());

668 TTL.setNameLoc(Primary->getLocation());

669

670

671

672 FunctionProtoType::ExtProtoInfo EPI;

675

676 QualType Result = SemaRef.BuildFunctionType(

677 ReturnType, ParamTypes, TL.getBeginLoc(), DeductionGuideName, EPI);

679 return QualType();

680

681 FunctionProtoTypeLoc NewTL = TLB.push(Result);

687 for (unsigned I = 0, E = NewTL.getNumParams(); I != E; ++I)

688 NewTL.setParam(I, Params[I]);

689

691 }

692

693 ParmVarDecl *transformFunctionTypeParam(

694 ParmVarDecl *OldParam, MultiLevelTemplateArgumentList &Args,

695 llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs,

696 bool TransformingOuterPatterns) {

698 TypeSourceInfo *NewTSI;

699 if (auto PackTL = OldTSI->getTypeLoc().getAs()) {

700

701 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, 0u);

702 NewTSI =

703 SemaRef.SubstType(PackTL.getPatternLoc(), Args,

705 if (!NewTSI)

706 return nullptr;

707 NewTSI =

708 SemaRef.CheckPackExpansion(NewTSI, PackTL.getEllipsisLoc(),

709 PackTL.getTypePtr()->getNumExpansions());

710 } else

711 NewTSI = SemaRef.SubstType(OldTSI, Args, OldParam->getLocation(),

713 if (!NewTSI)

714 return nullptr;

715

716

717

718

719

720 NewTSI = ExtractTypeForDeductionGuide(

721 SemaRef, MaterializedTypedefs, NestedPattern,

722 TransformingOuterPatterns ? &Args : nullptr)

723 .transform(NewTSI);

724 if (!NewTSI)

725 return nullptr;

726

727

730

731

732 QualType ParamTy = NewTSI->getType();

733 NewDefArg = new (SemaRef.Context)

739 }

740

741 auto NewType = NewTSI->getType();

743 NewType = SemaRef.Context.getDecayedType(NewType);

744

751 SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam);

752 return NewParam;

753 }

754};

755

756

757

761

762 llvm::SmallBitVector ReferencedTemplateParams(TemplateParamsList->size());

764 DeducedArgs, TemplateParamsList->getDepth(), ReferencedTemplateParams);

765

766 auto MarkDefaultArgs = [&](auto *Param) {

767 if (!Param->hasDefaultArgument())

768 return;

770 Param->getDefaultArgument().getArgument(),

771 TemplateParamsList->getDepth(), ReferencedTemplateParams);

772 };

773

774 for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) {

775 if (!ReferencedTemplateParams[Index])

776 continue;

777 auto *Param = TemplateParamsList->getParam(Index);

778 if (auto *TTPD = dyn_cast(Param))

779 MarkDefaultArgs(TTPD);

780 else if (auto *NTTPD = dyn_cast(Param))

781 MarkDefaultArgs(NTTPD);

782 else

784 }

785

787 for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) {

788 if (ReferencedTemplateParams[Index])

789 Results.push_back(Index);

790 }

791 return Results;

792}

793

795

796

799 "name must be a deduction guide name");

800 auto Existing = DC->lookup(Name);

801 for (auto *D : Existing)

802 if (D->isImplicit())

803 return true;

804 return false;

805}

806

807

808

809llvm::DenseSet<const NamedDecl *> getSourceDeductionGuides(DeclarationName Name,

813 "name must be a deduction guide name");

814 llvm::DenseSet<const NamedDecl *> Result;

815 for (auto *D : DC->lookup(Name)) {

816 if (const auto *FTD = dyn_cast(D))

818

819 if (const auto *GD = dyn_cast(D)) {

820 assert(GD->getSourceDeductionGuide() &&

821 "deduction guide for alias template must have a source deduction "

822 "guide");

823 Result.insert(GD->getSourceDeductionGuide());

824 }

825 }

826 return Result;

827}

828

829

830

831

832

833

834

835

836

841 unsigned FirstUndeducedParamIdx, Expr *IsDeducible) {

843 if (!RC)

844 return IsDeducible;

845

848

849

850

851

852

853

854

855

856

857

858

859

860

861

862

863

864

865

866 unsigned AdjustDepth = 0;

867 if (auto *PrimaryTemplate =

868 AliasTemplate->getInstantiatedFromMemberTemplate())

869 AdjustDepth = PrimaryTemplate->getTemplateDepth();

870

871

872

874

875 for (auto *TP : *AliasTemplate->getTemplateParameters()) {

876

877

881 NamedDecl *NewParam = transformTemplateParameter(

882 SemaRef, AliasTemplate->getDeclContext(), TP, Args,

883 AdjustedAliasTemplateArgs.size(),

885

887 Context.getInjectedTemplateArg(NewParam);

888 AdjustedAliasTemplateArgs.push_back(NewTemplateArgument);

889 }

890

891

894

898

899 for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {

900 const auto &D = DeduceResults[Index];

901 if (D.isNull()) {

906

908 transformTemplateParameter(SemaRef, F->getDeclContext(), TP, Args,

909 FirstUndeducedParamIdx,

911 FirstUndeducedParamIdx += 1;

912 assert(TemplateArgsForBuildingRC[Index].isNull());

913 TemplateArgsForBuildingRC[Index] =

914 Context.getInjectedTemplateArg(NewParam);

915 continue;

916 }

921 assert(TemplateArgsForBuildingRC[Index].isNull() &&

922 "InstantiatedArgs must be null before setting");

923 TemplateArgsForBuildingRC[Index] = Output.getArgument();

924 }

925 }

926

927

928

932

933

934

935

936

937

938

939

940

941

942

943

944

945

946

947

948

949

950

951

952

953

954

955

956

957

958

959

960

961

963 clang::Decl::ClassTemplateSpecialization) {

966 false, std::nullopt,

967 true,

968 nullptr,

969 true);

970 for (auto It : OuterLevelArgs)

972 }

973

976 return nullptr;

977

978 auto Conjunction =

980 BinaryOperatorKind::BO_LAnd, E.get(), IsDeducible);

981 if (Conjunction.isInvalid())

982 return nullptr;

983 return Conjunction.getAs<Expr>();

984}

985

986

987

988

989Expr *buildIsDeducibleConstraint(Sema &SemaRef,

994

995 if (auto *PrimaryTemplate =

996 AliasTemplate->getInstantiatedFromMemberTemplate();

997 PrimaryTemplate && TemplateParams.size() > 0) {

999

1000

1001 unsigned AdjustDepth = PrimaryTemplate->getTemplateDepth();

1003 for (auto *TP : TemplateParams) {

1004

1005

1009 NamedDecl *NewParam = transformTemplateParameter(

1010 SemaRef, AliasTemplate->getDeclContext(), TP, Args,

1011 TransformedTemplateArgs.size(),

1013

1015 Context.getInjectedTemplateArg(NewParam);

1016 TransformedTemplateArgs.push_back(NewTemplateArgument);

1017 }

1018

1024 Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate));

1025 }

1026

1028 Context.getTrivialTypeSourceInfo(

1029 Context.getDeducedTemplateSpecializationType(

1032 true),

1033 AliasTemplate->getLocation()),

1034

1035 Context.getTrivialTypeSourceInfo(

1036 ReturnType, AliasTemplate->getLocation()),

1037

1038 };

1040 Context, Context.getLogicalOperationType(), AliasTemplate->getLocation(),

1041 TypeTrait::BTT_IsDeducible, IsDeducibleTypeTraitArgs,

1043}

1044

1045std::pair<TemplateDecl *, llvm::ArrayRef>

1047 auto RhsType = AliasTemplate->getTemplatedDecl()->getUnderlyingType();

1050 if (const auto *TST = RhsType->getAs()) {

1051

1052

1053

1054 Template = TST->getTemplateName().getAsTemplateDecl();

1055 AliasRhsTemplateArgs =

1056 TST->getAsNonAliasTemplateSpecializationType()->template_arguments();

1057 } else if (const auto *RT = RhsType->getAs()) {

1058

1059

1060

1061 if (const auto *CTSD =

1062 dyn_cast(RT->getDecl())) {

1063 Template = CTSD->getSpecializedTemplate();

1064 AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray();

1065 }

1066 }

1067 return {Template, AliasRhsTemplateArgs};

1068}

1069

1071

1072

1073

1074

1075

1076

1077

1078 return TA.isNull() ||

1080 llvm::any_of(TA.pack_elements(), IsNonDeducedArgument));

1081}

1082

1083

1084

1086BuildDeductionGuideForTypeAlias(Sema &SemaRef,

1094 if (BuildingDeductionGuides.isInvalid())

1095 return nullptr;

1096

1097 auto &Context = SemaRef.Context;

1098 auto [Template, AliasRhsTemplateArgs] =

1099 getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);

1100

1101

1102

1103

1104

1105

1106

1107

1108

1109

1110

1111

1112

1113

1114

1115

1116

1117

1118

1120

1121 const auto *FReturnType = RType->getAs();

1122 if (const auto *ICNT = RType->getAsCanonical())

1123

1125 ICNT->getDecl()->getCanonicalTemplateSpecializationType(

1127 assert(FReturnType && "expected to see a return type");

1128

1129

1130

1131

1132

1133

1134

1135

1136

1137

1138

1139

1140

1141

1142

1143

1144

1145

1146

1147

1149

1152

1153

1154

1155

1156

1157

1160 AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,

1161 false);

1162

1165

1166

1167 for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {

1168 const auto &D = DeduceResults[Index];

1169 if (!IsNonDeducedArgument(D))

1170 DeducedArgs.push_back(D);

1171 else

1172 NonDeducedTemplateParamsInFIndex.push_back(Index);

1173 }

1174 auto DeducedAliasTemplateParams =

1175 TemplateParamsReferencedInTemplateArgumentList(

1176 SemaRef, AliasTemplate->getTemplateParameters(), DeducedArgs);

1177

1180

1181

1182

1183

1184

1185

1186

1187

1189

1190

1192 AliasTemplate->getTemplateParameters()->size());

1193

1194

1195

1197

1198 for (unsigned AliasTemplateParamIdx : DeducedAliasTemplateParams) {

1199 auto *TP =

1200 AliasTemplate->getTemplateParameters()->getParam(AliasTemplateParamIdx);

1201

1202

1206 NamedDecl *NewParam = transformTemplateParameter(

1207 SemaRef, AliasTemplate->getDeclContext(), TP, Args,

1208 FPrimeTemplateParams.size(), getDepthAndIndex(TP).first);

1209 FPrimeTemplateParams.push_back(NewParam);

1210

1212 Context.getInjectedTemplateArg(NewParam);

1213 TransformedDeducedAliasArgs[AliasTemplateParamIdx] = NewTemplateArgument;

1214 }

1215 unsigned FirstUndeducedParamIdx = FPrimeTemplateParams.size();

1216

1217

1218

1219

1220

1221

1222

1223

1224

1225

1226

1227

1228

1229

1230

1231

1235 for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) {

1236 const auto &D = DeduceResults[Index];

1238 if (IsNonDeducedArgument(D)) {

1239

1240 continue;

1241 }

1246 return nullptr;

1247 assert(TemplateArgsForBuildingFPrime[Index].isNull() &&

1248 "InstantiatedArgs must be null before setting");

1249

1250

1251

1252

1253

1255 for (auto TA : Output.arguments())

1258 -1, CTAI,

1260 return nullptr;

1262

1263

1264

1265 TemplateArgsForBuildingFPrime[Index] =

1267 } else {

1268 assert(Output.arguments().size() == 1);

1269 TemplateArgsForBuildingFPrime[Index] = CTAI.SugaredConverted[0];

1270 }

1271 }

1272

1273

1274

1275

1276 for (unsigned FTemplateParamIdx : NonDeducedTemplateParamsInFIndex) {

1280

1281

1283 NamedDecl *NewParam = transformTemplateParameter(

1284 SemaRef, F->getDeclContext(), TP, Args, FPrimeTemplateParams.size(),

1286 FPrimeTemplateParams.push_back(NewParam);

1287

1288 assert(TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull() &&

1289 "The argument must be null before setting");

1290 TemplateArgsForBuildingFPrime[FTemplateParamIdx] =

1291 Context.getInjectedTemplateArg(NewParam);

1292 }

1293

1294 auto *TemplateArgListForBuildingFPrime =

1296

1298 F, TemplateArgListForBuildingFPrime, AliasTemplate->getLocation(),

1301

1302 Expr *IsDeducible = buildIsDeducibleConstraint(

1303 SemaRef, AliasTemplate, FPrime->getReturnType(), FPrimeTemplateParams);

1304 Expr *RequiresClause =

1305 buildAssociatedConstraints(SemaRef, F, AliasTemplate, DeduceResults,

1306 FirstUndeducedParamIdx, IsDeducible);

1307

1309 Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(),

1310 AliasTemplate->getTemplateParameters()->getLAngleLoc(),

1311 FPrimeTemplateParams,

1312 AliasTemplate->getTemplateParameters()->getRAngleLoc(),

1313 RequiresClause);

1315 SemaRef, AliasTemplate, FPrimeTemplateParamList,

1316 GG->getCorrespondingConstructor(), GG->getExplicitSpecifier(),

1317 GG->getTypeSourceInfo(), AliasTemplate->getBeginLoc(),

1321 DGuide->setDeductionCandidateKind(GG->getDeductionCandidateKind());

1322 DGuide->setSourceDeductionGuide(

1324 DGuide->setSourceDeductionGuideKind(

1326 return Result;

1327 }

1328 return nullptr;

1329}

1330

1331void DeclareImplicitDeductionGuidesForTypeAlias(

1334 return;

1335 auto &Context = SemaRef.Context;

1336 auto [Template, AliasRhsTemplateArgs] =

1337 getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate);

1339 return;

1340 auto SourceDeductionGuides = getSourceDeductionGuides(

1341 Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate),

1343

1345 Context.DeclarationNames.getCXXDeductionGuideName(Template), Loc);

1348 Guides.suppressDiagnostics();

1349

1350 for (auto *G : Guides) {

1351 if (auto *DG = dyn_cast(G)) {

1352 if (SourceDeductionGuides.contains(DG))

1353 continue;

1354

1359

1360

1361 for (unsigned I = 0, N = DG->getNumParams(); I != N; ++I) {

1362 const auto *P = DG->getParamDecl(I);

1365 SemaRef.Context, G->getDeclContext(),

1366 DG->getParamDecl(I)->getBeginLoc(), P->getLocation(), nullptr,

1370 }

1372 SemaRef, AliasTemplate, nullptr,

1373 nullptr, DG->getExplicitSpecifier(), FunctionType,

1376 Transformed->setSourceDeductionGuide(DG);

1377 Transformed->setSourceDeductionGuideKind(

1379

1380

1381

1382

1384 SemaRef, AliasTemplate, Transformed->getReturnType(), {}));

1386 auto Conjunction = SemaRef.BuildBinOp(

1388 BinaryOperatorKind::BO_LAnd, const_cast<Expr *>(RC.ConstraintExpr),

1389 const_cast<Expr *>(Constraint.ConstraintExpr));

1390 if (!Conjunction.isInvalid()) {

1391 Constraint.ConstraintExpr = Conjunction.getAs<Expr>();

1392 Constraint.ArgPackSubstIndex = RC.ArgPackSubstIndex;

1393 }

1394 }

1395 Transformed->setTrailingRequiresClause(Constraint);

1396 continue;

1397 }

1399 if (!F || SourceDeductionGuides.contains(F->getTemplatedDecl()))

1400 continue;

1401

1402

1403

1406 continue;

1407

1408 BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate, F, Loc);

1409 }

1410}

1411

1412

1417 getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate).first;

1418 if (!RHSTemplate)

1419 return nullptr;

1420

1423 ExtractTypeForDeductionGuide TypeAliasTransformer(SemaRef, TypedefDecls);

1424 for (QualType P : ParamTypes) {

1425 QualType Type = TypeAliasTransformer.TransformType(P);

1426 if (Type.isNull())

1427 return nullptr;

1428 NewParamTypes.push_back(Type);

1429 }

1430

1432 RHSTemplate, NewParamTypes, Loc);

1433 if (!RHSDeductionGuide)

1434 return nullptr;

1435

1437 TD->setDeclContext(RHSDeductionGuide->getTemplatedDecl());

1438

1439 return BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate,

1440 RHSDeductionGuide, Loc);

1441}

1442

1443}

1444

1448 llvm::FoldingSetNodeID ID;

1450 for (auto &T : ParamTypes)

1451 T.getCanonicalType().Profile(ID);

1452 unsigned Hash = ID.ComputeHash();

1453

1458 }

1459

1461 if (auto *FTD = DeclareAggregateDeductionGuideForTypeAlias(

1466 return FTD;

1467 }

1468 }

1469

1473 DefRecord->getDescribedClassTemplate())

1474 Template = DescribedTemplate;

1475 }

1476

1479 return nullptr;

1480

1481 ConvertConstructorToDeductionGuideTransform Transform(

1484 return nullptr;

1485

1486

1487

1489

1490

1494 if (BuildingDeductionGuides.isInvalid())

1495 return nullptr;

1496

1498 Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;

1500

1502 Transform.buildSimpleDeductionGuide(ParamTypes));

1503 SavedContext.pop();

1507 return FTD;

1508}

1509

1513 DeclareImplicitDeductionGuidesForTypeAlias(*this, AliasTemplate, Loc);

1514 return;

1515 }

1517 dyn_cast_or_null(Template->getTemplatedDecl());

1518 if (!DefRecord)

1519 return;

1522 Definition->getDescribedClassTemplate())

1523 Template = DescribedTemplate;

1524 }

1525

1528 return;

1529

1530 ConvertConstructorToDeductionGuideTransform Transform(

1533 return;

1534

1535 if (hasDeclaredDeductionGuides(Transform.DeductionGuideName, DC))

1536 return;

1537

1538

1539

1541

1542

1546 if (BuildingDeductionGuides.isInvalid())

1547 return;

1548

1549

1550

1551

1552

1554 Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;

1557 bool AddedAny = false;

1559 D = D->getUnderlyingDecl();

1560 if (D->isInvalidDecl() || D->isImplicit())

1561 continue;

1562

1564

1565

1566

1567

1568 if (ProcessedCtors.count(D))

1569 continue;

1570

1571 auto *FTD = dyn_cast(D);

1572 auto *CD =

1573 dyn_cast_or_null(FTD ? FTD->getTemplatedDecl() : D);

1574

1575

1577 continue;

1578

1579

1581 return !P || P->hasUnparsedDefaultArg();

1582 }))

1583 continue;

1584

1585 ProcessedCtors.insert(D);

1586 Transform.transformConstructor(FTD, CD);

1587 AddedAny = true;

1588 }

1589

1590

1591

1592

1593

1594 if (!AddedAny)

1595 Transform.buildSimpleDeductionGuide({});

1596

1597

1598

1601 Transform.buildSimpleDeductionGuide(Transform.DeducedType))

1602 ->getTemplatedDecl())

1604

1605 SavedContext.pop();

1606}

Defines the clang::ASTContext interface.

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

This file defines the classes used to store parsed information about declaration-specifiers and decla...

Defines the C++ template declaration subclasses.

Defines the clang::Expr interface and subclasses for C++ expressions.

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

Defines the clang::SourceLocation class and associated facilities.

Defines various enumerations that describe declaration and type specifiers.

Defines the clang::TypeLoc interface and its subclasses.

Defines enumerations for the type traits support.

C Language Family Type Representation.

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

TranslationUnitDecl * getTranslationUnitDecl() const

DeclarationNameTable DeclarationNames

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

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

QualType getTypedefType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypedefNameDecl *Decl, QualType UnderlyingType=QualType(), std::optional< bool > TypeMatchesDeclOrNone=std::nullopt) const

Return the unique reference to the type for the specified typedef-name decl.

static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)

Represents a C++ constructor within a class.

ExplicitSpecifier getExplicitSpecifier()

Represents a C++ deduction guide declaration.

static CXXDeductionGuideDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, SourceLocation EndLocation, CXXConstructorDecl *Ctor=nullptr, DeductionCandidate Kind=DeductionCandidate::Normal, const AssociatedConstraint &TrailingRequiresClause={}, const CXXDeductionGuideDecl *SourceDG=nullptr, SourceDeductionGuideKind SK=SourceDeductionGuideKind::None)

CXXConstructorDecl * getCorrespondingConstructor() const

Get the constructor from which this deduction guide was generated, if this is an implicit deduction g...

Represents a C++ struct/union/class.

CXXRecordDecl * getDefinition() const

Declaration of a class template.

CXXRecordDecl * getTemplatedDecl() const

Get the underlying class declarations of the template.

ClassTemplateDecl * getInstantiatedFromMemberTemplate() const

const TypeClass * getTypePtr() const

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

DeclContext * getParent()

getParent - Returns the containing DeclContext.

bool Equals(const DeclContext *DC) const

Determine whether this declaration context is equivalent to the declaration context DC.

bool isDependentContext() const

Determines whether this context is dependent on a template parameter.

lookup_result lookup(DeclarationName Name) const

lookup - Find the declarations (if any) with the given Name in this context.

void addDecl(Decl *D)

Add the declaration D into this context.

Decl::Kind getDeclKind() const

SourceLocation getEndLoc() const LLVM_READONLY

bool isImplicit() const

isImplicit - Indicates whether the declaration was implicitly generated by the implementation.

SourceLocation getLocation() const

DeclContext * getDeclContext()

void setDeclContext(DeclContext *DC)

setDeclContext - Set both the semantic and lexical DeclContext to DC.

DeclContext * getLexicalDeclContext()

getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).

The name of a declaration.

NameKind getNameKind() const

Determine what kind of name this is.

SourceLocation getInnerLocStart() const

Return start of source range ignoring outer template declarations.

SourceLocation getBeginLoc() const LLVM_READONLY

const AssociatedConstraint & getTrailingRequiresClause() const

Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...

TypeSourceInfo * getTypeSourceInfo() const

SourceLocation getElaboratedKeywordLoc() const

SourceLocation getNameLoc() const

NestedNameSpecifierLoc getQualifierLoc() const

Store information needed for an explicit specifier.

This represents one expression.

bool isFunctionTemplateSpecialization() const

Determine whether this function is a function template specialization.

FunctionTemplateDecl * getDescribedFunctionTemplate() const

Retrieves the function template that is described by this function declaration.

QualType getReturnType() const

ArrayRef< ParmVarDecl * > parameters() const

void getAssociatedConstraints(SmallVectorImpl< AssociatedConstraint > &ACs) const

Get the associated-constraints of this function declaration.

bool isVariadic() const

Whether this function prototype is variadic.

Declaration of a template function.

FunctionDecl * getTemplatedDecl() const

Get the underlying function declaration of the template.

static FunctionTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)

Create a function template node.

unsigned getNumParams() const

SourceLocation getLocalRangeEnd() const

void setLocalRangeBegin(SourceLocation L)

void setLParenLoc(SourceLocation Loc)

void setParam(unsigned i, ParmVarDecl *VD)

ArrayRef< ParmVarDecl * > getParams() const

void setRParenLoc(SourceLocation Loc)

void setLocalRangeEnd(SourceLocation L)

void setExceptionSpecRange(SourceRange R)

SourceLocation getLocalRangeBegin() const

SourceLocation getLParenLoc() const

SourceLocation getRParenLoc() const

FunctionType - C99 6.7.5.3 - Function Declarators.

const TypeClass * getTypePtr() const

A stack-allocated class that identifies which local variable declaration instantiations are present i...

void InstantiatedLocal(const Decl *D, Decl *Inst)

Represents the results of name lookup.

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

void addOuterRetainedLevel()

Add an outermost level that we are not substituting.

void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args, bool Final)

Add a new outmost level to the multi-level template argument list.

void setKind(TemplateSubstitutionKind K)

void addOuterRetainedLevels(unsigned Num)

This represents a decl that may have a name.

IdentifierInfo * getIdentifier() const

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

DeclarationName getDeclName() const

Get the actual, stored name of the declaration, which may be a special name.

NestedNameSpecifier getNestedNameSpecifier() const

Retrieve the nested-name-specifier to which this instance refers.

Represents a parameter to a function.

unsigned getFunctionScopeIndex() const

Returns the index of this parameter in its prototype or method scope.

SourceRange getDefaultArgRange() const

Retrieve the source range that covers the entire default argument.

void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)

static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)

bool hasDefaultArg() const

Determines whether this parameter has a default argument, either parsed or not.

unsigned getFunctionScopeDepth() const

A (possibly-)qualified type.

QualType getNonLValueExprType(const ASTContext &Context) const

Determine the type of a (typically non-lvalue) expression with the specified result type.

bool isNull() const

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

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

RAII object used to change the argument pack substitution index within a Sema object.

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

bool SubstTypeConstraint(TemplateTypeParmDecl *Inst, const TypeConstraint *TC, const MultiLevelTemplateArgumentList &TemplateArgs, bool EvaluateConstraint)

LocalInstantiationScope * CurrentInstantiationScope

The current instantiation scope used to store local variables.

TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)

Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.

Scope * getCurScope() const

Retrieve the parser's current scope.

bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool UseMemberUsingDeclRules, bool ConsiderCudaAttrs=true)

@ LookupOrdinaryName

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

FunctionTemplateDecl * DeclareAggregateDeductionGuideFromInitList(TemplateDecl *Template, MutableArrayRef< QualType > ParamTypes, SourceLocation Loc)

Definition SemaTemplateDeductionGuide.cpp:1445

FunctionDecl * InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD, const TemplateArgumentList *Args, SourceLocation Loc, CodeSynthesisContext::SynthesisKind CSC=CodeSynthesisContext::ExplicitTemplateArgumentSubstitution)

Instantiate (or find existing instantiation of) a function template with a given set of template argu...

@ CTAK_Specified

The template argument was specified in the code or was instantiated with some deduced template argume...

ExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)

ASTContext & getASTContext() const

TypeSourceInfo * SubstType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, SourceLocation Loc, DeclarationName Entity, bool AllowDeducedTST=false)

Perform substitution on the type T with a given set of template arguments.

bool SubstTemplateArguments(ArrayRef< TemplateArgumentLoc > Args, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentListInfo &Outputs)

bool CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &Arg, NamedDecl *Template, SourceLocation TemplateLoc, SourceLocation RAngleLoc, unsigned ArgumentPackIndex, CheckTemplateArgumentInfo &CTAI, CheckTemplateArgumentKind CTAK)

Check that the given template argument corresponds to the given template parameter.

const LangOptions & getLangOpts() const

llvm::DenseMap< unsigned, CXXDeductionGuideDecl * > AggregateDeductionCandidates

bool AreConstraintExpressionsEqual(const NamedDecl *Old, const Expr *OldConstr, const TemplateCompareNewDeclInfo &New, const Expr *NewConstr)

MultiLevelTemplateArgumentList getTemplateInstantiationArgs(const NamedDecl *D, const DeclContext *DC=nullptr, bool Final=false, std::optional< ArrayRef< TemplateArgument > > Innermost=std::nullopt, bool RelativeToPrimary=false, const FunctionDecl *Pattern=nullptr, bool ForConstraintInstantiation=false, bool SkipForSpecialization=false, bool ForDefaultArgumentSubstitution=false)

Retrieve the template argument list(s) that should be used to instantiate the definition of the given...

void DeclareImplicitDeductionGuides(TemplateDecl *Template, SourceLocation Loc)

Declare implicit deduction guides for a class template if we've not already done so.

Definition SemaTemplateDeductionGuide.cpp:1510

Decl * SubstDecl(Decl *D, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs)

bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)

bool SubstTemplateArgument(const TemplateArgumentLoc &Input, const MultiLevelTemplateArgumentList &TemplateArgs, TemplateArgumentLoc &Output, SourceLocation Loc={}, const DeclarationName &Entity={})

void MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used)

Mark which template parameters are used in a given expression.

bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)

Perform qualified name lookup into a given context.

ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr, bool ForFoldExpression=false)

TemplateDeductionResult DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, ArrayRef< TemplateArgument > TemplateArgs, sema::TemplateDeductionInfo &Info)

DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class)

Look up the constructors for the given class.

Encodes a location in the source.

SourceLocation getBegin() const

A convenient class for passing around template argument information.

ArrayRef< TemplateArgumentLoc > arguments() const

static TemplateArgumentList * CreateCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)

Create a new template argument list that copies the given set of template arguments.

Location wrapper for a TemplateArgument.

const TemplateArgument & getArgument() const

Represents a template argument.

static TemplateArgument CreatePackCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)

Create a new template argument pack by copying the given set of template arguments.

bool isNull() const

Determine whether this template argument has no value.

ArrayRef< TemplateArgument > pack_elements() const

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

@ Pack

The template argument is actually a parameter pack.

ArgKind getKind() const

Return the kind of stored template argument.

The base class of all kinds of template declarations (e.g., class, function, etc.).

TemplateParameterList * getTemplateParameters() const

Get the list of template parameters.

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

Stores a list of template parameters for a TemplateDecl and its derived classes.

NamedDecl * getParam(unsigned Idx)

unsigned getDepth() const

Get the depth of this template parameter list in the set of template parameter lists.

static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)

Expr * getRequiresClause()

The constraint-expression of the associated requires-clause.

SourceLocation getTemplateLoc() const

Declaration of a template type parameter.

bool wasDeclaredWithTypename() const

Whether this template type parameter was declared with the 'typename' keyword.

SourceLocation getDefaultArgumentLoc() const

Retrieves the location of the default argument declaration.

const TemplateArgumentLoc & getDefaultArgument() const

Retrieve the default argument, if any.

bool hasTypeConstraint() const

Determine whether this template parameter has a type-constraint.

const TypeConstraint * getTypeConstraint() const

Returns the type constraint associated with this template parameter (if any).

UnsignedOrNone getNumExpansionParameters() const

Whether this parameter is a template type parameter pack that has a known list of different type-cons...

bool hasDefaultArgument() const

Determine whether this template parameter has a default argument.

bool isParameterPack() const

Returns whether this is a parameter pack.

static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, UnsignedOrNone NumExpanded=std::nullopt)

A semantic tree transformation that allows one to transform one abstract syntax tree into another.

QualType RebuildTemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &Args)

static TypeAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo)

Declaration of an alias template.

SourceLocation getBeginLoc() const LLVM_READONLY

TyLocType push(QualType T)

Pushes space for a new TypeLoc of the given type.

TypeSourceInfo * getTypeSourceInfo(ASTContext &Context, QualType T)

Creates a TypeSourceInfo for the given type.

T getAs() const

Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...

T castAs() const

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

T getAsAdjusted() const

Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...

SourceLocation getBeginLoc() const

Get the begin source location.

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.

static TypeTraitExpr * Create(const ASTContext &C, QualType T, SourceLocation Loc, TypeTrait Kind, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool Value)

Create a new type trait expression.

The base class of the type hierarchy.

bool isRValueReferenceType() const

const T * castAs() const

Member-template castAs.

bool isInstantiationDependentType() const

Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...

bool isLValueReferenceType() const

bool isFunctionType() const

const T * getAs() const

Member-template getAs'.

static TypedefDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo)

Base class for declarations which introduce a typedef-name.

TypeSourceInfo * getTypeSourceInfo() const

StorageClass getStorageClass() const

Returns the storage class as written in the source.

Provides information about an attempted template argument deduction, whose success or failure was des...

std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl

All declarations that can appear in a module declaration.

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

bool isa(CodeGen::Address addr)

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

@ Rewrite

We are substituting template parameters for (typically) other template parameters in order to rewrite...

@ TemplateName

The identifier is a template name. FIXME: Add an annotation for that.

@ OK_Ordinary

An ordinary object is located at an address in memory.

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

const FunctionProtoType * T

@ Template

We are parsing a template declaration.

@ Keyword

The name has been typo-corrected to a keyword.

@ VK_PRValue

A pr-value expression (in the C++11 taxonomy) produces a temporary value.

@ VK_XValue

An x-value expression is a reference to an object with independent storage but which can be "moved",...

@ VK_LValue

An l-value expression is a reference to an object with independent storage.

U cast(CodeGen::Address addr)

ElaboratedTypeKeyword

The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...

@ None

No keyword precedes the qualified type name.

ActionResult< Expr * > ExprResult

const Expr * ConstraintExpr

UnsignedOrNone ArgPackSubstIndex

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

unsigned HasTrailingReturn

SmallVector< TemplateArgument, 4 > SugaredConverted

The checked, converted argument will be added to the end of these vectors.

@ BuildingDeductionGuides

We are building deduction guides for a class.

A stack object to be created when performing template instantiation.