Skip to content

Commit 83e465f

Browse files
committed
Move up the Windows hack and fix it for static members/inits.
1 parent 4cb1704 commit 83e465f

File tree

2 files changed

+49
-31
lines changed

2 files changed

+49
-31
lines changed

lib/Sema/CSApply.cpp

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -235,27 +235,6 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
235235
decl->getASTContext().getClangModuleLoader()->importDeclDirectly(
236236
newFn));
237237

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-
259238
if (auto fn = dyn_cast<AbstractFunctionDecl>(newDecl)) {
260239
// On Windows x86-64 we have to hack around the fact that
261240
// Int -> long long -> Int64. So we re-write the parameters mapping
@@ -273,8 +252,17 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
273252
->getInterfaceType()
274253
->getAs<GenericFunctionType>()
275254
->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+
278266
SmallVector<ParamDecl *, 4> fixedParameters;
279267
unsigned parameterIndex = 0;
280268
for (auto *newFnParam : *fn->getParameters()) {
@@ -293,8 +281,6 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
293281
parameterIndex++;
294282
}
295283

296-
assert(fn->getParameters()->size() == fixedParameters.size());
297-
298284
auto fixedParams =
299285
ParameterList::create(fn->getASTContext(), fixedParameters);
300286
fn->setParameters(fixedParams);
@@ -306,17 +292,46 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
306292
fn->getASTContext().getUIntType())) {
307293
// Constructors don't have a result.
308294
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;
315309
}
316310
}
317311
}
318312
}
319313

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+
320335
return ConcreteDeclRef(newDecl);
321336
}
322337

test/Interop/Cxx/class/constructors-irgen.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ typealias Void = ()
1111
struct UnsafePointer<T> { }
1212
struct UnsafeMutablePointer<T> { }
1313

14+
struct Int { }
15+
struct UInt { }
16+
1417
public func createHasVirtualBase() -> HasVirtualBase {
1518
// ITANIUM_X64: define swiftcc void @"$ss20createHasVirtualBaseSo0bcD0VyF"(%TSo14HasVirtualBaseV* noalias nocapture sret({{.*}}) %0)
1619
// ITANIUM_X64-NOT: define

0 commit comments

Comments
 (0)