@@ -107,12 +107,19 @@ Solution::computeSubstitutions(GenericSignature sig,
107107}
108108
109109static ConcreteDeclRef generateDeclRefForSpecializedCXXFunctionTemplate (
110- ASTContext &ctx, FuncDecl *oldDecl, SubstitutionMap subst,
110+ ASTContext &ctx, AbstractFunctionDecl *oldDecl, SubstitutionMap subst,
111111 clang::FunctionDecl *specialized) {
112112 // Create a new ParameterList with the substituted type.
113113 auto oldFnType =
114114 cast<GenericFunctionType>(oldDecl->getInterfaceType ().getPointer ());
115115 auto newFnType = oldFnType->substGenericArgs (subst);
116+ // The constructor type is a function type as follows:
117+ // (CType.Type) -> (Generic) -> CType
118+ // But we only want the result of that function type because that is the
119+ // function type with the generic params that need to be substituted:
120+ // (Generic) -> CType
121+ if (isa<ConstructorDecl>(oldDecl))
122+ newFnType = cast<FunctionType>(newFnType->getResult ().getPointer ());
116123 SmallVector<ParamDecl *, 4 > newParams;
117124 unsigned i = 0 ;
118125 for (auto paramTy : newFnType->getParams ()) {
@@ -126,6 +133,16 @@ static ConcreteDeclRef generateDeclRefForSpecializedCXXFunctionTemplate(
126133 auto *newParamList =
127134 ParameterList::create (ctx, SourceLoc (), newParams, SourceLoc ());
128135
136+ if (isa<ConstructorDecl>(oldDecl)) {
137+ DeclName ctorName (ctx, DeclBaseName::createConstructor (), newParamList);
138+ auto newCtorDecl = ConstructorDecl::createImported (
139+ ctx, specialized, ctorName, oldDecl->getLoc (), /* failable=*/ false ,
140+ /* failabilityLoc=*/ SourceLoc (), /* throws=*/ false ,
141+ /* throwsLoc=*/ SourceLoc (), newParamList, /* genericParams=*/ nullptr ,
142+ oldDecl->getDeclContext ());
143+ return ConcreteDeclRef (newCtorDecl);
144+ }
145+
129146 // Generate a name for the specialized function.
130147 std::string newNameStr;
131148 llvm::raw_string_ostream buffer (newNameStr);
@@ -139,8 +156,8 @@ static ConcreteDeclRef generateDeclRefForSpecializedCXXFunctionTemplate(
139156
140157 auto newFnDecl = FuncDecl::createImported (
141158 ctx, oldDecl->getLoc (), newName, oldDecl->getNameLoc (),
142- /* Async*/ false , oldDecl->hasThrows (), newParamList,
143- newFnType->getResult (), /* GenericParams*/ nullptr ,
159+ /* Async= */ false , oldDecl->hasThrows (), newParamList,
160+ newFnType->getResult (), /* GenericParams= */ nullptr ,
144161 oldDecl->getDeclContext (), specialized);
145162 return ConcreteDeclRef (newFnDecl);
146163}
@@ -168,7 +185,7 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
168185 cast<clang::FunctionTemplateDecl>(decl->getClangDecl ())),
169186 subst);
170187 return generateDeclRefForSpecializedCXXFunctionTemplate (
171- decl->getASTContext (), cast<FuncDecl >(decl), subst, newFn);
188+ decl->getASTContext (), cast<AbstractFunctionDecl >(decl), subst, newFn);
172189 }
173190
174191 return ConcreteDeclRef (decl, subst);
0 commit comments