[PATCH] D36427: [libcxxabi][demangler] Improve representation of substitutions/templates
Duncan P. N. Exon Smith via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 7 17:11:03 PDT 2017
dexonsmith requested changes to this revision.
dexonsmith added a comment.
This revision now requires changes to proceed.
This looks like a great improvement. I've littered the patch with nit-picks, but my main concern is that there aren't any unit tests for the new data structures. I wonder if there's a hacky way to set that up...
================
Comment at: src/cxa_demangle.cpp:1460-1461
+template <class T, size_t N>
+class PODSmallVector {
+ static_assert(std::is_pod<T>::value, "");
----------------
This seems like a facility that should/could be unit tested (in C++).
I realize there's no precedent for that for the demangler. Perhaps this file could be `#include`d by a test file:
```
// unittest/PODSmallVectorTest.h
#include "../src/cxa_demangle.cpp"
namespace {
TEST(PODSmallVectorTest, ...) {
}
} // namespace
```
Thoughts?
================
Comment at: src/cxa_demangle.cpp:1462
+class PODSmallVector {
+ static_assert(std::is_pod<T>::value, "");
+
----------------
Please add an assertion string, such as `"T is required to be a plain-old data type"`.
================
Comment at: src/cxa_demangle.cpp:1499-1501
+ First = Inline;
+ Last = Inline;
+ Cap = Inline + N;
----------------
This is identical to code in the move constructor. Separate it out into a helper?
================
Comment at: src/cxa_demangle.cpp:1511-1517
+ First = Other.First;
+ Last = Other.Last;
+ Cap = Other.Cap;
+
+ Other.First = Other.Inline;
+ Other.Last = Other.Inline;
+ Other.Cap = Other.Inline + N;
----------------
Helper?
================
Comment at: src/cxa_demangle.cpp:1527-1535
+ size_t S = size();
+ if (!isInline()) {
+ First = static_cast<T*>(std::realloc(First, sizeof(T) * S * 2));
+ } else {
+ First = static_cast<T*>(std::malloc(sizeof(T) * S * 2));
+ std::copy(std::begin(Inline), std::end(Inline), First);
+ }
----------------
Should we assert when `nullptr` is returned from `std::malloc` or `std::realloc`?
================
Comment at: src/cxa_demangle.cpp:1540-1542
+ void pop_back() { --Last; }
+
+ void dropBack(size_t Index) { Last = First + Index; }
----------------
Assertions on popping/dropping past empty?
================
Comment at: src/cxa_demangle.cpp:1549-1550
+ size_t size() const { return static_cast<size_t>(Last - First); }
+ T& back() { return *(Last - 1); }
+ T& operator[](size_t Index) { return *(begin() + Index); }
+ void clear() { Last = First; }
----------------
Assertions on invalid access?
================
Comment at: src/cxa_demangle.cpp:1562
+template<size_t Size>
+class SubTable {
+ // Subs hold the actual entries in the table, and PackIndices tells us which
----------------
As I read this patch, I keep reading "sub" as a prefix. Can we just spell this out as "SubstitutionTable"?
Also, this probably deserves unit tests as well.
================
Comment at: src/cxa_demangle.cpp:1577-1580
+ void pushSub(Node* Entry) {
+ PackIndices.push_back(static_cast<unsigned>(Subs.size()));
+ Subs.push_back(Entry);
+ }
----------------
Can/should this be implemented using `pushPack()` and `pushSubIntoPack()`?
================
Comment at: src/cxa_demangle.cpp:1585
+ void pushPack() { PackIndices.push_back(static_cast<unsigned>(Subs.size())); }
+ void pushSubIntoPack(Node* Entry) { Subs.push_back(Entry); }
+
----------------
Do you need to assert that `pushPack` has been called at least once (i.e., `!PackIndices.empty()`)?
================
Comment at: src/cxa_demangle.cpp:1595
+ // For use in a range-for loop.
+ struct NodePair {
+ Node **First;
----------------
Perhaps `NodeRange` would be more clear.
================
Comment at: src/cxa_demangle.cpp:1596-1599
+ Node **First;
+ Node **Last;
+ Node **begin() { return First; }
+ Node **end() { return Last; }
----------------
Please be consistent with pointer style in this patch.
- I suspect the rest of the file attaches to the type, i.e., `Node** First`, which is why I didn't comment earlier on, e.g., `Node* Entry`.
- LLVM style is to attach to the name, like here.
I have a slight preference for switching toward LLVM style, but if the file consistently uses pointers attached to types, that's fine too. (Just be consistent within the patch.)
================
Comment at: src/cxa_demangle.cpp:1602
+
+ NodePair nthSub(size_t N) {
+ assert(N < PackIndices.size());
----------------
This could perhaps use a comment. At least, inside the function to explain the math.
================
Comment at: src/cxa_demangle.cpp:1603
+ NodePair nthSub(size_t N) {
+ assert(N < PackIndices.size());
+ Node **Begin = Subs.begin() + PackIndices[N];
----------------
Once you add this assertion to `operator[]` you can delete it here.
================
Comment at: src/cxa_demangle.cpp:1604
+ assert(N < PackIndices.size());
+ Node **Begin = Subs.begin() + PackIndices[N];
+ Node **End = (N + 1 == PackIndices.size())
----------------
Should there be some assertion on `Subs.size()` here? Perhaps, if so, this should be `&Subs[PackIndices[N]]`, so that `Subs.operator[]()` handles it for you. Same below.
================
Comment at: src/cxa_demangle.cpp:1605-1607
+ Node **End = (N + 1 == PackIndices.size())
+ ? Subs.end()
+ : Subs.begin() + PackIndices[N + 1];
----------------
Does this deserve its own helper function (e.g., `packEnd()`)? (I haven't read ahead to see if this logic is duplicated anywhere; probably not a separate function if it's not duplicated.)
================
Comment at: src/cxa_demangle.cpp:1621-1631
+ // Name stack, this is used by the parser to hold temporary names that were
+ // parsed. The parser colapses multiple names into new nodes to construct
+ // the AST. Once the parser is finished, names.size() == 1.
+ PODSmallVector<Node*, 32> names;
+
+ // Substitution table. Itanium supports name substitutions as a means of
+ // compression. The string "S42_" refers to the 42nd entry in this table.
----------------
How much have you thought about these sizes (32, 32, and 4)? Any evidence to back up these specific choices?
https://reviews.llvm.org/D36427
More information about the cfe-commits
mailing list