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)')
You're not *returning an anonymous enum*. an anonymous enum as a member. Replies have been disabled for this discussion. Problems with enums across a dll interface?
Retrieve the alignment of the record. Retrieve the type of the elements of the array type. Retrieve the size of the constant array. Return the canonical type for a Type. Clang’s type system explicitly models typedefs and all the ways a specific type can be represented. The canonical type is the underlying type with all the “sugar” removed.
It's not immediately obvious from the libclang API what an appropriate approach to extracting token is. However, it's rare that you would ever need (or want) to drop down to this level - the cursor layer is typically much more useful.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With