Skip to content

Commit f3cf6da

Browse files
authored
Merge pull request llvm#11896 from swiftlang/dsymutil/debug-names-insertion-to-6.3
🍒[llvm][dsymutil] Use the DW_AT_name of the uniqued DIE for insertion into .debug_names
2 parents 03bec58 + 2edd5f8 commit f3cf6da

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+355
-52
lines changed

llvm/include/llvm/DWARFLinker/Classic/DWARFLinker.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,11 @@ class LLVM_ABI DWARFLinker : public DWARFLinkerBase {
709709
/// already there.
710710
/// \returns is a name was found.
711711
bool getDIENames(const DWARFDie &Die, AttributesInfo &Info,
712-
OffsetsStringPool &StringPool, bool StripTemplate = false);
712+
OffsetsStringPool &StringPool, const DWARFFile &File,
713+
CompileUnit &Unit, bool StripTemplate = false);
714+
715+
llvm::StringRef getCanonicalDIEName(DWARFDie Die, const DWARFFile &File,
716+
CompileUnit *Unit);
713717

714718
uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
715719
const DWARFFile &File,

llvm/include/llvm/DWARFLinker/Classic/DWARFLinkerDeclContext.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,13 @@ class DeclContext {
8484
DeclContext() : DefinedInClangModule(0), Parent(*this) {}
8585

8686
DeclContext(unsigned Hash, uint32_t Line, uint32_t ByteSize, uint16_t Tag,
87-
StringRef Name, StringRef File, const DeclContext &Parent,
88-
DWARFDie LastSeenDIE = DWARFDie(), unsigned CUId = 0)
87+
StringRef Name, StringRef NameForUniquing, StringRef File,
88+
const DeclContext &Parent, DWARFDie LastSeenDIE = DWARFDie(),
89+
unsigned CUId = 0)
8990
: QualifiedNameHash(Hash), Line(Line), ByteSize(ByteSize), Tag(Tag),
90-
DefinedInClangModule(0), Name(Name), File(File), Parent(Parent),
91-
LastSeenDIE(LastSeenDIE), LastSeenCompileUnitID(CUId) {}
91+
DefinedInClangModule(0), Name(Name), NameForUniquing(NameForUniquing),
92+
File(File), Parent(Parent), LastSeenDIE(LastSeenDIE),
93+
LastSeenCompileUnitID(CUId) {}
9294

9395
uint32_t getQualifiedNameHash() const { return QualifiedNameHash; }
9496

