1414#include " ClangSyntaxPrinter.h"
1515#include " PrintClangValueType.h"
1616#include " swift/AST/Decl.h"
17+ #include " swift/IRGen/Linking.h"
1718
1819using namespace swift ;
1920
@@ -23,12 +24,20 @@ void ClangClassTypePrinter::printClassTypeDecl(
2324
2425 ClangSyntaxPrinter printer (os);
2526
27+ auto typeMetadataFunc = irgen::LinkEntity::forTypeMetadataAccessFunction (
28+ typeDecl->getDeclaredType ()->getCanonicalType ());
29+ std::string typeMetadataFuncName = typeMetadataFunc.mangleAsString ();
30+
2631 // Print out a forward declaration of the "hidden" _impl class.
2732 printer.printNamespace (cxx_synthesis::getCxxImplNamespaceName (),
2833 [&](raw_ostream &os) {
2934 os << " class " ;
3035 printCxxImplClassName (os, typeDecl);
3136 os << " ;\n " ;
37+ // Print out special functions, like functions that
38+ // access type metadata.
39+ printer.printCTypeMetadataTypeFunction (
40+ typeDecl, typeMetadataFuncName);
3241 });
3342
3443 std::string baseClassName;
@@ -84,6 +93,48 @@ void ClangClassTypePrinter::printClassTypeDecl(
8493 os << " (ptr); }\n " ;
8594 os << " };\n " ;
8695 });
96+
97+ // FIXME: avoid popping out of the module's namespace here.
98+ os << " } // end namespace \n\n " ;
99+ os << " namespace swift {\n " ;
100+
101+ os << " #pragma clang diagnostic push\n " ;
102+ os << " #pragma clang diagnostic ignored \" -Wc++17-extensions\"\n " ;
103+ os << " template<>\n " ;
104+ os << " static inline const constexpr bool isUsableInGenericContext<" ;
105+ printer.printBaseName (typeDecl->getModuleContext ());
106+ os << " ::" ;
107+ printer.printBaseName (typeDecl);
108+ os << " > = true;\n " ;
109+ os << " #pragma clang diagnostic pop\n " ;
110+
111+ os << " template<>\n " ;
112+ os << " inline void * _Nonnull getTypeMetadata<" ;
113+ printer.printBaseName (typeDecl->getModuleContext ());
114+ os << " ::" ;
115+ printer.printBaseName (typeDecl);
116+ os << " >() {\n " ;
117+ os << " return " ;
118+ printer.printBaseName (typeDecl->getModuleContext ());
119+ os << " ::" << cxx_synthesis::getCxxImplNamespaceName ()
120+ << " ::" << typeMetadataFuncName << " (0)._0;\n " ;
121+ os << " }\n " ;
122+ os << " namespace " << cxx_synthesis::getCxxImplNamespaceName () << " {\n " ;
123+ os << " template<>\n " ;
124+ os << " struct implClassFor<" ;
125+ printer.printBaseName (typeDecl->getModuleContext ());
126+ os << " ::" ;
127+ printer.printBaseName (typeDecl);
128+ os << " > { using type = " ;
129+ printer.printBaseName (typeDecl->getModuleContext ());
130+ os << " ::" << cxx_synthesis::getCxxImplNamespaceName () << " ::" ;
131+ printCxxImplClassName (os, typeDecl);
132+ os << " ; };\n " ;
133+ os << " } // namespace\n " ;
134+ os << " } // namespace swift\n " ;
135+ os << " \n namespace " ;
136+ printer.printBaseName (typeDecl->getModuleContext ());
137+ os << " {\n " ;
87138}
88139
89140void ClangClassTypePrinter::printClassTypeReturnScaffold (
0 commit comments