@@ -235,27 +235,6 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
235
235
decl->getASTContext ().getClangModuleLoader ()->importDeclDirectly (
236
236
newFn));
237
237
238
- if (auto fn = dyn_cast<FuncDecl>(decl)) {
239
- if (newFn->getNumParams () != fn->getParameters ()->size ()) {
240
- // We added additional metatype parameters to aid template
241
- // specialization, which are no longer now that we've specialized
242
- // this function. Create a thunk that only forwards the original
243
- // parameters along to the clang function.
244
- auto thunkTypeAndParamList = substituteFunctionTypeAndParamList (decl->getASTContext (),
245
- fn, subst);
246
- auto thunk = FuncDecl::createImplicit (
247
- fn->getASTContext (), fn->getStaticSpelling (), fn->getName (),
248
- fn->getNameLoc (), fn->hasAsync (), fn->hasThrows (),
249
- /* genericParams=*/ nullptr , thunkTypeAndParamList.second ,
250
- thunkTypeAndParamList.first ->getResult (), fn->getDeclContext ());
251
- thunk->copyFormalAccessFrom (fn);
252
- thunk->setBodySynthesizer (synthesizeForwardingThunkBody, cast<FuncDecl>(newDecl));
253
- thunk->setSelfAccessKind (fn->getSelfAccessKind ());
254
-
255
- newDecl = thunk;
256
- }
257
- }
258
-
259
238
if (auto fn = dyn_cast<AbstractFunctionDecl>(newDecl)) {
260
239
// On Windows x86-64 we have to hack around the fact that
261
240
// Int -> long long -> Int64. So we re-write the parameters mapping
@@ -273,8 +252,17 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
273
252
->getInterfaceType ()
274
253
->getAs <GenericFunctionType>()
275
254
->substGenericArgs (subst);
276
- assert (fn->getParameters ()->size () ==
277
- originalFnSubst->getParams ().size ());
255
+ // The constructor type is a function type as follows:
256
+ // (CType.Type) -> (Generic) -> CType
257
+ // And a method's function type is as follows:
258
+ // (inout CType) -> (Generic) -> Void
259
+ // In either case, we only want the result of that function type because that
260
+ // is the function type with the generic params that need to be substituted:
261
+ // (Generic) -> CType
262
+ if (isa<ConstructorDecl>(decl) || decl->isInstanceMember () ||
263
+ decl->isStatic ())
264
+ originalFnSubst = cast<FunctionType>(originalFnSubst->getResult ().getPointer ());
265
+
278
266
SmallVector<ParamDecl *, 4 > fixedParameters;
279
267
unsigned parameterIndex = 0 ;
280
268
for (auto *newFnParam : *fn->getParameters ()) {
@@ -293,8 +281,6 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
293
281
parameterIndex++;
294
282
}
295
283
296
- assert (fn->getParameters ()->size () == fixedParameters.size ());
297
-
298
284
auto fixedParams =
299
285
ParameterList::create (fn->getASTContext (), fixedParameters);
300
286
fn->setParameters (fixedParams);
@@ -306,17 +292,46 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
306
292
fn->getASTContext ().getUIntType ())) {
307
293
// Constructors don't have a result.
308
294
if (auto func = dyn_cast<FuncDecl>(fn)) {
309
- newDecl = FuncDecl::createImplicit (
310
- func->getASTContext (), func->getStaticSpelling (),
311
- func->getName (), func->getNameLoc (), func->hasAsync (),
312
- func->hasThrows (),
313
- /* genericParams=*/ nullptr , fixedParams,
314
- originalFnSubst->getResult (), func->getDeclContext ());
295
+ // We have to rebuild the whole function.
296
+ auto newFnDecl = FuncDecl::createImported (
297
+ func->getASTContext (), func->getNameLoc (),
298
+ func->getName (), func->getNameLoc (),
299
+ func->hasAsync (), func->hasThrows (),
300
+ fixedParams, originalFnSubst->getResult (),
301
+ /* genericParams=*/ nullptr , func->getDeclContext (), newFn);
302
+ if (func->isStatic ()) newFnDecl->setStatic ();
303
+ if (func->isImportAsStaticMember ()) newFnDecl->setImportAsStaticMember ();
304
+ if (!func->getDeclContext ()->isModuleScopeContext ()) {
305
+ newFnDecl->setSelfAccessKind (func->getSelfAccessKind ());
306
+ newFnDecl->setSelfIndex (func->getSelfIndex ());
307
+ }
308
+ newDecl = newFnDecl;
315
309
}
316
310
}
317
311
}
318
312
}
319
313
314
+ if (auto fn = dyn_cast<FuncDecl>(decl)) {
315
+ if (newFn->getNumParams () != fn->getParameters ()->size ()) {
316
+ // We added additional metatype parameters to aid template
317
+ // specialization, which are no longer now that we've specialized
318
+ // this function. Create a thunk that only forwards the original
319
+ // parameters along to the clang function.
320
+ auto thunkTypeAndParamList = substituteFunctionTypeAndParamList (decl->getASTContext (),
321
+ fn, subst);
322
+ auto thunk = FuncDecl::createImplicit (
323
+ fn->getASTContext (), fn->getStaticSpelling (), fn->getName (),
324
+ fn->getNameLoc (), fn->hasAsync (), fn->hasThrows (),
325
+ /* genericParams=*/ nullptr , thunkTypeAndParamList.second ,
326
+ thunkTypeAndParamList.first ->getResult (), fn->getDeclContext ());
327
+ thunk->copyFormalAccessFrom (fn);
328
+ thunk->setBodySynthesizer (synthesizeForwardingThunkBody, cast<FuncDecl>(newDecl));
329
+ thunk->setSelfAccessKind (fn->getSelfAccessKind ());
330
+
331
+ newDecl = thunk;
332
+ }
333
+ }
334
+
320
335
return ConcreteDeclRef (newDecl);
321
336
}
322
337
0 commit comments