@@ -76,16 +76,18 @@ void printCTypeMetadataTypeFunction(raw_ostream &os,
7676void ClangValueTypePrinter::printValueTypeDecl (
7777 const NominalTypeDecl *typeDecl,
7878 llvm::function_ref<void (void )> bodyPrinter) {
79- auto typeSizeAlign =
80- interopContext.getIrABIDetails ().getTypeSizeAlignment (typeDecl);
81- if (!typeSizeAlign) {
82- // FIXME: handle non-fixed layout structs.
83- return ;
84- }
85- if (typeSizeAlign->size == 0 ) {
86- // FIXME: How to represent 0 sized structs?
87- return ;
79+ llvm::Optional<IRABIDetailsProvider::SizeAndAlignment> typeSizeAlign;
80+ if (!typeDecl->isResilient ()) {
81+
82+ typeSizeAlign =
83+ interopContext.getIrABIDetails ().getTypeSizeAlignment (typeDecl);
84+ assert (typeSizeAlign && " unknown layout for non-resilient type!" );
85+ if (typeSizeAlign->size == 0 ) {
86+ // FIXME: How to represent 0 sized structs?
87+ return ;
88+ }
8889 }
90+ bool isOpaqueLayout = !typeSizeAlign.hasValue ();
8991
9092 ClangSyntaxPrinter printer (os);
9193
@@ -138,6 +140,11 @@ void ClangValueTypePrinter::printValueTypeDecl(
138140 os << " auto *vwTable = " ;
139141 printer.printValueWitnessTableAccessFromTypeMetadata (" metadata" );
140142 os << " ;\n " ;
143+ if (isOpaqueLayout) {
144+ os << " _storage = " ;
145+ printer.printSwiftImplQualifier ();
146+ os << cxx_synthesis::getCxxOpaqueStorageClassName () << " (vwTable);\n " ;
147+ }
141148 os << " vwTable->initializeWithCopy(_getOpaquePointer(), const_cast<char "
142149 " *>(other._getOpaquePointer()), metadata._0);\n " ;
143150 os << " }\n " ;
@@ -156,23 +163,55 @@ void ClangValueTypePrinter::printValueTypeDecl(
156163 // Print out private default constructor.
157164 os << " inline " ;
158165 printer.printBaseName (typeDecl);
159- os << " () {}\n " ;
166+ if (isOpaqueLayout) {
167+ os << " (" ;
168+ printer.printSwiftImplQualifier ();
169+ os << " ValueWitnessTable * _Nonnull vwTable) : _storage(vwTable) {}\n " ;
170+ } else {
171+ os << " () {}\n " ;
172+ }
160173 // Print out '_make' function which returns an unitialized instance for
161174 // passing to Swift.
162175 os << " static inline " ;
163176 printer.printBaseName (typeDecl);
164- os << " _make() { return " ;
165- printer.printBaseName (typeDecl);
166- os << " (); }\n " ;
177+ os << " _make() {" ;
178+ if (isOpaqueLayout) {
179+ os << " \n " ;
180+ os << " auto metadata = " << cxx_synthesis::getCxxImplNamespaceName ()
181+ << " ::" ;
182+ printer.printSwiftTypeMetadataAccessFunctionCall (typeMetadataFuncName);
183+ os << " ;\n " ;
184+ os << " return " ;
185+ printer.printBaseName (typeDecl);
186+ os << " (" ;
187+ printer.printValueWitnessTableAccessFromTypeMetadata (" metadata" );
188+ os << " );\n }\n " ;
189+ } else {
190+ os << " return " ;
191+ printer.printBaseName (typeDecl);
192+ os << " (); }\n " ;
193+ }
167194 // Print out the private accessors to the underlying Swift value storage.
168195 os << " inline const char * _Nonnull _getOpaquePointer() const { return "
169- " _storage; }\n " ;
170- os << " inline char * _Nonnull _getOpaquePointer() { return _storage; }\n " ;
196+ " _storage" ;
197+ if (isOpaqueLayout)
198+ os << " .getOpaquePointer()" ;
199+ os << " ; }\n " ;
200+ os << " inline char * _Nonnull _getOpaquePointer() { return _storage" ;
201+ if (isOpaqueLayout)
202+ os << " .getOpaquePointer()" ;
203+ os << " ; }\n " ;
171204 os << " \n " ;
172205
173206 // Print out the storage for the value type.
174- os << " alignas(" << typeSizeAlign->alignment << " ) " ;
175- os << " char _storage[" << typeSizeAlign->size << " ];\n " ;
207+ os << " " ;
208+ if (isOpaqueLayout) {
209+ printer.printSwiftImplQualifier ();
210+ os << cxx_synthesis::getCxxOpaqueStorageClassName () << " _storage;\n " ;
211+ } else {
212+ os << " alignas(" << typeSizeAlign->alignment << " ) " ;
213+ os << " char _storage[" << typeSizeAlign->size << " ];\n " ;
214+ }
176215 // Wrap up the value type.
177216 os << " friend class " << cxx_synthesis::getCxxImplNamespaceName () << " ::" ;
178217 printCxxImplClassName (os, typeDecl);
@@ -209,7 +248,8 @@ void ClangValueTypePrinter::printValueTypeDecl(
209248 os << " };\n " ;
210249 });
211250
212- printCValueTypeStorageStruct (cPrologueOS, typeDecl, *typeSizeAlign);
251+ if (!isOpaqueLayout)
252+ printCValueTypeStorageStruct (cPrologueOS, typeDecl, *typeSizeAlign);
213253}
214254
215255// / Print the name of the C stub struct for passing/returning a value type
0 commit comments