@@ -107,12 +107,19 @@ Solution::computeSubstitutions(GenericSignature sig,
107
107
}
108
108
109
109
static ConcreteDeclRef generateDeclRefForSpecializedCXXFunctionTemplate (
110
- ASTContext &ctx, FuncDecl *oldDecl, SubstitutionMap subst,
110
+ ASTContext &ctx, AbstractFunctionDecl *oldDecl, SubstitutionMap subst,
111
111
clang::FunctionDecl *specialized) {
112
112
// Create a new ParameterList with the substituted type.
113
113
auto oldFnType =
114
114
cast<GenericFunctionType>(oldDecl->getInterfaceType ().getPointer ());
115
115
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 ());
116
123
SmallVector<ParamDecl *, 4 > newParams;
117
124
unsigned i = 0 ;
118
125
for (auto paramTy : newFnType->getParams ()) {
@@ -126,6 +133,16 @@ static ConcreteDeclRef generateDeclRefForSpecializedCXXFunctionTemplate(
126
133
auto *newParamList =
127
134
ParameterList::create (ctx, SourceLoc (), newParams, SourceLoc ());
128
135
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
+
129
146
// Generate a name for the specialized function.
130
147
std::string newNameStr;
131
148
llvm::raw_string_ostream buffer (newNameStr);
@@ -139,8 +156,8 @@ static ConcreteDeclRef generateDeclRefForSpecializedCXXFunctionTemplate(
139
156
140
157
auto newFnDecl = FuncDecl::createImported (
141
158
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 ,
144
161
oldDecl->getDeclContext (), specialized);
145
162
return ConcreteDeclRef (newFnDecl);
146
163
}
@@ -168,7 +185,7 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
168
185
cast<clang::FunctionTemplateDecl>(decl->getClangDecl ())),
169
186
subst);
170
187
return generateDeclRefForSpecializedCXXFunctionTemplate (
171
- decl->getASTContext (), cast<FuncDecl >(decl), subst, newFn);
188
+ decl->getASTContext (), cast<AbstractFunctionDecl >(decl), subst, newFn);
172
189
}
173
190
174
191
return ConcreteDeclRef (decl, subst);
0 commit comments