diff options
author | Erik Pilkington <erik.pilkington@gmail.com> | 2018-04-12 20:41:06 +0000 |
---|---|---|
committer | Erik Pilkington <erik.pilkington@gmail.com> | 2018-04-12 20:41:06 +0000 |
commit | 0df654b3bbf36bf98a5b83b070b069bd53b72966 (patch) | |
tree | 8d0a4a5e1e387516a0c183124564841a425ab2c0 | |
parent | 52c7a3760aef1df328a9bc957f686410872f0dc0 (diff) |
[demangler] NFC: Some refactoring to support partial demangling.
I'm committing this to libcxxabi too so that the two demanglers remain as
simular as possible.
git-svn-id: https://llvm.org/svn/llvm-project/libcxxabi/trunk@329950 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | src/cxa_demangle.cpp | 139 |
1 files changed, 97 insertions, 42 deletions
diff --git a/src/cxa_demangle.cpp b/src/cxa_demangle.cpp index 1348b10..d70ffdf 100644 --- a/src/cxa_demangle.cpp +++ b/src/cxa_demangle.cpp @@ -104,6 +104,12 @@ class OutputStream { public: OutputStream(char *StartBuf, size_t Size) : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {} + OutputStream() = default; + void reset(char *Buffer_, size_t BufferCapacity_) { + CurrentPosition = 0; + Buffer = Buffer_; + BufferCapacity = BufferCapacity_; + } /// If a ParameterPackExpansion (or similar type) is encountered, the offset /// into the pack that we're currently printing. @@ -184,7 +190,8 @@ public: KSpecialName, KCtorVtableSpecialName, KQualifiedName, - KEmptyName, + KNestedName, + KLocalName, KVectorType, KParameterPack, KTemplateArgumentPack, @@ -470,11 +477,11 @@ public: } }; -class AbiTagAttr final : public Node { - const Node* Base; +struct AbiTagAttr : Node { + Node *Base; StringView Tag; -public: - AbiTagAttr(const Node* Base_, StringView Tag_) + + AbiTagAttr(Node* Base_, StringView Tag_) : Node(KAbiTagAttr, Base_->RHSComponentCache, Base_->ArrayCache, Base_->FunctionCache), Base(Base_), Tag(Tag_) {} @@ -804,8 +811,8 @@ public: }; class FunctionEncoding final : public Node { - const Node *Ret; - const Node *Name; + Node *Ret; + Node *Name; NodeArray Params; Node *Attrs; Qualifiers CVQuals; @@ -820,6 +827,11 @@ public: Ret(Ret_), Name(Name_), Params(Params_), Attrs(Attrs_), CVQuals(CVQuals_), RefQual(RefQual_) {} + Qualifiers getCVQuals() const { return CVQuals; } + FunctionRefQual getRefQual() const { return RefQual; } + NodeArray getParams() const { return Params; } + Node *getReturnType() const { return Ret; } + bool hasRHSComponentSlow(OutputStream &) const override { return true; } bool hasFunctionSlow(OutputStream &) const override { return true; } @@ -901,6 +913,36 @@ public: } }; +struct NestedName : Node { + Node *Qual; + Node *Name; + + NestedName(Node *Qual_, Node *Name_) + : Node(KNestedName), Qual(Qual_), Name(Name_) {} + + StringView getBaseName() const override { return Name->getBaseName(); } + + void printLeft(OutputStream &S) const override { + Qual->print(S); + S += "::"; + Name->print(S); + } +}; + +struct LocalName : Node { + Node *Encoding; + Node *Entity; + + LocalName(Node *Encoding_, Node *Entity_) + : Node(KLocalName), Encoding(Encoding_), Entity(Entity_) {} + + void printLeft(OutputStream &S) const override { + Encoding->print(S); + S += "::"; + Entity->print(S); + } +}; + class QualifiedName final : public Node { // qualifier::name const Node *Qualifier; @@ -919,12 +961,6 @@ public: } }; -class EmptyName : public Node { -public: - EmptyName() : Node(KEmptyName) {} - void printLeft(OutputStream &) const override {} -}; - class VectorType final : public Node { const Node *BaseType; const NodeOrString Dimension; @@ -1148,12 +1184,11 @@ struct ForwardTemplateReference : Node { } }; -class NameWithTemplateArgs final : public Node { +struct NameWithTemplateArgs : Node { // name<template_args> Node *Name; Node *TemplateArgs; -public: NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_) : Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {} @@ -1180,10 +1215,9 @@ public: } }; -class StdQualifiedName final : public Node { +struct StdQualifiedName : Node { Node *Child; -public: StdQualifiedName(Node *Child_) : Node(KStdQualifiedName), Child(Child_) {} StringView getBaseName() const override { return Child->getBaseName(); } @@ -1887,14 +1921,17 @@ public: BlockList->Current - N); } - ~BumpPointerAllocator() { + void reset() { while (BlockList) { BlockMeta* Tmp = BlockList; BlockList = BlockList->Next; if (reinterpret_cast<char*>(Tmp) != InitialBuffer) delete[] reinterpret_cast<char*>(Tmp); } + BlockList = new (InitialBuffer) BlockMeta{nullptr, 0}; } + + ~BumpPointerAllocator() { reset(); } }; template <class T, size_t N> @@ -2042,6 +2079,18 @@ struct Db { Db(const char *First_, const char *Last_) : First(First_), Last(Last_) {} + void reset(const char *First_, const char *Last_) { + First = First_; + Last = Last_; + Names.clear(); + Subs.clear(); + TemplateParams.clear(); + ParsingLambdaParams = false; + TryToParseTemplateArgs = true; + PermitForwardTemplateReferences = false; + ASTAllocator.reset(); + } + template <class T, class... Args> T *make(Args &&... args) { return new (ASTAllocator.allocate(sizeof(T))) T(std::forward<Args>(args)...); @@ -2236,7 +2285,7 @@ Node *Db::parseLocalName(NameState *State) { if (consumeIf('s')) { First = parse_discriminator(First, Last); - return make<QualifiedName>(Encoding, make<NameType>("string literal")); + return make<LocalName>(Encoding, make<NameType>("string literal")); } if (consumeIf('d')) { @@ -2246,14 +2295,14 @@ Node *Db::parseLocalName(NameState *State) { Node *N = parseName(State); if (N == nullptr) return nullptr; - return make<QualifiedName>(Encoding, N); + return make<LocalName>(Encoding, N); } Node *Entity = parseName(State); if (Entity == nullptr) return nullptr; First = parse_discriminator(First, Last); - return make<QualifiedName>(Encoding, Entity); + return make<LocalName>(Encoding, Entity); } // <unscoped-name> ::= <unqualified-name> @@ -2709,7 +2758,7 @@ Node *Db::parseNestedName(NameState *State) { Node *SoFar = nullptr; auto PushComponent = [&](Node *Comp) { - if (SoFar) SoFar = make<QualifiedName>(SoFar, Comp); + if (SoFar) SoFar = make<NestedName>(SoFar, Comp); else SoFar = Comp; if (State) State->EndsWithTemplateArgs = false; }; @@ -4991,6 +5040,22 @@ Node *Db::parse() { return nullptr; return Ty; } + +bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S, + size_t InitSize) { + size_t BufferSize; + if (Buf == nullptr) { + Buf = static_cast<char *>(std::malloc(InitSize)); + if (Buf == nullptr) + return true; + BufferSize = InitSize; + } else + BufferSize = *N; + + S.reset(Buf, BufferSize); + return false; +} + } // unnamed namespace enum { @@ -5010,33 +5075,23 @@ __cxa_demangle(const char *MangledName, char *Buf, size_t *N, int *Status) { return nullptr; } - size_t BufSize = Buf != nullptr ? *N : 0; int InternalStatus = success; - size_t MangledNameLength = std::strlen(MangledName); + Db Parser(MangledName, MangledName + std::strlen(MangledName)); + OutputStream S; - Db Parser(MangledName, MangledName + MangledNameLength); Node *AST = Parser.parse(); if (AST == nullptr) InternalStatus = invalid_mangled_name; - - if (InternalStatus == success) { + else if (initializeOutputStream(Buf, N, S, 1024)) + InternalStatus = memory_alloc_failure; + else { assert(Parser.ForwardTemplateRefs.empty()); - - if (Buf == nullptr) { - BufSize = 1024; - Buf = static_cast<char*>(std::malloc(BufSize)); - } - - if (Buf) { - OutputStream Stream(Buf, BufSize); - AST->print(Stream); - Stream += '\0'; - if (N != nullptr) - *N = Stream.getCurrentPosition(); - Buf = Stream.getBuffer(); - } else - InternalStatus = memory_alloc_failure; + AST->print(S); + S += '\0'; + if (N != nullptr) + *N = S.getCurrentPosition(); + Buf = S.getBuffer(); } if (Status) |