10b57cec5SDimitry Andric //===- RecordName.cpp ----------------------------------------- *- C++ --*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/RecordName.h"
100b57cec5SDimitry Andric
110b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
12e8d8bef9SDimitry Andric #include "llvm/ADT/StringExtras.h"
130b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
1481ad6265SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h"
1581ad6265SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
160b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
1781ad6265SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeCollection.h"
1881ad6265SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h"
1981ad6265SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeRecord.h"
200b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
210b57cec5SDimitry Andric #include "llvm/Support/FormatVariadic.h"
220b57cec5SDimitry Andric
230b57cec5SDimitry Andric using namespace llvm;
240b57cec5SDimitry Andric using namespace llvm::codeview;
250b57cec5SDimitry Andric
260b57cec5SDimitry Andric namespace {
270b57cec5SDimitry Andric class TypeNameComputer : public TypeVisitorCallbacks {
280b57cec5SDimitry Andric /// The type collection. Used to calculate names of nested types.
290b57cec5SDimitry Andric TypeCollection &Types;
300b57cec5SDimitry Andric TypeIndex CurrentTypeIndex = TypeIndex::None();
310b57cec5SDimitry Andric
320b57cec5SDimitry Andric /// Name of the current type. Only valid before visitTypeEnd.
330b57cec5SDimitry Andric SmallString<256> Name;
340b57cec5SDimitry Andric
350b57cec5SDimitry Andric public:
TypeNameComputer(TypeCollection & Types)360b57cec5SDimitry Andric explicit TypeNameComputer(TypeCollection &Types) : Types(Types) {}
370b57cec5SDimitry Andric
name() const380b57cec5SDimitry Andric StringRef name() const { return Name; }
390b57cec5SDimitry Andric
400b57cec5SDimitry Andric /// Paired begin/end actions for all types. Receives all record data,
410b57cec5SDimitry Andric /// including the fixed-length record prefix.
420b57cec5SDimitry Andric Error visitTypeBegin(CVType &Record) override;
430b57cec5SDimitry Andric Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
440b57cec5SDimitry Andric Error visitTypeEnd(CVType &Record) override;
450b57cec5SDimitry Andric
460b57cec5SDimitry Andric #define TYPE_RECORD(EnumName, EnumVal, Name) \
470b57cec5SDimitry Andric Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
480b57cec5SDimitry Andric #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
490b57cec5SDimitry Andric #define MEMBER_RECORD(EnumName, EnumVal, Name)
500b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
510b57cec5SDimitry Andric };
520b57cec5SDimitry Andric } // namespace
530b57cec5SDimitry Andric
visitTypeBegin(CVType & Record)540b57cec5SDimitry Andric Error TypeNameComputer::visitTypeBegin(CVType &Record) {
550b57cec5SDimitry Andric llvm_unreachable("Must call visitTypeBegin with a TypeIndex!");
560b57cec5SDimitry Andric return Error::success();
570b57cec5SDimitry Andric }
580b57cec5SDimitry Andric
visitTypeBegin(CVType & Record,TypeIndex Index)590b57cec5SDimitry Andric Error TypeNameComputer::visitTypeBegin(CVType &Record, TypeIndex Index) {
600b57cec5SDimitry Andric // Reset Name to the empty string. If the visitor sets it, we know it.
610b57cec5SDimitry Andric Name = "";
620b57cec5SDimitry Andric CurrentTypeIndex = Index;
630b57cec5SDimitry Andric return Error::success();
640b57cec5SDimitry Andric }
650b57cec5SDimitry Andric
visitTypeEnd(CVType & CVR)660b57cec5SDimitry Andric Error TypeNameComputer::visitTypeEnd(CVType &CVR) { return Error::success(); }
670b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,FieldListRecord & FieldList)680b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
690b57cec5SDimitry Andric FieldListRecord &FieldList) {
700b57cec5SDimitry Andric Name = "<field list>";
710b57cec5SDimitry Andric return Error::success();
720b57cec5SDimitry Andric }
730b57cec5SDimitry Andric
visitKnownRecord(CVRecord<TypeLeafKind> & CVR,StringIdRecord & String)740b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
750b57cec5SDimitry Andric StringIdRecord &String) {
760b57cec5SDimitry Andric Name = String.getString();
770b57cec5SDimitry Andric return Error::success();
780b57cec5SDimitry Andric }
790b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,ArgListRecord & Args)800b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
810b57cec5SDimitry Andric auto Indices = Args.getIndices();
820b57cec5SDimitry Andric uint32_t Size = Indices.size();
830b57cec5SDimitry Andric Name = "(";
840b57cec5SDimitry Andric for (uint32_t I = 0; I < Size; ++I) {
85e8d8bef9SDimitry Andric if (Indices[I] < CurrentTypeIndex)
860b57cec5SDimitry Andric Name.append(Types.getTypeName(Indices[I]));
87e8d8bef9SDimitry Andric else
88e8d8bef9SDimitry Andric Name.append("<unknown 0x" + utohexstr(Indices[I].getIndex()) + ">");
890b57cec5SDimitry Andric if (I + 1 != Size)
900b57cec5SDimitry Andric Name.append(", ");
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric Name.push_back(')');
930b57cec5SDimitry Andric return Error::success();
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,StringListRecord & Strings)960b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
970b57cec5SDimitry Andric StringListRecord &Strings) {
980b57cec5SDimitry Andric auto Indices = Strings.getIndices();
990b57cec5SDimitry Andric uint32_t Size = Indices.size();
1000b57cec5SDimitry Andric Name = "\"";
1010b57cec5SDimitry Andric for (uint32_t I = 0; I < Size; ++I) {
1020b57cec5SDimitry Andric Name.append(Types.getTypeName(Indices[I]));
1030b57cec5SDimitry Andric if (I + 1 != Size)
1040b57cec5SDimitry Andric Name.append("\" \"");
1050b57cec5SDimitry Andric }
1060b57cec5SDimitry Andric Name.push_back('\"');
1070b57cec5SDimitry Andric return Error::success();
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,ClassRecord & Class)1100b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
1110b57cec5SDimitry Andric Name = Class.getName();
1120b57cec5SDimitry Andric return Error::success();
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,UnionRecord & Union)1150b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
1160b57cec5SDimitry Andric Name = Union.getName();
1170b57cec5SDimitry Andric return Error::success();
1180b57cec5SDimitry Andric }
1190b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,EnumRecord & Enum)1200b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
1210b57cec5SDimitry Andric Name = Enum.getName();
1220b57cec5SDimitry Andric return Error::success();
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,ArrayRecord & AT)1250b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
1260b57cec5SDimitry Andric Name = AT.getName();
1270b57cec5SDimitry Andric return Error::success();
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,VFTableRecord & VFT)1300b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) {
1310b57cec5SDimitry Andric Name = VFT.getName();
1320b57cec5SDimitry Andric return Error::success();
1330b57cec5SDimitry Andric }
1340b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,MemberFuncIdRecord & Id)1350b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) {
1360b57cec5SDimitry Andric Name = Id.getName();
1370b57cec5SDimitry Andric return Error::success();
1380b57cec5SDimitry Andric }
1390b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,ProcedureRecord & Proc)1400b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) {
1410b57cec5SDimitry Andric StringRef Ret = Types.getTypeName(Proc.getReturnType());
1420b57cec5SDimitry Andric StringRef Params = Types.getTypeName(Proc.getArgumentList());
1430b57cec5SDimitry Andric Name = formatv("{0} {1}", Ret, Params).sstr<256>();
1440b57cec5SDimitry Andric return Error::success();
1450b57cec5SDimitry Andric }
1460b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,MemberFunctionRecord & MF)1470b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
1480b57cec5SDimitry Andric MemberFunctionRecord &MF) {
1490b57cec5SDimitry Andric StringRef Ret = Types.getTypeName(MF.getReturnType());
1500b57cec5SDimitry Andric StringRef Class = Types.getTypeName(MF.getClassType());
1510b57cec5SDimitry Andric StringRef Params = Types.getTypeName(MF.getArgumentList());
1520b57cec5SDimitry Andric Name = formatv("{0} {1}::{2}", Ret, Class, Params).sstr<256>();
1530b57cec5SDimitry Andric return Error::success();
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,FuncIdRecord & Func)1560b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {
1570b57cec5SDimitry Andric Name = Func.getName();
1580b57cec5SDimitry Andric return Error::success();
1590b57cec5SDimitry Andric }
1600b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,TypeServer2Record & TS)1610b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) {
1620b57cec5SDimitry Andric Name = TS.getName();
1630b57cec5SDimitry Andric return Error::success();
1640b57cec5SDimitry Andric }
1650b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,PointerRecord & Ptr)1660b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
1670b57cec5SDimitry Andric
1680b57cec5SDimitry Andric if (Ptr.isPointerToMember()) {
1690b57cec5SDimitry Andric const MemberPointerInfo &MI = Ptr.getMemberInfo();
1700b57cec5SDimitry Andric
1710b57cec5SDimitry Andric StringRef Pointee = Types.getTypeName(Ptr.getReferentType());
1720b57cec5SDimitry Andric StringRef Class = Types.getTypeName(MI.getContainingType());
1730b57cec5SDimitry Andric Name = formatv("{0} {1}::*", Pointee, Class);
1740b57cec5SDimitry Andric } else {
1750b57cec5SDimitry Andric Name.append(Types.getTypeName(Ptr.getReferentType()));
1760b57cec5SDimitry Andric
1770b57cec5SDimitry Andric if (Ptr.getMode() == PointerMode::LValueReference)
1780b57cec5SDimitry Andric Name.append("&");
1790b57cec5SDimitry Andric else if (Ptr.getMode() == PointerMode::RValueReference)
1800b57cec5SDimitry Andric Name.append("&&");
1810b57cec5SDimitry Andric else if (Ptr.getMode() == PointerMode::Pointer)
1820b57cec5SDimitry Andric Name.append("*");
1830b57cec5SDimitry Andric
1840b57cec5SDimitry Andric // Qualifiers in pointer records apply to the pointer, not the pointee, so
1850b57cec5SDimitry Andric // they go on the right.
1860b57cec5SDimitry Andric if (Ptr.isConst())
1870b57cec5SDimitry Andric Name.append(" const");
1880b57cec5SDimitry Andric if (Ptr.isVolatile())
1890b57cec5SDimitry Andric Name.append(" volatile");
1900b57cec5SDimitry Andric if (Ptr.isUnaligned())
1910b57cec5SDimitry Andric Name.append(" __unaligned");
1920b57cec5SDimitry Andric if (Ptr.isRestrict())
1930b57cec5SDimitry Andric Name.append(" __restrict");
1940b57cec5SDimitry Andric }
1950b57cec5SDimitry Andric return Error::success();
1960b57cec5SDimitry Andric }
1970b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,ModifierRecord & Mod)1980b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
1990b57cec5SDimitry Andric uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
2000b57cec5SDimitry Andric
2010b57cec5SDimitry Andric if (Mods & uint16_t(ModifierOptions::Const))
2020b57cec5SDimitry Andric Name.append("const ");
2030b57cec5SDimitry Andric if (Mods & uint16_t(ModifierOptions::Volatile))
2040b57cec5SDimitry Andric Name.append("volatile ");
2050b57cec5SDimitry Andric if (Mods & uint16_t(ModifierOptions::Unaligned))
2060b57cec5SDimitry Andric Name.append("__unaligned ");
2070b57cec5SDimitry Andric Name.append(Types.getTypeName(Mod.getModifiedType()));
2080b57cec5SDimitry Andric return Error::success();
2090b57cec5SDimitry Andric }
2100b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,VFTableShapeRecord & Shape)2110b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
2120b57cec5SDimitry Andric VFTableShapeRecord &Shape) {
2130b57cec5SDimitry Andric Name = formatv("<vftable {0} methods>", Shape.getEntryCount());
2140b57cec5SDimitry Andric return Error::success();
2150b57cec5SDimitry Andric }
2160b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,UdtModSourceLineRecord & ModSourceLine)2170b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(
2180b57cec5SDimitry Andric CVType &CVR, UdtModSourceLineRecord &ModSourceLine) {
2190b57cec5SDimitry Andric return Error::success();
2200b57cec5SDimitry Andric }
2210b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,UdtSourceLineRecord & SourceLine)2220b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
2230b57cec5SDimitry Andric UdtSourceLineRecord &SourceLine) {
2240b57cec5SDimitry Andric return Error::success();
2250b57cec5SDimitry Andric }
2260b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,BitFieldRecord & BF)2270b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, BitFieldRecord &BF) {
2280b57cec5SDimitry Andric return Error::success();
2290b57cec5SDimitry Andric }
2300b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,MethodOverloadListRecord & Overloads)2310b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
2320b57cec5SDimitry Andric MethodOverloadListRecord &Overloads) {
2330b57cec5SDimitry Andric return Error::success();
2340b57cec5SDimitry Andric }
2350b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,BuildInfoRecord & BI)2360b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, BuildInfoRecord &BI) {
2370b57cec5SDimitry Andric return Error::success();
2380b57cec5SDimitry Andric }
2390b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,LabelRecord & R)2400b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR, LabelRecord &R) {
2410b57cec5SDimitry Andric return Error::success();
2420b57cec5SDimitry Andric }
2430b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,PrecompRecord & Precomp)2440b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
2450b57cec5SDimitry Andric PrecompRecord &Precomp) {
2460b57cec5SDimitry Andric return Error::success();
2470b57cec5SDimitry Andric }
2480b57cec5SDimitry Andric
visitKnownRecord(CVType & CVR,EndPrecompRecord & EndPrecomp)2490b57cec5SDimitry Andric Error TypeNameComputer::visitKnownRecord(CVType &CVR,
2500b57cec5SDimitry Andric EndPrecompRecord &EndPrecomp) {
2510b57cec5SDimitry Andric return Error::success();
2520b57cec5SDimitry Andric }
2530b57cec5SDimitry Andric
computeTypeName(TypeCollection & Types,TypeIndex Index)2540b57cec5SDimitry Andric std::string llvm::codeview::computeTypeName(TypeCollection &Types,
2550b57cec5SDimitry Andric TypeIndex Index) {
2560b57cec5SDimitry Andric TypeNameComputer Computer(Types);
2570b57cec5SDimitry Andric CVType Record = Types.getType(Index);
2580b57cec5SDimitry Andric if (auto EC = visitTypeRecord(Record, Index, Computer)) {
2590b57cec5SDimitry Andric consumeError(std::move(EC));
2600b57cec5SDimitry Andric return "<unknown UDT>";
2610b57cec5SDimitry Andric }
2625ffd83dbSDimitry Andric return std::string(Computer.name());
2630b57cec5SDimitry Andric }
2640b57cec5SDimitry Andric
getSymbolNameOffset(CVSymbol Sym)2650b57cec5SDimitry Andric static int getSymbolNameOffset(CVSymbol Sym) {
2660b57cec5SDimitry Andric switch (Sym.kind()) {
2670b57cec5SDimitry Andric // See ProcSym
2680b57cec5SDimitry Andric case SymbolKind::S_GPROC32:
2690b57cec5SDimitry Andric case SymbolKind::S_LPROC32:
2700b57cec5SDimitry Andric case SymbolKind::S_GPROC32_ID:
2710b57cec5SDimitry Andric case SymbolKind::S_LPROC32_ID:
2720b57cec5SDimitry Andric case SymbolKind::S_LPROC32_DPC:
2730b57cec5SDimitry Andric case SymbolKind::S_LPROC32_DPC_ID:
2740b57cec5SDimitry Andric return 35;
2750b57cec5SDimitry Andric // See Thunk32Sym
2760b57cec5SDimitry Andric case SymbolKind::S_THUNK32:
2770b57cec5SDimitry Andric return 21;
2780b57cec5SDimitry Andric // See SectionSym
2790b57cec5SDimitry Andric case SymbolKind::S_SECTION:
2800b57cec5SDimitry Andric return 16;
2810b57cec5SDimitry Andric // See CoffGroupSym
2820b57cec5SDimitry Andric case SymbolKind::S_COFFGROUP:
2830b57cec5SDimitry Andric return 14;
2840b57cec5SDimitry Andric // See PublicSym32, FileStaticSym, RegRelativeSym, DataSym, ThreadLocalDataSym
2850b57cec5SDimitry Andric case SymbolKind::S_PUB32:
2860b57cec5SDimitry Andric case SymbolKind::S_FILESTATIC:
2870b57cec5SDimitry Andric case SymbolKind::S_REGREL32:
2880b57cec5SDimitry Andric case SymbolKind::S_GDATA32:
2890b57cec5SDimitry Andric case SymbolKind::S_LDATA32:
2900b57cec5SDimitry Andric case SymbolKind::S_LMANDATA:
2910b57cec5SDimitry Andric case SymbolKind::S_GMANDATA:
2920b57cec5SDimitry Andric case SymbolKind::S_LTHREAD32:
2930b57cec5SDimitry Andric case SymbolKind::S_GTHREAD32:
2940b57cec5SDimitry Andric case SymbolKind::S_PROCREF:
2950b57cec5SDimitry Andric case SymbolKind::S_LPROCREF:
2960b57cec5SDimitry Andric return 10;
2970b57cec5SDimitry Andric // See RegisterSym and LocalSym
2980b57cec5SDimitry Andric case SymbolKind::S_REGISTER:
2990b57cec5SDimitry Andric case SymbolKind::S_LOCAL:
3000b57cec5SDimitry Andric return 6;
3010b57cec5SDimitry Andric // See BlockSym
3020b57cec5SDimitry Andric case SymbolKind::S_BLOCK32:
3030b57cec5SDimitry Andric return 18;
3040b57cec5SDimitry Andric // See LabelSym
3050b57cec5SDimitry Andric case SymbolKind::S_LABEL32:
3060b57cec5SDimitry Andric return 7;
3070b57cec5SDimitry Andric // See ObjNameSym, ExportSym, and UDTSym
3080b57cec5SDimitry Andric case SymbolKind::S_OBJNAME:
3090b57cec5SDimitry Andric case SymbolKind::S_EXPORT:
3100b57cec5SDimitry Andric case SymbolKind::S_UDT:
3110b57cec5SDimitry Andric return 4;
3120b57cec5SDimitry Andric // See BPRelativeSym
3130b57cec5SDimitry Andric case SymbolKind::S_BPREL32:
3140b57cec5SDimitry Andric return 8;
3150b57cec5SDimitry Andric // See UsingNamespaceSym
3160b57cec5SDimitry Andric case SymbolKind::S_UNAMESPACE:
3170b57cec5SDimitry Andric return 0;
3180b57cec5SDimitry Andric default:
3190b57cec5SDimitry Andric return -1;
3200b57cec5SDimitry Andric }
3210b57cec5SDimitry Andric }
3220b57cec5SDimitry Andric
getSymbolName(CVSymbol Sym)3230b57cec5SDimitry Andric StringRef llvm::codeview::getSymbolName(CVSymbol Sym) {
3240b57cec5SDimitry Andric if (Sym.kind() == SymbolKind::S_CONSTANT) {
3250b57cec5SDimitry Andric // S_CONSTANT is preceded by an APSInt, which has a variable length. So we
3260b57cec5SDimitry Andric // have to do a full deserialization.
327*5f757f3fSDimitry Andric BinaryStreamReader Reader(Sym.content(), llvm::endianness::little);
3280b57cec5SDimitry Andric // The container doesn't matter for single records.
3290b57cec5SDimitry Andric SymbolRecordMapping Mapping(Reader, CodeViewContainer::ObjectFile);
3300b57cec5SDimitry Andric ConstantSym Const(SymbolKind::S_CONSTANT);
3310b57cec5SDimitry Andric cantFail(Mapping.visitSymbolBegin(Sym));
3320b57cec5SDimitry Andric cantFail(Mapping.visitKnownRecord(Sym, Const));
3330b57cec5SDimitry Andric cantFail(Mapping.visitSymbolEnd(Sym));
3340b57cec5SDimitry Andric return Const.Name;
3350b57cec5SDimitry Andric }
3360b57cec5SDimitry Andric
3370b57cec5SDimitry Andric int Offset = getSymbolNameOffset(Sym);
3380b57cec5SDimitry Andric if (Offset == -1)
3390b57cec5SDimitry Andric return StringRef();
3400b57cec5SDimitry Andric
3410b57cec5SDimitry Andric StringRef StringData = toStringRef(Sym.content()).drop_front(Offset);
3420b57cec5SDimitry Andric return StringData.split('\0').first;
3430b57cec5SDimitry Andric }
344