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 | f2a9b0fddab7bd1382d759a0f2bf1efda2e9abed (patch) | |
tree | 5a59746f24b2e8a4278ff421f07d932ad68a541c /llvm/lib/Demangle/ItaniumDemangle.cpp | |
parent | 5ef2b52e5ba6a7e58543a3608195f6798d240697 (diff) | |
download | bcm5719-llvm-f2a9b0fddab7bd1382d759a0f2bf1efda2e9abed.tar.gz bcm5719-llvm-f2a9b0fddab7bd1382d759a0f2bf1efda2e9abed.zip |
[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.
llvm-svn: 329950
Diffstat (limited to 'llvm/lib/Demangle/ItaniumDemangle.cpp')
-rw-r--r-- | llvm/lib/Demangle/ItaniumDemangle.cpp | 139 |
1 files changed, 97 insertions, 42 deletions
diff --git a/llvm/lib/Demangle/ItaniumDemangle.cpp b/llvm/lib/Demangle/ItaniumDemangle.cpp index bac68c40711..62546533177 100644 --- a/llvm/lib/Demangle/ItaniumDemangle.cpp +++ b/llvm/lib/Demangle/ItaniumDemangle.cpp @@ -96,6 +96,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. @@ -176,7 +182,8 @@ public: KSpecialName, KCtorVtableSpecialName, KQualifiedName, - KEmptyName, + KNestedName, + KLocalName, KVectorType, KParameterPack, KTemplateArgumentPack, @@ -462,11 +469,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_) {} @@ -796,8 +803,8 @@ public: }; class FunctionEncoding final : public Node { - const Node *Ret; - const Node *Name; + Node *Ret; + Node *Name; NodeArray Params; Node *Attrs; Qualifiers CVQuals; @@ -812,6 +819,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; } @@ -893,6 +905,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; @@ -911,12 +953,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; @@ -1140,12 +1176,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_) {} @@ -1172,10 +1207,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(); } @@ -1879,14 +1913,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> @@ -2034,6 +2071,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)...); @@ -2228,7 +2277,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')) { @@ -2238,14 +2287,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> @@ -2701,7 +2750,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; }; @@ -4983,6 +5032,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 { @@ -5001,33 +5066,23 @@ char *llvm::itaniumDemangle(const char *MangledName, char *Buf, 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) |