1 //===- SemaTemplateDeductionGude.cpp - Template Argument Deduction---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements deduction guides for C++ class template argument 10 // deduction. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "TypeLocBuilder.h" 16 #include "clang/AST/ASTConsumer.h" 17 #include "clang/AST/ASTContext.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclBase.h" 20 #include "clang/AST/DeclCXX.h" 21 #include "clang/AST/DeclFriend.h" 22 #include "clang/AST/DeclTemplate.h" 23 #include "clang/AST/DeclarationName.h" 24 #include "clang/AST/Expr.h" 25 #include "clang/AST/ExprCXX.h" 26 #include "clang/AST/OperationKinds.h" 27 #include "clang/AST/RecursiveASTVisitor.h" 28 #include "clang/AST/TemplateBase.h" 29 #include "clang/AST/TemplateName.h" 30 #include "clang/AST/Type.h" 31 #include "clang/AST/TypeLoc.h" 32 #include "clang/Basic/LLVM.h" 33 #include "clang/Basic/SourceLocation.h" 34 #include "clang/Basic/Specifiers.h" 35 #include "clang/Basic/TypeTraits.h" 36 #include "clang/Sema/DeclSpec.h" 37 #include "clang/Sema/Initialization.h" 38 #include "clang/Sema/Lookup.h" 39 #include "clang/Sema/Overload.h" 40 #include "clang/Sema/Ownership.h" 41 #include "clang/Sema/Scope.h" 42 #include "clang/Sema/SemaInternal.h" 43 #include "clang/Sema/Template.h" 44 #include "clang/Sema/TemplateDeduction.h" 45 #include "llvm/ADT/ArrayRef.h" 46 #include "llvm/ADT/DenseSet.h" 47 #include "llvm/ADT/STLExtras.h" 48 #include "llvm/ADT/SmallVector.h" 49 #include "llvm/Support/Casting.h" 50 #include "llvm/Support/ErrorHandling.h" 51 #include <cassert> 52 #include <optional> 53 #include <utility> 54 55 using namespace clang; 56 using namespace sema; 57 58 namespace { 59 /// Tree transform to "extract" a transformed type from a class template's 60 /// constructor to a deduction guide. 61 class ExtractTypeForDeductionGuide 62 : public TreeTransform<ExtractTypeForDeductionGuide> { 63 llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs; 64 ClassTemplateDecl *NestedPattern; 65 const MultiLevelTemplateArgumentList *OuterInstantiationArgs; 66 std::optional<TemplateDeclInstantiator> TypedefNameInstantiator; 67 68 public: 69 typedef TreeTransform<ExtractTypeForDeductionGuide> Base; 70 ExtractTypeForDeductionGuide( 71 Sema &SemaRef, 72 llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs, 73 ClassTemplateDecl *NestedPattern, 74 const MultiLevelTemplateArgumentList *OuterInstantiationArgs) 75 : Base(SemaRef), MaterializedTypedefs(MaterializedTypedefs), 76 NestedPattern(NestedPattern), 77 OuterInstantiationArgs(OuterInstantiationArgs) { 78 if (OuterInstantiationArgs) 79 TypedefNameInstantiator.emplace( 80 SemaRef, SemaRef.getASTContext().getTranslationUnitDecl(), 81 *OuterInstantiationArgs); 82 } 83 84 TypeSourceInfo *transform(TypeSourceInfo *TSI) { return TransformType(TSI); } 85 86 /// Returns true if it's safe to substitute \p Typedef with 87 /// \p OuterInstantiationArgs. 88 bool mightReferToOuterTemplateParameters(TypedefNameDecl *Typedef) { 89 if (!NestedPattern) 90 return false; 91 92 static auto WalkUp = [](DeclContext *DC, DeclContext *TargetDC) { 93 if (DC->Equals(TargetDC)) 94 return true; 95 while (DC->isRecord()) { 96 if (DC->Equals(TargetDC)) 97 return true; 98 DC = DC->getParent(); 99 } 100 return false; 101 }; 102 103 if (WalkUp(Typedef->getDeclContext(), NestedPattern->getTemplatedDecl())) 104 return true; 105 if (WalkUp(NestedPattern->getTemplatedDecl(), Typedef->getDeclContext())) 106 return true; 107 return false; 108 } 109 110 QualType 111 RebuildTemplateSpecializationType(TemplateName Template, 112 SourceLocation TemplateNameLoc, 113 TemplateArgumentListInfo &TemplateArgs) { 114 if (!OuterInstantiationArgs || 115 !isa_and_present<TypeAliasTemplateDecl>(Template.getAsTemplateDecl())) 116 return Base::RebuildTemplateSpecializationType(Template, TemplateNameLoc, 117 TemplateArgs); 118 119 auto *TATD = cast<TypeAliasTemplateDecl>(Template.getAsTemplateDecl()); 120 auto *Pattern = TATD; 121 while (Pattern->getInstantiatedFromMemberTemplate()) 122 Pattern = Pattern->getInstantiatedFromMemberTemplate(); 123 if (!mightReferToOuterTemplateParameters(Pattern->getTemplatedDecl())) 124 return Base::RebuildTemplateSpecializationType(Template, TemplateNameLoc, 125 TemplateArgs); 126 127 Decl *NewD = 128 TypedefNameInstantiator->InstantiateTypeAliasTemplateDecl(TATD); 129 if (!NewD) 130 return QualType(); 131 132 auto *NewTATD = cast<TypeAliasTemplateDecl>(NewD); 133 MaterializedTypedefs.push_back(NewTATD->getTemplatedDecl()); 134 135 return Base::RebuildTemplateSpecializationType( 136 TemplateName(NewTATD), TemplateNameLoc, TemplateArgs); 137 } 138 139 QualType TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) { 140 ASTContext &Context = SemaRef.getASTContext(); 141 TypedefNameDecl *OrigDecl = TL.getTypedefNameDecl(); 142 TypedefNameDecl *Decl = OrigDecl; 143 // Transform the underlying type of the typedef and clone the Decl only if 144 // the typedef has a dependent context. 145 bool InDependentContext = OrigDecl->getDeclContext()->isDependentContext(); 146 147 // A typedef/alias Decl within the NestedPattern may reference the outer 148 // template parameters. They're substituted with corresponding instantiation 149 // arguments here and in RebuildTemplateSpecializationType() above. 150 // Otherwise, we would have a CTAD guide with "dangling" template 151 // parameters. 152 // For example, 153 // template <class T> struct Outer { 154 // using Alias = S<T>; 155 // template <class U> struct Inner { 156 // Inner(Alias); 157 // }; 158 // }; 159 if (OuterInstantiationArgs && InDependentContext && 160 TL.getTypePtr()->isInstantiationDependentType()) { 161 Decl = cast_if_present<TypedefNameDecl>( 162 TypedefNameInstantiator->InstantiateTypedefNameDecl( 163 OrigDecl, /*IsTypeAlias=*/isa<TypeAliasDecl>(OrigDecl))); 164 if (!Decl) 165 return QualType(); 166 MaterializedTypedefs.push_back(Decl); 167 } else if (InDependentContext) { 168 TypeLocBuilder InnerTLB; 169 QualType Transformed = 170 TransformType(InnerTLB, OrigDecl->getTypeSourceInfo()->getTypeLoc()); 171 TypeSourceInfo *TSI = InnerTLB.getTypeSourceInfo(Context, Transformed); 172 if (isa<TypeAliasDecl>(OrigDecl)) 173 Decl = TypeAliasDecl::Create( 174 Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(), 175 OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI); 176 else { 177 assert(isa<TypedefDecl>(OrigDecl) && "Not a Type alias or typedef"); 178 Decl = TypedefDecl::Create( 179 Context, Context.getTranslationUnitDecl(), OrigDecl->getBeginLoc(), 180 OrigDecl->getLocation(), OrigDecl->getIdentifier(), TSI); 181 } 182 MaterializedTypedefs.push_back(Decl); 183 } 184 185 QualType TDTy = Context.getTypedefType(Decl); 186 TypedefTypeLoc TypedefTL = TLB.push<TypedefTypeLoc>(TDTy); 187 TypedefTL.setNameLoc(TL.getNameLoc()); 188 189 return TDTy; 190 } 191 }; 192 193 // Build a deduction guide using the provided information. 194 // 195 // A deduction guide can be either a template or a non-template function 196 // declaration. If \p TemplateParams is null, a non-template function 197 // declaration will be created. 198 NamedDecl *buildDeductionGuide( 199 Sema &SemaRef, TemplateDecl *OriginalTemplate, 200 TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor, 201 ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart, 202 SourceLocation Loc, SourceLocation LocEnd, bool IsImplicit, 203 llvm::ArrayRef<TypedefNameDecl *> MaterializedTypedefs = {}) { 204 DeclContext *DC = OriginalTemplate->getDeclContext(); 205 auto DeductionGuideName = 206 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName( 207 OriginalTemplate); 208 209 DeclarationNameInfo Name(DeductionGuideName, Loc); 210 ArrayRef<ParmVarDecl *> Params = 211 TInfo->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(); 212 213 // Build the implicit deduction guide template. 214 auto *Guide = 215 CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name, 216 TInfo->getType(), TInfo, LocEnd, Ctor); 217 Guide->setImplicit(IsImplicit); 218 Guide->setParams(Params); 219 220 for (auto *Param : Params) 221 Param->setDeclContext(Guide); 222 for (auto *TD : MaterializedTypedefs) 223 TD->setDeclContext(Guide); 224 if (isa<CXXRecordDecl>(DC)) 225 Guide->setAccess(AS_public); 226 227 if (!TemplateParams) { 228 DC->addDecl(Guide); 229 return Guide; 230 } 231 232 auto *GuideTemplate = FunctionTemplateDecl::Create( 233 SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide); 234 GuideTemplate->setImplicit(IsImplicit); 235 Guide->setDescribedFunctionTemplate(GuideTemplate); 236 237 if (isa<CXXRecordDecl>(DC)) 238 GuideTemplate->setAccess(AS_public); 239 240 DC->addDecl(GuideTemplate); 241 return GuideTemplate; 242 } 243 244 // Transform a given template type parameter `TTP`. 245 TemplateTypeParmDecl *transformTemplateTypeParam( 246 Sema &SemaRef, DeclContext *DC, TemplateTypeParmDecl *TTP, 247 MultiLevelTemplateArgumentList &Args, unsigned NewDepth, unsigned NewIndex, 248 bool EvaluateConstraint) { 249 // TemplateTypeParmDecl's index cannot be changed after creation, so 250 // substitute it directly. 251 auto *NewTTP = TemplateTypeParmDecl::Create( 252 SemaRef.Context, DC, TTP->getBeginLoc(), TTP->getLocation(), NewDepth, 253 NewIndex, TTP->getIdentifier(), TTP->wasDeclaredWithTypename(), 254 TTP->isParameterPack(), TTP->hasTypeConstraint(), 255 TTP->isExpandedParameterPack() 256 ? std::optional<unsigned>(TTP->getNumExpansionParameters()) 257 : std::nullopt); 258 if (const auto *TC = TTP->getTypeConstraint()) 259 SemaRef.SubstTypeConstraint(NewTTP, TC, Args, 260 /*EvaluateConstraint=*/EvaluateConstraint); 261 if (TTP->hasDefaultArgument()) { 262 TemplateArgumentLoc InstantiatedDefaultArg; 263 if (!SemaRef.SubstTemplateArgument( 264 TTP->getDefaultArgument(), Args, InstantiatedDefaultArg, 265 TTP->getDefaultArgumentLoc(), TTP->getDeclName())) 266 NewTTP->setDefaultArgument(SemaRef.Context, InstantiatedDefaultArg); 267 } 268 SemaRef.CurrentInstantiationScope->InstantiatedLocal(TTP, NewTTP); 269 return NewTTP; 270 } 271 // Similar to above, but for non-type template or template template parameters. 272 template <typename NonTypeTemplateOrTemplateTemplateParmDecl> 273 NonTypeTemplateOrTemplateTemplateParmDecl * 274 transformTemplateParam(Sema &SemaRef, DeclContext *DC, 275 NonTypeTemplateOrTemplateTemplateParmDecl *OldParam, 276 MultiLevelTemplateArgumentList &Args, unsigned NewIndex, 277 unsigned NewDepth) { 278 // Ask the template instantiator to do the heavy lifting for us, then adjust 279 // the index of the parameter once it's done. 280 auto *NewParam = cast<NonTypeTemplateOrTemplateTemplateParmDecl>( 281 SemaRef.SubstDecl(OldParam, DC, Args)); 282 NewParam->setPosition(NewIndex); 283 NewParam->setDepth(NewDepth); 284 return NewParam; 285 } 286 287 NamedDecl *transformTemplateParameter(Sema &SemaRef, DeclContext *DC, 288 NamedDecl *TemplateParam, 289 MultiLevelTemplateArgumentList &Args, 290 unsigned NewIndex, unsigned NewDepth, 291 bool EvaluateConstraint = true) { 292 if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam)) 293 return transformTemplateTypeParam( 294 SemaRef, DC, TTP, Args, NewDepth, NewIndex, 295 /*EvaluateConstraint=*/EvaluateConstraint); 296 if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam)) 297 return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex, NewDepth); 298 if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam)) 299 return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex, NewDepth); 300 llvm_unreachable("Unhandled template parameter types"); 301 } 302 303 /// Transform to convert portions of a constructor declaration into the 304 /// corresponding deduction guide, per C++1z [over.match.class.deduct]p1. 305 struct ConvertConstructorToDeductionGuideTransform { 306 ConvertConstructorToDeductionGuideTransform(Sema &S, 307 ClassTemplateDecl *Template) 308 : SemaRef(S), Template(Template) { 309 // If the template is nested, then we need to use the original 310 // pattern to iterate over the constructors. 311 ClassTemplateDecl *Pattern = Template; 312 while (Pattern->getInstantiatedFromMemberTemplate()) { 313 if (Pattern->isMemberSpecialization()) 314 break; 315 Pattern = Pattern->getInstantiatedFromMemberTemplate(); 316 NestedPattern = Pattern; 317 } 318 319 if (NestedPattern) 320 OuterInstantiationArgs = SemaRef.getTemplateInstantiationArgs(Template); 321 } 322 323 Sema &SemaRef; 324 ClassTemplateDecl *Template; 325 ClassTemplateDecl *NestedPattern = nullptr; 326 327 DeclContext *DC = Template->getDeclContext(); 328 CXXRecordDecl *Primary = Template->getTemplatedDecl(); 329 DeclarationName DeductionGuideName = 330 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(Template); 331 332 QualType DeducedType = SemaRef.Context.getTypeDeclType(Primary); 333 334 // Index adjustment to apply to convert depth-1 template parameters into 335 // depth-0 template parameters. 336 unsigned Depth1IndexAdjustment = Template->getTemplateParameters()->size(); 337 338 // Instantiation arguments for the outermost depth-1 templates 339 // when the template is nested 340 MultiLevelTemplateArgumentList OuterInstantiationArgs; 341 342 /// Transform a constructor declaration into a deduction guide. 343 NamedDecl *transformConstructor(FunctionTemplateDecl *FTD, 344 CXXConstructorDecl *CD) { 345 SmallVector<TemplateArgument, 16> SubstArgs; 346 347 LocalInstantiationScope Scope(SemaRef); 348 349 // C++ [over.match.class.deduct]p1: 350 // -- For each constructor of the class template designated by the 351 // template-name, a function template with the following properties: 352 353 // -- The template parameters are the template parameters of the class 354 // template followed by the template parameters (including default 355 // template arguments) of the constructor, if any. 356 TemplateParameterList *TemplateParams = 357 SemaRef.GetTemplateParameterList(Template); 358 if (FTD) { 359 TemplateParameterList *InnerParams = FTD->getTemplateParameters(); 360 SmallVector<NamedDecl *, 16> AllParams; 361 SmallVector<TemplateArgument, 16> Depth1Args; 362 AllParams.reserve(TemplateParams->size() + InnerParams->size()); 363 AllParams.insert(AllParams.begin(), TemplateParams->begin(), 364 TemplateParams->end()); 365 SubstArgs.reserve(InnerParams->size()); 366 Depth1Args.reserve(InnerParams->size()); 367 368 // Later template parameters could refer to earlier ones, so build up 369 // a list of substituted template arguments as we go. 370 for (NamedDecl *Param : *InnerParams) { 371 MultiLevelTemplateArgumentList Args; 372 Args.setKind(TemplateSubstitutionKind::Rewrite); 373 Args.addOuterTemplateArguments(Depth1Args); 374 Args.addOuterRetainedLevel(); 375 if (NestedPattern) 376 Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth()); 377 auto [Depth, Index] = getDepthAndIndex(Param); 378 NamedDecl *NewParam = transformTemplateParameter( 379 SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment, Depth - 1); 380 if (!NewParam) 381 return nullptr; 382 // Constraints require that we substitute depth-1 arguments 383 // to match depths when substituted for evaluation later 384 Depth1Args.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam)); 385 386 if (NestedPattern) { 387 auto [Depth, Index] = getDepthAndIndex(NewParam); 388 NewParam = transformTemplateParameter( 389 SemaRef, DC, NewParam, OuterInstantiationArgs, Index, 390 Depth - OuterInstantiationArgs.getNumSubstitutedLevels(), 391 /*EvaluateConstraint=*/false); 392 } 393 394 assert(NewParam->getTemplateDepth() == 0 && 395 "Unexpected template parameter depth"); 396 397 AllParams.push_back(NewParam); 398 SubstArgs.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam)); 399 } 400 401 // Substitute new template parameters into requires-clause if present. 402 Expr *RequiresClause = nullptr; 403 if (Expr *InnerRC = InnerParams->getRequiresClause()) { 404 MultiLevelTemplateArgumentList Args; 405 Args.setKind(TemplateSubstitutionKind::Rewrite); 406 Args.addOuterTemplateArguments(Depth1Args); 407 Args.addOuterRetainedLevel(); 408 if (NestedPattern) 409 Args.addOuterRetainedLevels(NestedPattern->getTemplateDepth()); 410 ExprResult E = SemaRef.SubstExpr(InnerRC, Args); 411 if (E.isInvalid()) 412 return nullptr; 413 RequiresClause = E.getAs<Expr>(); 414 } 415 416 TemplateParams = TemplateParameterList::Create( 417 SemaRef.Context, InnerParams->getTemplateLoc(), 418 InnerParams->getLAngleLoc(), AllParams, InnerParams->getRAngleLoc(), 419 RequiresClause); 420 } 421 422 // If we built a new template-parameter-list, track that we need to 423 // substitute references to the old parameters into references to the 424 // new ones. 425 MultiLevelTemplateArgumentList Args; 426 Args.setKind(TemplateSubstitutionKind::Rewrite); 427 if (FTD) { 428 Args.addOuterTemplateArguments(SubstArgs); 429 Args.addOuterRetainedLevel(); 430 } 431 432 FunctionProtoTypeLoc FPTL = CD->getTypeSourceInfo() 433 ->getTypeLoc() 434 .getAsAdjusted<FunctionProtoTypeLoc>(); 435 assert(FPTL && "no prototype for constructor declaration"); 436 437 // Transform the type of the function, adjusting the return type and 438 // replacing references to the old parameters with references to the 439 // new ones. 440 TypeLocBuilder TLB; 441 SmallVector<ParmVarDecl *, 8> Params; 442 SmallVector<TypedefNameDecl *, 4> MaterializedTypedefs; 443 QualType NewType = transformFunctionProtoType(TLB, FPTL, Params, Args, 444 MaterializedTypedefs); 445 if (NewType.isNull()) 446 return nullptr; 447 TypeSourceInfo *NewTInfo = TLB.getTypeSourceInfo(SemaRef.Context, NewType); 448 449 return buildDeductionGuide( 450 SemaRef, Template, TemplateParams, CD, CD->getExplicitSpecifier(), 451 NewTInfo, CD->getBeginLoc(), CD->getLocation(), CD->getEndLoc(), 452 /*IsImplicit=*/true, MaterializedTypedefs); 453 } 454 455 /// Build a deduction guide with the specified parameter types. 456 NamedDecl *buildSimpleDeductionGuide(MutableArrayRef<QualType> ParamTypes) { 457 SourceLocation Loc = Template->getLocation(); 458 459 // Build the requested type. 460 FunctionProtoType::ExtProtoInfo EPI; 461 EPI.HasTrailingReturn = true; 462 QualType Result = SemaRef.BuildFunctionType(DeducedType, ParamTypes, Loc, 463 DeductionGuideName, EPI); 464 TypeSourceInfo *TSI = SemaRef.Context.getTrivialTypeSourceInfo(Result, Loc); 465 if (NestedPattern) 466 TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc, 467 DeductionGuideName); 468 469 if (!TSI) 470 return nullptr; 471 472 FunctionProtoTypeLoc FPTL = 473 TSI->getTypeLoc().castAs<FunctionProtoTypeLoc>(); 474 475 // Build the parameters, needed during deduction / substitution. 476 SmallVector<ParmVarDecl *, 4> Params; 477 for (auto T : ParamTypes) { 478 auto *TSI = SemaRef.Context.getTrivialTypeSourceInfo(T, Loc); 479 if (NestedPattern) 480 TSI = SemaRef.SubstType(TSI, OuterInstantiationArgs, Loc, 481 DeclarationName()); 482 if (!TSI) 483 return nullptr; 484 485 ParmVarDecl *NewParam = 486 ParmVarDecl::Create(SemaRef.Context, DC, Loc, Loc, nullptr, 487 TSI->getType(), TSI, SC_None, nullptr); 488 NewParam->setScopeInfo(0, Params.size()); 489 FPTL.setParam(Params.size(), NewParam); 490 Params.push_back(NewParam); 491 } 492 493 return buildDeductionGuide( 494 SemaRef, Template, SemaRef.GetTemplateParameterList(Template), nullptr, 495 ExplicitSpecifier(), TSI, Loc, Loc, Loc, /*IsImplicit=*/true); 496 } 497 498 private: 499 QualType transformFunctionProtoType( 500 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, 501 SmallVectorImpl<ParmVarDecl *> &Params, 502 MultiLevelTemplateArgumentList &Args, 503 SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs) { 504 SmallVector<QualType, 4> ParamTypes; 505 const FunctionProtoType *T = TL.getTypePtr(); 506 507 // -- The types of the function parameters are those of the constructor. 508 for (auto *OldParam : TL.getParams()) { 509 ParmVarDecl *NewParam = OldParam; 510 // Given 511 // template <class T> struct C { 512 // template <class U> struct D { 513 // template <class V> D(U, V); 514 // }; 515 // }; 516 // First, transform all the references to template parameters that are 517 // defined outside of the surrounding class template. That is T in the 518 // above example. 519 if (NestedPattern) { 520 NewParam = transformFunctionTypeParam( 521 NewParam, OuterInstantiationArgs, MaterializedTypedefs, 522 /*TransformingOuterPatterns=*/true); 523 if (!NewParam) 524 return QualType(); 525 } 526 // Then, transform all the references to template parameters that are 527 // defined at the class template and the constructor. In this example, 528 // they're U and V, respectively. 529 NewParam = 530 transformFunctionTypeParam(NewParam, Args, MaterializedTypedefs, 531 /*TransformingOuterPatterns=*/false); 532 if (!NewParam) 533 return QualType(); 534 ParamTypes.push_back(NewParam->getType()); 535 Params.push_back(NewParam); 536 } 537 538 // -- The return type is the class template specialization designated by 539 // the template-name and template arguments corresponding to the 540 // template parameters obtained from the class template. 541 // 542 // We use the injected-class-name type of the primary template instead. 543 // This has the convenient property that it is different from any type that 544 // the user can write in a deduction-guide (because they cannot enter the 545 // context of the template), so implicit deduction guides can never collide 546 // with explicit ones. 547 QualType ReturnType = DeducedType; 548 TLB.pushTypeSpec(ReturnType).setNameLoc(Primary->getLocation()); 549 550 // Resolving a wording defect, we also inherit the variadicness of the 551 // constructor. 552 FunctionProtoType::ExtProtoInfo EPI; 553 EPI.Variadic = T->isVariadic(); 554 EPI.HasTrailingReturn = true; 555 556 QualType Result = SemaRef.BuildFunctionType( 557 ReturnType, ParamTypes, TL.getBeginLoc(), DeductionGuideName, EPI); 558 if (Result.isNull()) 559 return QualType(); 560 561 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result); 562 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin()); 563 NewTL.setLParenLoc(TL.getLParenLoc()); 564 NewTL.setRParenLoc(TL.getRParenLoc()); 565 NewTL.setExceptionSpecRange(SourceRange()); 566 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd()); 567 for (unsigned I = 0, E = NewTL.getNumParams(); I != E; ++I) 568 NewTL.setParam(I, Params[I]); 569 570 return Result; 571 } 572 573 ParmVarDecl *transformFunctionTypeParam( 574 ParmVarDecl *OldParam, MultiLevelTemplateArgumentList &Args, 575 llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs, 576 bool TransformingOuterPatterns) { 577 TypeSourceInfo *OldDI = OldParam->getTypeSourceInfo(); 578 TypeSourceInfo *NewDI; 579 if (auto PackTL = OldDI->getTypeLoc().getAs<PackExpansionTypeLoc>()) { 580 // Expand out the one and only element in each inner pack. 581 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, 0); 582 NewDI = 583 SemaRef.SubstType(PackTL.getPatternLoc(), Args, 584 OldParam->getLocation(), OldParam->getDeclName()); 585 if (!NewDI) 586 return nullptr; 587 NewDI = 588 SemaRef.CheckPackExpansion(NewDI, PackTL.getEllipsisLoc(), 589 PackTL.getTypePtr()->getNumExpansions()); 590 } else 591 NewDI = SemaRef.SubstType(OldDI, Args, OldParam->getLocation(), 592 OldParam->getDeclName()); 593 if (!NewDI) 594 return nullptr; 595 596 // Extract the type. This (for instance) replaces references to typedef 597 // members of the current instantiations with the definitions of those 598 // typedefs, avoiding triggering instantiation of the deduced type during 599 // deduction. 600 NewDI = ExtractTypeForDeductionGuide( 601 SemaRef, MaterializedTypedefs, NestedPattern, 602 TransformingOuterPatterns ? &Args : nullptr) 603 .transform(NewDI); 604 605 // Resolving a wording defect, we also inherit default arguments from the 606 // constructor. 607 ExprResult NewDefArg; 608 if (OldParam->hasDefaultArg()) { 609 // We don't care what the value is (we won't use it); just create a 610 // placeholder to indicate there is a default argument. 611 QualType ParamTy = NewDI->getType(); 612 NewDefArg = new (SemaRef.Context) 613 OpaqueValueExpr(OldParam->getDefaultArgRange().getBegin(), 614 ParamTy.getNonLValueExprType(SemaRef.Context), 615 ParamTy->isLValueReferenceType() ? VK_LValue 616 : ParamTy->isRValueReferenceType() ? VK_XValue 617 : VK_PRValue); 618 } 619 // Handle arrays and functions decay. 620 auto NewType = NewDI->getType(); 621 if (NewType->isArrayType() || NewType->isFunctionType()) 622 NewType = SemaRef.Context.getDecayedType(NewType); 623 624 ParmVarDecl *NewParam = ParmVarDecl::Create( 625 SemaRef.Context, DC, OldParam->getInnerLocStart(), 626 OldParam->getLocation(), OldParam->getIdentifier(), NewType, NewDI, 627 OldParam->getStorageClass(), NewDefArg.get()); 628 NewParam->setScopeInfo(OldParam->getFunctionScopeDepth(), 629 OldParam->getFunctionScopeIndex()); 630 SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam); 631 return NewParam; 632 } 633 }; 634 635 // Find all template parameters that appear in the given DeducedArgs. 636 // Return the indices of the template parameters in the TemplateParams. 637 SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList( 638 const TemplateParameterList *TemplateParamsList, 639 ArrayRef<TemplateArgument> DeducedArgs) { 640 struct TemplateParamsReferencedFinder 641 : public RecursiveASTVisitor<TemplateParamsReferencedFinder> { 642 const TemplateParameterList *TemplateParamList; 643 llvm::BitVector ReferencedTemplateParams; 644 645 TemplateParamsReferencedFinder( 646 const TemplateParameterList *TemplateParamList) 647 : TemplateParamList(TemplateParamList), 648 ReferencedTemplateParams(TemplateParamList->size()) {} 649 650 bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) { 651 // We use the index and depth to retrieve the corresponding template 652 // parameter from the parameter list, which is more robost. 653 Mark(TTP->getDepth(), TTP->getIndex()); 654 return true; 655 } 656 657 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 658 MarkAppeared(DRE->getFoundDecl()); 659 return true; 660 } 661 662 bool TraverseTemplateName(TemplateName Template) { 663 if (auto *TD = Template.getAsTemplateDecl()) 664 MarkAppeared(TD); 665 return RecursiveASTVisitor::TraverseTemplateName(Template); 666 } 667 668 void MarkAppeared(NamedDecl *ND) { 669 if (llvm::isa<NonTypeTemplateParmDecl, TemplateTypeParmDecl, 670 TemplateTemplateParmDecl>(ND)) { 671 auto [Depth, Index] = getDepthAndIndex(ND); 672 Mark(Depth, Index); 673 } 674 } 675 void Mark(unsigned Depth, unsigned Index) { 676 if (Index < TemplateParamList->size() && 677 TemplateParamList->getParam(Index)->getTemplateDepth() == Depth) 678 ReferencedTemplateParams.set(Index); 679 } 680 }; 681 TemplateParamsReferencedFinder Finder(TemplateParamsList); 682 Finder.TraverseTemplateArguments(DeducedArgs); 683 684 SmallVector<unsigned> Results; 685 for (unsigned Index = 0; Index < TemplateParamsList->size(); ++Index) { 686 if (Finder.ReferencedTemplateParams[Index]) 687 Results.push_back(Index); 688 } 689 return Results; 690 } 691 692 bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) { 693 // Check whether we've already declared deduction guides for this template. 694 // FIXME: Consider storing a flag on the template to indicate this. 695 assert(Name.getNameKind() == 696 DeclarationName::NameKind::CXXDeductionGuideName && 697 "name must be a deduction guide name"); 698 auto Existing = DC->lookup(Name); 699 for (auto *D : Existing) 700 if (D->isImplicit()) 701 return true; 702 return false; 703 } 704 705 // Build the associated constraints for the alias deduction guides. 706 // C++ [over.match.class.deduct]p3.3: 707 // The associated constraints ([temp.constr.decl]) are the conjunction of the 708 // associated constraints of g and a constraint that is satisfied if and only 709 // if the arguments of A are deducible (see below) from the return type. 710 // 711 // The return result is expected to be the require-clause for the synthesized 712 // alias deduction guide. 713 Expr * 714 buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F, 715 TypeAliasTemplateDecl *AliasTemplate, 716 ArrayRef<DeducedTemplateArgument> DeduceResults, 717 unsigned FirstUndeducedParamIdx, Expr *IsDeducible) { 718 Expr *RC = F->getTemplateParameters()->getRequiresClause(); 719 if (!RC) 720 return IsDeducible; 721 722 ASTContext &Context = SemaRef.Context; 723 LocalInstantiationScope Scope(SemaRef); 724 725 // In the clang AST, constraint nodes are deliberately not instantiated unless 726 // they are actively being evaluated. Consequently, occurrences of template 727 // parameters in the require-clause expression have a subtle "depth" 728 // difference compared to normal occurrences in places, such as function 729 // parameters. When transforming the require-clause, we must take this 730 // distinction into account: 731 // 732 // 1) In the transformed require-clause, occurrences of template parameters 733 // must use the "uninstantiated" depth; 734 // 2) When substituting on the require-clause expr of the underlying 735 // deduction guide, we must use the entire set of template argument lists; 736 // 737 // It's important to note that we're performing this transformation on an 738 // *instantiated* AliasTemplate. 739 740 // For 1), if the alias template is nested within a class template, we 741 // calcualte the 'uninstantiated' depth by adding the substitution level back. 742 unsigned AdjustDepth = 0; 743 if (auto *PrimaryTemplate = 744 AliasTemplate->getInstantiatedFromMemberTemplate()) 745 AdjustDepth = PrimaryTemplate->getTemplateDepth(); 746 747 // We rebuild all template parameters with the uninstantiated depth, and 748 // build template arguments refer to them. 749 SmallVector<TemplateArgument> AdjustedAliasTemplateArgs; 750 751 for (auto *TP : *AliasTemplate->getTemplateParameters()) { 752 // Rebuild any internal references to earlier parameters and reindex 753 // as we go. 754 MultiLevelTemplateArgumentList Args; 755 Args.setKind(TemplateSubstitutionKind::Rewrite); 756 Args.addOuterTemplateArguments(AdjustedAliasTemplateArgs); 757 NamedDecl *NewParam = transformTemplateParameter( 758 SemaRef, AliasTemplate->getDeclContext(), TP, Args, 759 /*NewIndex=*/AdjustedAliasTemplateArgs.size(), 760 getDepthAndIndex(TP).first + AdjustDepth); 761 762 TemplateArgument NewTemplateArgument = 763 Context.getInjectedTemplateArg(NewParam); 764 AdjustedAliasTemplateArgs.push_back(NewTemplateArgument); 765 } 766 // Template arguments used to transform the template arguments in 767 // DeducedResults. 768 SmallVector<TemplateArgument> TemplateArgsForBuildingRC( 769 F->getTemplateParameters()->size()); 770 // Transform the transformed template args 771 MultiLevelTemplateArgumentList Args; 772 Args.setKind(TemplateSubstitutionKind::Rewrite); 773 Args.addOuterTemplateArguments(AdjustedAliasTemplateArgs); 774 775 for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) { 776 const auto &D = DeduceResults[Index]; 777 if (D.isNull()) { // non-deduced template parameters of f 778 NamedDecl *TP = F->getTemplateParameters()->getParam(Index); 779 MultiLevelTemplateArgumentList Args; 780 Args.setKind(TemplateSubstitutionKind::Rewrite); 781 Args.addOuterTemplateArguments(TemplateArgsForBuildingRC); 782 // Rebuild the template parameter with updated depth and index. 783 NamedDecl *NewParam = 784 transformTemplateParameter(SemaRef, F->getDeclContext(), TP, Args, 785 /*NewIndex=*/FirstUndeducedParamIdx, 786 getDepthAndIndex(TP).first + AdjustDepth); 787 FirstUndeducedParamIdx += 1; 788 assert(TemplateArgsForBuildingRC[Index].isNull()); 789 TemplateArgsForBuildingRC[Index] = 790 Context.getInjectedTemplateArg(NewParam); 791 continue; 792 } 793 TemplateArgumentLoc Input = 794 SemaRef.getTrivialTemplateArgumentLoc(D, QualType(), SourceLocation{}); 795 TemplateArgumentLoc Output; 796 if (!SemaRef.SubstTemplateArgument(Input, Args, Output)) { 797 assert(TemplateArgsForBuildingRC[Index].isNull() && 798 "InstantiatedArgs must be null before setting"); 799 TemplateArgsForBuildingRC[Index] = Output.getArgument(); 800 } 801 } 802 803 // A list of template arguments for transforming the require-clause of F. 804 // It must contain the entire set of template argument lists. 805 MultiLevelTemplateArgumentList ArgsForBuildingRC; 806 ArgsForBuildingRC.setKind(clang::TemplateSubstitutionKind::Rewrite); 807 ArgsForBuildingRC.addOuterTemplateArguments(TemplateArgsForBuildingRC); 808 // For 2), if the underlying deduction guide F is nested in a class template, 809 // we need the entire template argument list, as the constraint AST in the 810 // require-clause of F remains completely uninstantiated. 811 // 812 // For example: 813 // template <typename T> // depth 0 814 // struct Outer { 815 // template <typename U> 816 // struct Foo { Foo(U); }; 817 // 818 // template <typename U> // depth 1 819 // requires C<U> 820 // Foo(U) -> Foo<int>; 821 // }; 822 // template <typename U> 823 // using AFoo = Outer<int>::Foo<U>; 824 // 825 // In this scenario, the deduction guide for `Foo` inside `Outer<int>`: 826 // - The occurrence of U in the require-expression is [depth:1, index:0] 827 // - The occurrence of U in the function parameter is [depth:0, index:0] 828 // - The template parameter of U is [depth:0, index:0] 829 // 830 // We add the outer template arguments which is [int] to the multi-level arg 831 // list to ensure that the occurrence U in `C<U>` will be replaced with int 832 // during the substitution. 833 // 834 // NOTE: The underlying deduction guide F is instantiated -- either from an 835 // explicitly-written deduction guide member, or from a constructor. 836 // getInstantiatedFromMemberTemplate() can only handle the former case, so we 837 // check the DeclContext kind. 838 if (F->getLexicalDeclContext()->getDeclKind() == 839 clang::Decl::ClassTemplateSpecialization) { 840 auto OuterLevelArgs = SemaRef.getTemplateInstantiationArgs( 841 F, F->getLexicalDeclContext(), 842 /*Final=*/false, /*Innermost=*/std::nullopt, 843 /*RelativeToPrimary=*/true, 844 /*Pattern=*/nullptr, 845 /*ForConstraintInstantiation=*/true); 846 for (auto It : OuterLevelArgs) 847 ArgsForBuildingRC.addOuterTemplateArguments(It.Args); 848 } 849 850 ExprResult E = SemaRef.SubstExpr(RC, ArgsForBuildingRC); 851 if (E.isInvalid()) 852 return nullptr; 853 854 auto Conjunction = 855 SemaRef.BuildBinOp(SemaRef.getCurScope(), SourceLocation{}, 856 BinaryOperatorKind::BO_LAnd, E.get(), IsDeducible); 857 if (Conjunction.isInvalid()) 858 return nullptr; 859 return Conjunction.getAs<Expr>(); 860 } 861 // Build the is_deducible constraint for the alias deduction guides. 862 // [over.match.class.deduct]p3.3: 863 // ... and a constraint that is satisfied if and only if the arguments 864 // of A are deducible (see below) from the return type. 865 Expr *buildIsDeducibleConstraint(Sema &SemaRef, 866 TypeAliasTemplateDecl *AliasTemplate, 867 QualType ReturnType, 868 SmallVector<NamedDecl *> TemplateParams) { 869 ASTContext &Context = SemaRef.Context; 870 // Constraint AST nodes must use uninstantiated depth. 871 if (auto *PrimaryTemplate = 872 AliasTemplate->getInstantiatedFromMemberTemplate(); 873 PrimaryTemplate && TemplateParams.size() > 0) { 874 LocalInstantiationScope Scope(SemaRef); 875 876 // Adjust the depth for TemplateParams. 877 unsigned AdjustDepth = PrimaryTemplate->getTemplateDepth(); 878 SmallVector<TemplateArgument> TransformedTemplateArgs; 879 for (auto *TP : TemplateParams) { 880 // Rebuild any internal references to earlier parameters and reindex 881 // as we go. 882 MultiLevelTemplateArgumentList Args; 883 Args.setKind(TemplateSubstitutionKind::Rewrite); 884 Args.addOuterTemplateArguments(TransformedTemplateArgs); 885 NamedDecl *NewParam = transformTemplateParameter( 886 SemaRef, AliasTemplate->getDeclContext(), TP, Args, 887 /*NewIndex=*/TransformedTemplateArgs.size(), 888 getDepthAndIndex(TP).first + AdjustDepth); 889 890 TemplateArgument NewTemplateArgument = 891 Context.getInjectedTemplateArg(NewParam); 892 TransformedTemplateArgs.push_back(NewTemplateArgument); 893 } 894 // Transformed the ReturnType to restore the uninstantiated depth. 895 MultiLevelTemplateArgumentList Args; 896 Args.setKind(TemplateSubstitutionKind::Rewrite); 897 Args.addOuterTemplateArguments(TransformedTemplateArgs); 898 ReturnType = SemaRef.SubstType( 899 ReturnType, Args, AliasTemplate->getLocation(), 900 Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate)); 901 }; 902 903 SmallVector<TypeSourceInfo *> IsDeducibleTypeTraitArgs = { 904 Context.getTrivialTypeSourceInfo( 905 Context.getDeducedTemplateSpecializationType( 906 TemplateName(AliasTemplate), /*DeducedType=*/QualType(), 907 /*IsDependent=*/true)), // template specialization type whose 908 // arguments will be deduced. 909 Context.getTrivialTypeSourceInfo( 910 ReturnType), // type from which template arguments are deduced. 911 }; 912 return TypeTraitExpr::Create( 913 Context, Context.getLogicalOperationType(), AliasTemplate->getLocation(), 914 TypeTrait::BTT_IsDeducible, IsDeducibleTypeTraitArgs, 915 AliasTemplate->getLocation(), /*Value*/ false); 916 } 917 918 std::pair<TemplateDecl *, llvm::ArrayRef<TemplateArgument>> 919 getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) { 920 // Unwrap the sugared ElaboratedType. 921 auto RhsType = AliasTemplate->getTemplatedDecl() 922 ->getUnderlyingType() 923 .getSingleStepDesugaredType(SemaRef.Context); 924 TemplateDecl *Template = nullptr; 925 llvm::ArrayRef<TemplateArgument> AliasRhsTemplateArgs; 926 if (const auto *TST = RhsType->getAs<TemplateSpecializationType>()) { 927 // Cases where the RHS of the alias is dependent. e.g. 928 // template<typename T> 929 // using AliasFoo1 = Foo<T>; // a class/type alias template specialization 930 Template = TST->getTemplateName().getAsTemplateDecl(); 931 AliasRhsTemplateArgs = TST->template_arguments(); 932 } else if (const auto *RT = RhsType->getAs<RecordType>()) { 933 // Cases where template arguments in the RHS of the alias are not 934 // dependent. e.g. 935 // using AliasFoo = Foo<bool>; 936 if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>( 937 RT->getAsCXXRecordDecl())) { 938 Template = CTSD->getSpecializedTemplate(); 939 AliasRhsTemplateArgs = CTSD->getTemplateArgs().asArray(); 940 } 941 } else { 942 assert(false && "unhandled RHS type of the alias"); 943 } 944 return {Template, AliasRhsTemplateArgs}; 945 } 946 947 // Build deduction guides for a type alias template from the given underlying 948 // deduction guide F. 949 FunctionTemplateDecl * 950 BuildDeductionGuideForTypeAlias(Sema &SemaRef, 951 TypeAliasTemplateDecl *AliasTemplate, 952 FunctionTemplateDecl *F, SourceLocation Loc) { 953 LocalInstantiationScope Scope(SemaRef); 954 Sema::InstantiatingTemplate BuildingDeductionGuides( 955 SemaRef, AliasTemplate->getLocation(), F, 956 Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{}); 957 if (BuildingDeductionGuides.isInvalid()) 958 return nullptr; 959 960 auto &Context = SemaRef.Context; 961 auto [Template, AliasRhsTemplateArgs] = 962 getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate); 963 964 auto RType = F->getTemplatedDecl()->getReturnType(); 965 // The (trailing) return type of the deduction guide. 966 const TemplateSpecializationType *FReturnType = 967 RType->getAs<TemplateSpecializationType>(); 968 if (const auto *InjectedCNT = RType->getAs<InjectedClassNameType>()) 969 // implicitly-generated deduction guide. 970 FReturnType = InjectedCNT->getInjectedTST(); 971 else if (const auto *ET = RType->getAs<ElaboratedType>()) 972 // explicit deduction guide. 973 FReturnType = ET->getNamedType()->getAs<TemplateSpecializationType>(); 974 assert(FReturnType && "expected to see a return type"); 975 // Deduce template arguments of the deduction guide f from the RHS of 976 // the alias. 977 // 978 // C++ [over.match.class.deduct]p3: ...For each function or function 979 // template f in the guides of the template named by the 980 // simple-template-id of the defining-type-id, the template arguments 981 // of the return type of f are deduced from the defining-type-id of A 982 // according to the process in [temp.deduct.type] with the exception 983 // that deduction does not fail if not all template arguments are 984 // deduced. 985 // 986 // 987 // template<typename X, typename Y> 988 // f(X, Y) -> f<Y, X>; 989 // 990 // template<typename U> 991 // using alias = f<int, U>; 992 // 993 // The RHS of alias is f<int, U>, we deduced the template arguments of 994 // the return type of the deduction guide from it: Y->int, X->U 995 sema::TemplateDeductionInfo TDeduceInfo(Loc); 996 // Must initialize n elements, this is required by DeduceTemplateArguments. 997 SmallVector<DeducedTemplateArgument> DeduceResults( 998 F->getTemplateParameters()->size()); 999 1000 // FIXME: DeduceTemplateArguments stops immediately at the first 1001 // non-deducible template argument. However, this doesn't seem to casue 1002 // issues for practice cases, we probably need to extend it to continue 1003 // performing deduction for rest of arguments to align with the C++ 1004 // standard. 1005 SemaRef.DeduceTemplateArguments( 1006 F->getTemplateParameters(), FReturnType->template_arguments(), 1007 AliasRhsTemplateArgs, TDeduceInfo, DeduceResults, 1008 /*NumberOfArgumentsMustMatch=*/false); 1009 1010 SmallVector<TemplateArgument> DeducedArgs; 1011 SmallVector<unsigned> NonDeducedTemplateParamsInFIndex; 1012 // !!NOTE: DeduceResults respects the sequence of template parameters of 1013 // the deduction guide f. 1014 for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) { 1015 if (const auto &D = DeduceResults[Index]; !D.isNull()) // Deduced 1016 DeducedArgs.push_back(D); 1017 else 1018 NonDeducedTemplateParamsInFIndex.push_back(Index); 1019 } 1020 auto DeducedAliasTemplateParams = 1021 TemplateParamsReferencedInTemplateArgumentList( 1022 AliasTemplate->getTemplateParameters(), DeducedArgs); 1023 // All template arguments null by default. 1024 SmallVector<TemplateArgument> TemplateArgsForBuildingFPrime( 1025 F->getTemplateParameters()->size()); 1026 1027 // Create a template parameter list for the synthesized deduction guide f'. 1028 // 1029 // C++ [over.match.class.deduct]p3.2: 1030 // If f is a function template, f' is a function template whose template 1031 // parameter list consists of all the template parameters of A 1032 // (including their default template arguments) that appear in the above 1033 // deductions or (recursively) in their default template arguments 1034 SmallVector<NamedDecl *> FPrimeTemplateParams; 1035 // Store template arguments that refer to the newly-created template 1036 // parameters, used for building `TemplateArgsForBuildingFPrime`. 1037 SmallVector<TemplateArgument, 16> TransformedDeducedAliasArgs( 1038 AliasTemplate->getTemplateParameters()->size()); 1039 1040 for (unsigned AliasTemplateParamIdx : DeducedAliasTemplateParams) { 1041 auto *TP = 1042 AliasTemplate->getTemplateParameters()->getParam(AliasTemplateParamIdx); 1043 // Rebuild any internal references to earlier parameters and reindex as 1044 // we go. 1045 MultiLevelTemplateArgumentList Args; 1046 Args.setKind(TemplateSubstitutionKind::Rewrite); 1047 Args.addOuterTemplateArguments(TransformedDeducedAliasArgs); 1048 NamedDecl *NewParam = transformTemplateParameter( 1049 SemaRef, AliasTemplate->getDeclContext(), TP, Args, 1050 /*NewIndex=*/FPrimeTemplateParams.size(), getDepthAndIndex(TP).first); 1051 FPrimeTemplateParams.push_back(NewParam); 1052 1053 TemplateArgument NewTemplateArgument = 1054 Context.getInjectedTemplateArg(NewParam); 1055 TransformedDeducedAliasArgs[AliasTemplateParamIdx] = NewTemplateArgument; 1056 } 1057 unsigned FirstUndeducedParamIdx = FPrimeTemplateParams.size(); 1058 // ...followed by the template parameters of f that were not deduced 1059 // (including their default template arguments) 1060 for (unsigned FTemplateParamIdx : NonDeducedTemplateParamsInFIndex) { 1061 auto *TP = F->getTemplateParameters()->getParam(FTemplateParamIdx); 1062 MultiLevelTemplateArgumentList Args; 1063 Args.setKind(TemplateSubstitutionKind::Rewrite); 1064 // We take a shortcut here, it is ok to reuse the 1065 // TemplateArgsForBuildingFPrime. 1066 Args.addOuterTemplateArguments(TemplateArgsForBuildingFPrime); 1067 NamedDecl *NewParam = transformTemplateParameter( 1068 SemaRef, F->getDeclContext(), TP, Args, FPrimeTemplateParams.size(), 1069 getDepthAndIndex(TP).first); 1070 FPrimeTemplateParams.push_back(NewParam); 1071 1072 assert(TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull() && 1073 "The argument must be null before setting"); 1074 TemplateArgsForBuildingFPrime[FTemplateParamIdx] = 1075 Context.getInjectedTemplateArg(NewParam); 1076 } 1077 1078 // To form a deduction guide f' from f, we leverage clang's instantiation 1079 // mechanism, we construct a template argument list where the template 1080 // arguments refer to the newly-created template parameters of f', and 1081 // then apply instantiation on this template argument list to instantiate 1082 // f, this ensures all template parameter occurrences are updated 1083 // correctly. 1084 // 1085 // The template argument list is formed from the `DeducedArgs`, two parts: 1086 // 1) appeared template parameters of alias: transfrom the deduced 1087 // template argument; 1088 // 2) non-deduced template parameters of f: rebuild a 1089 // template argument; 1090 // 1091 // 2) has been built already (when rebuilding the new template 1092 // parameters), we now perform 1). 1093 MultiLevelTemplateArgumentList Args; 1094 Args.setKind(TemplateSubstitutionKind::Rewrite); 1095 Args.addOuterTemplateArguments(TransformedDeducedAliasArgs); 1096 for (unsigned Index = 0; Index < DeduceResults.size(); ++Index) { 1097 const auto &D = DeduceResults[Index]; 1098 if (D.isNull()) { 1099 // 2): Non-deduced template parameter has been built already. 1100 assert(!TemplateArgsForBuildingFPrime[Index].isNull() && 1101 "template arguments for non-deduced template parameters should " 1102 "be been set!"); 1103 continue; 1104 } 1105 TemplateArgumentLoc Input = 1106 SemaRef.getTrivialTemplateArgumentLoc(D, QualType(), SourceLocation{}); 1107 TemplateArgumentLoc Output; 1108 if (!SemaRef.SubstTemplateArgument(Input, Args, Output)) { 1109 assert(TemplateArgsForBuildingFPrime[Index].isNull() && 1110 "InstantiatedArgs must be null before setting"); 1111 TemplateArgsForBuildingFPrime[Index] = Output.getArgument(); 1112 } 1113 } 1114 1115 auto *TemplateArgListForBuildingFPrime = 1116 TemplateArgumentList::CreateCopy(Context, TemplateArgsForBuildingFPrime); 1117 // Form the f' by substituting the template arguments into f. 1118 if (auto *FPrime = SemaRef.InstantiateFunctionDeclaration( 1119 F, TemplateArgListForBuildingFPrime, AliasTemplate->getLocation(), 1120 Sema::CodeSynthesisContext::BuildingDeductionGuides)) { 1121 auto *GG = cast<CXXDeductionGuideDecl>(FPrime); 1122 1123 Expr *IsDeducible = buildIsDeducibleConstraint( 1124 SemaRef, AliasTemplate, FPrime->getReturnType(), FPrimeTemplateParams); 1125 Expr *RequiresClause = 1126 buildAssociatedConstraints(SemaRef, F, AliasTemplate, DeduceResults, 1127 FirstUndeducedParamIdx, IsDeducible); 1128 1129 auto *FPrimeTemplateParamList = TemplateParameterList::Create( 1130 Context, AliasTemplate->getTemplateParameters()->getTemplateLoc(), 1131 AliasTemplate->getTemplateParameters()->getLAngleLoc(), 1132 FPrimeTemplateParams, 1133 AliasTemplate->getTemplateParameters()->getRAngleLoc(), 1134 /*RequiresClause=*/RequiresClause); 1135 auto *Result = cast<FunctionTemplateDecl>(buildDeductionGuide( 1136 SemaRef, AliasTemplate, FPrimeTemplateParamList, 1137 GG->getCorrespondingConstructor(), GG->getExplicitSpecifier(), 1138 GG->getTypeSourceInfo(), AliasTemplate->getBeginLoc(), 1139 AliasTemplate->getLocation(), AliasTemplate->getEndLoc(), 1140 F->isImplicit())); 1141 cast<CXXDeductionGuideDecl>(Result->getTemplatedDecl()) 1142 ->setDeductionCandidateKind(GG->getDeductionCandidateKind()); 1143 return Result; 1144 } 1145 return nullptr; 1146 } 1147 1148 void DeclareImplicitDeductionGuidesForTypeAlias( 1149 Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, SourceLocation Loc) { 1150 if (AliasTemplate->isInvalidDecl()) 1151 return; 1152 auto &Context = SemaRef.Context; 1153 // FIXME: if there is an explicit deduction guide after the first use of the 1154 // type alias usage, we will not cover this explicit deduction guide. fix this 1155 // case. 1156 if (hasDeclaredDeductionGuides( 1157 Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate), 1158 AliasTemplate->getDeclContext())) 1159 return; 1160 auto [Template, AliasRhsTemplateArgs] = 1161 getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate); 1162 if (!Template) 1163 return; 1164 DeclarationNameInfo NameInfo( 1165 Context.DeclarationNames.getCXXDeductionGuideName(Template), Loc); 1166 LookupResult Guides(SemaRef, NameInfo, clang::Sema::LookupOrdinaryName); 1167 SemaRef.LookupQualifiedName(Guides, Template->getDeclContext()); 1168 Guides.suppressDiagnostics(); 1169 1170 for (auto *G : Guides) { 1171 if (auto *DG = dyn_cast<CXXDeductionGuideDecl>(G)) { 1172 // The deduction guide is a non-template function decl, we just clone it. 1173 auto *FunctionType = 1174 SemaRef.Context.getTrivialTypeSourceInfo(DG->getType()); 1175 FunctionProtoTypeLoc FPTL = 1176 FunctionType->getTypeLoc().castAs<FunctionProtoTypeLoc>(); 1177 1178 // Clone the parameters. 1179 for (unsigned I = 0, N = DG->getNumParams(); I != N; ++I) { 1180 const auto *P = DG->getParamDecl(I); 1181 auto *TSI = SemaRef.Context.getTrivialTypeSourceInfo(P->getType()); 1182 ParmVarDecl *NewParam = ParmVarDecl::Create( 1183 SemaRef.Context, G->getDeclContext(), 1184 DG->getParamDecl(I)->getBeginLoc(), P->getLocation(), nullptr, 1185 TSI->getType(), TSI, SC_None, nullptr); 1186 NewParam->setScopeInfo(0, I); 1187 FPTL.setParam(I, NewParam); 1188 } 1189 auto *Transformed = cast<FunctionDecl>(buildDeductionGuide( 1190 SemaRef, AliasTemplate, /*TemplateParams=*/nullptr, 1191 /*Constructor=*/nullptr, DG->getExplicitSpecifier(), FunctionType, 1192 AliasTemplate->getBeginLoc(), AliasTemplate->getLocation(), 1193 AliasTemplate->getEndLoc(), DG->isImplicit())); 1194 1195 // FIXME: Here the synthesized deduction guide is not a templated 1196 // function. Per [dcl.decl]p4, the requires-clause shall be present only 1197 // if the declarator declares a templated function, a bug in standard? 1198 auto *Constraint = buildIsDeducibleConstraint( 1199 SemaRef, AliasTemplate, Transformed->getReturnType(), {}); 1200 if (auto *RC = DG->getTrailingRequiresClause()) { 1201 auto Conjunction = 1202 SemaRef.BuildBinOp(SemaRef.getCurScope(), SourceLocation{}, 1203 BinaryOperatorKind::BO_LAnd, RC, Constraint); 1204 if (!Conjunction.isInvalid()) 1205 Constraint = Conjunction.getAs<Expr>(); 1206 } 1207 Transformed->setTrailingRequiresClause(Constraint); 1208 } 1209 FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(G); 1210 if (!F) 1211 continue; 1212 // The **aggregate** deduction guides are handled in a different code path 1213 // (DeclareAggregateDeductionGuideFromInitList), which involves the tricky 1214 // cache. 1215 if (cast<CXXDeductionGuideDecl>(F->getTemplatedDecl()) 1216 ->getDeductionCandidateKind() == DeductionCandidate::Aggregate) 1217 continue; 1218 1219 BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate, F, Loc); 1220 } 1221 } 1222 1223 // Build an aggregate deduction guide for a type alias template. 1224 FunctionTemplateDecl *DeclareAggregateDeductionGuideForTypeAlias( 1225 Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, 1226 MutableArrayRef<QualType> ParamTypes, SourceLocation Loc) { 1227 TemplateDecl *RHSTemplate = 1228 getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate).first; 1229 if (!RHSTemplate) 1230 return nullptr; 1231 auto *RHSDeductionGuide = SemaRef.DeclareAggregateDeductionGuideFromInitList( 1232 RHSTemplate, ParamTypes, Loc); 1233 if (!RHSDeductionGuide) 1234 return nullptr; 1235 return BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate, 1236 RHSDeductionGuide, Loc); 1237 } 1238 1239 } // namespace 1240 1241 FunctionTemplateDecl *Sema::DeclareAggregateDeductionGuideFromInitList( 1242 TemplateDecl *Template, MutableArrayRef<QualType> ParamTypes, 1243 SourceLocation Loc) { 1244 llvm::FoldingSetNodeID ID; 1245 ID.AddPointer(Template); 1246 for (auto &T : ParamTypes) 1247 T.getCanonicalType().Profile(ID); 1248 unsigned Hash = ID.ComputeHash(); 1249 1250 auto Found = AggregateDeductionCandidates.find(Hash); 1251 if (Found != AggregateDeductionCandidates.end()) { 1252 CXXDeductionGuideDecl *GD = Found->getSecond(); 1253 return GD->getDescribedFunctionTemplate(); 1254 } 1255 1256 if (auto *AliasTemplate = llvm::dyn_cast<TypeAliasTemplateDecl>(Template)) { 1257 if (auto *FTD = DeclareAggregateDeductionGuideForTypeAlias( 1258 *this, AliasTemplate, ParamTypes, Loc)) { 1259 auto *GD = cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl()); 1260 GD->setDeductionCandidateKind(DeductionCandidate::Aggregate); 1261 AggregateDeductionCandidates[Hash] = GD; 1262 return FTD; 1263 } 1264 } 1265 1266 if (CXXRecordDecl *DefRecord = 1267 cast<CXXRecordDecl>(Template->getTemplatedDecl())->getDefinition()) { 1268 if (TemplateDecl *DescribedTemplate = 1269 DefRecord->getDescribedClassTemplate()) 1270 Template = DescribedTemplate; 1271 } 1272 1273 DeclContext *DC = Template->getDeclContext(); 1274 if (DC->isDependentContext()) 1275 return nullptr; 1276 1277 ConvertConstructorToDeductionGuideTransform Transform( 1278 *this, cast<ClassTemplateDecl>(Template)); 1279 if (!isCompleteType(Loc, Transform.DeducedType)) 1280 return nullptr; 1281 1282 // In case we were expanding a pack when we attempted to declare deduction 1283 // guides, turn off pack expansion for everything we're about to do. 1284 ArgumentPackSubstitutionIndexRAII SubstIndex(*this, 1285 /*NewSubstitutionIndex=*/-1); 1286 // Create a template instantiation record to track the "instantiation" of 1287 // constructors into deduction guides. 1288 InstantiatingTemplate BuildingDeductionGuides( 1289 *this, Loc, Template, 1290 Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{}); 1291 if (BuildingDeductionGuides.isInvalid()) 1292 return nullptr; 1293 1294 ClassTemplateDecl *Pattern = 1295 Transform.NestedPattern ? Transform.NestedPattern : Transform.Template; 1296 ContextRAII SavedContext(*this, Pattern->getTemplatedDecl()); 1297 1298 auto *FTD = cast<FunctionTemplateDecl>( 1299 Transform.buildSimpleDeductionGuide(ParamTypes)); 1300 SavedContext.pop(); 1301 auto *GD = cast<CXXDeductionGuideDecl>(FTD->getTemplatedDecl()); 1302 GD->setDeductionCandidateKind(DeductionCandidate::Aggregate); 1303 AggregateDeductionCandidates[Hash] = GD; 1304 return FTD; 1305 } 1306 1307 void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template, 1308 SourceLocation Loc) { 1309 if (auto *AliasTemplate = llvm::dyn_cast<TypeAliasTemplateDecl>(Template)) { 1310 DeclareImplicitDeductionGuidesForTypeAlias(*this, AliasTemplate, Loc); 1311 return; 1312 } 1313 if (CXXRecordDecl *DefRecord = 1314 cast<CXXRecordDecl>(Template->getTemplatedDecl())->getDefinition()) { 1315 if (TemplateDecl *DescribedTemplate = 1316 DefRecord->getDescribedClassTemplate()) 1317 Template = DescribedTemplate; 1318 } 1319 1320 DeclContext *DC = Template->getDeclContext(); 1321 if (DC->isDependentContext()) 1322 return; 1323 1324 ConvertConstructorToDeductionGuideTransform Transform( 1325 *this, cast<ClassTemplateDecl>(Template)); 1326 if (!isCompleteType(Loc, Transform.DeducedType)) 1327 return; 1328 1329 if (hasDeclaredDeductionGuides(Transform.DeductionGuideName, DC)) 1330 return; 1331 1332 // In case we were expanding a pack when we attempted to declare deduction 1333 // guides, turn off pack expansion for everything we're about to do. 1334 ArgumentPackSubstitutionIndexRAII SubstIndex(*this, -1); 1335 // Create a template instantiation record to track the "instantiation" of 1336 // constructors into deduction guides. 1337 InstantiatingTemplate BuildingDeductionGuides( 1338 *this, Loc, Template, 1339 Sema::InstantiatingTemplate::BuildingDeductionGuidesTag{}); 1340 if (BuildingDeductionGuides.isInvalid()) 1341 return; 1342 1343 // Convert declared constructors into deduction guide templates. 1344 // FIXME: Skip constructors for which deduction must necessarily fail (those 1345 // for which some class template parameter without a default argument never 1346 // appears in a deduced context). 1347 ClassTemplateDecl *Pattern = 1348 Transform.NestedPattern ? Transform.NestedPattern : Transform.Template; 1349 ContextRAII SavedContext(*this, Pattern->getTemplatedDecl()); 1350 llvm::SmallPtrSet<NamedDecl *, 8> ProcessedCtors; 1351 bool AddedAny = false; 1352 for (NamedDecl *D : LookupConstructors(Pattern->getTemplatedDecl())) { 1353 D = D->getUnderlyingDecl(); 1354 if (D->isInvalidDecl() || D->isImplicit()) 1355 continue; 1356 1357 D = cast<NamedDecl>(D->getCanonicalDecl()); 1358 1359 // Within C++20 modules, we may have multiple same constructors in 1360 // multiple same RecordDecls. And it doesn't make sense to create 1361 // duplicated deduction guides for the duplicated constructors. 1362 if (ProcessedCtors.count(D)) 1363 continue; 1364 1365 auto *FTD = dyn_cast<FunctionTemplateDecl>(D); 1366 auto *CD = 1367 dyn_cast_or_null<CXXConstructorDecl>(FTD ? FTD->getTemplatedDecl() : D); 1368 // Class-scope explicit specializations (MS extension) do not result in 1369 // deduction guides. 1370 if (!CD || (!FTD && CD->isFunctionTemplateSpecialization())) 1371 continue; 1372 1373 // Cannot make a deduction guide when unparsed arguments are present. 1374 if (llvm::any_of(CD->parameters(), [](ParmVarDecl *P) { 1375 return !P || P->hasUnparsedDefaultArg(); 1376 })) 1377 continue; 1378 1379 ProcessedCtors.insert(D); 1380 Transform.transformConstructor(FTD, CD); 1381 AddedAny = true; 1382 } 1383 1384 // C++17 [over.match.class.deduct] 1385 // -- If C is not defined or does not declare any constructors, an 1386 // additional function template derived as above from a hypothetical 1387 // constructor C(). 1388 if (!AddedAny) 1389 Transform.buildSimpleDeductionGuide(std::nullopt); 1390 1391 // -- An additional function template derived as above from a hypothetical 1392 // constructor C(C), called the copy deduction candidate. 1393 cast<CXXDeductionGuideDecl>( 1394 cast<FunctionTemplateDecl>( 1395 Transform.buildSimpleDeductionGuide(Transform.DeducedType)) 1396 ->getTemplatedDecl()) 1397 ->setDeductionCandidateKind(DeductionCandidate::Copy); 1398 1399 SavedContext.pop(); 1400 } 1401