mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #76011 from swiftlang/gaborh/emit-more-metadata
[cxx-interop] Emit type metadata for foreign types more often
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#include "GenKeyPath.h"
|
||||
#include "swift/AST/ASTContext.h"
|
||||
#include "swift/AST/ASTMangler.h"
|
||||
#include "swift/AST/Decl.h"
|
||||
#include "swift/AST/DiagnosticsIRGen.h"
|
||||
#include "swift/AST/ExtInfo.h"
|
||||
#include "swift/AST/GenericEnvironment.h"
|
||||
@@ -26,6 +27,9 @@
|
||||
#include "swift/AST/Pattern.h"
|
||||
#include "swift/AST/SemanticAttrs.h"
|
||||
#include "swift/AST/SubstitutionMap.h"
|
||||
#include "swift/AST/Type.h"
|
||||
#include "swift/AST/TypeExpansionContext.h"
|
||||
#include "swift/AST/TypeVisitor.h"
|
||||
#include "swift/AST/Types.h"
|
||||
#include "swift/Basic/Assertions.h"
|
||||
#include "swift/Basic/ExternalUnion.h"
|
||||
@@ -2485,6 +2489,53 @@ static void emitDynamicSelfMetadata(IRGenSILFunction &IGF) {
|
||||
IGF.setDynamicSelfMetadata(selfTy, isExact, value, selfKind);
|
||||
}
|
||||
|
||||
/// C++ interop might refer to the type metadata in some scenarios.
|
||||
/// This function covers those cases and makes sure metadata is emitted
|
||||
/// for the foreign types.
|
||||
static void noteUseOfMetadataByCXXInterop(IRGenerator &IRGen,
|
||||
const SILFunction *f,
|
||||
const TypeExpansionContext &context) {
|
||||
auto type = f->getLoweredFunctionType();
|
||||
|
||||
// Notes the use of foreign types in generic arguments for C++ interop.
|
||||
auto processType = [&](CanType type) {
|
||||
struct Walker : TypeWalker {
|
||||
Walker(IRGenerator &IRGen) : IRGen(IRGen) {}
|
||||
|
||||
Action walkToTypePre(Type ty) override {
|
||||
if (auto *BGT = ty->getAs<BoundGenericType>())
|
||||
genericDepth++;
|
||||
else if (auto *nominal = ty->getAs<NominalType>())
|
||||
noteUseOfTypeMetadata(nominal->getDecl());
|
||||
return Action::Continue;
|
||||
}
|
||||
|
||||
Action walkToTypePost(Type ty) override {
|
||||
if (auto *BGT = ty->getAs<BoundGenericType>())
|
||||
genericDepth--;
|
||||
|
||||
return Action::Continue;
|
||||
}
|
||||
|
||||
void noteUseOfTypeMetadata(NominalTypeDecl *type) {
|
||||
if (genericDepth == 0)
|
||||
return;
|
||||
if (!IRGen.hasLazyMetadata(type) || !type->hasClangNode())
|
||||
return;
|
||||
IRGen.noteUseOfTypeMetadata(type);
|
||||
}
|
||||
IRGenerator &IRGen;
|
||||
int genericDepth = 0;
|
||||
} walker{IRGen};
|
||||
type.walk(walker);
|
||||
};
|
||||
|
||||
for (const auto ¶m : type->getParameters())
|
||||
processType(param.getArgumentType(IRGen.SIL, type, context));
|
||||
for (const auto &result : type->getResultsWithError())
|
||||
processType(result.getReturnValueType(IRGen.SIL, type, context));
|
||||
}
|
||||
|
||||
/// Emit the definition for the given SIL constant.
|
||||
void IRGenModule::emitSILFunction(SILFunction *f) {
|
||||
if (f->isExternalDeclaration())
|
||||
@@ -2496,6 +2547,12 @@ void IRGenModule::emitSILFunction(SILFunction *f) {
|
||||
f->isAvailableExternally())
|
||||
return;
|
||||
|
||||
// Type metadata for foreign references is not yet supported on Windows. Bug #76168.
|
||||
if (Context.LangOpts.EnableCXXInterop &&
|
||||
f->getLinkage() == SILLinkage::Public &&
|
||||
!Context.LangOpts.Target.isOSWindows())
|
||||
noteUseOfMetadataByCXXInterop(IRGen, f, TypeExpansionContext(*f));
|
||||
|
||||
PrettyStackTraceSILFunction stackTrace("emitting IR", f);
|
||||
IRGenSILFunction(*this, f).emitSILFunction();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,14 @@ struct CxxStruct {
|
||||
int x;
|
||||
};
|
||||
|
||||
struct CxxStruct2 {
|
||||
inline CxxStruct2(int x) : x(x) {}
|
||||
inline CxxStruct2(const CxxStruct &other) : x(other.x) {}
|
||||
inline ~CxxStruct2() {}
|
||||
|
||||
int x;
|
||||
};
|
||||
|
||||
//--- module.modulemap
|
||||
module CxxTest {
|
||||
header "header.h"
|
||||
@@ -30,6 +38,12 @@ public func retCxxStruct() -> CxxStruct {
|
||||
return CxxStruct(2)
|
||||
}
|
||||
|
||||
#if !os(Windows)
|
||||
public func retCxxStruct2() -> CxxStruct2? {
|
||||
return CxxStruct2(2)
|
||||
}
|
||||
#endif
|
||||
|
||||
//--- use-swift-cxx-types.cpp
|
||||
|
||||
#include "header.h"
|
||||
@@ -38,5 +52,8 @@ public func retCxxStruct() -> CxxStruct {
|
||||
|
||||
int main() {
|
||||
auto x = UseCxx::retCxxStruct();
|
||||
#ifndef _WIN32
|
||||
auto y = UseCxx::retCxxStruct2();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user