[libclang] Getting unqualified version of Type

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[libclang] Getting unqualified version of Type

Anastasia Stulova via cfe-dev
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.
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [libclang] Getting unqualified version of Type

Anastasia Stulova via cfe-dev
> On Feb 12, 2018, at 8:05 AM, Łukasz Kucharski via cfe-dev <[hidden email]> wrote:
> 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.

>
> 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.
> _______________________________________________
> cfe-dev mailing list
> [hidden email]
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [libclang] Getting unqualified version of Type

Anastasia Stulova via cfe-dev
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.

On Thu, Feb 22, 2018 at 6:00 AM, John McCall <[hidden email]> wrote:

>> On Feb 12, 2018, at 8:05 AM, Łukasz Kucharski via cfe-dev <[hidden email]> wrote:
>> 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.
>
>>
>> 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.
>> _______________________________________________
>> cfe-dev mailing list
>> [hidden email]
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [libclang] Getting unqualified version of Type

Anastasia Stulova via cfe-dev
> On Feb 22, 2018, at 10:42 AM, Łukasz Kucharski <[hidden email]> wrote:
>
> 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.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev