@@ -227,6 +227,24 @@ clang::QualType ClangTypeConverter::convertMemberType(NominalTypeDecl *DC,
227
227
return convert (memberType);
228
228
}
229
229
230
+ clang::QualType ClangTypeConverter::visitStructType (StructType *type) {
231
+ auto importedType = reverseImportedTypeMapping (type);
232
+ if (!importedType.isNull ())
233
+ return importedType;
234
+
235
+ // We might be looking at a builtin
236
+ auto builtinType = reverseBuiltinTypeMapping (type);
237
+ if (!builtinType.isNull ())
238
+ return builtinType;
239
+
240
+ if (type->isPotentiallyBridgedValueType ())
241
+ if (auto t = Context.getBridgedToObjC (type->getDecl (), type))
242
+ return convert (t);
243
+
244
+ // Out of ideas, there must've been some error. :(
245
+ return clang::QualType ();
246
+ }
247
+
230
248
// TODO: It is unfortunate that we parse the name of a public library type
231
249
// in order to break it down into a vector component and length that in theory
232
250
// we could recover in some other way.
@@ -244,7 +262,8 @@ static clang::QualType getClangVectorType(const clang::ASTContext &ctx,
244
262
return ctx.getVectorType (eltTy, numElts, vecKind);
245
263
}
246
264
247
- clang::QualType ClangTypeConverter::visitStructType (StructType *type) {
265
+ clang::QualType
266
+ ClangTypeConverter::reverseImportedTypeMapping (StructType *type) {
248
267
auto &ctx = ClangASTContext;
249
268
250
269
auto swiftDecl = type->getDecl ();
@@ -281,17 +300,7 @@ clang::QualType ClangTypeConverter::visitStructType(StructType *type) {
281
300
}
282
301
#include " swift/ClangImporter/SIMDMappedTypes.def"
283
302
284
- // We might be looking at a builtin
285
- auto ret = reverseBuiltinTypeMapping (type);
286
- if (!ret.isNull ())
287
- return ret;
288
-
289
- if (type->isPotentiallyBridgedValueType ()) {
290
- if (auto t = Context.getBridgedToObjC (type->getDecl (), type))
291
- return convert (t);
292
- }
293
-
294
- // Out of ideas, there must've been some error. :(
303
+ // This is not an imported type (according to the name)
295
304
return clang::QualType ();
296
305
}
297
306
@@ -834,30 +843,16 @@ clang::QualType ClangTypeConverter::convert(Type type) {
834
843
if (it != Cache.end ())
835
844
return it->second ;
836
845
837
- // Try to do this without making cache entries for obvious cases.
838
846
if (auto existential = type->getAs <ExistentialType>())
839
847
type = existential->getConstraintType ();
840
848
849
+ // Try to do this without making cache entries for obvious cases.
841
850
if (auto nominal = type->getAs <NominalType>()) {
842
851
auto decl = nominal->getDecl ();
843
852
if (auto clangDecl = decl->getClangDecl ()) {
844
- auto &ctx = ClangASTContext;
845
- if (auto clangTypeDecl = dyn_cast<clang::TypeDecl>(clangDecl)) {
846
- auto qualType = ctx.getTypeDeclType (clangTypeDecl);
847
- if (type->isForeignReferenceType ()) {
848
- qualType = ctx.getPointerType (qualType);
849
- }
850
- return qualType.getUnqualifiedType ();
851
- } else if (auto ifaceDecl = dyn_cast<clang::ObjCInterfaceDecl>(clangDecl)) {
852
- auto clangType = ctx.getObjCInterfaceType (ifaceDecl);
853
- return ctx.getObjCObjectPointerType (clangType);
854
- } else if (auto protoDecl = dyn_cast<clang::ObjCProtocolDecl>(clangDecl)){
855
- auto clangType = ctx.getObjCObjectType (
856
- ctx.ObjCBuiltinIdTy ,
857
- const_cast <clang::ObjCProtocolDecl **>(&protoDecl),
858
- 1 );
859
- return ctx.getObjCObjectPointerType (clangType);
860
- }
853
+ auto qualType = convertClangDecl (type, clangDecl);
854
+ if (!qualType.isNull ())
855
+ return qualType;
861
856
}
862
857
}
863
858
@@ -867,6 +862,34 @@ clang::QualType ClangTypeConverter::convert(Type type) {
867
862
return result;
868
863
}
869
864
865
+ clang::QualType
866
+ ClangTypeConverter::convertClangDecl (Type type, const clang::Decl *clangDecl) {
867
+ auto &ctx = ClangASTContext;
868
+
869
+ if (auto clangTypeDecl = dyn_cast<clang::TypeDecl>(clangDecl)) {
870
+ auto qualType = ctx.getTypeDeclType (clangTypeDecl);
871
+ if (type->isForeignReferenceType ())
872
+ qualType = ctx.getPointerType (qualType);
873
+
874
+ return qualType.getUnqualifiedType ();
875
+ }
876
+
877
+ if (auto ifaceDecl = dyn_cast<clang::ObjCInterfaceDecl>(clangDecl)) {
878
+ auto clangType = ctx.getObjCInterfaceType (ifaceDecl);
879
+ return ctx.getObjCObjectPointerType (clangType);
880
+ }
881
+
882
+ if (auto protoDecl = dyn_cast<clang::ObjCProtocolDecl>(clangDecl)) {
883
+ auto clangType = ctx.getObjCObjectType (
884
+ ctx.ObjCBuiltinIdTy , const_cast <clang::ObjCProtocolDecl **>(&protoDecl),
885
+ 1 );
886
+ return ctx.getObjCObjectPointerType (clangType);
887
+ }
888
+
889
+ // Unable to convert this ClangDecl; give up
890
+ return clang::QualType ();
891
+ }
892
+
870
893
void ClangTypeConverter::registerExportedClangDecl (Decl *swiftDecl,
871
894
const clang::Decl *clangDecl) {
872
895
assert (clangDecl->isCanonicalDecl () &&
@@ -883,6 +906,46 @@ Decl *ClangTypeConverter::getSwiftDeclForExportedClangDecl(
883
906
return (it != ReversedExportMap.end () ? it->second : nullptr );
884
907
}
885
908
909
+ clang::QualType ClangTypeConverter::convertTemplateArgument (Type type) {
910
+ // C++ function templates can only be instantiated with Clang types and
911
+ // a handful of Swift builtin types. These are enumerated here rather than
912
+ // delegated to ClangTypeConverter::convert() (which is more general).
913
+
914
+ if (auto nominal = type->getAs <NominalType>())
915
+ if (auto clangDecl = nominal->getDecl ()->getClangDecl ())
916
+ return convertClangDecl (type, clangDecl);
917
+
918
+ if (auto pointerType = type->getAs <BuiltinRawPointerType>())
919
+ return visitBuiltinRawPointerType (pointerType);
920
+
921
+ if (auto integerType = type->getAs <BuiltinIntegerType>())
922
+ return visitBuiltinIntegerType (integerType);
923
+
924
+ if (auto floatType = type->getAs <BuiltinFloatType>())
925
+ return visitBuiltinFloatType (floatType);
926
+
927
+ if (auto structType = type->getAs <StructType>()) {
928
+ // Swift structs are not supported in general, but some foreign types are
929
+ // imported as Swift structs. We reverse that mapping here.
930
+ auto decl = structType->getDecl ();
931
+
932
+ // Ban ObjCBool type from being substituted into C++ templates (#74790)
933
+ if (decl->getName ().is (" ObjCBool" ) &&
934
+ decl->getModuleContext ()->getName () ==
935
+ decl->getASTContext ().Id_ObjectiveC )
936
+ return clang::QualType ();
937
+
938
+ auto importedType = reverseImportedTypeMapping (structType);
939
+ if (!importedType.isNull ())
940
+ return importedType;
941
+
942
+ return reverseBuiltinTypeMapping (structType);
943
+ }
944
+
945
+ // Most types cannot be used to instantiate C++ function templates; give up.
946
+ return clang::QualType ();
947
+ }
948
+
886
949
std::unique_ptr<TemplateInstantiationError>
887
950
ClangTypeConverter::getClangTemplateArguments (
888
951
const clang::TemplateParameterList *templateParams,
@@ -906,25 +969,12 @@ ClangTypeConverter::getClangTemplateArguments(
906
969
907
970
auto replacement = genericArgs[templateParam->getIndex ()];
908
971
909
- // Ban ObjCBool type from being substituted into C++ templates.
910
- if (auto nominal = replacement->getAs <NominalType>()) {
911
- if (auto nominalDecl = nominal->getDecl ()) {
912
- if (nominalDecl->getName ().is (" ObjCBool" ) &&
913
- nominalDecl->getModuleContext ()->getName () ==
914
- nominalDecl->getASTContext ().Id_ObjectiveC ) {
915
- failedTypes.push_back (replacement);
916
- continue ;
917
- }
918
- }
919
- }
972
+ auto qualType = convertTemplateArgument (replacement);
920
973
921
- auto qualType = convert (replacement);
922
- if (qualType.isNull ()) {
974
+ if (qualType.isNull ())
923
975
failedTypes.push_back (replacement);
924
- // Find all the types we can't convert.
925
- continue ;
926
- }
927
- templateArgs.push_back (clang::TemplateArgument (qualType));
976
+ else
977
+ templateArgs.push_back (clang::TemplateArgument (qualType));
928
978
}
929
979
if (failedTypes.empty ())
930
980
return nullptr ;
0 commit comments