Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions include/swift/AST/Types.h
Original file line number Diff line number Diff line change
@@ -2925,8 +2925,11 @@ class AnyFunctionType : public TypeBase {
friend ExtInfo;
friend class AnyFunctionType;
friend class FunctionType;
// We preserve a full clang::Type *, not a clang::FunctionType *, so
// we can keep sugar in case we need to present an error to the user.
// We preserve a full clang::Type *, not a clang::FunctionType * as:
// 1. We need to keep sugar in case we need to present an error to the user.
// 2. The actual type being stored is [ignoring sugar] either a
// clang::PointerType or a clang::BlockPointerType which points to a
// clang::FunctionType.
const clang::Type *ClangFunctionType;

bool empty() const { return !ClangFunctionType; }
24 changes: 15 additions & 9 deletions lib/AST/ClangTypeConverter.cpp
Original file line number Diff line number Diff line change
@@ -118,32 +118,38 @@ const clang::Type *ClangTypeConverter::getFunctionType(
ArrayRef<AnyFunctionType::Param> params, Type resultTy,
AnyFunctionType::Representation repr) {

SmallVector<Type, 4> paramsTy;
for (auto p : params)
paramsTy.push_back(p.getPlainType());

auto resultClangTy = convert(resultTy);
if (resultClangTy.isNull())
return nullptr;

SmallVector<clang::QualType, 8> paramsClangTy;
for (auto p : paramsTy) {
auto pc = convert(p);
SmallVector<clang::FunctionProtoType::ExtParameterInfo, 4> extParamInfos;
SmallVector<clang::QualType, 4> paramsClangTy;
bool someParamIsConsumed = false;
for (auto p : params) {
auto pc = convert(p.getPlainType());
if (pc.isNull())
return nullptr;
clang::FunctionProtoType::ExtParameterInfo extParamInfo;
if (p.getParameterFlags().isOwned()) {
someParamIsConsumed = true;
extParamInfo = extParamInfo.withIsConsumed(true);
}
extParamInfos.push_back(extParamInfo);
paramsClangTy.push_back(pc);
}

clang::FunctionProtoType::ExtProtoInfo info(clang::CallingConv::CC_C);
if (someParamIsConsumed)
info.ExtParameterInfos = extParamInfos.begin();
auto fn = ClangASTContext.getFunctionType(resultClangTy, paramsClangTy, info);
if (fn.isNull())
return nullptr;

switch (repr) {
case AnyFunctionType::Representation::CFunctionPointer:
return fn.getTypePtr();
return ClangASTContext.getPointerType(fn).getTypePtr();
case AnyFunctionType::Representation::Block:
return ClangASTContext.getBlockPointerType(fn).getTypePtrOrNull();
return ClangASTContext.getBlockPointerType(fn).getTypePtr();
case AnyFunctionType::Representation::Swift:
case AnyFunctionType::Representation::Thin:
llvm_unreachable("Expected a C-compatible representation.");
13 changes: 8 additions & 5 deletions lib/AST/Type.cpp
Original file line number Diff line number Diff line change
@@ -3235,10 +3235,13 @@ Type ProtocolCompositionType::get(const ASTContext &C,
void
AnyFunctionType::ExtInfo::assertIsFunctionType(const clang::Type *type) {
#ifndef NDEBUG
if (!type->isFunctionType()) {
llvm::errs() << "Expected a Clang function type but found\n";
type->dump(llvm::errs());
llvm_unreachable("");
if (!(type->isFunctionPointerType() || type->isBlockPointerType())) {
SmallString<256> buf;
llvm::raw_svector_ostream os(buf);
os << "Expected a Clang function type wrapped in a pointer type or "
<< "a block pointer type but found:\n";
type->dump(os);
llvm_unreachable(os.str().data());
}
#endif
return;
@@ -3250,7 +3253,7 @@ const clang::Type *AnyFunctionType::getClangFunctionType() const {
return cast<FunctionType>(this)->getClangFunctionType();
case TypeKind::GenericFunction:
// Generic functions do not have C types.
return nullptr;
return nullptr;
default:
llvm_unreachable("Illegal type kind for AnyFunctionType.");
}
2 changes: 1 addition & 1 deletion lib/ClangImporter/ImportType.cpp
Original file line number Diff line number Diff line change
@@ -421,7 +421,7 @@ namespace {
funcTy->getExtInfo()
.withRepresentation(
AnyFunctionType::Representation::CFunctionPointer)
.withClangFunctionType(pointeeQualType.getTypePtr())),
.withClangFunctionType(type)),
ImportHint::CFunctionPointer
};
}