libclang を使用した匿名列挙型の検索



スペル名のテキストに依存せずに 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)')

いくつかのコードの回答


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