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