Skip to content

Commit a6f5c57

Browse files
Merge pull request #28726 from varungandhi-apple/vg-fix-ClangTypeConverter.getFunctionType
Fix some problems in ClangTypeConverter::getFunctionType
2 parents f5b9ed6 + 61a2a11 commit a6f5c57

File tree

4 files changed

+29
-17
lines changed

4 files changed

+29
-17
lines changed

include/swift/AST/Types.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2925,8 +2925,11 @@ class AnyFunctionType : public TypeBase {
29252925
friend ExtInfo;
29262926
friend class AnyFunctionType;
29272927
friend class FunctionType;
2928-
// We preserve a full clang::Type *, not a clang::FunctionType *, so
2929-
// we can keep sugar in case we need to present an error to the user.
2928+
// We preserve a full clang::Type *, not a clang::FunctionType * as:
2929+
// 1. We need to keep sugar in case we need to present an error to the user.
2930+
// 2. The actual type being stored is [ignoring sugar] either a
2931+
// clang::PointerType or a clang::BlockPointerType which points to a
2932+
// clang::FunctionType.
29302933
const clang::Type *ClangFunctionType;
29312934

29322935
bool empty() const { return !ClangFunctionType; }

lib/AST/ClangTypeConverter.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,32 +118,38 @@ const clang::Type *ClangTypeConverter::getFunctionType(
118118
ArrayRef<AnyFunctionType::Param> params, Type resultTy,
119119
AnyFunctionType::Representation repr) {
120120

121-
SmallVector<Type, 4> paramsTy;
122-
for (auto p : params)
123-
paramsTy.push_back(p.getPlainType());
124-
125121
auto resultClangTy = convert(resultTy);
126122
if (resultClangTy.isNull())
127123
return nullptr;
128124

129-
SmallVector<clang::QualType, 8> paramsClangTy;
130-
for (auto p : paramsTy) {
131-
auto pc = convert(p);
125+
SmallVector<clang::FunctionProtoType::ExtParameterInfo, 4> extParamInfos;
126+
SmallVector<clang::QualType, 4> paramsClangTy;
127+
bool someParamIsConsumed = false;
128+
for (auto p : params) {
129+
auto pc = convert(p.getPlainType());
132130
if (pc.isNull())
133131
return nullptr;
132+
clang::FunctionProtoType::ExtParameterInfo extParamInfo;
133+
if (p.getParameterFlags().isOwned()) {
134+
someParamIsConsumed = true;
135+
extParamInfo = extParamInfo.withIsConsumed(true);
136+
}
137+
extParamInfos.push_back(extParamInfo);
134138
paramsClangTy.push_back(pc);
135139
}
136140

137141
clang::FunctionProtoType::ExtProtoInfo info(clang::CallingConv::CC_C);
142+
if (someParamIsConsumed)
143+
info.ExtParameterInfos = extParamInfos.begin();
138144
auto fn = ClangASTContext.getFunctionType(resultClangTy, paramsClangTy, info);
139145
if (fn.isNull())
140146
return nullptr;
141147

142148
switch (repr) {
143149
case AnyFunctionType::Representation::CFunctionPointer:
144-
return fn.getTypePtr();
150+
return ClangASTContext.getPointerType(fn).getTypePtr();
145151
case AnyFunctionType::Representation::Block:
146-
return ClangASTContext.getBlockPointerType(fn).getTypePtrOrNull();
152+
return ClangASTContext.getBlockPointerType(fn).getTypePtr();
147153
case AnyFunctionType::Representation::Swift:
148154
case AnyFunctionType::Representation::Thin:
149155
llvm_unreachable("Expected a C-compatible representation.");

lib/AST/Type.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3235,10 +3235,13 @@ Type ProtocolCompositionType::get(const ASTContext &C,
32353235
void
32363236
AnyFunctionType::ExtInfo::assertIsFunctionType(const clang::Type *type) {
32373237
#ifndef NDEBUG
3238-
if (!type->isFunctionType()) {
3239-
llvm::errs() << "Expected a Clang function type but found\n";
3240-
type->dump(llvm::errs());
3241-
llvm_unreachable("");
3238+
if (!(type->isFunctionPointerType() || type->isBlockPointerType())) {
3239+
SmallString<256> buf;
3240+
llvm::raw_svector_ostream os(buf);
3241+
os << "Expected a Clang function type wrapped in a pointer type or "
3242+
<< "a block pointer type but found:\n";
3243+
type->dump(os);
3244+
llvm_unreachable(os.str().data());
32423245
}
32433246
#endif
32443247
return;
@@ -3250,7 +3253,7 @@ const clang::Type *AnyFunctionType::getClangFunctionType() const {
32503253
return cast<FunctionType>(this)->getClangFunctionType();
32513254
case TypeKind::GenericFunction:
32523255
// Generic functions do not have C types.
3253-
return nullptr;
3256+
return nullptr;
32543257
default:
32553258
llvm_unreachable("Illegal type kind for AnyFunctionType.");
32563259
}

lib/ClangImporter/ImportType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ namespace {
421421
funcTy->getExtInfo()
422422
.withRepresentation(
423423
AnyFunctionType::Representation::CFunctionPointer)
424-
.withClangFunctionType(pointeeQualType.getTypePtr())),
424+
.withClangFunctionType(type)),
425425
ImportHint::CFunctionPointer
426426
};
427427
}

0 commit comments

Comments
 (0)