LLVM  13.0.0git
RecordName.cpp
Go to the documentation of this file.
1 //===- RecordName.cpp ----------------------------------------- *- C++ --*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringExtras.h"
18 
19 using namespace llvm;
20 using namespace llvm::codeview;
21 
22 namespace {
23 class TypeNameComputer : public TypeVisitorCallbacks {
24  /// The type collection. Used to calculate names of nested types.
25  TypeCollection &Types;
26  TypeIndex CurrentTypeIndex = TypeIndex::None();
27 
28  /// Name of the current type. Only valid before visitTypeEnd.
30 
31 public:
32  explicit TypeNameComputer(TypeCollection &Types) : Types(Types) {}
33 
34  StringRef name() const { return Name; }
35 
36  /// Paired begin/end actions for all types. Receives all record data,
37  /// including the fixed-length record prefix.
38  Error visitTypeBegin(CVType &Record) override;
39  Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
40  Error visitTypeEnd(CVType &Record) override;
41 
42 #define TYPE_RECORD(EnumName, EnumVal, Name) \
43  Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
44 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
45 #define MEMBER_RECORD(EnumName, EnumVal, Name)
46 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
47 };
48 } // namespace
49 
50 Error TypeNameComputer::visitTypeBegin(CVType &Record) {
51  llvm_unreachable("Must call visitTypeBegin with a TypeIndex!");
52  return Error::success();
53 }
54 
55 Error TypeNameComputer::visitTypeBegin(CVType &Record, TypeIndex Index) {
56  // Reset Name to the empty string. If the visitor sets it, we know it.
57  Name = "";
58  CurrentTypeIndex = Index;
59  return Error::success();
60 }
61 
62 Error TypeNameComputer::visitTypeEnd(CVType &CVR) { return Error::success(); }
63 
65  FieldListRecord &FieldList) {
66  Name = "<field list>";
67  return Error::success();
68 }
69 
71  StringIdRecord &String) {
72  Name = String.getString();
73  return Error::success();
74 }
75 
77  auto Indices = Args.getIndices();
78  uint32_t Size = Indices.size();
79  Name = "(";
80  for (uint32_t I = 0; I < Size; ++I) {
81  if (Indices[I] < CurrentTypeIndex)
82  Name.append(Types.getTypeName(Indices[I]));
83  else
84  Name.append("<unknown 0x" + utohexstr(Indices[I].getIndex()) + ">");
85  if (I + 1 != Size)
86  Name.append(", ");
87  }
88  Name.push_back(')');
89  return Error::success();
90 }
91 
93  StringListRecord &Strings) {
94  auto Indices = Strings.getIndices();
95  uint32_t Size = Indices.size();
96  Name = "\"";
97  for (uint32_t I = 0; I < Size; ++I) {
98  Name.append(Types.getTypeName(Indices[I]));
99  if (I + 1 != Size)
100  Name.append("\" \"");
101  }
102  Name.push_back('\"');
103  return Error::success();
104 }
105 
107  Name = Class.getName();
108  return Error::success();
109 }
110 
112  Name = Union.getName();
113  return Error::success();
114 }
115 
117  Name = Enum.getName();
118  return Error::success();
119 }
120 
122  Name = AT.getName();
123  return Error::success();
124 }
125 
127  Name = VFT.getName();
128  return Error::success();
129 }
130 
132  Name = Id.getName();
133  return Error::success();
134 }
135 
137  StringRef Ret = Types.getTypeName(Proc.getReturnType());
138  StringRef Params = Types.getTypeName(Proc.getArgumentList());
139  Name = formatv("{0} {1}", Ret, Params).sstr<256>();
140  return Error::success();
141 }
142 
144  MemberFunctionRecord &MF) {
145  StringRef Ret = Types.getTypeName(MF.getReturnType());
146  StringRef Class = Types.getTypeName(MF.getClassType());
147  StringRef Params = Types.getTypeName(MF.getArgumentList());
148  Name = formatv("{0} {1}::{2}", Ret, Class, Params).sstr<256>();
149  return Error::success();
150 }
151 
153  Name = Func.getName();
154  return Error::success();
155 }
156 
158  Name = TS.getName();
159  return Error::success();
160 }
161 
163 
164  if (Ptr.isPointerToMember()) {
165  const MemberPointerInfo &MI = Ptr.getMemberInfo();
166 
167  StringRef Pointee = Types.getTypeName(Ptr.getReferentType());
168  StringRef Class = Types.getTypeName(MI.getContainingType());
169  Name = formatv("{0} {1}::*", Pointee, Class);
170  } else {
171  Name.append(Types.getTypeName(Ptr.getReferentType()));
172 
174  Name.append("&");
175  else if (Ptr.getMode() == PointerMode::RValueReference)
176  Name.append("&&");
177  else if (Ptr.getMode() == PointerMode::Pointer)
178  Name.append("*");
179 
180  // Qualifiers in pointer records apply to the pointer, not the pointee, so
181  // they go on the right.
182  if (Ptr.isConst())
183  Name.append(" const");
184  if (Ptr.isVolatile())
185  Name.append(" volatile");
186  if (Ptr.isUnaligned())
187  Name.append(" __unaligned");
188  if (Ptr.isRestrict())
189  Name.append(" __restrict");
190  }
191  return Error::success();
192 }
193 
195  uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
196 
197  if (Mods & uint16_t(ModifierOptions::Const))
198  Name.append("const ");
200  Name.append("volatile ");
202  Name.append("__unaligned ");
203  Name.append(Types.getTypeName(Mod.getModifiedType()));
204  return Error::success();
205 }
206 
208  VFTableShapeRecord &Shape) {
209  Name = formatv("<vftable {0} methods>", Shape.getEntryCount());
210  return Error::success();
211 }
212 
214  CVType &CVR, UdtModSourceLineRecord &ModSourceLine) {
215  return Error::success();
216 }
217 
219  UdtSourceLineRecord &SourceLine) {
220  return Error::success();
221 }
222 
224  return Error::success();
225 }
226 
228  MethodOverloadListRecord &Overloads) {
229  return Error::success();
230 }
231 
233  return Error::success();
234 }
235 
237  return Error::success();
238 }
239 
241  PrecompRecord &Precomp) {
242  return Error::success();
243 }
244 
246  EndPrecompRecord &EndPrecomp) {
247  return Error::success();
248 }
249 
251  TypeIndex Index) {
252  TypeNameComputer Computer(Types);
253  CVType Record = Types.getType(Index);
254  if (auto EC = visitTypeRecord(Record, Index, Computer)) {
256  return "<unknown UDT>";
257  }
258  return std::string(Computer.name());
259 }
260 
261 static int getSymbolNameOffset(CVSymbol Sym) {
262  switch (Sym.kind()) {
263  // See ProcSym
264  case SymbolKind::S_GPROC32:
265  case SymbolKind::S_LPROC32:
266  case SymbolKind::S_GPROC32_ID:
267  case SymbolKind::S_LPROC32_ID:
268  case SymbolKind::S_LPROC32_DPC:
269  case SymbolKind::S_LPROC32_DPC_ID:
270  return 35;
271  // See Thunk32Sym
272  case SymbolKind::S_THUNK32:
273  return 21;
274  // See SectionSym
275  case SymbolKind::S_SECTION:
276  return 16;
277  // See CoffGroupSym
278  case SymbolKind::S_COFFGROUP:
279  return 14;
280  // See PublicSym32, FileStaticSym, RegRelativeSym, DataSym, ThreadLocalDataSym
281  case SymbolKind::S_PUB32:
282  case SymbolKind::S_FILESTATIC:
283  case SymbolKind::S_REGREL32:
284  case SymbolKind::S_GDATA32:
285  case SymbolKind::S_LDATA32:
286  case SymbolKind::S_LMANDATA:
287  case SymbolKind::S_GMANDATA:
288  case SymbolKind::S_LTHREAD32:
289  case SymbolKind::S_GTHREAD32:
290  case SymbolKind::S_PROCREF:
291  case SymbolKind::S_LPROCREF:
292  return 10;
293  // See RegisterSym and LocalSym
294  case SymbolKind::S_REGISTER:
295  case SymbolKind::S_LOCAL:
296  return 6;
297  // See BlockSym
298  case SymbolKind::S_BLOCK32:
299  return 18;
300  // See LabelSym
301  case SymbolKind::S_LABEL32:
302  return 7;
303  // See ObjNameSym, ExportSym, and UDTSym
304  case SymbolKind::S_OBJNAME:
305  case SymbolKind::S_EXPORT:
306  case SymbolKind::S_UDT:
307  return 4;
308  // See BPRelativeSym
309  case SymbolKind::S_BPREL32:
310  return 8;
311  // See UsingNamespaceSym
312  case SymbolKind::S_UNAMESPACE:
313  return 0;
314  default:
315  return -1;
316  }
317 }
318 
320  if (Sym.kind() == SymbolKind::S_CONSTANT) {
321  // S_CONSTANT is preceded by an APSInt, which has a variable length. So we
322  // have to do a full deserialization.
324  // The container doesn't matter for single records.
326  ConstantSym Const(SymbolKind::S_CONSTANT);
327  cantFail(Mapping.visitSymbolBegin(Sym));
328  cantFail(Mapping.visitKnownRecord(Sym, Const));
329  cantFail(Mapping.visitSymbolEnd(Sym));
330  return Const.Name;
331  }
332 
333  int Offset = getSymbolNameOffset(Sym);
334  if (Offset == -1)
335  return StringRef();
336 
337  StringRef StringData = toStringRef(Sym.content()).drop_front(Offset);
338  return StringData.split('\0').first;
339 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
SymbolRecordMapping.h
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:102
llvm
Definition: AllocatorList.h:23
llvm::codeview::computeTypeName
std::string computeTypeName(TypeCollection &Types, TypeIndex Index)
Definition: RecordName.cpp:250
llvm::codeview::VFTableShapeRecord::getEntryCount
uint32_t getEntryCount() const
Definition: TypeRecord.h:567
llvm::codeview::TypeVisitorCallbacks
Definition: TypeVisitorCallbacks.h:18
llvm::codeview::StringIdRecord
Definition: TypeRecord.h:594
llvm::codeview::PointerRecord::isVolatile
bool isVolatile() const
Definition: TypeRecord.h:327
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:332
llvm::codeview::PrecompRecord
Definition: TypeRecord.h:928
llvm::codeview::PointerRecord::getReferentType
TypeIndex getReferentType() const
Definition: TypeRecord.h:297
llvm::codeview::VFTableShapeRecord
Definition: TypeRecord.h:552
llvm::codeview::MemberFunctionRecord::getArgumentList
TypeIndex getArgumentList() const
Definition: TypeRecord.h:191
RecordName.h
TypeVisitorCallbacks.h
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:116
visitKnownRecord
static Error visitKnownRecord(CVSymbol &Record, SymbolVisitorCallbacks &Callbacks)
Definition: CVSymbolVisitor.cpp:21
llvm::codeview::PointerRecord
Definition: TypeRecord.h:263
llvm::codeview::PointerMode::Pointer
@ Pointer
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1006
llvm::codeview::TypeIndex::None
static TypeIndex None()
Definition: TypeIndex.h:147
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:250
llvm::codeview::SymbolRecordMapping
Definition: SymbolRecordMapping.h:20
llvm::codeview::ProcedureRecord::getReturnType
TypeIndex getReturnType() const
Definition: TypeRecord.h:156
llvm::codeview::ArgListRecord
Definition: TypeRecord.h:235
llvm::codeview::EnumRecord
Definition: TypeRecord.h:518
llvm::codeview::MemberFunctionRecord::getReturnType
TypeIndex getReturnType() const
Definition: TypeRecord.h:185
llvm::codeview::ConstantSym
Definition: SymbolRecord.h:921
SmallString.h
llvm::codeview::ProcedureRecord::getArgumentList
TypeIndex getArgumentList() const
Definition: TypeRecord.h:160
llvm::support::little
@ little
Definition: Endian.h:27
llvm::StringRef::split
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:727
llvm::codeview::BitFieldRecord
Definition: TypeRecord.h:534
llvm::codeview::SymbolRecordMapping::visitSymbolEnd
Error visitSymbolEnd(CVSymbol &Record) override
Definition: SymbolRecordMapping.cpp:41
llvm::codeview::MethodOverloadListRecord
Definition: TypeRecord.h:751
llvm::codeview::TypeCollection
Definition: TypeCollection.h:18
llvm::codeview::MemberFunctionRecord::getClassType
TypeIndex getClassType() const
Definition: TypeRecord.h:186
llvm::dwarf::toStringRef
StringRef toStringRef(const Optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
Definition: DWARFFormValue.h:177
llvm::codeview::TypeCollection::getType
virtual CVType getType(TypeIndex Index)=0
llvm::codeview::UdtModSourceLineRecord
Definition: TypeRecord.h:645
llvm::codeview::ArrayRecord::getName
StringRef getName() const
Definition: TypeRecord.h:407
llvm::codeview::ModifierOptions::Volatile
@ Volatile
llvm::codeview::ModifierRecord
Definition: TypeRecord.h:129
FormatVariadic.h
llvm::codeview::MemberFunctionRecord
Definition: TypeRecord.h:170
llvm::codeview::visitTypeRecord
Error visitTypeRecord(CVType &Record, TypeIndex Index, TypeVisitorCallbacks &Callbacks, VisitorDataSource Source=VDS_BytesPresent)
Definition: CVTypeVisitor.cpp:218
llvm::codeview::PointerMode::LValueReference
@ LValueReference
llvm::SmallString< 256 >
llvm::BinaryStreamReader
Provides read only access to a subclass of BinaryStream.
Definition: BinaryStreamReader.h:31
llvm::codeview::PointerRecord::getMode
PointerMode getMode() const
Definition: TypeRecord.h:304
llvm::codeview::PointerRecord::isUnaligned
bool isUnaligned() const
Definition: TypeRecord.h:331
llvm::codeview::TypeServer2Record
Definition: TypeRecord.h:574
llvm::codeview::TypeServer2Record::getName
StringRef getName() const
Definition: TypeRecord.h:586
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
llvm::codeview::CVRecord::kind
Kind kind() const
Definition: CVRecord.h:43
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
I
#define I(x, y, z)
Definition: MD5.cpp:59
getSymbolNameOffset
static int getSymbolNameOffset(CVSymbol Sym)
Definition: RecordName.cpp:261
StringExtras.h
llvm::codeview::PointerRecord::isConst
bool isConst() const
Definition: TypeRecord.h:325
llvm::elfabi::ELFSymbolType::Func
@ Func
llvm::codeview::CompileSym2Flags::EC
@ EC
llvm::codeview::CodeViewContainer::ObjectFile
@ ObjectFile
llvm::Record
Definition: Record.h:1472
llvm::pdb::PDB_UdtType::Union
@ Union
llvm::codeview::SymbolRecordMapping::visitSymbolBegin
Error visitSymbolBegin(CVSymbol &Record) override
Definition: SymbolRecordMapping.cpp:36
llvm::codeview::CVRecord::content
ArrayRef< uint8_t > content() const
Definition: CVRecord.h:57
llvm::codeview::FuncIdRecord
Definition: TypeRecord.h:609
llvm::codeview::FieldListRecord
Definition: TypeRecord.h:384
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::codeview::CVRecord< TypeLeafKind >
llvm::codeview::PointerMode::RValueReference
@ RValueReference
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:708
llvm::codeview::UdtSourceLineRecord
Definition: TypeRecord.h:627
uint32_t
llvm::codeview::VFTableRecord
Definition: TypeRecord.h:690
llvm::pdb::PDB_SymType::Enum
@ Enum
llvm::codeview::ProcedureRecord
Definition: TypeRecord.h:145
name
static const char * name
Definition: SVEIntrinsicOpts.cpp:84
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::StringRef::drop_front
LLVM_NODISCARD StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition: StringRef.h:651
uint16_t
llvm::codeview::UnionRecord
Definition: TypeRecord.h:497
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::codeview::ModifierOptions::Unaligned
@ Unaligned
CVTypeVisitor.h
llvm::codeview::BuildInfoRecord
Definition: TypeRecord.h:666
llvm::codeview::MemberFuncIdRecord
Definition: TypeRecord.h:216
llvm::codeview::ModifierOptions::Const
@ Const
llvm::codeview::PointerRecord::isPointerToMember
bool isPointerToMember() const
Definition: TypeRecord.h:319
llvm::tgtok::Class
@ Class
Definition: TGLexer.h:50
llvm::codeview
Definition: AppendingTypeTableBuilder.h:22
llvm::codeview::getSymbolName
StringRef getSymbolName(CVSymbol Sym)
Definition: RecordName.cpp:319
llvm::codeview::PointerRecord::isRestrict
bool isRestrict() const
Definition: TypeRecord.h:335
llvm::codeview::StringListRecord
Definition: TypeRecord.h:249
llvm::codeview::ArrayRecord
Definition: TypeRecord.h:395
llvm::codeview::PointerRecord::getMemberInfo
MemberPointerInfo getMemberInfo() const
Definition: TypeRecord.h:317
llvm::codeview::VFTableRecord::getName
StringRef getName() const
Definition: TypeRecord.h:706
CVSymbolVisitor.h
llvm::codeview::LabelRecord
Definition: TypeRecord.h:205
llvm::codeview::TypeIndex
A 32-bit type reference.
Definition: TypeIndex.h:95
llvm::codeview::ClassRecord
Definition: TypeRecord.h:464
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
Mod
Module * Mod
Definition: PassBuilderBindings.cpp:54
llvm::pdb::String
@ String
Definition: PDBTypes.h:407
llvm::AMDGPU::VGPRIndexMode::Id
Id
Definition: SIDefines.h:221
llvm::codeview::MemberPointerInfo
Definition: TypeRecord.h:100
llvm::codeview::EndPrecompRecord
Definition: TypeRecord.h:945