Skip to content

Fix some problems in ClangTypeConverter::getFunctionType #28726

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 13, 2019
Merged
Show file tree
Hide file tree
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
Expand Up @@ -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; }
Expand Down
24 changes: 15 additions & 9 deletions lib/AST/ClangTypeConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
Expand Down
13 changes: 8 additions & 5 deletions lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.");
}
Expand Down
2 changes: 1 addition & 1 deletion lib/ClangImporter/ImportType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ namespace {
funcTy->getExtInfo()
.withRepresentation(
AnyFunctionType::Representation::CFunctionPointer)
.withClangFunctionType(pointeeQualType.getTypePtr())),
.withClangFunctionType(type)),
ImportHint::CFunctionPointer
};
}
Expand Down