Skip to content

Commit be109b7

Browse files
[AST] Add method to check if a function type has a non-trivial Clang type.
1 parent 8bc6f83 commit be109b7

File tree

4 files changed

+52
-0
lines changed

4 files changed

+52
-0
lines changed

include/swift/AST/ExtInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class ClangTypeInfo {
7070
constexpr ClangTypeInfo(const clang::Type *type) : type(type) {}
7171

7272
friend bool operator==(ClangTypeInfo lhs, ClangTypeInfo rhs);
73+
friend bool operator!=(ClangTypeInfo lhs, ClangTypeInfo rhs);
7374
ClangTypeInfo getCanonical() const;
7475

7576
public:

include/swift/AST/Types.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2928,6 +2928,24 @@ class AnyFunctionType : public TypeBase {
29282928
ClangTypeInfo getClangTypeInfo() const;
29292929
ClangTypeInfo getCanonicalClangTypeInfo() const;
29302930

2931+
/// Returns true if the function type stores a Clang type that cannot
2932+
/// be derived from its Swift type. Returns false otherwise, including if
2933+
/// the function type is not @convention(c) or @convention(block).
2934+
///
2935+
/// For example, if you have a function pointer from C getting imported with
2936+
/// the following type:
2937+
///
2938+
/// @convention(c, cType: "void (*)(size_t (*)(size_t))")
2939+
/// (@convention(c, cType: "size_t (*)(size_t)") (Int) -> Int)) -> Void
2940+
///
2941+
/// The parameter's function type will have hasNonDerivableClangType() = true,
2942+
/// but the outer function type will have hasNonDerivableClangType() = false,
2943+
/// because the parameter and result type are sufficient to correctly derive
2944+
/// the Clang type for the outer function type. In terms of mangling,
2945+
/// the parameter type's mangling will incorporate the Clang type but the
2946+
/// outer function type's mangling doesn't need to duplicate that information.
2947+
bool hasNonDerivableClangType();
2948+
29312949
ExtInfo getExtInfo() const {
29322950
return ExtInfo(Bits.AnyFunctionType.ExtInfoBits, getClangTypeInfo());
29332951
}
@@ -4309,6 +4327,11 @@ class SILFunctionType final
43094327

43104328
ClangTypeInfo getClangTypeInfo() const;
43114329

4330+
/// Returns true if the function type stores a Clang type that cannot
4331+
/// be derived from its Swift type. Returns false otherwise, including if
4332+
/// the function type is not @convention(c) or @convention(block).
4333+
bool hasNonDerivableClangType();
4334+
43124335
bool hasSameExtInfoAs(const SILFunctionType *otherFn);
43134336

43144337
/// Given that `this` is a `@differentiable` or `@differentiable(linear)`

lib/AST/ExtInfo.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ bool operator==(ClangTypeInfo lhs, ClangTypeInfo rhs) {
3434
return false;
3535
}
3636

37+
bool operator!=(ClangTypeInfo lhs, ClangTypeInfo rhs) {
38+
return !(lhs == rhs);
39+
}
40+
3741
ClangTypeInfo ClangTypeInfo::getCanonical() const {
3842
if (!type)
3943
return ClangTypeInfo();

lib/AST/Type.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3424,6 +3424,16 @@ ClangTypeInfo AnyFunctionType::getCanonicalClangTypeInfo() const {
34243424
return getClangTypeInfo().getCanonical();
34253425
}
34263426

3427+
bool AnyFunctionType::hasNonDerivableClangType() {
3428+
auto clangTypeInfo = getClangTypeInfo();
3429+
if (clangTypeInfo.empty())
3430+
return false;
3431+
auto computedClangType = getASTContext().getClangFunctionType(
3432+
getParams(), getResult(), getRepresentation());
3433+
assert(computedClangType && "Failed to compute Clang type.");
3434+
return clangTypeInfo != ClangTypeInfo(computedClangType);
3435+
}
3436+
34273437
bool AnyFunctionType::hasSameExtInfoAs(const AnyFunctionType *otherFn) {
34283438
return getExtInfo().isEqualTo(otherFn->getExtInfo(), useClangTypes(this));
34293439
}
@@ -3437,6 +3447,20 @@ ClangTypeInfo SILFunctionType::getClangTypeInfo() const {
34373447
return *info;
34383448
}
34393449

3450+
bool SILFunctionType::hasNonDerivableClangType() {
3451+
auto clangTypeInfo = getClangTypeInfo();
3452+
if (clangTypeInfo.empty())
3453+
return false;
3454+
auto results = getResults();
3455+
auto computedClangType =
3456+
getASTContext().getCanonicalClangFunctionType(
3457+
getParameters(),
3458+
results.empty() ? None : Optional<SILResultInfo>(results[0]),
3459+
getRepresentation());
3460+
assert(computedClangType && "Failed to compute Clang type.");
3461+
return clangTypeInfo != ClangTypeInfo(computedClangType);
3462+
}
3463+
34403464
bool SILFunctionType::hasSameExtInfoAs(const SILFunctionType *otherFn) {
34413465
return getExtInfo().isEqualTo(otherFn->getExtInfo(), useClangTypes(this));
34423466
}

0 commit comments

Comments
 (0)