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