[clang] [clang] Implement CTAD for type alias template. (PR #77890)

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 27 11:26:41 PST 2024


================
@@ -2612,44 +2669,313 @@ struct ConvertConstructorToDeductionGuideTransform {
     SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam);
     return NewParam;
   }
+};
 
-  FunctionTemplateDecl *buildDeductionGuide(
-      TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor,
-      ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart,
-      SourceLocation Loc, SourceLocation LocEnd,
-      llvm::ArrayRef<TypedefNameDecl *> MaterializedTypedefs = {}) {
-    DeclarationNameInfo Name(DeductionGuideName, Loc);
-    ArrayRef<ParmVarDecl *> Params =
-        TInfo->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams();
+// Find all template parameters of the AliasTemplate that appear in the
+// given DeducedArgs.
+SmallVector<unsigned>
+FindAppearedTemplateParamsInAlias(ArrayRef<TemplateArgument> DeducedArgs,
+                                  TypeAliasTemplateDecl *AliasTemplate) {
+  struct FindAppearedTemplateParams
+      : public RecursiveASTVisitor<FindAppearedTemplateParams> {
+    llvm::DenseSet<NamedDecl *> TemplateParamsInAlias;
+    llvm::DenseSet<const NamedDecl *> AppearedTemplateParams;
+
+    FindAppearedTemplateParams(ArrayRef<NamedDecl *> TemplateParamsInAlias)
+        : TemplateParamsInAlias(TemplateParamsInAlias.begin(),
+                                TemplateParamsInAlias.end()) {}
+
+    bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) {
+      TTP->getIndex();
+      MarkAppeared(TTP->getDecl());
+      return true;
+    }
+    bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+      MarkAppeared(DRE->getFoundDecl());
+      return true;
+    }
 
-    // Build the implicit deduction guide template.
-    auto *Guide =
-        CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name,
-                                      TInfo->getType(), TInfo, LocEnd, Ctor);
-    Guide->setImplicit();
-    Guide->setParams(Params);
+    void MarkAppeared(NamedDecl *ND) {
+      if (TemplateParamsInAlias.contains(ND))
+        AppearedTemplateParams.insert(ND);
+    }
+  };
+  ArrayRef<NamedDecl *> TemplateParamsInAlias =
+      AliasTemplate->getTemplateParameters()->asArray();
+  FindAppearedTemplateParams MarkAppeared(TemplateParamsInAlias);
+  MarkAppeared.TraverseTemplateArguments(DeducedArgs);
 
-    for (auto *Param : Params)
-      Param->setDeclContext(Guide);
-    for (auto *TD : MaterializedTypedefs)
-      TD->setDeclContext(Guide);
+  SmallVector<unsigned> Results;
+  for (unsigned Index = 0; Index < TemplateParamsInAlias.size(); ++Index) {
+    if (MarkAppeared.AppearedTemplateParams.contains(
+            TemplateParamsInAlias[Index]))
+      Results.push_back(Index);
+  }
+  return Results;
+}
+
+bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) {
+  // Check whether we've already declared deduction guides for this template.
+  // FIXME: Consider storing a flag on the template to indicate this.
----------------
hokein wrote:

I think the flag change is orthogonal to the current patch, and we already do this lookup for non-type-alias CTAD implementation. 

We can address it in a followup.

https://github.com/llvm/llvm-project/pull/77890


More information about the cfe-commits mailing list