有没有办法获得“基础”类型,好吧,Type
。我看到可以测试const
或volatile
,但我没有办法获得基础类型。
我最终要做的是映射类之间的成员关系,由于类型A
与const A
不同,目前缺少一些。
我看到的唯一解决方法是检查clang_isConstQualifiedType
并解析拼写,这似乎不是一个好主意。
这是我遇到问题的类布局:
class A {};
class B {
A a;
}
class C {
const A a;
B* b;
}
很难映射C->A
。
答案 0 :(得分:1)
似乎至少有部分解决方案在于函数“ clang_getTypeDeclaration”。希望这可以为您指明正确的方向,但是我将发布一些我生成的代码以及得到的结果。
// 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);
}
因此,该程序采用文件名,行号和列,并输出确定的类型。我使用了以下测试文件:
//foo.cc
class A {};
class B {
A a;
}
class C {
const A a;
B *b;
}
并运行以下命令:
./clang_fullname foo.cc 10 5
(指向“ const”中的“ n”)
并得到了输出:
::C::A
我在其他一些地方对其进行了测试,这似乎是一个“可行的解决方案”,并且相比尝试手动“解析” const限定符,这无疑给了我更大的信心。
注意: 上面写的方式有些危险。由于CXCursor只是void *的typedef,因此该operator <<将耗尽所有以其方式发送的void指针。最好将CXCursor包装在一些帮助器类中。