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