From 71c1f42d85ee1819741786255dc8876047398e8e Mon Sep 17 00:00:00 2001 From: Paul Zander Date: Sun, 12 Jan 2025 19:22:48 +0100 Subject: [PATCH] properly demangle typenames C++ class names are mangled. How these are mangled is implementation specific. Using string offsets is naive and caused at minimum testfailures. For gcc and clang you can use cxxabi.h to get demangled name. This initial patch uses this for linux only, so the gentoo build suceeeds. Signed-off-by: Paul Zander diff --git a/OndselSolver/ASMTItem.cpp b/OndselSolver/ASMTItem.cpp index a18e7c9..9d5383a 100644 --- a/OndselSolver/ASMTItem.cpp +++ b/OndselSolver/ASMTItem.cpp @@ -12,6 +12,7 @@ #include "ASMTAssembly.h" #include "Constant.h" #include +#include "Demangle.h" using namespace MbD; @@ -41,9 +42,7 @@ void MbD::ASMTItem::noop() std::string MbD::ASMTItem::classname() { - std::string str = typeid(*this).name(); - auto answer = str.substr(11, str.size() - 11); - return answer; + return demangle(typeid(*this).name()); } void MbD::ASMTItem::setName(const std::string& str) diff --git a/OndselSolver/ASMTJoint.cpp b/OndselSolver/ASMTJoint.cpp index 40edd52..bb710e3 100644 --- a/OndselSolver/ASMTJoint.cpp +++ b/OndselSolver/ASMTJoint.cpp @@ -9,6 +9,7 @@ #include "ASMTJoint.h" #include "Joint.h" +#include "Demangle.h" using namespace MbD; @@ -47,9 +48,7 @@ void MbD::ASMTJoint::storeOnLevel(std::ofstream& os, size_t level) void MbD::ASMTJoint::storeOnTimeSeries(std::ofstream& os) { - std::string label = typeid(*this).name(); - label = label.substr(15, label.size() - 15); - os << label << "Series\t" << fullName("") << std::endl; + os << demangle(typeid(*this).name()) << "Series\t" << fullName("") << std::endl; ASMTItemIJ::storeOnTimeSeries(os); } diff --git a/OndselSolver/AccNewtonRaphson.cpp b/OndselSolver/AccNewtonRaphson.cpp index 588d0fe..abc9ce5 100644 --- a/OndselSolver/AccNewtonRaphson.cpp +++ b/OndselSolver/AccNewtonRaphson.cpp @@ -126,12 +126,12 @@ void AccNewtonRaphson::preRun() void MbD::AccNewtonRaphson::handleSingularMatrix() { auto& r = *matrixSolver; - std::string str = typeid(r).name(); + std::string str = demangle(typeid(r).name()); if (str.find("GESpMatParPvMarkoFast") != std::string::npos) { matrixSolver = CREATE::With(); this->solveEquations(); } else { - str = typeid(r).name(); + str = demangle(typeid(r).name()); if (str.find("GESpMatParPvPrecise") != std::string::npos) { this->logSingularMatrixMessage(); matrixSolver->throwSingularMatrixError("AccAccNewtonRaphson"); diff --git a/OndselSolver/Array.h b/OndselSolver/Array.h index 636e9a5..e270795 100644 --- a/OndselSolver/Array.h +++ b/OndselSolver/Array.h @@ -16,6 +16,7 @@ #include "Numeric.h" #include +#include "Demangle.h" //#include "Symbolic.h" namespace MbD { @@ -51,10 +52,7 @@ namespace MbD { void atitimes(size_t i, double factor); virtual std::ostream& printOn(std::ostream& s) const { - std::string str = typeid(*this).name(); - auto classname = str.substr(11, str.size() - 11); - s << classname << std::endl; - return s; + return s << demangle(typeid(*this).name()) << std::endl; } friend std::ostream& operator<<(std::ostream& s, const Array& array) { diff --git a/OndselSolver/CREATE.h b/OndselSolver/CREATE.h index 0c6fc96..7c94b82 100644 --- a/OndselSolver/CREATE.h +++ b/OndselSolver/CREATE.h @@ -70,7 +70,7 @@ namespace MbD { } static std::shared_ptr ConstraintWith(std::shared_ptr frmi, std::shared_ptr frmj, size_t axis) { std::shared_ptr inst; - std::string str = typeid(T).name(); + std::string str = demangle(typeid(T).name()); if (str.find("AtPointConstraintIqcJqc") != std::string::npos) { if (std::dynamic_pointer_cast(frmi)) { inst = std::make_shared(frmi, frmj, axis); @@ -97,7 +97,7 @@ namespace MbD { } static std::shared_ptr ConstraintWith(std::shared_ptr frmi, std::shared_ptr frmj, size_t axisi, size_t axisj) { std::shared_ptr inst; - std::string str = typeid(T).name(); + std::string str = demangle(typeid(T).name()); if (str.find("DirectionCosineConstraintIqcJqc") != std::string::npos) { if (std::dynamic_pointer_cast(frmi)) { inst = std::make_shared(frmi, frmj, axisi, axisj); diff --git a/OndselSolver/Demangle.h b/OndselSolver/Demangle.h new file mode 100644 index 0000000..810936d --- /dev/null +++ b/OndselSolver/Demangle.h @@ -0,0 +1,39 @@ +#ifndef DEMANGLE_H +#define DEMANGLE_H 1 +#include + +#ifdef _WIN32 +#include +namespace { +std::string demangle(const char* mangled_name) noexcept { + return mangled_name; +} +} +#else // __linux__ +#include +namespace { +std::string demangle(const char* mangled_name) noexcept { + int error = 0; + char *demang_name = abi::__cxa_demangle(mangled_name, 0, 0, &error); + + switch (error) { + case 0: + break; + case -1: + return "memory allocation failed"; + case -2: + return "not a valid mangled name"; + case -3: + return "invalid arguments"; + default: + return "__cxa_demangle failed"; + } + + std::string name(demang_name); + free(demang_name); + + return name.substr(name.find_last_of("::") + 1); +} +} +#endif // __linux__ +#endif diff --git a/OndselSolver/Item.cpp b/OndselSolver/Item.cpp index 4435d5d..120cd3c 100644 --- a/OndselSolver/Item.cpp +++ b/OndselSolver/Item.cpp @@ -15,6 +15,7 @@ #include "Item.h" #include "System.h" #include "Symbolic.h" +#include "Demangle.h" using namespace MbD; @@ -44,10 +45,7 @@ void Item::initialize() std::ostream& Item::printOn(std::ostream& s) const { - std::string str = typeid(*this).name(); - auto classname = str.substr(11, str.size() - 11); - s << classname << std::endl; - return s; + return s << demangle(typeid(*this).name()) << std::endl; } void Item::initializeLocally() diff --git a/OndselSolver/PartFrame.cpp b/OndselSolver/PartFrame.cpp index 5219bb8..b395458 100644 --- a/OndselSolver/PartFrame.cpp +++ b/OndselSolver/PartFrame.cpp @@ -187,7 +187,7 @@ void PartFrame::constraintsReport() std::string str = "MbD: " + part->classname() + std::string(" ") + part->name + " has the following constraint(s) removed: "; this->logString(str); std::for_each(redunCons->begin(), redunCons->end(), [&](auto& con) { - str = "MbD: " + std::string(" ") + std::string(typeid(*con).name()); + str = "MbD: " + std::string(" ") + std::string(demangle(typeid(*con).name())); this->logString(str); }); } diff --git a/OndselSolver/PosICNewtonRaphson.cpp b/OndselSolver/PosICNewtonRaphson.cpp index b581e82..87285eb 100644 --- a/OndselSolver/PosICNewtonRaphson.cpp +++ b/OndselSolver/PosICNewtonRaphson.cpp @@ -17,6 +17,7 @@ #include "CREATE.h" #include "GESpMatParPvPrecise.h" #include "GESpMatFullPvPosIC.h" +#include "Demangle.h" using namespace MbD; @@ -108,14 +109,14 @@ void PosICNewtonRaphson::handleSingularMatrix() } else { auto& r = *matrixSolver; - std::string str = typeid(r).name(); + std::string str = demangle(typeid(r).name()); if (str.find("GESpMatParPvMarkoFast") != std::string::npos) { matrixSolver = CREATE::With(); this->solveEquations(); } else { auto& msRef = *matrixSolver.get(); // extrapolated to suppress warning - str = typeid(msRef).name(); + str = demangle(typeid(msRef).name()); (void) msRef; // also for warning suppression if (str.find("GESpMatParPvPrecise") != std::string::npos) { this->lookForRedundantConstraints(); diff --git a/OndselSolver/Symbolic.cpp b/OndselSolver/Symbolic.cpp index 75bcbb6..4961964 100644 --- a/OndselSolver/Symbolic.cpp +++ b/OndselSolver/Symbolic.cpp @@ -15,6 +15,7 @@ #include "Product.h" #include "Sum.h" #include "Power.h" +#include "Demangle.h" using namespace MbD; @@ -160,10 +161,7 @@ bool Symbolic::isConstant() std::ostream& Symbolic::printOn(std::ostream& s) const { - std::string str = typeid(*this).name(); - auto classname = str.substr(11, str.size() - 11); - s << classname; - return s; + return s << demangle(typeid(*this).name()); } std::shared_ptr> Symbolic::getTerms() diff --git a/OndselSolver/SystemNewtonRaphson.cpp b/OndselSolver/SystemNewtonRaphson.cpp index 1a32f85..c2e5fc5 100644 --- a/OndselSolver/SystemNewtonRaphson.cpp +++ b/OndselSolver/SystemNewtonRaphson.cpp @@ -66,13 +66,13 @@ void SystemNewtonRaphson::basicSolveEquations() void SystemNewtonRaphson::handleSingularMatrix() { auto& r = *matrixSolver; - std::string str = typeid(r).name(); + std::string str = demangle(typeid(r).name()); if (str.find("GESpMatParPvMarkoFast") != std::string::npos) { matrixSolver = CREATE::With(); this->solveEquations(); } else { - str = typeid(r).name(); + str = demangle(typeid(r).name()); if (str.find("GESpMatParPvPrecise") != std::string::npos) { str = "MbD: Singular Matrix Error. "; system->logString(str); diff --git a/OndselSolver/VelSolver.cpp b/OndselSolver/VelSolver.cpp index b62cb70..a6a03da 100644 --- a/OndselSolver/VelSolver.cpp +++ b/OndselSolver/VelSolver.cpp @@ -25,13 +25,13 @@ void VelSolver::basicSolveEquations() void VelSolver::handleSingularMatrix() { auto& r = *matrixSolver; - std::string str = typeid(r).name(); + std::string str = demangle(typeid(r).name()); if (str.find("GESpMatParPvMarkoFast") != std::string::npos) { matrixSolver = CREATE::With(); this->solveEquations(); } else { - str = typeid(r).name(); + str = demangle(typeid(r).name()); if (str.find("GESpMatParPvPrecise") != std::string::npos) { this->logSingularMatrixMessage(); matrixSolver->throwSingularMatrixError("VelSolver"); diff --git a/OndselSolver/CMakeLists.txt b/OndselSolver/CMakeLists.txt index 6836e72..30d5bf4 100644 --- a/OndselSolver/CMakeLists.txt +++ b/OndselSolver/CMakeLists.txt @@ -426,6 +426,7 @@ set(ONDSELSOLVER_HEADERS CREATE.h CylindricalJoint.h CylSphJoint.h + Demangle.h DiagonalMatrix.h DifferenceOperator.h DifferentiatedGeneralSpline.h -- 2.48.0