40
40
#include " clang/Basic/TargetInfo.h"
41
41
#include " clang/Sema/Sema.h"
42
42
43
+ #include " llvm/ADT/STLExtras.h"
43
44
#include " llvm/ADT/StringSwitch.h"
44
45
#include " llvm/Support/Compiler.h"
45
46
@@ -124,17 +125,18 @@ const clang::ASTContext &clangCtx) {
124
125
125
126
const clang::Type *ClangTypeConverter::getFunctionType (
126
127
ArrayRef<AnyFunctionType::Param> params, Type resultTy,
127
- AnyFunctionType::Representation repr) {
128
-
129
- auto resultClangTy = convert (resultTy);
128
+ AnyFunctionType::Representation repr, bool templateArgument ) {
129
+ auto resultClangTy =
130
+ templateArgument ? convertTemplateArgument (resultTy) : convert (resultTy);
130
131
if (resultClangTy.isNull ())
131
132
return nullptr ;
132
133
133
134
SmallVector<clang::FunctionProtoType::ExtParameterInfo, 4 > extParamInfos;
134
135
SmallVector<clang::QualType, 4 > paramsClangTy;
135
136
bool someParamIsConsumed = false ;
136
137
for (auto p : params) {
137
- auto pc = convert (p.getPlainType ());
138
+ auto pc = templateArgument ? convertTemplateArgument (p.getPlainType ())
139
+ : convert (p.getPlainType ());
138
140
if (pc.isNull ())
139
141
return nullptr ;
140
142
clang::FunctionProtoType::ExtParameterInfo extParamInfo;
@@ -165,16 +167,19 @@ const clang::Type *ClangTypeConverter::getFunctionType(
165
167
llvm_unreachable (" invalid representation" );
166
168
}
167
169
168
- const clang::Type *
169
- ClangTypeConverter::getFunctionType (ArrayRef<SILParameterInfo> params,
170
- std::optional<SILResultInfo> result,
171
- SILFunctionType::Representation repr) {
172
-
173
- // Using the interface type is sufficient as type parameters get mapped to
174
- // `id`, since ObjC lightweight generics use type erasure. (See also: SE-0057)
175
- auto resultClangTy = result.has_value ()
176
- ? convert (result.value ().getInterfaceType ())
177
- : ClangASTContext.VoidTy ;
170
+ const clang::Type *ClangTypeConverter::getFunctionType (
171
+ ArrayRef<SILParameterInfo> params, std::optional<SILResultInfo> result,
172
+ SILFunctionType::Representation repr, bool templateArgument) {
173
+ clang::QualType resultClangTy = ClangASTContext.VoidTy ;
174
+ if (result) {
175
+ // Using the interface type is sufficient as type parameters get mapped to
176
+ // `id`, since ObjC lightweight generics use type erasure.
177
+ //
178
+ // (See also: SE-0057)
179
+ auto interfaceType = result->getInterfaceType ();
180
+ resultClangTy = templateArgument ? convertTemplateArgument (interfaceType)
181
+ : convert (interfaceType);
182
+ }
178
183
179
184
if (resultClangTy.isNull ())
180
185
return nullptr ;
@@ -183,7 +188,8 @@ ClangTypeConverter::getFunctionType(ArrayRef<SILParameterInfo> params,
183
188
SmallVector<clang::QualType, 4 > paramsClangTy;
184
189
bool someParamIsConsumed = false ;
185
190
for (auto &p : params) {
186
- auto pc = convert (p.getInterfaceType ());
191
+ auto pc = templateArgument ? convertTemplateArgument (p.getInterfaceType ())
192
+ : convert (p.getInterfaceType ());
187
193
if (pc.isNull ())
188
194
return nullptr ;
189
195
clang::FunctionProtoType::ExtParameterInfo extParamInfo;
@@ -651,7 +657,8 @@ clang::QualType ClangTypeConverter::visitEnumType(EnumType *type) {
651
657
return convert (type->getDecl ()->getRawType ());
652
658
}
653
659
654
- clang::QualType ClangTypeConverter::visitFunctionType (FunctionType *type) {
660
+ clang::QualType ClangTypeConverter::visitFunctionType (FunctionType *type,
661
+ bool templateArgument) {
655
662
const clang::Type *clangTy = nullptr ;
656
663
auto repr = type->getRepresentation ();
657
664
bool useClangTypes = type->getASTContext ().LangOpts .UseClangFunctionTypes ;
@@ -665,12 +672,15 @@ clang::QualType ClangTypeConverter::visitFunctionType(FunctionType *type) {
665
672
auto newRepr = (repr == FunctionTypeRepresentation::Swift
666
673
? FunctionTypeRepresentation::Block
667
674
: repr);
668
- clangTy = getFunctionType (type->getParams (), type->getResult (), newRepr);
675
+ clangTy = getFunctionType (type->getParams (), type->getResult (), newRepr,
676
+ templateArgument);
669
677
}
670
678
return clang::QualType (clangTy, 0 );
671
679
}
672
680
673
- clang::QualType ClangTypeConverter::visitSILFunctionType (SILFunctionType *type) {
681
+ clang::QualType
682
+ ClangTypeConverter::visitSILFunctionType (SILFunctionType *type,
683
+ bool templateArgument) {
674
684
const clang::Type *clangTy = nullptr ;
675
685
auto repr = type->getRepresentation ();
676
686
bool useClangTypes = type->getASTContext ().LangOpts .UseClangFunctionTypes ;
@@ -688,7 +698,8 @@ clang::QualType ClangTypeConverter::visitSILFunctionType(SILFunctionType *type)
688
698
auto optionalResult = results.empty ()
689
699
? std::nullopt
690
700
: std::optional<SILResultInfo>(results[0 ]);
691
- clangTy = getFunctionType (type->getParameters (), optionalResult, newRepr);
701
+ clangTy = getFunctionType (type->getParameters (), optionalResult, newRepr,
702
+ templateArgument);
692
703
}
693
704
return clang::QualType (clangTy, 0 );
694
705
}
@@ -933,6 +944,13 @@ clang::QualType ClangTypeConverter::convertTemplateArgument(Type type) {
933
944
if (auto floatType = type->getAs <BuiltinFloatType>())
934
945
return withCache ([&]() { return visitBuiltinFloatType (floatType); });
935
946
947
+ if (auto tupleType = type->getAs <TupleType>()) {
948
+ // We do not call visitTupleType() because we cannot yet handle tuples with
949
+ // a non-zero number of elements.
950
+ if (tupleType->getNumElements () == 0 )
951
+ return ClangASTContext.VoidTy ;
952
+ }
953
+
936
954
if (auto structType = type->getAs <StructType>()) {
937
955
// Swift structs are not supported in general, but some foreign types are
938
956
// imported as Swift structs. We reverse that mapping here.
@@ -953,8 +971,6 @@ clang::QualType ClangTypeConverter::convertTemplateArgument(Type type) {
953
971
return withCache ([&]() { return reverseBuiltinTypeMapping (structType); });
954
972
}
955
973
956
- // TODO: function pointers are not yet supported, but they should be.
957
-
958
974
if (auto boundGenericType = type->getAs <BoundGenericType>()) {
959
975
if (boundGenericType->getGenericArgs ().size () != 1 )
960
976
// Must've got something other than a T?, *Pointer<T>, or SIMD*<T>
@@ -991,6 +1007,18 @@ clang::QualType ClangTypeConverter::convertTemplateArgument(Type type) {
991
1007
return clang::QualType ();
992
1008
}
993
1009
1010
+ if (auto functionType = type->getAs <FunctionType>()) {
1011
+ return withCache ([&]() {
1012
+ return visitFunctionType (functionType, /* templateArgument=*/ true );
1013
+ });
1014
+ }
1015
+
1016
+ if (auto functionType = type->getAs <SILFunctionType>()) {
1017
+ return withCache ([&]() {
1018
+ return visitSILFunctionType (functionType, /* templateArgument=*/ true );
1019
+ });
1020
+ }
1021
+
994
1022
// Most types cannot be used to instantiate C++ function templates; give up.
995
1023
return clang::QualType ();
996
1024
}
0 commit comments