David Abdurachmanov
2014-May-23  08:23 UTC
[LLVMdev] clang_getCursorDefinition(C) == C fails in clang_isCursorDefinition (libClang) on aarch64, but works fine on x86_64
Hi,
I found that Python script using libClang fails in our project on aarch64
architecture.
Below you can find debug session fragment [GDB_FRAGMENT].
Below there is a small example. I found that libClang mostly will return False
for clang_isCursorDefinition (is_definition() in Python) on aarch64 and Python
script we have relies on is_definition() call.
At first look seems that data[1] of struct CXCursor is ID of SourceLocation,
which are different on aarch64, but points to the same file, line, and column.
As a quick hack I now use "node.location ==
node.get_definition().location", which yields the same results as on
x86_64. This compares two CXSourceLocation structs.
I also created a ticket for that http://llvm.org/bugs/show_bug.cgi?id=19759
I tested it a few days ago on trunk version.
david
$ cat my.h
struct timespec
{
  int tv_sec;
  int tv_nsec;
};
$ cat check.py
import sys
import clang.cindex
def find_all(node):
    for child in node.get_children():
      print("displayname: {0}, kind: {1}, is_definition: {2}, 
location:{3}".format(child.displayname, child.kind, child.is_definition(),
child.location))
      if child.get_definition() is not None:
        print(">> get_definition().location:
{0}".format(child.get_definition().location))
      find_all(child)
index = clang.cindex.Index.create()
tu = index.parse(sys.argv[1])
print 'Translation unit:', tu.spelling
find_all(tu.cursor)
python check.py ./my.h
## Fedora 20 / x86_64
$ python check.py my.h
Translation unit: my.h
displayname: __int128_t, kind: CursorKind.TYPEDEF_DECL, is_definition: True, 
location:<SourceLocation file None, line 0, column
0>>> get_definition().location: <SourceLocation file None, line 0, column
0>
displayname: __uint128_t, kind: CursorKind.TYPEDEF_DECL, is_definition: True, 
location:<SourceLocation file None, line 0, column
0>>> get_definition().location: <SourceLocation file None, line 0, column
0>
displayname: __builtin_va_list, kind: CursorKind.TYPEDEF_DECL, is_definition:
True,  location:<SourceLocation file None, line 0, column
0>>> get_definition().location: <SourceLocation file None, line 0, column
0>
displayname: __va_list_tag, kind: CursorKind.TYPE_REF, is_definition: False, 
location:<SourceLocation file None, line 0, column
0>>> get_definition().location: <SourceLocation file None, line 0, column
0>
displayname: timespec, kind: CursorKind.STRUCT_DECL, is_definition: True, 
location:<SourceLocation file 'my.h', line 1, column
8>>> get_definition().location: <SourceLocation file 'my.h', line
1, column 8>
displayname: tv_sec, kind: CursorKind.FIELD_DECL, is_definition: True, 
location:<SourceLocation file 'my.h', line 3, column
7>>> get_definition().location: <SourceLocation file 'my.h', line
3, column 7>
displayname: tv_nsec, kind: CursorKind.FIELD_DECL, is_definition: True, 
location:<SourceLocation file 'my.h', line 4, column
7>>> get_definition().location: <SourceLocation file 'my.h', line
4, column 7>
## Fedora 19 / AArch64
$ python check.py my.h
Translation unit: my.h
displayname: timespec, kind: CursorKind.STRUCT_DECL, is_definition: False, 
location:<SourceLocation file 'my.h', line 1, column
8>>> get_definition().location: <SourceLocation file 'my.h', line
1, column 8>
displayname: tv_sec, kind: CursorKind.FIELD_DECL, is_definition: True, 
location:<SourceLocation file 'my.h', line 3, column
7>>> get_definition().location: <SourceLocation file 'my.h', line
3, column 7>
displayname: tv_nsec, kind: CursorKind.FIELD_DECL, is_definition: True, 
location:<SourceLocation file 'my.h', line 4, column
7>>> get_definition().location: <SourceLocation file 'my.h', line
4, column 7>
<<GDB_FRAGMENT
Breakpoint 1, clang_isCursorDefinition (C=...)
   at
/home/david.abdurachmanov/new-arch/test/BUILD/fc19_aarch64_gcc490/external/llvm/3.4-cms2/llvm-3.4-6800b6d2afc/tools/clang/tools/libclang/CIndex.cpp:4709
4709      if (!clang_isDeclaration(C.kind))
(gdb) p C
$1 = {kind = CXCursor_ClassDecl, xdata = 0, data = {0x7fb39e60e0, 0x0,
0x7fb000cfb0}}
(gdb) p clang_getCString(clang_getCursorDisplayName(C))
$2 = 0x9a5cd0 "RunNumber"
(gdb) set $foo = clang_getCursorDefinition(C)
(gdb) p $foo
$3 = {kind = CXCursor_ClassDecl, xdata = 0, data = {0x7fb39e60e0, 0x1,
0x7fb000cfb0}}
clang::cxcursor::operator== (X=..., Y=...)
   at
/home/david.abdurachmanov/new-arch/test/BUILD/fc19_aarch64_gcc490/external/llvm/3.4-cms2/llvm-3.4-6800b6d2afc/tools/clang/tools/libclang/CXCursor.cpp:936
936       return X.kind == Y.kind && X.data[0] == Y.data[0] &&
X.data[1] == Y.data[1] &&
(gdb) info args
X = {kind = CXCursor_ClassDecl, xdata = 0, data = {0x7fb39e60e0, 0x1,
0x7fb000cfb0}}
Y = {kind = CXCursor_ClassDecl, xdata = 0, data = {0x7fb39e60e0, 0x0,
0x7fb000cfb0}}
GDB_FRAGMENT