1ee9906d8SZachary Turner //===- RecordName.cpp ----------------------------------------- *- C++ --*-===//
2ee9906d8SZachary Turner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ee9906d8SZachary Turner //
7ee9906d8SZachary Turner //===----------------------------------------------------------------------===//
8ee9906d8SZachary Turner
9ee9906d8SZachary Turner #include "llvm/DebugInfo/CodeView/RecordName.h"
10ee9906d8SZachary Turner
11ee9906d8SZachary Turner #include "llvm/ADT/SmallString.h"
125519e4daSReid Kleckner #include "llvm/ADT/StringExtras.h"
13ee9906d8SZachary Turner #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
14*81cde474Sserge-sans-paille #include "llvm/DebugInfo/CodeView/CodeView.h"
15*81cde474Sserge-sans-paille #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
16ee9906d8SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
17*81cde474Sserge-sans-paille #include "llvm/DebugInfo/CodeView/TypeCollection.h"
18*81cde474Sserge-sans-paille #include "llvm/DebugInfo/CodeView/TypeIndex.h"
19*81cde474Sserge-sans-paille #include "llvm/DebugInfo/CodeView/TypeRecord.h"
20ee9906d8SZachary Turner #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
21ee9906d8SZachary Turner #include "llvm/Support/FormatVariadic.h"
22ee9906d8SZachary Turner
23ee9906d8SZachary Turner using namespace llvm;
24ee9906d8SZachary Turner using namespace llvm::codeview;
25ee9906d8SZachary Turner
26ee9906d8SZachary Turner namespace {
27ee9906d8SZachary Turner class TypeNameComputer : public TypeVisitorCallbacks {
28ee9906d8SZachary Turner /// The type collection. Used to calculate names of nested types.
29ee9906d8SZachary Turner TypeCollection &Types;
30ee9906d8SZachary Turner TypeIndex CurrentTypeIndex = TypeIndex::None();
31ee9906d8SZachary Turner
32ee9906d8SZachary Turner /// Name of the current type. Only valid before visitTypeEnd.
33ee9906d8SZachary Turner SmallString<256> Name;
34ee9906d8SZachary Turner
35ee9906d8SZachary Turner public:
TypeNameComputer(TypeCollection & Types)36ee9906d8SZachary Turner explicit TypeNameComputer(TypeCollection &Types) : Types(Types) {}
37ee9906d8SZachary Turner
name() const38ee9906d8SZachary Turner StringRef name() const { return Name; }
39ee9906d8SZachary Turner
40ee9906d8SZachary Turner /// Paired begin/end actions for all types. Receives all record data,
41ee9906d8SZachary Turner /// including the fixed-length record prefix.
42ee9906d8SZachary Turner Error visitTypeBegin(CVType &Record) override;
43ee9906d8SZachary Turner Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
44ee9906d8SZachary Turner Error visitTypeEnd(CVType &Record) override;
45ee9906d8SZachary Turner
46ee9906d8SZachary Turner #define TYPE_RECORD(EnumName, EnumVal, Name) \
47ee9906d8SZachary Turner Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
48ee9906d8SZachary Turner #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
49ee9906d8SZachary Turner #define MEMBER_RECORD(EnumName, EnumVal, Name)
50ee9906d8SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
51ee9906d8SZachary Turner };
52ee9906d8SZachary Turner } // namespace
53ee9906d8SZachary Turner
visitTypeBegin(CVType & Record)54ee9906d8SZachary Turner Error TypeNameComputer::visitTypeBegin(CVType &Record) {
55ee9906d8SZachary Turner llvm_unreachable("Must call visitTypeBegin with a TypeIndex!");
56ee9906d8SZachary Turner return Error::success();
57ee9906d8SZachary Turner }
58ee9906d8SZachary Turner
visitTypeBegin(CVType & Record,TypeIndex Index)59ee9906d8SZachary Turner Error TypeNameComputer::visitTypeBegin(CVType &Record, TypeIndex Index) {
60ee9906d8SZachary Turner // Reset Name to the empty string. If the visitor sets it, we know it.
61ee9906d8SZachary Turner Name = "";
62ee9906d8SZachary Turner CurrentTypeIndex = Index;
63ee9906d8SZachary Turner return Error::success();
64ee9906d8SZachary Turner }
65ee9906d8SZachary Turner
visitTypeEnd(CVType & CVR)66ee9906d8SZachary Turner Error TypeNameComputer::visitTypeEnd(CVType &CVR) { return Error::success(); }
67ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,FieldListRecord & FieldList)68ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR,
69ee9906d8SZachary Turner FieldListRecord &FieldList) {
70ee9906d8SZachary Turner Name = "<field list>";
71ee9906d8SZachary Turner return Error::success();
72ee9906d8SZachary Turner }
73ee9906d8SZachary Turner
visitKnownRecord(CVRecord<TypeLeafKind> & CVR,StringIdRecord & String)74ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
75ee9906d8SZachary Turner StringIdRecord &String) {
76ee9906d8SZachary Turner Name = String.getString();
77ee9906d8SZachary Turner return Error::success();
78ee9906d8SZachary Turner }
79ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,ArgListRecord & Args)80ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
81ee9906d8SZachary Turner auto Indices = Args.getIndices();
82ee9906d8SZachary Turner uint32_t Size = Indices.size();
83ee9906d8SZachary Turner Name = "(";
84ee9906d8SZachary Turner for (uint32_t I = 0; I < Size; ++I) {
855519e4daSReid Kleckner if (Indices[I] < CurrentTypeIndex)
86ee9906d8SZachary Turner Name.append(Types.getTypeName(Indices[I]));
875519e4daSReid Kleckner else
885519e4daSReid Kleckner Name.append("<unknown 0x" + utohexstr(Indices[I].getIndex()) + ">");
89ee9906d8SZachary Turner if (I + 1 != Size)
90ee9906d8SZachary Turner Name.append(", ");
91ee9906d8SZachary Turner }
92ee9906d8SZachary Turner Name.push_back(')');
93ee9906d8SZachary Turner return Error::success();
94ee9906d8SZachary Turner }
95ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,StringListRecord & Strings)96ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR,
97ee9906d8SZachary Turner StringListRecord &Strings) {
98ee9906d8SZachary Turner auto Indices = Strings.getIndices();
99ee9906d8SZachary Turner uint32_t Size = Indices.size();
100ee9906d8SZachary Turner Name = "\"";
101ee9906d8SZachary Turner for (uint32_t I = 0; I < Size; ++I) {
102ee9906d8SZachary Turner Name.append(Types.getTypeName(Indices[I]));
103ee9906d8SZachary Turner if (I + 1 != Size)
104ee9906d8SZachary Turner Name.append("\" \"");
105ee9906d8SZachary Turner }
106ee9906d8SZachary Turner Name.push_back('\"');
107ee9906d8SZachary Turner return Error::success();
108ee9906d8SZachary Turner }
109ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,ClassRecord & Class)110ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
111ee9906d8SZachary Turner Name = Class.getName();
112ee9906d8SZachary Turner return Error::success();
113ee9906d8SZachary Turner }
114ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,UnionRecord & Union)115ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
116ee9906d8SZachary Turner Name = Union.getName();
117ee9906d8SZachary Turner return Error::success();
118ee9906d8SZachary Turner }
119ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,EnumRecord & Enum)120ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
121ee9906d8SZachary Turner Name = Enum.getName();
122ee9906d8SZachary Turner return Error::success();
123ee9906d8SZachary Turner }
124ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,ArrayRecord & AT)125ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
126ee9906d8SZachary Turner Name = AT.getName();
127ee9906d8SZachary Turner return Error::success();
128ee9906d8SZachary Turner }
129ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,VFTableRecord & VFT)130ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) {
131ee9906d8SZachary Turner Name = VFT.getName();
132ee9906d8SZachary Turner return Error::success();
133ee9906d8SZachary Turner }
134ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,MemberFuncIdRecord & Id)135ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) {
136ee9906d8SZachary Turner Name = Id.getName();
137ee9906d8SZachary Turner return Error::success();
138ee9906d8SZachary Turner }
139ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,ProcedureRecord & Proc)140ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) {
141ee9906d8SZachary Turner StringRef Ret = Types.getTypeName(Proc.getReturnType());
142ee9906d8SZachary Turner StringRef Params = Types.getTypeName(Proc.getArgumentList());
143ee9906d8SZachary Turner Name = formatv("{0} {1}", Ret, Params).sstr<256>();
144ee9906d8SZachary Turner return Error::success();
145ee9906d8SZachary Turner }
146ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,MemberFunctionRecord & MF)147ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR,
148ee9906d8SZachary Turner MemberFunctionRecord &MF) {
149ee9906d8SZachary Turner StringRef Ret = Types.getTypeName(MF.getReturnType());
150ee9906d8SZachary Turner StringRef Class = Types.getTypeName(MF.getClassType());
151ee9906d8SZachary Turner StringRef Params = Types.getTypeName(MF.getArgumentList());
152ee9906d8SZachary Turner Name = formatv("{0} {1}::{2}", Ret, Class, Params).sstr<256>();
153ee9906d8SZachary Turner return Error::success();
154ee9906d8SZachary Turner }
155ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,FuncIdRecord & Func)156ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {
157ee9906d8SZachary Turner Name = Func.getName();
158ee9906d8SZachary Turner return Error::success();
159ee9906d8SZachary Turner }
160ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,TypeServer2Record & TS)161ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) {
162ee9906d8SZachary Turner Name = TS.getName();
163ee9906d8SZachary Turner return Error::success();
164ee9906d8SZachary Turner }
165ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,PointerRecord & Ptr)166ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
167ee9906d8SZachary Turner
168ee9906d8SZachary Turner if (Ptr.isPointerToMember()) {
169ee9906d8SZachary Turner const MemberPointerInfo &MI = Ptr.getMemberInfo();
170ee9906d8SZachary Turner
171ee9906d8SZachary Turner StringRef Pointee = Types.getTypeName(Ptr.getReferentType());
172ee9906d8SZachary Turner StringRef Class = Types.getTypeName(MI.getContainingType());
173ee9906d8SZachary Turner Name = formatv("{0} {1}::*", Pointee, Class);
174ee9906d8SZachary Turner } else {
175ee9906d8SZachary Turner Name.append(Types.getTypeName(Ptr.getReferentType()));
176ee9906d8SZachary Turner
177ee9906d8SZachary Turner if (Ptr.getMode() == PointerMode::LValueReference)
178ee9906d8SZachary Turner Name.append("&");
179ee9906d8SZachary Turner else if (Ptr.getMode() == PointerMode::RValueReference)
180ee9906d8SZachary Turner Name.append("&&");
181ee9906d8SZachary Turner else if (Ptr.getMode() == PointerMode::Pointer)
182ee9906d8SZachary Turner Name.append("*");
1833acdc677SReid Kleckner
1843acdc677SReid Kleckner // Qualifiers in pointer records apply to the pointer, not the pointee, so
1853acdc677SReid Kleckner // they go on the right.
1863acdc677SReid Kleckner if (Ptr.isConst())
1873acdc677SReid Kleckner Name.append(" const");
1883acdc677SReid Kleckner if (Ptr.isVolatile())
1893acdc677SReid Kleckner Name.append(" volatile");
1903acdc677SReid Kleckner if (Ptr.isUnaligned())
1913acdc677SReid Kleckner Name.append(" __unaligned");
1923acdc677SReid Kleckner if (Ptr.isRestrict())
1933acdc677SReid Kleckner Name.append(" __restrict");
194ee9906d8SZachary Turner }
195ee9906d8SZachary Turner return Error::success();
196ee9906d8SZachary Turner }
197ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,ModifierRecord & Mod)198ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
199ee9906d8SZachary Turner uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
200ee9906d8SZachary Turner
201ee9906d8SZachary Turner if (Mods & uint16_t(ModifierOptions::Const))
202ee9906d8SZachary Turner Name.append("const ");
203ee9906d8SZachary Turner if (Mods & uint16_t(ModifierOptions::Volatile))
204ee9906d8SZachary Turner Name.append("volatile ");
205ee9906d8SZachary Turner if (Mods & uint16_t(ModifierOptions::Unaligned))
206ee9906d8SZachary Turner Name.append("__unaligned ");
207ee9906d8SZachary Turner Name.append(Types.getTypeName(Mod.getModifiedType()));
208ee9906d8SZachary Turner return Error::success();
209ee9906d8SZachary Turner }
210ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,VFTableShapeRecord & Shape)211ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR,
212ee9906d8SZachary Turner VFTableShapeRecord &Shape) {
213ee9906d8SZachary Turner Name = formatv("<vftable {0} methods>", Shape.getEntryCount());
214ee9906d8SZachary Turner return Error::success();
215ee9906d8SZachary Turner }
216ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,UdtModSourceLineRecord & ModSourceLine)217ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(
218ee9906d8SZachary Turner CVType &CVR, UdtModSourceLineRecord &ModSourceLine) {
219ee9906d8SZachary Turner return Error::success();
220ee9906d8SZachary Turner }
221ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,UdtSourceLineRecord & SourceLine)222ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR,
223ee9906d8SZachary Turner UdtSourceLineRecord &SourceLine) {
224ee9906d8SZachary Turner return Error::success();
225ee9906d8SZachary Turner }
226ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,BitFieldRecord & BF)227ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR, BitFieldRecord &BF) {
228ee9906d8SZachary Turner return Error::success();
229ee9906d8SZachary Turner }
230ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,MethodOverloadListRecord & Overloads)231ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR,
232ee9906d8SZachary Turner MethodOverloadListRecord &Overloads) {
233ee9906d8SZachary Turner return Error::success();
234ee9906d8SZachary Turner }
235ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,BuildInfoRecord & BI)236ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR, BuildInfoRecord &BI) {
237ee9906d8SZachary Turner return Error::success();
238ee9906d8SZachary Turner }
239ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,LabelRecord & R)240ee9906d8SZachary Turner Error TypeNameComputer::visitKnownRecord(CVType &CVR, LabelRecord &R) {
241ee9906d8SZachary Turner return Error::success();
242ee9906d8SZachary Turner }
243ee9906d8SZachary Turner
visitKnownRecord(CVType & CVR,PrecompRecord & Precomp)244d9e96741SAlexandre Ganea Error TypeNameComputer::visitKnownRecord(CVType &CVR,
245d9e96741SAlexandre Ganea PrecompRecord &Precomp) {
246d9e96741SAlexandre Ganea return Error::success();
247d9e96741SAlexandre Ganea }
248d9e96741SAlexandre Ganea
visitKnownRecord(CVType & CVR,EndPrecompRecord & EndPrecomp)249d9e96741SAlexandre Ganea Error TypeNameComputer::visitKnownRecord(CVType &CVR,
250d9e96741SAlexandre Ganea EndPrecompRecord &EndPrecomp) {
251d9e96741SAlexandre Ganea return Error::success();
252d9e96741SAlexandre Ganea }
253d9e96741SAlexandre Ganea
computeTypeName(TypeCollection & Types,TypeIndex Index)254ee9906d8SZachary Turner std::string llvm::codeview::computeTypeName(TypeCollection &Types,
255ee9906d8SZachary Turner TypeIndex Index) {
256ee9906d8SZachary Turner TypeNameComputer Computer(Types);
257ee9906d8SZachary Turner CVType Record = Types.getType(Index);
258ee9906d8SZachary Turner if (auto EC = visitTypeRecord(Record, Index, Computer)) {
259ee9906d8SZachary Turner consumeError(std::move(EC));
260ee9906d8SZachary Turner return "<unknown UDT>";
261ee9906d8SZachary Turner }
262adcd0268SBenjamin Kramer return std::string(Computer.name());
263ee9906d8SZachary Turner }
264ee9906d8SZachary Turner
getSymbolNameOffset(CVSymbol Sym)265ee9906d8SZachary Turner static int getSymbolNameOffset(CVSymbol Sym) {
266ee9906d8SZachary Turner switch (Sym.kind()) {
267ee9906d8SZachary Turner // See ProcSym
268ee9906d8SZachary Turner case SymbolKind::S_GPROC32:
269ee9906d8SZachary Turner case SymbolKind::S_LPROC32:
270ee9906d8SZachary Turner case SymbolKind::S_GPROC32_ID:
271ee9906d8SZachary Turner case SymbolKind::S_LPROC32_ID:
272ee9906d8SZachary Turner case SymbolKind::S_LPROC32_DPC:
273ee9906d8SZachary Turner case SymbolKind::S_LPROC32_DPC_ID:
274ee9906d8SZachary Turner return 35;
275ee9906d8SZachary Turner // See Thunk32Sym
276ee9906d8SZachary Turner case SymbolKind::S_THUNK32:
277ee9906d8SZachary Turner return 21;
278ee9906d8SZachary Turner // See SectionSym
279ee9906d8SZachary Turner case SymbolKind::S_SECTION:
280ee9906d8SZachary Turner return 16;
281ee9906d8SZachary Turner // See CoffGroupSym
282ee9906d8SZachary Turner case SymbolKind::S_COFFGROUP:
283ee9906d8SZachary Turner return 14;
284ee9906d8SZachary Turner // See PublicSym32, FileStaticSym, RegRelativeSym, DataSym, ThreadLocalDataSym
285ee9906d8SZachary Turner case SymbolKind::S_PUB32:
286ee9906d8SZachary Turner case SymbolKind::S_FILESTATIC:
287ee9906d8SZachary Turner case SymbolKind::S_REGREL32:
288ee9906d8SZachary Turner case SymbolKind::S_GDATA32:
289ee9906d8SZachary Turner case SymbolKind::S_LDATA32:
290ee9906d8SZachary Turner case SymbolKind::S_LMANDATA:
291ee9906d8SZachary Turner case SymbolKind::S_GMANDATA:
292ee9906d8SZachary Turner case SymbolKind::S_LTHREAD32:
293ee9906d8SZachary Turner case SymbolKind::S_GTHREAD32:
29468e1919dSZachary Turner case SymbolKind::S_PROCREF:
29568e1919dSZachary Turner case SymbolKind::S_LPROCREF:
296ee9906d8SZachary Turner return 10;
297ee9906d8SZachary Turner // See RegisterSym and LocalSym
298ee9906d8SZachary Turner case SymbolKind::S_REGISTER:
299ee9906d8SZachary Turner case SymbolKind::S_LOCAL:
300ee9906d8SZachary Turner return 6;
301ee9906d8SZachary Turner // See BlockSym
302ee9906d8SZachary Turner case SymbolKind::S_BLOCK32:
303ee9906d8SZachary Turner return 18;
304ee9906d8SZachary Turner // See LabelSym
305ee9906d8SZachary Turner case SymbolKind::S_LABEL32:
306ee9906d8SZachary Turner return 7;
307ee9906d8SZachary Turner // See ObjNameSym, ExportSym, and UDTSym
308ee9906d8SZachary Turner case SymbolKind::S_OBJNAME:
309ee9906d8SZachary Turner case SymbolKind::S_EXPORT:
310ee9906d8SZachary Turner case SymbolKind::S_UDT:
311ee9906d8SZachary Turner return 4;
312ee9906d8SZachary Turner // See BPRelativeSym
313ee9906d8SZachary Turner case SymbolKind::S_BPREL32:
314ee9906d8SZachary Turner return 8;
315ee8a7200SAlexandre Ganea // See UsingNamespaceSym
316ee8a7200SAlexandre Ganea case SymbolKind::S_UNAMESPACE:
317ee8a7200SAlexandre Ganea return 0;
318ee9906d8SZachary Turner default:
319ee9906d8SZachary Turner return -1;
320ee9906d8SZachary Turner }
321ee9906d8SZachary Turner }
322ee9906d8SZachary Turner
getSymbolName(CVSymbol Sym)323ee9906d8SZachary Turner StringRef llvm::codeview::getSymbolName(CVSymbol Sym) {
324ee9906d8SZachary Turner if (Sym.kind() == SymbolKind::S_CONSTANT) {
325ee9906d8SZachary Turner // S_CONSTANT is preceded by an APSInt, which has a variable length. So we
326ee9906d8SZachary Turner // have to do a full deserialization.
327ee9906d8SZachary Turner BinaryStreamReader Reader(Sym.content(), llvm::support::little);
328ee9906d8SZachary Turner // The container doesn't matter for single records.
329ee9906d8SZachary Turner SymbolRecordMapping Mapping(Reader, CodeViewContainer::ObjectFile);
330ee9906d8SZachary Turner ConstantSym Const(SymbolKind::S_CONSTANT);
331ee9906d8SZachary Turner cantFail(Mapping.visitSymbolBegin(Sym));
332ee9906d8SZachary Turner cantFail(Mapping.visitKnownRecord(Sym, Const));
333ee9906d8SZachary Turner cantFail(Mapping.visitSymbolEnd(Sym));
334ee9906d8SZachary Turner return Const.Name;
335ee9906d8SZachary Turner }
336ee9906d8SZachary Turner
337ee9906d8SZachary Turner int Offset = getSymbolNameOffset(Sym);
338ee9906d8SZachary Turner if (Offset == -1)
339ee9906d8SZachary Turner return StringRef();
340ee9906d8SZachary Turner
341ee9906d8SZachary Turner StringRef StringData = toStringRef(Sym.content()).drop_front(Offset);
342ee9906d8SZachary Turner return StringData.split('\0').first;
343ee9906d8SZachary Turner }
344