LLVM  16.0.0git
ItaniumDemangle.cpp
Go to the documentation of this file.
1 //===------------------------- ItaniumDemangle.cpp ------------------------===//
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 
9 // FIXME: (possibly) incomplete list of features that clang mangles that this
10 // file does not yet support:
11 // - C++ modules TS
12 
13 #include "llvm/Demangle/Demangle.h"
15 
16 #include <cassert>
17 #include <cctype>
18 #include <cstdio>
19 #include <cstdlib>
20 #include <cstring>
21 #include <functional>
22 #include <utility>
23 
24 using namespace llvm;
25 using namespace llvm::itanium_demangle;
26 
27 constexpr const char *itanium_demangle::FloatData<float>::spec;
28 constexpr const char *itanium_demangle::FloatData<double>::spec;
29 constexpr const char *itanium_demangle::FloatData<long double>::spec;
30 
31 // <discriminator> := _ <non-negative number> # when number < 10
32 // := __ <non-negative number> _ # when number >= 10
33 // extension := decimal-digit+ # at the end of string
34 const char *itanium_demangle::parse_discriminator(const char *first,
35  const char *last) {
36  // parse but ignore discriminator
37  if (first != last) {
38  if (*first == '_') {
39  const char *t1 = first + 1;
40  if (t1 != last) {
41  if (std::isdigit(*t1))
42  first = t1 + 1;
43  else if (*t1 == '_') {
44  for (++t1; t1 != last && std::isdigit(*t1); ++t1)
45  ;
46  if (t1 != last && *t1 == '_')
47  first = t1 + 1;
48  }
49  }
50  } else if (std::isdigit(*first)) {
51  const char *t1 = first + 1;
52  for (; t1 != last && std::isdigit(*t1); ++t1)
53  ;
54  if (t1 == last)
55  first = last;
56  }
57  }
58  return first;
59 }
60 
61 #ifndef NDEBUG
62 namespace {
63 struct DumpVisitor {
64  unsigned Depth = 0;
65  bool PendingNewline = false;
66 
67  template<typename NodeT> static constexpr bool wantsNewline(const NodeT *) {
68  return true;
69  }
70  static bool wantsNewline(NodeArray A) { return !A.empty(); }
71  static constexpr bool wantsNewline(...) { return false; }
72 
73  template<typename ...Ts> static bool anyWantNewline(Ts ...Vs) {
74  for (bool B : {wantsNewline(Vs)...})
75  if (B)
76  return true;
77  return false;
78  }
79 
80  void printStr(const char *S) { fprintf(stderr, "%s", S); }
81  void print(StringView SV) {
82  fprintf(stderr, "\"%.*s\"", (int)SV.size(), SV.begin());
83  }
84  void print(const Node *N) {
85  if (N)
86  N->visit(std::ref(*this));
87  else
88  printStr("<null>");
89  }
90  void print(NodeArray A) {
91  ++Depth;
92  printStr("{");
93  bool First = true;
94  for (const Node *N : A) {
95  if (First)
96  print(N);
97  else
98  printWithComma(N);
99  First = false;
100  }
101  printStr("}");
102  --Depth;
103  }
104 
105  // Overload used when T is exactly 'bool', not merely convertible to 'bool'.
106  void print(bool B) { printStr(B ? "true" : "false"); }
107 
108  template <class T> std::enable_if_t<std::is_unsigned<T>::value> print(T N) {
109  fprintf(stderr, "%llu", (unsigned long long)N);
110  }
111 
112  template <class T> std::enable_if_t<std::is_signed<T>::value> print(T N) {
113  fprintf(stderr, "%lld", (long long)N);
114  }
115 
116  void print(ReferenceKind RK) {
117  switch (RK) {
119  return printStr("ReferenceKind::LValue");
121  return printStr("ReferenceKind::RValue");
122  }
123  }
124  void print(FunctionRefQual RQ) {
125  switch (RQ) {
127  return printStr("FunctionRefQual::FrefQualNone");
129  return printStr("FunctionRefQual::FrefQualLValue");
131  return printStr("FunctionRefQual::FrefQualRValue");
132  }
133  }
134  void print(Qualifiers Qs) {
135  if (!Qs) return printStr("QualNone");
136  struct QualName { Qualifiers Q; const char *Name; } Names[] = {
137  {QualConst, "QualConst"},
138  {QualVolatile, "QualVolatile"},
139  {QualRestrict, "QualRestrict"},
140  };
141  for (QualName Name : Names) {
142  if (Qs & Name.Q) {
143  printStr(Name.Name);
144  Qs = Qualifiers(Qs & ~Name.Q);
145  if (Qs) printStr(" | ");
146  }
147  }
148  }
149  void print(SpecialSubKind SSK) {
150  switch (SSK) {
152  return printStr("SpecialSubKind::allocator");
154  return printStr("SpecialSubKind::basic_string");
156  return printStr("SpecialSubKind::string");
158  return printStr("SpecialSubKind::istream");
160  return printStr("SpecialSubKind::ostream");
162  return printStr("SpecialSubKind::iostream");
163  }
164  }
165  void print(TemplateParamKind TPK) {
166  switch (TPK) {
168  return printStr("TemplateParamKind::Type");
170  return printStr("TemplateParamKind::NonType");
172  return printStr("TemplateParamKind::Template");
173  }
174  }
175  void print(Node::Prec P) {
176  switch (P) {
177  case Node::Prec::Primary:
178  return printStr("Node::Prec::Primary");
179  case Node::Prec::Postfix:
180  return printStr("Node::Prec::Postfix");
181  case Node::Prec::Unary:
182  return printStr("Node::Prec::Unary");
183  case Node::Prec::Cast:
184  return printStr("Node::Prec::Cast");
185  case Node::Prec::PtrMem:
186  return printStr("Node::Prec::PtrMem");
188  return printStr("Node::Prec::Multiplicative");
190  return printStr("Node::Prec::Additive");
191  case Node::Prec::Shift:
192  return printStr("Node::Prec::Shift");
194  return printStr("Node::Prec::Spaceship");
196  return printStr("Node::Prec::Relational");
198  return printStr("Node::Prec::Equality");
199  case Node::Prec::And:
200  return printStr("Node::Prec::And");
201  case Node::Prec::Xor:
202  return printStr("Node::Prec::Xor");
203  case Node::Prec::Ior:
204  return printStr("Node::Prec::Ior");
205  case Node::Prec::AndIf:
206  return printStr("Node::Prec::AndIf");
207  case Node::Prec::OrIf:
208  return printStr("Node::Prec::OrIf");
210  return printStr("Node::Prec::Conditional");
211  case Node::Prec::Assign:
212  return printStr("Node::Prec::Assign");
213  case Node::Prec::Comma:
214  return printStr("Node::Prec::Comma");
215  case Node::Prec::Default:
216  return printStr("Node::Prec::Default");
217  }
218  }
219 
220  void newLine() {
221  printStr("\n");
222  for (unsigned I = 0; I != Depth; ++I)
223  printStr(" ");
224  PendingNewline = false;
225  }
226 
227  template<typename T> void printWithPendingNewline(T V) {
228  print(V);
229  if (wantsNewline(V))
230  PendingNewline = true;
231  }
232 
233  template<typename T> void printWithComma(T V) {
234  if (PendingNewline || wantsNewline(V)) {
235  printStr(",");
236  newLine();
237  } else {
238  printStr(", ");
239  }
240 
241  printWithPendingNewline(V);
242  }
243 
244  struct CtorArgPrinter {
245  DumpVisitor &Visitor;
246 
247  template<typename T, typename ...Rest> void operator()(T V, Rest ...Vs) {
248  if (Visitor.anyWantNewline(V, Vs...))
249  Visitor.newLine();
250  Visitor.printWithPendingNewline(V);
251  int PrintInOrder[] = { (Visitor.printWithComma(Vs), 0)..., 0 };
252  (void)PrintInOrder;
253  }
254  };
255 
256  template<typename NodeT> void operator()(const NodeT *Node) {
257  Depth += 2;
258  fprintf(stderr, "%s(", itanium_demangle::NodeKind<NodeT>::name());
259  Node->match(CtorArgPrinter{*this});
260  fprintf(stderr, ")");
261  Depth -= 2;
262  }
263 
264  void operator()(const ForwardTemplateReference *Node) {
265  Depth += 2;
266  fprintf(stderr, "ForwardTemplateReference(");
267  if (Node->Ref && !Node->Printing) {
268  Node->Printing = true;
269  CtorArgPrinter{*this}(Node->Ref);
270  Node->Printing = false;
271  } else {
272  CtorArgPrinter{*this}(Node->Index);
273  }
274  fprintf(stderr, ")");
275  Depth -= 2;
276  }
277 };
278 }
279 
280 void itanium_demangle::Node::dump() const {
281  DumpVisitor V;
282  visit(std::ref(V));
283  V.newLine();
284 }
285 #endif
286 
287 namespace {
288 class BumpPointerAllocator {
289  struct BlockMeta {
290  BlockMeta* Next;
291  size_t Current;
292  };
293 
294  static constexpr size_t AllocSize = 4096;
295  static constexpr size_t UsableAllocSize = AllocSize - sizeof(BlockMeta);
296 
297  alignas(long double) char InitialBuffer[AllocSize];
298  BlockMeta* BlockList = nullptr;
299 
300  void grow() {
301  char* NewMeta = static_cast<char *>(std::malloc(AllocSize));
302  if (NewMeta == nullptr)
303  std::terminate();
304  BlockList = new (NewMeta) BlockMeta{BlockList, 0};
305  }
306 
307  void* allocateMassive(size_t NBytes) {
308  NBytes += sizeof(BlockMeta);
309  BlockMeta* NewMeta = reinterpret_cast<BlockMeta*>(std::malloc(NBytes));
310  if (NewMeta == nullptr)
311  std::terminate();
312  BlockList->Next = new (NewMeta) BlockMeta{BlockList->Next, 0};
313  return static_cast<void*>(NewMeta + 1);
314  }
315 
316 public:
317  BumpPointerAllocator()
318  : BlockList(new (InitialBuffer) BlockMeta{nullptr, 0}) {}
319 
320  void* allocate(size_t N) {
321  N = (N + 15u) & ~15u;
322  if (N + BlockList->Current >= UsableAllocSize) {
323  if (N > UsableAllocSize)
324  return allocateMassive(N);
325  grow();
326  }
327  BlockList->Current += N;
328  return static_cast<void*>(reinterpret_cast<char*>(BlockList + 1) +
329  BlockList->Current - N);
330  }
331 
332  void reset() {
333  while (BlockList) {
334  BlockMeta* Tmp = BlockList;
335  BlockList = BlockList->Next;
336  if (reinterpret_cast<char*>(Tmp) != InitialBuffer)
337  std::free(Tmp);
338  }
339  BlockList = new (InitialBuffer) BlockMeta{nullptr, 0};
340  }
341 
342  ~BumpPointerAllocator() { reset(); }
343 };
344 
345 class DefaultAllocator {
346  BumpPointerAllocator Alloc;
347 
348 public:
349  void reset() { Alloc.reset(); }
350 
351  template<typename T, typename ...Args> T *makeNode(Args &&...args) {
352  return new (Alloc.allocate(sizeof(T)))
353  T(std::forward<Args>(args)...);
354  }
355 
356  void *allocateNodeArray(size_t sz) {
357  return Alloc.allocate(sizeof(Node *) * sz);
358  }
359 };
360 } // unnamed namespace
361 
362 //===----------------------------------------------------------------------===//
363 // Code beyond this point should not be synchronized with libc++abi.
364 //===----------------------------------------------------------------------===//
365 
366 using Demangler = itanium_demangle::ManglingParser<DefaultAllocator>;
367 
368 char *llvm::itaniumDemangle(const char *MangledName, char *Buf,
369  size_t *N, int *Status) {
370  if (MangledName == nullptr || (Buf != nullptr && N == nullptr)) {
371  if (Status)
373  return nullptr;
374  }
375 
376  int InternalStatus = demangle_success;
377  Demangler Parser(MangledName, MangledName + std::strlen(MangledName));
378  OutputBuffer OB;
379 
380  Node *AST = Parser.parse();
381 
382  if (AST == nullptr)
383  InternalStatus = demangle_invalid_mangled_name;
384  else if (!initializeOutputBuffer(Buf, N, OB, 1024))
385  InternalStatus = demangle_memory_alloc_failure;
386  else {
387  assert(Parser.ForwardTemplateRefs.empty());
388  AST->print(OB);
389  OB += '\0';
390  if (N != nullptr)
391  *N = OB.getCurrentPosition();
392  Buf = OB.getBuffer();
393  }
394 
395  if (Status)
396  *Status = InternalStatus;
397  return InternalStatus == demangle_success ? Buf : nullptr;
398 }
399 
401  : RootNode(nullptr), Context(new Demangler{nullptr, nullptr}) {}
402 
404  delete static_cast<Demangler *>(Context);
405 }
406 
408  ItaniumPartialDemangler &&Other)
409  : RootNode(Other.RootNode), Context(Other.Context) {
410  Other.Context = Other.RootNode = nullptr;
411 }
412 
415  std::swap(RootNode, Other.RootNode);
416  std::swap(Context, Other.Context);
417  return *this;
418 }
419 
420 // Demangle MangledName into an AST, storing it into this->RootNode.
421 bool ItaniumPartialDemangler::partialDemangle(const char *MangledName) {
422  Demangler *Parser = static_cast<Demangler *>(Context);
423  size_t Len = std::strlen(MangledName);
424  Parser->reset(MangledName, MangledName + Len);
425  RootNode = Parser->parse();
426  return RootNode == nullptr;
427 }
428 
429 static char *printNode(const Node *RootNode, char *Buf, size_t *N) {
430  OutputBuffer OB;
431  if (!initializeOutputBuffer(Buf, N, OB, 128))
432  return nullptr;
433  RootNode->print(OB);
434  OB += '\0';
435  if (N != nullptr)
436  *N = OB.getCurrentPosition();
437  return OB.getBuffer();
438 }
439 
440 char *ItaniumPartialDemangler::getFunctionBaseName(char *Buf, size_t *N) const {
441  if (!isFunction())
442  return nullptr;
443 
444  const Node *Name = static_cast<const FunctionEncoding *>(RootNode)->getName();
445 
446  while (true) {
447  switch (Name->getKind()) {
448  case Node::KAbiTagAttr:
449  Name = static_cast<const AbiTagAttr *>(Name)->Base;
450  continue;
451  case Node::KModuleEntity:
452  Name = static_cast<const ModuleEntity *>(Name)->Name;
453  continue;
454  case Node::KNestedName:
455  Name = static_cast<const NestedName *>(Name)->Name;
456  continue;
457  case Node::KLocalName:
458  Name = static_cast<const LocalName *>(Name)->Entity;
459  continue;
460  case Node::KNameWithTemplateArgs:
461  Name = static_cast<const NameWithTemplateArgs *>(Name)->Name;
462  continue;
463  default:
464  return printNode(Name, Buf, N);
465  }
466  }
467 }
468 
470  size_t *N) const {
471  if (!isFunction())
472  return nullptr;
473  const Node *Name = static_cast<const FunctionEncoding *>(RootNode)->getName();
474 
475  OutputBuffer OB;
476  if (!initializeOutputBuffer(Buf, N, OB, 128))
477  return nullptr;
478 
479  KeepGoingLocalFunction:
480  while (true) {
481  if (Name->getKind() == Node::KAbiTagAttr) {
482  Name = static_cast<const AbiTagAttr *>(Name)->Base;
483  continue;
484  }
485  if (Name->getKind() == Node::KNameWithTemplateArgs) {
486  Name = static_cast<const NameWithTemplateArgs *>(Name)->Name;
487  continue;
488  }
489  break;
490  }
491 
492  if (Name->getKind() == Node::KModuleEntity)
493  Name = static_cast<const ModuleEntity *>(Name)->Name;
494 
495  switch (Name->getKind()) {
496  case Node::KNestedName:
497  static_cast<const NestedName *>(Name)->Qual->print(OB);
498  break;
499  case Node::KLocalName: {
500  auto *LN = static_cast<const LocalName *>(Name);
501  LN->Encoding->print(OB);
502  OB += "::";
503  Name = LN->Entity;
504  goto KeepGoingLocalFunction;
505  }
506  default:
507  break;
508  }
509  OB += '\0';
510  if (N != nullptr)
511  *N = OB.getCurrentPosition();
512  return OB.getBuffer();
513 }
514 
515 char *ItaniumPartialDemangler::getFunctionName(char *Buf, size_t *N) const {
516  if (!isFunction())
517  return nullptr;
518  auto *Name = static_cast<FunctionEncoding *>(RootNode)->getName();
519  return printNode(Name, Buf, N);
520 }
521 
523  size_t *N) const {
524  if (!isFunction())
525  return nullptr;
526  NodeArray Params = static_cast<FunctionEncoding *>(RootNode)->getParams();
527 
528  OutputBuffer OB;
529  if (!initializeOutputBuffer(Buf, N, OB, 128))
530  return nullptr;
531 
532  OB += '(';
533  Params.printWithComma(OB);
534  OB += ')';
535  OB += '\0';
536  if (N != nullptr)
537  *N = OB.getCurrentPosition();
538  return OB.getBuffer();
539 }
540 
542  char *Buf, size_t *N) const {
543  if (!isFunction())
544  return nullptr;
545 
546  OutputBuffer OB;
547  if (!initializeOutputBuffer(Buf, N, OB, 128))
548  return nullptr;
549 
550  if (const Node *Ret =
551  static_cast<const FunctionEncoding *>(RootNode)->getReturnType())
552  Ret->print(OB);
553 
554  OB += '\0';
555  if (N != nullptr)
556  *N = OB.getCurrentPosition();
557  return OB.getBuffer();
558 }
559 
560 char *ItaniumPartialDemangler::finishDemangle(char *Buf, size_t *N) const {
561  assert(RootNode != nullptr && "must call partialDemangle()");
562  return printNode(static_cast<Node *>(RootNode), Buf, N);
563 }
564 
566  assert(RootNode != nullptr && "must call partialDemangle()");
567  if (!isFunction())
568  return false;
569  auto *E = static_cast<const FunctionEncoding *>(RootNode);
570  return E->getCVQuals() != QualNone || E->getRefQual() != FrefQualNone;
571 }
572 
574  const Node *N = static_cast<const Node *>(RootNode);
575  while (N) {
576  switch (N->getKind()) {
577  default:
578  return false;
579  case Node::KCtorDtorName:
580  return true;
581 
582  case Node::KAbiTagAttr:
583  N = static_cast<const AbiTagAttr *>(N)->Base;
584  break;
585  case Node::KFunctionEncoding:
586  N = static_cast<const FunctionEncoding *>(N)->getName();
587  break;
588  case Node::KLocalName:
589  N = static_cast<const LocalName *>(N)->Entity;
590  break;
591  case Node::KNameWithTemplateArgs:
592  N = static_cast<const NameWithTemplateArgs *>(N)->Name;
593  break;
594  case Node::KNestedName:
595  N = static_cast<const NestedName *>(N)->Name;
596  break;
597  case Node::KModuleEntity:
598  N = static_cast<const ModuleEntity *>(N)->Name;
599  break;
600  }
601  }
602  return false;
603 }
604 
606  assert(RootNode != nullptr && "must call partialDemangle()");
607  return static_cast<const Node *>(RootNode)->getKind() ==
608  Node::KFunctionEncoding;
609 }
610 
612  assert(RootNode != nullptr && "must call partialDemangle()");
613  auto K = static_cast<const Node *>(RootNode)->getKind();
614  return K == Node::KSpecialName || K == Node::KCtorVtableSpecialName;
615 }
616 
618  return !isFunction() && !isSpecialName();
619 }
Node::Prec::Multiplicative
@ Multiplicative
Node::Prec::Assign
@ Assign
ReferenceKind::RValue
@ RValue
llvm::ItaniumPartialDemangler::~ItaniumPartialDemangler
~ItaniumPartialDemangler()
Definition: ItaniumDemangle.cpp:403
llvm::demangle_invalid_mangled_name
@ demangle_invalid_mangled_name
Definition: Demangle.h:26
llvm::binaryformat::last
@ last
Definition: Swift.h:19
getName
static StringRef getName(Value *V)
Definition: ProvenanceAnalysisEvaluator.cpp:42
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
TemplateParamKind::NonType
@ NonType
llvm::ItaniumPartialDemangler::ItaniumPartialDemangler
ItaniumPartialDemangler()
Definition: ItaniumDemangle.cpp:400
print
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Definition: ArchiveWriter.cpp:189
llvm::ItaniumPartialDemangler::getFunctionName
char * getFunctionName(char *Buf, size_t *N) const
Get the entire name of this function.
Definition: ItaniumDemangle.cpp:515
QualConst
@ QualConst
Definition: ItaniumDemangle.h:395
T
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
QualRestrict
@ QualRestrict
Definition: ItaniumDemangle.h:397
double
into xmm2 addss xmm2 xmm1 xmm3 addss xmm3 movaps xmm0 unpcklps xmm0 ret seems silly when it could just be one addps Expand libm rounding functions main should enable SSE DAZ mode and other fast SSE modes Think about doing i64 math in SSE regs on x86 This testcase should have no SSE instructions in and only one load from a constant double
Definition: README-SSE.txt:85
Node::Prec::Primary
@ Primary
TemplateParamKind::Template
@ Template
ModuleEntity::Name
Node * Name
Definition: ItaniumDemangle.h:1022
Node::Prec::Default
@ Default
llvm::Depth
@ Depth
Definition: SIMachineScheduler.h:36
QualVolatile
@ QualVolatile
Definition: ItaniumDemangle.h:396
llvm::ItaniumPartialDemangler::isSpecialName
bool isSpecialName() const
If this symbol is a <special-name>.
Definition: ItaniumDemangle.cpp:611
llvm::ItaniumPartialDemangler
"Partial" demangler.
Definition: Demangle.h:78
Node::Prec::Conditional
@ Conditional
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:119
llvm::dump
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Definition: SparseBitVector.h:877
QualNone
@ QualNone
Definition: ItaniumDemangle.h:394
SpecialSubKind::allocator
@ allocator
llvm::ItaniumPartialDemangler::partialDemangle
bool partialDemangle(const char *MangledName)
Demangle into an AST.
Definition: ItaniumDemangle.cpp:421
SpecialSubKind::istream
@ istream
ReferenceKind::LValue
@ LValue
llvm::demangle_invalid_args
@ demangle_invalid_args
Definition: Demangle.h:25
new
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM ID Predecessors according to mbb< bb27, 0x8b0a7c0 > Note ADDri is not a two address instruction its result reg1037 is an operand of the PHI node in bb76 and its operand reg1039 is the result of the PHI node We should treat it as a two address code and make sure the ADDri is scheduled after any node that reads reg1039 Use info(i.e. register scavenger) to assign it a free register to allow reuse the collector could move the objects and invalidate the derived pointer This is bad enough in the first but safe points can crop up unpredictably **array_addr i32 n y store obj * new
Definition: README.txt:125
Demangler
itanium_demangle::ManglingParser< DefaultAllocator > Demangler
Definition: ItaniumDemangle.cpp:366
llvm::X86II::OB
@ OB
Definition: X86BaseInfo.h:801
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
Node::Prec::AndIf
@ AndIf
Node::Prec::Xor
@ Xor
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::ARM_PROC::A
@ A
Definition: ARMBaseInfo.h:34
FrefQualRValue
@ FrefQualRValue
Definition: ItaniumDemangle.h:390
Node::Prec
Prec
Operator precedence for expression nodes.
Definition: ItaniumDemangle.h:168
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
First
into llvm powi allowing the code generator to produce balanced multiplication trees First
Definition: README.txt:54
Node::Prec::Additive
@ Additive
LocalName
Definition: ItaniumDemangle.h:1038
Node::Prec::Equality
@ Equality
printNode
static char * printNode(const Node *RootNode, char *Buf, size_t *N)
Definition: ItaniumDemangle.cpp:429
SpecialSubKind::iostream
@ iostream
parse_discriminator
const char * parse_discriminator(const char *first, const char *last)
llvm::ItaniumPartialDemangler::operator=
ItaniumPartialDemangler & operator=(ItaniumPartialDemangler &&Other)
Definition: ItaniumDemangle.cpp:414
Node::Prec::Unary
@ Unary
SpecialSubKind
SpecialSubKind
Definition: ItaniumDemangle.h:1512
llvm::ItaniumPartialDemangler::isData
bool isData() const
If this symbol describes a variable.
Definition: ItaniumDemangle.cpp:617
llvm::ItaniumPartialDemangler::getFunctionParameters
char * getFunctionParameters(char *Buf, size_t *N) const
Get the parameters for this function.
Definition: ItaniumDemangle.cpp:522
Alloc
Node::Prec::Shift
@ Shift
Qualifiers
Qualifiers
Definition: ItaniumDemangle.h:393
I
#define I(x, y, z)
Definition: MD5.cpp:58
Node::Prec::Postfix
@ Postfix
TemplateParamKind::Type
@ Type
llvm::ItaniumPartialDemangler::getFunctionDeclContextName
char * getFunctionDeclContextName(char *Buf, size_t *N) const
Get the context name for a function.
Definition: ItaniumDemangle.cpp:469
NestedName
Definition: ItaniumDemangle.h:980
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:853
Status
Definition: SIModeRegister.cpp:29
Node::Prec::PtrMem
@ PtrMem
Demangle.h
llvm::itanium_demangle
Definition: MicrosoftDemangleNodes.h:22
Node::Prec::And
@ And
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
Node::Prec::Relational
@ Relational
Node::print
void print(OutputBuffer &OB) const
Definition: ItaniumDemangle.h:273
NodeArray::printWithComma
void printWithComma(OutputBuffer &OB) const
Definition: ItaniumDemangle.h:315
llvm::ItaniumPartialDemangler::hasFunctionQualifiers
bool hasFunctionQualifiers() const
If this function has any any cv or reference qualifiers.
Definition: ItaniumDemangle.cpp:565
t1
<%struct.bf ** > define void t1() nounwind ssp
Definition: README.txt:1497
Node::Prec::Spaceship
@ Spaceship
ItaniumDemangle.h
name
static const char * name
Definition: SVEIntrinsicOpts.cpp:74
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
initializeOutputBuffer
bool initializeOutputBuffer(char *Buf, size_t *N, OutputBuffer &OB, size_t InitSize)
Definition: Utility.h:201
llvm::ItaniumPartialDemangler::getFunctionBaseName
char * getFunctionBaseName(char *Buf, size_t *N) const
Get the base name of a function.
Definition: ItaniumDemangle.cpp:440
FunctionRefQual
FunctionRefQual
Definition: ItaniumDemangle.h:387
SpecialSubKind::basic_string
@ basic_string
ModuleEntity
Definition: ItaniumDemangle.h:1020
AbiTagAttr
Definition: ItaniumDemangle.h:528
Node::Prec::Cast
@ Cast
Node::Prec::Comma
@ Comma
FunctionEncoding
Definition: ItaniumDemangle.h:865
llvm::demangle_success
@ demangle_success
Definition: Demangle.h:28
NameWithTemplateArgs
Definition: ItaniumDemangle.h:1477
llvm::demangle_memory_alloc_failure
@ demangle_memory_alloc_failure
Definition: Demangle.h:27
ReferenceKind
ReferenceKind
Definition: ItaniumDemangle.h:631
llvm::ItaniumPartialDemangler::getFunctionReturnType
char * getFunctionReturnType(char *Buf, size_t *N) const
Definition: ItaniumDemangle.cpp:541
N
#define N
Node::Prec::Ior
@ Ior
llvm::ItaniumPartialDemangler::finishDemangle
char * finishDemangle(char *Buf, size_t *N) const
Just print the entire mangled name into Buf.
Definition: ItaniumDemangle.cpp:560
llvm::itaniumDemangle
char * itaniumDemangle(const char *mangled_name, char *buf, size_t *n, int *status)
Definition: ItaniumDemangle.cpp:368
SpecialSubKind::ostream
@ ostream
NodeArray
Definition: ItaniumDemangle.h:298
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
TemplateParamKind
TemplateParamKind
Definition: ItaniumDemangle.h:1128
Node::Prec::OrIf
@ OrIf
FrefQualNone
@ FrefQualNone
Definition: ItaniumDemangle.h:388
FrefQualLValue
@ FrefQualLValue
Definition: ItaniumDemangle.h:389
LocalName::Encoding
Node * Encoding
Definition: ItaniumDemangle.h:1039
llvm::ItaniumPartialDemangler::isCtorOrDtor
bool isCtorOrDtor() const
If this symbol describes a constructor or destructor.
Definition: ItaniumDemangle.cpp:573
llvm::ItaniumPartialDemangler::isFunction
bool isFunction() const
If this symbol describes a function.
Definition: ItaniumDemangle.cpp:605
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
SpecialSubKind::string
@ string
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1247