If you have an explicit (full) template specialization, Clang preserves the exact spelling of the template arguments you used, and then uses them when you ask for a canonical type name.
Here's an example code:
namespace NS
{
template <typename T> struct A {};
struct B {};
using C = B;
template <> struct A<C> {};
}
NS::A<NS::B> foo();
When printing the return type of foo using clang_getTypeSpelling(clang_getCanonicalType(clang_getCursorType(cursor))), I get NS::A<C>. (The part <C> is spelled exactly as in the specialization. If I specialize using <B> instead, I get that. Same for any qualifiers, etc.)
This is annoying, because I'm trying to use canonical names to generate some code, and I expect them to be fully qualified (maybe they aren't the right tool for the job, but I didn't find anything else in the C API).
If you have an explicit (full) template specialization, Clang preserves the exact spelling of the template arguments you used, and then uses them when you ask for a canonical type name.
Here's an example code:
When printing the return type of
foo
usingclang_getTypeSpelling(clang_getCanonicalType(clang_getCursorType(cursor)))
, I getNS::A<C>
. (The part<C>
is spelled exactly as in the specialization. If I specialize using<B>
instead, I get that. Same for any qualifiers, etc.)This is annoying, because I'm trying to use canonical names to generate some code, and I expect them to be fully qualified (maybe they aren't the right tool for the job, but I didn't find anything else in the C API).
This might've been introduced in LLVM 16 along with similar changes to
__PRETTY_FUNCTION__
.Here's a small snippet using libclang that can be used to test this: