[libclang] clang_Type_getOffsetOf returns incorrect result for type with flexible array.

Hi,

For project Panama [1] we are using libclang to parse header files and generate layout descriptors for structs. But, we're having some trouble when in comes to structs with flexible arrays.

For instance, for the following struct declaration:

struct Foo {
     int size;
     void *data[];
};

trying to get the offset of any of the fields returns CXTypeLayoutError_Incomplete (-2). However, it should be possible to find the offset of the fields. When using the offsetof macro [2], this does return the correct result; offsetof(struct Foo, size) = 0, and offsetof(struct Foo, data) = 8. clang_Type_getSizeOf returns the correct size for Foo as well.

See the following example program:

#include <iostream>
#include <string>
#include <clang-c/Index.h>
#include <cstddef>

#include "a.h"

int main() {
     CXIndex index = clang_createIndex(0, 0);
     CXTranslationUnit unit = clang_parseTranslationUnit(
         index,
         "a.h", nullptr, 0,
         nullptr, 0,
         CXTranslationUnit_None);

     CXCursor cursor = clang_getTranslationUnitCursor(unit);
     clang_visitChildren(
         cursor,
         [](CXCursor c, CXCursor, CXClientData) {
             CXType type = clang_getCursorType(c);
             std::string spelling = clang_getCString(clang_getTypeSpelling(type));
             if(spelling == "struct Foo") {
                 long long size = clang_Type_getSizeOf(type);
                 std::cout << "size of 'Foo': " << size << std::endl;

                 long long offset_size = clang_Type_getOffsetOf(type, "size");
                 std::cout << "offset of 'size': " << offset_size << std::endl;
                 std::cout << "offset of 'size' with operator: " << offsetof(struct Foo, size) << std::endl;

                 long long offset_data = clang_Type_getOffsetOf(type, "data");
                 std::cout << "offset of 'data': " << offset_data << std::endl;
                 std::cout << "offset of 'size' with operator: " << offsetof(struct Foo, data) << std::endl;
             }
             return CXChildVisit_Recurse;
         },
         nullptr
     );

     clang_disposeTranslationUnit(unit);
     clang_disposeIndex(index);
     return 0;
}

where a.h is just:

struct Foo {
     int size;
     void * data[];
};

The inability to report the field offset seems to be a bug/shortcoming. Bugzilla doesn't seem to know about this [3], and since it currently doesn't allow new user self-registration, I thought I'd try on here first.

I've looked into the source here: https://github.com/llvm-mirror/clang/blob/master/tools/libclang/CXType.cpp#L985 . But, I don't really see where exactly the problem would be, or how to fix it. We are currently using the binary distribution of LLVM found here: http://releases.llvm.org/download.html . I've tried with the latest version (7.0.1 at the time of writing), which also has the problem.

I'm hoping someone here can help.

Best regards,
Jorn Vernee

[1] : http://openjdk.java.net/projects/panama/
[2] : https://en.cppreference.com/w/cpp/types/offsetof
[3] : https://bugs.llvm.org/buglist.cgi?quicksearch=flexible%20array