erik.pilkington created this revision.
Herald added a reviewer: EricWF.

This is a NFC patch to not make every parse_* function templated on Db, which 
makes it easier to use methods on Db because it isn't dependent anymore. This 
is a prerequisite to using an AST to demangle, as per this thread: 
http://lists.llvm.org/pipermail/llvm-dev/2017-June/114448.html

Thanks,
Erik


https://reviews.llvm.org/D35158

Files:
  src/cxa_demangle.cpp

Index: src/cxa_demangle.cpp
===================================================================
--- src/cxa_demangle.cpp
+++ src/cxa_demangle.cpp
@@ -41,23 +41,223 @@
     success
 };
 
-template <class C>
-    const char* parse_type(const char* first, const char* last, C& db);
-template <class C>
-    const char* parse_encoding(const char* first, const char* last, C& db);
-template <class C>
-    const char* parse_name(const char* first, const char* last, C& db,
-                           bool* ends_with_template_args = 0);
-template <class C>
-    const char* parse_expression(const char* first, const char* last, C& db);
-template <class C>
-    const char* parse_template_args(const char* first, const char* last, C& db);
-template <class C>
-    const char* parse_operator_name(const char* first, const char* last, C& db);
-template <class C>
-    const char* parse_unqualified_name(const char* first, const char* last, C& db);
-template <class C>
-    const char* parse_decltype(const char* first, const char* last, C& db);
+template <std::size_t N>
+class arena
+{
+    static const std::size_t alignment = 16;
+    alignas(alignment) char buf_[N];
+    char* ptr_;
+
+    std::size_t 
+    align_up(std::size_t n) noexcept
+        {return (n + (alignment-1)) & ~(alignment-1);}
+
+    bool
+    pointer_in_buffer(char* p) noexcept
+        {return buf_ <= p && p <= buf_ + N;}
+
+public:
+    arena() noexcept : ptr_(buf_) {}
+    ~arena() {ptr_ = nullptr;}
+    arena(const arena&) = delete;
+    arena& operator=(const arena&) = delete;
+
+    char* allocate(std::size_t n);
+    void deallocate(char* p, std::size_t n) noexcept;
+
+    static constexpr std::size_t size() {return N;}
+    std::size_t used() const {return static_cast<std::size_t>(ptr_ - buf_);}
+    void reset() {ptr_ = buf_;}
+};
+
+template <std::size_t N>
+char*
+arena<N>::allocate(std::size_t n)
+{
+    n = align_up(n);
+    if (static_cast<std::size_t>(buf_ + N - ptr_) >= n)
+    {
+        char* r = ptr_;
+        ptr_ += n;
+        return r;
+    }
+    return static_cast<char*>(std::malloc(n));
+}
+
+template <std::size_t N>
+void
+arena<N>::deallocate(char* p, std::size_t n) noexcept
+{
+    if (pointer_in_buffer(p))
+    {
+        n = align_up(n);
+        if (p + n == ptr_)
+            ptr_ = p;
+    }
+    else
+        std::free(p);
+}
+
+template <class T, std::size_t N>
+class short_alloc
+{
+    arena<N>& a_;
+public:
+    typedef T value_type;
+
+public:
+    template <class _Up> struct rebind {typedef short_alloc<_Up, N> other;};
+
+    short_alloc(arena<N>& a) noexcept : a_(a) {}
+    template <class U>
+        short_alloc(const short_alloc<U, N>& a) noexcept
+            : a_(a.a_) {}
+    short_alloc(const short_alloc&) = default;
+    short_alloc& operator=(const short_alloc&) = delete;
+
+    T* allocate(std::size_t n)
+    {
+        return reinterpret_cast<T*>(a_.allocate(n*sizeof(T)));
+    }
+    void deallocate(T* p, std::size_t n) noexcept
+    {
+        a_.deallocate(reinterpret_cast<char*>(p), n*sizeof(T));
+    }
+
+    template <class T1, std::size_t N1, class U, std::size_t M>
+    friend
+    bool
+    operator==(const short_alloc<T1, N1>& x, const short_alloc<U, M>& y) noexcept;
+
+    template <class U, std::size_t M> friend class short_alloc;
+};
+
+template <class T, std::size_t N, class U, std::size_t M>
+inline
+bool
+operator==(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept
+{
+    return N == M && &x.a_ == &y.a_;
+}
+
+template <class T, std::size_t N, class U, std::size_t M>
+inline
+bool
+operator!=(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept
+{
+    return !(x == y);
+}
+
+template <class T>
+class malloc_alloc
+{
+public:
+    typedef T value_type;
+    typedef T& reference;
+    typedef const T& const_reference;
+    typedef T* pointer;
+    typedef const T* const_pointer;
+    typedef std::size_t size_type;
+    typedef std::ptrdiff_t difference_type;
+
+    malloc_alloc() = default;
+    template <class U> malloc_alloc(const malloc_alloc<U>&) noexcept {}
+
+    T* allocate(std::size_t n)
+    {
+        return static_cast<T*>(std::malloc(n*sizeof(T)));
+    }
+    void deallocate(T* p, std::size_t) noexcept
+    {
+        std::free(p);
+    }
+
+    template <class U> struct rebind { using other = malloc_alloc<U>; };
+    template <class U, class... Args>
+    void construct(U* p, Args&&... args)
+    {
+        ::new ((void*)p) U(std::forward<Args>(args)...);
+    }
+    void destroy(T* p)
+    {
+        p->~T();
+    }
+};
+
+template <class T, class U>
+inline
+bool
+operator==(const malloc_alloc<T>&, const malloc_alloc<U>&) noexcept
+{
+    return true;
+}
+
+template <class T, class U>
+inline
+bool
+operator!=(const malloc_alloc<T>& x, const malloc_alloc<U>& y) noexcept
+{
+    return !(x == y);
+}
+
+const size_t bs = 4 * 1024;
+template <class T> using Alloc = short_alloc<T, bs>;
+template <class T> using Vector = std::vector<T, Alloc<T>>;
+
+template <class StrT>
+struct string_pair
+{
+    StrT first;
+    StrT second;
+
+    string_pair() = default;
+    string_pair(StrT f) : first(std::move(f)) {}
+    string_pair(StrT f, StrT s)
+        : first(std::move(f)), second(std::move(s)) {}
+    template <size_t N>
+        string_pair(const char (&s)[N]) : first(s, N-1) {}
+
+    size_t size() const {return first.size() + second.size();}
+    bool empty() const { return first.empty() && second.empty(); }
+    StrT full() const {return first + second;}
+    StrT move_full() {return std::move(first) + std::move(second);}
+};
+
+struct Db
+{
+    typedef std::basic_string<char, std::char_traits<char>,
+                              malloc_alloc<char>> String;
+    typedef Vector<string_pair<String>> sub_type;
+    typedef Vector<sub_type> template_param_type;
+    sub_type names;
+    template_param_type subs;
+    Vector<template_param_type> template_param;
+    unsigned cv = 0;
+    unsigned ref = 0;
+    unsigned encoding_depth = 0;
+    bool parsed_ctor_dtor_cv = false;
+    bool tag_templates = true;
+    bool fix_forward_references = false;
+    bool try_to_parse_template_args = true;
+
+    template <size_t N>
+    Db(arena<N>& ar) :
+        names(ar),
+        subs(0, names, ar),
+        template_param(0, subs, ar)
+    {}
+};
+
+
+const char* parse_type(const char* first, const char* last, Db& db);
+const char* parse_encoding(const char* first, const char* last, Db& db);
+const char* parse_name(const char* first, const char* last, Db& db,
+                       bool* ends_with_template_args = 0);
+const char* parse_expression(const char* first, const char* last, Db& db);
+const char* parse_template_args(const char* first, const char* last, Db& db);
+const char* parse_operator_name(const char* first, const char* last, Db& db);
+const char* parse_unqualified_name(const char* first, const char* last, Db& db);
+const char* parse_decltype(const char* first, const char* last, Db& db);
 
 template <class C>
 void
@@ -178,9 +378,9 @@
 
 constexpr const char* float_data<long double>::spec;
 
-template <class Float, class C>
+template <class Float>
 const char*
-parse_floating_number(const char* first, const char* last, C& db)
+parse_floating_number(const char* first, const char* last, Db& db)
 {
     const size_t N = float_data<Float>::mangled_size;
     if (static_cast<std::size_t>(last - first) > N)
@@ -213,18 +413,17 @@
             int n = snprintf(num, sizeof(num), float_data<Float>::spec, value);
             if (static_cast<std::size_t>(n) >= sizeof(num))
                 return first;
-            db.names.push_back(typename C::String(num, static_cast<std::size_t>(n)));
+            db.names.push_back(Db::String(num, static_cast<std::size_t>(n)));
             first = t+1;
         }
     }
     return first;
 }
 
 // <source-name> ::= <positive length number> <identifier>
 
