How do I get an enum element's numerical value using libclang?

enum java
enum c++
java enum with values
enum java 8
java enum constructor
enum in c
enum c#
java enum with numbers

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:

  1. "MyEnum" (CXType_Enum)
    • "First" (CXToken_Identifier)
    • "=" (CXToken_Punctuation)
    • "1" (CXToken_Literal)
  2. "unsigned int" (CXType_UInt)
    • "1" (CXToken_Literal)
  3. "MyEnum" (CXType_Enum)
    • "Second" (CXToken_Identifier)
  4. "MyEnum" (CXType_Enum)
    • "Third" (CXToken_Identifier)
  5. "MyEnum" (CXType_Enum)
    • "TwoAgain" (CXToken_Identifier)
    • "=" (CXToken_Punctuation)
    • "Second" (CXToken_Identifier)
  6. "unsigned int" (CXType_UInt)
    • "Second" (CXToken_Identifier)

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?

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

Number of elements in an enum, I don't believe there is. But what would you do with such a number if they are not sequential, and you don't already have a list of them� using System; public class GetNameTest { enum Colors { Red, Green, Blue, Yellow }; enum Styles { Plaid, Striped, Tartan, Corduroy }; public static void Main() { Console.WriteLine("The 4th value of the Colors Enum is {0}", Enum.GetName(typeof(Colors), 3)); Console.WriteLine("The 4th value of the Styles Enum is {0}", Enum.GetName(typeof(Styles), 3)); } } // The example displays the following output: // The 4th value of the Colors Enum is Yellow // The 4th value of the Styles Enum is Corduroy

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

Enumerated type, Furthermore, we're also missing other properties of the periodic table elements, like the name and atomic weight. Although the enum type has� The keyword “enum” is used to declare an enumeration. The following is the syntax of enums. enum enum_name{const1, const2, .. }; Here, enum_name − Any name given by user. const1, const2 − These are values of type flag. The enum keyword is also used to define the variables of enum type.

You can use following way in get name and value for your map. i am using clang 8.

bool VisitEnumDecl(EnumDecl *ED)
      {

        for (auto it = ED->enumerator_begin(); it != ED->enumerator_end(); it++)
        {


         std::cout <<it->getNameAsString()<<" "<<it->getInitVal().getSExtValue()<<std::endl;


        }
        return true;
      }

Attaching Values to Java Enum, Retrieves the name of the constant in the specified enumeration that has the specified value. *** The function enum2symbol returns the name of an element of an enum client server public static str enum2Symbol (EnumId _id, int _val) On executing the below code the result of using these both functions can be found: static void devAXJob (Args _args)

Enum.GetName(Type, Object) Method (System), The random number (0-2) generated corresponds to the index of the elements in the array (or the oridnal of the element in the enumeration). EnumName.values(). Basically you can swap the enum values - put enumValue 4 for the element E3 and enumValue 3 for element E4. As you cannot assign the same number for two elements simultaneously, you will have to temporary put, let's say, a value 99 for element E4, then set a value 4 to element E3 and then go back to element E4 and set it's value to 3.

Enum - Java Programming Tutorial, An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have� Get the literal label of an enum value I couldn't find a function in the standard to give me the literal label (@SYSxxxx) of an enum value, so I came up with this prototype:

Enum Types (The Java™ Tutorials > Learning the Java Language , In C#, an enum (or enumeration type) is used to assign constant names to a group of numeric integer values. It makes constant values more readable, for example,� When using enumerated types (enums), always make a type definition of the control. Creating type definitions prevents you from needing to rewrite the code each time you add or remove an item from an enum. This way, when you modify one of them, you don't get your string values replaced by numbers in the Case Structure labels.

Comments
  • That's perfect, @MattStevens; thank you! We really can't get any simpler and cleaner than this. I was trying to work with CXTypeKind, but I had somehow missed CXCursorKind.
  • Thanks for providing an alternative solution, @TartanLlama! I half-suspected this is out of scope for libclang, but it's good to have confirmation and the alternative.
  • Actually, it is possible through libclang. See @MattStevens' answer.