[Lldb-commits] [lldb] r197171 - Pickup fixes for demangling crashers.

Greg Clayton gclayton at apple.com
Thu Dec 12 09:39:39 PST 2013


Author: gclayton
Date: Thu Dec 12 11:39:39 2013
New Revision: 197171

URL: http://llvm.org/viewvc/llvm-project?rev=197171&view=rev
Log:
Pickup fixes for demangling crashers.

<rdar://problem/15600471>


Modified:
    lldb/trunk/source/Core/Mangled.cpp

Modified: lldb/trunk/source/Core/Mangled.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Mangled.cpp?rev=197171&r1=197170&r2=197171&view=diff
==============================================================================
--- lldb/trunk/source/Core/Mangled.cpp (original)
+++ lldb/trunk/source/Core/Mangled.cpp Thu Dec 12 11:39:39 2013
@@ -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,
         {
             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,
                     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* 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* firs
             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*
             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* 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* 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* 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(co
         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, con
             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, cons
         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, c
             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
             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,
             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,
                     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,
             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* f
                     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* f
                     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,
         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,
                 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,
                 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,
                 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,
                     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,
                     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,
                         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,
                     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
             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
         {
             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
                 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
                 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
                 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
                         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
             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,
                             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,
                 }
                 ++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, cons
             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, c
                     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*
             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, cons
             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, cons
                 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, cons
                 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
                 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, con
                     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, con
                 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, con
                 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
                         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
                         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
                         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
                         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
                         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
                                 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
                             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
                                 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
                                 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
                                 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
                             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, c
                     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, c
                 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, co
                             ;
                         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,
             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,
             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* firs
                     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* firs
                     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, c
         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, co
         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, co
         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* fi
     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* firs
     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* firs
         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, cons
                     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, cons
                     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, cons
                     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, cons
                     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, cons
                     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, cons
                         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, cons
             {
             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, cons
                         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, cons
                     {
                         // 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
             {
                 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
                     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, co
                 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, co
                 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, co
                 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, co
                 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, co
                 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, co
                         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, co
                 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, co
                 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, co
                 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, co
     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
 {
     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
             {
                 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
                                     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
                             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
                         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, co
             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, cons
 {
     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,
     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,
     return buf;
 }
 
-}  // unnamed namespace
-
+}
 #endif
 
 





More information about the lldb-commits mailing list