Print demangled callback signatures if they mismatch. bug #507
authorTimo Bingmann <timo.bingmann@student.kit.edu>
Sun, 22 Feb 2009 17:28:45 +0100
changeset 4205 751691462d36
parent 4204 1b2a20c85856
child 4206 279c3dbe7572
Print demangled callback signatures if they mismatch. bug #507
src/core/callback.cc
src/core/callback.h
--- a/src/core/callback.cc	Sat Feb 21 23:19:18 2009 +0000
+++ b/src/core/callback.cc	Sun Feb 22 17:28:45 2009 +0100
@@ -35,4 +35,54 @@
 
 ATTRIBUTE_CHECKER_IMPLEMENT (Callback);
 
+#if (__GNUC__ >= 3)
+
+#include <cxxabi.h>
+#include "log.h"
+
+std::string
+CallbackBase::Demangle(const std::string& mangled)
+{
+    int status;
+    char* demangled = abi::__cxa_demangle(mangled.c_str(),
+                                          NULL, NULL, &status);
+
+    std::string ret;
+    if (status == 0) {
+        NS_ASSERT(demangled);
+        ret = demangled;
+    }
+    else if (status == -1) {
+        NS_LOG_UNCOND("Callback demangling failed: Memory allocation failure occured.");
+        ret = mangled;
+    }
+    else if (status == -2) {
+        NS_LOG_UNCOND("Callback demangling failed: Mangled name is not a valid under the C++ ABI mangling rules.");
+        ret = mangled;
+    }
+    else if (status == -3) {
+        NS_LOG_UNCOND("Callback demangling failed: One of the arguments is invalid.");
+        ret = mangled;
+    }
+    else {
+        NS_LOG_UNCOND("Callback demangling failed: status " << status);
+        ret = mangled;
+    }
+
+    if (demangled) {
+        free(demangled);
+    }
+    return ret;
+}
+
+#else
+
+std::string
+CallbackBase::Demangle(const std::string& mangled)
+{
+    return mangled;
+}
+
+#endif
+
 } // namespace ns3
--- a/src/core/callback.h	Sat Feb 21 23:19:18 2009 +0000
+++ b/src/core/callback.h	Sun Feb 22 17:28:45 2009 +0100
@@ -340,6 +340,8 @@
 protected:
   CallbackBase (Ptr<CallbackImplBase> impl) : m_impl (impl) {}
   Ptr<CallbackImplBase> m_impl;
+
+  static std::string Demangle(const std::string& mangled);
 };
 
 /**
@@ -476,9 +478,9 @@
   void DoAssign (Ptr<const CallbackImplBase> other) {
     if (!DoCheckType (other))
       {
-        NS_FATAL_ERROR ("Incompatible types. (feed to \"c++filt -t\")"
-                        " got=" << typeid (*other).name () << 
-                        ", expected=" << typeid (CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> *).name ());
+        NS_FATAL_ERROR ("Incompatible types. (feed to \"c++filt -t\" if needed)" << std::endl <<
+                        "got=" << Demangle ( typeid (*other).name () ) << std::endl <<
+                        "expected=" << Demangle ( typeid (CallbackImpl<R,T1,T2,T3,T4,T5,T6,T7,T8,T9> *).name () ));
       }
     m_impl = const_cast<CallbackImplBase *> (PeekPointer (other));
   }