Skip to content

Commit 9cd004c

Browse files
authored
Merge pull request #62469 from hyp/eng/fix-CxxToSwiftToCxx
[interop][CxxToSwiftToCxx] fix the tests for unsupported class templa…
2 parents 599cd1f + 510b767 commit 9cd004c

8 files changed

+66
-55
lines changed

lib/PrintAsClang/ClangSyntaxPrinter.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ bool ClangSyntaxPrinter::printNominalTypeOutsideMemberDeclInnerStaticAssert(
9292
return false;
9393
}
9494

95-
void ClangSyntaxPrinter::printNominalClangTypeReference(
96-
const clang::Decl *typeDecl) {
95+
void ClangSyntaxPrinter::printClangTypeReference(const clang::Decl *typeDecl) {
9796
auto &clangCtx = typeDecl->getASTContext();
9897
clang::PrintingPolicy pp(clangCtx.getLangOpts());
9998
const auto *NS = clang::NestedNameSpecifier::getRequiredQualification(
@@ -118,7 +117,7 @@ void ClangSyntaxPrinter::printNominalClangTypeReference(
118117
void ClangSyntaxPrinter::printNominalTypeReference(
119118
const NominalTypeDecl *typeDecl, const ModuleDecl *moduleContext) {
120119
if (typeDecl->hasClangNode()) {
121-
printNominalClangTypeReference(typeDecl->getClangDecl());
120+
printClangTypeReference(typeDecl->getClangDecl());
122121
return;
123122
}
124123
printModuleNamespaceQualifiersIfNeeded(typeDecl->getModuleContext(),
@@ -266,7 +265,7 @@ void ClangSyntaxPrinter::printValueWitnessTableAccessSequenceFromTypeMetadata(
266265
}
267266

268267
void ClangSyntaxPrinter::printCTypeMetadataTypeFunction(
269-
const NominalTypeDecl *typeDecl, StringRef typeMetadataFuncName,
268+
const TypeDecl *typeDecl, StringRef typeMetadataFuncName,
270269
llvm::ArrayRef<GenericRequirement> genericRequirements) {
271270
// FIXME: Support generic requirements > 3.
272271
if (!genericRequirements.empty())

lib/PrintAsClang/ClangSyntaxPrinter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class ClangSyntaxPrinter {
104104
const ModuleDecl *moduleContext);
105105

106106
/// Print out the C++ record qualifier for the given C++ record.
107-
void printNominalClangTypeReference(const clang::Decl *typeDecl);
107+
void printClangTypeReference(const clang::Decl *typeDecl);
108108

109109
/// Print out the C++ class access qualifier for the given Swift type
110110
/// declaration.
@@ -170,7 +170,7 @@ class ClangSyntaxPrinter {
170170

171171
/// Print the metadata accessor function for the given type declaration.
172172
void printCTypeMetadataTypeFunction(
173-
const NominalTypeDecl *typeDecl, StringRef typeMetadataFuncName,
173+
const TypeDecl *typeDecl, StringRef typeMetadataFuncName,
174174
llvm::ArrayRef<GenericRequirement> genericRequirements);
175175

176176
/// Print the name of the generic type param type in C++.

lib/PrintAsClang/ModuleContentsWriter.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ class ModuleWriter {
126126
ModuleDecl &M;
127127

128128
llvm::DenseMap<const TypeDecl *, std::pair<EmissionState, bool>> seenTypes;
129-
llvm::DenseSet<const NominalTypeDecl *> seenClangTypes;
129+
llvm::DenseSet<const clang::Type *> seenClangTypes;
130130
std::vector<const Decl *> declsToWrite;
131131
DelayedMemberSet delayedMembers;
132132
PrimitiveTypeMapping typeMapping;
@@ -276,8 +276,13 @@ class ModuleWriter {
276276
});
277277
}
278278

279-
void emitReferencedClangTypeMetadata(const NominalTypeDecl *typeDecl) {
280-
auto it = seenClangTypes.insert(typeDecl);
279+
void emitReferencedClangTypeMetadata(const TypeDecl *typeDecl) {
280+
if (!isa<clang::TypeDecl>(typeDecl->getClangDecl()))
281+
return;
282+
// Get the underlying clang type from a type alias decl or record decl.
283+
clang::QualType clangType(
284+
cast<clang::TypeDecl>(typeDecl->getClangDecl())->getTypeForDecl(), 0);
285+
auto it = seenClangTypes.insert(clangType.getCanonicalType().getTypePtr());
281286
if (it.second)
282287
ClangValueTypePrinter::printClangTypeSwiftGenericTraits(os, typeDecl, &M);
283288
}
@@ -295,6 +300,9 @@ class ModuleWriter {
295300
forwardDeclareCxxValueTypeIfNeeded(NTD);
296301
else if (isa<StructDecl>(TD) && NTD->hasClangNode())
297302
emitReferencedClangTypeMetadata(NTD);
303+
} else if (auto TAD = dyn_cast<TypeAliasDecl>(TD)) {
304+
if (TAD->hasClangNode())
305+
emitReferencedClangTypeMetadata(TAD);
298306
}
299307
return;
300308
}

lib/PrintAsClang/PrintClangFunction.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class ClangTypeHandler {
112112
}
113113

114114
void printTypeName(raw_ostream &os) const {
115-
ClangSyntaxPrinter(os).printNominalClangTypeReference(typeDecl);
115+
ClangSyntaxPrinter(os).printClangTypeReference(typeDecl);
116116
}
117117

118118
static void
@@ -268,7 +268,7 @@ class CFunctionSignatureTypePrinter
268268
bool isInOutParam) {
269269
auto *cd = CT->getDecl();
270270
if (cd->hasClangNode()) {
271-
ClangSyntaxPrinter(os).printNominalClangTypeReference(cd->getClangDecl());
271+
ClangSyntaxPrinter(os).printClangTypeReference(cd->getClangDecl());
272272
os << " *"
273273
<< (!optionalKind || *optionalKind == OTK_None ? "_Nonnull"
274274
: "_Nullable");

lib/PrintAsClang/PrintClangValueType.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -477,14 +477,14 @@ void ClangValueTypePrinter::printValueTypeReturnScaffold(
477477
}
478478

479479
void ClangValueTypePrinter::printClangTypeSwiftGenericTraits(
480-
raw_ostream &os, const NominalTypeDecl *typeDecl,
480+
raw_ostream &os, const TypeDecl *typeDecl,
481481
const ModuleDecl *moduleContext) {
482482
assert(typeDecl->hasClangNode());
483483
// Do not reference unspecialized templates.
484484
if (isa<clang::ClassTemplateDecl>(typeDecl->getClangDecl()))
485485
return;
486486
auto typeMetadataFunc = irgen::LinkEntity::forTypeMetadataAccessFunction(
487-
typeDecl->getDeclaredType()->getCanonicalType());
487+
typeDecl->getDeclaredInterfaceType()->getCanonicalType());
488488
std::string typeMetadataFuncName = typeMetadataFunc.mangleAsString();
489489
printTypeGenericTraits(os, typeDecl, typeMetadataFuncName,
490490
/*typeMetadataFuncRequirements=*/{}, moduleContext);
@@ -516,10 +516,10 @@ void ClangValueTypePrinter::printTypePrecedingGenericTraits(
516516
}
517517

518518
void ClangValueTypePrinter::printTypeGenericTraits(
519-
raw_ostream &os, const NominalTypeDecl *typeDecl,
520-
StringRef typeMetadataFuncName,
519+
raw_ostream &os, const TypeDecl *typeDecl, StringRef typeMetadataFuncName,
521520
ArrayRef<GenericRequirement> typeMetadataFuncRequirements,
522521
const ModuleDecl *moduleContext) {
522+
auto *NTD = dyn_cast<NominalTypeDecl>(typeDecl);
523523
ClangSyntaxPrinter printer(os);
524524
// FIXME: avoid popping out of the module's namespace here.
525525
os << "} // end namespace \n\n";
@@ -540,15 +540,19 @@ void ClangValueTypePrinter::printTypeGenericTraits(
540540
// FIXME: share the code.
541541
os << "template<>\n";
542542
os << "static inline const constexpr bool isUsableInGenericContext<";
543-
printer.printNominalTypeReference(typeDecl,
544-
/*moduleContext=*/nullptr);
543+
printer.printClangTypeReference(typeDecl->getClangDecl());
545544
os << "> = true;\n";
546545
}
547-
if (printer.printNominalTypeOutsideMemberDeclTemplateSpecifiers(typeDecl))
546+
if (!NTD || printer.printNominalTypeOutsideMemberDeclTemplateSpecifiers(NTD))
548547
os << "template<>\n";
549548
os << "struct TypeMetadataTrait<";
550-
printer.printNominalTypeReference(typeDecl,
551-
/*moduleContext=*/nullptr);
549+
if (typeDecl->hasClangNode()) {
550+
printer.printClangTypeReference(typeDecl->getClangDecl());
551+
} else {
552+
assert(NTD);
553+
printer.printNominalTypeReference(NTD,
554+
/*moduleContext=*/nullptr);
555+
}
552556
os << "> {\n";
553557
os << " static inline void * _Nonnull getTypeMetadata() {\n";
554558
os << " return ";
@@ -567,7 +571,7 @@ void ClangValueTypePrinter::printTypeGenericTraits(
567571
if (typeDecl->hasClangNode()) {
568572
os << "template<>\n";
569573
os << "static inline const constexpr bool isSwiftBridgedCxxRecord<";
570-
printer.printNominalClangTypeReference(typeDecl->getClangDecl());
574+
printer.printClangTypeReference(typeDecl->getClangDecl());
571575
os << "> = true;\n";
572576
}
573577

@@ -580,7 +584,7 @@ void ClangValueTypePrinter::printTypeGenericTraits(
580584
os << "::";
581585
printer.printBaseName(typeDecl);
582586
os << "> = true;\n";
583-
if (typeDecl->isResilient()) {
587+
if (NTD && NTD->isResilient()) {
584588
os << "template<>\n";
585589
os << "static inline const constexpr bool isOpaqueLayout<";
586590
printer.printBaseName(typeDecl->getModuleContext());
@@ -592,6 +596,7 @@ void ClangValueTypePrinter::printTypeGenericTraits(
592596

593597
// FIXME: generic support.
594598
if (!typeDecl->hasClangNode() && typeMetadataFuncRequirements.empty()) {
599+
assert(NTD);
595600
os << "template<>\n";
596601
os << "struct implClassFor<";
597602
printer.printBaseName(typeDecl->getModuleContext());
@@ -600,7 +605,7 @@ void ClangValueTypePrinter::printTypeGenericTraits(
600605
os << "> { using type = ";
601606
printer.printBaseName(typeDecl->getModuleContext());
602607
os << "::" << cxx_synthesis::getCxxImplNamespaceName() << "::";
603-
printCxxImplClassName(os, typeDecl);
608+
printCxxImplClassName(os, NTD);
604609
os << "; };\n";
605610
}
606611
os << "} // namespace\n";

lib/PrintAsClang/PrintClangValueType.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,7 @@ class ClangValueTypePrinter {
9191
StringRef vwTableVarName = "vwTable");
9292

9393
static void printTypeGenericTraits(
94-
raw_ostream &os, const NominalTypeDecl *typeDecl,
95-
StringRef typeMetadataFuncName,
94+
raw_ostream &os, const TypeDecl *typeDecl, StringRef typeMetadataFuncName,
9695
ArrayRef<GenericRequirement> typeMetadataFuncRequirements,
9796
const ModuleDecl *moduleContext);
9897

@@ -105,7 +104,7 @@ class ClangValueTypePrinter {
105104
/// Print out the type traits that allow a C++ type be used a Swift generic
106105
/// context.
107106
static void printClangTypeSwiftGenericTraits(raw_ostream &os,
108-
const NominalTypeDecl *typeDecl,
107+
const TypeDecl *typeDecl,
109108
const ModuleDecl *moduleContext);
110109

111110
private:

test/Interop/CxxToSwiftToCxx/bridge-cxx-struct-back-to-cxx-execution.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// rdar://101431096
2-
// XFAIL: *
3-
41
// RUN: %empty-directory(%t)
52
// RUN: split-file %s %t
63

@@ -18,7 +15,7 @@
1815

1916
//--- header.h
2017

21-
extern "C" void puts(const char *);
18+
#include <stdio.h>
2219

2320
struct Trivial {
2421
int x, y;
@@ -44,6 +41,8 @@ struct NonTrivialTemplate {
4441
}
4542
};
4643

44+
using NonTrivialTemplateTrivial = NonTrivialTemplate<Trivial>;
45+
4746
//--- module.modulemap
4847
module CxxTest {
4948
header "header.h"
@@ -53,19 +52,19 @@ module CxxTest {
5352
//--- use-cxx-types.swift
5453
import CxxTest
5554

56-
public func retNonTrivial(y: CInt) -> NonTrivialTemplate<Trivial> {
57-
return NonTrivialTemplate<Trivial>(Trivial(42, y))
55+
public func retNonTrivial(y: CInt) -> NonTrivialTemplateTrivial {
56+
return NonTrivialTemplateTrivial(Trivial(42, y))
5857
}
5958

60-
public func takeNonTrivial(_ x: NonTrivialTemplate<Trivial>) {
59+
public func takeNonTrivial(_ x: NonTrivialTemplateTrivial) {
6160
print(x)
6261
}
6362

64-
public func passThroughNonTrivial(_ x: NonTrivialTemplate<Trivial>) -> NonTrivialTemplate<Trivial>{
63+
public func passThroughNonTrivial(_ x: NonTrivialTemplateTrivial) -> NonTrivialTemplateTrivial {
6564
return x
6665
}
6766

68-
public func inoutNonTrivial(_ x: inout NonTrivialTemplate<Trivial>) {
67+
public func inoutNonTrivial(_ x: inout NonTrivialTemplateTrivial) {
6968
x.x.y *= 2
7069
}
7170

@@ -93,8 +92,8 @@ public func retPassThroughGeneric<T>(_ x: T) -> T {
9392
return x
9493
}
9594

96-
public func retArrayNonTrivial(_ x: CInt) -> [NonTrivialTemplate<Trivial>] {
97-
return [NonTrivialTemplate<Trivial>(Trivial(x, -x))]
95+
public func retArrayNonTrivial(_ x: CInt) -> [NonTrivialTemplateTrivial] {
96+
return [NonTrivialTemplateTrivial(Trivial(x, -x))]
9897
}
9998

10099
//--- use-swift-cxx-types.cpp

test/Interop/CxxToSwiftToCxx/bridge-cxx-struct-back-to-cxx.swift

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// rdar://101431096
2-
// XFAIL: *
3-
41
// RUN: %empty-directory(%t)
52
// RUN: split-file %s %t
63

@@ -70,6 +67,10 @@ namespace ns {
7067
}
7168

7269
using ImmortalCInt = ImmortalTemplate<int>;
70+
71+
using NonTrivialTemplateInt = NonTrivialTemplate<int>;
72+
73+
using NonTrivialTemplateTrivial = NonTrivialTemplate<TrivialinNS>;
7374
}
7475

7576
//--- module.modulemap
@@ -92,13 +93,13 @@ public func retImmortalTemplate() -> ns.ImmortalCInt {
9293
}
9394

9495
@_expose(Cxx)
95-
public func retNonTrivial() -> ns.NonTrivialTemplate<CInt> {
96-
return ns.NonTrivialTemplate<CInt>()
96+
public func retNonTrivial() -> ns.NonTrivialTemplateInt {
97+
return ns.NonTrivialTemplateInt()
9798
}
9899

99100
@_expose(Cxx)
100-
public func retNonTrivial2() -> ns.NonTrivialTemplate<ns.TrivialinNS> {
101-
return ns.NonTrivialTemplate<ns.TrivialinNS>()
101+
public func retNonTrivial2() -> ns.NonTrivialTemplateTrivial {
102+
return ns.NonTrivialTemplateTrivial()
102103
}
103104

104105
@_expose(Cxx)
@@ -125,7 +126,7 @@ public func takeImmortalTemplate(_ x: ns.ImmortalCInt) {
125126
}
126127

127128
@_expose(Cxx)
128-
public func takeNonTrivial2(_ x: ns.NonTrivialTemplate<ns.TrivialinNS>) {
129+
public func takeNonTrivial2(_ x: ns.NonTrivialTemplateTrivial) {
129130
}
130131

131132
@_expose(Cxx)
@@ -161,7 +162,7 @@ public func takeTrivialInout(_ x: inout Trivial) {
161162
// CHECK-NEXT: namespace swift {
162163
// CHECK-NEXT: namespace _impl {
163164
// CHECK-EMPTY:
164-
// CHECK-NEXT: // Type metadata accessor for __CxxTemplateInstN2ns18NonTrivialTemplateIiEE
165+
// CHECK-NEXT: // Type metadata accessor for NonTrivialTemplateInt
165166
// CHECK-NEXT: SWIFT_EXTERN swift::_impl::MetadataResponseTy $sSo2nsO033__CxxTemplateInstN2ns18NonTrivialC4IiEEVMa(swift::_impl::MetadataRequestTy) SWIFT_NOEXCEPT SWIFT_CALL;
166167
// CHECK-EMPTY:
167168
// CHECK-EMPTY:
@@ -170,21 +171,21 @@ public func takeTrivialInout(_ x: inout Trivial) {
170171
// CHECK-NEXT: #pragma clang diagnostic push
171172
// CHECK-NEXT: #pragma clang diagnostic ignored "-Wc++17-extensions"
172173
// CHECK-NEXT: template<>
173-
// CHECK-NEXT: static inline const constexpr bool isUsableInGenericContext<ns::NonTrivialTemplate<int>> = true;
174+
// CHECK-NEXT: static inline const constexpr bool isUsableInGenericContext<ns::NonTrivialTemplateInt> = true;
174175
// CHECK-NEXT: template<>
175-
// CHECK-NEXT: struct TypeMetadataTrait<ns::NonTrivialTemplate<int>> {
176+
// CHECK-NEXT: struct TypeMetadataTrait<ns::NonTrivialTemplateInt> {
176177
// CHECK-NEXT: static inline void * _Nonnull getTypeMetadata() {
177178
// CHECK-NEXT: return _impl::$sSo2nsO033__CxxTemplateInstN2ns18NonTrivialC4IiEEVMa(0)._0;
178179
// CHECK-NEXT: }
179180
// CHECK-NEXT: };
180181
// CHECK-NEXT: namespace _impl{
181182
// CHECK-NEXT: template<>
182-
// CHECK-NEXT: static inline const constexpr bool isSwiftBridgedCxxRecord<ns::NonTrivialTemplate<int>> = true;
183+
// CHECK-NEXT: static inline const constexpr bool isSwiftBridgedCxxRecord<ns::NonTrivialTemplateInt> = true;
183184
// CHECK-NEXT: } // namespace
184185
// CHECK-NEXT: #pragma clang diagnostic pop
185186
// CHECK-NEXT: } // namespace swift
186187
// CHECK-EMPTY:
187-
// CHECK-NEXT: namespace UseCxxTy {
188+
// CHECK-NEXT: namespace UseCxxTy __attribute__((swift_private)) {
188189

189190
// CHECK: inline ns::NonTrivialTemplate<int> retNonTrivial() noexcept SWIFT_WARN_UNUSED_RESULT {
190191
// CHECK-NEXT: alignas(alignof(ns::NonTrivialTemplate<int>)) char storage[sizeof(ns::NonTrivialTemplate<int>)];
@@ -200,7 +201,7 @@ public func takeTrivialInout(_ x: inout Trivial) {
200201
// CHECK-NEXT: namespace swift {
201202
// CHECK-NEXT: namespace _impl {
202203
// CHECK-EMPTY:
203-
// CHECK-NEXT: // Type metadata accessor for __CxxTemplateInstN2ns18NonTrivialTemplateINS_11TrivialinNSEEE
204+
// CHECK-NEXT: // Type metadata accessor for NonTrivialTemplateTrivial
204205
// CHECK-NEXT: SWIFT_EXTERN swift::_impl::MetadataResponseTy $sSo2nsO033__CxxTemplateInstN2ns18NonTrivialC20INS_11TrivialinNSEEEVMa(swift::_impl::MetadataRequestTy) SWIFT_NOEXCEPT SWIFT_CALL;
205206
// CHECK-EMPTY:
206207
// CHECK-EMPTY:
@@ -209,21 +210,21 @@ public func takeTrivialInout(_ x: inout Trivial) {
209210
// CHECK-NEXT: #pragma clang diagnostic push
210211
// CHECK-NEXT: #pragma clang diagnostic ignored "-Wc++17-extensions"
211212
// CHECK-NEXT: template<>
212-
// CHECK-NEXT: static inline const constexpr bool isUsableInGenericContext<ns::NonTrivialTemplate<ns::TrivialinNS>> = true;
213+
// CHECK-NEXT: static inline const constexpr bool isUsableInGenericContext<ns::NonTrivialTemplateTrivial> = true;
213214
// CHECK-NEXT: template<>
214-
// CHECK-NEXT: struct TypeMetadataTrait<ns::NonTrivialTemplate<ns::TrivialinNS>> {
215+
// CHECK-NEXT: struct TypeMetadataTrait<ns::NonTrivialTemplateTrivial> {
215216
// CHECK-NEXT: static inline void * _Nonnull getTypeMetadata() {
216217
// CHECK-NEXT: return _impl::$sSo2nsO033__CxxTemplateInstN2ns18NonTrivialC20INS_11TrivialinNSEEEVMa(0)._0;
217218
// CHECK-NEXT: }
218219
// CHECK-NEXT: };
219220
// CHECK-NEXT: namespace _impl{
220221
// CHECK-NEXT: template<>
221-
// CHECK-NEXT: static inline const constexpr bool isSwiftBridgedCxxRecord<ns::NonTrivialTemplate<ns::TrivialinNS>> = true;
222+
// CHECK-NEXT: static inline const constexpr bool isSwiftBridgedCxxRecord<ns::NonTrivialTemplateTrivial> = true;
222223
// CHECK-NEXT: } // namespace
223224
// CHECK-NEXT: #pragma clang diagnostic pop
224225
// CHECK-NEXT: } // namespace swift
225226
// CHECK-EMPTY:
226-
// CHECK-NEXT: namespace UseCxxTy {
227+
// CHECK-NEXT: namespace UseCxxTy __attribute__((swift_private)) {
227228
// CHECK-EMPTY:
228229
// CHECK-NEXT: inline ns::NonTrivialTemplate<ns::TrivialinNS> retNonTrivial2() noexcept SWIFT_WARN_UNUSED_RESULT {
229230
// CHECK-NEXT: alignas(alignof(ns::NonTrivialTemplate<ns::TrivialinNS>)) char storage[sizeof(ns::NonTrivialTemplate<ns::TrivialinNS>)];

0 commit comments

Comments
 (0)