Suppose I have an enum definition, e.g.:
// myenum.h
enum MyEnum {
First = 1,
Second,
Third,
TwoAgain = Second
};
I would like to programmatically generate a map from any given enum definition, where the key is the enum element's name, and the value is the enum element's numerical value (e.g. myMap["TwoAgain"] == 2
)
So far, I know how to traverse the source file using clang_visitChildren()
, and extract individual tokens using clang_tokenize()
. Recursing through the AST, I get cursors/tokens in this order:
I guess I could write an algorithm that uses this information to calculate every value. However, I was wondering if there's a simpler way? Can I get the numerical values directly from the libclang API?
Use the len() class to get the number of elements in an enum, e.g. len(Color) . The len() function returns the length (the number of items) of an object and can directly be passed an enum. Copied! The len() function returns the length (the number of items) of an object.
Numeric enums are number-based enums i.e. they store string values as numbers. Enums are always assigned numeric values when they are stored. The first value always takes the numeric value of 0, while the other values in the enum are incremented by 1.
valueOf() method returns the enum constant of the specified enumtype with the specified name. The name must match exactly an identifier used to declare an enum constant in this type.
libclang exposes this information through clang_getEnumConstantDeclValue
and clang_getEnumConstantDeclUnsignedValue
. A map like you describe can be built by visiting the children of a CXCursor_EnumDecl
:
static enum CXChildVisitResult VisitCursor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
if (cursor.kind == CXCursor_EnumConstantDecl) {
CXString spelling = clang_getCursorSpelling(cursor);
myMap[clang_getCString(spelling)] = clang_getEnumConstantDeclValue(cursor);
clang_disposeString(spelling);
}
return CXChildVisit_Continue;
}
As id256 said, I don't think you can do this with libclang
. However, Clang's libtooling
and plugin interface allow you to access the AST and operate on that directly. For enums, you'll want to look at the EnumDecl
class, which allows you to iterate over the inner decls. Then it's just a case of building up a map like:
for (auto declIterator = myEnumDecl.decls_begin();
declIterator != myEnumDecl.decls_end();
++declIterator)
{
myMap[declIterator->getNameAsString()] = declIterator->getInitVal;
}
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