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/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.
|
||||
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 createOpaqueStruct(Scope, Decl ? Decl->getNameStr() : MangledName,
|
||||
L.File, FwdDeclLine, SizeInBits, AlignInBits,
|
||||
Flags, MangledName);
|
||||
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();
|
||||
|
||||
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