-template <class C>
 const char*
-parse_source_name(const char* first, const char* last, C& db)
+parse_source_name(const char* first, const char* last, Db& db)
 {
     if (first != last)
     {
@@ -241,7 +440,7 @@
             }
             if (static_cast<size_t>(last - t) >= n)
             {
-                typename C::String r(t, n);
+                Db::String r(t, n);
                 if (r.substr(0, 10) == "_GLOBAL__N")
                     db.names.push_back("(anonymous namespace)");
                 else
@@ -264,9 +463,8 @@
 // <substitution> ::= So # ::std::basic_ostream<char,  std::char_traits<char> >
 // <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
 
-template <class C>
 const char*
-parse_substitution(const char* first, const char* last, C& db)
+parse_substitution(const char* first, const char* last, Db& db)
 {
     if (last - first >= 2)
     {
@@ -372,9 +570,8 @@
 //                ::= Dn   # std::nullptr_t (i.e., decltype(nullptr))
 //                ::= u <source-name>    # vendor extended type
 
-template <class C>
 const char*
-parse_builtin_type(const char* first, const char* last, C& db)
+parse_builtin_type(const char* first, const char* last, Db& db)
 {
     if (first != last)
     {
@@ -550,9 +747,8 @@
 // <template-param> ::= T_    # first template parameter
 //                  ::= T <parameter-2 non-negative number> _
 
-template <class C>
 const char*
-parse_template_param(const char* first, const char* last, C& db)
+parse_template_param(const char* first, const char* last, Db& db)
 {
     if (last - first >= 2)
     {
@@ -595,7 +791,7 @@
                 }
                 else
                 {
-                    db.names.push_back(typename C::String(first, t+1));
+                    db.names.push_back(Db::String(first, t+1));
                     first = t+1;
                     db.fix_forward_references = true;
                 }
@@ -607,9 +803,8 @@
 
 // cc <type> <expression>                               # const_cast<type> (expression)
 
-template <class C>
 const char*
-parse_const_cast_expr(const char* first, const char* last, C& db)
+parse_const_cast_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 'c' && first[1] == 'c')
     {
@@ -635,9 +830,8 @@
 
 // dc <type> <expression>                               # dynamic_cast<type> (expression)
 
-template <class C>
 const char*
-parse_dynamic_cast_expr(const char* first, const char* last, C& db)
+parse_dynamic_cast_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 'd' && first[1] == 'c')
     {
@@ -663,9 +857,8 @@
 
 // rc <type> <expression>                               # reinterpret_cast<type> (expression)
 
-template <class C>
 const char*
-parse_reinterpret_cast_expr(const char* first, const char* last, C& db)
+parse_reinterpret_cast_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 'r' && first[1] == 'c')
     {
@@ -691,9 +884,8 @@
 
 // sc <type> <expression>                               # static_cast<type> (expression)
 
-template <class C>
 const char*
-parse_static_cast_expr(const char* first, const char* last, C& db)
+parse_static_cast_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 's' && first[1] == 'c')
     {
@@ -717,9 +909,8 @@
 
 // sp <expression>                                  # pack expansion
 
-template <class C>
 const char*
-parse_pack_expansion(const char* first, const char* last, C& db)
+parse_pack_expansion(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 's' && first[1] == 'p')
     {
@@ -732,9 +923,8 @@
 
 // st <type>                                            # sizeof (a type)
 
-template <class C>
 const char*
-parse_sizeof_type_expr(const char* first, const char* last, C& db)
+parse_sizeof_type_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 's' && first[1] == 't')
     {
@@ -752,9 +942,8 @@
 
 // sz <expr>                                            # sizeof (a expression)
 
-template <class C>
 const char*
-parse_sizeof_expr_expr(const char* first, const char* last, C& db)
+parse_sizeof_expr_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 's' && first[1] == 'z')
     {
@@ -772,18 +961,17 @@
 
 // sZ <template-param>                                  # size of a parameter pack
 
-template <class C>
 const char*
-parse_sizeof_param_pack_expr(const char* first, const char* last, C& db)
+parse_sizeof_param_pack_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'T')
     {
         size_t k0 = db.names.size();
         const char* t = parse_template_param(first+2, last, db);
         size_t k1 = db.names.size();
         if (t != first+2)
         {
-            typename C::String tmp("sizeof...(");
+            Db::String tmp("sizeof...(");
             size_t k = k0;
             if (k != k1)
             {
@@ -806,9 +994,8 @@
 //                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> _         # L > 0, first parameter
 //                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> <parameter-2 non-negative number> _   # L > 0, second and later parameters
 
-template <class C>
 const char*
-parse_function_param(const char* first, const char* last, C& db)
+parse_function_param(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && *first == 'f')
     {
@@ -819,7 +1006,7 @@
             const char* t1 = parse_number(t, last);
             if (t1 != last && *t1 == '_')
             {
-                db.names.push_back("fp" + typename C::String(t, t1));
+                db.names.push_back("fp" + Db::String(t, t1));
                 first = t1+1;
             }
         }
@@ -834,7 +1021,7 @@
                 const char* t1 = parse_number(t, last);
                 if (t1 != last && *t1 == '_')
                 {
-                    db.names.push_back("fp" + typename C::String(t, t1));
+                    db.names.push_back("fp" + Db::String(t, t1));
                     first = t1+1;
                 }
             }
@@ -845,9 +1032,8 @@
 
 // sZ <function-param>                                  # size of a function parameter pack
 
-template <class C>
 const char*
-parse_sizeof_function_param_pack_expr(const char* first, const char* last, C& db)
+parse_sizeof_function_param_pack_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'f')
     {
@@ -866,9 +1052,8 @@
 // te <expression>                                      # typeid (expression)
 // ti <type>                                            # typeid (type)
 
-template <class C>
 const char*
-parse_typeid_expr(const char* first, const char* last, C& db)
+parse_typeid_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 't' && (first[1] == 'e' || first[1] == 'i'))
     {
@@ -890,9 +1075,8 @@
 
 // tw <expression>                                      # throw expression
 
-template <class C>
 const char*
-parse_throw_expr(const char* first, const char* last, C& db)
+parse_throw_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 't' && first[1] == 'w')
     {
@@ -910,9 +1094,8 @@
 
 // ds <expression> <expression>                         # expr.*expr
 
-template <class C>
 const char*
-parse_dot_star_expr(const char* first, const char* last, C& db)
+parse_dot_star_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 'd' && first[1] == 's')
     {
@@ -936,9 +1119,8 @@
 
 // <simple-id> ::= <source-name> [ <template-args> ]
 
-template <class C>
 const char*
-parse_simple_id(const char* first, const char* last, C& db)
+parse_simple_id(const char* first, const char* last, Db& db)
 {
     if (first != last)
     {
@@ -966,9 +1148,8 @@
 //                   ::= <decltype>
 //                   ::= <substitution>
 
-template <class C>
 const char*
-parse_unresolved_type(const char* first, const char* last, C& db)
+parse_unresolved_type(const char* first, const char* last, Db& db)
 {
     if (first != last)
     {
@@ -982,7 +1163,7 @@
             size_t k1 = db.names.size();
             if (t != first && k1 == k0 + 1)
             {
-                db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                 first = t;
             }
             else
@@ -998,7 +1179,7 @@
             {
                 if (db.names.empty())
                     return first;
-                db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                 first = t;
             }
             break;
@@ -1016,7 +1197,7 @@
                         if (db.names.empty())
                             return first;
                         db.names.back().first.insert(0, "std::");
-                        db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                        db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                         first = t;
                     }
                 }
@@ -1030,9 +1211,8 @@
 // <destructor-name> ::= <unresolved-type>                               # e.g., ~T or ~decltype(f())
 //                   ::= <simple-id>                                     # e.g., ~A<2*N>
 
-template <class C>
 const char*
-parse_destructor_name(const char* first, const char* last, C& db)
+parse_destructor_name(const char* first, const char* last, Db& db)
 {
     if (first != last)
     {
@@ -1058,9 +1238,8 @@
 //                        ::= dn <destructor-name>                       # destructor or pseudo-destructor;
 //                                                                         # e.g. ~X or ~X<N-1>
 
-template <class C>
 const char*
-parse_base_unresolved_name(const char* first, const char* last, C& db)
+parse_base_unresolved_name(const char* first, const char* last, Db& db)
 {
     if (last - first >= 2)
     {
@@ -1117,9 +1296,8 @@
 
 // <unresolved-qualifier-level> ::= <simple-id>
 
-template <class C>
 const char*
-parse_unresolved_qualifier_level(const char* first, const char* last, C& db)
+parse_unresolved_qualifier_level(const char* first, const char* last, Db& db)
 {
     return parse_simple_id(first, last, db);
 }
@@ -1134,9 +1312,8 @@
 //                                                                       # T::N::x /decltype(p)::N::x
 //  (ignored)        ::= srN <unresolved-type>  <unresolved-qualifier-level>+ E <base-unresolved-name>
 
-template <class C>
 const char*
-parse_unresolved_name(const char* first, const char* last, C& db)
+parse_unresolved_name(const char* first, const char* last, Db& db)
 {
     if (last - first > 2)
     {
@@ -1283,9 +1460,8 @@
 
 // dt <expression> <unresolved-name>                    # expr.name
 
-template <class C>
 const char*
-parse_dot_expr(const char* first, const char* last, C& db)
+parse_dot_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 'd' && first[1] == 't')
     {
@@ -1311,9 +1487,8 @@
 
 // cl <expression>+ E                                   # call
 
-template <class C>
 const char*
-parse_call_expr(const char* first, const char* last, C& db)
+parse_call_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 4 && first[0] == 'c' && first[1] == 'l')
     {
@@ -1325,7 +1500,7 @@
             if (db.names.empty())
                 return first;
             db.names.back().first += db.names.back().second;
-            db.names.back().second = typename C::String();
+            db.names.back().second = Db::String();
             db.names.back().first.append("(");
             bool first_expr = true;
             while (*t != 'E')
@@ -1366,9 +1541,8 @@
 // [gs] na <expression>* _ <type> <initializer>         # new[] (expr-list) type (init)
 // <initializer> ::= pi <expression>* E                 # parenthesized initialization
 
-template <class C>
 const char*
-parse_new_expr(const char* first, const char* last, C& db)
+parse_new_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 4)
     {
@@ -1446,7 +1620,7 @@
             }
             if (*t != 'E')
                 return first;
-            typename C::String init_list;
+            Db::String init_list;
             if (has_init)
             {
                 if (db.names.empty())
@@ -1458,15 +1632,15 @@
                 return first;
             auto type = db.names.back().move_full();
             db.names.pop_back();
-            typename C::String expr_list;
+            Db::String expr_list;
             if (has_expr_list)
             {
                 if (db.names.empty())
                     return first;
                 expr_list = db.names.back().move_full();
                 db.names.pop_back();
             }
-            typename C::String r;
+            Db::String r;
             if (parsed_gs)
                 r = "::";
             if (is_array)
@@ -1488,9 +1662,8 @@
 // cv <type> <expression>                               # conversion with one argument
 // cv <type> _ <expression>* E                          # conversion with a different number of arguments
 
-template <class C>
 const char*
-parse_conversion_expr(const char* first, const char* last, C& db)
+parse_conversion_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 'c' && first[1] == 'v')
     {
@@ -1555,9 +1728,8 @@
 
 // pt <expression> <expression>                    # expr->name
 
-template <class C>
 const char*
-parse_arrow_expr(const char* first, const char* last, C& db)
+parse_arrow_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 'p' && first[1] == 't')
     {
@@ -1585,9 +1757,8 @@
 
 // <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
 
-template <class C>
 const char*
-parse_function_type(const char* first, const char* last, C& db)
+parse_function_type(const char* first, const char* last, Db& db)
 {
     if (first != last && *first == 'F')
     {
@@ -1604,7 +1775,7 @@
             if (t1 != t)
             {
                 t = t1;
-                typename C::String sig("(");
+                Db::String sig("(");
                 int ref_qual = 0;
                 while (true)
                 {
@@ -1674,9 +1845,8 @@
 
 // <pointer-to-member-type> ::= M <class type> <member type>
 
-template <class C>
 const char*
-parse_pointer_to_member_type(const char* first, const char* last, C& db)
+parse_pointer_to_member_type(const char* first, const char* last, Db& db)
 {
     if (first != last && *first == 'M')
     {
@@ -1711,9 +1881,8 @@
 // <array-type> ::= A <positive dimension number> _ <element type>
 //              ::= A [<dimension expression>] _ <element type>
 
-template <class C>
 const char*
-parse_array_type(const char* first, const char* last, C& db)
+parse_array_type(const char* first, const char* last, Db& db)
 {
     if (first != last && *first == 'A' && first+1 != last)
     {
@@ -1742,7 +1911,7 @@
                         return first;
                     if (db.names.back().second.substr(0, 2) == " [")
                         db.names.back().second.erase(0, 1);
-                    db.names.back().second.insert(0, " [" + typename C::String(first+1, t) + "]");
+                    db.names.back().second.insert(0, " [" + Db::String(first+1, t) + "]");
                     first = t2;
                 }
             }
@@ -1775,9 +1944,8 @@
 // <decltype>  ::= Dt <expression> E  # decltype of an id-expression or class member access (C++0x)
 //             ::= DT <expression> E  # decltype of an expression (C++0x)
 
-template <class C>
 const char*
-parse_decltype(const char* first, const char* last, C& db)
+parse_decltype(const char* first, const char* last, Db& db)
 {
     if (last - first >= 4 && first[0] == 'D')
     {
@@ -1808,9 +1976,8 @@
 // <extended element type> ::= <element type>
 //                         ::= p # AltiVec vector pixel
 
-template <class C>
 const char*
-parse_vector_type(const char* first, const char* last, C& db)
+parse_vector_type(const char* first, const char* last, Db& db)
 {
     if (last - first > 3 && first[0] == 'D' && first[1] == 'v')
     {
@@ -1830,21 +1997,21 @@
                     {
                         if (db.names.empty())
                             return first;
-                        db.names.back().first += " vector[" + typename C::String(num, sz) + "]";
+                        db.names.back().first += " vector[" + Db::String(num, sz) + "]";
                         first = t1;
                     }
                 }
                 else
                 {
                     ++t;
-                    db.names.push_back("pixel vector[" + typename C::String(num, sz) + "]");
+                    db.names.push_back("pixel vector[" + Db::String(num, sz) + "]");
                     first = t;
                 }
             }
         }
         else
         {
-            typename C::String num;
+            Db::String num;
             const char* t1 = first+2;
             if (*t1 != '_')
             {
@@ -1897,9 +2064,8 @@
 // <objc-name> ::= <k0 number> objcproto <k1 number> <identifier>  # k0 = 9 + <number of digits in k1> + k1
 // <objc-type> := <source-name>  # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
 
-template <class C>
 const char*
-parse_type(const char* first, const char* last, C& db)
+parse_type(const char* first, const char* last, Db& db)
 {
     if (first != last)
     {
@@ -1979,7 +2145,7 @@
                             if (db.names.empty())
                                 return first;
                             first = t;
-                            db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                            db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                         }
                         break;
                     case 'C':
@@ -1990,7 +2156,7 @@
                                 return first;
                             db.names.back().first.append(" complex");
                             first = t;
-                            db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                            db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                         }
                         break;
                     case 'F':
@@ -2000,7 +2166,7 @@
                             if (db.names.empty())
                                 return first;
                             first = t;
-                            db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                            db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                         }
                         break;
                     case 'G':
@@ -2011,7 +2177,7 @@
                                 return first;
                             db.names.back().first.append(" imaginary");
                             first = t;
-                            db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                            db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                         }
                         break;
                     case 'M':
@@ -2021,7 +2187,7 @@
                             if (db.names.empty())
                                 return first;
                             first = t;
-                            db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                            db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                         }
                         break;
                     case 'O':
@@ -2133,7 +2299,7 @@
                                     auto args = db.names.back().move_full();
                                     db.names.pop_back();
                                     db.names.back().first += std::move(args);
-                                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                                    db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                                     t = t1;
                                 }
                             }
@@ -2172,7 +2338,7 @@
                                             db.names.push_back(type + " " + proto);
                                         }
                                     }
-                                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                                    db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                                     first = t2;
                                 }
                             }
@@ -2186,7 +2352,7 @@
                             {
                                 if (db.names.empty())
                                     return first;
-                                db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                                db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                                 first = t;
                             }
                         }
@@ -2207,7 +2373,7 @@
                                     db.names.pop_back();
                                     db.names.back().first += template_args;
                                     // Need to create substitution for <template-template-param> <template-args>
-                                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                                    db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                                     first = t;
                                 }
                             }
@@ -2240,7 +2406,7 @@
                                 {
                                     if (db.names.empty())
                                         return first;
-                                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                                    db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                                     first = t;
                                     return first;
                                 }
@@ -2251,7 +2417,7 @@
                                 {
                                     if (db.names.empty())
                                         return first;
-                                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                                    db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                                     first = t;
                                     return first;
                                 }
@@ -2274,7 +2440,7 @@
                             {
                                 if (db.names.empty())
                                     return first;
-                                db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                                db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                                 first = t;
                             }
                         }
@@ -2340,9 +2506,8 @@
 //                   ::= rS    # >>=           
 //                   ::= v <digit> <source-name>        # vendor extended operator
 
-template <class C>
 const char*
-parse_operator_name(const char* first, const char* last, C& db)
+parse_operator_name(const char* first, const char* last, Db& db)
 {
     if (last - first >= 2)
     {
@@ -2640,9 +2805,8 @@
     return first;
 }
 
-template <class C>
 const char*
-parse_integer_literal(const char* first, const char* last, const typename C::String& lit, C& db)
+parse_integer_literal(const char* first, const char* last, const Db::String& lit, Db& db)
 {
     const char* t = parse_number(first, last);
     if (t != first && t != last && *t == 'E')
@@ -2671,9 +2835,8 @@
 //                ::= L <type> <real-part float> _ <imag-part float> E   # complex floating point literal (C 2000)
 //                ::= L <mangled-name> E                                 # external name
 
-template <class C>
 const char*
-parse_expr_primary(const char* first, const char* last, C& db)
+parse_expr_primary(const char* first, const char* last, Db& db)
 {
     if (last - first >= 4 && *first == 'L')
     {
@@ -2841,7 +3004,7 @@
                         {
                             if (db.names.empty())
                                 return first;
-                            db.names.back() = "(" + db.names.back().move_full() + ")" + typename C::String(t, n);
+                            db.names.back() = "(" + db.names.back().move_full() + ")" + Db::String(t, n);
                             first = n+1;
                             break;
                         }
@@ -2932,9 +3095,8 @@
 //                  ::= D2    # base object destructor
 //   extension      ::= D5    # ?
 
-template <class C>
 const char*
-parse_ctor_dtor_name(const char* first, const char* last, C& db)
+parse_ctor_dtor_name(const char* first, const char* last, Db& db)
 {
     if (last-first >= 2 && !db.names.empty())
     {
@@ -2982,18 +3144,17 @@
 // 
 // <lambda-sig> ::= <parameter type>+  # Parameter types or "v" if the lambda has no parameters
 
-template <class C>
 const char*
-parse_unnamed_type_name(const char* first, const char* last, C& db)
+parse_unnamed_type_name(const char* first, const char* last, Db& db)
 {
     if (last - first > 2 && first[0] == 'U')
     {
         char type = first[1];
         switch (type)
         {
         case 't':
           {
-            db.names.push_back(typename C::String("'unnamed"));
+            db.names.push_back(Db::String("'unnamed"));
             const char* t0 = first+2;
             if (t0 == last)
             {
@@ -3020,7 +3181,7 @@
         case 'l':
           {
             size_t lambda_pos = db.names.size();
-            db.names.push_back(typename C::String("'lambda'("));
+            db.names.push_back(Db::String("'lambda'("));
             const char* t0 = first+2;
             if (first[2] == 'v')
             {
@@ -3044,7 +3205,7 @@
                     // inserted into the name table. Walk through the names,
                     // appending each onto the lambda's parameter list.
                     std::for_each(db.names.begin() + k0, db.names.begin() + k1,
-                                  [&](typename C::sub_type::value_type &pair) {
+                                  [&](Db::sub_type::value_type &pair) {
                                       if (pair.empty())
                                           return;
                                       auto &lambda = db.names[lambda_pos].first;
@@ -3106,9 +3267,8 @@
 //                    ::= <source-name>   
 //                    ::= <unnamed-type-name>
 
-template <class C>
 const char*
-parse_unqualified_name(const char* first, const char* last, C& db)
+parse_unqualified_name(const char* first, const char* last, Db& db)
 {
     if (first != last)
     {
@@ -3153,9 +3313,8 @@
 //                 ::= St <unqualified-name>   # ::std::
 // extension       ::= StL<unqualified-name>
 
-template <class C>
 const char*
-parse_unscoped_name(const char* first, const char* last, C& db)
+parse_unscoped_name(const char* first, const char* last, Db& db)
 {
     if (last - first >= 2)
     {
@@ -3185,9 +3344,8 @@
 
 // at <type>                                            # alignof (a type)
 
-template <class C>
 const char*
-parse_alignof_type(const char* first, const char* last, C& db)
+parse_alignof_type(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 'a' && first[1] == 't')
     {
@@ -3205,9 +3363,8 @@
 
 // az <expression>                                            # alignof (a expression)
 
-template <class C>
 const char*
-parse_alignof_expr(const char* first, const char* last, C& db)
+parse_alignof_expr(const char* first, const char* last, Db& db)
 {
     if (last - first >= 3 && first[0] == 'a' && first[1] == 'z')
     {
@@ -3223,9 +3380,8 @@
     return first;
 }
 
-template <class C>
 const char*
-parse_noexcept_expression(const char* first, const char* last, C& db)
+parse_noexcept_expression(const char* first, const char* last, Db& db)
 {
     const char* t1 = parse_expression(first, last, db);
     if (t1 != first)
@@ -3238,9 +3394,8 @@
     return first;
 }
 
-template <class C>
 const char*
-parse_prefix_expression(const char* first, const char* last, const typename C::String& op, C& db)
+parse_prefix_expression(const char* first, const char* last, const Db::String& op, Db& db)
 {
     const char* t1 = parse_expression(first, last, db);
     if (t1 != first)
@@ -3253,9 +3408,8 @@
     return first;
 }
 
-template <class C>
 const char*
-parse_binary_expression(const char* first, const char* last, const typename C::String& op, C& db)
+parse_binary_expression(const char* first, const char* last, const Db::String& op, Db& db)
 {
     const char* t1 = parse_expression(first, last, db);
     if (t1 != first)
@@ -3323,9 +3477,8 @@
 //                                                                       # objectless nonstatic member reference
 //              ::= <expr-primary>
 
-template <class C>
 const char*
-parse_expression(const char* first, const char* last, C& db)
+parse_expression(const char* first, const char* last, Db& db)
 {
     if (last - first >= 2)
     {
@@ -3417,7 +3570,7 @@
                     {
                         if (db.names.empty())
                             return first;
-                        db.names.back().first = (parsed_gs ? typename C::String("::") : typename C::String()) +
+                        db.names.back().first = (parsed_gs ? Db::String("::") : Db::String()) +
                                           "delete[] " + db.names.back().move_full();
                         first = t1;
                     }
@@ -3438,7 +3591,7 @@
                     {
                         if (db.names.empty())
                             return first;
-                        db.names.back().first = (parsed_gs ? typename C::String("::") : typename C::String()) +
+                        db.names.back().first = (parsed_gs ? Db::String("::") : Db::String()) +
                                           "delete " + db.names.back().move_full();
                         first = t1;
                     }
@@ -3821,9 +3974,8 @@
 //                ::= J <template-arg>* E                                # argument pack
 //                ::= LZ <encoding> E                                    # extension
 
-template <class C>
 const char*
-parse_template_arg(const char* first, const char* last, C& db)
+parse_template_arg(const char* first, const char* last, Db& db)
 {
     if (first != last)
     {
@@ -3874,16 +4026,15 @@
 // <template-args> ::= I <template-arg>* E
 //     extension, the abi says <template-arg>+
 
-template <class C>
 const char*
-parse_template_args(const char* first, const char* last, C& db)
+parse_template_args(const char* first, const char* last, Db& db)
 {
     if (last - first >= 2 && *first == 'I')
     {
         if (db.tag_templates)
             db.template_param.back().clear();
         const char* t = first+1;
-        typename C::String args("<");
+        Db::String args("<");
         while (*t != 'E')
         {
             if (db.tag_templates)
@@ -3939,9 +4090,8 @@
 //                   ::= <template-param>
 //                   ::= <substitution>
 
-template <class C>
 const char*
-parse_nested_name(const char* first, const char* last, C& db,
+parse_nested_name(const char* first, const char* last, Db& db,
                   bool* ends_with_template_args)
 {
     if (first != last && *first == 'N')
@@ -3993,7 +4143,7 @@
                     if (!db.names.back().first.empty())
                     {
                         db.names.back().first += "::" + name;
-                        db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                        db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                     }
                     else
                         db.names.back().first = name;
@@ -4015,7 +4165,7 @@
                         db.names.back().first += "::" + name;
                     else
                         db.names.back().first = name;
-                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                    db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                     pop_subs = true;
                     t0 = t1;
                 }
@@ -4036,7 +4186,7 @@
                         db.names.back().first += "::" + name;
                     else
                         db.names.back().first = name;
-                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                    db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                     pop_subs = true;
                     t0 = t1;
                 }
@@ -4052,7 +4202,7 @@
                     if (db.names.empty())
                         return first;
                     db.names.back().first += name;
-                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                    db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                     t0 = t1;
                     component_ends_with_template_args = true;
                 }
@@ -4076,7 +4226,7 @@
                         db.names.back().first += "::" + name;
                     else
                         db.names.back().first = name;
-                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                    db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                     pop_subs = true;
                     t0 = t1;
                 }
@@ -4136,9 +4286,8 @@
 //              := Z <function encoding> E s [<discriminator>]
 //              := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
 
-template <class C>
 const char*
-parse_local_name(const char* first, const char* last, C& db,
+parse_local_name(const char* first, const char* last, Db& db,
                  bool* ends_with_template_args)
 {
     if (first != last && *first == 'Z')
@@ -4215,9 +4364,8 @@
 // <unscoped-template-name> ::= <unscoped-name>
 //                          ::= <substitution>
 
-template <class C>
 const char*
-parse_name(const char* first, const char* last, C& db,
+parse_name(const char* first, const char* last, Db& db,
            bool* ends_with_template_args)
 {
     if (last - first >= 2)
@@ -4253,7 +4401,7 @@
                 {
                     if (db.names.empty())
                         return first;
-                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
+                    db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
                     t0 = t1;
                     t1 = parse_template_args(t0, last, db);
                     if (t1 != t0)
@@ -4358,9 +4506,8 @@
 //      extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
 //      extension ::= GR <object name> # reference temporary for object
 
-template <class C>
 const char*
-parse_special_name(const char* first, const char* last, C& db)
+parse_special_name(const char* first, const char* last, Db& db)
 {
     if (last - first > 2)
     {
@@ -4562,9 +4709,8 @@
 //            ::= <data name>
 //            ::= <special-name>
 
-template <class C>
 const char*
-parse_encoding(const char* first, const char* last, C& db)
+parse_encoding(const char* first, const char* last, Db& db)
 {
     if (first != last)
     {
@@ -4595,10 +4741,10 @@
                     save_value<bool> sb2(db.tag_templates);
                     db.tag_templates = false;
                     const char* t2;
-                    typename C::String ret2;
+                    Db::String ret2;
                     if (db.names.empty())
                         return first;
-                    const typename C::String& nm = db.names.back().first;
+                    const Db::String& nm = db.names.back().first;
                     if (nm.empty())
                         return first;
                     if (!db.parsed_ctor_dtor_cv && ends_with_template_args)
@@ -4636,7 +4782,7 @@
                                 break;
                             if (k1 > k0)
                             {
-                                typename C::String tmp;
+                                Db::String tmp;
                                 for (size_t k = k0; k < k1; ++k)
                                 {
                                     if (!tmp.empty())
@@ -4692,9 +4838,8 @@
 // _block_invoke<decimal-digit>+
 // _block_invoke_<decimal-digit>+
 
-template <class C>
 const char*
-parse_block_invoke(const char* first, const char* last, C& db)
+parse_block_invoke(const char* first, const char* last, Db& db)
 {
     if (last - first >= 13)
     {
@@ -4729,15 +4874,14 @@
 // extension
 // <dot-suffix> := .<anything and everything>
 
-template <class C>
 const char*
-parse_dot_suffix(const char* first, const char* last, C& db)
+parse_dot_suffix(const char* first, const char* last, Db& db)
 {
     if (first != last && *first == '.')
     {
         if (db.names.empty())
             return first;
-        db.names.back().first += " (" + typename C::String(first, last) + ")";
+        db.names.back().first += " (" + Db::String(first, last) + ")";
         first = last;
     }
     return first;
@@ -4749,9 +4893,8 @@
 // <mangled-name> ::= _Z<encoding>
 //                ::= <type>
 
-template <class C>
 void
-demangle(const char* first, const char* last, C& db, int& status)
+demangle(const char* first, const char* last, Db& db, int& status)
 {
     if (first >= last)
     {
@@ -4798,213 +4941,6 @@
         status = invalid_mangled_name;
 }
 
-template <std::size_t N>
-class arena
-{
-    static const std::size_t alignment = 16;
-    alignas(alignment) char buf_[N];
-    char* ptr_;
-
-    std::size_t 
-    align_up(std::size_t n) noexcept
-        {return (n + (alignment-1)) & ~(alignment-1);}
-
-    bool
-    pointer_in_buffer(char* p) noexcept
-        {return buf_ <= p && p <= buf_ + N;}
-
-public:
-    arena() noexcept : ptr_(buf_) {}
-    ~arena() {ptr_ = nullptr;}
-    arena(const arena&) = delete;
-    arena& operator=(const arena&) = delete;
-
-    char* allocate(std::size_t n);
-    void deallocate(char* p, std::size_t n) noexcept;
-
-    static constexpr std::size_t size() {return N;}
-    std::size_t used() const {return static_cast<std::size_t>(ptr_ - buf_);}
-    void reset() {ptr_ = buf_;}
-};
-
-template <std::size_t N>
-char*
-arena<N>::allocate(std::size_t n)
-{
-    n = align_up(n);
-    if (static_cast<std::size_t>(buf_ + N - ptr_) >= n)
-    {
-        char* r = ptr_;
-        ptr_ += n;
-        return r;
-    }
-    return static_cast<char*>(std::malloc(n));
-}
-
-template <std::size_t N>
-void
-arena<N>::deallocate(char* p, std::size_t n) noexcept
-{
-    if (pointer_in_buffer(p))
-    {
-        n = align_up(n);
-        if (p + n == ptr_)
-            ptr_ = p;
-    }
-    else
-        std::free(p);
-}
-
-template <class T, std::size_t N>
-class short_alloc
-{
-    arena<N>& a_;
-public:
-    typedef T value_type;
-
-public:
-    template <class _Up> struct rebind {typedef short_alloc<_Up, N> other;};
-
-    short_alloc(arena<N>& a) noexcept : a_(a) {}
-    template <class U>
-        short_alloc(const short_alloc<U, N>& a) noexcept
-            : a_(a.a_) {}
-    short_alloc(const short_alloc&) = default;
-    short_alloc& operator=(const short_alloc&) = delete;
-
-    T* allocate(std::size_t n)
-    {
-        return reinterpret_cast<T*>(a_.allocate(n*sizeof(T)));
-    }
-    void deallocate(T* p, std::size_t n) noexcept
-    {
-        a_.deallocate(reinterpret_cast<char*>(p), n*sizeof(T));
-    }
-
-    template <class T1, std::size_t N1, class U, std::size_t M>
-    friend
-    bool
-    operator==(const short_alloc<T1, N1>& x, const short_alloc<U, M>& y) noexcept;
-
-    template <class U, std::size_t M> friend class short_alloc;
-};
-
-template <class T, std::size_t N, class U, std::size_t M>
-inline
-bool
-operator==(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept
-{
-    return N == M && &x.a_ == &y.a_;
-}
-
-template <class T, std::size_t N, class U, std::size_t M>
-inline
-bool
-operator!=(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept
-{
-    return !(x == y);
-}
-
-template <class T>
-class malloc_alloc
-{
-public:
-    typedef T value_type;
-    typedef T& reference;
-    typedef const T& const_reference;
-    typedef T* pointer;
-    typedef const T* const_pointer;
-    typedef std::size_t size_type;
-    typedef std::ptrdiff_t difference_type;
-
-    malloc_alloc() = default;
-    template <class U> malloc_alloc(const malloc_alloc<U>&) noexcept {}
-
-    T* allocate(std::size_t n)
-    {
-        return static_cast<T*>(std::malloc(n*sizeof(T)));
-    }
-    void deallocate(T* p, std::size_t) noexcept
-    {
-        std::free(p);
-    }
-
-    template <class U> struct rebind { using other = malloc_alloc<U>; };
-    template <class U, class... Args>
-    void construct(U* p, Args&&... args)
-    {
-        ::new ((void*)p) U(std::forward<Args>(args)...);
-    }
-    void destroy(T* p)
-    {
-        p->~T();
-    }
-};
-
-template <class T, class U>
-inline
-bool
-operator==(const malloc_alloc<T>&, const malloc_alloc<U>&) noexcept
-{
-    return true;
-}
-
-template <class T, class U>
-inline
-bool
-operator!=(const malloc_alloc<T>& x, const malloc_alloc<U>& y) noexcept
-{
-    return !(x == y);
-}
-
-const size_t bs = 4 * 1024;
-template <class T> using Alloc = short_alloc<T, bs>;
-template <class T> using Vector = std::vector<T, Alloc<T>>;
-
-template <class StrT>
-struct string_pair
-{
-    StrT first;
-    StrT second;
-
-    string_pair() = default;
-    string_pair(StrT f) : first(std::move(f)) {}
-    string_pair(StrT f, StrT s)
-        : first(std::move(f)), second(std::move(s)) {}
-    template <size_t N>
-        string_pair(const char (&s)[N]) : first(s, N-1) {}
-
-    size_t size() const {return first.size() + second.size();}
-    bool empty() const { return first.empty() && second.empty(); }
-    StrT full() const {return first + second;}
-    StrT move_full() {return std::move(first) + std::move(second);}
-};
-
-struct Db
-{
-    typedef std::basic_string<char, std::char_traits<char>,
-                              malloc_alloc<char>> String;
-    typedef Vector<string_pair<String>> sub_type;
-    typedef Vector<sub_type> template_param_type;
-    sub_type names;
-    template_param_type subs;
-    Vector<template_param_type> template_param;
-    unsigned cv = 0;
-    unsigned ref = 0;
-    unsigned encoding_depth = 0;
-    bool parsed_ctor_dtor_cv = false;
-    bool tag_templates = true;
-    bool fix_forward_references = false;
-    bool try_to_parse_template_args = true;
-
-    template <size_t N>
-    Db(arena<N>& ar) :
-        names(ar),
-        subs(0, names, ar),
-        template_param(0, subs, ar)
-    {}
-};
-
 }  // unnamed namespace
 
 extern "C" _LIBCXXABI_FUNC_VIS char *
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D35158: [libcxxabi... Erik Pilkington via Phabricator via cfe-commits

Reply via email to