@@ -231,7 +231,7 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
231
231
if (!newFn)
232
232
return ConcreteDeclRef (decl);
233
233
234
- auto newDecl = cast <ValueDecl>(decl->getASTContext ().getClangModuleLoader ()->importDeclDirectly (newFn));
234
+ auto newDecl = cast_or_null <ValueDecl>(decl->getASTContext ().getClangModuleLoader ()->importDeclDirectly (newFn));
235
235
236
236
if (auto fn = dyn_cast<FuncDecl>(decl)) {
237
237
if (newFn->getNumParams () != fn->getParameters ()->size ()) {
@@ -250,9 +250,61 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
250
250
thunk->setBodySynthesizer (synthesizeForwardingThunkBody, cast<FuncDecl>(newDecl));
251
251
thunk->setSelfAccessKind (fn->getSelfAccessKind ());
252
252
253
- return ConcreteDeclRef (thunk);
253
+ newDecl = thunk;
254
+ }
255
+ }
256
+
257
+ if (auto fn = dyn_cast<AbstractFunctionDecl>(newDecl)) {
258
+ // On Windows x86-64 we have to hack around the fact that
259
+ // Int -> long long -> Int64. So we re-write the parameters mapping
260
+ // Int64 -> Int.
261
+ auto triple = decl->getASTContext ().LangOpts .Target ;
262
+ if (triple.isOSWindows () && triple.isArch64Bit () &&
263
+ !triple.isWindowsCygwinEnvironment () &&
264
+ // Make sure we're substituting in at least one Int or UInt
265
+ // (technically not necessary).
266
+ llvm::any_of (subst.getReplacementTypes (),[](Type t) {
267
+ return t->isEqual (t->getASTContext ().getIntType ()) ||
268
+ t->isEqual (t->getASTContext ().getUIntType ());
269
+ })) {
270
+ auto originalFnSubst = cast<AbstractFunctionDecl>(decl)->getInterfaceType ()->getAs <GenericFunctionType>()->substGenericArgs (subst);
271
+ assert (fn->getParameters ()->size () == originalFnSubst->getParams ().size ());
272
+ SmallVector<ParamDecl *, 4 > fixedParameters;
273
+ unsigned parameterIndex = 0 ;
274
+ for (auto *newFnParam : *fn->getParameters ()) {
275
+ // If the user substituted this param with an (U)Int, use (U)Int.
276
+ auto substParamType = originalFnSubst->getParams ()[parameterIndex].getParameterType ();
277
+ if (substParamType->isEqual (fn->getASTContext ().getIntType ()) ||
278
+ substParamType->isEqual (fn->getASTContext ().getUIntType ())) {
279
+ auto intParam = ParamDecl::cloneWithoutType (fn->getASTContext (), newFnParam);
280
+ intParam->setInterfaceType (substParamType);
281
+ fixedParameters.push_back (intParam);
282
+ } else {
283
+ fixedParameters.push_back (newFnParam);
284
+ }
285
+ parameterIndex++;
286
+ }
287
+
288
+ assert (fn->getParameters ()->size () == fixedParameters.size ());
289
+
290
+ auto fixedParams = ParameterList::create (fn->getASTContext (), fixedParameters);
291
+ fn->setParameters (fixedParams);
292
+
293
+ // Now fix the result type:
294
+ if (originalFnSubst->getResult ()->isEqual (fn->getASTContext ().getIntType ()) ||
295
+ originalFnSubst->getResult ()->isEqual (fn->getASTContext ().getUIntType ())) {
296
+ // Constructors don't have a result.
297
+ if (auto func = dyn_cast<FuncDecl>(fn)) {
298
+ newDecl = FuncDecl::createImplicit (
299
+ func->getASTContext (), func->getStaticSpelling (), func->getName (),
300
+ func->getNameLoc (), func->hasAsync (), func->hasThrows (),
301
+ /* genericParams=*/ nullptr , fixedParams,
302
+ originalFnSubst->getResult (), func->getDeclContext ());
303
+ }
304
+ }
254
305
}
255
306
}
307
+
256
308
return ConcreteDeclRef (newDecl);
257
309
}
258
310
0 commit comments