42 const char *t1 = first + 1;
44 if (std::isdigit(*t1))
46 else if (*t1 ==
'_') {
47 for (++t1; t1 != last && std::isdigit(*t1); ++t1)
49 if (t1 != last && *t1 ==
'_')
53 }
else if (std::isdigit(*first)) {
54 const char *t1 = first + 1;
55 for (; t1 != last && std::isdigit(*t1); ++t1)
68 bool PendingNewline =
false;
70 template<
typename NodeT>
static constexpr
bool wantsNewline(
const NodeT *) {
74 static constexpr
bool wantsNewline(...) {
return false; }
76 template<
typename ...Ts>
static bool anyWantNewline(Ts ...Vs) {
77 for (
bool B : {wantsNewline(Vs)...})
83 void printStr(
const char *S) { fprintf(stderr,
"%s", S); }
85 fprintf(stderr,
"\"%.*s\"", (
int)SV.
size(), SV.
begin());
89 N->
visit(std::ref(*
this));
99 printStr(
"NodeOrString()");
105 for (
const Node *N : A) {
117 void print(
bool B) { printStr(B ?
"true" :
"false"); }
120 typename std::enable_if<std::is_unsigned<T>::value>
::type print(
T N) {
121 fprintf(stderr,
"%llu", (
unsigned long long)N);
125 typename std::enable_if<std::is_signed<T>::value>
::type print(
T N) {
126 fprintf(stderr,
"%lld", (
long long)N);
132 return printStr(
"ReferenceKind::LValue");
134 return printStr(
"ReferenceKind::RValue");
140 return printStr(
"FunctionRefQual::FrefQualNone");
142 return printStr(
"FunctionRefQual::FrefQualLValue");
144 return printStr(
"FunctionRefQual::FrefQualRValue");
148 if (!Qs)
return printStr(
"QualNone");
154 for (QualName
Name : Names) {
158 if (Qs) printStr(
" | ");
165 return printStr(
"SpecialSubKind::allocator");
167 return printStr(
"SpecialSubKind::basic_string");
169 return printStr(
"SpecialSubKind::string");
171 return printStr(
"SpecialSubKind::istream");
173 return printStr(
"SpecialSubKind::ostream");
175 return printStr(
"SpecialSubKind::iostream");
181 for (
unsigned I = 0;
I !=
Depth; ++
I)
183 PendingNewline =
false;
186 template<
typename T>
void printWithPendingNewline(
T V) {
189 PendingNewline =
true;
192 template<
typename T>
void printWithComma(
T V) {
193 if (PendingNewline || wantsNewline(V)) {
200 printWithPendingNewline(V);
203 struct CtorArgPrinter {
204 DumpVisitor &Visitor;
206 template<
typename T,
typename ...Rest>
void operator()(
T V, Rest ...Vs) {
207 if (Visitor.anyWantNewline(V, Vs...))
209 Visitor.printWithPendingNewline(V);
210 int PrintInOrder[] = { (Visitor.printWithComma(Vs), 0)..., 0 };
215 template<
typename NodeT>
void operator()(
const NodeT *
Node) {
218 Node->match(CtorArgPrinter{*
this});
219 fprintf(stderr,
")");
225 fprintf(stderr,
"ForwardTemplateReference(");
228 CtorArgPrinter{*
this}(Node->
Ref);
231 CtorArgPrinter{*
this}(Node->
Index);
233 fprintf(stderr,
")");
247 class BumpPointerAllocator {
253 static constexpr
size_t AllocSize = 4096;
254 static constexpr
size_t UsableAllocSize = AllocSize -
sizeof(BlockMeta);
256 alignas(
long double)
char InitialBuffer[AllocSize];
257 BlockMeta* BlockList =
nullptr;
260 char* NewMeta =
static_cast<char *
>(std::malloc(AllocSize));
261 if (NewMeta ==
nullptr)
263 BlockList =
new (NewMeta) BlockMeta{BlockList, 0};
266 void* allocateMassive(
size_t NBytes) {
267 NBytes +=
sizeof(BlockMeta);
268 BlockMeta* NewMeta =
reinterpret_cast<BlockMeta*
>(std::malloc(NBytes));
269 if (NewMeta ==
nullptr)
271 BlockList->Next =
new (NewMeta) BlockMeta{BlockList->Next, 0};
272 return static_cast<void*
>(NewMeta + 1);
276 BumpPointerAllocator()
277 : BlockList(
new (InitialBuffer) BlockMeta{
nullptr, 0}) {}
279 void* allocate(
size_t N) {
280 N = (N + 15u) & ~15u;
281 if (N + BlockList->Current >= UsableAllocSize) {
282 if (N > UsableAllocSize)
283 return allocateMassive(N);
286 BlockList->Current +=
N;
287 return static_cast<void*
>(
reinterpret_cast<char*
>(BlockList + 1) +
288 BlockList->Current - N);
293 BlockMeta* Tmp = BlockList;
294 BlockList = BlockList->Next;
295 if (reinterpret_cast<char*>(Tmp) != InitialBuffer)
298 BlockList =
new (InitialBuffer) BlockMeta{
nullptr, 0};
301 ~BumpPointerAllocator() { reset(); }
304 class DefaultAllocator {
305 BumpPointerAllocator Alloc;
308 void reset() { Alloc.reset(); }
310 template<
typename T,
typename ...Args>
T *makeNode(
Args &&...args) {
311 return new (Alloc.allocate(
sizeof(
T)))
312 T(std::forward<Args>(args)...);
315 void *allocateNodeArray(
size_t sz) {
316 return Alloc.allocate(
sizeof(
Node *) * sz);
329 if (MangledName ==
nullptr || (Buf !=
nullptr && N ==
nullptr)) {
336 Demangler Parser(MangledName, MangledName + std::strlen(MangledName));
355 *Status = InternalStatus;
363 delete static_cast<Demangler *
>(Context);
368 : RootNode(
Other.RootNode), Context(
Other.Context) {
382 size_t Len = std::strlen(MangledName);
383 Parser->
reset(MangledName, MangledName + Len);
384 RootNode = Parser->
parse();
385 return RootNode ==
nullptr;
407 case Node::KAbiTagAttr:
410 case Node::KStdQualifiedName:
413 case Node::KNestedName:
416 case Node::KLocalName:
419 case Node::KNameWithTemplateArgs:
438 KeepGoingLocalFunction:
440 if (Name->
getKind() == Node::KAbiTagAttr) {
444 if (Name->
getKind() == Node::KNameWithTemplateArgs) {
452 case Node::KStdQualifiedName:
455 case Node::KNestedName:
458 case Node::KLocalName: {
463 goto KeepGoingLocalFunction;
501 char *Buf,
size_t *
N)
const {
510 static_cast<const FunctionEncoding *>(RootNode)->getReturnType())
520 assert(RootNode !=
nullptr &&
"must call partialDemangle()");
521 return printNode(static_cast<Node *>(RootNode), Buf, N);
525 assert(RootNode !=
nullptr &&
"must call partialDemangle()");
533 const Node *
N =
static_cast<const Node *
>(RootNode);
538 case Node::KCtorDtorName:
541 case Node::KAbiTagAttr:
544 case Node::KFunctionEncoding:
547 case Node::KLocalName:
548 N =
static_cast<const LocalName *
>(
N)->Entity;
550 case Node::KNameWithTemplateArgs:
553 case Node::KNestedName:
556 case Node::KStdQualifiedName:
565 assert(RootNode !=
nullptr &&
"must call partialDemangle()");
566 return static_cast<const Node *
>(RootNode)->getKind() ==
567 Node::KFunctionEncoding;
571 assert(RootNode !=
nullptr &&
"must call partialDemangle()");
572 auto K =
static_cast<const Node *
>(RootNode)->getKind();
573 return K == Node::KSpecialName || K == Node::KCtorVtableSpecialName;
void visit(Fn F) const
Visit the most-derived object corresponding to this object.
char * itaniumDemangle(const char *mangled_name, char *buf, size_t *n, int *status)
ItaniumPartialDemangler & operator=(ItaniumPartialDemangler &&Other)
PODSmallVector< ForwardTemplateReference *, 4 > ForwardTemplateRefs
ItaniumPartialDemangler()
This class represents lattice values for constants.
LLVM_DUMP_METHOD void dump() const
bool isData() const
If this symbol describes a variable.
bool isFunction() const
If this symbol describes a function.
char * getFunctionName(char *Buf, size_t *N) const
Get the entire name of this function.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
static StringRef getName(Value *V)
const char * begin() const
bool isCtorOrDtor() const
If this symbol describes a constructor or destructor.
void printWithComma(OutputStream &S) const
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
size_t getCurrentPosition() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
char * getFunctionBaseName(char *Buf, size_t *N) const
Get the base name of a function.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Node * parse()
Top-level entry point into the parser.
bool partialDemangle(const char *MangledName)
Demangle into an AST.
A forward-reference to a template argument that was not known at the point where the template paramet...
char * getFunctionDeclContextName(char *Buf, size_t *N) const
Get the context name for a function.
char * getFunctionParameters(char *Buf, size_t *N) const
Get the parameters for this function.
char * getFunctionReturnType(char *Buf, size_t *N) const
bool isSpecialName() const
If this symbol is a <special-name>.
static char * printNode(const Node *RootNode, char *Buf, size_t *N)
void print(OutputStream &S) const
void reset(const char *First_, const char *Last_)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool hasFunctionQualifiers() const
If this function has any any cv or reference qualifiers.
char * finishDemangle(char *Buf, size_t *N) const
Just print the entire mangled name into Buf.
StringView asString() const
const char * parse_discriminator(const char *first, const char *last)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S, size_t InitSize)
const Node * asNode() const
Determine the kind of a node from its type.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
~ItaniumPartialDemangler()