[Debug Info] Represent type alias existantials in debug info

Previously debug info made not difference between an existential type and a
protocol type. This caused us to loose typealiases such as

typealias Alias = ProtocolType

in the debug info.

rdar://161134092
This commit is contained in:
Adrian Prantl
2025-11-21 15:14:51 -08:00
parent cf535d8b99
commit 45547be3f8
3 changed files with 56 additions and 10 deletions

View File

@@ -69,6 +69,7 @@
#include "llvm/IR/Module.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -1730,6 +1731,21 @@ private:
llvm::dwarf::DW_LANG_Swift, nullptr);
}
/// Create struct with a single member, used for Swift types that do not yet
/// have specialized DIDerivedTypes.
llvm::DIType *createSingleMemberStruct(
llvm::DIScope *Scope, StringRef Name, llvm::DIFile *File, unsigned Line,
unsigned SizeInBits, unsigned AlignInBits, llvm::DINode::DIFlags Flags,
StringRef MangledName, StringRef MemberName, llvm::DIType *MemberType) {
llvm::Metadata *Elements[] = {
DBuilder.createMemberType(Scope, MemberName, File, 0, SizeInBits,
AlignInBits, 0, Flags, MemberType)};
return DBuilder.createStructType(
Scope, Name, File, Line, SizeInBits, AlignInBits, Flags,
/* DerivedFrom */ nullptr, DBuilder.getOrCreateArray(Elements),
llvm::dwarf::DW_LANG_Swift, nullptr, MangledName, nullptr, 0);
}
llvm::DIType *createFunctionPointer(DebugTypeInfo DbgTy, llvm::DIScope *Scope,
unsigned SizeInBits, unsigned AlignInBits,
llvm::DINode::DIFlags Flags,
@@ -2062,18 +2078,29 @@ private:
SpecificationOf);
}
case TypeKind::Protocol: {
auto *ProtocolTy = BaseTy->castTo<ProtocolType>();
auto *Decl = ProtocolTy->getDecl();
// FIXME: (LLVM branch) This should probably be a DW_TAG_interface_type.
auto L = getFileAndLocation(Decl);
unsigned FwdDeclLine = 0;
return createOpaqueStruct(Scope, Decl ? Decl->getNameStr() : MangledName,
L.File, FwdDeclLine, SizeInBits, AlignInBits,
Flags, MangledName);
case TypeKind::Existential: {
auto *ExistentialTy = BaseTy->castTo<ExistentialType>();
Type ConstraintTy = ExistentialTy->getConstraintType();
TypeBase *TyPtr = ConstraintTy.getPointer();
if (!isa<ProtocolType>(TyPtr) && !isa<ProtocolCompositionType>(TyPtr) &&
!isa<ParameterizedProtocolType>(TyPtr)) {
// This could be an alias type, which we need to anchor in DWARF.
auto *Decl = DbgTy.getDecl();
auto L = getFileAndLocation(Decl);
unsigned FwdDeclLine = 0;
return createSingleMemberStruct(
Scope, Decl ? Decl->getNameStr() : MangledName, L.File, FwdDeclLine,
SizeInBits, AlignInBits, Flags, MangledName, "$swift.constraint",
getOrCreateType(ConstraintTy));
}
// If the existential is just a protocol type it shares its mangled name
// with it, so we can just represent it directly as a protocol.
BaseTy = TyPtr;
}
LLVM_FALLTHROUGH;
case TypeKind::Existential:
// FIXME: (LLVM branch) This should probably be a DW_TAG_interface_type.
case TypeKind::Protocol:
case TypeKind::ProtocolComposition:
case TypeKind::ParameterizedProtocol: {
auto *Decl = DbgTy.getDecl();

View File

@@ -0,0 +1,2 @@
public protocol ProtocolFromModule {}
public typealias AliasFromModule = ProtocolFromModule

View File

@@ -0,0 +1,17 @@
// RUN: %target-swift-frontend -emit-module-path %t/Alias.swiftmodule %S/Inputs/Alias.swift
// RUN: %target-swift-frontend %s -emit-ir -parse-as-library -module-name a -I%t -g -o - | %FileCheck %s
import Alias
public final class C {
public func use(a: AliasFromModule) {}
}
let c = C()
// CHECK-DAG: !DILocalVariable(name: "a", arg: 1, {{.*}}, type: ![[CONST_TY:[0-9]+]])
// CHECK-DAG: ![[CONST_TY]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[EXIST_TY:[0-9]+]])
// CHECK-DAG: ![[EXIST_TY]] = !DICompositeType(tag: DW_TAG_structure_type, name: "ProtocolFromModule", {{.*}}, elements: ![[ELTS:[0-9]+]], runtimeLang: DW_LANG_Swift, identifier: "$s5Alias0A10FromModuleaD")
// CHECK-DAG: ![[ELTS]] = !{![[INNER:[0-9]+]]}
// CHECK-DAG: ![[INNER]] = !DIDerivedType(tag: DW_TAG_member, name: "$swift.constraint", {{.*}}, baseType: ![[TYPEDEF:[0-9]+]]
// CHECK-DAG: ![[TYPEDEF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "$s5Alias0A10FromModuleaD", {{.*}}, baseType: ![[PROTO_TY:[0-9]+]])
// CHECK-DAG: ![[PROTO_TY]] = !DICompositeType(tag: DW_TAG_structure_type, name: "ProtocolFromModule", {{.*}}, identifier: "$s5Alias18ProtocolFromModule_pD")