【问题标题】:Finding anonymous enums with libclang使用 libclang 查找匿名枚举
【发布时间】:2016-05-08 21:08:33
【问题描述】:

有没有办法使用 libclang 检测匿名枚举而不依赖拼写名称中的文本?

libclang 的python 绑定包括使用clang.cindex.Cursor.is_anonymous 检测C/C++ 结构或联合是否匿名的功能,最终调用clang_Cursor_isAnonymous

以下示例演示了该问题。

import sys
from clang.cindex import *

def nodeinfo(n):
    return (n.kind, n.is_anonymous(), n.spelling, n.type.spelling)

idx = Index.create()

# translation unit parsed correctly
tu = idx.parse(sys.argv[1], ['-std=c++11'])
assert(len(tu.diagnostics) == 0)

for n in tu.cursor.walk_preorder():
    if n.kind == CursorKind.STRUCT_DECL and n.is_anonymous():
        print nodeinfo(n)
    if n.kind == CursorKind.UNION_DECL and n.is_anonymous():
        print nodeinfo(n)
    if n.kind == CursorKind.ENUM_DECL:
        if n.is_anonymous():
            print nodeinfo(n)
        else:
            print 'INCORRECT', nodeinfo(n)

在 sample.cpp 上运行时

enum
{
    VAL = 1
};

struct s
{
    struct {};
    union
    {
        int x;
        float y;
    };
};

给予:

INCORRECT (CursorKind.ENUM_DECL, False, '', '(anonymous enum at sample1.cpp:1:1)')
(CursorKind.STRUCT_DECL, True, '', 's::(anonymous struct at sample1.cpp:8:5)')
(CursorKind.UNION_DECL, True, '', 's::(anonymous union at sample1.cpp:9:5)')

【问题讨论】:

  • 观察:你查询n的匿名标志,但稍后打印n.type的拼写。这可能是造成混乱的根源。
  • 感谢您的关注。我更新了示例以显示光标拼写(空字符串)以及要澄清的类型拼写。
  • n.kind == CursorKind.ENUM_DECL and n.is_anonymous() 不够?
  • @J.J.Hakala - 我已经修改了示例以使其更清楚,这还不够

标签: python c++ c clang libclang


【解决方案1】:

不幸的是,clang_Cursor_isAnonymous 仅适用于结构和联合,正如您从 tools/libclang/CXType.cpp 中的 clang 源代码中看到的那样

unsigned clang_Cursor_isAnonymous(CXCursor C){
  if (!clang_isDeclaration(C.kind))
    return 0;
  const Decl *D = cxcursor::getCursorDecl(C);
  if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D))
    return FD->isAnonymousStructOrUnion();
  return 0;
}

所以回退到clang.cindex.Cursor.is_anonymous 中的conf.lib.clang_Cursor_isAnonymous 并没有什么新变化,因为游标类型已经根据 FIELD_DECL 进行了检查(仅适用于结构和联合)

def is_anonymous(self):
        """
        Check if the record is anonymous.
        """
        if self.kind == CursorKind.FIELD_DECL:
            return self.type.get_declaration().is_anonymous()
        return conf.lib.clang_Cursor_isAnonymous(self)

您可以尝试提取当前元素的标识符(示例中为 n)并检查它是否存在或为空

【讨论】:

    猜你喜欢
    • 2011-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-27
    相关资源
    最近更新 更多