diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index 69c7fce7aad..73dba8cc7b6 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -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(); - 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(); + Type ConstraintTy = ExistentialTy->getConstraintType(); + TypeBase *TyPtr = ConstraintTy.getPointer(); + if (!isa(TyPtr) && !isa(TyPtr) && + !isa(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(); diff --git a/test/DebugInfo/Inputs/Alias.swift b/test/DebugInfo/Inputs/Alias.swift new file mode 100644 index 00000000000..14094958c52 --- /dev/null +++ b/test/DebugInfo/Inputs/Alias.swift @@ -0,0 +1,2 @@ +public protocol ProtocolFromModule {} +public typealias AliasFromModule = ProtocolFromModule diff --git a/test/DebugInfo/typealias-external.swift b/test/DebugInfo/typealias-external.swift new file mode 100644 index 00000000000..5cab5b51270 --- /dev/null +++ b/test/DebugInfo/typealias-external.swift @@ -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")