Find Type by name

Hello,

Is it possible to find type in AST by it’s qualified type?

For example I have string “my_nm::my_type<int, 10u>”, how can I get clang::QualType if type is present in translation unit?

Thanks,
Roman

I don't think it's possible via straightforward lookup - you might need to scan the AST to do this.

Eg. using ASTMatchers:

 qualType\(asString\(&quot;my\_nm::my\_type&lt;int, 10u&gt;&quot;\)\)

Or, if you're not using ASTMatchers (likely), you can do the same with a RecursiveASTVisitor. Or manually.

Thanks Artem. This is what I’ve tried before writing original mail. However it does not work, I got zero matches.

Here is reproducer:

namespace my_nm {
template<typename T, unsigned U>
struct my_type { };
}

my_nm::my_type<int, 10> m;

I got types from LLVM IR analysis, and then want to find them in Clang AST.

From LLVM I got mangled name:
N5my_nm7my_typeIiLj10EEE

Demangled to:

my_nm::my_type<int, 10u>

However I can’t find it by any matcher:

auto matches = match(qualType(asString(“my_nm::my_type<int, 10u>”)).bind(“types”), astCtx); // Zero matches

auto matches = match(qualType(asString(“N5my_nm7my_typeIiLj10EEE”)).bind(“types”), astCtx); // Zero matches

Probably there is some other way to go back from LLVM IR to Clang AST?

Thanks,
Roman

Sorry i don't have a quick way of trying this at the moment; Does it work with "struct my_nm::my_type<int, 10>"? - because that's what i see in clang's -ast-dump. Does varDecl(hasType(asString(...))) work? If you match qualType() and dump .getAsString() on all results, what do you see?

Cause i think it should ultimately work.

Huh, nice one. It means that the problem is somewhere in QualType::getQualifiedNameAsString(). No, it doesn't seem to be fixed in trunk. This might be an easy and welcomed patch.

Ok, let me run the code in debugger to understand how it makes decision when to print U.

Well, from what I’m seeing non-type argument printer is actually untyped.
It uses APInt, which looks like “generic” arbitrary precision integer, that knows nothing about C++ type system.

So solution is to print APInt value without type postfix, and then generate type postfix based on template parameter type.

I’m not really familiar with Clang yet, so it will take a time to fix this. But I will try.

Another option would be using mangled type names in AST Matcher. This way it will be even better: you wan’t need to demangle names from LLVM IR.

Ok, simply adding suffixes based on BuiltinType Kind solves the problem for me. I will update to Clang trunk tomorrow and check if it will work there.

Well, it turned out there are more problems in this direction.

Consider this code sample:

template < auto &ref , auto *ptr, auto v>
struct foo {};
static int x;
foo <x, &x, nullptr> f;

Standard demangler from <cxxabi.h> demangles f type like this:

foo<x, &x, (decltype(nullptr))0>

But clang Type printer used by ASTMatcher prints it like this:

struct foo<&x, &x, nullptr> &&

-Roman

So what should be a proper solution to this problem? :

  1. Make type printer output to be equivalent to <cxxabi.h> demangler?
  2. Implement AST Matcher for mangled names?
    Or there is some other way I’m missing?

Thanks,
Roman