diff options
Diffstat (limited to 'source/Plugins/Language/CPlusPlus/LibCxx.cpp')
| -rw-r--r-- | source/Plugins/Language/CPlusPlus/LibCxx.cpp | 186 | 
1 files changed, 140 insertions, 46 deletions
diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 95e02a473cd7..7e8c06bd4c75 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -9,10 +9,7 @@  #include "LibCxx.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes +#include "llvm/ADT/ScopeExit.h"  #include "lldb/Core/Debugger.h"  #include "lldb/Core/FormatEntity.h"  #include "lldb/Core/ValueObject.h" @@ -22,7 +19,9 @@  #include "lldb/DataFormatters/TypeSummary.h"  #include "lldb/DataFormatters/VectorIterator.h"  #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Target/CPPLanguageRuntime.h"  #include "lldb/Target/ProcessStructReader.h" +#include "lldb/Target/SectionLoadList.h"  #include "lldb/Target/Target.h"  #include "lldb/Utility/DataBufferHeap.h"  #include "lldb/Utility/Endian.h" @@ -33,6 +32,76 @@ using namespace lldb;  using namespace lldb_private;  using namespace lldb_private::formatters; +bool lldb_private::formatters::LibcxxOptionalSummaryProvider( +    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { +  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); +  if (!valobj_sp) +    return false; + +  // An optional either contains a value or not, the member __engaged_ is +  // a bool flag, it is true if the optional has a value and false otherwise. +  ValueObjectSP engaged_sp( +      valobj_sp->GetChildMemberWithName(ConstString("__engaged_"), true)); + +  if (!engaged_sp) +    return false; + +  llvm::StringRef engaged_as_cstring( +      engaged_sp->GetValueAsUnsigned(0) == 1 ? "true" : "false"); + +  stream.Printf(" Has Value=%s ", engaged_as_cstring.data()); + +  return true; +} + +bool lldb_private::formatters::LibcxxFunctionSummaryProvider( +    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + +  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); + +  if (!valobj_sp) +    return false; + +  ExecutionContext exe_ctx(valobj_sp->GetExecutionContextRef()); +  Process *process = exe_ctx.GetProcessPtr(); + +  if (process == nullptr) +    return false; + +  CPPLanguageRuntime *cpp_runtime = process->GetCPPLanguageRuntime(); + +  if (!cpp_runtime) +    return false; + +  CPPLanguageRuntime::LibCppStdFunctionCallableInfo callable_info = +      cpp_runtime->FindLibCppStdFunctionCallableInfo(valobj_sp); + +  switch (callable_info.callable_case) { +  case CPPLanguageRuntime::LibCppStdFunctionCallableCase::Invalid: +    stream.Printf(" __f_ = %" PRIu64, callable_info.member__f_pointer_value); +    return false; +    break; +  case CPPLanguageRuntime::LibCppStdFunctionCallableCase::Lambda: +    stream.Printf( +        " Lambda in File %s at Line %u", +        callable_info.callable_line_entry.file.GetFilename().GetCString(), +        callable_info.callable_line_entry.line); +    break; +  case CPPLanguageRuntime::LibCppStdFunctionCallableCase::CallableObject: +    stream.Printf( +        " Function in File %s at Line %u", +        callable_info.callable_line_entry.file.GetFilename().GetCString(), +        callable_info.callable_line_entry.line); +    break; +  case CPPLanguageRuntime::LibCppStdFunctionCallableCase::FreeOrMemberFunction: +    stream.Printf(" Function = %s ", +                  callable_info.callable_symbol.GetName().GetCString()); +    break; +  } + +  return true; +} +  bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider(      ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {    ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); @@ -120,9 +189,9 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {    if (!valobj_sp)      return false; -   +    static ConstString g___i_("__i_"); -   +    // this must be a ValueObject* because it is a child of the ValueObject we    // are producing children for it if were a ValueObjectSP, we would end up    // with a loop (iterator -> synthetic -> child -> parent == iterator) and @@ -156,37 +225,53 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {          m_pair_ptr = nullptr;          return false;        } -      CompilerType pair_type(__i_->GetCompilerType().GetTypeTemplateArgument(0)); -      std::string name; uint64_t bit_offset_ptr; uint32_t bitfield_bit_size_ptr; bool is_bitfield_ptr; -      pair_type = pair_type.GetFieldAtIndex(0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr); +      CompilerType pair_type( +          __i_->GetCompilerType().GetTypeTemplateArgument(0)); +      std::string name; +      uint64_t bit_offset_ptr; +      uint32_t bitfield_bit_size_ptr; +      bool is_bitfield_ptr; +      pair_type = pair_type.GetFieldAtIndex( +          0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr);        if (!pair_type) {          m_pair_ptr = nullptr;          return false;        } -       +        auto addr(m_pair_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRESS));        m_pair_ptr = nullptr; -      if (addr && addr!=LLDB_INVALID_ADDRESS) { -        ClangASTContext *ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(pair_type.GetTypeSystem()); +      if (addr && addr != LLDB_INVALID_ADDRESS) { +        ClangASTContext *ast_ctx = +            llvm::dyn_cast_or_null<ClangASTContext>(pair_type.GetTypeSystem());          if (!ast_ctx)            return false; -        CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(ConstString(), { -          {"ptr0",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, -          {"ptr1",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, -          {"ptr2",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, -          {"cw",ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, -          {"payload",pair_type} -        }); -        DataBufferSP buffer_sp(new DataBufferHeap(tree_node_type.GetByteSize(nullptr),0)); +        CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( +            ConstString(), +            {{"ptr0", +              ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, +             {"ptr1", +              ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, +             {"ptr2", +              ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, +             {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, +             {"payload", pair_type}}); +        llvm::Optional<uint64_t> size = tree_node_type.GetByteSize(nullptr); +        if (!size) +          return false; +        DataBufferSP buffer_sp(new DataBufferHeap(*size, 0));          ProcessSP process_sp(target_sp->GetProcessSP());          Status error; -        process_sp->ReadMemory(addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), error); +        process_sp->ReadMemory(addr, buffer_sp->GetBytes(), +                               buffer_sp->GetByteSize(), error);          if (error.Fail())            return false; -        DataExtractor extractor(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize()); -        auto pair_sp = CreateValueObjectFromData("pair", extractor, valobj_sp->GetExecutionContextRef(), tree_node_type); +        DataExtractor extractor(buffer_sp, process_sp->GetByteOrder(), +                                process_sp->GetAddressByteSize()); +        auto pair_sp = CreateValueObjectFromData( +            "pair", extractor, valobj_sp->GetExecutionContextRef(), +            tree_node_type);          if (pair_sp) -          m_pair_sp = pair_sp->GetChildAtIndex(4,true); +          m_pair_sp = pair_sp->GetChildAtIndex(4, true);        }      }    } @@ -491,6 +576,8 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(                            ->GetScratchClangASTContext()                            ->GetBasicType(lldb::eBasicTypeWChar)                            .GetByteSize(nullptr); +  if (!wchar_t_size) +    return false;    options.SetData(extractor);    options.SetStream(&stream); @@ -499,7 +586,7 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(    options.SetSourceSize(size);    options.SetBinaryZeroIsTerminator(false); -  switch (wchar_t_size) { +  switch (*wchar_t_size) {    case 1:      StringPrinter::ReadBufferAndDumpToStream<          lldb_private::formatters::StringPrinter::StringElementType::UTF8>( @@ -526,9 +613,10 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(    return true;  } -bool lldb_private::formatters::LibcxxStringSummaryProvider( -    ValueObject &valobj, Stream &stream, -    const TypeSummaryOptions &summary_options) { +template <StringPrinter::StringElementType element_type> +bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, +                                 const TypeSummaryOptions &summary_options, +                                 std::string prefix_token = "") {    uint64_t size = 0;    ValueObjectSP location_sp; @@ -557,31 +645,37 @@ bool lldb_private::formatters::LibcxxStringSummaryProvider(    options.SetData(extractor);    options.SetStream(&stream); -  options.SetPrefixToken(nullptr); + +  if (prefix_token.empty()) +    options.SetPrefixToken(nullptr); +  else +    options.SetPrefixToken(prefix_token); +    options.SetQuote('"');    options.SetSourceSize(size);    options.SetBinaryZeroIsTerminator(false); -  StringPrinter::ReadBufferAndDumpToStream< -      StringPrinter::StringElementType::ASCII>(options); +  StringPrinter::ReadBufferAndDumpToStream<element_type>(options);    return true;  } -class LibcxxFunctionFrontEnd : public SyntheticValueProviderFrontEnd { -public: -  LibcxxFunctionFrontEnd(ValueObject &backend) -      : SyntheticValueProviderFrontEnd(backend) {} +bool lldb_private::formatters::LibcxxStringSummaryProviderASCII( +    ValueObject &valobj, Stream &stream, +    const TypeSummaryOptions &summary_options) { +  return LibcxxStringSummaryProvider<StringPrinter::StringElementType::ASCII>( +      valobj, stream, summary_options); +} -  lldb::ValueObjectSP GetSyntheticValue() override { -    static ConstString g___f_("__f_"); -    return m_backend.GetChildMemberWithName(g___f_, true); -  } -}; +bool lldb_private::formatters::LibcxxStringSummaryProviderUTF16( +    ValueObject &valobj, Stream &stream, +    const TypeSummaryOptions &summary_options) { +  return LibcxxStringSummaryProvider<StringPrinter::StringElementType::UTF16>( +      valobj, stream, summary_options, "u"); +} -SyntheticChildrenFrontEnd * -lldb_private::formatters::LibcxxFunctionFrontEndCreator( -    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { -  if (valobj_sp) -    return new LibcxxFunctionFrontEnd(*valobj_sp); -  return nullptr; +bool lldb_private::formatters::LibcxxStringSummaryProviderUTF32( +    ValueObject &valobj, Stream &stream, +    const TypeSummaryOptions &summary_options) { +  return LibcxxStringSummaryProvider<StringPrinter::StringElementType::UTF32>( +      valobj, stream, summary_options, "U");  }  | 
