[libclang] Getting unqualified version of Type

Is there a way to get "base" type of, well, Type. I see that it's
possible to test for const or volatile, but I don't see a way, to get
the underlying type.

What I am ultimately trying to do is to map member relationships
between classes, and currently the solution is missing some due to
type `A` being different from `const A`.

The only workaround I see is to check with
`clang_isConstQualifiedType` and parse spelling, which does not seem
like a good idea.

This is an example class layout that I have problem with:

class A {};

class B {
 A a;
}

class C {
  const A a;
  B* b;
}

It's hard to map C->A.

`B` is possitle to obtain through checking `CXType::kind` against
`CXType_Pointer` and `clang_getPointeeType`, so it's not a problem
that `B` and `B*` are different as there is a programatic way to get
it.

Is there a way to do it in current version of libclang? Or, would I
need to manually work with AST.

Regards,
Łukasz.

Is there a way to get "base" type of, well, Type. I see that it's
possible to test for const or volatile, but I don't see a way, to get
the underlying type.

It would be reasonable to add a clang_getUnqualifiedType. It looks like the existing
functions intentionally only consider "local" qualifiers, so you would need to decide
whether the function should remove only local qualifiers or whether it should strip
type sugar until it can return an unqualified type.

For example:
  typedef int int32_t;
  typedef volatile int32_t vint32_t;
  const vint32_t x;

Should clang_getUnqualifiedType on the type of 'x' return the typedef type 'vint32_t' or
the underlying unqualified type 'int32_t'? Note that in the latter case it is not necessary
to strip all the way down to 'int'.

John.

John,

Thanks for reply. I have found `QualType::getUnqualifiedType` when
digging through clang sources. I thought about exporting it, doesn't
seem like much of trouble, however so far I didn't find free personal
time, neither asked for company time to do it.

I presume it would look like e.g `clang_getPointeeType`, there is a
`libclag.exports` entry and a python binding, and that is seemingly
pretty much it.

Regarding the functional spec, to me it would make most sense to
follow original implementation, and be consistent with already
exported `is_const_qualified` and `is_volatile_qualified`, the just
wrap around respective `CXType.cpp` function which in turn are simple
wrappers around methods:

unsigned clang_isConstQualifiedType(CXType CT) {
QualType T = GetQualType(CT);
return T.isLocalConstQualified();
}

I imagine something similar could be done for
`QualType::getUnqualifiedType`. I don't think it looks only at local
specifiers as there are `Local` counterparts for those methods such as
`getLocalUnqualifiedType`, `isLocalVolatileQualified`, etc. Those are
not exported. IMO for the consistency it should be 1-1 export, and if
other functionality is needed then probably more appropriate methods
should be exported for external binding.

Best regards,
Łukasz.

John,

Thanks for reply. I have found `QualType::getUnqualifiedType` when
digging through clang sources. I thought about exporting it, doesn't
seem like much of trouble, however so far I didn't find free personal
time, neither asked for company time to do it.

I presume it would look like e.g `clang_getPointeeType`, there is a
`libclag.exports` entry and a python binding, and that is seemingly
pretty much it.

I'm not an expert in the C API, but yes, I think that's all that's required.

In general, Clang's C API is understood to be incomplete in a number of ways;
we often recommend that people write tools against the C++ API for that reason,
but of course that doesn't provide source or binary compatibility guarantees.

Regarding the functional spec, to me it would make most sense to
follow original implementation, and be consistent with already
exported `is_const_qualified` and `is_volatile_qualified`, the just
wrap around respective `CXType.cpp` function which in turn are simple
wrappers around methods:

unsigned clang_isConstQualifiedType(CXType CT) {
QualType T = GetQualType(CT);
return T.isLocalConstQualified();
}

I imagine something similar could be done for
`QualType::getUnqualifiedType`. I don't think it looks only at local
specifiers as there are `Local` counterparts for those methods such as
`getLocalUnqualifiedType`, `isLocalVolatileQualified`, etc. Those are
not exported. IMO for the consistency it should be 1-1 export, and if
other functionality is needed then probably more appropriate methods
should be exported for external binding.

There is a QualType::getLocalUnqualifiedType() method that just removes
these top-level qualifiers.

John.