18
18
#include " GenKeyPath.h"
19
19
#include " swift/AST/ASTContext.h"
20
20
#include " swift/AST/ASTMangler.h"
21
+ #include " swift/AST/Decl.h"
21
22
#include " swift/AST/DiagnosticsIRGen.h"
22
23
#include " swift/AST/ExtInfo.h"
23
24
#include " swift/AST/GenericEnvironment.h"
26
27
#include " swift/AST/Pattern.h"
27
28
#include " swift/AST/SemanticAttrs.h"
28
29
#include " swift/AST/SubstitutionMap.h"
30
+ #include " swift/AST/Type.h"
31
+ #include " swift/AST/TypeExpansionContext.h"
32
+ #include " swift/AST/TypeVisitor.h"
29
33
#include " swift/AST/Types.h"
30
34
#include " swift/Basic/Assertions.h"
31
35
#include " swift/Basic/ExternalUnion.h"
@@ -2472,6 +2476,76 @@ static void emitDynamicSelfMetadata(IRGenSILFunction &IGF) {
2472
2476
IGF.setDynamicSelfMetadata (selfTy, isExact, value, selfKind);
2473
2477
}
2474
2478
2479
+ namespace {
2480
+ // Notes the use of foreign types in generic arguments for C++ interop.
2481
+ class NoteUseOfForeignTypeMetadata
2482
+ : public TypeVisitor<NoteUseOfForeignTypeMetadata, void , bool > {
2483
+ public:
2484
+ NoteUseOfForeignTypeMetadata (IRGenerator &IRGen) : IRGen(IRGen) {}
2485
+
2486
+ void visitType (TypeBase *, bool ) {}
2487
+
2488
+ void visitTupleType (TupleType *TT, bool isInGenericArgument) {
2489
+ for (auto type : TT->getElementTypes ())
2490
+ TypeVisitor::visit (type, isInGenericArgument);
2491
+ }
2492
+
2493
+ void visitSugarType (SugarType *sugarTy, bool isInGenericArgument) {
2494
+ TypeVisitor::visit (sugarTy->getSinglyDesugaredType (), isInGenericArgument);
2495
+ }
2496
+
2497
+ void visitClassType (ClassType *CT, bool isInGenericArgument) {
2498
+ noteUseOfTypeMetadata (CT->getDecl (), isInGenericArgument);
2499
+ }
2500
+
2501
+ void visitEnumType (EnumType *ET, bool isInGenericArgument) {
2502
+ noteUseOfTypeMetadata (ET->getDecl (), isInGenericArgument);
2503
+ }
2504
+
2505
+ void visitStructType (StructType *ST, bool isInGenericArgument) {
2506
+ noteUseOfTypeMetadata (ST->getDecl (), isInGenericArgument);
2507
+ }
2508
+
2509
+ void visitBoundGenericType (BoundGenericType *BGT, bool isInGenericArgument) {
2510
+ for (auto type : BGT->getGenericArgs ())
2511
+ TypeVisitor::visit (type, true );
2512
+ }
2513
+
2514
+ void visitDynamicSelfType (DynamicSelfType *ds, bool isInGenericArgument) {
2515
+ TypeVisitor::visit (ds->getSelfType (), isInGenericArgument);
2516
+ }
2517
+
2518
+ private:
2519
+ void noteUseOfTypeMetadata (NominalTypeDecl *type, bool isInGenericArgument) {
2520
+ if (!isInGenericArgument)
2521
+ return ;
2522
+ if (!IRGen.hasLazyMetadata (type) || !type->hasClangNode ())
2523
+ return ;
2524
+ IRGen.noteUseOfTypeMetadata (type);
2525
+ }
2526
+ IRGenerator &IRGen;
2527
+ };
2528
+ } // namespace
2529
+
2530
+ // / C++ interop might refer to the type metadat in some scenarios.
2531
+ // / This function covers those cases and makes sure metadata is emitted
2532
+ // / for the foreing types.
2533
+ static void noteUseOfMetadataByCXXInterop (IRGenerator &IRGen,
2534
+ const SILFunction *f,
2535
+ const TypeExpansionContext &context) {
2536
+ auto type = f->getLoweredFunctionType ();
2537
+
2538
+ auto processType = [&](CanType type) {
2539
+ NoteUseOfForeignTypeMetadata visitor (IRGen);
2540
+ visitor.visit (type, false );
2541
+ };
2542
+
2543
+ for (const auto ¶m : type->getParameters ())
2544
+ processType (param.getArgumentType (IRGen.SIL , type, context));
2545
+ for (const auto &result : type->getResultsWithError ())
2546
+ processType (result.getReturnValueType (IRGen.SIL , type, context));
2547
+ }
2548
+
2475
2549
// / Emit the definition for the given SIL constant.
2476
2550
void IRGenModule::emitSILFunction (SILFunction *f) {
2477
2551
if (f->isExternalDeclaration ())
@@ -2487,6 +2561,10 @@ void IRGenModule::emitSILFunction(SILFunction *f) {
2487
2561
f->isAvailableExternally ())
2488
2562
return ;
2489
2563
2564
+ if (Context.LangOpts .EnableCXXInterop &&
2565
+ f->getLinkage () == SILLinkage::Public)
2566
+ noteUseOfMetadataByCXXInterop (IRGen, f, TypeExpansionContext (*f));
2567
+
2490
2568
PrettyStackTraceSILFunction stackTrace (" emitting IR" , f);
2491
2569
IRGenSILFunction (*this , f).emitSILFunction ();
2492
2570
}
0 commit comments