Skip to content

Report back errors in GetNumChildren() #84265

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lldb/include/lldb/DataFormatters/ValueObjectPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class ValueObjectPrinter {
void PrintChild(lldb::ValueObjectSP child_sp,
const DumpValueObjectOptions::PointerDepth &curr_ptr_depth);

uint32_t GetMaxNumChildrenToPrint(bool &print_dotdotdot);
llvm::Expected<uint32_t> GetMaxNumChildrenToPrint(bool &print_dotdotdot);

void
PrintChildren(bool value_printed, bool summary_printed,
Expand Down
3 changes: 2 additions & 1 deletion lldb/source/Core/ValueObjectVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ ValueObjectVariable::CalculateNumChildren(uint32_t max) {
CompilerType type(GetCompilerType());

if (!type.IsValid())
return 0;
return llvm::make_error<llvm::StringError>("invalid type",
llvm::inconvertibleErrorCode());

ExecutionContext exe_ctx(GetExecutionContextRef());
const bool omit_empty_base_classes = true;
Expand Down
22 changes: 18 additions & 4 deletions lldb/source/DataFormatters/ValueObjectPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,13 +621,17 @@ void ValueObjectPrinter::PrintChild(
}
}

uint32_t ValueObjectPrinter::GetMaxNumChildrenToPrint(bool &print_dotdotdot) {
llvm::Expected<uint32_t>
ValueObjectPrinter::GetMaxNumChildrenToPrint(bool &print_dotdotdot) {
ValueObject &synth_valobj = GetValueObjectForChildrenGeneration();

if (m_options.m_pointer_as_array)
return m_options.m_pointer_as_array.m_element_count;

uint32_t num_children = synth_valobj.GetNumChildrenIgnoringErrors();
auto num_children_or_err = synth_valobj.GetNumChildren();
if (!num_children_or_err)
return num_children_or_err;
uint32_t num_children = *num_children_or_err;
print_dotdotdot = false;
if (num_children) {
const size_t max_num_children = GetMostSpecializedValue()
Expand Down Expand Up @@ -704,7 +708,12 @@ void ValueObjectPrinter::PrintChildren(
ValueObject &synth_valobj = GetValueObjectForChildrenGeneration();

bool print_dotdotdot = false;
size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
auto num_children_or_err = GetMaxNumChildrenToPrint(print_dotdotdot);
if (!num_children_or_err) {
*m_stream << " <" << llvm::toString(num_children_or_err.takeError()) << '>';
return;
}
uint32_t num_children = *num_children_or_err;
if (num_children) {
bool any_children_printed = false;

Expand Down Expand Up @@ -753,7 +762,12 @@ bool ValueObjectPrinter::PrintChildrenOneLiner(bool hide_names) {
ValueObject &synth_valobj = GetValueObjectForChildrenGeneration();

bool print_dotdotdot = false;
size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
auto num_children_or_err = GetMaxNumChildrenToPrint(print_dotdotdot);
if (!num_children_or_err) {
*m_stream << '<' << llvm::toString(num_children_or_err.takeError()) << '>';
return true;
}
uint32_t num_children = *num_children_or_err;

if (num_children) {
m_stream->PutChar('(');
Expand Down
9 changes: 6 additions & 3 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5268,7 +5268,8 @@ TypeSystemClang::GetNumChildren(lldb::opaque_compiler_type_t type,
bool omit_empty_base_classes,
const ExecutionContext *exe_ctx) {
if (!type)
return 0;
return llvm::make_error<llvm::StringError>("invalid clang type",
llvm::inconvertibleErrorCode());

uint32_t num_children = 0;
clang::QualType qual_type(RemoveWrappingTypes(GetQualType(type)));
Expand Down Expand Up @@ -5325,9 +5326,11 @@ TypeSystemClang::GetNumChildren(lldb::opaque_compiler_type_t type,
}
num_children += std::distance(record_decl->field_begin(),
record_decl->field_end());
}
} else
return llvm::make_error<llvm::StringError>(
"incomplete type \"" + GetDisplayTypeName(type).GetString() + "\"",
llvm::inconvertibleErrorCode());
break;

case clang::Type::ObjCObject:
case clang::Type::ObjCInterface:
if (GetCompleteQualType(&getASTContext(), qual_type)) {
Expand Down
3 changes: 2 additions & 1 deletion lldb/source/Symbol/CompilerType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,8 @@ CompilerType::GetNumChildren(bool omit_empty_base_classes,
if (auto type_system_sp = GetTypeSystem())
return type_system_sp->GetNumChildren(m_type, omit_empty_base_classes,
exe_ctx);
return 0;
return llvm::make_error<llvm::StringError>("invalid type",
llvm::inconvertibleErrorCode());
}

lldb::BasicType CompilerType::GetBasicTypeEnumeration() const {
Expand Down
9 changes: 9 additions & 0 deletions lldb/test/API/functionalities/valobj_errors/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
C_SOURCES := main.c
LD_EXTRAS = hidden.o

a.out: hidden.o

hidden.o: hidden.c
$(CC) -g0 -c -o $@ $<

include Makefile.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil


class ValueObjectErrorsTestCase(TestBase):
def test(self):
"""Test that the error message for a missing type
is visible when printing an object"""
self.build()
lldbutil.run_to_source_breakpoint(self, "break here",
lldb.SBFileSpec('main.c'))
self.expect('v -ptr-depth 1 x', substrs=['<incomplete type "Opaque">'])
4 changes: 4 additions & 0 deletions lldb/test/API/functionalities/valobj_errors/hidden.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
struct Opaque {
int i, j, k;
} *global;
struct Opaque *getOpaque() { return &global; }
9 changes: 9 additions & 0 deletions lldb/test/API/functionalities/valobj_errors/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
struct Opaque;
struct Opaque *getOpaque();
void puts(const char *);

int main() {
struct Opaque *x = getOpaque();
puts("break here\n");
return (int)x;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
target var a
# CHECK-LABEL: target var a
# FIXME: This should also produce some kind of an error.
# CHECK: (A) a = {}
# CHECK: (A) a = <incomplete type "A">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

expr a
# CHECK-LABEL: expr a
# CHECK: incomplete type 'A' where a complete type is required
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ RUN: not %lldb %t -b -o "expression (EC) 1" 2>&1 | FileCheck --check-prefix=PRIN
PRINTEC: use of undeclared identifier 'EC'

RUN: %lldb %t -b -o "target variable a e ec" | FileCheck --check-prefix=VARS %s
VARS: (const (unnamed struct)) a = {}
VARS: (const (unnamed struct)) a = <incomplete type "const (unnamed struct)">
VARS: (const (unnamed enum)) e = 0x1
VARS: (const (unnamed enum)) ec = 0x1