Skip to content

Commit bbbfc62

Browse files
committed
ClangImporter: Fixes for non-copyable generics
1 parent 9e24746 commit bbbfc62

File tree

5 files changed

+44
-21
lines changed

5 files changed

+44
-21
lines changed

lib/AST/SwiftNameTranslation.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ swift::cxx_translation::getDeclRepresentation(const ValueDecl *VD) {
215215
return {Unsupported, UnrepresentableObjC};
216216
if (getActorIsolation(const_cast<ValueDecl *>(VD)).isActorIsolated())
217217
return {Unsupported, UnrepresentableIsolatedInActor};
218-
llvm::Optional<CanGenericSignature> genericSignature;
218+
GenericSignature genericSignature;
219219
// Don't expose @_alwaysEmitIntoClient decls as they require their
220220
// bodies to be emitted into client.
221221
if (VD->getAttrs().hasAttribute<AlwaysEmitIntoClientAttr>())
@@ -228,7 +228,7 @@ swift::cxx_translation::getDeclRepresentation(const ValueDecl *VD) {
228228
Feature::GenerateBindingsForThrowingFunctionsInCXX))
229229
return {Unsupported, UnrepresentableThrows};
230230
if (AFD->isGeneric())
231-
genericSignature = AFD->getGenericSignature().getCanonicalSignature();
231+
genericSignature = AFD->getGenericSignature();
232232
}
233233
if (const auto *typeDecl = dyn_cast<NominalTypeDecl>(VD)) {
234234
if (isa<ProtocolDecl>(typeDecl))
@@ -239,8 +239,7 @@ swift::cxx_translation::getDeclRepresentation(const ValueDecl *VD) {
239239
if (typeDecl->isGeneric()) {
240240
if (isa<ClassDecl>(VD))
241241
return {Unsupported, UnrepresentableGeneric};
242-
genericSignature =
243-
typeDecl->getGenericSignature().getCanonicalSignature();
242+
genericSignature = typeDecl->getGenericSignature();
244243
}
245244
// Nested types are not yet supported.
246245
if (!typeDecl->hasClangNode() &&
@@ -280,9 +279,24 @@ swift::cxx_translation::getDeclRepresentation(const ValueDecl *VD) {
280279
}
281280
}
282281
}
282+
283283
// Generic requirements are not yet supported in C++.
284-
if (genericSignature && !genericSignature->getRequirements().empty())
285-
return {Unsupported, UnrepresentableGenericRequirements};
284+
if (genericSignature) {
285+
286+
// FIXME: We're using getRequirementsWithInverses() here as a shortcut for
287+
// checking for "no requirements except the implied Copyable ones".
288+
//
289+
// Eventually you don't want to call getRequirementsWithInverses() at all;
290+
// instead, the code here should walk the desugared requirements of the
291+
// signature directly and handle everything.
292+
SmallVector<Requirement, 2> reqs;
293+
SmallVector<InverseRequirement, 2> inverseReqs;
294+
genericSignature->getRequirementsWithInverses(reqs, inverseReqs);
295+
assert(inverseReqs.empty() && "Non-copyable generics not supported here!");
296+
if (!reqs.empty())
297+
return {Unsupported, UnrepresentableGenericRequirements};
298+
}
299+
286300
return {Representable, llvm::None};
287301
}
288302

