@@ -231,7 +231,7 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
231231 if (!newFn)
232232 return ConcreteDeclRef (decl);
233233
234- auto newDecl = cast <ValueDecl>(decl->getASTContext ().getClangModuleLoader ()->importDeclDirectly (newFn));
234+ auto newDecl = cast_or_null <ValueDecl>(decl->getASTContext ().getClangModuleLoader ()->importDeclDirectly (newFn));
235235
236236 if (auto fn = dyn_cast<FuncDecl>(decl)) {
237237 if (newFn->getNumParams () != fn->getParameters ()->size ()) {
@@ -250,9 +250,61 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
250250 thunk->setBodySynthesizer (synthesizeForwardingThunkBody, cast<FuncDecl>(newDecl));
251251 thunk->setSelfAccessKind (fn->getSelfAccessKind ());
252252
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+ }
254305 }
255306 }
307+
256308 return ConcreteDeclRef (newDecl);
257309 }
258310
0 commit comments