diff options
author | Howard Hinnant <hhinnant@apple.com> | 2011-12-09 20:07:56 +0000 |
---|---|---|
committer | Howard Hinnant <hhinnant@apple.com> | 2011-12-09 20:07:56 +0000 |
commit | f270035a31a0abd92c1592ba0e87db0016127c3e (patch) | |
tree | a633c28711df5ee5a5df7943321313c9b4133ac9 /src/cxa_demangle.cpp | |
parent | 6eb54ad96edcf6311d304068c2fc7c9f15eb808d (diff) |
Added support for <special-name> ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first, and for <special-name> ::= GR <object name> # reference temporary for object
git-svn-id: https://llvm.org/svn/llvm-project/libcxxabi/trunk@146274 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'src/cxa_demangle.cpp')
-rw-r--r-- | src/cxa_demangle.cpp | 132 |
1 files changed, 131 insertions, 1 deletions
diff --git a/src/cxa_demangle.cpp b/src/cxa_demangle.cpp index 9af59dd..22adf13 100644 --- a/src/cxa_demangle.cpp +++ b/src/cxa_demangle.cpp @@ -264,6 +264,71 @@ public: } }; +class __construction_vtable + : public __node +{ + static const ptrdiff_t n = sizeof("construction vtable for ") - 1 + 4; +public: + __construction_vtable(__node* left, __node* right) + { + __left_ = left; + __right_ = right; + } + + virtual size_t first_size() const + { + if (__cached_size_ == -1) + const_cast<long&>(__cached_size_) = n + __left_->size() + + __right_->size(); + return __cached_size_; + } + virtual char* first_demangled_name(char* buf) const + { + strncpy(buf, "construction vtable for ", n-4); + buf = __left_->get_demangled_name(buf+n-4); + *buf++ = '-'; + *buf++ = 'i'; + *buf++ = 'n'; + *buf++ = '-'; + return __right_->get_demangled_name(buf); + } + virtual ptrdiff_t print_first(char* f, char* l) const + { + const ptrdiff_t r = l - f; + if (r < n) + return n + __left_->print(l, l) + __right_->print(l, l); + ptrdiff_t lsz = __left_->print(f+n-4, l); + ptrdiff_t sz = lsz + n; + if (r >= sz) + { + sz += __right_->print(f+sz, l); + if (r >= sz) + { + strncpy(f, "construction vtable for ", n-4); + f += n-4 + lsz; + *f++ = '-'; + *f++ = 'i'; + *f++ = 'n'; + *f++ = '-'; + } + } + else + return sz + __right_->print(l, l); + return sz; + } + virtual __node* base_name() const + { + return __right_->base_name(); + } + virtual bool fix_forward_references(__node** t_begin, __node** t_end) + { + bool r = true; + if (__left_) + r = __left_->fix_forward_references(t_begin, t_end); + return r && __right_->fix_forward_references(t_begin, t_end); + } +}; + class __typeinfo : public __node { @@ -626,6 +691,43 @@ public: } }; +class __reference_temporary + : public __node +{ + static const size_t n = sizeof("reference temporary for ") - 1; +public: + __reference_temporary(__node* type) + { + __right_ = type; + } + + virtual size_t first_size() const + { + if (__cached_size_ == -1) + const_cast<long&>(__cached_size_) = n + __right_->size(); + return __cached_size_; + } + virtual char* first_demangled_name(char* buf) const + { + strncpy(buf, "reference temporary for ", n); + return __right_->get_demangled_name(buf+n); + } + virtual ptrdiff_t print_first(char* f, char* l) const + { + const ptrdiff_t r = l - f; + if (r < n) + return n + __right_->print(l, l); + ptrdiff_t sz = __right_->print(f+n, l) + n; + if (r >= sz) + strncpy(f, "reference temporary for ", n); + return sz; + } + virtual bool fix_forward_references(__node** t_begin, __node** t_end) + { + return __right_->fix_forward_references(t_begin, t_end); + } +}; + class __source_name : public __node { @@ -12846,6 +12948,8 @@ __demangle_tree::__parse_call_offset(const char* first, const char* last) // # base is the nominal target function of thunk // ::= GV <object name> # Guard variable for one-time initialization // # No <type> +// extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first +// extension ::= GR <object name> # reference temporary for object const char* __demangle_tree::__parse_special_name(const char* first, const char* last) @@ -12896,6 +13000,24 @@ __demangle_tree::__parse_special_name(const char* first, const char* last) first = t; } break; + case 'C': + // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first + t = __parse_type(first+2, last); + if (t != first+2) + { + __node* op1 = __root_; + const char* t0 = __parse_number(t, last); + if (t0 != t && t0 != last && *t0 == '_') + { + const char* t1 = __parse_type(++t0, last); + if (t1 != t0) + { + if (__make<__construction_vtable>(__root_, op1)) + first = t1; + } + } + } + break; default: // T <call-offset> <base encoding> { @@ -12921,12 +13043,20 @@ __demangle_tree::__parse_special_name(const char* first, const char* last) } break; case 'G': - if (first[1] == 'V') + switch (first[1]) { + case 'V': // GV <object name> # Guard variable for one-time initialization t = __parse_name(first+2, last); if (t != first+2 && __make<__guard_variable>(__root_)) first = t; + break; + case 'R': + // extension ::= GR <object name> # reference temporary for object + t = __parse_name(first+2, last); + if (t != first+2 && __make<__reference_temporary>(__root_)) + first = t; + break; } break; } |