@@ -9486,6 +9486,82 @@ void ClangASTContext::DumpValue(
9486
9486
}
9487
9487
}
9488
9488
9489
+ static bool DumpEnumValue (const clang::QualType &qual_type, Stream *s,
9490
+ const DataExtractor &data, lldb::offset_t byte_offset,
9491
+ size_t byte_size, uint32_t bitfield_bit_offset,
9492
+ uint32_t bitfield_bit_size) {
9493
+ const clang::EnumType *enutype =
9494
+ llvm::cast<clang::EnumType>(qual_type.getTypePtr ());
9495
+ const clang::EnumDecl *enum_decl = enutype->getDecl ();
9496
+ assert (enum_decl);
9497
+ lldb::offset_t offset = byte_offset;
9498
+ const uint64_t enum_svalue = data.GetMaxS64Bitfield (
9499
+ &offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
9500
+ bool can_be_bitfield = true ;
9501
+ uint64_t covered_bits = 0 ;
9502
+ int num_enumerators = 0 ;
9503
+
9504
+ // Try to find an exact match for the value.
9505
+ // At the same time, we're applying a heuristic to determine whether we want
9506
+ // to print this enum as a bitfield. We're likely dealing with a bitfield if
9507
+ // every enumrator is either a one bit value or a superset of the previous
9508
+ // enumerators. Also 0 doesn't make sense when the enumerators are used as
9509
+ // flags.
9510
+ for (auto enumerator : enum_decl->enumerators ()) {
9511
+ uint64_t val = enumerator->getInitVal ().getSExtValue ();
9512
+ if (llvm::countPopulation (val) != 1 && (val & ~covered_bits) != 0 )
9513
+ can_be_bitfield = false ;
9514
+ covered_bits |= val;
9515
+ ++num_enumerators;
9516
+ if (val == enum_svalue) {
9517
+ // Found an exact match, that's all we need to do.
9518
+ s->PutCString (enumerator->getNameAsString ());
9519
+ return true ;
9520
+ }
9521
+ }
9522
+
9523
+ // No exact match, but we don't think this is a bitfield. Print the value as
9524
+ // decimal.
9525
+ if (!can_be_bitfield) {
9526
+ s->Printf (" %" PRIi64, enum_svalue);
9527
+ return true ;
9528
+ }
9529
+
9530
+ // Unsigned values make more sense for flags.
9531
+ offset = byte_offset;
9532
+ const uint64_t enum_uvalue = data.GetMaxU64Bitfield (
9533
+ &offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
9534
+
9535
+ uint64_t remaining_value = enum_uvalue;
9536
+ std::vector<std::pair<uint64_t , llvm::StringRef>> values;
9537
+ values.reserve (num_enumerators);
9538
+ for (auto enumerator : enum_decl->enumerators ())
9539
+ if (auto val = enumerator->getInitVal ().getZExtValue ())
9540
+ values.emplace_back (val, enumerator->getName ());
9541
+
9542
+ // Sort in reverse order of the number of the population count, so that in
9543
+ // `enum {A, B, ALL = A|B }` we visit ALL first. Use a stable sort so that
9544
+ // A | C where A is declared before C is displayed in this order.
9545
+ std::stable_sort (values.begin (), values.end (), [](const auto &a, const auto &b) {
9546
+ return llvm::countPopulation (a.first ) > llvm::countPopulation (b.first );
9547
+ });
9548
+
9549
+ for (const auto &val : values) {
9550
+ if ((remaining_value & val.first ) != val.first )
9551
+ continue ;
9552
+ remaining_value &= ~val.first ;
9553
+ s->PutCString (val.second );
9554
+ if (remaining_value)
9555
+ s->PutCString (" | " );
9556
+ }
9557
+
9558
+ // If there is a remainder that is not covered by the value, print it as hex.
9559
+ if (remaining_value)
9560
+ s->Printf (" 0x%" PRIx64, remaining_value);
9561
+
9562
+ return true ;
9563
+ }
9564
+
9489
9565
bool ClangASTContext::DumpTypeValue (
9490
9566
lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format,
9491
9567
const DataExtractor &data, lldb::offset_t byte_offset, size_t byte_size,
@@ -9500,6 +9576,13 @@ bool ClangASTContext::DumpTypeValue(
9500
9576
clang::QualType qual_type (GetQualType (type));
9501
9577
9502
9578
const clang::Type::TypeClass type_class = qual_type->getTypeClass ();
9579
+
9580
+ if (type_class == clang::Type::Elaborated) {
9581
+ qual_type = llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType ();
9582
+ return DumpTypeValue (qual_type.getAsOpaquePtr (), s, format, data, byte_offset, byte_size,
9583
+ bitfield_bit_size, bitfield_bit_offset, exe_scope, is_base_class);
9584
+ }
9585
+
9503
9586
switch (type_class) {
9504
9587
case clang::Type::Typedef: {
9505
9588
clang::QualType typedef_qual_type =
@@ -9530,45 +9613,9 @@ bool ClangASTContext::DumpTypeValue(
9530
9613
// If our format is enum or default, show the enumeration value as its
9531
9614
// enumeration string value, else just display it as requested.
9532
9615
if ((format == eFormatEnum || format == eFormatDefault) &&
9533
- GetCompleteType (type)) {
9534
- const clang::EnumType *enutype =
9535
- llvm::cast<clang::EnumType>(qual_type.getTypePtr ());
9536
- const clang::EnumDecl *enum_decl = enutype->getDecl ();
9537
- assert (enum_decl);
9538
- clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
9539
- const bool is_signed = qual_type->isSignedIntegerOrEnumerationType ();
9540
- lldb::offset_t offset = byte_offset;
9541
- if (is_signed) {
9542
- const int64_t enum_svalue = data.GetMaxS64Bitfield (
9543
- &offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
9544
- for (enum_pos = enum_decl->enumerator_begin (),
9545
- enum_end_pos = enum_decl->enumerator_end ();
9546
- enum_pos != enum_end_pos; ++enum_pos) {
9547
- if (enum_pos->getInitVal ().getSExtValue () == enum_svalue) {
9548
- s->PutCString (enum_pos->getNameAsString ());
9549
- return true ;
9550
- }
9551
- }
9552
- // If we have gotten here we didn't get find the enumerator in the
9553
- // enum decl, so just print the integer.
9554
- s->Printf (" %" PRIi64, enum_svalue);
9555
- } else {
9556
- const uint64_t enum_uvalue = data.GetMaxU64Bitfield (
9557
- &offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
9558
- for (enum_pos = enum_decl->enumerator_begin (),
9559
- enum_end_pos = enum_decl->enumerator_end ();
9560
- enum_pos != enum_end_pos; ++enum_pos) {
9561
- if (enum_pos->getInitVal ().getZExtValue () == enum_uvalue) {
9562
- s->PutCString (enum_pos->getNameAsString ());
9563
- return true ;
9564
- }
9565
- }
9566
- // If we have gotten here we didn't get find the enumerator in the
9567
- // enum decl, so just print the integer.
9568
- s->Printf (" %" PRIu64, enum_uvalue);
9569
- }
9570
- return true ;
9571
- }
9616
+ GetCompleteType (type))
9617
+ return DumpEnumValue (qual_type, s, data, byte_offset, byte_size,
9618
+ bitfield_bit_offset, bitfield_bit_size);
9572
9619
// format was not enum, just fall through and dump the value as
9573
9620
// requested....
9574
9621
LLVM_FALLTHROUGH;
0 commit comments