Skip to content

Commit bfa2f98

Browse files
[AST] Add functionality for computing Clang types for SIL functions.
1 parent feb76ea commit bfa2f98

File tree

4 files changed

+92
-6
lines changed

4 files changed

+92
-6
lines changed

include/swift/AST/ASTContext.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,10 @@ class ASTContext final {
576576
Type getBridgedToObjC(const DeclContext *dc, Type type,
577577
Type *bridgedValueType = nullptr) const;
578578

579+
private:
580+
void initializeClangTypeConverter();
581+
582+
public:
579583
/// Get the Clang type corresponding to a Swift function type.
580584
///
581585
/// \param params The function parameters.
@@ -589,6 +593,15 @@ class ASTContext final {
589593
const FunctionType::ExtInfo incompleteExtInfo,
590594
FunctionTypeRepresentation trueRep);
591595

596+
/// Get the canonical Clang type corresponding to a SIL function type.
597+
///
598+
/// SIL analog of \c ASTContext::getClangFunctionType .
599+
const clang::Type *
600+
getCanonicalClangFunctionType(
601+
ArrayRef<SILParameterInfo> params, Optional<SILResultInfo> result,
602+
const SILFunctionType::ExtInfo incompleteExtInfo,
603+
SILFunctionType::Representation trueRep);
604+
592605
/// Determine whether the given Swift type is representable in a
593606
/// given foreign language.
594607
ForeignRepresentationInfo

lib/AST/ASTContext.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4372,17 +4372,35 @@ Type ASTContext::getBridgedToObjC(const DeclContext *dc, Type type,
43724372
return Type();
43734373
}
43744374

4375-
const clang::Type *
4376-
ASTContext::getClangFunctionType(ArrayRef<AnyFunctionType::Param> params,
4377-
Type resultTy,
4378-
FunctionType::ExtInfo incompleteExtInfo,
4379-
FunctionTypeRepresentation trueRep) {
4375+
void
4376+
ASTContext::initializeClangTypeConverter() {
43804377
auto &impl = getImpl();
43814378
if (!impl.Converter) {
43824379
auto *cml = getClangModuleLoader();
43834380
impl.Converter.emplace(*this, cml->getClangASTContext(), LangOpts.Target);
43844381
}
4385-
return impl.Converter.getValue().getFunctionType(params, resultTy, trueRep);
4382+
}
4383+
4384+
const clang::Type *
4385+
ASTContext::getClangFunctionType(ArrayRef<AnyFunctionType::Param> params,
4386+
Type resultTy,
4387+
FunctionType::ExtInfo incompleteExtInfo,
4388+
FunctionTypeRepresentation trueRep) {
4389+
initializeClangTypeConverter();
4390+
return getImpl().Converter.getValue().getFunctionType(params, resultTy,
4391+
trueRep);
4392+
}
4393+
4394+
const clang::Type *
4395+
ASTContext::getCanonicalClangFunctionType(
4396+
ArrayRef<SILParameterInfo> params,
4397+
Optional<SILResultInfo> result,
4398+
SILFunctionType::ExtInfo incompleteExtInfo,
4399+
SILFunctionType::Representation trueRep) {
4400+
initializeClangTypeConverter();
4401+
auto *ty = getImpl().Converter.getValue().getFunctionType(params, result,
4402+
trueRep);
4403+
return ty ? ty->getCanonicalTypeInternal().getTypePtr() : nullptr;
43864404
}
43874405

43884406
CanGenericSignature ASTContext::getSingleGenericParameterSignature() const {

lib/AST/ClangTypeConverter.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,57 @@ const clang::Type *ClangTypeConverter::getFunctionType(
156156
}
157157
}
158158

159+
const clang::Type *ClangTypeConverter::getFunctionType(
160+
ArrayRef<SILParameterInfo> params, Optional<SILResultInfo> result,
161+
SILFunctionType::Representation repr) {
162+
163+
// Using the interface type is sufficient as Swift does not allow abstracting
164+
// over @convention(c) functions, hence we don't need any substitutions.
165+
auto resultClangTy = result.hasValue()
166+
? convert(result.getValue().getInterfaceType())
167+
: ClangASTContext.VoidTy;
168+
169+
if (resultClangTy.isNull())
170+
return nullptr;
171+
172+
SmallVector<clang::FunctionProtoType::ExtParameterInfo, 4> extParamInfos;
173+
SmallVector<clang::QualType, 4> paramsClangTy;
174+
bool someParamIsConsumed = false;
175+
for (auto &p : params) {
176+
auto pc = convert(p.getInterfaceType());
177+
if (pc.isNull())
178+
return nullptr;
179+
clang::FunctionProtoType::ExtParameterInfo extParamInfo;
180+
if (p.isConsumed()) {
181+
someParamIsConsumed = true;
182+
extParamInfo = extParamInfo.withIsConsumed(true);
183+
}
184+
extParamInfos.push_back(extParamInfo);
185+
paramsClangTy.push_back(pc);
186+
}
187+
188+
clang::FunctionProtoType::ExtProtoInfo info(clang::CallingConv::CC_C);
189+
if (someParamIsConsumed)
190+
info.ExtParameterInfos = extParamInfos.begin();
191+
auto fn = ClangASTContext.getFunctionType(resultClangTy, paramsClangTy, info);
192+
if (fn.isNull())
193+
return nullptr;
194+
195+
switch (repr) {
196+
case SILFunctionType::Representation::CFunctionPointer:
197+
return ClangASTContext.getPointerType(fn).getTypePtr();
198+
case SILFunctionType::Representation::Block:
199+
return ClangASTContext.getBlockPointerType(fn).getTypePtr();
200+
case SILFunctionType::Representation::Thick:
201+
case SILFunctionType::Representation::Thin:
202+
case SILFunctionType::Representation::Method:
203+
case SILFunctionType::Representation::ObjCMethod:
204+
case SILFunctionType::Representation::WitnessMethod:
205+
case SILFunctionType::Representation::Closure:
206+
llvm_unreachable("Expected a C-compatible representation.");
207+
}
208+
}
209+
159210
clang::QualType ClangTypeConverter::convertMemberType(NominalTypeDecl *DC,
160211
StringRef memberName) {
161212
auto memberTypeDecl = cast<TypeDecl>(

lib/AST/ClangTypeConverter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ class ClangTypeConverter :
7373
ArrayRef<AnyFunctionType::Param> params, Type resultTy,
7474
AnyFunctionType::Representation repr);
7575

76+
const clang::Type *getFunctionType(
77+
ArrayRef<SILParameterInfo> params, Optional<SILResultInfo> result,
78+
SILFunctionType::Representation repr);
79+
7680
private:
7781
clang::QualType convert(Type type);
7882
clang::QualType convertMemberType(NominalTypeDecl *DC,

0 commit comments

Comments
 (0)