1044eb2f6SDimitry Andric //===- RecordName.cpp ----------------------------------------- *- C++ --*-===//
208bbd35aSDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
608bbd35aSDimitry Andric //
708bbd35aSDimitry Andric //===----------------------------------------------------------------------===//
808bbd35aSDimitry Andric
9044eb2f6SDimitry Andric #include "llvm/DebugInfo/CodeView/RecordName.h"
1008bbd35aSDimitry Andric
1108bbd35aSDimitry Andric #include "llvm/ADT/SmallString.h"
12b60736ecSDimitry Andric #include "llvm/ADT/StringExtras.h"
1308bbd35aSDimitry Andric #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
14145449b1SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h"
15145449b1SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
16044eb2f6SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
17145449b1SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeCollection.h"
18145449b1SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h"
19145449b1SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeRecord.h"
2008bbd35aSDimitry Andric #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
2108bbd35aSDimitry Andric #include "llvm/Support/FormatVariadic.h"
2208bbd35aSDimitry Andric
2308bbd35aSDimitry Andric using namespace llvm;
2408bbd35aSDimitry Andric using namespace llvm::codeview;
2508bbd35aSDimitry Andric
2608bbd35aSDimitry Andric namespace {
2708bbd35aSDimitry Andric class TypeNameComputer : public TypeVisitorCallbacks {
2808bbd35aSDimitry Andric /// The type collection. Used to calculate names of nested types.
2908bbd35aSDimitry Andric TypeCollection &Types;
3008bbd35aSDimitry Andric TypeIndex CurrentTypeIndex = TypeIndex::None();
3108bbd35aSDimitry Andric
3208bbd35aSDimitry Andric /// Name of the current type. Only valid before visitTypeEnd.
3308bbd35aSDimitry Andric SmallString<256> Name;
3408bbd35aSDimitry Andric
3508bbd35aSDimitry Andric public:
TypeNameComputer(TypeCollection & Types)3608bbd35aSDimitry Andric explicit TypeNameComputer(TypeCollection &Types) : Types(Types) {}
3708bbd35aSDimitry Andric
name() const3808bbd35aSDimitry Andric StringRef name() const { return Name; }
3908bbd35aSDimitry Andric
4008bbd35aSDimitry Andric /// Paired begin/end actions for all types. Receives all record data,
4108bbd35aSDimitry Andric /// including the fixed-length record prefix.
4208bbd35aSDimitry Andric Error visitTypeBegin(CVType &Record) override;
4308bbd35aSDimitry Andric Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
4408bbd35aSDimitry Andric Error visitTypeEnd(CVType &Record) override;
4508bbd35aSDimitry Andric
4608bbd35aSDimitry Andric #define TYPE_RECORD(EnumName, EnumVal, Name) \
4708bbd35aSDimitry Andric Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
4808bbd35aSDimitry Andric #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
4908bbd35aSDimitry Andric #define MEMBER_RECORD(EnumName, EnumVal, Name)
5008bbd35aSDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
5108bbd35aSDimitry Andric };
5208bbd35aSDimitry Andric } // namespace
5308bbd35aSDimitry Andric
visitTypeBegin(CVType & Record)5408bbd35aSDimitry Andric Error TypeNameComputer::visitTypeBegin(CVType &Record) {
5508bbd35aSDimitry Andric llvm_unreachable("Must call visitTypeBegin with a TypeIndex!");
5608bbd35aSDimitry Andric return Error::success();
5708bbd35aSDimitry Andric }
5808bbd35aSDimitry Andric
visitTypeBegin(CVType & Record,TypeIndex Index)5908bbd35aSDimitry Andric Error TypeNameComputer::visitTypeBegin(CVType &Record, TypeIndex Index) {
6008bbd35aSDimitry Andric // Reset Name to the empty string. If the visitor sets it, we know it.
6108bbd35aSDimitry Andric Name = "";
6208bbd35aSDimitry Andric CurrentTypeIndex = Index;
6308bbd35aSDimitry Andric return Error::success();
6408bbd35aSDimitry Andric }
6508bbd35aSDimitry Andric
visitTypeEnd(CVType & CVR)6608bbd35aSDimitry Andric Error TypeNameComputer::visitTypeEnd(CVType &CVR) { return Error::success(); }
6708bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,FieldListRecord & FieldList)6808bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
6908bbd35aSDimitry Andric FieldListRecord &FieldList) {
7008bbd35aSDimitry Andric Name = "<field list>";
7108bbd35aSDimitry Andric return Error::success();
7208bbd35aSDimitry Andric }
7308bbd35aSDimitry Andric
visitKnownRecord(CVRecord<TypeLeafKind> & CVR,StringIdRecord & String)7408bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
7508bbd35aSDimitry Andric StringIdRecord &String) {
7608bbd35aSDimitry Andric Name = String.getString();
7708bbd35aSDimitry Andric return Error::success();
7808bbd35aSDimitry Andric }
7908bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,ArgListRecord & Args)8008bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
8108bbd35aSDimitry Andric auto Indices = Args.getIndices();
8208bbd35aSDimitry Andric uint32_t Size = Indices.size();
8308bbd35aSDimitry Andric Name = "(";
8408bbd35aSDimitry Andric for (uint32_t I = 0; I < Size; ++I) {
85b60736ecSDimitry Andric if (Indices[I] < CurrentTypeIndex)
8608bbd35aSDimitry Andric Name.append(Types.getTypeName(Indices[I]));
87b60736ecSDimitry Andric else
88b60736ecSDimitry Andric Name.append("<unknown 0x" + utohexstr(Indices[I].getIndex()) + ">");
8908bbd35aSDimitry Andric if (I + 1 != Size)
9008bbd35aSDimitry Andric Name.append(", ");
9108bbd35aSDimitry Andric }
9208bbd35aSDimitry Andric Name.push_back(')');
9308bbd35aSDimitry Andric return Error::success();
9408bbd35aSDimitry Andric }
9508bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,StringListRecord & Strings)9608bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
9708bbd35aSDimitry Andric StringListRecord &Strings) {
9808bbd35aSDimitry Andric auto Indices = Strings.getIndices();
9908bbd35aSDimitry Andric uint32_t Size = Indices.size();
10008bbd35aSDimitry Andric Name = "\"";
10108bbd35aSDimitry Andric for (uint32_t I = 0; I < Size; ++I) {
10208bbd35aSDimitry Andric Name.append(Types.getTypeName(Indices[I]));
10308bbd35aSDimitry Andric if (I + 1 != Size)
10408bbd35aSDimitry Andric Name.append("\" \"");
10508bbd35aSDimitry Andric }
10608bbd35aSDimitry Andric Name.push_back('\"');
10708bbd35aSDimitry Andric return Error::success();
10808bbd35aSDimitry Andric }
10908bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,ClassRecord & Class)11008bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
11108bbd35aSDimitry Andric Name = Class.getName();
11208bbd35aSDimitry Andric return Error::success();
11308bbd35aSDimitry Andric }
11408bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,UnionRecord & Union)11508bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
11608bbd35aSDimitry Andric Name = Union.getName();
11708bbd35aSDimitry Andric return Error::success();
11808bbd35aSDimitry Andric }
11908bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,EnumRecord & Enum)12008bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
12108bbd35aSDimitry Andric Name = Enum.getName();
12208bbd35aSDimitry Andric return Error::success();
12308bbd35aSDimitry Andric }
12408bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,ArrayRecord & AT)12508bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
12608bbd35aSDimitry Andric Name = AT.getName();
12708bbd35aSDimitry Andric return Error::success();
12808bbd35aSDimitry Andric }
12908bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,VFTableRecord & VFT)13008bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) {
13108bbd35aSDimitry Andric Name = VFT.getName();
13208bbd35aSDimitry Andric return Error::success();
13308bbd35aSDimitry Andric }
13408bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,MemberFuncIdRecord & Id)13508bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) {
13608bbd35aSDimitry Andric Name = Id.getName();
13708bbd35aSDimitry Andric return Error::success();
13808bbd35aSDimitry Andric }
13908bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,ProcedureRecord & Proc)14008bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) {
14108bbd35aSDimitry Andric StringRef Ret = Types.getTypeName(Proc.getReturnType());
14208bbd35aSDimitry Andric StringRef Params = Types.getTypeName(Proc.getArgumentList());
14308bbd35aSDimitry Andric Name = formatv("{0} {1}", Ret, Params).sstr<256>();
14408bbd35aSDimitry Andric return Error::success();
14508bbd35aSDimitry Andric }
14608bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,MemberFunctionRecord & MF)14708bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
14808bbd35aSDimitry Andric MemberFunctionRecord &MF) {
14908bbd35aSDimitry Andric StringRef Ret = Types.getTypeName(MF.getReturnType());
15008bbd35aSDimitry Andric StringRef Class = Types.getTypeName(MF.getClassType());
15108bbd35aSDimitry Andric StringRef Params = Types.getTypeName(MF.getArgumentList());
15208bbd35aSDimitry Andric Name = formatv("{0} {1}::{2}", Ret, Class, Params).sstr<256>();
15308bbd35aSDimitry Andric return Error::success();
15408bbd35aSDimitry Andric }
15508bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,FuncIdRecord & Func)15608bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {
15708bbd35aSDimitry Andric Name = Func.getName();
15808bbd35aSDimitry Andric return Error::success();
15908bbd35aSDimitry Andric }
16008bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,TypeServer2Record & TS)16108bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) {
16208bbd35aSDimitry Andric Name = TS.getName();
16308bbd35aSDimitry Andric return Error::success();
16408bbd35aSDimitry Andric }
16508bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,PointerRecord & Ptr)16608bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
16708bbd35aSDimitry Andric
16808bbd35aSDimitry Andric if (Ptr.isPointerToMember()) {
16908bbd35aSDimitry Andric const MemberPointerInfo &MI = Ptr.getMemberInfo();
17008bbd35aSDimitry Andric
17108bbd35aSDimitry Andric StringRef Pointee = Types.getTypeName(Ptr.getReferentType());
17208bbd35aSDimitry Andric StringRef Class = Types.getTypeName(MI.getContainingType());
17308bbd35aSDimitry Andric Name = formatv("{0} {1}::*", Pointee, Class);
17408bbd35aSDimitry Andric } else {
17508bbd35aSDimitry Andric Name.append(Types.getTypeName(Ptr.getReferentType()));
17608bbd35aSDimitry Andric
17708bbd35aSDimitry Andric if (Ptr.getMode() == PointerMode::LValueReference)
17808bbd35aSDimitry Andric Name.append("&");
17908bbd35aSDimitry Andric else if (Ptr.getMode() == PointerMode::RValueReference)
18008bbd35aSDimitry Andric Name.append("&&");
18108bbd35aSDimitry Andric else if (Ptr.getMode() == PointerMode::Pointer)
18208bbd35aSDimitry Andric Name.append("*");
183eb11fae6SDimitry Andric
184eb11fae6SDimitry Andric // Qualifiers in pointer records apply to the pointer, not the pointee, so
185eb11fae6SDimitry Andric // they go on the right.
186eb11fae6SDimitry Andric if (Ptr.isConst())
187eb11fae6SDimitry Andric Name.append(" const");
188eb11fae6SDimitry Andric if (Ptr.isVolatile())
189eb11fae6SDimitry Andric Name.append(" volatile");
190eb11fae6SDimitry Andric if (Ptr.isUnaligned())
191eb11fae6SDimitry Andric Name.append(" __unaligned");
192eb11fae6SDimitry Andric if (Ptr.isRestrict())
193eb11fae6SDimitry Andric Name.append(" __restrict");
19408bbd35aSDimitry Andric }
19508bbd35aSDimitry Andric return Error::success();
19608bbd35aSDimitry Andric }
19708bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,ModifierRecord & Mod)19808bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
19908bbd35aSDimitry Andric uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
20008bbd35aSDimitry Andric
20108bbd35aSDimitry Andric if (Mods & uint16_t(ModifierOptions::Const))
20208bbd35aSDimitry Andric Name.append("const ");
20308bbd35aSDimitry Andric if (Mods & uint16_t(ModifierOptions::Volatile))
20408bbd35aSDimitry Andric Name.append("volatile ");
20508bbd35aSDimitry Andric if (Mods & uint16_t(ModifierOptions::Unaligned))
20608bbd35aSDimitry Andric Name.append("__unaligned ");
20708bbd35aSDimitry Andric Name.append(Types.getTypeName(Mod.getModifiedType()));
20808bbd35aSDimitry Andric return Error::success();
20908bbd35aSDimitry Andric }
21008bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,VFTableShapeRecord & Shape)21108bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
21208bbd35aSDimitry Andric VFTableShapeRecord &Shape) {
21308bbd35aSDimitry Andric Name = formatv("<vftable {0} methods>", Shape.getEntryCount());
21408bbd35aSDimitry Andric return Error::success();
21508bbd35aSDimitry Andric }
21608bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,UdtModSourceLineRecord & ModSourceLine)21708bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(
21808bbd35aSDimitry Andric CVType &CVR, UdtModSourceLineRecord &ModSourceLine) {
21908bbd35aSDimitry Andric return Error::success();
22008bbd35aSDimitry Andric }
22108bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,UdtSourceLineRecord & SourceLine)22208bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
22308bbd35aSDimitry Andric UdtSourceLineRecord &SourceLine) {
22408bbd35aSDimitry Andric return Error::success();
22508bbd35aSDimitry Andric }
22608bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,BitFieldRecord & BF)22708bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, BitFieldRecord &BF) {
22808bbd35aSDimitry Andric return Error::success();
22908bbd35aSDimitry Andric }
23008bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,MethodOverloadListRecord & Overloads)23108bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
23208bbd35aSDimitry Andric MethodOverloadListRecord &Overloads) {
23308bbd35aSDimitry Andric return Error::success();
23408bbd35aSDimitry Andric }
23508bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,BuildInfoRecord & BI)23608bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, BuildInfoRecord &BI) {
23708bbd35aSDimitry Andric return Error::success();
23808bbd35aSDimitry Andric }
23908bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,LabelRecord & R)24008bbd35aSDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, LabelRecord &R) {
24108bbd35aSDimitry Andric return Error::success();
24208bbd35aSDimitry Andric }
24308bbd35aSDimitry Andric
visitKnownRecord(CVType & CVR,PrecompRecord & Precomp)244eb11fae6SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
245eb11fae6SDimitry Andric PrecompRecord &Precomp) {
246eb11fae6SDimitry Andric return Error::success();
247eb11fae6SDimitry Andric }
248eb11fae6SDimitry Andric
visitKnownRecord(CVType & CVR,EndPrecompRecord & EndPrecomp)249eb11fae6SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
250eb11fae6SDimitry Andric EndPrecompRecord &EndPrecomp) {
251eb11fae6SDimitry Andric return Error::success();
252eb11fae6SDimitry Andric }
253eb11fae6SDimitry Andric
computeTypeName(TypeCollection & Types,TypeIndex Index)25408bbd35aSDimitry Andric std::string llvm::codeview::computeTypeName(TypeCollection &Types,
25508bbd35aSDimitry Andric TypeIndex Index) {
25608bbd35aSDimitry Andric TypeNameComputer Computer(Types);
25708bbd35aSDimitry Andric CVType Record = Types.getType(Index);
25808bbd35aSDimitry Andric if (auto EC = visitTypeRecord(Record, Index, Computer)) {
25908bbd35aSDimitry Andric consumeError(std::move(EC));
26008bbd35aSDimitry Andric return "<unknown UDT>";
26108bbd35aSDimitry Andric }
262cfca06d7SDimitry Andric return std::string(Computer.name());
26308bbd35aSDimitry Andric }
264044eb2f6SDimitry Andric
getSymbolNameOffset(CVSymbol Sym)265044eb2f6SDimitry Andric static int getSymbolNameOffset(CVSymbol Sym) {
266044eb2f6SDimitry Andric switch (Sym.kind()) {
267044eb2f6SDimitry Andric // See ProcSym
268044eb2f6SDimitry Andric case SymbolKind::S_GPROC32:
269044eb2f6SDimitry Andric case SymbolKind::S_LPROC32:
270044eb2f6SDimitry Andric case SymbolKind::S_GPROC32_ID:
271044eb2f6SDimitry Andric case SymbolKind::S_LPROC32_ID:
272044eb2f6SDimitry Andric case SymbolKind::S_LPROC32_DPC:
273044eb2f6SDimitry Andric case SymbolKind::S_LPROC32_DPC_ID:
274044eb2f6SDimitry Andric return 35;
275044eb2f6SDimitry Andric // See Thunk32Sym
276044eb2f6SDimitry Andric case SymbolKind::S_THUNK32:
277044eb2f6SDimitry Andric return 21;
278044eb2f6SDimitry Andric // See SectionSym
279044eb2f6SDimitry Andric case SymbolKind::S_SECTION:
280044eb2f6SDimitry Andric return 16;
281044eb2f6SDimitry Andric // See CoffGroupSym
282044eb2f6SDimitry Andric case SymbolKind::S_COFFGROUP:
283044eb2f6SDimitry Andric return 14;
284044eb2f6SDimitry Andric // See PublicSym32, FileStaticSym, RegRelativeSym, DataSym, ThreadLocalDataSym
285044eb2f6SDimitry Andric case SymbolKind::S_PUB32:
286044eb2f6SDimitry Andric case SymbolKind::S_FILESTATIC:
287044eb2f6SDimitry Andric case SymbolKind::S_REGREL32:
288044eb2f6SDimitry Andric case SymbolKind::S_GDATA32:
289044eb2f6SDimitry Andric case SymbolKind::S_LDATA32:
290044eb2f6SDimitry Andric case SymbolKind::S_LMANDATA:
291044eb2f6SDimitry Andric case SymbolKind::S_GMANDATA:
292044eb2f6SDimitry Andric case SymbolKind::S_LTHREAD32:
293044eb2f6SDimitry Andric case SymbolKind::S_GTHREAD32:
294eb11fae6SDimitry Andric case SymbolKind::S_PROCREF:
295eb11fae6SDimitry Andric case SymbolKind::S_LPROCREF:
296044eb2f6SDimitry Andric return 10;
297044eb2f6SDimitry Andric // See RegisterSym and LocalSym
298044eb2f6SDimitry Andric case SymbolKind::S_REGISTER:
299044eb2f6SDimitry Andric case SymbolKind::S_LOCAL:
300044eb2f6SDimitry Andric return 6;
301044eb2f6SDimitry Andric // See BlockSym
302044eb2f6SDimitry Andric case SymbolKind::S_BLOCK32:
303044eb2f6SDimitry Andric return 18;
304044eb2f6SDimitry Andric // See LabelSym
305044eb2f6SDimitry Andric case SymbolKind::S_LABEL32:
306044eb2f6SDimitry Andric return 7;
307044eb2f6SDimitry Andric // See ObjNameSym, ExportSym, and UDTSym
308044eb2f6SDimitry Andric case SymbolKind::S_OBJNAME:
309044eb2f6SDimitry Andric case SymbolKind::S_EXPORT:
310044eb2f6SDimitry Andric case SymbolKind::S_UDT:
311044eb2f6SDimitry Andric return 4;
312044eb2f6SDimitry Andric // See BPRelativeSym
313044eb2f6SDimitry Andric case SymbolKind::S_BPREL32:
314044eb2f6SDimitry Andric return 8;
315b7eb8e35SDimitry Andric // See UsingNamespaceSym
316b7eb8e35SDimitry Andric case SymbolKind::S_UNAMESPACE:
317b7eb8e35SDimitry Andric return 0;
318044eb2f6SDimitry Andric default:
319044eb2f6SDimitry Andric return -1;
320044eb2f6SDimitry Andric }
321044eb2f6SDimitry Andric }
322044eb2f6SDimitry Andric
getSymbolName(CVSymbol Sym)323044eb2f6SDimitry Andric StringRef llvm::codeview::getSymbolName(CVSymbol Sym) {
324044eb2f6SDimitry Andric if (Sym.kind() == SymbolKind::S_CONSTANT) {
325044eb2f6SDimitry Andric // S_CONSTANT is preceded by an APSInt, which has a variable length. So we
326044eb2f6SDimitry Andric // have to do a full deserialization.
327b1c73532SDimitry Andric BinaryStreamReader Reader(Sym.content(), llvm::endianness::little);
328044eb2f6SDimitry Andric // The container doesn't matter for single records.
329044eb2f6SDimitry Andric SymbolRecordMapping Mapping(Reader, CodeViewContainer::ObjectFile);
330044eb2f6SDimitry Andric ConstantSym Const(SymbolKind::S_CONSTANT);
331044eb2f6SDimitry Andric cantFail(Mapping.visitSymbolBegin(Sym));
332044eb2f6SDimitry Andric cantFail(Mapping.visitKnownRecord(Sym, Const));
333044eb2f6SDimitry Andric cantFail(Mapping.visitSymbolEnd(Sym));
334044eb2f6SDimitry Andric return Const.Name;
335044eb2f6SDimitry Andric }
336044eb2f6SDimitry Andric
337044eb2f6SDimitry Andric int Offset = getSymbolNameOffset(Sym);
338044eb2f6SDimitry Andric if (Offset == -1)
339044eb2f6SDimitry Andric return StringRef();
340044eb2f6SDimitry Andric
341044eb2f6SDimitry Andric StringRef StringData = toStringRef(Sym.content()).drop_front(Offset);
342044eb2f6SDimitry Andric return StringData.split('\0').first;
343044eb2f6SDimitry Andric }
344