|
69 | 69 | #include "llvm/IR/Module.h" |
70 | 70 | #include "llvm/Support/Casting.h" |
71 | 71 | #include "llvm/Support/CommandLine.h" |
| 72 | +#include "llvm/Support/Compiler.h" |
72 | 73 | #include "llvm/Support/Debug.h" |
73 | 74 | #include "llvm/Support/FileSystem.h" |
74 | 75 | #include "llvm/Support/MemoryBuffer.h" |
@@ -1730,6 +1731,21 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { |
1730 | 1731 | llvm::dwarf::DW_LANG_Swift, nullptr); |
1731 | 1732 | } |
1732 | 1733 |
|
| 1734 | + /// Create struct with a single member, used for Swift types that do not yet |
| 1735 | + /// have specialized DIDerivedTypes. |
| 1736 | + llvm::DIType *createSingleMemberStruct( |
| 1737 | + llvm::DIScope *Scope, StringRef Name, llvm::DIFile *File, unsigned Line, |
| 1738 | + unsigned SizeInBits, unsigned AlignInBits, llvm::DINode::DIFlags Flags, |
| 1739 | + StringRef MangledName, StringRef MemberName, llvm::DIType *MemberType) { |
| 1740 | + llvm::Metadata *Elements[] = { |
| 1741 | + DBuilder.createMemberType(Scope, MemberName, File, 0, SizeInBits, |
| 1742 | + AlignInBits, 0, Flags, MemberType)}; |
| 1743 | + return DBuilder.createStructType( |
| 1744 | + Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, |
| 1745 | + /* DerivedFrom */ nullptr, DBuilder.getOrCreateArray(Elements), |
| 1746 | + llvm::dwarf::DW_LANG_Swift, nullptr, MangledName, nullptr, 0); |
| 1747 | + } |
| 1748 | + |
1733 | 1749 | llvm::DIType *createFunctionPointer(DebugTypeInfo DbgTy, llvm::DIScope *Scope, |
1734 | 1750 | unsigned SizeInBits, unsigned AlignInBits, |
1735 | 1751 | llvm::DINode::DIFlags Flags, |
@@ -2062,18 +2078,29 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { |
2062 | 2078 | SpecificationOf); |
2063 | 2079 | } |
2064 | 2080 |
|
2065 | | - case TypeKind::Protocol: { |
2066 | | - auto *ProtocolTy = BaseTy->castTo<ProtocolType>(); |
2067 | | - auto *Decl = ProtocolTy->getDecl(); |
2068 | | - // FIXME: (LLVM branch) This should probably be a DW_TAG_interface_type. |
2069 | | - auto L = getFileAndLocation(Decl); |
2070 | | - unsigned FwdDeclLine = 0; |
2071 | | - return createOpaqueStruct(Scope, Decl ? Decl->getNameStr() : MangledName, |
2072 | | - L.File, FwdDeclLine, SizeInBits, AlignInBits, |
2073 | | - Flags, MangledName); |
| 2081 | + case TypeKind::Existential: { |
| 2082 | + auto *ExistentialTy = BaseTy->castTo<ExistentialType>(); |
| 2083 | + Type ConstraintTy = ExistentialTy->getConstraintType(); |
| 2084 | + TypeBase *TyPtr = ConstraintTy.getPointer(); |
| 2085 | + if (!isa<ProtocolType>(TyPtr) && !isa<ProtocolCompositionType>(TyPtr) && |
| 2086 | + !isa<ParameterizedProtocolType>(TyPtr)) { |
| 2087 | + // This could be an alias type, which we need to anchor in DWARF. |
| 2088 | + auto *Decl = DbgTy.getDecl(); |
| 2089 | + auto L = getFileAndLocation(Decl); |
| 2090 | + unsigned FwdDeclLine = 0; |
| 2091 | + return createSingleMemberStruct( |
| 2092 | + Scope, Decl ? Decl->getNameStr() : MangledName, L.File, FwdDeclLine, |
| 2093 | + SizeInBits, AlignInBits, Flags, MangledName, "$swift.constraint", |
| 2094 | + getOrCreateType(ConstraintTy)); |
| 2095 | + } |
| 2096 | + // If the existential is just a protocol type it shares its mangled name |
| 2097 | + // with it, so we can just represent it directly as a protocol. |
| 2098 | + BaseTy = TyPtr; |
2074 | 2099 | } |
| 2100 | + LLVM_FALLTHROUGH; |
2075 | 2101 |
|
2076 | | - case TypeKind::Existential: |
| 2102 | + // FIXME: (LLVM branch) This should probably be a DW_TAG_interface_type. |
| 2103 | + case TypeKind::Protocol: |
2077 | 2104 | case TypeKind::ProtocolComposition: |
2078 | 2105 | case TypeKind::ParameterizedProtocol: { |
2079 | 2106 | auto *Decl = DbgTy.getDecl(); |
|
0 commit comments