在libclang中获取Type的不合格版本

时间:2018-02-09 11:53:35

标签: c++ libclang

有没有办法获得“基础”类型,好吧,Type。我看到可以测试constvolatile,但我没有办法获得基础类型。

我最终要做的是映射类之间的成员关系,由于类型Aconst A不同,目前缺少一些。

我看到的唯一解决方法是检查clang_isConstQualifiedType并解析拼写,这似乎不是一个好主意。

这是我遇到问题的类布局:

class A {};

class B {
 A a;
}

class C {
  const A a;
  B* b;
}

很难映射C->A

1 个答案:

答案 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包装在一些帮助器类中。