LLVM  15.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"
22 
23 using namespace llvm;
24 using namespace llvm::codeview;
25 
26 namespace {
27 class TypeNameComputer : public TypeVisitorCallbacks {
28  /// The type collection. Used to calculate names of nested types.
29  TypeCollection &Types;
30  TypeIndex CurrentTypeIndex = TypeIndex::None();
31 
32  /// Name of the current type. Only valid before visitTypeEnd.
34 
35 public:
36  explicit TypeNameComputer(TypeCollection &Types) : Types(Types) {}
37 
38  StringRef name() const { return Name; }
39 
40  /// Paired begin/end actions for all types. Receives all record data,
41  /// including the fixed-length record prefix.
42  Error visitTypeBegin(CVType &Record) override;
43  Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
44  Error visitTypeEnd(CVType &Record) override;
45 
46 #define TYPE_RECORD(EnumName, EnumVal, Name) \
47  Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
48 #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
49 #define MEMBER_RECORD(EnumName, EnumVal, Name)
50 #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
51 };
52 } // namespace
53 
54 Error TypeNameComputer::visitTypeBegin(CVType &Record) {
55  llvm_unreachable("Must call visitTypeBegin with a TypeIndex!");
56  return Error::success();
57 }
58 
59 Error TypeNameComputer::visitTypeBegin(CVType &Record, TypeIndex Index) {
60  // Reset Name to the empty string. If the visitor sets it, we know it.
61  Name = "";
62  CurrentTypeIndex = Index;
63  return Error::success();
64 }
65 
66 Error TypeNameComputer::visitTypeEnd(CVType &CVR) { return Error::success(); }
67 
69  FieldListRecord &FieldList) {
70  Name = "<field list>";
71  return Error::success();
72 }
73 
75  StringIdRecord &String) {
76  Name = String.getString();
77  return Error::success();
78 }
79 
81  auto Indices = Args.getIndices();
82  uint32_t Size = Indices.size();
83  Name = "(";
84  for (uint32_t I = 0; I < Size; ++I) {
85  if (Indices[I] < CurrentTypeIndex)
86  Name.append(Types.getTypeName(Indices[I]));
87  else
88  Name.append("<unknown 0x" + utohexstr(Indices[I].getIndex()) + ">");
89  if (I + 1 != Size)
90  Name.append(", ");
91  }
92  Name.push_back(')');
93  return Error::success();
94 }
95 
97  StringListRecord &Strings) {
98  auto Indices = Strings.getIndices();
99  uint32_t Size = Indices.size();
100  Name = "\"";
101  for (uint32_t I = 0; I < Size; ++I) {
102  Name.append(Types.getTypeName(Indices[I]));
103  if (I + 1 != Size)
104  Name.append("\" \"");
105  }
106  Name.push_back('\"');
107  return Error::success();
108 }
109 
111  Name = Class.getName();
112  return Error::success();
113 }
114 
116  Name = Union.getName();
117  return Error::success();
118 }
119 
121  Name = Enum.getName();
122  return Error::success();
123 }
124 
126  Name = AT.getName();
127  return Error::success();
128 }
129 
131  Name = VFT.getName();
132  return Error::success();
133 }
134 
136  Name = Id.getName();
137  return Error::success();
138 }
139 
141  StringRef Ret = Types.getTypeName(Proc.getReturnType());
142  StringRef Params = Types.getTypeName(Proc.getArgumentList());
143  Name = formatv("{0} {1}", Ret, Params).sstr<256>();
144  return Error::success();
145 }
146 
148  MemberFunctionRecord &MF) {
149  StringRef Ret = Types.getTypeName(MF.getReturnType());
150  StringRef Class = Types.getTypeName(MF.getClassType());
151  StringRef Params = Types.getTypeName(MF.getArgumentList());
152  Name = formatv("{0} {1}::{2}", Ret, Class, Params).sstr<256>();
153  return Error::success();
154 }
155 
157  Name = Func.getName();
158  return Error::success();
159 }
160 
162  Name = TS.getName();
163  return Error::success();
164 }
165 
167 
168  if (Ptr.isPointerToMember()) {
169  const MemberPointerInfo &MI = Ptr.getMemberInfo();
170 
171  StringRef Pointee = Types.getTypeName(Ptr.getReferentType());
172  StringRef Class = Types.getTypeName(MI.getContainingType());
173  Name = formatv("{0} {1}::*", Pointee, Class);
174  } else {
175  Name.append(Types.getTypeName(Ptr.getReferentType()));
176 
178  Name.append("&");
179  else if (Ptr.getMode() == PointerMode::RValueReference)
180  Name.append("&&");
181  else if (Ptr.getMode() == PointerMode::Pointer)
182  Name.append("*");
183 
184  // Qualifiers in pointer records apply to the pointer, not the pointee, so
185  // they go on the right.
186  if (Ptr.isConst())
187  Name.append(" const");
188  if (Ptr.isVolatile())
189  Name.append(" volatile");
190  if (Ptr.isUnaligned())
191  Name.append(" __unaligned");
192  if (Ptr.isRestrict())
193  Name.append(" __restrict");
194  }
195  return Error::success();
196 }
197 
199  uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
200 
201  if (Mods & uint16_t(ModifierOptions::Const))
202  Name.append("const ");
204  Name.append("volatile ");
206  Name.append("__unaligned ");
207  Name.append(Types.getTypeName(Mod.getModifiedType()));
208  return Error::success();
209 }
210 
212  VFTableShapeRecord &Shape) {
213  Name = formatv("<vftable {0} methods>", Shape.getEntryCount());
214  return Error::success();
215 }
216 
218  CVType &CVR, UdtModSourceLineRecord &ModSourceLine) {
219  return Error::success();
220 }
221 
223  UdtSourceLineRecord &SourceLine) {
224  return Error::success();
225 }
226 
228  return Error::success();
229 }
230 
232  MethodOverloadListRecord &Overloads) {
233  return Error::success();
234 }
235 
237  return Error::success();
238 }
239 
241  return Error::success();
242 }
243 
245  PrecompRecord &Precomp) {
246  return Error::success();
247 }
248 
250  EndPrecompRecord &EndPrecomp) {
251  return Error::success();
252 }
253 
255  TypeIndex Index) {
256  TypeNameComputer Computer(Types);
257  CVType Record = Types.getType(Index);
258  if (auto EC = visitTypeRecord(Record, Index, Computer)) {
260  return "<unknown UDT>";
261  }
262  return std::string(Computer.name());
263 }
264 
265 static int getSymbolNameOffset(CVSymbol Sym) {
266  switch (Sym.kind()) {
267  // See ProcSym
268  case SymbolKind::S_GPROC32:
269  case SymbolKind::S_LPROC32:
270  case SymbolKind::S_GPROC32_ID:
271  case SymbolKind::S_LPROC32_ID:
272  case SymbolKind::S_LPROC32_DPC:
273  case SymbolKind::S_LPROC32_DPC_ID:
274  return 35;
275  // See Thunk32Sym
276  case SymbolKind::S_THUNK32:
277  return 21;
278  // See SectionSym
279  case SymbolKind::S_SECTION:
280  return 16;
281  // See CoffGroupSym
282  case SymbolKind::S_COFFGROUP:
283  return 14;
284  // See PublicSym32, FileStaticSym, RegRelativeSym, DataSym, ThreadLocalDataSym
285  case SymbolKind::S_PUB32:
286  case SymbolKind::S_FILESTATIC:
287  case SymbolKind::S_REGREL32:
288  case SymbolKind::S_GDATA32:
289  case SymbolKind::S_LDATA32:
290  case SymbolKind::S_LMANDATA:
291  case SymbolKind::S_GMANDATA:
292  case SymbolKind::S_LTHREAD32:
293  case SymbolKind::S_GTHREAD32:
294  case SymbolKind::S_PROCREF:
295  case SymbolKind::S_LPROCREF:
296  return 10;
297  // See RegisterSym and LocalSym
298  case SymbolKind::S_REGISTER:
299  case SymbolKind::S_LOCAL:
300  return 6;
301  // See BlockSym
302  case SymbolKind::S_BLOCK32:
303  return 18;
304  // See LabelSym
305  case SymbolKind::S_LABEL32:
306  return 7;
307  // See ObjNameSym, ExportSym, and UDTSym
308  case SymbolKind::S_OBJNAME:
309  case SymbolKind::S_EXPORT:
310  case SymbolKind::S_UDT:
311  return 4;
312  // See BPRelativeSym
313  case SymbolKind::S_BPREL32:
314  return 8;
315  // See UsingNamespaceSym
316  case SymbolKind::S_UNAMESPACE:
317  return 0;
318  default:
319  return -1;
320  }
321 }
322 
324  if (Sym.kind() == SymbolKind::S_CONSTANT) {
325  // S_CONSTANT is preceded by an APSInt, which has a variable length. So we
326  // have to do a full deserialization.
328  // The container doesn't matter for single records.
330  ConstantSym Const(SymbolKind::S_CONSTANT);
331  cantFail(Mapping.visitSymbolBegin(Sym));
332  cantFail(Mapping.visitKnownRecord(Sym, Const));
333  cantFail(Mapping.visitSymbolEnd(Sym));
334  return Const.Name;
335  }
336 
337  int Offset = getSymbolNameOffset(Sym);
338  if (Offset == -1)
339  return StringRef();
340 
341  StringRef StringData = toStringRef(Sym.content()).drop_front(Offset);
342  return StringData.split('\0').first;
343 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:77
SymbolRecordMapping.h
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::codeview::computeTypeName
std::string computeTypeName(TypeCollection &Types, TypeIndex Index)
Definition: RecordName.cpp:254
llvm::codeview::VFTableShapeRecord::getEntryCount
uint32_t getEntryCount() const
Definition: TypeRecord.h:568
llvm::codeview::TypeVisitorCallbacks
Definition: TypeVisitorCallbacks.h:18
llvm::codeview::StringIdRecord
Definition: TypeRecord.h:595
SymbolRecord.h
llvm::codeview::PointerRecord::isVolatile
bool isVolatile() const
Definition: TypeRecord.h:328
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::codeview::PrecompRecord
Definition: TypeRecord.h:929
llvm::codeview::PointerRecord::getReferentType
TypeIndex getReferentType() const
Definition: TypeRecord.h:298
llvm::codeview::VFTableShapeRecord
Definition: TypeRecord.h:553
llvm::codeview::MemberFunctionRecord::getArgumentList
TypeIndex getArgumentList() const
Definition: TypeRecord.h:192
RecordName.h
TypeVisitorCallbacks.h
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:119
visitKnownRecord
static Error visitKnownRecord(CVSymbol &Record, SymbolVisitorCallbacks &Callbacks)
Definition: CVSymbolVisitor.cpp:25
llvm::codeview::PointerRecord
Definition: TypeRecord.h:264
llvm::codeview::PointerMode::Pointer
@ Pointer
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1043
llvm::codeview::TypeIndex::None
static TypeIndex None()
Definition: TypeIndex.h:148
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:251
llvm::codeview::SymbolRecordMapping
Definition: SymbolRecordMapping.h:20
llvm::codeview::ProcedureRecord::getReturnType
TypeIndex getReturnType() const
Definition: TypeRecord.h:157
llvm::codeview::ArgListRecord
Definition: TypeRecord.h:236
llvm::codeview::EnumRecord
Definition: TypeRecord.h:519
llvm::codeview::MemberFunctionRecord::getReturnType
TypeIndex getReturnType() const
Definition: TypeRecord.h:186
llvm::codeview::ConstantSym
Definition: SymbolRecord.h:921
SmallString.h
llvm::codeview::ProcedureRecord::getArgumentList
TypeIndex getArgumentList() const
Definition: TypeRecord.h:161
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:753
llvm::codeview::BitFieldRecord
Definition: TypeRecord.h:535
llvm::codeview::SymbolRecordMapping::visitSymbolEnd
Error visitSymbolEnd(CVSymbol &Record) override
Definition: SymbolRecordMapping.cpp:41
llvm::codeview::MethodOverloadListRecord
Definition: TypeRecord.h:752
llvm::codeview::TypeCollection
Definition: TypeCollection.h:18
llvm::codeview::MemberFunctionRecord::getClassType
TypeIndex getClassType() const
Definition: TypeRecord.h:187
llvm::dwarf::Index
Index
Definition: Dwarf.h:472
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:193
llvm::codeview::TypeCollection::getType
virtual CVType getType(TypeIndex Index)=0
llvm::codeview::UdtModSourceLineRecord
Definition: TypeRecord.h:646
llvm::codeview::ArrayRecord::getName
StringRef getName() const
Definition: TypeRecord.h:408
llvm::codeview::ModifierOptions::Volatile
@ Volatile
llvm::codeview::ModifierRecord
Definition: TypeRecord.h:130
CodeView.h
FormatVariadic.h
llvm::codeview::MemberFunctionRecord
Definition: TypeRecord.h:171
llvm::codeview::visitTypeRecord
Error visitTypeRecord(CVType &Record, TypeIndex Index, TypeVisitorCallbacks &Callbacks, VisitorDataSource Source=VDS_BytesPresent)
Definition: CVTypeVisitor.cpp:219
llvm::codeview::PointerMode::LValueReference
@ LValueReference
llvm::SmallString< 256 >
llvm::BinaryStreamReader
Provides read only access to a subclass of BinaryStream.
Definition: BinaryStreamReader.h:29
llvm::codeview::PointerRecord::getMode
PointerMode getMode() const
Definition: TypeRecord.h:305
llvm::codeview::PointerRecord::isUnaligned
bool isUnaligned() const
Definition: TypeRecord.h:332
llvm::codeview::TypeServer2Record
Definition: TypeRecord.h:575
llvm::codeview::TypeServer2Record::getName
StringRef getName() const
Definition: TypeRecord.h:587
TypeRecord.h
llvm::codeview::CVRecord::kind
Kind kind() const
Definition: CVRecord.h:42
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:58
getSymbolNameOffset
static int getSymbolNameOffset(CVSymbol Sym)
Definition: RecordName.cpp:265
StringExtras.h
llvm::codeview::PointerRecord::isConst
bool isConst() const
Definition: TypeRecord.h:326
llvm::codeview::CompileSym2Flags::EC
@ EC
llvm::codeview::CodeViewContainer::ObjectFile
@ ObjectFile
llvm::Record
Definition: Record.h:1543
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:56
llvm::codeview::FuncIdRecord
Definition: TypeRecord.h:610
llvm::codeview::FieldListRecord
Definition: TypeRecord.h:385
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:143
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:745
llvm::codeview::UdtSourceLineRecord
Definition: TypeRecord.h:628
uint32_t
llvm::codeview::VFTableRecord
Definition: TypeRecord.h:691
llvm::pdb::PDB_SymType::Enum
@ Enum
llvm::ifs::IFSSymbolType::Func
@ Func
llvm::codeview::ProcedureRecord
Definition: TypeRecord.h:146
name
static const char * name
Definition: SVEIntrinsicOpts.cpp:74
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
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:657
uint16_t
llvm::codeview::UnionRecord
Definition: TypeRecord.h:498
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
TypeCollection.h
llvm::codeview::ModifierOptions::Unaligned
@ Unaligned
CVTypeVisitor.h
TypeIndex.h
llvm::codeview::BuildInfoRecord
Definition: TypeRecord.h:667
llvm::codeview::MemberFuncIdRecord
Definition: TypeRecord.h:217
llvm::codeview::ModifierOptions::Const
@ Const
llvm::codeview::PointerRecord::isPointerToMember
bool isPointerToMember() const
Definition: TypeRecord.h:320
llvm::tgtok::Class
@ Class
Definition: TGLexer.h:50
llvm::codeview
Definition: AppendingTypeTableBuilder.h:22
llvm::codeview::getSymbolName
StringRef getSymbolName(CVSymbol Sym)
Definition: RecordName.cpp:323
llvm::codeview::PointerRecord::isRestrict
bool isRestrict() const
Definition: TypeRecord.h:336
llvm::codeview::StringListRecord
Definition: TypeRecord.h:250
llvm::codeview::ArrayRecord
Definition: TypeRecord.h:396
llvm::codeview::PointerRecord::getMemberInfo
MemberPointerInfo getMemberInfo() const
Definition: TypeRecord.h:318
llvm::codeview::VFTableRecord::getName
StringRef getName() const
Definition: TypeRecord.h:707
llvm::codeview::LabelRecord
Definition: TypeRecord.h:206
llvm::codeview::TypeIndex
A 32-bit type reference.
Definition: TypeIndex.h:96
llvm::codeview::ClassRecord
Definition: TypeRecord.h:465
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
Mod
Module * Mod
Definition: PassBuilderBindings.cpp:54
llvm::pdb::String
@ String
Definition: PDBTypes.h:408
llvm::AMDGPU::VGPRIndexMode::Id
Id
Definition: SIDefines.h:241
llvm::codeview::MemberPointerInfo
Definition: TypeRecord.h:100
llvm::codeview::EndPrecompRecord
Definition: TypeRecord.h:946