Skip to content

Commit e675740

Browse files
Merge pull request #34513 from varungandhi-apple/vg-ast-fix-clangtypeconverter-crash
[AST] Account for parameter bridging in Clang type computation.
2 parents a7ca167 + 3784900 commit e675740

File tree

5 files changed

+43
-7
lines changed

5 files changed

+43
-7
lines changed

include/swift/Option/FrontendOptions.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,8 @@ def experimental_spi_imports :
665665
def experimental_print_full_convention :
666666
Flag<["-"], "experimental-print-full-convention">,
667667
HelpText<"When emitting a module interface or SIL, emit additional @convention"
668-
" arguments, regardless of whether they were written in the source">;
668+
" arguments, regardless of whether they were written in the source."
669+
" Also requires -use-clang-function-types to be enabled.">;
669670

670671
def experimental_one_way_closure_params :
671672
Flag<["-"], "experimental-one-way-closure-params">,

lib/AST/ClangTypeConverter.cpp

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -623,13 +623,44 @@ clang::QualType ClangTypeConverter::visitEnumType(EnumType *type) {
623623
}
624624

625625
clang::QualType ClangTypeConverter::visitFunctionType(FunctionType *type) {
626-
// We must've already computed it before if applicable.
627-
return clang::QualType(type->getClangTypeInfo().getType(), 0);
626+
const clang::Type *clangTy = nullptr;
627+
auto repr = type->getRepresentation();
628+
bool useClangTypes = type->getASTContext().LangOpts.UseClangFunctionTypes;
629+
if (useClangTypes && (getSILFunctionLanguage(convertRepresentation(repr)) ==
630+
SILFunctionLanguage::C)) {
631+
clangTy = type->getClangTypeInfo().getType();
632+
} else if (!useClangTypes || repr == FunctionTypeRepresentation::Swift) {
633+
// C function pointer types themselves are not bridged but their components
634+
// can be. If a component is an @convention(block) function, it may be
635+
// bridged to a Swift function type.
636+
auto newRepr = (repr == FunctionTypeRepresentation::Swift
637+
? FunctionTypeRepresentation::Block
638+
: repr);
639+
clangTy = getFunctionType(type->getParams(), type->getResult(), newRepr);
640+
}
641+
return clang::QualType(clangTy, 0);
628642
}
629643

630644
clang::QualType ClangTypeConverter::visitSILFunctionType(SILFunctionType *type) {
631-
// We must've already computed it before if applicable.
632-
return clang::QualType(type->getClangTypeInfo().getType(), 0);
645+
const clang::Type *clangTy = nullptr;
646+
auto repr = type->getRepresentation();
647+
bool useClangTypes = type->getASTContext().LangOpts.UseClangFunctionTypes;
648+
if (useClangTypes &&
649+
(getSILFunctionLanguage(repr) == SILFunctionLanguage::C)) {
650+
clangTy = type->getClangTypeInfo().getType();
651+
} else if (!useClangTypes || repr == SILFunctionTypeRepresentation::Thick) {
652+
// C function pointer types themselves are not bridged but their components
653+
// can be. If a component is an @convention(block) function, it may be
654+
// bridged to a Swift function type.
655+
auto newRepr = (repr == SILFunctionTypeRepresentation::Thick
656+
? SILFunctionTypeRepresentation::Block
657+
: repr);
658+
auto results = type->getResults();
659+
auto optionalResult =
660+
results.empty() ? None : llvm::Optional<SILResultInfo>(results[0]);
661+
clangTy = getFunctionType(type->getParameters(), optionalResult, newRepr);
662+
}
663+
return clang::QualType(clangTy, 0);
633664
}
634665

635666
clang::QualType

test/ClangImporter/blocks_returning_bool.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen %s -I %S/Inputs/ | %FileCheck %s
22

3+
// Check that bridging an @convention(c)'s function's @convention(block)
4+
// parameter to a Swift function type doesn't crash the compiler.
5+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen %s -I %S/Inputs/ -o /dev/null -use-clang-function-types -experimental-print-full-convention
6+
37
// REQUIRES: objc_interop
48

59
import Foundation

test/ClangImporter/clang-function-types.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -typecheck -swift-version 5 -emit-module-interface-path - -sdk %clang-importer-sdk -enable-library-evolution %s -experimental-print-full-convention | %FileCheck %s
1+
// RUN: %target-swift-frontend -typecheck -swift-version 5 -emit-module-interface-path - -sdk %clang-importer-sdk -enable-library-evolution %s -experimental-print-full-convention -use-clang-function-types | %FileCheck %s
22

33
import ctypes
44

test/ModuleInterface/full-convention.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -swift-version 5 -emit-module-interface-path - -enable-library-evolution %s -experimental-print-full-convention | %FileCheck %s
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -swift-version 5 -emit-module-interface-path - -enable-library-evolution %s -experimental-print-full-convention -use-clang-function-types | %FileCheck %s
22

33
import ctypes
44

0 commit comments

Comments
 (0)