@@ -152,7 +152,8 @@ void ClangValueTypePrinter::printValueTypeDecl(
152152 if (isOpaqueLayout) {
153153 os << " _storage = " ;
154154 printer.printSwiftImplQualifier ();
155- os << cxx_synthesis::getCxxOpaqueStorageClassName () << " (vwTable);\n " ;
155+ os << cxx_synthesis::getCxxOpaqueStorageClassName ()
156+ << " (vwTable->size, vwTable->getAlignment());\n " ;
156157 }
157158 os << " vwTable->initializeWithCopy(_getOpaquePointer(), const_cast<char "
158159 " *>(other._getOpaquePointer()), metadata._0);\n " ;
@@ -172,10 +173,12 @@ void ClangValueTypePrinter::printValueTypeDecl(
172173 // Print out private default constructor.
173174 os << " inline " ;
174175 printer.printBaseName (typeDecl);
176+ // FIXME: make noexcept.
175177 if (isOpaqueLayout) {
176178 os << " (" ;
177179 printer.printSwiftImplQualifier ();
178- os << " ValueWitnessTable * _Nonnull vwTable) : _storage(vwTable) {}\n " ;
180+ os << " ValueWitnessTable * _Nonnull vwTable) : _storage(vwTable->size, "
181+ " vwTable->getAlignment()) {}\n " ;
179182 } else {
180183 os << " () {}\n " ;
181184 }
@@ -281,6 +284,8 @@ void ClangValueTypePrinter::printValueTypeDecl(
281284
282285 if (!isOpaqueLayout)
283286 printCValueTypeStorageStruct (cPrologueOS, typeDecl, *typeSizeAlign);
287+
288+ printTypeGenericTraits (os, typeDecl, typeMetadataFuncName);
284289}
285290
286291// / Print the name of the C stub struct for passing/returning a value type
@@ -456,3 +461,68 @@ void ClangValueTypePrinter::printValueTypeDirectReturnScaffold(
456461 os << " );\n " ;
457462 os << " });\n " ;
458463}
464+
465+ void ClangValueTypePrinter::printTypeGenericTraits (
466+ raw_ostream &os, const NominalTypeDecl *typeDecl,
467+ StringRef typeMetadataFuncName) {
468+ ClangSyntaxPrinter printer (os);
469+ // FIXME: avoid popping out of the module's namespace here.
470+ os << " } // end namespace \n\n " ;
471+ os << " namespace swift {\n " ;
472+
473+ os << " #pragma clang diagnostic push\n " ;
474+ os << " #pragma clang diagnostic ignored \" -Wc++17-extensions\"\n " ;
475+ os << " template<>\n " ;
476+ os << " static inline const constexpr bool isUsableInGenericContext<" ;
477+ printer.printBaseName (typeDecl->getModuleContext ());
478+ os << " ::" ;
479+ printer.printBaseName (typeDecl);
480+ os << " > = true;\n " ;
481+ os << " template<>\n " ;
482+ os << " inline void * _Nonnull getTypeMetadata<" ;
483+ printer.printBaseName (typeDecl->getModuleContext ());
484+ os << " ::" ;
485+ printer.printBaseName (typeDecl);
486+ os << " >() {\n " ;
487+ os << " return " ;
488+ printer.printBaseName (typeDecl->getModuleContext ());
489+ os << " ::" << cxx_synthesis::getCxxImplNamespaceName ()
490+ << " ::" << typeMetadataFuncName << " (0)._0;\n " ;
491+ os << " }\n " ;
492+
493+ os << " namespace " << cxx_synthesis::getCxxImplNamespaceName () << " {\n " ;
494+
495+ if (!isa<ClassDecl>(typeDecl)) {
496+ os << " template<>\n " ;
497+ os << " static inline const constexpr bool isValueType<" ;
498+ printer.printBaseName (typeDecl->getModuleContext ());
499+ os << " ::" ;
500+ printer.printBaseName (typeDecl);
501+ os << " > = true;\n " ;
502+ if (typeDecl->isResilient ()) {
503+ os << " template<>\n " ;
504+ os << " static inline const constexpr bool isOpaqueLayout<" ;
505+ printer.printBaseName (typeDecl->getModuleContext ());
506+ os << " ::" ;
507+ printer.printBaseName (typeDecl);
508+ os << " > = true;\n " ;
509+ }
510+ }
511+
512+ os << " template<>\n " ;
513+ os << " struct implClassFor<" ;
514+ printer.printBaseName (typeDecl->getModuleContext ());
515+ os << " ::" ;
516+ printer.printBaseName (typeDecl);
517+ os << " > { using type = " ;
518+ printer.printBaseName (typeDecl->getModuleContext ());
519+ os << " ::" << cxx_synthesis::getCxxImplNamespaceName () << " ::" ;
520+ printCxxImplClassName (os, typeDecl);
521+ os << " ; };\n " ;
522+ os << " } // namespace\n " ;
523+ os << " #pragma clang diagnostic pop\n " ;
524+ os << " } // namespace swift\n " ;
525+ os << " \n namespace " ;
526+ printer.printBaseName (typeDecl->getModuleContext ());
527+ os << " {\n " ;
528+ }
0 commit comments