spiritsaway
spiritsaway

Reputation: 645

libclang give wrong result for type qualifier

Currentlty I'm working on a project to dump class infomation for c++ code with libclang. And there comes some miserable experience with regards to type qualifiers: const, volatile, &, && and their combination. Here are the sample code to dump function delearation's parameters type.

auto _cur_cursor = one_node->get_cursor();
auto _cur_type = clang_getCursorType(_cur_cursor);
auto is_const = clang_isConstQualifiedType(_cur_type);
auto is_refer = clang_Type_getCXXRefQualifier(_cur_type);
auto is_volatile = clang_isVolatileQualifiedType(_cur_type);
auto is_pointer = clang_getPointeeType(_cur_type);
auto is_const_ref = false;
if (is_pointer.kind)
{
    is_const_ref = clang_isConstQualifiedType(is_pointer);
}
the_logger.info("get parameter name {} type {} is_const {} is_reference {} is volatile {} is_pointer {} is_const_ref {}", utils::to_string(clang_getCursorSpelling(_cur_cursor)), utils::to_string(clang_getTypeSpelling(_cur_type)), is_const, is_refer, is_volatile, utils::to_string(is_pointer), is_const_ref);

my test case is below

int test_1(const std::vector<std::unordered_map<int, int>>&  a,  std::vector<int>&& b, std::vector<std::uint32_t>& c)
{
    return b.size();
}

and the output for this func is

[2019-06-01 23:14:18.171] [meta] [info] get parameter name a type const std::vector<std::unordered_map<int, int> > & is_const 0 is_reference 0 is volatile 0 is_pointer const std::vector<std::unordered_map<int, int> > is_const_ref true
[2019-06-01 23:14:18.171] [meta] [info] get parameter name b type std::vector<int> && is_const 0 is_reference 0 is volatile 0 is_pointer std::vector<int> is_const_ref false
[2019-06-01 23:14:18.171] [meta] [info] get parameter name c type std::vector<std::uint32_t> & is_const 0 is_reference 0 is volatile 0 is_pointer std::vector<std::uint32_t> is_const_ref false

And here comes these observation, which are suspicious to me:

  1. clang_isConstQualifiedType return true just for const T, not for const T (&, *, &&)
  2. clang_Type_getCXXRefQualifier always false for any type
  3. clang_getPointeeType return T for T(,&, &&), return const T for const T(, &, &&)

These api seems not act as expected. Any ideas to get the right const reference volatile qualifier status for a CXType?

Upvotes: 2

Views: 493

Answers (1)

Valeriy Savchenko
Valeriy Savchenko

Reputation: 1614

  1. and 3. const T (&, *, &&) is indeed not a const qualified type, it's a (reference, pointer, r-value reference) to a const qualified type. const T * const would be a const qualified pointer to a const qualified type T. You can check cppreference for more details.

  2. From libclang's documentation:

Retrieve the ref-qualifier kind of a function or method.

The ref-qualifier is returned for C++ functions or methods. For other types or non-C++ declarations, CXRefQualifier_None is returned.

Probably, you're looking for something else. Check CXType::kind (_cur_type.kind in your snippet) for CXType_Pointer, CXType_LValueReference and CXType_RValueReference instead.

I hope that was useful. Happy hacking with clang!

Upvotes: 2

Related Questions