Enumerating the members of an enum

Is there a way to enumerate the fields of an enum (e.x. get an SBTypeList from an enum), or is that missing API?

Thanks
Russell Harmon

As far as I can tell/remember, this is missing API

Technically, it would not be an SBTypeList since the entries in an enumerator are NOT types.

We would probably have to come up with a new class like an SBEnumeratorEntry (I am sure better names are possible :slight_smile: that wraps the notion of a (numeric_value,string_name) pair

Enrico Granata
:envelope_with_arrow: egranata@.com
:phone: 27683

According to the C11 standard, N1570, §6.7.2.2.3, “The identifiers in an enumerator list are declared as constants that have type int”. Based on this, wouldn’t it make most sense to have a function that returns an SBTypeList of ints?

Is there an easy work around for this missing bit of API, or shall I add the necessary pieces?

An SBTypeList contains a list of SBType objects. It would not be very useful since SBType objects do not contain a values.

We should probably make an SBTypeEnumerator. Something like:

class SBTypeEnumerator
{
  bool
  IsSigned();
  
  // Get the enumerator value as a signed integer
  int64_t
  GetValueAsSigned();

  // Get the enumerator value as an unsigned integer
        uint64_t
  GetValueAsUnsigned();

  // Return the exact integer type for this enumerator
  SBType
  GetType();

  const char *
  GetName();
};

Then we would need to add a SBTypeEnumeratorList class as well:

class SBTypeEnumeratorList
{
  SBTypeEnumerator
  GetEnumeratorAtIndex (uint32_t idx);

  SBTypeEnumerator
  GetEnumeratorByName (const char *name);

  SBTypeEnumeratorList
  GetEnumeratorsByValue (int64_t value);

  SBTypeEnumeratorList
  GetEnumeratorsByValue (uint64_t value);
};

Then we would need to add functions to SBType:

class SBType
{
  SBTypeEnumeratorList
  GetEnumerators();
}

This would return a valid SBTypeEnumeratorList only if the SBType it was run on is an enumeration type.

Russell,
I agree with Greg that this is a more sensible approach than hijacking SBTypeList for something that is not a type
If you want to go ahead and work in this area, you are most welcome to

Just a side note, since our SB objects are backed by one opaque-pointer type instance variable, it might make sense to define a TypeEnumeratorImpl class (and a corresponding TypeEnumeratorListImpl) much like SBType is backed by TypeImpl (technically, shared_ptr)
Having these classes in lldb-core would allow us to implement this functionality at the ClangASTType level and then just export it at the SB API level

What are your thoughts on this approach?

Enrico Granata
:envelope_with_arrow: egranata@.com
:phone: 27683

I had a full email saying why I disagree written when I convinced myself that I agree. My thinking is that an enum member is the only “type” (that I can think of) which is itself also a value. Anyway, I’m fine with what you’ve outlined, although the name SBTypeEnumerator is a bit confusing. How about SBValuedType or SBEnumTypeMember?

I see the point in SBTypeEnumerator being confusing, tbh

My original idea was SBEnumeratorEntry, which I still prefer

However, I am sure someone on this list will come up with something amazing :slight_smile:

Enrico Granata
:envelope_with_arrow: egranata@.com
:phone: 27683

How about SBTypeEnumMember? Everything in SBType.h currently starts with SBType.

That’s fine with me.

Since an enumeration member has no corresponding QualType (there’s only EnumConstantDecl), in order to put all the logic of enumerating enum members into QualASTType, QualASTType would have to be able to create instances of itself not directly backed by a QualType. I think probably the best way to go would be to have the TypeEnumMemberImpl that I’m writing recieve a reference to the QualASTType of the enum itself and the index of this enum member and either eagerly or lazily pull the relevant information out. What do you think?

That sounds good.

Here ya’ go. Let me know if it needs some changes.

0001-Add-support-for-inspecting-enum-members.patch (24.4 KB)

bump

Looks good. The only thing I can think of is we might want to expose the following function:

bool
SBTypeEnumMember::IsSigned();

That way clients know if each member is signed or not. I know that each enum member in clang code knows if it is signed or not.

Greg

I had figured that a client could figure that out by looking at the enum member’s type. I’ll add it though

Yeah, in clang at least the main enumeration has a type that is signed or unsigned, but each enumerator also has a type.

Actually scratch my suggestion, because SBTypeEnumMember already has GetType():

SBType
SBTypeEnumMember::GetType()

Which we can then figure out if it is signed or not.

So your patch looks good as is.

Greg