Description
Current Behavior
// C++ source
namespace chimera_test { namespace common {
constexpr int Dynamic = -1;
} }
namespace chimera_test { namespace math {
template <int Dimension>
class Vector {
public:
Vector() = default;
};
using VectorX = Vector<common::Dynamic>;
} }
// Binding code
void _ZN12chimera_test4math6VectorILin1EEE(::pybind11::module& m) {
auto sm = m.def_submodule("math");
auto attr = sm;
::pybind11::class_<chimera_test::math::Vector<common::Dynamic> >(attr, "VectorX") // 'common::Dynamic' is expected to be 'chimera_test::common::Dynamic'
.def(::pybind11::init<>());
}
The template argument of Vector
, Dynamic
, is not fully qualified.
- Expected:
chimera_test::math::Vector<chimera_test::common::Dynamic>
orchimera_test::math::Vector<-1>
(after evaluated) - Actual:
chimera_test::math::Vector<common::Dynamic>
Reasoning
Type template arguments are converted to fully qualified type name here:
chimera/external/cling/src/cling_utils_AST.cpp
Lines 261 to 300 in a9b6132
However, non-type template arguments not handled by this function, as documented in the code (line: 266-268).
Simple Workaround
For this particular case, we can work around by putting using namespace chimera_test;
to the configuration YAML in the template section accordingly. But I'm not sure if this could be problematic in other situations.
Possible Approaches
Overwriting Type of Expression
We could print the expression by:
Expr* expr = arg.getAsExpr();
llvm::SmallString<256> Buf;
llvm::raw_svector_ostream StrOS(Buf);
PrintingPolicy Policy(Ctx.getPrintingPolicy());
Policy.SuppressScope = false;
Policy.AnonymousTagLocations = false;
expr->printPretty(StrOS, nullptr, Policy);
std::string str = StrOS.str(); // common::Dynamic
Once we get the expression in string, we might be able to get the fully qualified type by using chimera::util::resolveType()
and cling::utils::GetFullyQualifiedType()
. Then we could overwrite the type by expr->setType(fully_qualified_type)
.
This approach requires to change the code dependencies so that we can call chimera::util::resolveType()
in cling_utils_AST.cpp
. I haven't tested this approach yet for this limitation.
Overwriting Output of Fully-Qualified Type Name
This would be a more hacky version than the previous one. We could modify cling::utils::GetFullyQualifiedType()
to return which template arguments are still needed to be fully-qualified, and update them afterward. This is because we don't have control over clang::QualType::getAsString()
.