Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libclang] Type names are getting incorrectly canonicalized in template arguments of full specializations #92371

Open
HolyBlackCat opened this issue May 16, 2024 · 0 comments
Labels
clang:as-a-library libclang and C++ API

Comments

@HolyBlackCat
Copy link

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).

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:

#include <clang-c/Index.h>
#include <stdio.h>

static enum CXChildVisitResult visitor(CXCursor cursor, CXCursor parent, CXClientData client_data)
{
    (void)parent;
    (void)client_data;

    CXString str = clang_getTypeSpelling(clang_getCursorType(cursor));
    printf("%s\n", clang_getCString(str));
    clang_disposeString(str);

    return CXChildVisit_Recurse;
}

int main(int argc, char **argv)
{
    CXIndex idx = clang_createIndex(0, 1);
    CXTranslationUnit tu = clang_parseTranslationUnit(idx, 0, (const char **)argv, argc, 0, 0, 0);
    if (!tu)
        return 1;

    clang_visitChildren(clang_getTranslationUnitCursor(tu), visitor, 0);

    clang_disposeTranslationUnit(tu);
    clang_disposeIndex(idx);
}
@EugeneZelenko EugeneZelenko added clang:as-a-library libclang and C++ API and removed new issue labels May 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:as-a-library libclang and C++ API
Projects
None yet
Development

No branches or pull requests

2 participants