<div dir="ltr">I commit this (<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D9949&d=AwMGaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=dRVtezha6XiI8JDn7qdrzU6dMVI5a_JOY9pYlT67zzc&s=0mLi0gP713PwyLc4XiGcS_XLTbVF9pURV5nlR9Q6FVY&e=">http://reviews.llvm.org/D9949</a>) and <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D10040&d=AwMGaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=dRVtezha6XiI8JDn7qdrzU6dMVI5a_JOY9pYlT67zzc&s=u_niTGkeRH9L99I4SIsqvttuIxOnZX9OzDDmv_kbZNk&e=">http://reviews.llvm.org/D10040</a> together. This one was sort of expected to break on Windows because of the missing keywords in MSVC, but I wanted to preserve the original cxa_demangle.cpp in history somewhere. The immediate next commit should fix it. I had assumed that the buildbot would test both together since I committed them together, but apparently I'm wrong. I apologize.</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, May 28, 2015 at 12:40 PM, Zachary Turner <span dir="ltr"><<a href="mailto:zturner@google.com" target="_blank">zturner@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Can you take a look at this build failure? <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__lab.llvm.org-3A8011_builders_lldb-2Dx86-2Dwindows-2Dmsvc_builds_6224_steps_build_logs_stdio&d=AwMGaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=dRVtezha6XiI8JDn7qdrzU6dMVI5a_JOY9pYlT67zzc&s=SYVHbyk9qGQ1qdtjfQBAI1brgSQi-8LAsk2jTADeRKk&e=" target="_blank">http://lab.llvm.org:8011/builders/lldb-x86-windows-msvc/builds/6224/steps/build/logs/stdio</a><br></div><br><div class="gmail_quote"><div dir="ltr">On Thu, May 28, 2015 at 12:33 PM Chaoren Lin <<a href="mailto:chaorenl@google.com" target="_blank">chaorenl@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: chaoren<br>
Date: Thu May 28 14:15:15 2015<br>
New Revision: 238459<br>
<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D238459-26view-3Drev&d=AwMGaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=dRVtezha6XiI8JDn7qdrzU6dMVI5a_JOY9pYlT67zzc&s=t97HkCwZCmw6s8j3oROxXEUKhQ_DIuBlWpdfgxYYNkY&e=" target="_blank">http://llvm.org/viewvc/llvm-project?rev=238459&view=rev</a><br>
Log:<br>
Move inlined cxa_demangle.cpp to a separate file.<br>
<br>
Summary: In preparation for some changes to make this compatible with MSVC.<br>
<br>
Reviewers: emaste, zturner, clayborg<br>
<br>
Reviewed By: clayborg<br>
<br>
Subscribers: lldb-commits<br>
<br>
Differential Revision: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__reviews.llvm.org_D9949&d=AwMGaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=dRVtezha6XiI8JDn7qdrzU6dMVI5a_JOY9pYlT67zzc&s=0mLi0gP713PwyLc4XiGcS_XLTbVF9pURV5nlR9Q6FVY&e=" target="_blank">http://reviews.llvm.org/D9949</a><br>
<br>
Added:<br>
lldb/trunk/include/lldb/Core/CxaDemangle.h<br>
lldb/trunk/include/lldb/Core/FastDemangle.h<br>
lldb/trunk/source/Core/CxaDemangle.cpp<br>
- copied, changed from r238454, lldb/trunk/source/Core/Mangled.cpp<br>
Modified:<br>
lldb/trunk/source/Core/CMakeLists.txt<br>
lldb/trunk/source/Core/Mangled.cpp<br>
<br>
Added: lldb/trunk/include/lldb/Core/CxaDemangle.h<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lldb_trunk_include_lldb_Core_CxaDemangle.h-3Frev-3D238459-26view-3Dauto&d=AwMGaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=dRVtezha6XiI8JDn7qdrzU6dMVI5a_JOY9pYlT67zzc&s=rktdDIydis59d1Nj7WaPxKt9crWj6gda64_380s_VCw&e=" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/CxaDemangle.h?rev=238459&view=auto</a><br>
==============================================================================<br>
--- lldb/trunk/include/lldb/Core/CxaDemangle.h (added)<br>
+++ lldb/trunk/include/lldb/Core/CxaDemangle.h Thu May 28 14:15:15 2015<br>
@@ -0,0 +1,21 @@<br>
+//===-- CxaDemangle.h -------------------------------------------*- C++ -*-===//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef liblldb_CxaDemangle_h_<br>
+#define liblldb_CxaDemangle_h_<br>
+<br>
+namespace lldb_private<br>
+{<br>
+<br>
+ char*<br>
+ __cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status);<br>
+<br>
+}<br>
+<br>
+#endif<br>
<br>
Added: lldb/trunk/include/lldb/Core/FastDemangle.h<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lldb_trunk_include_lldb_Core_FastDemangle.h-3Frev-3D238459-26view-3Dauto&d=AwMGaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=dRVtezha6XiI8JDn7qdrzU6dMVI5a_JOY9pYlT67zzc&s=CqVUtr-r0pOmGsocMra7HdbPX2LqbJ1XiDN4RMjpcUY&e=" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FastDemangle.h?rev=238459&view=auto</a><br>
==============================================================================<br>
--- lldb/trunk/include/lldb/Core/FastDemangle.h (added)<br>
+++ lldb/trunk/include/lldb/Core/FastDemangle.h Thu May 28 14:15:15 2015<br>
@@ -0,0 +1,24 @@<br>
+//===-- FastDemangle.h ------------------------------------------*- C++ -*-===//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef liblldb_FastDemangle_h_<br>
+#define liblldb_FastDemangle_h_<br>
+<br>
+namespace lldb_private<br>
+{<br>
+<br>
+ char *<br>
+ FastDemangle(const char *mangled_name);<br>
+<br>
+ char *<br>
+ FastDemangle(const char *mangled_name, long mangled_name_length);<br>
+<br>
+}<br>
+<br>
+#endif<br>
<br>
Modified: lldb/trunk/source/Core/CMakeLists.txt<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lldb_trunk_source_Core_CMakeLists.txt-3Frev-3D238459-26r1-3D238458-26r2-3D238459-26view-3Ddiff&d=AwMGaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=dRVtezha6XiI8JDn7qdrzU6dMVI5a_JOY9pYlT67zzc&s=PDXiRhQX_A9gSZ_IvyqHbETsYpMvKeJ4pNlB1U-CxVE&e=" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/CMakeLists.txt?rev=238459&r1=238458&r2=238459&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Core/CMakeLists.txt (original)<br>
+++ lldb/trunk/source/Core/CMakeLists.txt Thu May 28 14:15:15 2015<br>
@@ -14,6 +14,7 @@ add_lldb_library(lldbCore<br>
ConnectionMachPort.cpp<br>
ConnectionSharedMemory.cpp<br>
ConstString.cpp<br>
+ CxaDemangle.cpp<br>
DataBufferHeap.cpp<br>
DataBufferMemoryMap.cpp<br>
DataEncoder.cpp<br>
<br>
Copied: lldb/trunk/source/Core/CxaDemangle.cpp (from r238454, lldb/trunk/source/Core/Mangled.cpp)<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lldb_trunk_source_Core_CxaDemangle.cpp-3Fp2-3Dlldb_trunk_source_Core_CxaDemangle.cpp-26p1-3Dlldb_trunk_source_Core_Mangled.cpp-26r1-3D238454-26r2-3D238459-26rev-3D238459-26view-3Ddiff&d=AwMGaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=dRVtezha6XiI8JDn7qdrzU6dMVI5a_JOY9pYlT67zzc&s=D9tkW6bynsJsj0aQGhVMmxoGY9Bxqdg3V0kRGlldTcU&e=" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/CxaDemangle.cpp?p2=lldb/trunk/source/Core/CxaDemangle.cpp&p1=lldb/trunk/source/Core/Mangled.cpp&r1=238454&r2=238459&rev=238459&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Core/Mangled.cpp (original)<br>
+++ lldb/trunk/source/Core/CxaDemangle.cpp Thu May 28 14:15:15 2015<br>
@@ -1,45 +1,12 @@<br>
-//===-- Mangled.cpp ---------------------------------------------*- C++ -*-===//<br>
-//<br>
-// The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-<br>
-// FreeBSD9-STABLE requires this to know about size_t in cxxabi.h<br>
-#include <cstddef><br>
-#if defined(_MSC_VER)<br>
-#include "lldb/Host/windows/windows.h"<br>
-#include <Dbghelp.h><br>
-#elif defined (__FreeBSD__)<br>
-#define LLDB_USE_BUILTIN_DEMANGLER<br>
-#else<br>
-#include <cxxabi.h><br>
-#endif<br>
-<br>
-#ifdef LLDB_USE_BUILTIN_DEMANGLER<br>
-<br>
-// Provide a fast-path demangler implemented in FastDemangle.cpp until it can<br>
-// replace the existing C++ demangler with a complete implementation<br>
-namespace lldb_private<br>
-{<br>
- extern char * FastDemangle (const char * mangled_name,<br>
- long mangled_name_length);<br>
-}<br>
-<br>
//----------------------------------------------------------------------<br>
// Inlined copy of:<br>
// <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_svn_llvm-2Dproject_libcxxabi_trunk_src_cxa-5Fdemangle.cpp&d=AwMGaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=dRVtezha6XiI8JDn7qdrzU6dMVI5a_JOY9pYlT67zzc&s=ki-FHPcszvBIIQeWieV7fH1LREESFamv8YBYt7mVmYs&e=" target="_blank">http://llvm.org/svn/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp</a><br>
-// revision 199944.<br>
+// revision 238263.<br>
//<br>
// Changes include:<br>
-// - remove the "__cxxabiv1" namespace<br>
-// - stripped GCC attributes()<br>
-// - removed extern "C" from the cxa_demangle function<br>
-// - Changed the scope of the unnamed namespace to include cxa_demangle<br>
-// function.<br>
+// - Renamed the "__cxxabiv1" namespace to "lldb_private"<br>
+// - Stripped GCC attributes()<br>
+// - Removed extern "C" from the cxa_demangle function<br>
// - Added "#undef _LIBCPP_EXTERN_TEMPLATE" to avoid warning<br>
//----------------------------------------------------------------------<br>
<br>
@@ -65,6 +32,8 @@ namespace lldb_private<br>
#include <cstring><br>
#include <cctype><br>
<br>
+namespace lldb_private<br>
+{<br>
<br>
namespace<br>
{<br>
@@ -83,7 +52,8 @@ template <class C><br>
template <class C><br>
const char* parse_encoding(const char* first, const char* last, C& db);<br>
template <class C><br>
- const char* parse_name(const char* first, const char* last, C& db);<br>
+ const char* parse_name(const char* first, const char* last, C& db,<br>
+ bool* ends_with_template_args = 0);<br>
template <class C><br>
const char* parse_expression(const char* first, const char* last, C& db);<br>
template <class C><br>
@@ -99,51 +69,51 @@ template <class C><br>
void<br>
print_stack(const C& db)<br>
{<br>
- printf("---------\n");<br>
- printf("names:\n");<br>
+ fprintf(stderr, "---------\n");<br>
+ fprintf(stderr, "names:\n");<br>
for (auto& s : db.names)<br>
- printf("{%s#%s}\n", s.first.c_str(), s.second.c_str());<br>
+ fprintf(stderr, "{%s#%s}\n", s.first.c_str(), s.second.c_str());<br>
int i = -1;<br>
- printf("subs:\n");<br>
+ fprintf(stderr, "subs:\n");<br>
for (auto& v : db.subs)<br>
{<br>
if (i >= 0)<br>
- printf("S%i_ = {", i);<br>
+ fprintf(stderr, "S%i_ = {", i);<br>
else<br>
- printf("S_ = {");<br>
+ fprintf(stderr, "S_ = {");<br>
for (auto& s : v)<br>
- printf("{%s#%s}", s.first.c_str(), s.second.c_str());<br>
- printf("}\n");<br>
+ fprintf(stderr, "{%s#%s}", s.first.c_str(), s.second.c_str());<br>
+ fprintf(stderr, "}\n");<br>
++i;<br>
}<br>
- printf("template_param:\n");<br>
+ fprintf(stderr, "template_param:\n");<br>
for (auto& t : db.template_param)<br>
{<br>
- printf("--\n");<br>
+ fprintf(stderr, "--\n");<br>
i = -1;<br>
for (auto& v : t)<br>
{<br>
if (i >= 0)<br>
- printf("T%i_ = {", i);<br>
+ fprintf(stderr, "T%i_ = {", i);<br>
else<br>
- printf("T_ = {");<br>
+ fprintf(stderr, "T_ = {");<br>
for (auto& s : v)<br>
- printf("{%s#%s}", s.first.c_str(), s.second.c_str());<br>
- printf("}\n");<br>
+ fprintf(stderr, "{%s#%s}", s.first.c_str(), s.second.c_str());<br>
+ fprintf(stderr, "}\n");<br>
++i;<br>
}<br>
}<br>
- printf("---------\n\n");<br>
+ fprintf(stderr, "---------\n\n");<br>
}<br>
<br>
template <class C><br>
void<br>
print_state(const char* msg, const char* first, const char* last, const C& db)<br>
{<br>
- printf("%s: ", msg);<br>
+ fprintf(stderr, "%s: ", msg);<br>
for (; first != last; ++first)<br>
- printf("%c", *first);<br>
- printf("\n");<br>
+ fprintf(stderr, "%c", *first);<br>
+ fprintf(stderr, "\n");<br>
print_stack(db);<br>
}<br>
<br>
@@ -200,7 +170,11 @@ constexpr const char* float_data<double><br>
template <><br>
struct float_data<long double><br>
{<br>
+#if defined(__arm__)<br>
+ static const size_t mangled_size = 16;<br>
+#else<br>
static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms<br>
+#endif<br>
static const size_t max_demangled_size = 40;<br>
static constexpr const char* spec = "%LaL";<br>
};<br>
@@ -235,7 +209,7 @@ parse_floating_number(const char* first,<br>
}<br>
if (*t == 'E')<br>
{<br>
-#if __LITTLE_ENDIAN__<br>
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__<br>
std::reverse(buf, e);<br>
#endif<br>
char num[float_data<Float>::max_demangled_size] = {0};<br>
@@ -397,6 +371,7 @@ parse_substitution(const char* first, co<br>
// ::= Di # char32_t<br>
// ::= Ds # char16_t<br>
// ::= Da # auto (in dependent new-expressions)<br>
+// ::= Dc # decltype(auto)<br>
// ::= Dn # std::nullptr_t (i.e., decltype(nullptr))<br>
// ::= u <source-name> # vendor extended type<br>
<br>
@@ -532,6 +507,10 @@ parse_builtin_type(const char* first, co<br>
db.names.push_back("auto");<br>
first += 2;<br>
break;<br>
+ case 'c':<br>
+ db.names.push_back("decltype(auto)");<br>
+ first += 2;<br>
+ break;<br>
case 'n':<br>
db.names.push_back("std::nullptr_t");<br>
first += 2;<br>
@@ -1610,10 +1589,9 @@ parse_function_type(const char* first, c<br>
const char* t = first+1;<br>
if (t != last)<br>
{<br>
- bool externC = false;<br>
if (*t == 'Y')<br>
{<br>
- externC = true;<br>
+ /* extern "C" */<br>
if (++t == last)<br>
return first;<br>
}<br>
@@ -1707,7 +1685,7 @@ parse_pointer_to_member_type(const char*<br>
auto func = std::move(db.names.back());<br>
db.names.pop_back();<br>
auto class_type = std::move(db.names.back());<br>
- if (func.second.front() == '(')<br>
+ if (!func.second.empty() && func.second.front() == '(')<br>
{<br>
db.names.back().first = std::move(func.first) + "(" + class_type.move_full() + "::*";<br>
db.names.back().second = ")" + std::move(func.second);<br>
@@ -2054,7 +2032,8 @@ parse_type(const char* first, const char<br>
db.names[k].first += " (";<br>
db.names[k].second.insert(0, ")");<br>
}<br>
- else if (db.names[k].second.front() == '(')<br>
+ else if (!db.names[k].second.empty() &&<br>
+ db.names[k].second.front() == '(')<br>
{<br>
db.names[k].first += "(";<br>
db.names[k].second.insert(0, ")");<br>
@@ -2081,7 +2060,8 @@ parse_type(const char* first, const char<br>
db.names[k].first += " (";<br>
db.names[k].second.insert(0, ")");<br>
}<br>
- else if (db.names[k].second.front() == '(')<br>
+ else if (!db.names[k].second.empty() &&<br>
+ db.names[k].second.front() == '(')<br>
{<br>
db.names[k].first += "(";<br>
db.names[k].second.insert(0, ")");<br>
@@ -2115,7 +2095,8 @@ parse_type(const char* first, const char<br>
db.names[k].first += " (";<br>
db.names[k].second.insert(0, ")");<br>
}<br>
- else if (db.names[k].second.front() == '(')<br>
+ else if (!db.names[k].second.empty() &&<br>
+ db.names[k].second.front() == '(')<br>
{<br>
db.names[k].first += "(";<br>
db.names[k].second.insert(0, ")");<br>
@@ -3933,7 +3914,8 @@ parse_template_args(const char* first, c<br>
<br>
template <class C><br>
const char*<br>
-parse_nested_name(const char* first, const char* last, C& db)<br>
+parse_nested_name(const char* first, const char* last, C& db,<br>
+ bool* ends_with_template_args)<br>
{<br>
if (first != last && *first == 'N')<br>
{<br>
@@ -3941,15 +3923,15 @@ parse_nested_name(const char* first, con<br>
const char* t0 = parse_cv_qualifiers(first+1, last, cv);<br>
if (t0 == last)<br>
return first;<br>
- unsigned ref = 0;<br>
+ db.ref = 0;<br>
if (*t0 == 'R')<br>
{<br>
- ref = 1;<br>
+ db.ref = 1;<br>
++t0;<br>
}<br>
else if (*t0 == 'O')<br>
{<br>
- ref = 2;<br>
+ db.ref = 2;<br>
++t0;<br>
}<br>
db.names.emplace_back();<br>
@@ -3964,8 +3946,10 @@ parse_nested_name(const char* first, con<br>
return first;<br>
}<br>
bool pop_subs = false;<br>
+ bool component_ends_with_template_args = false;<br>
while (*t0 != 'E')<br>
{<br>
+ component_ends_with_template_args = false;<br>
const char* t1;<br>
switch (*t0)<br>
{<br>
@@ -4035,6 +4019,7 @@ parse_nested_name(const char* first, con<br>
db.names.back().first += name;<br>
db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));<br>
t0 = t1;<br>
+ component_ends_with_template_args = true;<br>
}<br>
else<br>
return first;<br>
@@ -4063,10 +4048,11 @@ parse_nested_name(const char* first, con<br>
}<br>
}<br>
first = t0 + 1;<br>
- db.ref = ref;<br>
<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__db.cv&d=AwMGaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=dRVtezha6XiI8JDn7qdrzU6dMVI5a_JOY9pYlT67zzc&s=eRNoSGdl81MQy8-l1_JMXWpRu8_SL2X69Vx6actWYbQ&e=" target="_blank">db.cv</a> = cv;<br>
if (pop_subs && !db.subs.empty())<br>
db.subs.pop_back();<br>
+ if (ends_with_template_args)<br>
+ *ends_with_template_args = component_ends_with_template_args;<br>
}<br>
return first;<br>
}<br>
@@ -4114,7 +4100,8 @@ parse_discriminator(const char* first, c<br>
<br>
template <class C><br>
const char*<br>
-parse_local_name(const char* first, const char* last, C& db)<br>
+parse_local_name(const char* first, const char* last, C& db,<br>
+ bool* ends_with_template_args)<br>
{<br>
if (first != last && *first == 'Z')<br>
{<br>
@@ -4136,7 +4123,8 @@ parse_local_name(const char* first, cons<br>
if (t1 != last && *t1 == '_')<br>
{<br>
t = t1 + 1;<br>
- t1 = parse_name(t, last, db);<br>
+ t1 = parse_name(t, last, db,<br>
+ ends_with_template_args);<br>
if (t1 != t)<br>
{<br>
if (db.names.size() < 2)<br>
@@ -4154,7 +4142,8 @@ parse_local_name(const char* first, cons<br>
break;<br>
default:<br>
{<br>
- const char* t1 = parse_name(t, last, db);<br>
+ const char* t1 = parse_name(t, last, db,<br>
+ ends_with_template_args);<br>
if (t1 != t)<br>
{<br>
// parse but ignore discriminator<br>
@@ -4186,7 +4175,8 @@ parse_local_name(const char* first, cons<br>
<br>
template <class C><br>
const char*<br>
-parse_name(const char* first, const char* last, C& db)<br>
+parse_name(const char* first, const char* last, C& db,<br>
+ bool* ends_with_template_args)<br>
{<br>
if (last - first >= 2)<br>
{<br>
@@ -4198,14 +4188,16 @@ parse_name(const char* first, const char<br>
{<br>
case 'N':<br>
{<br>
- const char* t1 = parse_nested_name(t0, last, db);<br>
+ const char* t1 = parse_nested_name(t0, last, db,<br>
+ ends_with_template_args);<br>
if (t1 != t0)<br>
first = t1;<br>
break;<br>
}<br>
case 'Z':<br>
{<br>
- const char* t1 = parse_local_name(t0, last, db);<br>
+ const char* t1 = parse_local_name(t0, last, db,<br>
+ ends_with_template_args);<br>
if (t1 != t0)<br>
first = t1;<br>
break;<br>
@@ -4230,6 +4222,8 @@ parse_name(const char* first, const char<br>
db.names.pop_back();<br>
db.names.back().first += tmp;<br>
first = t1;<br>
+ if (ends_with_template_args)<br>
+ *ends_with_template_args = true;<br>
}<br>
}<br>
else // <unscoped-name><br>
@@ -4250,6 +4244,8 @@ parse_name(const char* first, const char<br>
db.names.pop_back();<br>
db.names.back().first += tmp;<br>
first = t1;<br>
+ if (ends_with_template_args)<br>
+ *ends_with_template_args = true;<br>
}<br>
}<br>
}<br>
@@ -4423,7 +4419,7 @@ parse_special_name(const char* first, co<br>
{<br>
if (db.names.empty())<br>
return first;<br>
- if (first[1] == 'v')<br>
+ if (first[2] == 'v')<br>
{<br>
db.names.back().first.insert(0, "virtual thunk to ");<br>
first = t;<br>
@@ -4513,7 +4509,9 @@ parse_encoding(const char* first, const<br>
break;<br>
default:<br>
{<br>
- const char* t = parse_name(first, last, db);<br>
+ bool ends_with_template_args = false;<br>
+ const char* t = parse_name(first, last, db,<br>
+ &ends_with_template_args);<br>
unsigned cv = <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__db.cv&d=AwMGaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=dRVtezha6XiI8JDn7qdrzU6dMVI5a_JOY9pYlT67zzc&s=eRNoSGdl81MQy8-l1_JMXWpRu8_SL2X69Vx6actWYbQ&e=" target="_blank">db.cv</a>;<br>
unsigned ref = db.ref;<br>
if (t != first)<br>
@@ -4529,8 +4527,7 @@ parse_encoding(const char* first, const<br>
const typename C::String& nm = db.names.back().first;<br>
if (nm.empty())<br>
return first;<br>
- if (!db.parsed_ctor_dtor_cv && nm.back() == '>' && nm[nm.size()-2] != '-'<br>
- && nm[nm.size()-2] != '>')<br>
+ if (!db.parsed_ctor_dtor_cv && ends_with_template_args)<br>
{<br>
t2 = parse_type(t, last, db);<br>
if (t2 == t)<br>
@@ -4730,7 +4727,7 @@ class arena<br>
<br>
std::size_t<br>
align_up(std::size_t n) noexcept<br>
- {return n + (alignment-1) & ~(alignment-1);}<br>
+ {return (n + (alignment-1)) & ~(alignment-1);}<br>
<br>
bool<br>
pointer_in_buffer(char* p) noexcept<br>
@@ -4866,32 +4863,33 @@ operator!=(const malloc_alloc<T>& x, con<br>
const size_t bs = 4 * 1024;<br>
template <class T> using Alloc = short_alloc<T, bs>;<br>
template <class T> using Vector = std::vector<T, Alloc<T>>;<br>
-using String = std::basic_string<char, std::char_traits<char>, malloc_alloc<char>>;<br>
<br>
+template <class StrT><br>
struct string_pair<br>
{<br>
- String first;<br>
- String second;<br>
+ StrT first;<br>
+ StrT second;<br>
<br>
string_pair() = default;<br>
- string_pair(String f) : first(std::move(f)) {}<br>
- string_pair(String f, String s)<br>
+ string_pair(StrT f) : first(std::move(f)) {}<br>
+ string_pair(StrT f, StrT s)<br>
: first(std::move(f)), second(std::move(s)) {}<br>
template <size_t N><br>
string_pair(const char (&s)[N]) : first(s, N-1) {}<br>
<br>
size_t size() const {return first.size() + second.size();}<br>
- String full() const {return first + second;}<br>
- String move_full() {return std::move(first) + std::move(second);}<br>
+ StrT full() const {return first + second;}<br>
+ StrT move_full() {return std::move(first) + std::move(second);}<br>
};<br>
<br>
struct Db<br>
{<br>
- typedef ::String String;<br>
- typedef Vector<string_pair> sub_type;<br>
+ typedef std::basic_string<char, std::char_traits<char>,<br>
+ malloc_alloc<char>> String;<br>
+ typedef Vector<string_pair<String>> sub_type;<br>
typedef Vector<sub_type> template_param_type;<br>
- Vector<string_pair> names;<br>
- Vector<sub_type> subs;<br>
+ sub_type names;<br>
+ template_param_type subs;<br>
Vector<template_param_type> template_param;<br>
unsigned cv;<br>
unsigned ref;<br>
@@ -4909,6 +4907,8 @@ struct Db<br>
{}<br>
};<br>
<br>
+} // unnamed namespace<br>
+<br>
char*<br>
__cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status)<br>
{<br>
@@ -4976,410 +4976,4 @@ __cxa_demangle(const char* mangled_name,<br>
return buf;<br>
}<br>
<br>
-}<br>
-#endif<br>
-<br>
-<br>
-#include "llvm/ADT/DenseMap.h"<br>
-<br>
-#include "lldb/Core/ConstString.h"<br>
-#include "lldb/Core/Mangled.h"<br>
-#include "lldb/Core/RegularExpression.h"<br>
-#include "lldb/Core/Stream.h"<br>
-#include "lldb/Core/Timer.h"<br>
-#include "lldb/Target/CPPLanguageRuntime.h"<br>
-#include <ctype.h><br>
-#include <string.h><br>
-#include <stdlib.h><br>
-<br>
-<br>
-using namespace lldb_private;<br>
-<br>
-static inline bool<br>
-cstring_is_mangled (const char *s)<br>
-{<br>
- if (s)<br>
-#if defined(_MSC_VER)<br>
- return (s[0] == '?');<br>
-#else<br>
- return (s[0] == '_' && s[1] == 'Z');<br>
-#endif<br>
- return false;<br>
-}<br>
-<br>
-static const ConstString &<br>
-get_demangled_name_without_arguments (const Mangled *obj)<br>
-{<br>
- // This pair is <mangled name, demangled name without function arguments><br>
- static std::pair<ConstString, ConstString> g_most_recent_mangled_to_name_sans_args;<br>
-<br>
- // Need to have the mangled & demangled names we're currently examining as statics<br>
- // so we can return a const ref to them at the end of the func if we don't have<br>
- // anything better.<br>
- static ConstString g_last_mangled;<br>
- static ConstString g_last_demangled;<br>
-<br>
- ConstString mangled = obj->GetMangledName ();<br>
- ConstString demangled = obj->GetDemangledName ();<br>
-<br>
- if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled)<br>
- {<br>
- return g_most_recent_mangled_to_name_sans_args.second;<br>
- }<br>
-<br>
- g_last_demangled = demangled;<br>
- g_last_mangled = mangled;<br>
-<br>
- const char *mangled_name_cstr = mangled.GetCString();<br>
-<br>
- if (demangled && mangled_name_cstr && mangled_name_cstr[0])<br>
- {<br>
- if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&<br>
- (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure, typeinfo structure, and typeinfo mangled_name<br>
- mangled_name_cstr[2] != 'G' && // avoid guard variables<br>
- mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually handle eSymbolTypeData, we will want this back)<br>
- {<br>
- CPPLanguageRuntime::MethodName cxx_method (demangled);<br>
- if (!cxx_method.GetBasename().empty() && !cxx_method.GetContext().empty())<br>
- {<br>
- std::string shortname = cxx_method.GetContext().str();<br>
- shortname += "::";<br>
- shortname += cxx_method.GetBasename().str();<br>
- ConstString result(shortname.c_str());<br>
- g_most_recent_mangled_to_name_sans_args.first = mangled;<br>
- g_most_recent_mangled_to_name_sans_args.second = result;<br>
- return g_most_recent_mangled_to_name_sans_args.second;<br>
- }<br>
- }<br>
- }<br>
-<br>
- if (demangled)<br>
- return g_last_demangled;<br>
- return g_last_mangled;<br>
-}<br>
-<br>
-#pragma mark Mangled<br>
-//----------------------------------------------------------------------<br>
-// Default constructor<br>
-//----------------------------------------------------------------------<br>
-Mangled::Mangled () :<br>
- m_mangled(),<br>
- m_demangled()<br>
-{<br>
-}<br>
-<br>
-//----------------------------------------------------------------------<br>
-// Constructor with an optional string and a boolean indicating if it is<br>
-// the mangled version.<br>
-//----------------------------------------------------------------------<br>
-Mangled::Mangled (const ConstString &s, bool mangled) :<br>
- m_mangled(),<br>
- m_demangled()<br>
-{<br>
- if (s)<br>
- SetValue(s, mangled);<br>
-}<br>
-<br>
-Mangled::Mangled (const ConstString &s) :<br>
- m_mangled(),<br>
- m_demangled()<br>
-{<br>
- if (s)<br>
- SetValue(s);<br>
-}<br>
-<br>
-//----------------------------------------------------------------------<br>
-// Destructor<br>
-//----------------------------------------------------------------------<br>
-Mangled::~Mangled ()<br>
-{<br>
-}<br>
-<br>
-//----------------------------------------------------------------------<br>
-// Convert to pointer operator. This allows code to check any Mangled<br>
-// objects to see if they contain anything valid using code such as:<br>
-//<br>
-// Mangled mangled(...);<br>
-// if (mangled)<br>
-// { ...<br>
-//----------------------------------------------------------------------<br>
-Mangled::operator void* () const<br>
-{<br>
- return (m_mangled) ? const_cast<Mangled*>(this) : NULL;<br>
-}<br>
-<br>
-//----------------------------------------------------------------------<br>
-// Logical NOT operator. This allows code to check any Mangled<br>
-// objects to see if they are invalid using code such as:<br>
-//<br>
-// Mangled mangled(...);<br>
-// if (!file_spec)<br>
-// { ...<br>
-//----------------------------------------------------------------------<br>
-bool<br>
-Mangled::operator! () const<br>
-{<br>
- return !m_mangled;<br>
-}<br>
-<br>
-//----------------------------------------------------------------------<br>
-// Clear the mangled and demangled values.<br>
-//----------------------------------------------------------------------<br>
-void<br>
-Mangled::Clear ()<br>
-{<br>
- m_mangled.Clear();<br>
- m_demangled.Clear();<br>
-}<br>
-<br>
-<br>
-//----------------------------------------------------------------------<br>
-// Compare the the string values.<br>
-//----------------------------------------------------------------------<br>
-int<br>
-Mangled::Compare (const Mangled& a, const Mangled& b)<br>
-{<br>
- return ConstString::Compare(a.GetName(ePreferMangled), a.GetName(ePreferMangled));<br>
-}<br>
-<br>
-<br>
-<br>
-//----------------------------------------------------------------------<br>
-// Set the string value in this objects. If "mangled" is true, then<br>
-// the mangled named is set with the new value in "s", else the<br>
-// demangled name is set.<br>
-//----------------------------------------------------------------------<br>
-void<br>
-Mangled::SetValue (const ConstString &s, bool mangled)<br>
-{<br>
- if (s)<br>
- {<br>
- if (mangled)<br>
- {<br>
- m_demangled.Clear();<br>
- m_mangled = s;<br>
- }<br>
- else<br>
- {<br>
- m_demangled = s;<br>
- m_mangled.Clear();<br>
- }<br>
- }<br>
- else<br>
- {<br>
- m_demangled.Clear();<br>
- m_mangled.Clear();<br>
- }<br>
-}<br>
-<br>
-void<br>
-Mangled::SetValue (const ConstString &name)<br>
-{<br>
- if (name)<br>
- {<br>
- if (cstring_is_mangled(name.GetCString()))<br>
- {<br>
- m_demangled.Clear();<br>
- m_mangled = name;<br>
- }<br>
- else<br>
- {<br>
- m_demangled = name;<br>
- m_mangled.Clear();<br>
- }<br>
- }<br>
- else<br>
- {<br>
- m_demangled.Clear();<br>
- m_mangled.Clear();<br>
- }<br>
-}<br>
-<br>
-//----------------------------------------------------------------------<br>
-// Generate the demangled name on demand using this accessor. Code in<br>
-// this class will need to use this accessor if it wishes to decode<br>
-// the demangled name. The result is cached and will be kept until a<br>
-// new string value is supplied to this object, or until the end of the<br>
-// object's lifetime.<br>
-//----------------------------------------------------------------------<br>
-const ConstString&<br>
-Mangled::GetDemangledName () const<br>
-{<br>
- // Check to make sure we have a valid mangled name and that we<br>
- // haven't already decoded our mangled name.<br>
- if (m_mangled && !m_demangled)<br>
- {<br>
- // We need to generate and cache the demangled name.<br>
- Timer scoped_timer (__PRETTY_FUNCTION__,<br>
- "Mangled::GetDemangledName (m_mangled = %s)",<br>
- m_mangled.GetCString());<br>
-<br>
- // Don't bother running anything that isn't mangled<br>
- const char *mangled_cstr = m_mangled.GetCString();<br>
- if (cstring_is_mangled(mangled_cstr))<br>
- {<br>
- if (!m_mangled.GetMangledCounterpart(m_demangled))<br>
- {<br>
- // We didn't already mangle this name, demangle it and if all goes well<br>
- // add it to our map.<br>
-#ifdef LLDB_USE_BUILTIN_DEMANGLER<br>
- // Try to use the fast-path demangler first for the<br>
- // performance win, falling back to the full demangler only<br>
- // when necessary<br>
- char *demangled_name = FastDemangle (mangled_cstr,<br>
- m_mangled.GetLength());<br>
- if (!demangled_name)<br>
- demangled_name = __cxa_demangle (mangled_cstr, NULL, NULL, NULL);<br>
-#elif defined(_MSC_VER)<br>
- char *demangled_name = (char *)::malloc(1024);<br>
- ::ZeroMemory(demangled_name, 1024);<br>
- DWORD result = ::UnDecorateSymbolName(mangled_cstr, demangled_name, 1023,<br>
- UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected keywords<br>
- UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall, etc keywords<br>
- UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications<br>
- UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc specifiers<br>
- UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords<br>
- );<br>
- if (result == 0)<br>
- {<br>
- free (demangled_name);<br>
- demangled_name = nullptr;<br>
- }<br>
-#else<br>
- char *demangled_name = abi::__cxa_demangle (mangled_cstr, NULL, NULL, NULL);<br>
-#endif<br>
-<br>
- if (demangled_name)<br>
- {<br>
- m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);<br>
- free (demangled_name);<br>
- }<br>
- }<br>
- }<br>
- if (!m_demangled)<br>
- {<br>
- // Set the demangled string to the empty string to indicate we<br>
- // tried to parse it once and failed.<br>
- m_demangled.SetCString("");<br>
- }<br>
- }<br>
-<br>
- return m_demangled;<br>
-}<br>
-<br>
-<br>
-bool<br>
-Mangled::NameMatches (const RegularExpression& regex) const<br>
-{<br>
- if (m_mangled && regex.Execute (m_mangled.AsCString()))<br>
- return true;<br>
-<br>
- if (GetDemangledName() && regex.Execute (m_demangled.AsCString()))<br>
- return true;<br>
- return false;<br>
-}<br>
-<br>
-//----------------------------------------------------------------------<br>
-// Get the demangled name if there is one, else return the mangled name.<br>
-//----------------------------------------------------------------------<br>
-const ConstString&<br>
-Mangled::GetName (Mangled::NamePreference preference) const<br>
-{<br>
- if (preference == ePreferDemangledWithoutArguments)<br>
- {<br>
- // Call the accessor to make sure we get a demangled name in case<br>
- // it hasn't been demangled yet...<br>
- GetDemangledName();<br>
-<br>
- return get_demangled_name_without_arguments (this);<br>
- }<br>
- if (preference == ePreferDemangled)<br>
- {<br>
- // Call the accessor to make sure we get a demangled name in case<br>
- // it hasn't been demangled yet...<br>
- if (GetDemangledName())<br>
- return m_demangled;<br>
- return m_mangled;<br>
- }<br>
- else<br>
- {<br>
- if (m_mangled)<br>
- return m_mangled;<br>
- return GetDemangledName();<br>
- }<br>
-}<br>
-<br>
-//----------------------------------------------------------------------<br>
-// Dump a Mangled object to stream "s". We don't force our<br>
-// demangled name to be computed currently (we don't use the accessor).<br>
-//----------------------------------------------------------------------<br>
-void<br>
-Mangled::Dump (Stream *s) const<br>
-{<br>
- if (m_mangled)<br>
- {<br>
- *s << ", mangled = " << m_mangled;<br>
- }<br>
- if (m_demangled)<br>
- {<br>
- const char * demangled = m_demangled.AsCString();<br>
- s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");<br>
- }<br>
-}<br>
-<br>
-//----------------------------------------------------------------------<br>
-// Dumps a debug version of this string with extra object and state<br>
-// information to stream "s".<br>
-//----------------------------------------------------------------------<br>
-void<br>
-Mangled::DumpDebug (Stream *s) const<br>
-{<br>
- s->Printf("%*p: Mangled mangled = ", static_cast<int>(sizeof(void*) * 2),<br>
- static_cast<const void*>(this));<br>
- m_mangled.DumpDebug(s);<br>
- s->Printf(", demangled = ");<br>
- m_demangled.DumpDebug(s);<br>
-}<br>
-<br>
-//----------------------------------------------------------------------<br>
-// Return the size in byte that this object takes in memory. The size<br>
-// includes the size of the objects it owns, and not the strings that<br>
-// it references because they are shared strings.<br>
-//----------------------------------------------------------------------<br>
-size_t<br>
-Mangled::MemorySize () const<br>
-{<br>
- return m_mangled.MemorySize() + m_demangled.MemorySize();<br>
-}<br>
-<br>
-lldb::LanguageType<br>
-Mangled::GetLanguage ()<br>
-{<br>
- ConstString mangled = GetMangledName();<br>
- if (mangled)<br>
- {<br>
- if (GetDemangledName())<br>
- {<br>
- if (cstring_is_mangled(mangled.GetCString()))<br>
- return lldb::eLanguageTypeC_plus_plus;<br>
- }<br>
- }<br>
- return lldb::eLanguageTypeUnknown;<br>
-}<br>
-<br>
-//----------------------------------------------------------------------<br>
-// Dump OBJ to the supplied stream S.<br>
-//----------------------------------------------------------------------<br>
-Stream&<br>
-operator << (Stream& s, const Mangled& obj)<br>
-{<br>
- if (obj.GetMangledName())<br>
- s << "mangled = '" << obj.GetMangledName() << "'";<br>
-<br>
- const ConstString& demangled = obj.GetDemangledName();<br>
- if (demangled)<br>
- s << ", demangled = '" << demangled << '\'';<br>
- else<br>
- s << ", demangled = <error>";<br>
- return s;<br>
-}<br>
+} // lldb_private<br>
<br>
Modified: lldb/trunk/source/Core/Mangled.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_lldb_trunk_source_Core_Mangled.cpp-3Frev-3D238459-26r1-3D238458-26r2-3D238459-26view-3Ddiff&d=AwMGaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=dRVtezha6XiI8JDn7qdrzU6dMVI5a_JOY9pYlT67zzc&s=7x6oLjP_GFqG9yBCxbAdEXxxyTdPo2g5HcKC9go3WXo&e=" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Mangled.cpp?rev=238459&r1=238458&r2=238459&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Core/Mangled.cpp (original)<br>
+++ lldb/trunk/source/Core/Mangled.cpp Thu May 28 14:15:15 2015<br>
@@ -23,4960 +23,9 @@<br>
<br>
// Provide a fast-path demangler implemented in FastDemangle.cpp until it can<br>
// replace the existing C++ demangler with a complete implementation<br>
-namespace lldb_private<br>
-{<br>
- extern char * FastDemangle (const char * mangled_name,<br>
- long mangled_name_length);<br>
-}<br>
+#include "lldb/Core/FastDemangle.h"<br>
+#include "lldb/Core/CxaDemangle.h"<br>
<br>
-//----------------------------------------------------------------------<br>
-// Inlined copy of:<br>
-// <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_svn_llvm-2Dproject_libcxxabi_trunk_src_cxa-5Fdemangle.cpp&d=AwMGaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=MEqT8U_n7oNfuDW5NRbY3ZV384ZquXIYFPWmprwUdKM&m=dRVtezha6XiI8JDn7qdrzU6dMVI5a_JOY9pYlT67zzc&s=ki-FHPcszvBIIQeWieV7fH1LREESFamv8YBYt7mVmYs&e=" target="_blank">http://llvm.org/svn/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp</a><br>
-// revision 199944.<br>
-//<br>
-// Changes include:<br>
-// - remove the "__cxxabiv1" namespace<br>
-// - stripped GCC attributes()<br>
-// - removed extern "C" from the cxa_demangle function<br>
-// - Changed the scope of the unnamed namespace to include cxa_demangle<br>
-// function.<br>
-// - Added "#undef _LIBCPP_EXTERN_TEMPLATE" to avoid warning<br>
-//----------------------------------------------------------------------<br>
-<br>
-#undef _LIBCPP_EXTERN_TEMPLATE // Avoid warning below<br>
-<br>
-//===-------------------------- cxa_demangle.cpp --------------------------===//<br>
-//<br>
-// The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is dual licensed under the MIT and the University of Illinois Open<br>
-// Source Licenses. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#define _LIBCPP_EXTERN_TEMPLATE(...)<br>
-#define _LIBCPP_NO_EXCEPTIONS<br>
-<br>
-#include <vector><br>
-#include <algorithm><br>
-#include <string><br>
-#include <numeric><br>
-#include <cstdlib><br>
-#include <cstring><br>
-#include <cctype><br>
-<br>
-<br>
-namespace<br>
-{<br>
-<br>
-enum<br>
-{<br>
- unknown_error = -4,<br>
- invalid_args = -3,<br>
- invalid_mangled_name,<br>
- memory_alloc_failure,<br>
- success<br>
-};<br>
-<br>
-template <class C><br>
- const char* parse_type(const char* first, const char* last, C& db);<br>
-template <class C><br>
- const char* parse_encoding(const char* first, const char* last, C& db);<br>
-template <class C><br>
- const char* parse_name(const char* first, const char* last, C& db);<br>
-template <class C><br>
- const char* parse_expression(const char* first, const char* last, C& db);<br>
-template <class C><br>
- const char* parse_template_args(const char* first, const char* last, C& db);<br>
-template <class C><br>
- const char* parse_operator_name(const char* first, const char* last, C& db);<br>
-template <class C><br>
- const char* parse_unqualified_name(const char* first, const char* last, C& db);<br>
-template <class C><br>
- const char* parse_decltype(const char* first, const char* last, C& db);<br>
-<br>
-template <class C><br>
-void<br>
-print_stack(const C& db)<br>
-{<br>
- printf("---------\n");<br>
- printf("names:\n");<br>
- for (auto& s : db.names)<br>
- printf("{%s#%s}\n", s.first.c_str(), s.second.c_str());<br>
- int i = -1;<br>
- printf("subs:\n");<br>
- for (auto& v : db.subs)<br>
- {<br>
- if (i >= 0)<br>
- printf("S%i_ = {", i);<br>
- else<br>
- printf("S_ = {");<br>
- for (auto& s : v)<br>
- printf("{%s#%s}", s.first.c_str(), s.second.c_str());<br>
- printf("}\n");<br>
- ++i;<br>
- }<br>
- printf("template_param:\n");<br>
- for (auto& t : db.template_param)<br>
- {<br>
- printf("--\n");<br>
- i = -1;<br>
- for (auto& v : t)<br>
- {<br>
- if (i >= 0)<br>
- printf("T%i_ = {", i);<br>
- else<br>
- printf("T_ = {");<br>
- for (auto& s : v)<br>
- printf("{%s#%s}", s.first.c_str(), s.second.c_str());<br>
- printf("}\n");<br>
- ++i;<br>
- }<br>
- }<br>
- printf("---------\n\n");<br>
-}<br>
-<br>
-template <class C><br>
-void<br>
-print_state(const char* msg, const char* first, const char* last, const C& db)<br>
-{<br>
- printf("%s: ", msg);<br>
- for (; first != last; ++first)<br>
- printf("%c", *first);<br>
- printf("\n");<br>
- print_stack(db);<br>
-}<br>
-<br>
-// <number> ::= [n] <non-negative decimal integer><br>
-<br>
-const char*<br>
-parse_number(const char* first, const char* last)<br>
-{<br>
- if (first != last)<br>
- {<br>
- const char* t = first;<br>
- if (*t == 'n')<br>
- ++t;<br>
- if (t != last)<br>
- {<br>
- if (*t == '0')<br>
- {<br>
- first = t+1;<br>
- }<br>
- else if ('1' <= *t && *t <= '9')<br>
- {<br>
- first = t+1;<br>
- while (first != last && std::isdigit(*first))<br>
- ++first;<br>
- }<br>
- }<br>
- }<br>
- return first;<br>
-}<br>
-<br>
-template <class Float><br>
-struct float_data;<br>
-<br>
-template <><br>
-struct float_data<float><br>
-{<br>
- static const size_t mangled_size = 8;<br>
- static const size_t max_demangled_size = 24;<br>
- static constexpr const char* spec = "%af";<br>
-};<br>
-<br>
-constexpr const char* float_data<float>::spec;<br>
-<br>
-template <><br>
-struct float_data<double><br>
-{<br>
- static const size_t mangled_size = 16;<br>
- static const size_t max_demangled_size = 32;<br>
- static constexpr const char* spec = "%a";<br>
-};<br>
-<br>
-constexpr const char* float_data<double>::spec;<br>
-<br>
-template <><br>
-struct float_data<long double><br>
-{<br>
- static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms<br>
- static const size_t max_demangled_size = 40;<br>
- static constexpr const char* spec = "%LaL";<br>
-};<br>
-<br>
-constexpr const char* float_data<long double>::spec;<br>
-<br>
-template <class Float, class C><br>
-const char*<br>
-parse_floating_number(const char* first, const char* last, C& db)<br>
-{<br>
- const size_t N = float_data<Float>::mangled_size;<br>
- if (static_cast<std::size_t>(last - first) > N)<br>
- {<br>
- last = first + N;<br>
- union<br>
- {<br>
- Float value;<br>
- char buf[sizeof(Float)];<br>
- };<br>
- const char* t = first;<br>
- char* e = buf;<br>
- for (; t != last; ++t, ++e)<br>
- {<br>
- if (!isxdigit(*t))<br>
- return first;<br>
- unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0') :<br>
- static_cast<unsigned>(*t - 'a' + 10);<br>
- ++t;<br>
- unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0') :<br>
- static_cast<unsigned>(*t - 'a' + 10);<br>
- *e = static_cast<char>((d1 << 4) + d0);<br>
- }<br>
- if (*t == 'E')<br>
- {<br>
-#if __LITTLE_ENDIAN__<br>
- std::reverse(buf, e);<br>
-#endif<br>
- char num[float_data<Float>::max_demangled_size] = {0};<br>
- int n = snprintf(num, sizeof(num), float_data<Float>::spec, value);<br>
- if (static_cast<std::size_t>(n) >= sizeof(num))<br>
- return first;<br>
- db.names.push_back(typename C::String(num, static_cast<std::size_t>(n)));<br>
- first = t+1;<br>
- }<br>
- }<br>
- return first;<br>
-}<br>
-<br>
-// <source-name> ::= <positive length number> <identifier><br>
-<br>
-template <class C><br>
-const char*<br>
-parse_source_name(const char* first, const char* last, C& db)<br>
-{<br>
- if (first != last)<br>
- {<br>
- char c = *first;<br>
- if (isdigit(c) && first+1 != last)<br>
- {<br>
- const char* t = first+1;<br>
- size_t n = static_cast<size_t>(c - '0');<br>
- for (c = *t; isdigit(c); c = *t)<br>
- {<br>
- n = n * 10 + static_cast<size_t>(c - '0');<br>
- if (++t == last)<br>
- return first;<br>
- }<br>
- if (static_cast<size_t>(last - t) >= n)<br>
- {<br>
- typename C::String r(t, n);<br>
- if (r.substr(0, 10) == "_GLOBAL__N")<br>
- db.names.push_back("(anonymous namespace)");<br>
- else<br>
- db.names.push_back(std::move(r));<br>
- first = t + n;<br>
- }<br>
- }<br>
- }<br>
- return first;<br>
-}<br>
-<br>
-// <substitution> ::= S <seq-id> _<br>
-// ::= S_<br>
-// <substitution> ::= Sa # ::std::allocator<br>
-// <substitution> ::= Sb # ::std::basic_string<br>
-// <substitution> ::= Ss # ::std::basic_string < char,<br>
-// ::std::char_traits<char>,<br>
-// ::std::allocator<char> ><br>
-// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> ><br>
-// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> ><br>
-// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> ><br>
-<br>
-template <class C><br>
-const char*<br>
-parse_substitution(const char* first, const char* last, C& db)<br>
-{<br>
- if (last - first >= 2)<br>
- {<br>
- if (*first == 'S')<br>
- {<br>
- switch (first[1])<br>
- {<br>
- case 'a':<br>
- db.names.push_back("std::allocator");<br>
- first += 2;<br>
- break;<br>
- case 'b':<br>
- db.names.push_back("std::basic_string");<br>
- first += 2;<br>
- break;<br>
- case 's':<br>
- db.names.push_back("std::string");<br>
- first += 2;<br>
- break;<br>
- case 'i':<br>
- db.names.push_back("std::istream");<br>
- first += 2;<br>
- break;<br>
- case 'o':<br>
- db.names.push_back("std::ostream");<br>
- first += 2;<br>
- break;<br>
- case 'd':<br>
- db.names.push_back("std::iostream");<br>
- first += 2;<br>
- break;<br>
- case '_':<br>
- if (!db.subs.empty())<br>
- {<br>
- for (const auto& n : db.subs.front())<br>
- db.names.push_back(n);<br>
- first += 2;<br>
- }<br>
- break;<br>
- default:<br>
- if (std::isdigit(first[1]) || std::isupper(first[1]))<br>
- {<br>
- size_t sub = 0;<br>
- const char* t = first+1;<br>
- if (std::isdigit(*t))<br>
- sub = static_cast<size_t>(*t - '0');<br>
- else<br>
- sub = static_cast<size_t>(*t - 'A') + 10;<br>
- for (++t; t != last && (std::isdigit(*t) || std::isupper(*t)); ++t)<br>
- {<br>
- sub *= 36;<br>
- if (std::isdigit(*t))<br>
- sub += static_cast<size_t>(*t - '0');<br>
- else<br>
- sub += static_cast<size_t>(*t - 'A') + 10;<br>
- }<br>
- if (t == last || *t != '_')<br>
- return first;<br>
- ++sub;<br>
- if (sub < db.subs.size())<br>
- {<br>
- for (const auto& n : db.subs[sub])<br>
- db.names.push_back(n);<br>
- first = t+1;<br>
- }<br>
- }<br>
- break;<br>
- }<br>
- }<br>
- }<br>
- return first;<br>
-}<br>
-<br>
-// <builtin-type> ::= v # void<br>
-// ::= w # wchar_t<br>
-// ::= b # bool<br>
-// ::= c # char<br>
-// ::= a # signed char<br>
-// ::= h # unsigned char<br>
-// ::= s # short<br>
-// ::= t # unsigned short<br>
-// ::= i # int<br>
-// ::= j # unsigned int<br>
-// ::= l # long<br>
-// ::= m # unsigned long<br>
-// ::= x # long long, __int64<br>
-// ::= y # unsigned long long, __int64<br>
-// ::= n # __int128<br>
-// ::= o # unsigned __int128<br>
-// ::= f # float<br>
-// ::= d # double<br>
-// ::= e # long double, __float80<br>
-// ::= g # __float128<br>
-// ::= z # ellipsis<br>
-// ::= Dd # IEEE 754r decimal floating point (64 bits)<br>
-// ::= De # IEEE 754r decimal floating point (128 bits)<br>
-// ::= Df # IEEE 754r decimal floating point (32 bits)<br>
-// ::= Dh # IEEE 754r half-precision floating point (16 bits)<br>
-// ::= Di # char32_t<br>
-// ::= Ds # char16_t<br>
-// ::= Da # auto (in dependent new-expressions)<br>
-// ::= Dn # std::nullptr_t (i.e., decltype(nullptr))<br>
-// ::= u <source-name> # vendor extended type<br>
-<br>
-template <class C><br>
-const char*<br>
-parse_builtin_type(const char* first, const char* last, C& db)<br>
-{<br>
- if (first != last)<br>
- {<br>
- switch (*first)<br>
- {<br>
- case 'v':<br>
- db.names.push_back("void");<br>
- ++first;<br>
- break;<br>
- case 'w':<br>
- db.names.push_back("wchar_t");<br>
- ++first;<br>
- break;<br>
- case 'b':<br>
- db.names.push_back("bool");<br>
- ++first;<br>
- break;<br>
- case 'c':<br>
- db.names.push_back("char");<br>
- ++first;<br>
- break;<br>
- case 'a':<br>
- db.names.push_back("signed char");<br>
- ++first;<br>
- break;<br>
- case 'h':<br>
- db.names.push_back("unsigned char");<br>
- ++first;<br>
- break;<br>
- case 's':<br>
- db.names.push_back("short");<br>
- ++first;<br>
- break;<br>
- case 't':<br>
- db.names.push_back("unsigned short");<br>
- ++first;<br>
- break;<br>
- case 'i':<br>
- db.names.push_back("int");<br>
- ++first;<br>
- break;<br>
- case 'j':<br>
- db.names.push_back("unsigned int");<br>
- ++first;<br>
- break;<br>
- case 'l':<br>
- db.names.push_back("long");<br>
- ++first;<br>
- break;<br>
- case 'm':<br>
- db.names.push_back("unsigned long");<br>
- ++first;<br>
- break;<br>
- case 'x':<br>
- db.names.push_back("long long");<br>
- ++first;<br>
- break;<br>
- case 'y':<br>
- db.names.push_back("unsigned long long");<br>
- ++first;<br>
- break;<br>
- case 'n':<br>
- db.names.push_back("__int128");<br>
- ++first;<br>
- break;<br>
- case 'o':<br>
- db.names.push_back("unsigned __int128");<br>
- ++first;<br>
- break;<br>
- case 'f':<br>
- db.names.push_back("float");<br>
- ++first;<br>
- break;<br>
- case 'd':<br>
- db.names.push_back("double");<br>
- ++first;<br>
- break;<br>
- case 'e':<br>
- db.names.push_back("long double");<br>
- ++first;<br>
- break;<br>
- case 'g':<br>
- db.names.push_back("__float128");<br>
- ++first;<br>
- break;<br>
- case 'z':<br>
- db.names.push_back("...");<br>
- ++first;<br>
- break;<br>
- case 'u':<br>
- {<br>
- const char*t = parse_source_name(first+1, last, db);<br>
- if (t != first+1)<br>
- first = t;<br>
- }<br>
- break;<br>
- case 'D':<br>
- if (first+1 != last)<br>
- {<br>
- switch (first[1])<br>
- {<br>
- case 'd':<br>
- db.names.push_back("decimal64");<br>
- first += 2;<br>
- break;<br>
- case 'e':<br>
- db.names.push_back("decimal128");<br>
- first += 2;<br>
- break;<br>
- case 'f':<br>
- db.names.push_back("decimal32");<br>
- first += 2;<br>
- break;<br>
- case 'h':<br>
- db.names.push_back("decimal16");<br>
- first += 2;<br>
- break;<br>
- case 'i':<br>
- db.names.push_back("char32_t");<br>
- first += 2;<br>
- break;<br>
- case 's':<br>
- db.names.push_back("char16_t");<br>
- first += 2;<br>
- break;<br>
- case 'a':<br>
- db.names.push_back("auto");<br>
- first += 2;<br>
- break;<br>
- case 'n':<br>
- db.names.push_back("std::nullptr_t");<br>
- first += 2;<br>
- break;<br>
- }<br>
- }<br>
- break;<br>
- }<br>
- }<br>
- return first;<br>
-}<br>
-<br>
-// <CV-qualifiers> ::= [r] [V] [K]<br>
-<br>
-const char*<br>
-parse_cv_qualifiers(const char* first, const char* last, unsigned& cv)<br>
-{<br>
- cv = 0;<br>
- if (first != last)<br>
- {<br>
- if (*first == 'r')<br>
- {<br>
- cv |= 4;<br>
- ++first;<br>
- }<br>
- if (*first == 'V')<br>
- {<br>
- cv |= 2;<br>
- ++first;<br>
- }<br>
- if (*first == 'K')<br>
- {<br>
- cv |= 1;<br>
- ++first;<br>
- }<br>
- }<br>
- return first;<br>
-}<br>
-<br>
-// <template-param> ::= T_ # first template parameter<br>
-// ::= T <parameter-2 non-negative number> _<br>
-<br>
-template <class C><br>
-const char*<br>
-parse_template_param(const char* first, const char* last, C& db)<br>
-{<br>
- if (last - first >= 2)<br>
- {<br>
- if (*first == 'T')<br>
- {<br>
- if (first[1] == '_')<br>
- {<br>
- if (db.template_param.empty())<br>
- return first;<br>
- if (!db.template_param.back().empty())<br>
- {<br>
- for (auto& t : db.template_param.back().front())<br>
- db.names.push_back(t);<br>
- first += 2;<br>
- }<br>
- else<br>
- {<br>
- db.names.push_back("T_");<br>
- first += 2;<br>
- db.fix_forward_references = true;<br>
- }<br>
- }<br>
- else if (isdigit(first[1]))<br>
- {<br>
- const char* t = first+1;<br>
- size_t sub = static_cast<size_t>(*t - '0');<br>
- for (++t; t != last && isdigit(*t); ++t)<br>
- {<br>
- sub *= 10;<br>
- sub += static_cast<size_t>(*t - '0');<br>
- }<br>
- if (t == last || *t != '_' || db.template_param.empty())<br>
- return first;<br>
- ++sub;<br>
- if (sub < db.template_param.back().size())<br>
- {<br>
- for (auto& temp : db.template_param.back()[sub])<br>
- db.names.push_back(temp);<br>
- first = t+1;<br>
- }<br>
- else<br>
- {<br>
- db.names.push_back(typename C::String(first, t+1));<br>
- first = t+1;<br>
- db.fix_forward_references = true;<br>
- }<br>
- }<br>
- }<br>
- }<br>
- return first;<br>
-}<br>
-<br>
-// cc <type> <expression> # const_cast<type> (expression)<br>
-<br>
-template <class C><br>
-const char*<br>
-parse_const_cast_expr(const char* first, c</blockquote></div>
</blockquote></div><br></div>