@@ -485,21 +485,22 @@ class DeducedTypeVisitor : public RecursiveASTVisitor<DeducedTypeVisitor> {
485
485
}
486
486
487
487
// Handle functions/lambdas with `auto` typed parameters.
488
- // We'll examine visible specializations and see if they yield a unique type .
488
+ // We deduce the type if there's exactly one instantiation visible .
489
489
bool VisitParmVarDecl (ParmVarDecl *PVD) {
490
490
if (!PVD->getType ()->isDependentType ())
491
491
return true ;
492
492
// 'auto' here does not name an AutoType, but an implicit template param.
493
493
TemplateTypeParmTypeLoc Auto =
494
- findContainedAutoTTPLoc (PVD->getTypeSourceInfo ()->getTypeLoc ());
494
+ getContainedAutoParamType (PVD->getTypeSourceInfo ()->getTypeLoc ());
495
495
if (Auto.isNull () || Auto.getNameLoc () != SearchedLocation)
496
496
return true ;
497
+
497
498
// We expect the TTP to be attached to this function template.
498
499
// Find the template and the param index.
499
- auto *FD = llvm::dyn_cast<FunctionDecl>(PVD->getDeclContext ());
500
- if (!FD )
500
+ auto *Templated = llvm::dyn_cast<FunctionDecl>(PVD->getDeclContext ());
501
+ if (!Templated )
501
502
return true ;
502
- auto *FTD = FD ->getDescribedFunctionTemplate ();
503
+ auto *FTD = Templated ->getDescribedFunctionTemplate ();
503
504
if (!FTD)
504
505
return true ;
505
506
int ParamIndex = paramIndex (*FTD, *Auto.getDecl ());
@@ -508,53 +509,18 @@ class DeducedTypeVisitor : public RecursiveASTVisitor<DeducedTypeVisitor> {
508
509
return true ;
509
510
}
510
511
511
- // Now determine the unique type arg among the implicit specializations.
512
- const ASTContext &Ctx = PVD->getASTContext ();
513
- QualType UniqueType;
514
- CanQualType CanUniqueType;
515
- for (const FunctionDecl *Spec : FTD->specializations ()) {
516
- // Meaning `auto` is a bit overloaded if the function is specialized.
517
- if (Spec->getTemplateSpecializationKind () == TSK_ExplicitSpecialization)
518
- return true ;
519
- // Find the type for this specialization.
520
- const auto *Args = Spec->getTemplateSpecializationArgs ();
521
- if (Args->size () != FTD->getTemplateParameters ()->size ())
522
- continue ; // no weird variadic stuff
523
- QualType SpecType = Args->get (ParamIndex).getAsType ();
524
- if (SpecType.isNull ())
525
- continue ;
526
-
527
- // Deduced types need only be *canonically* equal.
528
- CanQualType CanSpecType = Ctx.getCanonicalType (SpecType);
529
- if (CanUniqueType.isNull ()) {
530
- CanUniqueType = CanSpecType;
531
- UniqueType = SpecType;
532
- continue ;
533
- }
534
- if (CanUniqueType != CanSpecType)
535
- return true ; // deduced type is not unique
536
- }
537
- DeducedType = UniqueType;
512
+ // Now find the instantiation and the deduced template type arg.
513
+ auto *Instantiation =
514
+ llvm::dyn_cast_or_null<FunctionDecl>(getOnlyInstantiation (Templated));
515
+ if (!Instantiation)
516
+ return true ;
517
+ const auto *Args = Instantiation->getTemplateSpecializationArgs ();
518
+ if (Args->size () != FTD->getTemplateParameters ()->size ())
519
+ return true ; // no weird variadic stuff
520
+ DeducedType = Args->get (ParamIndex).getAsType ();
538
521
return true ;
539
522
}
540
523
541
- // Find the abbreviated-function-template `auto` within a type.
542
- // Similar to getContainedAutoTypeLoc, but these `auto`s are
543
- // TemplateTypeParmTypes for implicit TTPs, instead of AutoTypes.
544
- // Also we don't look very hard, just stripping const, references, pointers.
545
- // FIXME: handle more types: vector<auto>?
546
- static TemplateTypeParmTypeLoc findContainedAutoTTPLoc (TypeLoc TL) {
547
- if (auto QTL = TL.getAs <QualifiedTypeLoc>())
548
- return findContainedAutoTTPLoc (QTL.getUnqualifiedLoc ());
549
- if (llvm::isa<PointerType, ReferenceType>(TL.getTypePtr ()))
550
- return findContainedAutoTTPLoc (TL.getNextTypeLoc ());
551
- if (auto TTPTL = TL.getAs <TemplateTypeParmTypeLoc>()) {
552
- if (TTPTL.getTypePtr ()->getDecl ()->isImplicit ())
553
- return TTPTL;
554
- }
555
- return {};
556
- }
557
-
558
524
static int paramIndex (const TemplateDecl &TD, NamedDecl &Param) {
559
525
unsigned I = 0 ;
560
526
for (auto *ND : *TD.getTemplateParameters ()) {
@@ -580,6 +546,45 @@ llvm::Optional<QualType> getDeducedType(ASTContext &ASTCtx,
580
546
return V.DeducedType ;
581
547
}
582
548
549
+ TemplateTypeParmTypeLoc getContainedAutoParamType (TypeLoc TL) {
550
+ if (auto QTL = TL.getAs <QualifiedTypeLoc>())
551
+ return getContainedAutoParamType (QTL.getUnqualifiedLoc ());
552
+ if (llvm::isa<PointerType, ReferenceType, ParenType>(TL.getTypePtr ()))
553
+ return getContainedAutoParamType (TL.getNextTypeLoc ());
554
+ if (auto FTL = TL.getAs <FunctionTypeLoc>())
555
+ return getContainedAutoParamType (FTL.getReturnLoc ());
556
+ if (auto TTPTL = TL.getAs <TemplateTypeParmTypeLoc>()) {
557
+ if (TTPTL.getTypePtr ()->getDecl ()->isImplicit ())
558
+ return TTPTL;
559
+ }
560
+ return {};
561
+ }
562
+
563
+ template <typename TemplateDeclTy>
564
+ static NamedDecl *getOnlyInstantiationImpl (TemplateDeclTy *TD) {
565
+ NamedDecl *Only = nullptr ;
566
+ for (auto *Spec : TD->specializations ()) {
567
+ if (Spec->getTemplateSpecializationKind () == TSK_ExplicitSpecialization)
568
+ continue ;
569
+ if (Only != nullptr )
570
+ return nullptr ;
571
+ Only = Spec;
572
+ }
573
+ return Only;
574
+ }
575
+
576
+ NamedDecl *getOnlyInstantiation (NamedDecl *TemplatedDecl) {
577
+ if (TemplateDecl *TD = TemplatedDecl->getDescribedTemplate ()) {
578
+ if (auto *CTD = llvm::dyn_cast<ClassTemplateDecl>(TD))
579
+ return getOnlyInstantiationImpl (CTD);
580
+ if (auto *FTD = llvm::dyn_cast<FunctionTemplateDecl>(TD))
581
+ return getOnlyInstantiationImpl (FTD);
582
+ if (auto *VTD = llvm::dyn_cast<VarTemplateDecl>(TD))
583
+ return getOnlyInstantiationImpl (VTD);
584
+ }
585
+ return nullptr ;
586
+ }
587
+
583
588
std::vector<const Attr *> getAttributes (const DynTypedNode &N) {
584
589
std::vector<const Attr *> Result;
585
590
if (const auto *TL = N.get <TypeLoc>()) {
0 commit comments