It appears an at least partial solution lies in the function "clang_getTypeDeclaration." Hopefully that should point you in the right direction, but I'll post some code I genned up and the results I'm getting.
// clang_fullname.cc
#include <clang-c/Index.h>
#include <iostream>
using namespace std;
/*
* help with CXString
*/
ostream &operator<<(ostream &o, CXString cxs) {
o << clang_getCString(cxs);
clang_disposeString(cxs);
return o;
}
/*
* Display fully qualified cursor name
*/
ostream &operator<<(ostream &o, CXCursor cursor) {
/*
* Base of recursion
*/
if (clang_Cursor_isNull(cursor) || clang_isTranslationUnit(cursor.kind))
return o;
/*
* switching to a referenced cursor is nice for templates and function calls
*/
CXCursor cursorReferenced = clang_getCursorReferenced(cursor);
/*
* Sometimes a cursorReferenced will be the same cursor, so we must avoid
* infinite recursion
*/
if (!clang_Cursor_isNull(cursorReferenced) &&
!clang_equalCursors(cursor, cursorReferenced)) {
return o << clang_getCursorReferenced(cursor);
} else {
/*
* Typical recursive step
*/
return o << clang_getCursorSemanticParent(cursor)
<< "::"
/*
* Here the type of the type declaration is retrieved #ugly
*/
<< clang_getTypeSpelling(clang_getCursorType(
clang_getTypeDeclaration(clang_getCursorType(cursor))));
}
}
int main(int argc, char *argv[]) {
if (argc != 4) {
cout << "usage: filename line col" << endl;
return 0;
}
CXIndex index = clang_createIndex(0, 0);
CXTranslationUnit TU = clang_createTranslationUnitFromSourceFile(
index, argv[1], 0, nullptr, 0, nullptr);
CXFile cxfile = clang_getFile(TU, argv[1]);
unsigned line = atoi(argv[2]);
unsigned column = atoi(argv[3]);
CXSourceLocation cxloc = clang_getLocation(TU, cxfile, line, column);
cout << clang_getCursor(TU, cxloc) << endl;
clang_disposeTranslationUnit(TU);
clang_disposeIndex(index);
}
So, the program takes a filename, line number, and column, and outputs the determined type. I used the following test file:
//foo.cc
class A {};
class B {
A a;
}
class C {
const A a;
B *b;
}
And ran the following command:
./clang_fullname foo.cc 10 5
(That points to the "n" in "const")
And got as output:
::C::A
I tested it on some other things, and it seems to be a "workable solution," and certainly gives me more confidence than trying to "parse out" the const qualifier manually.
NOTE:
The way this is written above is somewhat dangerous. Because CXCursor is just a typedef of void*, that operator<< will eat up all void pointers sent its way. Better to wrap CXCursor in some helper class.