@@ -740,6 +740,28 @@ bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) {
740
740
return false ;
741
741
}
742
742
743
+ // Returns all source deduction guides associated with the declared
744
+ // deduction guides that have the specified deduction guide name.
745
+ llvm::DenseSet<const NamedDecl *> getSourceDeductionGuides (DeclarationName Name,
746
+ DeclContext *DC) {
747
+ assert (Name.getNameKind () ==
748
+ DeclarationName::NameKind::CXXDeductionGuideName &&
749
+ " name must be a deduction guide name" );
750
+ llvm::DenseSet<const NamedDecl *> Result;
751
+ for (auto *D : DC->lookup (Name)) {
752
+ if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
753
+ D = FTD->getTemplatedDecl ();
754
+
755
+ if (const auto *GD = dyn_cast<CXXDeductionGuideDecl>(D)) {
756
+ assert (GD->getSourceDeductionGuide () &&
757
+ " deduction guide for alias template must have a source deduction "
758
+ " guide" );
759
+ Result.insert (GD->getSourceDeductionGuide ());
760
+ }
761
+ }
762
+ return Result;
763
+ }
764
+
743
765
// Build the associated constraints for the alias deduction guides.
744
766
// C++ [over.match.class.deduct]p3.3:
745
767
// The associated constraints ([temp.constr.decl]) are the conjunction of the
@@ -1191,17 +1213,14 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
1191
1213
if (AliasTemplate->isInvalidDecl ())
1192
1214
return ;
1193
1215
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
1216
auto [Template, AliasRhsTemplateArgs] =
1202
1217
getRHSTemplateDeclAndArgs (SemaRef, AliasTemplate);
1203
1218
if (!Template)
1204
1219
return ;
1220
+ auto SourceDeductionGuides = getSourceDeductionGuides (
1221
+ Context.DeclarationNames .getCXXDeductionGuideName (AliasTemplate),
1222
+ AliasTemplate->getDeclContext ());
1223
+
1205
1224
DeclarationNameInfo NameInfo (
1206
1225
Context.DeclarationNames .getCXXDeductionGuideName (Template), Loc);
1207
1226
LookupResult Guides (SemaRef, NameInfo, clang::Sema::LookupOrdinaryName);
@@ -1210,6 +1229,8 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
1210
1229
1211
1230
for (auto *G : Guides) {
1212
1231
if (auto *DG = dyn_cast<CXXDeductionGuideDecl>(G)) {
1232
+ if (SourceDeductionGuides.contains (DG))
1233
+ continue ;
1213
1234
// The deduction guide is a non-template function decl, we just clone it.
1214
1235
auto *FunctionType =
1215
1236
SemaRef.Context .getTrivialTypeSourceInfo (DG->getType ());
@@ -1252,7 +1273,7 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
1252
1273
continue ;
1253
1274
}
1254
1275
FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(G);
1255
- if (!F)
1276
+ if (!F || SourceDeductionGuides. contains (F-> getTemplatedDecl ()) )
1256
1277
continue ;
1257
1278
// The **aggregate** deduction guides are handled in a different code path
1258
1279
// (DeclareAggregateDeductionGuideFromInitList), which involves the tricky
0 commit comments