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"
59static bool HaveSameAssociatedConstraints(
62 if (OldACs.size() != NewACs.size())
69 for (
size_t I = 0, E = OldACs.size(); I != E; ++I)
71 Old, OldACs[I].ConstraintExpr, NewInfo, NewACs[I].ConstraintExpr))
79class ExtractTypeForDeductionGuide
81 llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs;
82 ClassTemplateDecl *NestedPattern;
83 const MultiLevelTemplateArgumentList *OuterInstantiationArgs;
84 std::optional<TemplateDeclInstantiator> TypedefNameInstantiator;
87 typedef TreeTransform<ExtractTypeForDeductionGuide> Base;
88 ExtractTypeForDeductionGuide(
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);
102 TypeSourceInfo *transform(TypeSourceInfo *TSI) {
return TransformType(TSI); }
106 bool mightReferToOuterTemplateParameters(TypedefNameDecl *
Typedef) {
110 static auto WalkUp = [](DeclContext *DC, DeclContext *TargetDC) {
121 if (WalkUp(
Typedef->getDeclContext(), NestedPattern->getTemplatedDecl()))
123 if (WalkUp(NestedPattern->getTemplatedDecl(),
Typedef->getDeclContext()))
128 QualType RebuildTemplateSpecializationType(
130 SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {
131 if (!OuterInstantiationArgs ||
132 !isa_and_present<TypeAliasTemplateDecl>(
Template.getAsTemplateDecl()))
137 auto *Pattern = TATD;
138 while (Pattern->getInstantiatedFromMemberTemplate())
139 Pattern = Pattern->getInstantiatedFromMemberTemplate();
140 if (!mightReferToOuterTemplateParameters(Pattern->getTemplatedDecl()))
145 TypedefNameInstantiator->InstantiateTypeAliasTemplateDecl(TATD);
150 MaterializedTypedefs.push_back(NewTATD->getTemplatedDecl());
156 QualType TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) {
158 TypedefNameDecl *OrigDecl = TL.
getDecl();
159 TypedefNameDecl *
Decl = OrigDecl;
177 if (OuterInstantiationArgs && InDependentContext &&
179 Decl = cast_if_present<TypedefNameDecl>(
180 TypedefNameInstantiator->InstantiateTypedefNameDecl(
184 MaterializedTypedefs.push_back(Decl);
185 }
else if (InDependentContext) {
186 TypeLocBuilder InnerTLB;
187 QualType Transformed =
200 MaterializedTypedefs.push_back(Decl);
205 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
232 auto DeductionGuideName =
245 if (IsImplicit && Ctor && SemaRef.
getLangOpts().CUDA) {
250 auto *ExistingFT = dyn_cast<FunctionTemplateDecl>(Existing);
251 auto *ExistingGuide =
253 ? dyn_cast<CXXDeductionGuideDecl>(ExistingFT->getTemplatedDecl())
275 ExistingCtor->getAssociatedConstraints(ExistingACs);
277 if (HaveSameAssociatedConstraints(SemaRef, ExistingCtor, ExistingACs,
284 SemaRef.
Context, DC, LocStart, ES, Name, GuideType, TInfo, LocEnd, Ctor,
286 Guide->setImplicit(IsImplicit);
287 Guide->setParams(Params);
289 for (
auto *Param : Params)
290 Param->setDeclContext(Guide);
291 for (
auto *TD : MaterializedTypedefs)
292 TD->setDeclContext(Guide);
296 if (!TemplateParams) {
302 SemaRef.
Context, DC, Loc, DeductionGuideName, TemplateParams, Guide);
303 GuideTemplate->setImplicit(IsImplicit);
304 Guide->setDescribedFunctionTemplate(GuideTemplate);
310 return GuideTemplate;
317 bool EvaluateConstraint) {
333 NewTTP->setDefaultArgument(SemaRef.
Context, InstantiatedDefaultArg);
339template <
typename NonTypeTemplateOrTemplateTemplateParmDecl>
340NonTypeTemplateOrTemplateTemplateParmDecl *
342 NonTypeTemplateOrTemplateTemplateParmDecl *OldParam,
349 NewParam->setPosition(NewIndex);
350 NewParam->setDepth(NewDepth);
357 unsigned NewIndex,
unsigned NewDepth,
358 bool EvaluateConstraint =
true) {
359 if (
auto *TTP = dyn_cast<TemplateTypeParmDecl>(
TemplateParam))
360 return transformTemplateTypeParam(
361 SemaRef, DC, TTP, Args, NewDepth, NewIndex,
363 if (
auto *TTP = dyn_cast<TemplateTemplateParmDecl>(
TemplateParam))
364 return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex, NewDepth);
365 if (
auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(
TemplateParam))
366 return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex, NewDepth);
367 llvm_unreachable(
"Unhandled template parameter types");
372struct ConvertConstructorToDeductionGuideTransform {
373 ConvertConstructorToDeductionGuideTransform(Sema &S,
374 ClassTemplateDecl *Template)
375 : SemaRef(S), Template(Template) {
378 ClassTemplateDecl *Pattern = Template;
380 if (Pattern->isMemberSpecialization())
382 Pattern = Pattern->getInstantiatedFromMemberTemplate();
383 NestedPattern = Pattern;
387 OuterInstantiationArgs = SemaRef.getTemplateInstantiationArgs(Template);
391 ClassTemplateDecl *Template;
392 ClassTemplateDecl *NestedPattern =
nullptr;
394 DeclContext *DC = Template->getDeclContext();
395 CXXRecordDecl *Primary = Template->getTemplatedDecl();
396 DeclarationName DeductionGuideName =
397 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(Template);
399 QualType DeducedType = SemaRef.Context.getCanonicalTagType(Primary);
403 unsigned Depth1IndexAdjustment = Template->getTemplateParameters()->size();
407 MultiLevelTemplateArgumentList OuterInstantiationArgs;
410 NamedDecl *transformConstructor(FunctionTemplateDecl *FTD,
411 CXXConstructorDecl *CD) {
412 SmallVector<TemplateArgument, 16> SubstArgs;
414 LocalInstantiationScope Scope(SemaRef);
423 TemplateParameterList *TemplateParams =
424 SemaRef.GetTemplateParameterList(Template);
425 SmallVector<TemplateArgument, 16> Depth1Args;
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());
438 for (NamedDecl *Param : *InnerParams) {
439 MultiLevelTemplateArgumentList Args;
440 Args.
setKind(TemplateSubstitutionKind::Rewrite);
450 NamedDecl *NewParam = transformTemplateParameter(
451 SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment,
452 Depth ? Depth - 1 : 0);
457 Depth1Args.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));
461 NewParam = transformTemplateParameter(
462 SemaRef, DC, NewParam, OuterInstantiationArgs, Index,
463 Depth - OuterInstantiationArgs.getNumSubstitutedLevels(),
468 "Unexpected template parameter depth");
470 AllParams.push_back(NewParam);
471 SubstArgs.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));
475 Expr *RequiresClause =
nullptr;
476 if (Expr *InnerRC = InnerParams->getRequiresClause()) {
477 MultiLevelTemplateArgumentList Args;
478 Args.
setKind(TemplateSubstitutionKind::Rewrite);
484 SemaRef.SubstConstraintExprWithoutSatisfaction(InnerRC, Args);
487 RequiresClause = E.
get();
490 TemplateParams = TemplateParameterList::Create(
491 SemaRef.Context, InnerParams->getTemplateLoc(),
492 InnerParams->getLAngleLoc(), AllParams, InnerParams->getRAngleLoc(),
499 MultiLevelTemplateArgumentList Args;
500 Args.
setKind(TemplateSubstitutionKind::Rewrite);
509 assert(FPTL &&
"no prototype for constructor declaration");
515 SmallVector<ParmVarDecl *, 8> Params;
516 SmallVector<TypedefNameDecl *, 4> MaterializedTypedefs;
517 QualType NewType = transformFunctionProtoType(TLB, FPTL, Params, Args,
518 MaterializedTypedefs);
526 AssociatedConstraint FunctionTrailingRC;
528 MultiLevelTemplateArgumentList Args;
529 Args.
setKind(TemplateSubstitutionKind::Rewrite);
534 ExprResult E = SemaRef.SubstConstraintExprWithoutSatisfaction(
535 const_cast<Expr *
>(RC.ConstraintExpr), Args);
538 FunctionTrailingRC = AssociatedConstraint(E.
get(), RC.ArgPackSubstIndex);
553 if (!FunctionTrailingRC)
554 FunctionTrailingRC = OuterRC;
556 FunctionTrailingRC = AssociatedConstraint(
559 const_cast<Expr *
>(OuterRC.ConstraintExpr),
566 return buildDeductionGuide(
569 true, MaterializedTypedefs, FunctionTrailingRC);
573 NamedDecl *buildSimpleDeductionGuide(MutableArrayRef<QualType> ParamTypes) {
574 SourceLocation Loc = Template->getLocation();
577 FunctionProtoType::ExtProtoInfo EPI;
579 QualType
Result = SemaRef.BuildFunctionType(DeducedType, ParamTypes, Loc,
580 DeductionGuideName, EPI);
581 TypeSourceInfo *TSI = SemaRef.Context.getTrivialTypeSourceInfo(
Result, Loc);
583 TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
589 FunctionProtoTypeLoc FPTL =
593 SmallVector<ParmVarDecl *, 4> Params;
594 for (
auto T : ParamTypes) {
595 auto *TSI = SemaRef.Context.getTrivialTypeSourceInfo(T, Loc);
597 TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc,
602 ParmVarDecl *NewParam =
606 FPTL.
setParam(Params.size(), NewParam);
607 Params.push_back(NewParam);
610 return buildDeductionGuide(
611 SemaRef, Template, SemaRef.GetTemplateParameterList(Template),
nullptr,
612 ExplicitSpecifier(), TSI, Loc, Loc, Loc,
true);
616 QualType transformFunctionProtoType(
617 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL,
618 SmallVectorImpl<ParmVarDecl *> &Params,
619 MultiLevelTemplateArgumentList &Args,
620 SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs) {
621 SmallVector<QualType, 4> ParamTypes;
626 ParmVarDecl *NewParam = OldParam;
637 NewParam = transformFunctionTypeParam(
638 NewParam, OuterInstantiationArgs, MaterializedTypedefs,
647 transformFunctionTypeParam(NewParam, Args, MaterializedTypedefs,
651 ParamTypes.push_back(NewParam->
getType());
652 Params.push_back(NewParam);
664 QualType ReturnType = DeducedType;
665 auto TTL = TLB.
push<TagTypeLoc>(ReturnType);
666 TTL.setElaboratedKeywordLoc(SourceLocation());
667 TTL.setQualifierLoc(NestedNameSpecifierLoc());
668 TTL.setNameLoc(Primary->getLocation());
672 FunctionProtoType::ExtProtoInfo EPI;
676 QualType
Result = SemaRef.BuildFunctionType(
677 ReturnType, ParamTypes, TL.
getBeginLoc(), DeductionGuideName, EPI);
681 FunctionProtoTypeLoc NewTL = TLB.
push<FunctionProtoTypeLoc>(
Result);
687 for (
unsigned I = 0, E = NewTL.
getNumParams(); I != E; ++I)
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<PackExpansionTypeLoc>()) {
701 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, 0u);
703 SemaRef.SubstType(PackTL.getPatternLoc(), Args,
708 SemaRef.CheckPackExpansion(NewTSI, PackTL.getEllipsisLoc(),
709 PackTL.getTypePtr()->getNumExpansions());
711 NewTSI = SemaRef.SubstType(OldTSI, Args, OldParam->
getLocation(),
720 NewTSI = ExtractTypeForDeductionGuide(
721 SemaRef, MaterializedTypedefs, NestedPattern,
722 TransformingOuterPatterns ? &Args :
nullptr)
732 QualType ParamTy = NewTSI->
getType();
733 NewDefArg =
new (SemaRef.Context)
741 auto NewType = NewTSI->
getType();
743 NewType = SemaRef.Context.getDecayedType(NewType);
751 SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam);
762 llvm::SmallBitVector ReferencedTemplateParams(TemplateParamsList->
size());
764 DeducedArgs, TemplateParamsList->
getDepth(), ReferencedTemplateParams);
766 auto MarkDefaultArgs = [&](
auto *Param) {
767 if (!Param->hasDefaultArgument())
770 Param->getDefaultArgument().getArgument(),
771 TemplateParamsList->
getDepth(), ReferencedTemplateParams);
774 for (
unsigned Index = 0; Index < TemplateParamsList->
size(); ++Index) {
775 if (!ReferencedTemplateParams[Index])
777 auto *Param = TemplateParamsList->
getParam(Index);
778 if (
auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param))
779 MarkDefaultArgs(TTPD);
780 else if (
auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param))
781 MarkDefaultArgs(NTTPD);
787 for (
unsigned Index = 0; Index < TemplateParamsList->
size(); ++Index) {
788 if (ReferencedTemplateParams[Index])
789 Results.push_back(Index);
799 "name must be a deduction guide name");
800 auto Existing = DC->
lookup(Name);
801 for (
auto *D : Existing)
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<FunctionTemplateDecl>(D))
819 if (
const auto *GD = dyn_cast<CXXDeductionGuideDecl>(D)) {
820 assert(GD->getSourceDeductionGuide() &&
821 "deduction guide for alias template must have a source deduction "
823 Result.insert(GD->getSourceDeductionGuide());
841 unsigned FirstUndeducedParamIdx,
Expr *IsDeducible) {
866 unsigned AdjustDepth = 0;
867 if (
auto *PrimaryTemplate =
869 AdjustDepth = PrimaryTemplate->getTemplateDepth();
881 NamedDecl *NewParam = transformTemplateParameter(
883 AdjustedAliasTemplateArgs.size(),
887 Context.getInjectedTemplateArg(NewParam);
888 AdjustedAliasTemplateArgs.push_back(NewTemplateArgument);
899 for (
unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
900 const auto &D = DeduceResults[Index];
908 transformTemplateParameter(SemaRef, F->
getDeclContext(), TP, Args,
909 FirstUndeducedParamIdx,
911 FirstUndeducedParamIdx += 1;
912 assert(TemplateArgsForBuildingRC[Index].isNull());
913 TemplateArgsForBuildingRC[Index] =
914 Context.getInjectedTemplateArg(NewParam);
921 assert(TemplateArgsForBuildingRC[Index].isNull() &&
922 "InstantiatedArgs must be null before setting");
923 TemplateArgsForBuildingRC[Index] = Output.
getArgument();
963 clang::Decl::ClassTemplateSpecialization) {
970 for (
auto It : OuterLevelArgs)
980 BinaryOperatorKind::BO_LAnd, E.
get(), IsDeducible);
981 if (Conjunction.isInvalid())
989Expr *buildIsDeducibleConstraint(
Sema &SemaRef,
995 if (
auto *PrimaryTemplate =
997 PrimaryTemplate && TemplateParams.size() > 0) {
1001 unsigned AdjustDepth = PrimaryTemplate->getTemplateDepth();
1003 for (
auto *TP : TemplateParams) {
1009 NamedDecl *NewParam = transformTemplateParameter(
1011 TransformedTemplateArgs.size(),
1015 Context.getInjectedTemplateArg(NewParam);
1016 TransformedTemplateArgs.push_back(NewTemplateArgument);
1024 Context.DeclarationNames.getCXXDeductionGuideName(
AliasTemplate));
1028 Context.getTrivialTypeSourceInfo(
1029 Context.getDeducedTemplateSpecializationType(
1035 Context.getTrivialTypeSourceInfo(
1040 Context, Context.getLogicalOperationType(),
AliasTemplate->getLocation(),
1041 TypeTrait::BTT_IsDeducible, IsDeducibleTypeTraitArgs,
1045std::pair<TemplateDecl *, llvm::ArrayRef<TemplateArgument>>
1047 auto RhsType =
AliasTemplate->getTemplatedDecl()->getUnderlyingType();
1050 if (
const auto *TST = RhsType->getAs<TemplateSpecializationType>()) {
1054 Template = TST->getTemplateName().getAsTemplateDecl();
1055 AliasRhsTemplateArgs =
1056 TST->getAsNonAliasTemplateSpecializationType()->template_arguments();
1057 }
else if (
const auto *RT = RhsType->getAs<RecordType>()) {
1061 if (
const auto *CTSD =
1062 dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl())) {
1063 Template = CTSD->getSpecializedTemplate();
1064 AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray();
1067 return {
Template, AliasRhsTemplateArgs};
1086BuildDeductionGuideForTypeAlias(
Sema &SemaRef,
1094 if (BuildingDeductionGuides.isInvalid())
1097 auto &Context = SemaRef.
Context;
1098 auto [
Template, AliasRhsTemplateArgs] =
1121 const auto *FReturnType = RType->
getAs<TemplateSpecializationType>();
1122 if (
const auto *ICNT = RType->getAsCanonical<InjectedClassNameType>())
1125 ICNT->getDecl()->getCanonicalTemplateSpecializationType(
1130 FReturnTemplateArgs = FReturnType->template_arguments();
1131 }
else if (
const auto *RT = RType->getAs<RecordType>()) {
1134 if (
const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()))
1135 FReturnTemplateArgs = CTSD->getTemplateArgs().asArray();
1137 assert(!FReturnTemplateArgs.empty() &&
"expected to see template arguments");
1171 AliasRhsTemplateArgs, TDeduceInfo, DeduceResults,
1178 for (
unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
1179 const auto &D = DeduceResults[Index];
1180 if (!IsNonDeducedArgument(D))
1181 DeducedArgs.push_back(D);
1183 NonDeducedTemplateParamsInFIndex.push_back(Index);
1185 auto DeducedAliasTemplateParams =
1186 TemplateParamsReferencedInTemplateArgumentList(
1187 SemaRef,
AliasTemplate->getTemplateParameters(), DeducedArgs);
1209 for (
unsigned AliasTemplateParamIdx : DeducedAliasTemplateParams) {
1211 AliasTemplate->getTemplateParameters()->getParam(AliasTemplateParamIdx);
1217 NamedDecl *NewParam = transformTemplateParameter(
1220 FPrimeTemplateParams.push_back(NewParam);
1223 Context.getInjectedTemplateArg(NewParam);
1224 TransformedDeducedAliasArgs[AliasTemplateParamIdx] = NewTemplateArgument;
1226 unsigned FirstUndeducedParamIdx = FPrimeTemplateParams.size();
1246 for (
unsigned Index = 0; Index < DeduceResults.size(); ++Index) {
1247 const auto &D = DeduceResults[Index];
1249 if (IsNonDeducedArgument(D)) {
1258 assert(TemplateArgsForBuildingFPrime[Index].isNull() &&
1259 "InstantiatedArgs must be null before setting");
1276 TemplateArgsForBuildingFPrime[Index] =
1287 for (
unsigned FTemplateParamIdx : NonDeducedTemplateParamsInFIndex) {
1294 NamedDecl *NewParam = transformTemplateParameter(
1295 SemaRef, F->
getDeclContext(), TP, Args, FPrimeTemplateParams.size(),
1297 FPrimeTemplateParams.push_back(NewParam);
1299 assert(TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull() &&
1300 "The argument must be null before setting");
1301 TemplateArgsForBuildingFPrime[FTemplateParamIdx] =
1302 Context.getInjectedTemplateArg(NewParam);
1305 auto *TemplateArgListForBuildingFPrime =
1309 F, TemplateArgListForBuildingFPrime,
AliasTemplate->getLocation(),
1313 Expr *IsDeducible = buildIsDeducibleConstraint(
1314 SemaRef,
AliasTemplate, FPrime->getReturnType(), FPrimeTemplateParams);
1315 Expr *RequiresClause =
1316 buildAssociatedConstraints(SemaRef, F,
AliasTemplate, DeduceResults,
1317 FirstUndeducedParamIdx, IsDeducible);
1320 Context,
AliasTemplate->getTemplateParameters()->getTemplateLoc(),
1322 FPrimeTemplateParams,
1327 GG->getCorrespondingConstructor(), GG->getExplicitSpecifier(),
1332 DGuide->setDeductionCandidateKind(GG->getDeductionCandidateKind());
1333 DGuide->setSourceDeductionGuide(
1335 DGuide->setSourceDeductionGuideKind(
1342void DeclareImplicitDeductionGuidesForTypeAlias(
1346 auto &Context = SemaRef.
Context;
1347 auto [
Template, AliasRhsTemplateArgs] =
1351 auto SourceDeductionGuides = getSourceDeductionGuides(
1352 Context.DeclarationNames.getCXXDeductionGuideName(
AliasTemplate),
1356 Context.DeclarationNames.getCXXDeductionGuideName(
Template), Loc);
1359 Guides.suppressDiagnostics();
1361 for (
auto *G : Guides) {
1362 if (
auto *DG = dyn_cast<CXXDeductionGuideDecl>(G)) {
1363 if (SourceDeductionGuides.contains(DG))
1372 for (
unsigned I = 0, N = DG->getNumParams(); I != N; ++I) {
1373 const auto *P = DG->getParamDecl(I);
1376 SemaRef.
Context, G->getDeclContext(),
1377 DG->getParamDecl(I)->getBeginLoc(), P->getLocation(),
nullptr,
1387 Transformed->setSourceDeductionGuide(DG);
1388 Transformed->setSourceDeductionGuideKind(
1399 BinaryOperatorKind::BO_LAnd,
const_cast<Expr *
>(RC.ConstraintExpr),
1400 const_cast<Expr *
>(Constraint.ConstraintExpr));
1401 if (!Conjunction.isInvalid()) {
1402 Constraint.ConstraintExpr = Conjunction.getAs<
Expr>();
1403 Constraint.ArgPackSubstIndex = RC.ArgPackSubstIndex;
1406 Transformed->setTrailingRequiresClause(Constraint);
1419 BuildDeductionGuideForTypeAlias(SemaRef,
AliasTemplate, F, Loc);
1434 ExtractTypeForDeductionGuide TypeAliasTransformer(SemaRef, TypedefDecls);
1439 NewParamTypes.push_back(
Type);
1443 RHSTemplate, NewParamTypes, Loc);
1444 if (!RHSDeductionGuide)
1450 return BuildDeductionGuideForTypeAlias(SemaRef,
AliasTemplate,
1451 RHSDeductionGuide, Loc);
1459 llvm::FoldingSetNodeID ID;
1461 for (
auto &T : ParamTypes)
1462 T.getCanonicalType().Profile(ID);
1463 unsigned Hash = ID.ComputeHash();
1472 if (
auto *FTD = DeclareAggregateDeductionGuideForTypeAlias(
1484 DefRecord->getDescribedClassTemplate())
1492 ConvertConstructorToDeductionGuideTransform Transform(
1505 if (BuildingDeductionGuides.isInvalid())
1509 Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
1513 Transform.buildSimpleDeductionGuide(ParamTypes));
1524 DeclareImplicitDeductionGuidesForTypeAlias(*
this,
AliasTemplate, Loc);
1528 dyn_cast_or_null<CXXRecordDecl>(
Template->getTemplatedDecl());
1541 ConvertConstructorToDeductionGuideTransform Transform(
1546 if (hasDeclaredDeductionGuides(Transform.DeductionGuideName, DC))
1557 if (BuildingDeductionGuides.isInvalid())
1565 Transform.NestedPattern ? Transform.NestedPattern : Transform.Template;
1568 bool AddedAny =
false;
1570 D = D->getUnderlyingDecl();
1571 if (D->isInvalidDecl() || D->isImplicit())
1579 if (ProcessedCtors.count(D))
1582 auto *FTD = dyn_cast<FunctionTemplateDecl>(D);
1592 return !P || P->hasUnparsedDefaultArg();
1596 ProcessedCtors.insert(D);
1597 Transform.transformConstructor(FTD, CD);
1606 Transform.buildSimpleDeductionGuide({});
1612 Transform.buildSimpleDeductionGuide(Transform.DeducedType))
1613 ->getTemplatedDecl())
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
ElaboratedTypeKeyword getKeyword() 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)
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.
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.
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)
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<specific type>.
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<specific type>'.
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.
@ Template
We are parsing a template declaration.
@ Keyword
The name has been typo-corrected to a keyword.
@ DeducedAsDependent
This is a special case where the initializer is dependent, so we can't deduce a type yet.
@ 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.