Skip to content

Commit daceecf

Browse files
committed
[cxx-interop] Remove generateSpecializedCXXFunctionTemplate and just import the decl directly.
1) This unifies two code paths that do essentially the same thing. 2) This fixes how we import certain types (such as return types).
1 parent c8ab423 commit daceecf

File tree

5 files changed

+9
-90
lines changed

5 files changed

+9
-90
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4672,8 +4672,7 @@ clang::FunctionDecl *ClangImporter::instantiateCXXFunctionTemplate(
46724672
ctx.Diags.diagnose(SourceLoc(),
46734673
diag::unable_to_convert_generic_swift_types.ID,
46744674
{func->getName(), StringRef(failedTypesStr)});
4675-
// Return a valid FunctionDecl but, we'll never use it.
4676-
return func->getAsFunction();
4675+
return nullptr;
46774676
}
46784677

46794678
// Instanciate a specialization of this template using the substitution map.

lib/Sema/CSApply.cpp

Lines changed: 7 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -149,65 +149,6 @@ substituteFunctionTypeAndParamList(ASTContext &ctx, AbstractFunctionDecl *fdecl,
149149
return {newFnType, newParamList};
150150
}
151151

152-
static ValueDecl *generateSpecializedCXXFunctionTemplate(
153-
ASTContext &ctx, AbstractFunctionDecl *oldDecl, SubstitutionMap subst,
154-
clang::FunctionDecl *specialized) {
155-
auto newFnTypeAndParams = substituteFunctionTypeAndParamList(ctx, oldDecl, subst);
156-
auto newFnType = newFnTypeAndParams.first;
157-
auto paramList = newFnTypeAndParams.second;
158-
159-
SmallVector<ParamDecl *, 4> newParamsWithoutMetatypes;
160-
for (auto param : *paramList ) {
161-
if (isa<FuncDecl>(oldDecl) &&
162-
isa<MetatypeType>(param->getType().getPointer())) {
163-
// Metatype parameters are added synthetically to account for template
164-
// params that don't make it to the function signature. These shouldn't
165-
// exist in the resulting specialized FuncDecl. Note that this doesn't
166-
// affect constructors because all template params for a constructor
167-
// must be in the function signature by design.
168-
continue;
169-
}
170-
newParamsWithoutMetatypes.push_back(param);
171-
}
172-
auto *newParamList =
173-
ParameterList::create(ctx, SourceLoc(), newParamsWithoutMetatypes, SourceLoc());
174-
175-
if (isa<ConstructorDecl>(oldDecl)) {
176-
DeclName ctorName(ctx, DeclBaseName::createConstructor(), newParamList);
177-
auto newCtorDecl = ConstructorDecl::createImported(
178-
ctx, specialized, ctorName, oldDecl->getLoc(),
179-
/*failable=*/false, /*failabilityLoc=*/SourceLoc(),
180-
/*Async=*/false, /*AsyncLoc=*/SourceLoc(),
181-
/*throws=*/false, /*throwsLoc=*/SourceLoc(),
182-
newParamList, /*genericParams=*/nullptr,
183-
oldDecl->getDeclContext());
184-
return newCtorDecl;
185-
}
186-
187-
// Generate a name for the specialized function.
188-
std::string newNameStr;
189-
llvm::raw_string_ostream buffer(newNameStr);
190-
std::unique_ptr<clang::MangleContext> mangler(
191-
specialized->getASTContext().createMangleContext());
192-
mangler->mangleName(specialized, buffer);
193-
buffer.flush();
194-
// Add all parameters as empty parameters.
195-
auto newName = DeclName(
196-
ctx, DeclName(ctx.getIdentifier(newNameStr)).getBaseName(), newParamList);
197-
198-
auto newFnDecl = FuncDecl::createImported(
199-
ctx, oldDecl->getLoc(), newName, oldDecl->getNameLoc(),
200-
/*Async=*/false, oldDecl->hasThrows(), newParamList,
201-
newFnType->getResult(), /*GenericParams=*/nullptr,
202-
oldDecl->getDeclContext(), specialized);
203-
if (oldDecl->isStatic()) {
204-
newFnDecl->setStatic();
205-
newFnDecl->setImportAsStaticMember();
206-
}
207-
newFnDecl->setSelfAccessKind(cast<FuncDecl>(oldDecl)->getSelfAccessKind());
208-
return newFnDecl;
209-
}
210-
211152
// Synthesizes the body of a thunk that takes extra metatype arguments and
212153
// skips over them to forward them along to the FuncDecl contained by context.
213154
// This is used when importing a C++ templated function where the template params
@@ -285,8 +226,13 @@ Solution::resolveConcreteDeclRef(ValueDecl *decl,
285226
const_cast<clang::FunctionTemplateDecl *>(
286227
cast<clang::FunctionTemplateDecl>(decl->getClangDecl())),
287228
subst);
288-
auto newDecl = generateSpecializedCXXFunctionTemplate(
289-
decl->getASTContext(), cast<AbstractFunctionDecl>(decl), subst, newFn);
229+
// We failed to specialize this function template. The compiler is going to
230+
// exit soon. Return something valid in the meantime.
231+
if (!newFn)
232+
return ConcreteDeclRef(decl);
233+
234+
auto newDecl = cast<ValueDecl>(decl->getASTContext().getClangModuleLoader()->importDeclDirectly(newFn));
235+
290236
if (auto fn = dyn_cast<FuncDecl>(decl)) {
291237
if (newFn->getNumParams() != fn->getParameters()->size()) {
292238
// We added additional metatype parameters to aid template

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public func deletedConstructor(a: UnsafeMutablePointer<Int32>) {
6565
// CHECK: apply [[FN]]([[TEMPL]], [[ARG_VAL]]) : $@convention(c) (ArgType) -> @out TemplatedConstructor
6666
// CHECK-LABEL: end sil function '$s4main20templatedConstructoryyF'
6767

68-
// CHECK-LABEL: sil hidden_external [clang TemplatedConstructor.init] @{{_ZN20TemplatedConstructorC1I7ArgTypeEET_|\?\?\$\?0UArgType@@@TemplatedConstructor@@QEAA@UArgType@@@Z}} : $@convention(c) (ArgType) -> @out TemplatedConstructor
68+
// CHECK-LABEL: sil [clang TemplatedConstructor.init] @{{_ZN20TemplatedConstructorC1I7ArgTypeEET_|\?\?\$\?0UArgType@@@TemplatedConstructor@@QEAA@UArgType@@@Z}} : $@convention(c) (ArgType) -> @out TemplatedConstructor
6969
public func templatedConstructor() {
7070
let templated = TemplatedConstructor(ArgType())
7171
}

test/Interop/Cxx/templates/function-template-irgen-objc.swift

Lines changed: 0 additions & 17 deletions
This file was deleted.

test/Interop/Cxx/templates/function-template.swift

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,6 @@ FunctionTemplateTestSuite.test("lvalueReference<T> where T == Int") {
2828
expectEqual(value, 42)
2929
}
3030

31-
// TODO: currently "Any" is imported as an Objective-C "id".
32-
// This doesn't work without the Objective-C runtime.
33-
#if _runtime(_ObjC)
34-
FunctionTemplateTestSuite.test("passThrough<T> where T == Any") {
35-
let result = passThrough(42 as Any)
36-
expectEqual(42, result as! Int)
37-
}
38-
#endif
39-
4031
// TODO: Generics, Any, and Protocols should be tested here but need to be
4132
// better supported in ClangTypeConverter first.
4233

0 commit comments

Comments
 (0)