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"
@@ -2472,6 +2476,53 @@ static void emitDynamicSelfMetadata(IRGenSILFunction &IGF) {
24722476 IGF.setDynamicSelfMetadata (selfTy, isExact, value, selfKind);
24732477}
24742478
2479+ // / C++ interop might refer to the type metadata in some scenarios.
2480+ // / This function covers those cases and makes sure metadata is emitted
2481+ // / for the foreign types.
2482+ static void noteUseOfMetadataByCXXInterop (IRGenerator &IRGen,
2483+ const SILFunction *f,
2484+ const TypeExpansionContext &context) {
2485+ auto type = f->getLoweredFunctionType ();
2486+
2487+ // Notes the use of foreign types in generic arguments for C++ interop.
2488+ auto processType = [&](CanType type) {
2489+ struct Walker : TypeWalker {
2490+ Walker (IRGenerator &IRGen) : IRGen(IRGen) {}
2491+
2492+ Action walkToTypePre (Type ty) override {
2493+ if (auto *BGT = ty->getAs <BoundGenericType>())
2494+ genericDepth++;
2495+ else if (auto *nominal = ty->getAs <NominalType>())
2496+ noteUseOfTypeMetadata (nominal->getDecl ());
2497+ return Action::Continue;
2498+ }
2499+
2500+ Action walkToTypePost (Type ty) override {
2501+ if (auto *BGT = ty->getAs <BoundGenericType>())
2502+ genericDepth--;
2503+
2504+ return Action::Continue;
2505+ }
2506+
2507+ void noteUseOfTypeMetadata (NominalTypeDecl *type) {
2508+ if (genericDepth == 0 )
2509+ return ;
2510+ if (!IRGen.hasLazyMetadata (type) || !type->hasClangNode ())
2511+ return ;
2512+ IRGen.noteUseOfTypeMetadata (type);
2513+ }
2514+ IRGenerator &IRGen;
2515+ int genericDepth = 0 ;
2516+ } walker{IRGen};
2517+ type.walk (walker);
2518+ };
2519+
2520+ for (const auto ¶m : type->getParameters ())
2521+ processType (param.getArgumentType (IRGen.SIL , type, context));
2522+ for (const auto &result : type->getResultsWithError ())
2523+ processType (result.getReturnValueType (IRGen.SIL , type, context));
2524+ }
2525+
24752526// / Emit the definition for the given SIL constant.
24762527void IRGenModule::emitSILFunction (SILFunction *f) {
24772528 if (f->isExternalDeclaration ())
@@ -2487,6 +2538,12 @@ void IRGenModule::emitSILFunction(SILFunction *f) {
24872538 f->isAvailableExternally ())
24882539 return ;
24892540
2541+ // Type metadata for foreign references is not yet supported on Windows. Bug #76168.
2542+ if (Context.LangOpts .EnableCXXInterop &&
2543+ f->getLinkage () == SILLinkage::Public &&
2544+ !Context.LangOpts .Target .isOSWindows ())
2545+ noteUseOfMetadataByCXXInterop (IRGen, f, TypeExpansionContext (*f));
2546+
24902547 PrettyStackTraceSILFunction stackTrace (" emitting IR" , f);
24912548 IRGenSILFunction (*this , f).emitSILFunction ();
24922549}
0 commit comments