3
class aclass{
public:
    int num;
};

int main()
{
    aclass *ok;
    ok->num = 4;
    return 0;
}

now when I do clang_getCursorDefinition(cur_cursor); on the cursor right at the beginning of the o at ok->num = 4; it gives the cursor for int num; inside aclass. I want it to give me the cursor for the aclass *ok; declaration inside main. Calling clang_getCursorSemanticParent(cur_cursor) seems wrong as if I put the declaration inside or outside the main() func it still returns main() as the semantic parent.

Is there a way to efficiently do this, without iterating every single possible cursor?

EDIT: Clang counts tabs as 1 character which is correct. The editor I was testing with was automatically counting tabs as size 4, so what clang expected as column 2, my editor was sending as column 5. Now the getCursorDefinition is working as expected, and is taking me to the scoped definition.

Vans S
  • 1,743
  • 3
  • 21
  • 36

1 Answers1

2

when I do clang_getCursorDefinition(cur_cursor); on the cursor right at the beginning of the o at ok->num = 4;

Maybe you are surprised by your code behaviour because of the (common) misconception that there is only one cursor at each source location.

There are actually many cursors at this position, one of them pointing to the whole expression, another to the member reference ok->num, and yet another to the pointer ok. (see for example this question for more detailed explanations about this: C++ libclang: Retrieving cursor from CXSourceLocation returning wrong cursor?)

You should probably try to find the correct cursor, among all which are located at the same place. The way to do it depends on how you initially got your cursor.

Community
  • 1
  • 1
François Févotte
  • 19,520
  • 4
  • 51
  • 74
  • Yes. This must be it, looking into this. Another question. Is there a way to get the CXCursor_MemberRefExpr kind of cursor when setting the line:column to anywhere between n u m? The reason is if I set the cursor say between o k I want to go to the declaration of the class in the scope. If i set the cursor between n u I want to go to the declaration member inside the actual class. – Vans S Dec 29 '14 at 15:46
  • To be brief, I think a good heuristic to get your behaviour would be to select the CXCursor having the smallest extent, while still enclosing the location you are interested in. This is what I implemented into [clang-tags](https://github.com/ffevotte/clang-tags), and it seems to work well enough. – François Févotte Dec 29 '14 at 16:18
  • I believe your second question is general enough that it could potentially interest others... Maybe you should consider making it a proper full-fledged question on SO. – François Févotte Dec 29 '14 at 16:19
  • That is a good idea but still stuck on the first problem. The closest thing I can find in the API is clang_getCursorExtent, which gives me a CXSourceRange. Now I can get the clang_getRangeStart and clang_getRangeEnd which seem useless to me. As it will return cursors at different locations. I need to cycle through the cursors at the current location. Which API call do I need for that? – Vans S Dec 30 '14 at 01:45
  • OK I think I need to tokenize the CXSourceRange via http://stackoverflow.com/questions/10692015/libclang-get-primitive-value this. Will update the question later if it works. – Vans S Dec 30 '14 at 02:25
  • How did you get your cursor in the first place? Did you traverse the whole AST, or call [clang_getCursor()](http://clang.llvm.org/doxygen/group__CINDEX__CURSOR__SOURCE.html#ga30a9972c7e099ab2735fa6c45e247ec8)? – François Févotte Dec 30 '14 at 07:30
  • CXFile test_file = clang_getFile(tu, src_fname); CXSourceLocation cxsl = clang_getLocation(tu, test_file, 32, 5); CXCursor cur_cursor = clang_getCursor(tu, cxsl); CXSourceRange range = clang_getCursorExtent(cur_cursor); ... now tokenize and annotate (is there a better way to do this all / skip right to annotate?) – Vans S Dec 30 '14 at 15:51
  • Im baffled as to why its so difficult to get whats exactly under the cursor. Im writing like 50+ lines of code using an already abstracted API just to get the same cursor when its at beginning of ok vs in the middle. – Vans S Dec 30 '14 at 16:48
  • Normally, `clang_getCursor` should already give you the most specific cursor at the given source location. – François Févotte Dec 30 '14 at 21:56