@@ -100,6 +102,7 @@ class DeclContext {
100102

101103
uint32_t getCanonicalDIEOffset() const { return CanonicalDIEOffset; }
102104
void setCanonicalDIEOffset(uint32_t Offset) { CanonicalDIEOffset = Offset; }
105+
llvm::StringRef getCanonicalName() const { return Name; }
103106

104107
bool isDefinedInClangModule() const { return DefinedInClangModule; }
105108
void setDefinedInClangModule(bool Val) { DefinedInClangModule = Val; }
@@ -115,6 +118,7 @@ class DeclContext {
115118
uint16_t Tag = dwarf::DW_TAG_compile_unit;
116119
unsigned DefinedInClangModule : 1;
117120
StringRef Name;
121+
StringRef NameForUniquing;
118122
StringRef File;
119123
const DeclContext &Parent;
120124
DWARFDie LastSeenDIE;
@@ -180,7 +184,7 @@ struct DeclMapInfo : private DenseMapInfo<DeclContext *> {
180184
return RHS == LHS;
181185
return LHS->QualifiedNameHash == RHS->QualifiedNameHash &&
182186
LHS->Line == RHS->Line && LHS->ByteSize == RHS->ByteSize &&
183-
LHS->Name.data() == RHS->Name.data() &&
187+
LHS->NameForUniquing.data() == RHS->NameForUniquing.data() &&
184188
LHS->File.data() == RHS->File.data() &&
185189
LHS->Parent.QualifiedNameHash == RHS->Parent.QualifiedNameHash;
186190
}

llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,22 +150,84 @@ static bool isTypeTag(uint16_t Tag) {
150150
return false;
151151
}
152152

153-
bool DWARFLinker::DIECloner::getDIENames(const DWARFDie &Die,
154-
AttributesInfo &Info,
155-
OffsetsStringPool &StringPool,
156-
bool StripTemplate) {
153+
/// Recurse through the input DIE's canonical references until we find a
154+
/// DW_AT_name.
155+
llvm::StringRef
156+
DWARFLinker::DIECloner::getCanonicalDIEName(DWARFDie Die, const DWARFFile &File,
157+
CompileUnit *Unit) {
158+
if (!Die)
159+
return {};
160+
161+
std::optional<DWARFFormValue> Ref;
162+
163+
auto GetDieName = [](const DWARFDie &D) -> llvm::StringRef {
164+
auto NameForm = D.find(llvm::dwarf::DW_AT_name);
165+
if (!NameForm)
166+
return {};
167+
168+
auto NameOrErr = NameForm->getAsCString();
169+
if (!NameOrErr) {
170+
llvm::consumeError(NameOrErr.takeError());
171+
return {};
172+
}
173+
174+
return *NameOrErr;
175+
};
176+
177+
llvm::StringRef Name = GetDieName(Die);
178+
if (!Name.empty())
179+
return Name;
180+
181+
while (true) {
182+
if (!(Ref = Die.find(llvm::dwarf::DW_AT_specification)) &&
183+
!(Ref = Die.find(llvm::dwarf::DW_AT_abstract_origin)))
184+
break;
185+
186+
Die = Linker.resolveDIEReference(File, CompileUnits, *Ref, Die, Unit);
187+
if (!Die)
188+
break;
189+
190+
assert(Unit);
191+
192+
unsigned SpecIdx = Unit->getOrigUnit().getDIEIndex(Die);
193+
CompileUnit::DIEInfo &SpecInfo = Unit->getInfo(SpecIdx);
194+
if (SpecInfo.Ctxt && SpecInfo.Ctxt->hasCanonicalDIE()) {
195+
if (!SpecInfo.Ctxt->getCanonicalName().empty()) {
196+
Name = SpecInfo.Ctxt->getCanonicalName();
197+
break;
198+
}
199+
}
200+
201+
Name = GetDieName(Die);
202+
if (!Name.empty())
203+
break;
204+
}
205+
206+
return Name;
207+
}
208+
209+
bool DWARFLinker::DIECloner::getDIENames(
210+
const DWARFDie &Die, AttributesInfo &Info, OffsetsStringPool &StringPool,
211+
const DWARFFile &File, CompileUnit &Unit, bool StripTemplate) {
157212
// This function will be called on DIEs having low_pcs and
158213
// ranges. As getting the name might be more expansive, filter out
159214
// blocks directly.
160215
if (Die.getTag() == dwarf::DW_TAG_lexical_block)
161216
return false;
162217

218+
// The mangled name of an specification DIE will by virtue of the
219+
// uniquing algorithm be the same as the one it got uniqued into.
220+
// So just use the input DIE's linkage name.
163221
if (!Info.MangledName)
164222
if (const char *MangledName = Die.getLinkageName())
165223
Info.MangledName = StringPool.getEntry(MangledName);
166224

225+
// For subprograms with linkage names, we unique on the linkage name,
226+
// so DW_AT_name's may differ between the input and canonical DIEs.
227+
// Use the name of the canonical DIE.
167228
if (!Info.Name)
168-
if (const char *Name = Die.getShortName())
229+
if (llvm::StringRef Name = getCanonicalDIEName(Die, File, &Unit);
230+
!Name.empty())
169231
Info.Name = StringPool.getEntry(Name);
170232

171233
if (!Info.MangledName)
@@ -1827,7 +1889,7 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
18271889
// accelerator tables too. For now stick with dsymutil's behavior.
18281890
if ((Info.InDebugMap || AttrInfo.HasLowPc || AttrInfo.HasRanges) &&
18291891
Tag != dwarf::DW_TAG_compile_unit &&
1830-
getDIENames(InputDIE, AttrInfo, DebugStrPool,
1892+
getDIENames(InputDIE, AttrInfo, DebugStrPool, File, Unit,
18311893
Tag != dwarf::DW_TAG_inlined_subroutine)) {
18321894
if (AttrInfo.MangledName && AttrInfo.MangledName != AttrInfo.Name)
18331895
Unit.addNameAccelerator(Die, AttrInfo.MangledName,
@@ -1850,7 +1912,7 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
18501912
} else if (Tag == dwarf::DW_TAG_imported_declaration && AttrInfo.Name) {
18511913
Unit.addNamespaceAccelerator(Die, AttrInfo.Name);
18521914
} else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration) {
1853-
bool Success = getDIENames(InputDIE, AttrInfo, DebugStrPool);
1915+
bool Success = getDIENames(InputDIE, AttrInfo, DebugStrPool, File, Unit);
18541916
uint64_t RuntimeLang =
18551917
dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_runtime_class))
18561918
.value_or(0);

llvm/lib/DWARFLinker/Classic/DWARFLinkerDeclContext.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,24 +84,26 @@ DeclContextTree::getChildDeclContext(DeclContext &Context, const DWARFDie &DIE,
8484
break;
8585
}
8686

87-
StringRef NameRef;
87+
StringRef Name = DIE.getShortName();
88+
StringRef NameForUniquing;
8889
StringRef FileRef;
8990

9091
if (const char *LinkageName = DIE.getLinkageName())
91-
NameRef = StringPool.internString(LinkageName);
92-
else if (const char *ShortName = DIE.getShortName())
93-
NameRef = StringPool.internString(ShortName);
92+
NameForUniquing = StringPool.internString(LinkageName);
93+
else if (!Name.empty())
94+
NameForUniquing = StringPool.internString(Name);
9495

95-
bool IsAnonymousNamespace = NameRef.empty() && Tag == dwarf::DW_TAG_namespace;
96+
bool IsAnonymousNamespace =
97+
NameForUniquing.empty() && Tag == dwarf::DW_TAG_namespace;
9698
if (IsAnonymousNamespace) {
9799
// FIXME: For dsymutil-classic compatibility. I think uniquing within
98100
// anonymous namespaces is wrong. There is no ODR guarantee there.
99-
NameRef = "(anonymous namespace)";
101+
NameForUniquing = "(anonymous namespace)";
100102
}
101103

102104
if (Tag != dwarf::DW_TAG_class_type && Tag != dwarf::DW_TAG_structure_type &&
103105
Tag != dwarf::DW_TAG_union_type &&
104-
Tag != dwarf::DW_TAG_enumeration_type && NameRef.empty())
106+
Tag != dwarf::DW_TAG_enumeration_type && NameForUniquing.empty())
105107
return PointerIntPair<DeclContext *, 1>(nullptr);
106108

107109
unsigned Line = 0;
@@ -140,10 +142,10 @@ DeclContextTree::getChildDeclContext(DeclContext &Context, const DWARFDie &DIE,
140142
}
141143
}
142144

143-
if (!Line && NameRef.empty())
145+
if (!Line && NameForUniquing.empty())
144146
return PointerIntPair<DeclContext *, 1>(nullptr);
145147

146-
// We hash NameRef, which is the mangled name, in order to get most
148+
// We hash NameForUniquing, which is the mangled name, in order to get most
147149
// overloaded functions resolve correctly.
148150
//
149151
// Strictly speaking, hashing the Tag is only necessary for a
@@ -153,23 +155,25 @@ DeclContextTree::getChildDeclContext(DeclContext &Context, const DWARFDie &DIE,
153155
// FIXME: dsymutil-classic won't unique the same type presented
154156
// once as a struct and once as a class. Using the Tag in the fully
155157
// qualified name hash to get the same effect.
156-
unsigned Hash = hash_combine(Context.getQualifiedNameHash(), Tag, NameRef);
158+
unsigned Hash =
159+
hash_combine(Context.getQualifiedNameHash(), Tag, NameForUniquing);
157160

158161
// FIXME: dsymutil-classic compatibility: when we don't have a name,
159162
// use the filename.
160163
if (IsAnonymousNamespace)
161164
Hash = hash_combine(Hash, FileRef);
162165

163166
// Now look if this context already exists.
164-
DeclContext Key(Hash, Line, ByteSize, Tag, NameRef, FileRef, Context);
167+
DeclContext Key(Hash, Line, ByteSize, Tag, Name, NameForUniquing, FileRef,
168+
Context);
165169
auto ContextIter = Contexts.find(&Key);
166170

167171
if (ContextIter == Contexts.end()) {
168172
// The context wasn't found.
169173
bool Inserted;
170-
DeclContext *NewContext =
171-
new (Allocator) DeclContext(Hash, Line, ByteSize, Tag, NameRef, FileRef,
172-
Context, DIE, U.getUniqueID());
174+
DeclContext *NewContext = new (Allocator)
175+
DeclContext(Hash, Line, ByteSize, Tag, Name, NameForUniquing, FileRef,
176+
Context, DIE, U.getUniqueID());
173177
std::tie(ContextIter, Inserted) = Contexts.insert(NewContext);
174178
assert(Inserted && "Failed to insert DeclContext");
175179
(void)Inserted;

0 commit comments

Comments
 (0)