9

我一直在使用出色的 C 接口 libclang ( http://clang.llvm.org/doxygen/group__CINDEX.html ) 编写 C++ AST 解析器。不幸的是,C++ 11 范围内的枚举和老式枚举之间似乎没有歧义:两者都具有 CXCursor_EnumDecl 的游标类型和 CXType_Enum 的类型,即相同。

我曾尝试拜访孩子们,看看他们的父母类型是否不同 - 遗憾的是没有。我尝试询问基础类型,我得到了两者的整数。我检查了 Enum 之后声明的所有项目,看看是否可能出现老式 Enum 的 bind 或 typedef,同样没有明显区别。

我开始认为我一定是错过了什么。我是否必须使用代码完成 API 来确定它是哪种枚举?

4

1 回答 1

3

所以这是一个解决方案,虽然不是很好,但它可能会帮助其他人。CXCursor 是一个看起来像这样的结构:

typedef struct {
  enum CXCursorKind kind;
  int xdata;
  const void *data[3];
} CXCursor;

目前,void *data[3] 映射到 { const clang::Decl *Parent, const clang::Stmt *S, CXTranslationUnit TU }。知道了这一点,我们可以编写从 libclang C 状态中提取内部 clang C++ 对象的代码:

#include "clang/AST/Decl.h"
bool isScoped=false;
{
  using namespace clang;
  const Decl *D = static_cast<const Decl *>(cursor.data[0]);
  if(const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D))
  {
    isScoped=TD->isScoped();
  }
}

如果您的 clang 标头偏离您的 libclang,则此解决方案可能会发生很多不好的事情。我不太关心这个解决方案,但它确实有效。

于 2014-10-03T16:03:50.383 回答