@@ -406,7 +406,8 @@ void ClangValueTypePrinter::printValueTypeDecl(
406406 printCValueTypeStorageStruct (cPrologueOS, typeDecl, *typeSizeAlign);
407407
408408 printTypeGenericTraits (os, typeDecl, typeMetadataFuncName,
409- typeMetadataFuncGenericParams);
409+ typeMetadataFuncGenericParams,
410+ typeDecl->getModuleContext ());
410411}
411412
412413void ClangValueTypePrinter::printParameterCxxToCUseScaffold (
@@ -456,24 +457,47 @@ void ClangValueTypePrinter::printValueTypeReturnScaffold(
456457 os << " });\n " ;
457458}
458459
460+ void ClangValueTypePrinter::printClangTypeSwiftGenericTraits (
461+ raw_ostream &os, const NominalTypeDecl *typeDecl,
462+ const ModuleDecl *moduleContext) {
463+ assert (typeDecl->hasClangNode ());
464+ // Do not reference unspecialized templates.
465+ if (isa<clang::ClassTemplateDecl>(typeDecl->getClangDecl ()))
466+ return ;
467+ auto typeMetadataFunc = irgen::LinkEntity::forTypeMetadataAccessFunction (
468+ typeDecl->getDeclaredType ()->getCanonicalType ());
469+ std::string typeMetadataFuncName = typeMetadataFunc.mangleAsString ();
470+ printTypeGenericTraits (os, typeDecl, typeMetadataFuncName,
471+ /* typeMetadataFuncRequirements=*/ {}, moduleContext);
472+ }
473+
459474void ClangValueTypePrinter::printTypeGenericTraits (
460475 raw_ostream &os, const NominalTypeDecl *typeDecl,
461476 StringRef typeMetadataFuncName,
462- ArrayRef<GenericRequirement> typeMetadataFuncRequirements) {
477+ ArrayRef<GenericRequirement> typeMetadataFuncRequirements,
478+ const ModuleDecl *moduleContext) {
463479 ClangSyntaxPrinter printer (os);
464480 // FIXME: avoid popping out of the module's namespace here.
465481 os << " } // end namespace \n\n " ;
466482 os << " namespace swift {\n " ;
467483
484+ if (typeDecl->hasClangNode ()) {
485+ // / Print a reference to the type metadata fucntion for a C++ type.
486+ ClangSyntaxPrinter (os).printNamespace (
487+ cxx_synthesis::getCxxImplNamespaceName (), [&](raw_ostream &os) {
488+ ClangSyntaxPrinter (os).printCTypeMetadataTypeFunction (
489+ typeDecl, typeMetadataFuncName, typeMetadataFuncRequirements);
490+ });
491+ }
492+
468493 os << " #pragma clang diagnostic push\n " ;
469494 os << " #pragma clang diagnostic ignored \" -Wc++17-extensions\"\n " ;
470495 if (typeMetadataFuncRequirements.empty ()) {
471496 // FIXME: generic type support.
472497 os << " template<>\n " ;
473498 os << " static inline const constexpr bool isUsableInGenericContext<" ;
474- printer.printBaseName (typeDecl->getModuleContext ());
475- os << " ::" ;
476- printer.printBaseName (typeDecl);
499+ printer.printNominalTypeReference (typeDecl,
500+ /* moduleContext=*/ nullptr );
477501 os << " > = true;\n " ;
478502 }
479503 if (printer.printNominalTypeOutsideMemberDeclTemplateSpecifiers (typeDecl))
@@ -484,16 +508,27 @@ void ClangValueTypePrinter::printTypeGenericTraits(
484508 os << " > {\n " ;
485509 os << " static inline void * _Nonnull getTypeMetadata() {\n " ;
486510 os << " return " ;
487- printer.printBaseName (typeDecl->getModuleContext ());
488- os << " ::" << cxx_synthesis::getCxxImplNamespaceName () << " ::" ;
511+ if (!typeDecl->hasClangNode ()) {
512+ printer.printBaseName (typeDecl->getModuleContext ());
513+ os << " ::" ;
514+ }
515+ os << cxx_synthesis::getCxxImplNamespaceName () << " ::" ;
489516 ClangSyntaxPrinter (os).printSwiftTypeMetadataAccessFunctionCall (
490517 typeMetadataFuncName, typeMetadataFuncRequirements);
491518 os << " ._0;\n " ;
492519 os << " }\n };\n " ;
493520
494521 os << " namespace " << cxx_synthesis::getCxxImplNamespaceName () << " {\n " ;
495522
496- if (!isa<ClassDecl>(typeDecl) && typeMetadataFuncRequirements.empty ()) {
523+ if (typeDecl->hasClangNode ()) {
524+ os << " template<>\n " ;
525+ os << " static inline const constexpr bool isSwiftBridgedCxxRecord<" ;
526+ printer.printNominalClangTypeReference (typeDecl->getClangDecl ());
527+ os << " > = true;\n " ;
528+ }
529+
530+ if (!isa<ClassDecl>(typeDecl) && !typeDecl->hasClangNode () &&
531+ typeMetadataFuncRequirements.empty ()) {
497532 // FIXME: generic support.
498533 os << " template<>\n " ;
499534 os << " static inline const constexpr bool isValueType<" ;
@@ -512,7 +547,7 @@ void ClangValueTypePrinter::printTypeGenericTraits(
512547 }
513548
514549 // FIXME: generic support.
515- if (typeMetadataFuncRequirements.empty ()) {
550+ if (!typeDecl-> hasClangNode () && typeMetadataFuncRequirements.empty ()) {
516551 os << " template<>\n " ;
517552 os << " struct implClassFor<" ;
518553 printer.printBaseName (typeDecl->getModuleContext ());
@@ -528,6 +563,6 @@ void ClangValueTypePrinter::printTypeGenericTraits(
528563 os << " #pragma clang diagnostic pop\n " ;
529564 os << " } // namespace swift\n " ;
530565 os << " \n namespace " ;
531- printer.printBaseName (typeDecl-> getModuleContext () );
566+ printer.printBaseName (moduleContext );
532567 os << " {\n " ;
533568}
0 commit comments