diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 5b216847cd3..6a5e7a1f145 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -2925,8 +2925,11 @@ public: 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; } diff --git a/lib/AST/ClangTypeConverter.cpp b/lib/AST/ClangTypeConverter.cpp index 07ade583b19..58a5b2a5a41 100644 --- a/lib/AST/ClangTypeConverter.cpp +++ b/lib/AST/ClangTypeConverter.cpp @@ -137,9 +137,9 @@ const clang::Type *ClangTypeConverter::getFunctionType( 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."); diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 1ac3ef765ef..01e89ce6247 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -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(this)->getClangFunctionType(); case TypeKind::GenericFunction: // Generic functions do not have C types. - return nullptr; + return nullptr; default: llvm_unreachable("Illegal type kind for AnyFunctionType."); } diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp index 94425388d65..8e112ab39ef 100644 --- a/lib/ClangImporter/ImportType.cpp +++ b/lib/ClangImporter/ImportType.cpp @@ -421,7 +421,7 @@ namespace { funcTy->getExtInfo() .withRepresentation( AnyFunctionType::Representation::CFunctionPointer) - .withClangFunctionType(pointeeQualType.getTypePtr())), + .withClangFunctionType(type)), ImportHint::CFunctionPointer }; }