Reputation: 675
Consider an object t
of type clang.cindex.Type
representing a C++ variable declaration such as const T& x;
or a parameter declaration occurring in something like
template<typename... Ts> void f(Ts&&...);
Is there a canonical way to determine if t
is/represents (1) a pointer, (2) a lvalue or rvalue reference, (3) a parameter pack?
Obviously, by manually parsing t.spelling
, one can solve the above problems, roughly as follows: Assume that the file x.h
contains
const T & x;
Then the following code will print True
:
import clang
from clang import cindex
def is_lvalue_ref(type):
spell = type.spelling # 'const T &'
tokens = spell.split(' ') # ['const', 'T', '&']
return (tokens[-1] == '&')
cindex.Config.set_library_path('/Library/Developer/CommandLineTools/usr/lib')
index = cindex.Index.create()
tu = index.parse('x.h', ['c++', '-std=c++17'])
for x in tu.cursor.get_children():
# x is CursorKind.VAR_DECL
print(is_lvalue_ref(x.type))
(For pointers or parameter packs, proceed similarly.) But clearly, this is undesirable! Is there a canonical way to achieve this?
Upvotes: 2
Views: 1337
Reputation: 21
I think i'm super late right now, but i had the same problem and solved in a canonical way.
Whenever you have a PARM_DECL
you can understand if some qualifier is applied in this way:
node.type.get_pointee().is_const_qualified()
It returns True if the parameter declaration has the const
qualifier, like:
const string &
EDIT:
I have finally found the solution: once you have a typekind
object you just access the attribute kind
and if it is a reference its kind will be TypeKind.LVALUEREFERENCE.
node.type.kind
If you want to access the underlying type of the reference you need to get it through get_pointee(), so
node.type.get_pointee().spelling
Upvotes: 2