寻找具有libclang匿名枚举 [英] Finding anonymous enums with libclang

查看:199
本文介绍了寻找具有libclang匿名枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法来检测使用libclang匿名枚举,而不依赖于在拼写名称的文本?

Python绑定到<一个href=\"https://raw.githubusercontent.com/llvm-mirror/clang/release_36/bindings/python/clang/cindex.py\">libclang包括功能检测C / C ++结构或联合是否使用匿名<一个href=\"https://github.com/llvm-mirror/clang/blob/release_37/bindings/python/clang/cindex.py#L1483\">clang.cindex.Cursor.is_anonymous,这最终调用<一个href=\"http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#ga6e0d2674d126fd43816ce3a80b592373\">clang_Cursor_isAnonymous.

下面的示例说明这个问题。

 进口SYS
从clang.cindex进口*高清的nodeinfo(N):
    回报(n.kind,n.is_anonymous(),n.spelling,n.type.spelling)IDX = Index.create()#翻译单元正确解析
TU = idx.parse(sys.argv中[1],['-std = C ++ 11'])
断言(LEN(tu.diagnostics)== 0)在tu.cursor.walk_ preorder N():
    如果n.kind == CursorKind.STRUCT_DECL和n.is_anonymous():
        打印的nodeinfo(N)
    如果n.kind == CursorKind.UNION_DECL和n.is_anonymous():
        打印的nodeinfo(N)
    如果n.kind == CursorKind.ENUM_DECL:
        如果n.is_anonymous():
            打印的nodeinfo(N)
        其他:
            打印'不正确',将nodeinfo(N)

,当上sample.cpp的运行

 枚举
{
    VAL = 1
};的struct
{
    结构{};
    联盟
    {
        INT X;
        浮ÿ;
    };
};

给出:

 不正确(CursorKind.ENUM_DECL,假,'','(匿名在sample1.cpp枚举:1:1))
(CursorKind.STRUCT_DECL,诚然,'',的::(在sample1.cpp匿名结构:8:5))
(CursorKind.UNION_DECL,诚然,'',的::(在sample1.cpp匿名联合:9:5))


解决方案

不幸的是 clang_Cursor_isAnonymous 仅适用于结构和联合,你可以从铛源$ C ​​$ C看到工具/ libclang / CXType.cpp

 无符号clang_Cursor_isAnonymous(CXCursor C){
  如果(!clang_isDeclaration(C.kind))
    返回0;
  常量申报* D = cxcursor :: getCursorDecl(C);
  如果(常量RecordDecl * FD = dyn_cast_or_null&LT; RecordDecl&GT;(D))
    返回FD-&GT; isAnonymousStructOrUnion();
  返回0;
}

于是退回到了 conf.lib.clang_Cursor_isAnonymous 中的 clang.cindex.Cursor.is_anonymous 确实没有什么新的游标类型已经被核对FIELD_DECL(仅用于结构和联合是真实的)

 高清is_anonymous(个体经营):
        
        检查记录是匿名的。
        
        如果self.kind == CursorKind.FIELD_DECL:
            返回self.type.get_declaration()。is_anonymous()
        返回conf.lib.clang_Cursor_isAnonymous(个体经营)

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

Is there a way to detect anonymous enumerations using libclang without relying on the text in the spelling name?

The python bindings to libclang include functionality to detect whether C/C++ structs or unions are anonymous using clang.cindex.Cursor.is_anonymous, which ends up calling clang_Cursor_isAnonymous.

The following sample demonstrates the issue.

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)

Which when run on sample.cpp

enum
{
    VAL = 1
};

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

Gives:

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)')

解决方案

Unfortunately clang_Cursor_isAnonymous works only with structs and unions as you can see from clang source code in tools/libclang/CXType.cpp

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;
}

So fallback to the conf.lib.clang_Cursor_isAnonymous in clang.cindex.Cursor.is_anonymous does nothing new as cursor type has been already checked against FIELD_DECL (which is true only for structs and unions)

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)

You can try to extract identifier of current element (n in your sample) and check if it exists or is null

这篇关于寻找具有libclang匿名枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