1818#include " GenKeyPath.h"
1919#include " swift/AST/ASTContext.h"
2020#include " swift/AST/ASTMangler.h"
21+ #include " swift/AST/Decl.h"
2122#include " swift/AST/DiagnosticsIRGen.h"
2223#include " swift/AST/ExtInfo.h"
2324#include " swift/AST/GenericEnvironment.h"
2627#include " swift/AST/Pattern.h"
2728#include " swift/AST/SemanticAttrs.h"
2829#include " swift/AST/SubstitutionMap.h"
30+ #include " swift/AST/Type.h"
31+ #include " swift/AST/TypeExpansionContext.h"
32+ #include " swift/AST/TypeVisitor.h"
2933#include " swift/AST/Types.h"
3034#include " swift/Basic/Assertions.h"
3135#include " swift/Basic/ExternalUnion.h"
@@ -2485,6 +2489,53 @@ static void emitDynamicSelfMetadata(IRGenSILFunction &IGF) {
24852489 IGF.setDynamicSelfMetadata (selfTy, isExact, value, selfKind);
24862490}
24872491
2492+ // / C++ interop might refer to the type metadata in some scenarios.
2493+ // / This function covers those cases and makes sure metadata is emitted
2494+ // / for the foreign types.
2495+ static void noteUseOfMetadataByCXXInterop (IRGenerator &IRGen,
2496+ const SILFunction *f,
2497+ const TypeExpansionContext &context) {
2498+ auto type = f->getLoweredFunctionType ();
2499+
2500+ // Notes the use of foreign types in generic arguments for C++ interop.
2501+ auto processType = [&](CanType type) {
2502+ struct Walker : TypeWalker {
2503+ Walker (IRGenerator &IRGen) : IRGen(IRGen) {}
2504+
2505+ Action walkToTypePre (Type ty) override {
2506+ if (auto *BGT = ty->getAs <BoundGenericType>())
2507+ genericDepth++;
2508+ else if (auto *nominal = ty->getAs <NominalType>())
2509+ noteUseOfTypeMetadata (nominal->getDecl ());
2510+ return Action::Continue;
2511+ }
2512+
2513+ Action walkToTypePost (Type ty) override {
2514+ if (auto *BGT = ty->getAs <BoundGenericType>())
2515+ genericDepth--;
2516+
2517+ return Action::Continue;
2518+ }
2519+
2520+ void noteUseOfTypeMetadata (NominalTypeDecl *type) {
2521+ if (genericDepth == 0 )
2522+ return ;
2523+ if (!IRGen.hasLazyMetadata (type) || !type->hasClangNode ())
2524+ return ;
2525+ IRGen.noteUseOfTypeMetadata (type);
2526+ }
2527+ IRGenerator &IRGen;
2528+ int genericDepth = 0 ;
2529+ } walker{IRGen};
2530+ type.walk (walker);
2531+ };
2532+
2533+ for (const auto ¶m : type->getParameters ())
2534+ processType (param.getArgumentType (IRGen.SIL , type, context));
2535+ for (const auto &result : type->getResultsWithError ())
2536+ processType (result.getReturnValueType (IRGen.SIL , type, context));
2537+ }
2538+
24882539// / Emit the definition for the given SIL constant.
24892540void IRGenModule::emitSILFunction (SILFunction *f) {
24902541 if (f->isExternalDeclaration ())
@@ -2496,6 +2547,12 @@ void IRGenModule::emitSILFunction(SILFunction *f) {
24962547 f->isAvailableExternally ())
24972548 return ;
24982549
2550+ // Type metadata for foreign references is not yet supported on Windows. Bug #76168.
2551+ if (Context.LangOpts .EnableCXXInterop &&
2552+ f->getLinkage () == SILLinkage::Public &&
2553+ !Context.LangOpts .Target .isOSWindows ())
2554+ noteUseOfMetadataByCXXInterop (IRGen, f, TypeExpansionContext (*f));
2555+
24992556 PrettyStackTraceSILFunction stackTrace (" emitting IR" , f);
25002557 IRGenSILFunction (*this , f).emitSILFunction ();
25012558}
0 commit comments