Skip to content

Commit 50f55c1

Browse files
authored
Merge pull request #35416 from zoecarver/cxx/cleanup-function-template-post-commit
[NFC] Cleanup function templates implementation. Address post-commit review comments from #33053.
2 parents 742ad76 + c4da497 commit 50f55c1

16 files changed

+105
-89
lines changed

include/swift/AST/ASTContext.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -629,8 +629,15 @@ class ASTContext final {
629629
ArrayRef<SILParameterInfo> params, Optional<SILResultInfo> result,
630630
SILFunctionType::Representation trueRep);
631631

632-
/// Instantiates "Impl.Converter" if needed, then calls
633-
/// ClangTypeConverter::getClangTemplateArguments.
632+
/// Instantiates "Impl.Converter" if needed, then translate Swift generic
633+
/// substitutions to equivalent C++ types using \p templateParams and \p
634+
/// genericArgs. The converted Clang types are placed into \p templateArgs.
635+
///
636+
/// \p templateArgs must be empty. \p templateParams and \p genericArgs must
637+
/// be equal in size.
638+
///
639+
/// \returns nullptr if successful. If an error occors, returns a list of
640+
/// types that couldn't be converted.
634641
std::unique_ptr<TemplateInstantiationError> getClangTemplateArguments(
635642
const clang::TemplateParameterList *templateParams,
636643
ArrayRef<Type> genericArgs,

include/swift/AST/ClangModuleLoader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ class ClangModuleLoader : public ModuleLoader {
228228
SubstitutionMap subst) = 0;
229229
};
230230

