[PATCH] D50930: Move Itanium demangler implementation into a header file and add visitation support.
Erik Pilkington via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 20 09:36:58 PDT 2018
erik.pilkington accepted this revision.
erik.pilkington added a comment.
LGTM too, thanks for doing this!
================
Comment at: include/llvm/Demangle/ItaniumDemangle.h:144
+ // would construct an equivalent node.
+ //template<typename Fn> void match(Fn F) const;
+
----------------
rsmith wrote:
> erik.pilkington wrote:
> > Shouldn't this be match(Fn &&)? Otherwise, someone using std::function would get needlessly bad performance by default.
> I'm following the convention used by the C++ standard library: function objects are passed by value by default, and users use `std::ref` to have them passed by copy instead. (Pass-by-value is likely better when copying is acceptable and the function object is small or empty.)
>
> That said, I forgot the `std::ref`s in the `dump()` implementation (fixed now). Perhaps that's a good argument to not follow the standard library convention.
Oh, okay, I guess it makes more sense to follow the standard conventions here then.
================
Comment at: include/llvm/Demangle/ItaniumDemangle.h:1136
- bool hasRHSComponentSlow(OutputStream &S) const override {
- if (Printing)
- return false;
- SwapAndRestore<bool> SavePrinting(Printing, true);
- return Ref->hasRHSComponent(S);
- }
+ // We don't provide a matcher for these, because the value of the node is
+ // not determined by its construction parameters, and it generally needs
----------------
rsmith wrote:
> erik.pilkington wrote:
> > Do you think it makes more sense from a library perspective to move the special-case rule to the implementation of the canonicalizer?
> Here are four example use cases for the visit/match functionality:
>
> 1) AST dumping. As this patch shows, `ForwardTemplateReference` is a special case. (We want to visit the resolved node where possible, not the template parameter index, and need to deal with infinite recursion.)
> 2) AST pretty-printing. (This is really the same as case 1.)
> 3) Canonicalizing allocation. We don't want to canonicalize `ForwardTemplateReference` based on constructor arguments, because two nodes with the same constructor arguments do not have the same meaning in general.
> 4) Cloning / tree transformation. We do not want to clone `ForwardTemplateReference` by calling the constructor with the same constructor arguments, because that would create an unresolved node.
>
> Every reasonable visitor I've considered wants to special-case `ForwardTemplateReference`. It is fundamentally different from the other nodes, because it is not immutable after construction, so there is no way to produce a set of constructor arguments that produce an identical node.
>
> So I think it's better to force every caller of `match` to think about this case by not providing a default implementation. Maybe adding a deleted version would be better though, to make it easier to see that this is intentional when the client hits the inevitable build break? I'll do that.
Okay, I agree then, that's pretty convincing.
================
Comment at: include/llvm/Demangle/ItaniumDemangle.h:1262
case SpecialSubKind::allocator:
S += "std::basic_string<char, std::char_traits<char>, "
"std::allocator<char> >";
----------------
rsmith wrote:
> dlj wrote:
> > Isn't this just std::allocator? (Assuming it's for `Sa`)
> Yes, that sure looks like a (pre-existing) bug! As it happens, this is unreachable, since we don't ever form an `ExpandedSpecialSubstitution` for `SpecialSubKind::allocator`. (The `SpecialSubKind::string` case is also wrong and also unreachable.)
>
> I'll fix this in a separate commit.
Oops! Since this was unreachable, we should just remove these cases from the `switch`.
================
Comment at: include/llvm/Demangle/ItaniumDemangle.h:1769
-class BumpPointerAllocator {
- struct BlockMeta {
----------------
rsmith wrote:
> erik.pilkington wrote:
> > I think you forgot to add a file that contained these definitions?
> This patch doesn't delete the existing lib/Demangle/ItaniumDemangle.cpp; this is still present there. Phabricator seems to hide its contents by default, though, so maybe that's why you're not seeing it?
Oh, right, my mistake!
================
Comment at: include/llvm/Demangle/ItaniumDemangle.h:28
-namespace {
// Base class of all AST nodes. The AST is built by the parser, then is
----------------
Don't remove this in the libcxxabi version, or enclose the `#include` in namespace {}!. You were probably planning on doing that, but just to be sure.
================
Comment at: lib/Demangle/ItaniumDemangle.cpp:63
#ifndef NDEBUG
- LLVM_DUMP_METHOD void dump() const {
- char *Buffer = static_cast<char*>(std::malloc(1024));
- OutputStream S(Buffer, 1024);
- print(S);
- S += '\0';
- printf("Symbol dump for %p: %s\n", (const void*)this, S.getBuffer());
- std::free(S.getBuffer());
- }
-#endif
-};
-
-class NodeArray {
- Node **Elements;
- size_t NumElements;
-
-public:
- NodeArray() : Elements(nullptr), NumElements(0) {}
- NodeArray(Node **Elements_, size_t NumElements_)
- : Elements(Elements_), NumElements(NumElements_) {}
-
- bool empty() const { return NumElements == 0; }
- size_t size() const { return NumElements; }
-
- Node **begin() const { return Elements; }
- Node **end() const { return Elements + NumElements; }
-
- Node *operator[](size_t Idx) const { return Elements[Idx]; }
-
- void printWithComma(OutputStream &S) const {
- bool FirstElement = true;
- for (size_t Idx = 0; Idx != NumElements; ++Idx) {
- size_t BeforeComma = S.getCurrentPosition();
- if (!FirstElement)
- S += ", ";
- size_t AfterComma = S.getCurrentPosition();
- Elements[Idx]->print(S);
-
- // Elements[Idx] is an empty parameter pack expansion, we should erase the
- // comma we just printed.
- if (AfterComma == S.getCurrentPosition()) {
- S.setCurrentPosition(BeforeComma);
- continue;
- }
-
- FirstElement = false;
- }
- }
-};
+struct DumpVisitor {
+ unsigned Depth = 0;
----------------
This should be defined in an anon namespace, right?
================
Comment at: lib/Demangle/ItaniumDemangle.cpp:236-238
+//===----------------------------------------------------------------------===//
+// Code beyond this point should not be synchronized with libc++abi.
+//===----------------------------------------------------------------------===//
----------------
I think this comment is too high: initializeOutputStream() and BumpPointerAllocator are both used in the libcxxabi version.
Repository:
rL LLVM
https://reviews.llvm.org/D50930
More information about the llvm-commits
mailing list