Hello all -
When using the clang_getCursor function, the caller is returned the most specific cursor at the location given. Is there a process by which I can get progressively less specific cursors? For instance, if given a position inside a function, I’d like to be able to get the cursor from that position, and then look at that cursor’s parents until I find the function declaration.
Currently, I always start at the top and work down, but under some circumstances, it would be very convenient to be able to work up instead.
Thanks for any ideas
Hi Nick
Have a look at clang_getCursorLexicalParent and
clang_getCursorSemanticParent.
By the way, ipython is an excellent way to explore this API. Here's how
I found the above:
$ export PYTHONPATH=/path/to/clang/bindings/python
$ ipython
::: import clang.cindex
::: index = clang.cindex.Index.create()
::: tu = index.parse('example.cpp')
::: cs = tu.cursor.get_children()
::: c = cs.next(); print c.spelling # Ignore the first few implicit typedefs
::: c = cs.next(); print c.spelling
::: c = cs.next(); print c.spelling
::: c = cs.next(); print c.spelling
::: cs = c.get_children()
::: c = cs.next()
::: c.<TAB>
c.canonical c.get_definition c.result_type
c.data c.get_usr c.semantic_parent
c.displayname c.hash c.spelling
c.enum_type c.is_definition c.translation_unit
c.enum_value c.is_static_method c.type
c.extent c.kind c.underlying_typedef_type
c.from_location c.lexical_parent c.xdata
c.from_result c.location
c.get_children c.objc_type_encoding
Then look in clang/bindings/python/clang/cindex.py to find the names
of the corresponding C functions.
Hope this helps!
--Dave.
Hello David -
Thanks for the information - especially regarding ipython. I hadn’t seen that before.
While clang_getCursorLexicalParent and clang_getCursorSemanticParent are helpful under some circumstances, what I’m looking for is a finer grain of control. What I would really like is essentially the opposite of clang_visitChildren. The project I’m working on requires me to be able to give various information about the thing that lies at a particular cursor location. For instance, consider the following code:
#include <stddef.h>
void foo() {
size_t a;
}
If I’m given the position (3, 5) and I ask for the cursor at that location, I’m given a TypeRef cursor for the size_t type. However, what I would really like is the VarDecl that scopes that TypeRef. In order to solve this problem generically, it seems I have to go all the way to global scope and then clang_visitChildren until I find the TypeRef, all while remembering where I was before.
If I were to get the FunctionDecl cursor and then visit its children, I would get the following tree:
FunctionDecl
CompoundStmt
DeclStmt
VarDecl
TypeRef
What I really want is to be able to walk up the tree, instead of only down.
Thanks -
I'm afraid I'm stumped. My suggestion of using
clang_getCursor{Lexical,Semantic}Parent won't work. With the example
code you gave, each cursor's parents are: (Lexical Parent, Semantic
Parent)
FunctionDecl [TranslationUnit, TranslationUnit]
CompoundStmt [None, FunctionDecl]
DeclStmt [None, None]
VarDecl [FunctionDecl, FunctionDecl]
TypeRef [None, None]
I don't really know the AST API, so I can't say whether the above parent
values are correct. My (naive) expectation was that the lexical parent
was always the cursor immediately preceding in that hierarchy, but maybe
there's a reason it isn't so.
Cheers,
Dave.
I’m afraid I’m stumped. My suggestion of using
clang_getCursor{Lexical,Semantic}Parent won’t work. With the example
code you gave, each cursor’s parents are: (Lexical Parent, Semantic
Parent)
FunctionDecl [TranslationUnit, TranslationUnit]
CompoundStmt [None, FunctionDecl]
DeclStmt [None, None]
VarDecl [FunctionDecl, FunctionDecl]
TypeRef [None, None]
I don’t really know the AST API, so I can’t say whether the above parent
values are correct or a bug. My (naive) expectation was that the lexical
parent was always the cursor immediately preceding in that hierarchy,
but maybe there’s a reason it isn’t so.
Cheers,
Dave.
I'm afraid I'm stumped. My suggestion of using
clang_getCursor{Lexical,Semantic}Parent won't work. With the example
code you gave, each cursor's parents are: (Lexical Parent, Semantic
Parent)
FunctionDecl [TranslationUnit, TranslationUnit]
CompoundStmt [None, FunctionDecl]
DeclStmt [None, None]
VarDecl [FunctionDecl, FunctionDecl]
TypeRef [None, None]
I don't really know the AST API, so I can't say whether the above parent
values are correct or a bug. My (naive) expectation was that the lexical
parent was always the cursor immediately preceding in that hierarchy,
but maybe there's a reason it isn't so.
Cheers,
Dave.