231-
/// Used to describe a template instantiation error.
231+
/// Describes a C++ template instantiation error.
232232
struct TemplateInstantiationError {
233233
/// Generic types that could not be converted to QualTypes using the
234234
/// ClangTypeConverter.

include/swift/AST/DiagnosticsSema.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1692,7 +1692,7 @@ ERROR(where_nongeneric_toplevel,none,
16921692
"declaration", ())
16931693
ERROR(unable_to_convert_generic_swift_types,none,
16941694
"could not generate C++ types from the generic Swift types provided. "
1695-
"The following Swift type(s) provided to '%0' were unable to be "
1695+
"The following Swift type(s) provided to '%0' could not be "
16961696
"converted: %1.",
16971697
(StringRef, StringRef))
16981698

lib/AST/ClangTypeConverter.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -860,12 +860,15 @@ ClangTypeConverter::getClangTemplateArguments(
860860
const clang::TemplateParameterList *templateParams,
861861
ArrayRef<Type> genericArgs,
862862
SmallVectorImpl<clang::TemplateArgument> &templateArgs) {
863+
assert(templateArgs.size() == 0);
864+
assert(genericArgs.size() == templateParams->size());
865+
863866
// Keep track of the types we failed to convert so we can return a useful
864867
// error.
865868
SmallVector<Type, 2> failedTypes;
866869
for (clang::NamedDecl *param : *templateParams) {
867870
// Note: all template parameters must be template type parameters. This is
868-
// verified when we import the clang decl.
871+
// verified when we import the Clang decl.
869872
auto templateParam = cast<clang::TemplateTypeParmDecl>(param);
870873
auto replacement = genericArgs[templateParam->getIndex()];
871874
auto qualType = convert(replacement);
@@ -878,6 +881,9 @@ ClangTypeConverter::getClangTemplateArguments(
878881
}
879882
if (failedTypes.empty())
880883
return nullptr;
884+
// Clear "templateArgs" to prevent the clients from accidently reading a
885+
// partially converted set of template arguments.
886+
templateArgs.clear();
881887
auto errorInfo = std::make_unique<TemplateInstantiationError>();
882888
llvm::for_each(failedTypes, [&errorInfo](auto type) {
883889
errorInfo->failedTypes.push_back(type);

lib/AST/ClangTypeConverter.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,13 @@ class ClangTypeConverter :
8484
/// Swift declaration.
8585
Decl *getSwiftDeclForExportedClangDecl(const clang::Decl *decl) const;
8686

87-
/// Translate Swift generic arguments to template arguments.
87+
/// Translate Swift generic arguments to Clang C++ template arguments.
8888
///
89-
/// \returns nullptr if successful. If an error occors, returns a unique_ptr
90-
/// to a `TemplateInstantiationError` with a list of the failed types.
89+
/// \p templateArgs must be empty. \p templateParams and \p genericArgs must
90+
/// be equal in size.
91+
///
92+
/// \returns nullptr if successful. If an error occors, returns a list of
93+
/// types that couldn't be converted.
9194
std::unique_ptr<TemplateInstantiationError> getClangTemplateArguments(
9295
const clang::TemplateParameterList *templateParams,
9396
ArrayRef<Type> genericArgs,

test/Interop/Cxx/templates/Inputs/function-templates.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
#ifndef TEST_INTEROP_CXX_TEMPLATES_INPUTS_FUNCTION_TEMPLATES_H
22
#define TEST_INTEROP_CXX_TEMPLATES_INPUTS_FUNCTION_TEMPLATES_H
33

4-
template <class T> T add(T a, T b) { return a + b; }
4+
template <class T> T addSameTypeParams(T a, T b) { return a + b; }
55

6-
template <class A, class B> A addTwoTemplates(A a, B b) { return a + b; }
6+
template <class A, class B> A addMixedTypeParams(A a, B b) { return a + b; }
77

88
template <class T> T passThrough(T value) { return value; }
99

1010
template <class T> const T passThroughConst(const T value) { return value; }
1111

1212
void takesString(const char *) {}
13-
template <class T> void expectsString(T str) { takesString(str); }
13+
template <class T> void expectsConstCharPtr(T str) { takesString(str); }
1414

15-
template <long x> void integerTemplate() {}
16-
template <long x = 0> void defaultIntegerTemplate() {}
15+
template <long x> void hasNonTypeTemplateParameter() {}
16+
template <long x = 0> void hasDefaultedNonTypeTemplateParameter() {}
1717

18-
// We cannot yet use this in swift but, make sure we don't crash when parsing
18+
// We cannot yet use this in Swift but, make sure we don't crash when parsing
1919
// it.
20-
template <class R, class T, class U> R returns_template(T a, U b) {
20+
template <class R, class T, class U> R templateParameterReturnType(T a, U b) {
2121
return a + b;
2222
}
2323

2424
// Same here:
25-
template <class T> void cannot_infer_template() {}
25+
template <class T> void cannotInferTemplate() {}
2626

2727
struct HasVariadicMemeber {
2828
void test1(...) {}

test/Interop/Cxx/templates/Inputs/member-templates.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
struct HasMemberTemplates {
2-
template <class T> T add(T a, T b) { return a + b; }
2+
template <class T> T addSameTypeParams(T a, T b) { return a + b; }
33

4-
template <class T, class U> T addTwoTemplates(T a, U b) { return a + b; }
4+
template <class T, class U> T addMixedTypeParams(T a, U b) { return a + b; }
55

66
template <class T, class U> int addAll(int a, T b, U c) { return a + b + c; }
77

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

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

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,20 @@ public func testPassThrough(x: Int32) -> Int32 {
2020
return passThrough(x)
2121
}
2222

23-
// CHECK-LABEL: define {{.*}}i32 @"$s4main19testAddTwoTemplates1xs5Int32VAE_tF"(i32 %0)
24-
// CHECK: [[OUT_VAL:%.*]] = call i32 @{{_Z15addTwoTemplatesIiiET_S0_T0_|"\?\?\$addTwoTemplates@HH@@YAHHH@Z"}}(i32 %0, i32 %0)
23+
// CHECK-LABEL: define {{.*}}i32 @"$s4main22testAddMixedTypeParams1xs5Int32VAE_tF"(i32 %0)
24+
// CHECK: [[OUT_VAL:%.*]] = call i32 @{{_Z18addMixedTypeParamsIiiET_S0_T0_|"\?\?\$addMixedTypeParams@HH@@YAHHH@Z"}}(i32 %0, i32 %0)
2525
// CHECK: ret i32 [[OUT_VAL]]
2626

27-
// CHECK-LABEL: define linkonce_odr {{.*}}i32 @{{_Z15addTwoTemplatesIiiET_S0_T0_|"\?\?\$addTwoTemplates@HH@@YAHHH@Z"}}(i32 %a, i32 %b)
28-
public func testAddTwoTemplates(x: Int32) -> Int32 {
29-
return addTwoTemplates(x, x)
27+
// CHECK-LABEL: define linkonce_odr {{.*}}i32 @{{_Z18addMixedTypeParamsIiiET_S0_T0_|"\?\?\$addMixedTypeParams@HH@@YAHHH@Z"}}(i32 %a, i32 %b)
28+
public func testAddMixedTypeParams(x: Int32) -> Int32 {
29+
return addMixedTypeParams(x, x)
3030
}
3131

32-
// CHECK-LABEL: define {{.*}}i32 @"$s4main7testAdd1xs5Int32VAE_tF"(i32 %0)
33-
// CHECK: [[OUT_VAL:%.*]] = call i32 @{{_Z3addIiET_S0_S0_|"\?\?\$add@H@@YAHHH@Z"}}(i32 %0, i32 %0)
32+
// CHECK-LABEL: define {{.*}}i32 @"$s4main21testAddSameTypeParams1xs5Int32VAE_tF"(i32 %0)
33+
// CHECK: [[OUT_VAL:%.*]] = call i32 @{{_Z17addSameTypeParamsIiET_S0_S0_|"\?\?\$addSameTypeParams@H@@YAHHH@Z"}}(i32 %0, i32 %0)
3434
// CHECK: ret i32 [[OUT_VAL]]
3535

36-
// CHECK-LABEL: define linkonce_odr {{.*}}i32 @{{_Z3addIiET_S0_S0_|"\?\?\$add@H@@YAHHH@Z"}}(i32 %a, i32 %b)
37-
public func testAdd(x: Int32) -> Int32 {
38-
return add(x, x)
36+
// CHECK-LABEL: define linkonce_odr {{.*}}i32 @{{_Z17addSameTypeParamsIiET_S0_S0_|"\?\?\$addSameTypeParams@H@@YAHHH@Z"}}(i32 %a, i32 %b)
37+
public func testAddSameTypeParams(x: Int32) -> Int32 {
38+
return addSameTypeParams(x, x)
3939
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// RUN: %target-swift-ide-test -print-module -module-to-print=FunctionTemplates -I %S/Inputs -source-filename=x -enable-cxx-interop | %FileCheck %s
22

3-
// CHECK: func add<T>(_ a: T, _ b: T) -> T
4-
// CHECK: func addTwoTemplates<A, B>(_ a: A, _ b: B) -> A
3+
// CHECK: func addSameTypeParams<T>(_ a: T, _ b: T) -> T
4+
// CHECK: func addMixedTypeParams<A, B>(_ a: A, _ b: B) -> A
55
// CHECK: func passThrough<T>(_ value: T) -> T
66
// CHECK: func passThroughConst<T>(_ value: T) -> T
7-
// CHECK: func returns_template<R, T, U>(_ a: T, _ b: U) -> R
8-
// CHECK: func cannot_infer_template<T>()
7+
// CHECK: func templateParameterReturnType<R, T, U>(_ a: T, _ b: U) -> R
8+
// CHECK: func cannotInferTemplate<T>()
99

1010
// CHECK: struct HasVariadicMemeber {
1111
// CHECK: @available(*, unavailable, message: "Variadic function is unavailable")

0 commit comments

Comments
 (0)