lib/ClangImporter/ClangImporter.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4742,7 +4742,9 @@ TinyPtrVector<ValueDecl *> CXXNamespaceMemberLookup::evaluate(
47424742

47434743
// Just create a specialized function decl for "__swift_interopStaticCast"
47444744
// using the types base and derived.
4745+
static
47454746
DeclRefExpr *getInteropStaticCastDeclRefExpr(ASTContext &ctx,
4747+
ModuleDecl *swiftModule,
47464748
const clang::Module *owningModule,
47474749
Type base, Type derived) {
47484750
if (base->isForeignReferenceType() && derived->isForeignReferenceType()) {
@@ -4767,7 +4769,7 @@ DeclRefExpr *getInteropStaticCastDeclRefExpr(ASTContext &ctx,
47674769
// this yet because it can't infer the "To" type.
47684770
auto subst =
47694771
SubstitutionMap::get(staticCastFn->getGenericSignature(), {derived, base},
4770-
ArrayRef<ProtocolConformanceRef>());
4772+
LookUpConformanceInModule(swiftModule));
47714773
auto functionTemplate = const_cast<clang::FunctionTemplateDecl *>(
47724774
cast<clang::FunctionTemplateDecl>(staticCastFn->getClangDecl()));
47734775
auto spec = ctx.getClangModuleLoader()->instantiateCXXFunctionTemplate(
@@ -4789,6 +4791,7 @@ DeclRefExpr *getInteropStaticCastDeclRefExpr(ASTContext &ctx,
47894791
// %2 = __swift_interopStaticCast<UnsafeMutablePointer<Base>?>(%1)
47904792
// %3 = %2!
47914793
// return %3.pointee
4794+
static
47924795
MemberRefExpr *getSelfInteropStaticCast(FuncDecl *funcDecl,
47934796
NominalTypeDecl *baseStruct,
47944797
NominalTypeDecl *derivedStruct) {
@@ -4840,7 +4843,7 @@ MemberRefExpr *getSelfInteropStaticCast(FuncDecl *funcDecl,
48404843
selfPointer->setType(derivedPtrType);
48414844

48424845
auto staticCastRefExpr = getInteropStaticCastDeclRefExpr(
4843-
ctx, baseStruct->getClangDecl()->getOwningModule(),
4846+
ctx, module, baseStruct->getClangDecl()->getOwningModule(),
48444847
baseStruct->getSelfInterfaceType()->wrapInPointer(
48454848
PTK_UnsafeMutablePointer),
48464849
derivedStruct->getSelfInterfaceType()->wrapInPointer(

lib/PrintAsClang/ClangSyntaxPrinter.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ void ClangSyntaxPrinter::printGenericTypeParamTypeName(
312312
}
313313

314314
void ClangSyntaxPrinter::printGenericSignature(
315-
const CanGenericSignature &signature) {
315+
GenericSignature signature) {
316316
os << "template<";
317317
llvm::interleaveComma(signature.getInnermostGenericParams(), os,
318318
[&](const GenericTypeParamType *genericParamType) {
@@ -334,7 +334,7 @@ void ClangSyntaxPrinter::printGenericSignature(
334334
}
335335

336336
void ClangSyntaxPrinter::printGenericSignatureInnerStaticAsserts(
337-
const CanGenericSignature &signature) {
337+
GenericSignature signature) {
338338
os << "#ifndef __cpp_concepts\n";
339339
llvm::interleave(
340340
signature.getInnermostGenericParams(), os,
@@ -348,7 +348,7 @@ void ClangSyntaxPrinter::printGenericSignatureInnerStaticAsserts(
348348
}
349349

350350
void ClangSyntaxPrinter::printGenericSignatureParams(
351-
const CanGenericSignature &signature) {
351+
GenericSignature signature) {
352352
os << '<';
353353
llvm::interleaveComma(signature.getInnermostGenericParams(), os,
354354
[&](const GenericTypeParamType *genericParamType) {

lib/PrintAsClang/ClangSyntaxPrinter.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,16 +183,16 @@ class ClangSyntaxPrinter {
183183

184184
/// Print the Swift generic signature as C++ template declaration alongside
185185
/// its requirements.
186-
void printGenericSignature(const CanGenericSignature &signature);
186+
void printGenericSignature(GenericSignature signature);
187187

188188
/// Print the `static_assert` statements used for legacy type-checking for
189189
/// generics in C++14/C++17 mode.
190190
void
191-
printGenericSignatureInnerStaticAsserts(const CanGenericSignature &signature);
191+
printGenericSignatureInnerStaticAsserts(GenericSignature signature);
192192

193193
/// Print the C++ template parameters that should be passed for a given
194194
/// generic signature.
195-
void printGenericSignatureParams(const CanGenericSignature &signature);
195+
void printGenericSignatureParams(GenericSignature signature);
196196

197197
/// Print the call to the C++ type traits that computes the underlying type /
198198
/// witness table pointer value that are passed to Swift for the given generic

lib/PrintAsClang/PrintClangValueType.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -180,21 +180,27 @@ void ClangValueTypePrinter::printValueTypeDecl(
180180
DeclAndTypePrinter &declAndTypePrinter) {
181181
// FIXME: Add support for generic structs.
182182
llvm::Optional<IRABIDetailsProvider::SizeAndAlignment> typeSizeAlign;
183-
llvm::Optional<CanGenericSignature> genericSignature;
183+
GenericSignature genericSignature;
184184
auto printGenericSignature = [&](raw_ostream &os) {
185185
if (!genericSignature)
186186
return;
187-
ClangSyntaxPrinter(os).printGenericSignature(*genericSignature);
187+
ClangSyntaxPrinter(os).printGenericSignature(genericSignature);
188188
};
189189
auto printGenericParamRefs = [&](raw_ostream &os) {
190190
if (!genericSignature)
191191
return;
192-
ClangSyntaxPrinter(os).printGenericSignatureParams(*genericSignature);
192+
ClangSyntaxPrinter(os).printGenericSignatureParams(genericSignature);
193193
};
194194
if (typeDecl->isGeneric()) {
195-
genericSignature = typeDecl->getGenericSignature().getCanonicalSignature();
195+
genericSignature = typeDecl->getGenericSignature();
196+
196197
// FIXME: Support generic requirements.
197-
assert(genericSignature->getRequirements().empty());
198+
SmallVector<Requirement, 2> reqs;
199+
SmallVector<InverseRequirement, 2> inverseReqs;
200+
genericSignature->getRequirementsWithInverses(reqs, inverseReqs);
201+
assert(inverseReqs.empty() && "Non-copyable generics not supported here!");
202+
assert(reqs.empty());
203+
198204
// FIXME: Can we make some better layout than opaque layout for generic
199205
// types.
200206
} else if (!typeDecl->isResilient()) {
@@ -275,7 +281,7 @@ void ClangValueTypePrinter::printValueTypeDecl(
275281
os << "public:\n";
276282
if (genericSignature)
277283
ClangSyntaxPrinter(os).printGenericSignatureInnerStaticAsserts(
278-
*genericSignature);
284+
genericSignature);
279285

280286
// Print out the destructor.
281287
os << " ";
@@ -457,7 +463,7 @@ void ClangValueTypePrinter::printValueTypeDecl(
457463
os << "public:\n";
458464
if (genericSignature)
459465
ClangSyntaxPrinter(os).printGenericSignatureInnerStaticAsserts(
460-
*genericSignature);
466+
genericSignature);
461467

462468
os << " static ";
463469
ClangSyntaxPrinter(os).printInlineForThunk();

0 commit comments

Comments
 (0)