forked from OSchip/llvm-project
Pickup fixes for demangling crashers.
<rdar://problem/15600471> llvm-svn: 197171
This commit is contained in:
parent
3db958387f
commit
b73a31efe6
|
@ -20,17 +20,10 @@
|
|||
|
||||
#ifdef LLDB_USE_BUILTIN_DEMANGLER
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <numeric>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
//----------------------------------------------------------------------
|
||||
// Inlined copy of:
|
||||
// http://llvm.org/svn/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp
|
||||
// revision 193704.
|
||||
// revision 197169.
|
||||
//
|
||||
// Changes include:
|
||||
// - remove the "__cxxabiv1" namespace
|
||||
|
@ -38,8 +31,32 @@
|
|||
// - removed extern "C" from the cxa_demangle function
|
||||
// - Changed the scope of the unnamed namespace to include cxa_demangle
|
||||
// function.
|
||||
// - Added "#undef _LIBCPP_EXTERN_TEMPLATE" to avoid warning
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#undef _LIBCPP_EXTERN_TEMPLATE // Avoid warning below
|
||||
|
||||
//===-------------------------- cxa_demangle.cpp --------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define _LIBCPP_EXTERN_TEMPLATE(...)
|
||||
#define _LIBCPP_NO_EXCEPTIONS
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <numeric>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
|
@ -558,6 +575,8 @@ parse_template_param(const char* first, const char* last, C& db)
|
|||
{
|
||||
if (first[1] == '_')
|
||||
{
|
||||
if (db.template_param.empty())
|
||||
return first;
|
||||
if (!db.template_param.back().empty())
|
||||
{
|
||||
for (auto& t : db.template_param.back().front())
|
||||
|
@ -580,7 +599,7 @@ parse_template_param(const char* first, const char* last, C& db)
|
|||
sub *= 10;
|
||||
sub += static_cast<size_t>(*t - '0');
|
||||
}
|
||||
if (t == last || *t != '_')
|
||||
if (t == last || *t != '_' || db.template_param.empty())
|
||||
return first;
|
||||
++sub;
|
||||
if (sub < db.template_param.back().size())
|
||||
|
@ -615,6 +634,8 @@ parse_const_cast_expr(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_expression(t, last, db);
|
||||
if (t1 != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto expr = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back() = "const_cast<" + db.names.back().move_full() + ">(" + expr + ")";
|
||||
|
@ -639,6 +660,8 @@ parse_dynamic_cast_expr(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_expression(t, last, db);
|
||||
if (t1 != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto expr = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back() = "dynamic_cast<" + db.names.back().move_full() + ">(" + expr + ")";
|
||||
|
@ -663,6 +686,8 @@ parse_reinterpret_cast_expr(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_expression(t, last, db);
|
||||
if (t1 != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto expr = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back() = "reinterpret_cast<" + db.names.back().move_full() + ">(" + expr + ")";
|
||||
|
@ -687,6 +712,8 @@ parse_static_cast_expr(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_expression(t, last, db);
|
||||
if (t1 != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto expr = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back() = "static_cast<" + db.names.back().move_full() + ">(" + expr + ")";
|
||||
|
@ -723,6 +750,8 @@ parse_sizeof_type_expr(const char* first, const char* last, C& db)
|
|||
const char* t = parse_type(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back() = "sizeof (" + db.names.back().move_full() + ")";
|
||||
first = t;
|
||||
}
|
||||
|
@ -741,6 +770,8 @@ parse_sizeof_expr_expr(const char* first, const char* last, C& db)
|
|||
const char* t = parse_expression(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back() = "sizeof (" + db.names.back().move_full() + ")";
|
||||
first = t;
|
||||
}
|
||||
|
@ -832,6 +863,8 @@ parse_sizeof_function_param_pack_expr(const char* first, const char* last, C& db
|
|||
const char* t = parse_function_param(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back() = "sizeof...(" + db.names.back().move_full() + ")";
|
||||
first = t;
|
||||
}
|
||||
|
@ -855,6 +888,8 @@ parse_typeid_expr(const char* first, const char* last, C& db)
|
|||
t = parse_type(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back() = "typeid(" + db.names.back().move_full() + ")";
|
||||
first = t;
|
||||
}
|
||||
|
@ -873,6 +908,8 @@ parse_throw_expr(const char* first, const char* last, C& db)
|
|||
const char* t = parse_expression(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back() = "throw " + db.names.back().move_full();
|
||||
first = t;
|
||||
}
|
||||
|
@ -894,6 +931,8 @@ parse_dot_star_expr(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_expression(t, last, db);
|
||||
if (t1 != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto expr = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first += ".*" + expr;
|
||||
|
@ -918,6 +957,8 @@ parse_simple_id(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_template_args(t, last, db);
|
||||
if (t1 != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto args = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first += std::move(args);
|
||||
|
@ -964,6 +1005,8 @@ parse_unresolved_type(const char* first, const char* last, C& db)
|
|||
t = parse_decltype(first, last, db);
|
||||
if (t != first)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
|
||||
first = t;
|
||||
}
|
||||
|
@ -979,6 +1022,8 @@ parse_unresolved_type(const char* first, const char* last, C& db)
|
|||
t = parse_unqualified_name(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
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()));
|
||||
first = t;
|
||||
|
@ -1005,6 +1050,8 @@ parse_destructor_name(const char* first, const char* last, C& db)
|
|||
t = parse_simple_id(first, last, db);
|
||||
if (t != first)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.insert(0, "~");
|
||||
first = t;
|
||||
}
|
||||
|
@ -1036,6 +1083,8 @@ parse_base_unresolved_name(const char* first, const char* last, C& db)
|
|||
first = parse_template_args(t, last, db);
|
||||
if (first != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto args = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first += std::move(args);
|
||||
|
@ -1060,6 +1109,8 @@ parse_base_unresolved_name(const char* first, const char* last, C& db)
|
|||
first = parse_template_args(t, last, db);
|
||||
if (first != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto args = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first += std::move(args);
|
||||
|
@ -1109,7 +1160,11 @@ parse_unresolved_name(const char* first, const char* last, C& db)
|
|||
if (t2 != t)
|
||||
{
|
||||
if (global)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.insert(0, "::");
|
||||
}
|
||||
first = t2;
|
||||
}
|
||||
else if (last - t > 2 && t[0] == 's' && t[1] == 'r')
|
||||
|
@ -1124,6 +1179,8 @@ parse_unresolved_name(const char* first, const char* last, C& db)
|
|||
t1 = parse_template_args(t, last, db);
|
||||
if (t1 != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto args = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first += std::move(args);
|
||||
|
@ -1137,7 +1194,7 @@ parse_unresolved_name(const char* first, const char* last, C& db)
|
|||
while (*t != 'E')
|
||||
{
|
||||
t1 = parse_unresolved_qualifier_level(t, last, db);
|
||||
if (t1 == t || t1 == last)
|
||||
if (t1 == t || t1 == last || db.names.size() < 2)
|
||||
return first;
|
||||
auto s = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
|
@ -1148,9 +1205,12 @@ parse_unresolved_name(const char* first, const char* last, C& db)
|
|||
t1 = parse_base_unresolved_name(t, last, db);
|
||||
if (t1 == t)
|
||||
{
|
||||
db.names.pop_back();
|
||||
if (!db.names.empty())
|
||||
db.names.pop_back();
|
||||
return first;
|
||||
}
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto s = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first += "::" + std::move(s);
|
||||
|
@ -1166,6 +1226,8 @@ parse_unresolved_name(const char* first, const char* last, C& db)
|
|||
t1 = parse_template_args(t, last, db);
|
||||
if (t1 != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto args = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first += std::move(args);
|
||||
|
@ -1174,9 +1236,12 @@ parse_unresolved_name(const char* first, const char* last, C& db)
|
|||
t1 = parse_base_unresolved_name(t, last, db);
|
||||
if (t1 == t)
|
||||
{
|
||||
db.names.pop_back();
|
||||
if (!db.names.empty())
|
||||
db.names.pop_back();
|
||||
return first;
|
||||
}
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto s = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first += "::" + std::move(s);
|
||||
|
@ -1189,11 +1254,15 @@ parse_unresolved_name(const char* first, const char* last, C& db)
|
|||
return first;
|
||||
t = t1;
|
||||
if (global)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.insert(0, "::");
|
||||
}
|
||||
while (*t != 'E')
|
||||
{
|
||||
t1 = parse_unresolved_qualifier_level(t, last, db);
|
||||
if (t1 == t || t1 == last)
|
||||
if (t1 == t || t1 == last || db.names.size() < 2)
|
||||
return first;
|
||||
auto s = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
|
@ -1204,9 +1273,12 @@ parse_unresolved_name(const char* first, const char* last, C& db)
|
|||
t1 = parse_base_unresolved_name(t, last, db);
|
||||
if (t1 == t)
|
||||
{
|
||||
db.names.pop_back();
|
||||
if (!db.names.empty())
|
||||
db.names.pop_back();
|
||||
return first;
|
||||
}
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto s = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first += "::" + std::move(s);
|
||||
|
@ -1232,6 +1304,8 @@ parse_dot_expr(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_unresolved_name(t, last, db);
|
||||
if (t1 != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto name = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first += "." + name;
|
||||
|
@ -1255,6 +1329,8 @@ parse_call_expr(const char* first, const char* last, C& db)
|
|||
{
|
||||
if (t == last)
|
||||
return first;
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first += db.names.back().second;
|
||||
db.names.back().second = typename C::String();
|
||||
db.names.back().first.append("(");
|
||||
|
@ -1264,10 +1340,14 @@ parse_call_expr(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_expression(t, last, db);
|
||||
if (t1 == t || t1 == last)
|
||||
return first;
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
auto tmp = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
if (!tmp.empty())
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
if (!first_expr)
|
||||
{
|
||||
db.names.back().first.append(", ");
|
||||
|
@ -1278,6 +1358,8 @@ parse_call_expr(const char* first, const char* last, C& db)
|
|||
t = t1;
|
||||
}
|
||||
++t;
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.append(")");
|
||||
first = t;
|
||||
}
|
||||
|
@ -1320,10 +1402,14 @@ parse_new_expr(const char* first, const char* last, C& db)
|
|||
has_expr_list = true;
|
||||
if (!first_expr)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
auto tmp = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
if (!tmp.empty())
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.append(", ");
|
||||
db.names.back().first.append(tmp);
|
||||
first_expr = false;
|
||||
|
@ -1349,10 +1435,14 @@ parse_new_expr(const char* first, const char* last, C& db)
|
|||
return first;
|
||||
if (!first_expr)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
auto tmp = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
if (!tmp.empty())
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.append(", ");
|
||||
db.names.back().first.append(tmp);
|
||||
first_expr = false;
|
||||
|
@ -1366,14 +1456,20 @@ parse_new_expr(const char* first, const char* last, C& db)
|
|||
typename C::String init_list;
|
||||
if (has_init)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
init_list = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
}
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
auto type = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
typename C::String expr_list;
|
||||
if (has_expr_list)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
expr_list = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
}
|
||||
|
@ -1435,10 +1531,14 @@ parse_conversion_expr(const char* first, const char* last, C& db)
|
|||
return first;
|
||||
if (!first_expr)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
auto tmp = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
if (!tmp.empty())
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.append(", ");
|
||||
db.names.back().first.append(tmp);
|
||||
first_expr = false;
|
||||
|
@ -1449,6 +1549,8 @@ parse_conversion_expr(const char* first, const char* last, C& db)
|
|||
}
|
||||
++t;
|
||||
}
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto tmp = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back() = "(" + db.names.back().move_full() + ")(" + tmp + ")";
|
||||
|
@ -1472,6 +1574,8 @@ parse_arrow_expr(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_expression(t, last, db);
|
||||
if (t1 != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto tmp = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first += "->";
|
||||
|
@ -1564,6 +1668,8 @@ parse_function_type(const char* first, const char* last, C& db)
|
|||
sig += " &&";
|
||||
break;
|
||||
}
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first += " ";
|
||||
db.names.back().second.insert(0, sig);
|
||||
first = t;
|
||||
|
@ -1587,6 +1693,8 @@ parse_pointer_to_member_type(const char* first, const char* last, C& db)
|
|||
const char* t2 = parse_type(t, last, db);
|
||||
if (t2 != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto func = std::move(db.names.back());
|
||||
db.names.pop_back();
|
||||
auto class_type = std::move(db.names.back());
|
||||
|
@ -1621,6 +1729,8 @@ parse_array_type(const char* first, const char* last, C& db)
|
|||
const char* t = parse_type(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
if (db.names.back().second.substr(0, 2) == " [")
|
||||
db.names.back().second.erase(0, 1);
|
||||
db.names.back().second.insert(0, " []");
|
||||
|
@ -1635,6 +1745,8 @@ parse_array_type(const char* first, const char* last, C& db)
|
|||
const char* t2 = parse_type(t+1, last, db);
|
||||
if (t2 != t+1)
|
||||
{
|
||||
if (db.names.empty())
|
||||
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) + "]");
|
||||
|
@ -1650,6 +1762,8 @@ parse_array_type(const char* first, const char* last, C& db)
|
|||
const char* t2 = parse_type(++t, last, db);
|
||||
if (t2 != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto type = std::move(db.names.back());
|
||||
db.names.pop_back();
|
||||
auto expr = std::move(db.names.back());
|
||||
|
@ -1682,6 +1796,8 @@ parse_decltype(const char* first, const char* last, C& db)
|
|||
const char* t = parse_expression(first+2, last, db);
|
||||
if (t != first+2 && t != last && *t == 'E')
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back() = "decltype(" + db.names.back().move_full() + ")";
|
||||
first = t+1;
|
||||
}
|
||||
|
@ -1719,6 +1835,8 @@ parse_vector_type(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_type(t, last, db);
|
||||
if (t1 != t)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first += " vector[" + typename C::String(num, sz) + "]";
|
||||
first = t1;
|
||||
}
|
||||
|
@ -1740,6 +1858,8 @@ parse_vector_type(const char* first, const char* last, C& db)
|
|||
const char* t = parse_expression(t1, last, db);
|
||||
if (t != t1)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
num = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
t1 = t;
|
||||
|
@ -1750,6 +1870,8 @@ parse_vector_type(const char* first, const char* last, C& db)
|
|||
const char* t = parse_type(t1, last, db);
|
||||
if (t != t1)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first += " vector[" + num + "]";
|
||||
first = t;
|
||||
}
|
||||
|
@ -1860,6 +1982,8 @@ parse_type(const char* first, const char* last, C& db)
|
|||
t = parse_array_type(first, last, db);
|
||||
if (t != first)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
first = t;
|
||||
db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
|
||||
}
|
||||
|
@ -1868,6 +1992,8 @@ parse_type(const char* first, const char* last, C& db)
|
|||
t = parse_type(first+1, last, db);
|
||||
if (t != first+1)
|
||||
{
|
||||
if (db.names.empty())
|
||||
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()));
|
||||
|
@ -1877,6 +2003,8 @@ parse_type(const char* first, const char* last, C& db)
|
|||
t = parse_function_type(first, last, db);
|
||||
if (t != first)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
first = t;
|
||||
db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
|
||||
}
|
||||
|
@ -1885,6 +2013,8 @@ parse_type(const char* first, const char* last, C& db)
|
|||
t = parse_type(first+1, last, db);
|
||||
if (t != first+1)
|
||||
{
|
||||
if (db.names.empty())
|
||||
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()));
|
||||
|
@ -1894,6 +2024,8 @@ parse_type(const char* first, const char* last, C& db)
|
|||
t = parse_pointer_to_member_type(first, last, db);
|
||||
if (t != first)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
first = t;
|
||||
db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
|
||||
}
|
||||
|
@ -2021,6 +2153,8 @@ parse_type(const char* first, const char* last, C& db)
|
|||
const char* t2 = parse_type(t, last, db);
|
||||
if (t2 != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto type = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
if (db.names.back().first.substr(0, 9) != "objcproto")
|
||||
|
@ -2053,6 +2187,8 @@ parse_type(const char* first, const char* last, C& db)
|
|||
t = parse_name(first, last, db);
|
||||
if (t != first)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
|
||||
first = t;
|
||||
}
|
||||
|
@ -2068,6 +2204,8 @@ parse_type(const char* first, const char* last, C& db)
|
|||
t = parse_template_args(first, last, db);
|
||||
if (t != first)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto template_args = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first += template_args;
|
||||
|
@ -2103,6 +2241,8 @@ parse_type(const char* first, const char* last, C& db)
|
|||
t = parse_decltype(first, last, db);
|
||||
if (t != first)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
|
||||
first = t;
|
||||
return first;
|
||||
|
@ -2112,6 +2252,8 @@ parse_type(const char* first, const char* last, C& db)
|
|||
t = parse_vector_type(first, last, db);
|
||||
if (t != first)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
|
||||
first = t;
|
||||
return first;
|
||||
|
@ -2133,6 +2275,8 @@ parse_type(const char* first, const char* last, C& db)
|
|||
t = parse_name(first, last, db);
|
||||
if (t != first)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
|
||||
first = t;
|
||||
}
|
||||
|
@ -2251,6 +2395,8 @@ parse_operator_name(const char* first, const char* last, C& db)
|
|||
db.try_to_parse_template_args = try_to_parse_template_args;
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.insert(0, "operator ");
|
||||
db.parsed_ctor_dtor_cv = true;
|
||||
first = t;
|
||||
|
@ -2472,6 +2618,8 @@ parse_operator_name(const char* first, const char* last, C& db)
|
|||
const char* t = parse_source_name(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.insert(0, "operator ");
|
||||
first = t;
|
||||
}
|
||||
|
@ -2681,6 +2829,8 @@ parse_expr_primary(const char* first, const char* last, C& db)
|
|||
;
|
||||
if (n != t && n != last && *n == 'E')
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back() = "(" + db.names.back().move_full() + ")" + typename C::String(t, n);
|
||||
first = n+1;
|
||||
break;
|
||||
|
@ -2781,6 +2931,8 @@ parse_ctor_dtor_name(const char* first, const char* last, C& db)
|
|||
case '2':
|
||||
case '3':
|
||||
case '5':
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.push_back(base_name(db.names.back().first));
|
||||
first += 2;
|
||||
db.parsed_ctor_dtor_cv = true;
|
||||
|
@ -2794,6 +2946,8 @@ parse_ctor_dtor_name(const char* first, const char* last, C& db)
|
|||
case '1':
|
||||
case '2':
|
||||
case '5':
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.push_back("~" + base_name(db.names.back().first));
|
||||
first += 2;
|
||||
db.parsed_ctor_dtor_cv = true;
|
||||
|
@ -2864,6 +3018,8 @@ parse_unnamed_type_name(const char* first, const char* last, C& db)
|
|||
db.names.pop_back();
|
||||
return first;
|
||||
}
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto tmp = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first.append(tmp);
|
||||
|
@ -2873,6 +3029,8 @@ parse_unnamed_type_name(const char* first, const char* last, C& db)
|
|||
t1 = parse_type(t0, last, db);
|
||||
if (t1 == t0)
|
||||
break;
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
tmp = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
if (!tmp.empty())
|
||||
|
@ -2987,7 +3145,11 @@ parse_unscoped_name(const char* first, const char* last, C& db)
|
|||
if (t1 != t0)
|
||||
{
|
||||
if (St)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.insert(0, "std::");
|
||||
}
|
||||
first = t1;
|
||||
}
|
||||
}
|
||||
|
@ -3005,6 +3167,8 @@ parse_alignof_type(const char* first, const char* last, C& db)
|
|||
const char* t = parse_type(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first = "alignof (" + db.names.back().move_full() + ")";
|
||||
first = t;
|
||||
}
|
||||
|
@ -3023,6 +3187,8 @@ parse_alignof_expr(const char* first, const char* last, C& db)
|
|||
const char* t = parse_expression(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first = "alignof (" + db.names.back().move_full() + ")";
|
||||
first = t;
|
||||
}
|
||||
|
@ -3037,6 +3203,8 @@ parse_noexcept_expression(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_expression(first, last, db);
|
||||
if (t1 != first)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first = "noexcept (" + db.names.back().move_full() + ")";
|
||||
first = t1;
|
||||
}
|
||||
|
@ -3050,6 +3218,8 @@ parse_prefix_expression(const char* first, const char* last, const typename C::S
|
|||
const char* t1 = parse_expression(first, last, db);
|
||||
if (t1 != first)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first = op + "(" + db.names.back().move_full() + ")";
|
||||
first = t1;
|
||||
}
|
||||
|
@ -3066,6 +3236,8 @@ parse_binary_expression(const char* first, const char* last, const typename C::S
|
|||
const char* t2 = parse_expression(t1, last, db);
|
||||
if (t2 != t1)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto op2 = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
auto op1 = db.names.back().move_full();
|
||||
|
@ -3216,6 +3388,8 @@ parse_expression(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_expression(t+2, last, db);
|
||||
if (t1 != t+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first = (parsed_gs ? typename C::String("::") : typename C::String()) +
|
||||
"delete[] " + db.names.back().move_full();
|
||||
first = t1;
|
||||
|
@ -3235,6 +3409,8 @@ parse_expression(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_expression(t+2, last, db);
|
||||
if (t1 != t+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first = (parsed_gs ? typename C::String("::") : typename C::String()) +
|
||||
"delete " + db.names.back().move_full();
|
||||
first = t1;
|
||||
|
@ -3305,6 +3481,8 @@ parse_expression(const char* first, const char* last, C& db)
|
|||
const char* t2 = parse_expression(t1, last, db);
|
||||
if (t2 != t1)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto op2 = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
auto op1 = db.names.back().move_full();
|
||||
|
@ -3376,6 +3554,8 @@ parse_expression(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_expression(first+2, last, db);
|
||||
if (t1 != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back() = "(" + db.names.back().move_full() + ")--";
|
||||
first = t1;
|
||||
}
|
||||
|
@ -3464,6 +3644,8 @@ parse_expression(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_expression(first+2, last, db);
|
||||
if (t1 != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back() = "(" + db.names.back().move_full() + ")++";
|
||||
first = t1;
|
||||
}
|
||||
|
@ -3491,6 +3673,8 @@ parse_expression(const char* first, const char* last, C& db)
|
|||
const char* t3 = parse_expression(t2, last, db);
|
||||
if (t3 != t2)
|
||||
{
|
||||
if (db.names.size() < 3)
|
||||
return first;
|
||||
auto op3 = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
auto op2 = db.names.back().move_full();
|
||||
|
@ -3918,6 +4102,8 @@ parse_local_name(const char* first, const char* last, C& db)
|
|||
{
|
||||
case 's':
|
||||
first = parse_discriminator(t+1, last);
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.append("::string literal");
|
||||
break;
|
||||
case 'd':
|
||||
|
@ -3930,6 +4116,8 @@ parse_local_name(const char* first, const char* last, C& db)
|
|||
t1 = parse_name(t, last, db);
|
||||
if (t1 != t)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto name = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first.append("::");
|
||||
|
@ -3948,6 +4136,8 @@ parse_local_name(const char* first, const char* last, C& db)
|
|||
{
|
||||
// parse but ignore discriminator
|
||||
first = parse_discriminator(t1, last);
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto name = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first.append("::");
|
||||
|
@ -4004,11 +4194,15 @@ parse_name(const char* first, const char* last, C& db)
|
|||
{
|
||||
if (t1 != last && *t1 == 'I') // <unscoped-template-name> <template-args>
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
|
||||
t0 = t1;
|
||||
t1 = parse_template_args(t0, last, db);
|
||||
if (t1 != t0)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto tmp = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first += tmp;
|
||||
|
@ -4027,6 +4221,8 @@ parse_name(const char* first, const char* last, C& db)
|
|||
t1 = parse_template_args(t0, last, db);
|
||||
if (t1 != t0)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto tmp = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first += tmp;
|
||||
|
@ -4112,6 +4308,8 @@ parse_special_name(const char* first, const char* last, C& db)
|
|||
t = parse_type(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.insert(0, "vtable for ");
|
||||
first = t;
|
||||
}
|
||||
|
@ -4121,6 +4319,8 @@ parse_special_name(const char* first, const char* last, C& db)
|
|||
t = parse_type(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.insert(0, "VTT for ");
|
||||
first = t;
|
||||
}
|
||||
|
@ -4130,6 +4330,8 @@ parse_special_name(const char* first, const char* last, C& db)
|
|||
t = parse_type(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.insert(0, "typeinfo for ");
|
||||
first = t;
|
||||
}
|
||||
|
@ -4139,6 +4341,8 @@ parse_special_name(const char* first, const char* last, C& db)
|
|||
t = parse_type(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.insert(0, "typeinfo name for ");
|
||||
first = t;
|
||||
}
|
||||
|
@ -4155,6 +4359,8 @@ parse_special_name(const char* first, const char* last, C& db)
|
|||
t = parse_encoding(t1, last, db);
|
||||
if (t != t1)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.insert(0, "covariant return thunk to ");
|
||||
first = t;
|
||||
}
|
||||
|
@ -4171,6 +4377,8 @@ parse_special_name(const char* first, const char* last, C& db)
|
|||
const char* t1 = parse_type(++t0, last, db);
|
||||
if (t1 != t0)
|
||||
{
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto left = db.names.back().move_full();
|
||||
db.names.pop_back();
|
||||
db.names.back().first = "construction vtable for " +
|
||||
|
@ -4190,6 +4398,8 @@ parse_special_name(const char* first, const char* last, C& db)
|
|||
t = parse_encoding(t0, last, db);
|
||||
if (t != t0)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
if (first[2] == 'v')
|
||||
{
|
||||
db.names.back().first.insert(0, "virtual thunk to ");
|
||||
|
@ -4213,6 +4423,8 @@ parse_special_name(const char* first, const char* last, C& db)
|
|||
t = parse_name(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.insert(0, "guard variable for ");
|
||||
first = t;
|
||||
}
|
||||
|
@ -4222,6 +4434,8 @@ parse_special_name(const char* first, const char* last, C& db)
|
|||
t = parse_name(first+2, last, db);
|
||||
if (t != first+2)
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.insert(0, "reference temporary for ");
|
||||
first = t;
|
||||
}
|
||||
|
@ -4233,6 +4447,26 @@ parse_special_name(const char* first, const char* last, C& db)
|
|||
return first;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class save_value
|
||||
{
|
||||
T& restore_;
|
||||
T original_value_;
|
||||
public:
|
||||
save_value(T& restore)
|
||||
: restore_(restore),
|
||||
original_value_(restore)
|
||||
{}
|
||||
|
||||
~save_value()
|
||||
{
|
||||
restore_ = std::move(original_value_);
|
||||
}
|
||||
|
||||
save_value(const save_value&) = delete;
|
||||
save_value& operator=(const save_value&) = delete;
|
||||
};
|
||||
|
||||
// <encoding> ::= <function name> <bare-function-type>
|
||||
// ::= <data name>
|
||||
// ::= <special-name>
|
||||
|
@ -4243,6 +4477,11 @@ parse_encoding(const char* first, const char* last, C& db)
|
|||
{
|
||||
if (first != last)
|
||||
{
|
||||
save_value<decltype(db.encoding_depth)> su(db.encoding_depth);
|
||||
++db.encoding_depth;
|
||||
save_value<decltype(db.tag_templates)> sb(db.tag_templates);
|
||||
if (db.encoding_depth > 1)
|
||||
db.tag_templates = true;
|
||||
switch (*first)
|
||||
{
|
||||
case 'G':
|
||||
|
@ -4258,17 +4497,23 @@ parse_encoding(const char* first, const char* last, C& db)
|
|||
{
|
||||
if (t != last && *t != 'E' && *t != '.')
|
||||
{
|
||||
bool tag_templates = db.tag_templates;
|
||||
save_value<bool> sb2(db.tag_templates);
|
||||
db.tag_templates = false;
|
||||
const char* t2;
|
||||
typename C::String ret2;
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
const typename C::String& nm = db.names.back().first;
|
||||
if (nm.empty())
|
||||
return first;
|
||||
if (!db.parsed_ctor_dtor_cv && nm.back() == '>' && nm[nm.size()-2] != '-'
|
||||
&& nm[nm.size()-2] != '>')
|
||||
{
|
||||
t2 = parse_type(t, last, db);
|
||||
if (t2 == t)
|
||||
return first;
|
||||
if (db.names.size() < 2)
|
||||
return first;
|
||||
auto ret1 = std::move(db.names.back().first);
|
||||
ret2 = std::move(db.names.back().second);
|
||||
if (ret2.empty())
|
||||
|
@ -4305,6 +4550,8 @@ parse_encoding(const char* first, const char* last, C& db)
|
|||
db.names.pop_back();
|
||||
if (!tmp.empty())
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
if (!first_arg)
|
||||
db.names.back().first += ", ";
|
||||
else
|
||||
|
@ -4315,6 +4562,8 @@ parse_encoding(const char* first, const char* last, C& db)
|
|||
t = t2;
|
||||
}
|
||||
}
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first += ')';
|
||||
if (cv & 1)
|
||||
db.names.back().first.append(" const");
|
||||
|
@ -4328,7 +4577,6 @@ parse_encoding(const char* first, const char* last, C& db)
|
|||
db.names.back().first.append(" &&");
|
||||
db.names.back().first += ret2;
|
||||
first = t;
|
||||
db.tag_templates = tag_templates;
|
||||
}
|
||||
else
|
||||
first = t;
|
||||
|
@ -4370,6 +4618,8 @@ parse_block_invoke(const char* first, const char* last, C& db)
|
|||
while (t != last && isdigit(*t))
|
||||
++t;
|
||||
}
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first.insert(0, "invocation function for block in ");
|
||||
first = t;
|
||||
}
|
||||
|
@ -4385,6 +4635,8 @@ parse_dot_suffix(const char* first, const char* last, C& db)
|
|||
{
|
||||
if (first != last && *first == '.')
|
||||
{
|
||||
if (db.names.empty())
|
||||
return first;
|
||||
db.names.back().first += " (" + typename C::String(first, last) + ")";
|
||||
first = last;
|
||||
}
|
||||
|
@ -4620,6 +4872,7 @@ struct Db
|
|||
Vector<template_param_type> template_param;
|
||||
unsigned cv;
|
||||
unsigned ref;
|
||||
unsigned encoding_depth;
|
||||
bool parsed_ctor_dtor_cv;
|
||||
bool tag_templates;
|
||||
bool fix_forward_references;
|
||||
|
@ -4647,6 +4900,7 @@ __cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status)
|
|||
Db db(a);
|
||||
db.cv = 0;
|
||||
db.ref = 0;
|
||||
db.encoding_depth = 0;
|
||||
db.parsed_ctor_dtor_cv = false;
|
||||
db.tag_templates = true;
|
||||
db.template_param.emplace_back(a);
|
||||
|
@ -4699,8 +4953,7 @@ __cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status)
|
|||
return buf;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue