[DebugInfo] Use underlying type of global variables with opaque type

rdar://144881938
This commit is contained in:
Augusto Noronha
2025-03-28 13:55:38 -07:00
parent ecc90933a2
commit 6abbc0d754
8 changed files with 68 additions and 21 deletions

View File

@@ -4985,6 +4985,8 @@ enum class SILCoroutineKind : uint8_t {
class SILFunctionConventions;
Type substOpaqueTypesWithUnderlyingTypes(Type type,
TypeExpansionContext context);
CanType substOpaqueTypesWithUnderlyingTypes(CanType type,
TypeExpansionContext context);

View File

@@ -1071,8 +1071,8 @@ operator()(SubstitutableType *maybeOpaqueType) const {
return substTy;
}
CanType swift::substOpaqueTypesWithUnderlyingTypes(CanType ty,
TypeExpansionContext context) {
Type swift::substOpaqueTypesWithUnderlyingTypes(Type ty,
TypeExpansionContext context) {
if (!context.shouldLookThroughOpaqueTypeArchetypes() ||
!ty->hasOpaqueArchetype())
return ty;
@@ -1082,7 +1082,14 @@ CanType swift::substOpaqueTypesWithUnderlyingTypes(CanType ty,
context.isWholeModuleContext());
SubstOptions flags = (SubstFlags::SubstituteOpaqueArchetypes |
SubstFlags::PreservePackExpansionLevel);
return ty.subst(replacer, replacer, flags)->getCanonicalType();
return ty.subst(replacer, replacer, flags);
}
CanType
swift::substOpaqueTypesWithUnderlyingTypes(CanType ty,
TypeExpansionContext context) {
return substOpaqueTypesWithUnderlyingTypes(static_cast<Type>(ty), context)
->getCanonicalType();
}
static ProtocolConformanceRef substOpaqueTypesWithUnderlyingTypesRec(

View File

@@ -105,8 +105,7 @@ DebugTypeInfo DebugTypeInfo::getForwardDecl(swift::Type Ty) {
return DbgTy;
}
DebugTypeInfo DebugTypeInfo::getGlobal(SILGlobalVariable *GV,
IRGenModule &IGM) {
static TypeBase *getTypeForGlobal(SILGlobalVariable *GV, IRGenModule &IGM) {
// Prefer the original, potentially sugared version of the type if
// the type hasn't been mucked with by an optimization pass.
auto LowTy = GV->getLoweredType().getASTType();
@@ -116,6 +115,15 @@ DebugTypeInfo DebugTypeInfo::getGlobal(SILGlobalVariable *GV,
if (DeclType->isEqual(LowTy))
Type = DeclType.getPointer();
}
// If this global variable contains an opaque type, replace it with its
// underlying type.
Type = IGM.substOpaqueTypesWithUnderlyingTypes(Type).getPointer();
return Type;
}
DebugTypeInfo DebugTypeInfo::getGlobal(SILGlobalVariable *GV,
IRGenModule &IGM) {
auto *Type = getTypeForGlobal(GV, IGM);
auto &TI = IGM.getTypeInfoForUnlowered(Type);
DebugTypeInfo DbgTy = getFromTypeInfo(Type, TI, IGM);
assert(!DbgTy.isContextArchetype() &&
@@ -124,17 +132,9 @@ DebugTypeInfo DebugTypeInfo::getGlobal(SILGlobalVariable *GV,
}
DebugTypeInfo DebugTypeInfo::getGlobalFixedBuffer(SILGlobalVariable *GV,
Size SizeInBytes,
Alignment Align) {
// Prefer the original, potentially sugared version of the type if
// the type hasn't been mucked with by an optimization pass.
auto LowTy = GV->getLoweredType().getASTType();
auto *Type = LowTy.getPointer();
if (auto *Decl = GV->getDecl()) {
auto DeclType = Decl->getTypeInContext();
if (DeclType->isEqual(LowTy))
Type = DeclType.getPointer();
}
Alignment Align,
IRGenModule &IGM) {
auto *Type = getTypeForGlobal(GV, IGM);
DebugTypeInfo DbgTy(Type, Align, ::hasDefaultAlignment(Type),
/* IsMetadataType = */ false, /* IsFixedBuffer = */ true);
assert(!DbgTy.isContextArchetype() &&

View File

@@ -76,7 +76,7 @@ public:
/// Global variables.
static DebugTypeInfo getGlobal(SILGlobalVariable *GV, IRGenModule &IGM);
static DebugTypeInfo getGlobalFixedBuffer(SILGlobalVariable *GV,
Size SizeInBytes, Alignment align);
Alignment align, IRGenModule &IGM);
/// ObjC classes.
static DebugTypeInfo getObjCClass(ClassDecl *theClass, Size size,
Alignment align);

View File

@@ -2778,9 +2778,9 @@ Address IRGenModule::getAddrOfSILGlobalVariable(SILGlobalVariable *var,
}
DebugTypeInfo DbgTy =
inFixedBuffer ? DebugTypeInfo::getGlobalFixedBuffer(var, fixedSize,
fixedAlignment)
: DebugTypeInfo::getGlobal(var, *this);
inFixedBuffer
? DebugTypeInfo::getGlobalFixedBuffer(var, fixedAlignment, *this)
: DebugTypeInfo::getGlobal(var, *this);
gvar = createVariable(*this, link, globalTy, fixedAlignment, DbgTy, loc, name);
}

View File

@@ -1118,6 +1118,7 @@ public:
clang::CodeGen::CodeGenModule &getClangCGM() const;
CanType getRuntimeReifiedType(CanType type);
Type substOpaqueTypesWithUnderlyingTypes(Type type);
CanType substOpaqueTypesWithUnderlyingTypes(CanType type);
SILType substOpaqueTypesWithUnderlyingTypes(SILType type, CanGenericSignature genericSig);
std::pair<CanType, ProtocolConformanceRef>

View File

@@ -526,7 +526,7 @@ CanType IRGenModule::getRuntimeReifiedType(CanType type) {
}));
}
CanType IRGenModule::substOpaqueTypesWithUnderlyingTypes(CanType type) {
Type IRGenModule::substOpaqueTypesWithUnderlyingTypes(Type type) {
// Substitute away opaque types whose underlying types we're allowed to
// assume are constant.
if (type->hasOpaqueArchetype()) {
@@ -537,6 +537,11 @@ CanType IRGenModule::substOpaqueTypesWithUnderlyingTypes(CanType type) {
return type;
}
CanType IRGenModule::substOpaqueTypesWithUnderlyingTypes(CanType type) {
return substOpaqueTypesWithUnderlyingTypes(static_cast<Type>(type))
->getCanonicalType();
}
SILType IRGenModule::substOpaqueTypesWithUnderlyingTypes(
SILType type, CanGenericSignature genericSig) {
// Substitute away opaque types whose underlying types we're allowed to

View File

@@ -0,0 +1,32 @@
// RUN: %target-swift-frontend -primary-file %s -emit-ir -g -o - | %FileCheck %s
public protocol TheProtocol {}
public class TheClass: TheProtocol {
}
struct TheStruct<T> {
let t: T
}
func f() -> some TheProtocol {
let p: some TheProtocol = TheClass()
return p
}
let v = f()
// CHECK: !DIGlobalVariable(name: "v", {{.*}}type: ![[FIXED_BUFFER:[0-9]+]]
// CHECK: ![[FIXED_BUFFER]] = !DICompositeType(tag: DW_TAG_structure_type, name: "$swift.fixedbuffer", {{.*}}, elements: ![[TYPE_1:[0-9]+]]
// CHECK: ![[TYPE_1]] = !{![[TYPE_2:[0-9]+]]}
// CHECK: ![[TYPE_2]] = !DIDerivedType(tag: DW_TAG_member, name: "contents"{{.*}}baseType: ![[TYPE_3:[0-9]+]]
// CHECK: ![[TYPE_3]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[TYPE:[0-9]+]])
// CHECK: ![[TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "TheClass"
let v2 = TheStruct(t: f())
// CHECK: !DIGlobalVariable(name: "v2", {{.*}}type: ![[CONST_TYPE_GEN:[0-9]+]]
// CHECK: ![[CONST_TYPE_GEN]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[TYPE_GEN_1:[0-9]+]])
// CHECK: ![[TYPE_GEN_1]] = !DICompositeType(tag: DW_TAG_structure_type{{.*}}elements: ![[TYPE_GEN_2:[0-9]+]]
// CHECK: ![[TYPE_GEN_2]] = !{![[TYPE_GEN_3:[0-9]+]]}
// CHECK: ![[TYPE_GEN_3]] = !DIDerivedType(tag: DW_TAG_member{{.*}}baseType: ![[TYPE_GEN:[0-9]+]]
// CHECK: ![[TYPE_GEN]] = !DICompositeType(tag: DW_TAG_structure_type, name: "$s17global_opaque_var9TheStructVyAA0D5ClassCGD"