[cfe-dev] libclang appears to be returning incorrect CXCursor in include statement.
Josh Gray
gray.josh at gmail.com
Wed Jan 8 15:03:49 PST 2014
Hello,
I think I may have hit a bug in libclang.
Given a source file, test.cpp, which contains only the following line
#include <string>
If I parse it with clang_parseTranslationUnit() using the
CXTranslationUnit_DetailedPreprocessingRecord option I find there is a
single CXCursor located in my source file with kind
CXCursor_InclusionDirective and extent of offset 0 to offset 17.
If I get a CXCursor via calls to clang_getLocationForOffset() and
clang_getCursor() for offsets 0 to 9 I get this cursor. For offsets 10 to
17 I get a CXCursor with kind CXCursor_NoDeclFound.
I would expect to get the CXCursor_InclusionDirective CXCursor for all
offsets 0 to 17. Can anyone explain why? (For include statements using ""
rather than <> the problem does not seem to occur)
See attached sample code
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140109/e641e580/attachment.html>
-------------- next part --------------
CXCursor GetCursotAt(CXTranslationUnit tu, CXFile file, unsigned offset)
{
CXSourceLocation sl;
sl = clang_getLocationForOffset(tu, file, offset);
assert(!clang_equalLocations(sl, clang_getNullLocation()));
return clang_getCursor(tu, sl);
}
void GetCursorExtentOffsets(CXCursor cursor, unsigned* start, unsigned* end)
{
CXSourceRange range = clang_getCursorExtent(cursor);
CXSourceLocation loc;
CXFile f;
unsigned l, c, o;
loc = clang_getRangeStart(range);
clang_getInstantiationLocation(loc, &f, &l, &c, &o);
*start = o;
loc = clang_getRangeEnd(range);
clang_getInstantiationLocation(loc, &f, &l, &c, &o);
*end = o;
}
int main(int argc, const char **argv)
{
CXIndex idx = clang_createIndex(1, 0);
CXTranslationUnit tu = clang_parseTranslationUnit(idx, "test.cpp", NULL, 0, NULL, 0, CXTranslationUnit_DetailedPreprocessingRecord);
assert(tu);
CXFile file = clang_getFile(tu, "test.cpp");
assert(file);
CXCursor c;
unsigned start, end;
unsigned testOffset;
//Check Curosr at offset 0
testOffset = 0;
c = GetCursotAt(tu, file, testOffset);
assert(!clang_equalCursors(c, clang_getNullCursor()));
//check we have a cursor for the #include
assert(clang_getCursorKind(c) == CXCursor_InclusionDirective);
//check cursor covers entire range (0 -> 17)
GetCursorExtentOffsets(c, &start, &end);
assert(start == 0);
assert(end == 17);
//Check Cursor returned for offsets 1,2,3...9
for(testOffset = 1; testOffset < 10; testOffset++)
{
c = GetCursotAt(tu, file, testOffset);
assert(!clang_equalCursors(c, clang_getNullCursor()));
//check we have a cursor for the #include
assert(clang_getCursorKind(c) == CXCursor_InclusionDirective);
}
//Check Cursor at offset 9,10...17. All will return a CXCursor with kind CXCursor_NoDeclFound
for(testOffset = 10; testOffset < 17; testOffset++)
{
c = GetCursotAt(tu, file, 10);
assert(!clang_equalCursors(c, clang_getNullCursor()));
//check we have a cursor for the #include
//!!clang_getCursorKind(c) now returns CXCursor_NoDeclFound!!
assert(clang_getCursorKind(c) == CXCursor_NoDeclFound);
}
return 0;
}
More information about the cfe-dev
mailing list