Anonyme Aufzählungen mit libclang finden

Anonyme Aufzählungen mit libclang finden


Gibt es eine Möglichkeit, anonyme Aufzählungen mit libclang zu erkennen, ohne sich auf den Text in der Schreibweise des Namens zu verlassen?


Die Python-Bindungen an libclang enthalten Funktionen zum Erkennen, ob C/C++-Strukturen oder Unions anonym sind, indem clang.cindex.Cursor.is_anonymous verwendet wird, was schließlich zum Aufruf von clang_Cursor_isAnonymous führt.


Das folgende Beispiel veranschaulicht das Problem.


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)

Was bei Ausführung auf sample.cpp


enum
{
VAL = 1
};
struct s
{
struct {};
union
{
int x;
float y;
};
};

Ergibt:


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

Einige Code-Antworten


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)