Author: hhinnant
Date: Sun Jun 23 14:52:45 2013
New Revision: 184672

URL: http://llvm.org/viewvc/llvm-project?rev=184672&view=rev
Log:
I'd no sooner made the last commit when Matthew Dempsky sent me another test 
case that led me to yet another closely related test case that the current 
design could not handle.  I've now changed the way forward references are 
handled completely.  It wasn't that much code to change.  The demangler, when 
confronted with a forward reference to a template parameter, now parses things 
twice.  During the second parse, all forward references are remembered from the 
first parse.  Test suite updated with new case.

Modified:
    libcxxabi/trunk/src/cxa_demangle.cpp
    libcxxabi/trunk/test/test_demangle.cpp

Modified: libcxxabi/trunk/src/cxa_demangle.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp?rev=184672&r1=184671&r2=184672&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_demangle.cpp (original)
+++ libcxxabi/trunk/src/cxa_demangle.cpp Sun Jun 23 14:52:45 2013
@@ -547,7 +547,7 @@ parse_template_param(const char* first,
                 }
                 else
                 {
-                    db.names.push_back("`T_");
+                    db.names.push_back("T_");
                     first += 2;
                     db.fix_forward_references = true;
                 }
@@ -572,7 +572,7 @@ parse_template_param(const char* first,
                 }
                 else
                 {
-                    db.names.push_back("`" + typename C::String(first, t+1));
+                    db.names.push_back(typename C::String(first, t+1));
                     first = t+1;
                     db.fix_forward_references = true;
                 }
@@ -4425,51 +4425,6 @@ demangle(const char* first, const char*
     }
     if (status == success && db.names.empty())
         status = invalid_mangled_name;
-    if (status == success && db.fix_forward_references)
-    {
-        auto nm = db.names.back().move_full();
-        db.names.pop_back();
-        size_t p = nm.size();
-        while (p != 0)
-        {
-            if (nm[--p] == '`')
-            {
-                size_t k0 = db.names.size();
-                const char* t = parse_template_param(&nm[p+1], &nm[nm.size()], 
db);
-                size_t k1 = db.names.size();
-                if (t == &nm[p+1])
-                {
-                    status = invalid_mangled_name;
-                    return;
-                }
-                if (k1 == k0)
-                {
-                    nm.erase(p, static_cast<std::size_t>(t - &nm[p]));
-                }
-                else
-                {
-                    if (db.names[k0].first.front() == '`')
-                    {
-                        status = invalid_mangled_name;
-                        return;
-                    }
-                    size_t p2 = static_cast<size_t>(t - &nm[p]);
-                    size_t s = db.names[k0].size();
-                    nm.replace(p, p2, db.names[k0].move_full());
-                    p2 = p + s;
-                    for (size_t k = k0+1; k < k1; ++k)
-                    {
-                        s = db.names[k].size() + 2;
-                        nm.insert(p2, ", " + db.names[k].move_full());
-                        p2 += s;
-                    }
-                    for (; k1 > k0; --k1)
-                        db.names.pop_back();
-                }
-            }
-        }
-        db.names.push_back(std::move(nm));
-    }
 }
 
 template <std::size_t N>
@@ -4682,8 +4637,20 @@ __cxa_demangle(const char* mangled_name,
     db.fix_forward_references = false;
     db.try_to_parse_template_args = true;
     int internal_status = success;
-    demangle(mangled_name, mangled_name + std::strlen(mangled_name), db,
+    size_t len = std::strlen(mangled_name);
+    demangle(mangled_name, mangled_name + len, db,
              internal_status);
+    if (internal_status == success && db.fix_forward_references &&
+           !db.template_param.empty() && !db.template_param.front().empty())
+    {
+        db.fix_forward_references = false;
+        db.tag_templates = false;
+        db.names.clear();
+        db.subs.clear();
+        demangle(mangled_name, mangled_name + len, db, internal_status);
+        if (db.fix_forward_references)
+            internal_status = invalid_mangled_name;
+    }
     if (internal_status == success)
     {
         size_t sz = db.names.back().size() + 1;

Modified: libcxxabi/trunk/test/test_demangle.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_demangle.cpp?rev=184672&r1=184671&r2=184672&view=diff
==============================================================================
--- libcxxabi/trunk/test/test_demangle.cpp (original)
+++ libcxxabi/trunk/test/test_demangle.cpp Sun Jun 23 14:52:45 2013
@@ -29582,6 +29582,7 @@ const char* cases[][2] =
     {"_Z1rM1GFivEMS_KFivES_M1HFivES1_4whatIKS_E5what2IS8_ES3_", "r(int 
(G::*)(), int (G::*)() const, G, int (H::*)(), int (G::*)(), what<G const>, 
what2<G const>, int (G::*)() const)"},
     {"_Z1fPU11objcproto1A11objc_object", "f(id<A>)"},
     {"_Z1fPKU11objcproto1A7NSArray", "f(NSArray<A> const*)"},
+    {"_ZNK1AIJ1Z1Y1XEEcv1BIJDpPT_EEIJS2_S1_S0_EEEv", "A<Z, Y, X>::operator 
B<X*, Y*, Z*><X, Y, Z>() const"},
 };
 
 const unsigned N = sizeof(cases) / sizeof(cases[0]);
@@ -29592,7 +29593,6 @@ const char* invalid_cases[] =
     "Agentt",
     "NSoERj5E=Y1[uM:ga",
     
"Aon_PmKVPDk7?fg4XP5smMUL6;<WsI_mgbf23cCgsHbT<l8EE\0uVRkNOoXDrgdA4[8IU>Vl<>IL8ayHpiVDDDXTY;^o9;i",
-    "_ZN8Blizza`d6Memory12voidp_returncvPT_IcEEv",
     
"_ZNSt16allocator_traitsISaIN4llvm3sys2fs18directory_iteratorEEE9constructIS3_IS3_EEEDTcl12_S_constructfp_fp0_spcl7forwardIT0_Efp1_EEERS4_PT_DpOS7_",
 };
 


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to