如何使用libclang检测枚举和范围枚举之间的区别?

Nia*_*las 8 abstract-syntax-tree c++11 libclang

我一直在使用优秀的C接口libclang(http://clang.llvm.org/doxygen/group__CINDEX.html)编写C++ AST解析器.不幸的是,在C++ 11作用域枚举和旧式枚举之间似乎没有消歧:两者都有一个游标类型CXCursor_EnumDecl和一个类型CXType_Enum即相同.

我试过拜访孩子,看他们的父母类型是否不同 - 遗憾的是没有.我试过要求底层类型,我得到两个整数.我已经检查了Enum之后声明的所有项目,看看是否可能出现旧式枚举的bind或typedef,再次没有明显区别.

我开始认为我必须遗漏一些东西.我是否必须使用代码完成API来确定它是哪种枚举?

Nia*_*las 3

所以这是一种解决方案,虽然不是很好,但可能对其他人有帮助。CXCursor 是一个如下所示的结构:

typedef struct {
  enum CXCursorKind kind;
  int xdata;
  const void *data[3];
} CXCursor;
Run Code Online (Sandbox Code Playgroud)

目前, 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();
  }
}
Run Code Online (Sandbox Code Playgroud)

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