mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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:
@@ -69,6 +69,7 @@
|
|||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/Support/Casting.h"
|
#include "llvm/Support/Casting.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
#include "llvm/Support/Compiler.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/FileSystem.h"
|
#include "llvm/Support/FileSystem.h"
|
||||||
#include "llvm/Support/MemoryBuffer.h"
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
@@ -1730,6 +1731,21 @@ private:
|
|||||||
llvm::dwarf::DW_LANG_Swift, nullptr);
|
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,
|
llvm::DIType *createFunctionPointer(DebugTypeInfo DbgTy, llvm::DIScope *Scope,
|
||||||
unsigned SizeInBits, unsigned AlignInBits,
|
unsigned SizeInBits, unsigned AlignInBits,
|
||||||
llvm::DINode::DIFlags Flags,
|
llvm::DINode::DIFlags Flags,
|
||||||
@@ -2062,18 +2078,29 @@ private:
|
|||||||
SpecificationOf);
|
SpecificationOf);
|
||||||
}
|
}
|
||||||
|
|
||||||
case TypeKind::Protocol: {
|
case TypeKind::Existential: {
|
||||||
auto *ProtocolTy = BaseTy->castTo<ProtocolType>();
|
auto *ExistentialTy = BaseTy->castTo<ExistentialType>();
|
||||||
auto *Decl = ProtocolTy->getDecl();
|
Type ConstraintTy = ExistentialTy->getConstraintType();
|
||||||
// FIXME: (LLVM branch) This should probably be a DW_TAG_interface_type.
|
TypeBase *TyPtr = ConstraintTy.getPointer();
|
||||||
auto L = getFileAndLocation(Decl);
|
if (!isa<ProtocolType>(TyPtr) && !isa<ProtocolCompositionType>(TyPtr) &&
|
||||||
unsigned FwdDeclLine = 0;
|
!isa<ParameterizedProtocolType>(TyPtr)) {
|
||||||
return createOpaqueStruct(Scope, Decl ? Decl->getNameStr() : MangledName,
|
// This could be an alias type, which we need to anchor in DWARF.
|
||||||
L.File, FwdDeclLine, SizeInBits, AlignInBits,
|
auto *Decl = DbgTy.getDecl();
|
||||||
Flags, MangledName);
|
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::ProtocolComposition:
|
||||||
case TypeKind::ParameterizedProtocol: {
|
case TypeKind::ParameterizedProtocol: {
|
||||||
auto *Decl = DbgTy.getDecl();
|
auto *Decl = DbgTy.getDecl();
|
||||||
|
|||||||
2
test/DebugInfo/Inputs/Alias.swift
Normal file
2
test/DebugInfo/Inputs/Alias.swift
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
public protocol ProtocolFromModule {}
|
||||||
|
public typealias AliasFromModule = ProtocolFromModule
|
||||||
17
test/DebugInfo/typealias-external.swift
Normal file
17
test/DebugInfo/typealias-external.swift
Normal 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")
|
||||||
Reference in New Issue
Block a user