diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /lldb/source/Plugins/Language | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'lldb/source/Plugins/Language')
53 files changed, 1150 insertions, 375 deletions
diff --git a/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp index 5cfd978774fd..42f6bd9ffb7b 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp @@ -1,4 +1,4 @@ -//===-- BlockPointer.cpp ----------------------------------------*- C++ -*-===// +//===-- BlockPointer.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,14 +8,14 @@ #include "BlockPointer.h" +#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" +#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangASTImporter.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/Target.h" - #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" @@ -45,18 +45,24 @@ public: if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR( lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS), - std::move(err), "Failed to get scratch ClangASTContext"); + std::move(err), "Failed to get scratch TypeSystemClang"); return; } - ClangASTContext *clang_ast_context = - llvm::dyn_cast<ClangASTContext>(&type_system_or_err.get()); + TypeSystemClang *clang_ast_context = + llvm::dyn_cast<TypeSystemClang>(&type_system_or_err.get()); if (!clang_ast_context) { return; } - ClangASTImporterSP clang_ast_importer = target_sp->GetClangASTImporter(); + std::shared_ptr<ClangASTImporter> clang_ast_importer; + auto *state = target_sp->GetPersistentExpressionStateForLanguage( + lldb::eLanguageTypeC_plus_plus); + if (state) { + auto *persistent_vars = llvm::cast<ClangPersistentVariables>(state); + clang_ast_importer = persistent_vars->GetClangASTImporter(); + } if (!clang_ast_importer) { return; diff --git a/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h b/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h index 624c17a6a6af..23f3f7b34b4f 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h +++ b/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_BlockPointer_h_ -#define liblldb_BlockPointer_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_BLOCKPOINTER_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_BLOCKPOINTER_H #include "lldb/lldb-forward.h" @@ -22,4 +22,4 @@ BlockPointerSyntheticFrontEndCreator(CXXSyntheticChildren *, } // namespace formatters } // namespace lldb_private -#endif // liblldb_BlockPointer_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_BLOCKPOINTER_H diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 4385a60f5862..08e43ae6b3e8 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -1,4 +1,4 @@ -//===-- CPlusPlusLanguage.cpp -----------------------------------*- C++ -*-===// +//===-- CPlusPlusLanguage.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -43,6 +43,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; +LLDB_PLUGIN_DEFINE(CPlusPlusLanguage) + void CPlusPlusLanguage::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), "C++ Language", CreateInstance); @@ -68,7 +70,9 @@ uint32_t CPlusPlusLanguage::GetPluginVersion() { return 1; } // Static Functions Language *CPlusPlusLanguage::CreateInstance(lldb::LanguageType language) { - if (Language::LanguageIsCPlusPlus(language)) + // Use plugin for C++ but not for Objective-C++ (which has its own plugin). + if (Language::LanguageIsCPlusPlus(language) && + language != eLanguageTypeObjC_plus_plus) return new CPlusPlusLanguage(); return nullptr; } @@ -125,7 +129,7 @@ static bool IsTrivialBasename(const llvm::StringRef &basename) { return false; // Empty string or "~" if (!std::isalpha(basename[idx]) && basename[idx] != '_') - return false; // First charater (after removing the possible '~'') isn't in + return false; // First character (after removing the possible '~'') isn't in // [A-Za-z_] // Read all characters matching [A-Za-z_0-9] @@ -230,7 +234,7 @@ std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() { if (!m_parsed) Parse(); if (m_context.empty()) - return m_basename; + return std::string(m_basename); std::string res; res += m_context; @@ -609,6 +613,15 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "shared_ptr synthetic children", ConstString("^(std::__[[:alnum:]]+::)shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true); + + ConstString libcxx_std_unique_ptr_regex( + "^std::__[[:alnum:]]+::unique_ptr<.+>(( )?&)?$"); + AddCXXSynthetic( + cpp_category_sp, + lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator, + "unique_ptr synthetic children", libcxx_std_unique_ptr_regex, + stl_synth_flags, true); + AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, @@ -713,6 +726,10 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "libc++ std::weak_ptr summary provider", ConstString("^std::__[[:alnum:]]+::weak_ptr<.+>(( )?&)?$"), stl_summary_flags, true); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibcxxUniquePointerSummaryProvider, + "libc++ std::unique_ptr summary provider", + libcxx_std_unique_ptr_regex, stl_summary_flags, true); AddCXXSynthetic( cpp_category_sp, diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h index 4ed45bc904ce..89dea08a2c53 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CPlusPlusLanguage_h_ -#define liblldb_CPlusPlusLanguage_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSLANGUAGE_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSLANGUAGE_H #include <set> #include <vector> @@ -133,4 +133,4 @@ public: } // namespace lldb_private -#endif // liblldb_CPlusPlusLanguage_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSLANGUAGE_H diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp index 932db17b964a..eca36fff18f8 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp @@ -1,4 +1,4 @@ -//===-- CPlusPlusNameParser.cpp ---------------------------------*- C++ -*-===// +//===-- CPlusPlusNameParser.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -329,6 +329,37 @@ bool CPlusPlusNameParser::ConsumeOperator() { } const auto &token = Peek(); + + // When clang generates debug info it adds template parameters to names. + // Since clang doesn't add a space between the name and the template parameter + // in some cases we are not generating valid C++ names e.g.: + // + // operator<<A::B> + // + // In some of these cases we will not parse them correctly. This fixes the + // issue by detecting this case and inserting tok::less in place of + // tok::lessless and returning successfully that we consumed the operator. + if (token.getKind() == tok::lessless) { + // Make sure we have more tokens before attempting to look ahead one more. + if (m_next_token_index + 1 < m_tokens.size()) { + // Look ahead two tokens. + clang::Token n_token = m_tokens[m_next_token_index + 1]; + // If we find ( or < then this is indeed operator<< no need for fix. + if (n_token.getKind() != tok::l_paren && n_token.getKind() != tok::less) { + clang::Token tmp_tok; + tmp_tok.startToken(); + tmp_tok.setLength(1); + tmp_tok.setLocation(token.getLocation().getLocWithOffset(1)); + tmp_tok.setKind(tok::less); + + m_tokens[m_next_token_index] = tmp_tok; + + start_position.Remove(); + return true; + } + } + } + switch (token.getKind()) { case tok::kw_new: case tok::kw_delete: diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h index 414c3a009157..6fe6b12725b0 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h @@ -6,9 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CPlusPlusNameParser_h_ -#define liblldb_CPlusPlusNameParser_h_ - +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSNAMEPARSER_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSNAMEPARSER_H #include "clang/Lex/Lexer.h" #include "llvm/ADT/Optional.h" @@ -174,4 +173,4 @@ private: } // namespace lldb_private -#endif // liblldb_CPlusPlusNameParser_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CPLUSPLUSNAMEPARSER_H diff --git a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp index 3ea7589d8e4a..41bbd2b01a1e 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp @@ -1,4 +1,4 @@ -//===-- CxxStringTypes.cpp --------------------------------------*- C++ -*-===// +//===-- CxxStringTypes.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,13 +10,13 @@ #include "llvm/Support/ConvertUTF.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/Host/Time.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/ProcessStructReader.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" diff --git a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h index 35498b3b568f..2713ded45929 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h +++ b/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CxxStringTypes_h_ -#define liblldb_CxxStringTypes_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CXXSTRINGTYPES_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CXXSTRINGTYPES_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -46,4 +46,4 @@ bool WCharSummaryProvider(ValueObject &valobj, Stream &stream, } // namespace formatters } // namespace lldb_private -#endif // liblldb_CxxStringTypes_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_CXXSTRINGTYPES_H diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index ecadaef7a87e..84dd09a47d8a 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -1,4 +1,4 @@ -//===-- LibCxx.cpp ----------------------------------------------*- C++ -*-===// +//===-- LibCxx.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,7 +8,6 @@ #include "LibCxx.h" -#include "llvm/ADT/ScopeExit.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/FormatEntity.h" #include "lldb/Core/ValueObject.h" @@ -17,7 +16,6 @@ #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/DataFormatters/VectorIterator.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/ProcessStructReader.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" @@ -27,6 +25,7 @@ #include "lldb/Utility/Stream.h" #include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" using namespace lldb; using namespace lldb_private; @@ -145,6 +144,43 @@ bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider( return true; } +bool lldb_private::formatters::LibcxxUniquePointerSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); + if (!valobj_sp) + return false; + + ValueObjectSP ptr_sp( + valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true)); + if (!ptr_sp) + return false; + + ptr_sp = GetValueOfLibCXXCompressedPair(*ptr_sp); + if (!ptr_sp) + return false; + + if (ptr_sp->GetValueAsUnsigned(0) == 0) { + stream.Printf("nullptr"); + return true; + } else { + bool print_pointee = false; + Status error; + ValueObjectSP pointee_sp = ptr_sp->Dereference(error); + if (pointee_sp && error.Success()) { + if (pointee_sp->DumpPrintableRepresentation( + stream, ValueObject::eValueObjectRepresentationStyleSummary, + lldb::eFormatInvalid, + ValueObject::PrintableRepresentationSpecialCases::eDisable, + false)) + print_pointee = true; + } + if (!print_pointee) + stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0)); + } + + return true; +} + /* (lldb) fr var ibeg --raw --ptr-depth 1 (std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::pair<int, @@ -241,8 +277,8 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() { 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()); + TypeSystemClang *ast_ctx = + llvm::dyn_cast_or_null<TypeSystemClang>(pair_type.GetTypeSystem()); if (!ast_ctx) return false; CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( @@ -450,6 +486,67 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator( : nullptr); } +lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: + LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) + : SyntheticChildrenFrontEnd(*valobj_sp), m_compressed_pair_sp() { + if (valobj_sp) + Update(); +} + +lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: + ~LibcxxUniquePtrSyntheticFrontEnd() = default; + +SyntheticChildrenFrontEnd * +lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator( + CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { + return (valobj_sp ? new LibcxxUniquePtrSyntheticFrontEnd(valobj_sp) + : nullptr); +} + +size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: + CalculateNumChildren() { + return (m_compressed_pair_sp ? 1 : 0); +} + +lldb::ValueObjectSP +lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::GetChildAtIndex( + size_t idx) { + if (!m_compressed_pair_sp) + return lldb::ValueObjectSP(); + + if (idx != 0) + return lldb::ValueObjectSP(); + + return m_compressed_pair_sp; +} + +bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() { + ValueObjectSP valobj_sp = m_backend.GetSP(); + if (!valobj_sp) + return false; + + ValueObjectSP ptr_sp( + valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true)); + if (!ptr_sp) + return false; + + m_compressed_pair_sp = GetValueOfLibCXXCompressedPair(*ptr_sp); + + return false; +} + +bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: + MightHaveChildren() { + return true; +} + +size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: + GetIndexOfChildWithName(ConstString name) { + if (name == "__value_") + return 0; + return UINT32_MAX; +} + bool lldb_private::formatters::LibcxxContainerSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { if (valobj.IsPointerType()) { @@ -469,22 +566,20 @@ enum LibcxxStringLayoutMode { eLibcxxStringLayoutModeInvalid = 0xffff }; -// this function abstracts away the layout and mode details of a libc++ string -// and returns the address of the data and the size ready for callers to -// consume -static bool ExtractLibcxxStringInfo(ValueObject &valobj, - ValueObjectSP &location_sp, - uint64_t &size) { +/// Determine the size in bytes of \p valobj (a libc++ std::string object) and +/// extract its data payload. Return the size + payload pair. +static llvm::Optional<std::pair<uint64_t, ValueObjectSP>> +ExtractLibcxxStringInfo(ValueObject &valobj) { ValueObjectSP D(valobj.GetChildAtIndexPath({0, 0, 0, 0})); if (!D) - return false; + return {}; ValueObjectSP layout_decider( D->GetChildAtIndexPath(llvm::ArrayRef<size_t>({0, 0}))); // this child should exist if (!layout_decider) - return false; + return {}; ConstString g_data_name("__data_"); ConstString g_size_name("__size_"); @@ -498,13 +593,13 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, if (layout == eLibcxxStringLayoutModeDSC) { ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 1, 0})); if (!size_mode) - return false; + return {}; if (size_mode->GetName() != g_size_name) { // we are hitting the padding structure, move along size_mode = D->GetChildAtIndexPath({1, 1, 1}); if (!size_mode) - return false; + return {}; } size_mode_value = (size_mode->GetValueAsUnsigned(0)); @@ -512,7 +607,7 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, } else { ValueObjectSP size_mode(D->GetChildAtIndexPath({1, 0, 0})); if (!size_mode) - return false; + return {}; size_mode_value = (size_mode->GetValueAsUnsigned(0)); short_mode = ((size_mode_value & 1) == 0); @@ -521,36 +616,58 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, if (short_mode) { ValueObjectSP s(D->GetChildAtIndex(1, true)); if (!s) - return false; - location_sp = s->GetChildAtIndex( + return {}; + ValueObjectSP location_sp = s->GetChildAtIndex( (layout == eLibcxxStringLayoutModeDSC) ? 0 : 1, true); - size = (layout == eLibcxxStringLayoutModeDSC) - ? size_mode_value - : ((size_mode_value >> 1) % 256); - return (location_sp.get() != nullptr); - } else { - ValueObjectSP l(D->GetChildAtIndex(0, true)); - if (!l) - return false; - // we can use the layout_decider object as the data pointer - location_sp = (layout == eLibcxxStringLayoutModeDSC) - ? layout_decider - : l->GetChildAtIndex(2, true); - ValueObjectSP size_vo(l->GetChildAtIndex(1, true)); - if (!size_vo || !location_sp) - return false; - size = size_vo->GetValueAsUnsigned(0); - return true; + const uint64_t size = (layout == eLibcxxStringLayoutModeDSC) + ? size_mode_value + : ((size_mode_value >> 1) % 256); + + // When the small-string optimization takes place, the data must fit in the + // inline string buffer (23 bytes on x86_64/Darwin). If it doesn't, it's + // likely that the string isn't initialized and we're reading garbage. + ExecutionContext exe_ctx(location_sp->GetExecutionContextRef()); + const llvm::Optional<uint64_t> max_bytes = + location_sp->GetCompilerType().GetByteSize( + exe_ctx.GetBestExecutionContextScope()); + if (!max_bytes || size > *max_bytes || !location_sp) + return {}; + + return std::make_pair(size, location_sp); } + + ValueObjectSP l(D->GetChildAtIndex(0, true)); + if (!l) + return {}; + // we can use the layout_decider object as the data pointer + ValueObjectSP location_sp = (layout == eLibcxxStringLayoutModeDSC) + ? layout_decider + : l->GetChildAtIndex(2, true); + ValueObjectSP size_vo(l->GetChildAtIndex(1, true)); + const unsigned capacity_index = + (layout == eLibcxxStringLayoutModeDSC) ? 2 : 0; + ValueObjectSP capacity_vo(l->GetChildAtIndex(capacity_index, true)); + if (!size_vo || !location_sp || !capacity_vo) + return {}; + const uint64_t size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); + const uint64_t capacity = + capacity_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); + if (size == LLDB_INVALID_OFFSET || capacity == LLDB_INVALID_OFFSET || + capacity < size) + return {}; + return std::make_pair(size, location_sp); } bool lldb_private::formatters::LibcxxWStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options) { - uint64_t size = 0; - ValueObjectSP location_sp; - if (!ExtractLibcxxStringInfo(valobj, location_sp, size)) + auto string_info = ExtractLibcxxStringInfo(valobj); + if (!string_info) return false; + uint64_t size; + ValueObjectSP location_sp; + std::tie(size, location_sp) = *string_info; + if (size == 0) { stream.Printf("L\"\""); return true; @@ -558,10 +675,8 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( if (!location_sp) return false; - DataExtractor extractor; StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); - if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) { const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary(); if (size > max_size) { @@ -569,11 +684,15 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( options.SetIsTruncated(true); } } - location_sp->GetPointeeData(extractor, 0, size); + + DataExtractor extractor; + const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size); + if (bytes_read < size) + return false; // std::wstring::size() is measured in 'characters', not bytes - ClangASTContext *ast_context = - ClangASTContext::GetScratch(*valobj.GetTargetSP()); + TypeSystemClang *ast_context = + TypeSystemClang::GetScratch(*valobj.GetTargetSP()); if (!ast_context) return false; @@ -591,40 +710,35 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( switch (*wchar_t_size) { case 1: - StringPrinter::ReadBufferAndDumpToStream< + return StringPrinter::ReadBufferAndDumpToStream< lldb_private::formatters::StringPrinter::StringElementType::UTF8>( options); break; case 2: - lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream< + return StringPrinter::ReadBufferAndDumpToStream< lldb_private::formatters::StringPrinter::StringElementType::UTF16>( options); break; case 4: - lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream< + return StringPrinter::ReadBufferAndDumpToStream< lldb_private::formatters::StringPrinter::StringElementType::UTF32>( options); - break; - - default: - stream.Printf("size for wchar_t is not valid"); - return true; } - - return true; + return false; } 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; - - if (!ExtractLibcxxStringInfo(valobj, location_sp, size)) + std::string prefix_token) { + auto string_info = ExtractLibcxxStringInfo(valobj); + if (!string_info) return false; + uint64_t size; + ValueObjectSP location_sp; + std::tie(size, location_sp) = *string_info; if (size == 0) { stream.Printf("\"\""); @@ -636,7 +750,6 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); - DataExtractor extractor; if (summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryCapped) { const auto max_size = valobj.GetTargetSP()->GetMaximumSizeOfStringSummary(); if (size > max_size) { @@ -644,41 +757,55 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, options.SetIsTruncated(true); } } - location_sp->GetPointeeData(extractor, 0, size); + + DataExtractor extractor; + const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size); + if (bytes_read < size) + return false; options.SetData(extractor); options.SetStream(&stream); - if (prefix_token.empty()) options.SetPrefixToken(nullptr); else options.SetPrefixToken(prefix_token); - options.SetQuote('"'); options.SetSourceSize(size); options.SetBinaryZeroIsTerminator(false); - StringPrinter::ReadBufferAndDumpToStream<element_type>(options); + return StringPrinter::ReadBufferAndDumpToStream<element_type>(options); +} +template <StringPrinter::StringElementType element_type> +static bool formatStringImpl(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &summary_options, + std::string prefix_token) { + StreamString scratch_stream; + const bool success = LibcxxStringSummaryProvider<element_type>( + valobj, scratch_stream, summary_options, prefix_token); + if (success) + stream << scratch_stream.GetData(); + else + stream << "Summary Unavailable"; return true; } bool lldb_private::formatters::LibcxxStringSummaryProviderASCII( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options) { - return LibcxxStringSummaryProvider<StringPrinter::StringElementType::ASCII>( - valobj, stream, summary_options); + return formatStringImpl<StringPrinter::StringElementType::ASCII>( + valobj, stream, summary_options, ""); } bool lldb_private::formatters::LibcxxStringSummaryProviderUTF16( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options) { - return LibcxxStringSummaryProvider<StringPrinter::StringElementType::UTF16>( + return formatStringImpl<StringPrinter::StringElementType::UTF16>( valobj, stream, summary_options, "u"); } bool lldb_private::formatters::LibcxxStringSummaryProviderUTF32( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options) { - return LibcxxStringSummaryProvider<StringPrinter::StringElementType::UTF32>( + return formatStringImpl<StringPrinter::StringElementType::UTF32>( valobj, stream, summary_options, "U"); } diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h index 214f5512e4a5..ea5a7c178178 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LibCxx_h_ -#define liblldb_LibCxx_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXX_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXX_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -43,6 +43,10 @@ bool LibcxxSmartPointerSummaryProvider( const TypeSummaryOptions &options); // libc++ std::shared_ptr<> and std::weak_ptr<> +// libc++ std::unique_ptr<> +bool LibcxxUniquePointerSummaryProvider(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); + bool LibcxxFunctionSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); // libc++ std::function<> @@ -107,6 +111,26 @@ private: lldb::ByteOrder m_byte_order; }; +class LibcxxUniquePtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: + LibcxxUniquePtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + + size_t CalculateNumChildren() override; + + lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + + bool Update() override; + + bool MightHaveChildren() override; + + size_t GetIndexOfChildWithName(ConstString name) override; + + ~LibcxxUniquePtrSyntheticFrontEnd() override; + +private: + lldb::ValueObjectSP m_compressed_pair_sp; +}; + SyntheticChildrenFrontEnd * LibcxxBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); @@ -116,6 +140,10 @@ LibcxxSharedPtrSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); SyntheticChildrenFrontEnd * +LibcxxUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *, + lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd * LibcxxStdVectorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); @@ -156,4 +184,4 @@ LibcxxVariantFrontEndCreator(CXXSyntheticChildren *, } // namespace formatters } // namespace lldb_private -#endif // liblldb_LibCxx_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXX_H diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp index b4e7a1703e46..45d4322e93d7 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp @@ -1,5 +1,4 @@ -//===-- LibCxxAtomic.cpp ------------------------------------------*- C++ -//-*-===// +//===-- LibCxxAtomic.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "LibCxxAtomic.h" +#include "lldb/DataFormatters/FormattersHelpers.h" using namespace lldb; using namespace lldb_private; @@ -101,8 +101,6 @@ public: size_t GetIndexOfChildWithName(ConstString name) override; - lldb::ValueObjectSP GetSyntheticValue() override; - private: ValueObject *m_real_child; }; @@ -128,26 +126,20 @@ bool lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: CalculateNumChildren() { - return m_real_child ? m_real_child->GetNumChildren() : 0; + return m_real_child ? 1 : 0; } lldb::ValueObjectSP lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetChildAtIndex( size_t idx) { - return m_real_child ? m_real_child->GetChildAtIndex(idx, true) : nullptr; + if (idx == 0) + return m_real_child->GetSP()->Clone(ConstString("Value")); + return nullptr; } size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: GetIndexOfChildWithName(ConstString name) { - return m_real_child ? m_real_child->GetIndexOfChildWithName(name) - : UINT32_MAX; -} - -lldb::ValueObjectSP lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: - GetSyntheticValue() { - if (m_real_child && m_real_child->CanProvideValue()) - return m_real_child->GetSP(); - return nullptr; + return formatters::ExtractIndexFromString(name.GetCString()); } SyntheticChildrenFrontEnd * diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h index 8be833dd82f6..6fcceb645c7b 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LibCxxAtomic_h_ -#define liblldb_LibCxxAtomic_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXATOMIC_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXATOMIC_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -30,4 +30,4 @@ LibcxxAtomicSyntheticFrontEndCreator(CXXSyntheticChildren *, } // namespace formatters } // namespace lldb_private -#endif // liblldb_LibCxxAtomic_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXATOMIC_H diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp index 78c453cd1b3c..6de4637a6a4a 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxBitset.cpp ----------------------------------------*- C++ -*-===// +//===-- LibCxxBitset.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "LibCxx.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Target.h" using namespace lldb; diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp index 79c7434f617f..65e88d114fcc 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxInitializerList.cpp -------------------------------*- C++ -*-===// +//===-- LibCxxInitializerList.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp index f5281f2ce532..0d5ae16a0b29 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxList.cpp ------------------------------------------*- C++ -*-===// +//===-- LibCxxList.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,10 +8,10 @@ #include "LibCxx.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" @@ -290,15 +290,6 @@ ValueObjectSP ForwardListFrontEnd::GetChildAtIndex(size_t idx) { m_element_type); } -static ValueObjectSP GetValueOfCompressedPair(ValueObject &pair) { - ValueObjectSP value = pair.GetChildMemberWithName(ConstString("__value_"), true); - if (! value) { - // pre-r300140 member name - value = pair.GetChildMemberWithName(ConstString("__first_"), true); - } - return value; -} - bool ForwardListFrontEnd::Update() { AbstractListFrontEnd::Update(); @@ -311,7 +302,7 @@ bool ForwardListFrontEnd::Update() { m_backend.GetChildMemberWithName(ConstString("__before_begin_"), true)); if (!impl_sp) return false; - impl_sp = GetValueOfCompressedPair(*impl_sp); + impl_sp = GetValueOfLibCXXCompressedPair(*impl_sp); if (!impl_sp) return false; m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get(); @@ -332,7 +323,7 @@ size_t ListFrontEnd::CalculateNumChildren() { ValueObjectSP size_alloc( m_backend.GetChildMemberWithName(ConstString("__size_alloc_"), true)); if (size_alloc) { - ValueObjectSP value = GetValueOfCompressedPair(*size_alloc); + ValueObjectSP value = GetValueOfLibCXXCompressedPair(*size_alloc); if (value) { m_count = value->GetValueAsUnsigned(UINT32_MAX); } diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index f6d8d4d9a7eb..64a199e24e4a 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxMap.cpp -------------------------------------------*- C++ -*-===// +//===-- LibCxxMap.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,10 +8,10 @@ #include "LibCxx.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" @@ -298,8 +298,8 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( UINT32_MAX) { m_skip_size = bit_offset / 8u; } else { - ClangASTContext *ast_ctx = - llvm::dyn_cast_or_null<ClangASTContext>(node_type.GetTypeSystem()); + TypeSystemClang *ast_ctx = + llvm::dyn_cast_or_null<TypeSystemClang>(node_type.GetTypeSystem()); if (!ast_ctx) return; CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp index b1ad171d0b0c..c0c819632851 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxOptional.cpp --------------------------------------*- C++ -*-===// +//===-- LibCxxOptional.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -26,11 +26,12 @@ public: bool MightHaveChildren() override { return true; } bool Update() override; - size_t CalculateNumChildren() override { return m_size; } + size_t CalculateNumChildren() override { return m_has_value ? 1U : 0U; } ValueObjectSP GetChildAtIndex(size_t idx) override; private: - size_t m_size = 0; + /// True iff the option contains a value. + bool m_has_value = false; }; } // namespace @@ -44,13 +45,13 @@ bool OptionalFrontEnd::Update() { // __engaged_ is a bool flag and is true if the optional contains a value. // Converting it to unsigned gives us a size of 1 if it contains a value // and 0 if not. - m_size = engaged_sp->GetValueAsUnsigned(0); + m_has_value = engaged_sp->GetValueAsUnsigned(0) == 1; return false; } ValueObjectSP OptionalFrontEnd::GetChildAtIndex(size_t idx) { - if (idx >= m_size) + if (!m_has_value) return ValueObjectSP(); // __val_ contains the underlying value of an optional if it has one. @@ -71,7 +72,7 @@ ValueObjectSP OptionalFrontEnd::GetChildAtIndex(size_t idx) { if (!holder_type) return ValueObjectSP(); - return val_sp->Clone(ConstString(llvm::formatv("Value").str())); + return val_sp->Clone(ConstString("Value")); } SyntheticChildrenFrontEnd * diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp index 2f06d684f953..616ffdca107d 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxQueue.cpp -----------------------------------------*- C++ -*-===// +//===-- LibCxxQueue.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp index 45294e25f0f5..a113fe98c6b6 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxTuple.cpp -----------------------------------------*- C++ -*-===// +//===-- LibCxxTuple.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp index b2c38c915c81..3a441973fc73 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxUnorderedMap.cpp ----------------------------------*- C++ -*-===// +//===-- LibCxxUnorderedMap.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,10 +8,10 @@ #include "LibCxx.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp index 62945bd3ce80..951bf2896fb0 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxVariant.cpp --------------------------------------*- C++ -*-===// +//===-- LibCxxVariant.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -60,10 +60,10 @@ using namespace lldb_private; namespace { // libc++ std::variant index could have one of three states -// 1) VALID, we can obtain it and its not variant_npos -// 2) INVALID, we can't obtain it or it is not a type we expect -// 3) NPOS, its value is variant_npos which means the variant has no value -enum class LibcxxVariantIndexValidity { VALID, INVALID, NPOS }; +// 1) Valid, we can obtain it and its not variant_npos +// 2) Invalid, we can't obtain it or it is not a type we expect +// 3) NPos, its value is variant_npos which means the variant has no value +enum class LibcxxVariantIndexValidity { Valid, Invalid, NPos }; LibcxxVariantIndexValidity LibcxxVariantGetIndexValidity(ValueObjectSP &impl_sp) { @@ -71,14 +71,14 @@ LibcxxVariantGetIndexValidity(ValueObjectSP &impl_sp) { impl_sp->GetChildMemberWithName(ConstString("__index"), true)); if (!index_sp) - return LibcxxVariantIndexValidity::INVALID; + return LibcxxVariantIndexValidity::Invalid; int64_t index_value = index_sp->GetValueAsSigned(0); if (index_value == -1) - return LibcxxVariantIndexValidity::NPOS; + return LibcxxVariantIndexValidity::NPos; - return LibcxxVariantIndexValidity::VALID; + return LibcxxVariantIndexValidity::Valid; } llvm::Optional<uint64_t> LibcxxVariantIndexValue(ValueObjectSP &impl_sp) { @@ -129,10 +129,10 @@ bool LibcxxVariantSummaryProvider(ValueObject &valobj, Stream &stream, LibcxxVariantIndexValidity validity = LibcxxVariantGetIndexValidity(impl_sp); - if (validity == LibcxxVariantIndexValidity::INVALID) + if (validity == LibcxxVariantIndexValidity::Invalid) return false; - if (validity == LibcxxVariantIndexValidity::NPOS) { + if (validity == LibcxxVariantIndexValidity::NPos) { stream.Printf(" No Value"); return true; } @@ -159,7 +159,7 @@ bool LibcxxVariantSummaryProvider(ValueObject &valobj, Stream &stream, if (!template_type) return false; - stream.Printf(" Active Type = %s ", template_type.GetTypeName().GetCString()); + stream << " Active Type = " << template_type.GetDisplayTypeName() << " "; return true; } @@ -196,10 +196,10 @@ bool VariantFrontEnd::Update() { LibcxxVariantIndexValidity validity = LibcxxVariantGetIndexValidity(impl_sp); - if (validity == LibcxxVariantIndexValidity::INVALID) + if (validity == LibcxxVariantIndexValidity::Invalid) return false; - if (validity == LibcxxVariantIndexValidity::NPOS) + if (validity == LibcxxVariantIndexValidity::NPos) return true; m_size = 1; @@ -242,7 +242,7 @@ ValueObjectSP VariantFrontEnd::GetChildAtIndex(size_t idx) { if (!head_value) return ValueObjectSP(); - return head_value->Clone(ConstString(ConstString("Value").AsCString())); + return head_value->Clone(ConstString("Value")); } SyntheticChildrenFrontEnd * diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h index 65db5aeaa99d..b4c27ccb9d77 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LibCxxVariant_h_ -#define liblldb_LibCxxVariant_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXVARIANT_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXVARIANT_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -27,4 +27,4 @@ SyntheticChildrenFrontEnd *LibcxxVariantFrontEndCreator(CXXSyntheticChildren *, } // namespace formatters } // namespace lldb_private -#endif // liblldb_LibCxxVariant_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBCXXVARIANT_H diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp index bcd7442bc669..43f76b0df810 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxVector.cpp ----------------------------------------*- C++ -*-===// +//===-- LibCxxVector.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index 0e0f6663c924..b4af67ecee0d 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -1,4 +1,4 @@ -//===-- LibStdcpp.cpp -------------------------------------------*- C++ -*-===// +//===-- LibStdcpp.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,11 +8,11 @@ #include "LibStdcpp.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/VectorIterator.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" @@ -259,6 +259,7 @@ bool lldb_private::formatters::LibStdcppStringSummaryProvider( if (error.Fail()) return false; options.SetSourceSize(size_of_data); + options.SetHasSourceSize(true); if (!StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF8>(options)) { @@ -319,6 +320,7 @@ bool lldb_private::formatters::LibStdcppWStringSummaryProvider( if (error.Fail()) return false; options.SetSourceSize(size_of_data); + options.SetHasSourceSize(true); options.SetPrefixToken("L"); switch (wchar_size) { diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h index e7f88d667c14..9e41aa0ffc01 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_LibStdCpp_h_ -#define liblldb_LibStdCpp_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBSTDCPP_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBSTDCPP_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -56,4 +56,4 @@ LibStdcppUniquePtrSyntheticFrontEndCreator(CXXSyntheticChildren *, } // namespace formatters } // namespace lldb_private -#endif // liblldb_LibStdCpp_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_LIBSTDCPP_H diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp index 0ac7b8f8e02b..7ba59ff9d1ad 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp @@ -1,4 +1,4 @@ -//===-- LibStdcppTuple.cpp --------------------------------------*- C++ -*-===// +//===-- LibStdcppTuple.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp index cceb511cdc46..0b34b4e2fc89 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp @@ -1,4 +1,4 @@ -//===-- LibStdcppUniquePointer.cpp ------------------------------*- C++ -*-===// +//===-- LibStdcppUniquePointer.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp b/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp index 248c51acea42..b24bcc1344e2 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp @@ -1,4 +1,4 @@ -//===-- MSVCUndecoratedNameParser.cpp ---------------------------*- C++ -*-===// +//===-- MSVCUndecoratedNameParser.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h b/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h index 6e20877cae1b..e5b60a0a1d5b 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h +++ b/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_MSVCUndecoratedNameParser_h_ -#define liblldb_MSVCUndecoratedNameParser_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_MSVCUNDECORATEDNAMEPARSER_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CPLUSPLUS_MSVCUNDECORATEDNAMEPARSER_H #include <vector> diff --git a/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp b/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp index 3e77b1646739..aaf578c6f728 100644 --- a/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp +++ b/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp @@ -1,4 +1,4 @@ -//===-- ClangHighlighter.cpp ------------------------------------*- C++ -*-===// +//===-- ClangHighlighter.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,6 +13,7 @@ #include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/StreamString.h" +#include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" #include "llvm/ADT/StringSet.h" diff --git a/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h b/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h index f459f9424697..5257c728ca5c 100644 --- a/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h +++ b/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ClangHighlighter_h_ -#define liblldb_ClangHighlighter_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_CLANGCOMMON_CLANGHIGHLIGHTER_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_CLANGCOMMON_CLANGHIGHLIGHTER_H #include "lldb/Utility/Stream.h" #include "llvm/ADT/StringSet.h" @@ -34,4 +34,4 @@ public: } // namespace lldb_private -#endif // liblldb_ClangHighlighter_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_CLANGCOMMON_CLANGHIGHLIGHTER_H diff --git a/lldb/source/Plugins/Language/ObjC/CF.cpp b/lldb/source/Plugins/Language/ObjC/CF.cpp index 5bca260616ea..2610468b17fd 100644 --- a/lldb/source/Plugins/Language/ObjC/CF.cpp +++ b/lldb/source/Plugins/Language/ObjC/CF.cpp @@ -1,5 +1,4 @@ -//===-- CF.cpp ----------------------------------------------------*- C++ -//-*-===// +//===-- CF.cpp ------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,10 +8,10 @@ #include "CF.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" @@ -30,7 +29,7 @@ using namespace lldb_private::formatters; bool lldb_private::formatters::CFAbsoluteTimeSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { time_t epoch = GetOSXEpoch(); - epoch = epoch + (time_t)valobj.GetValueAsUnsigned(0); + epoch = epoch + (time_t)valobj.GetValueAsSigned(0); tm *tm_date = localtime(&epoch); if (!tm_date) return false; diff --git a/lldb/source/Plugins/Language/ObjC/CF.h b/lldb/source/Plugins/Language/ObjC/CF.h index 2abb56d407eb..6165e1c235bc 100644 --- a/lldb/source/Plugins/Language/ObjC/CF.h +++ b/lldb/source/Plugins/Language/ObjC/CF.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CF_h_ -#define liblldb_CF_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CF_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CF_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -29,4 +29,4 @@ bool CFAbsoluteTimeSummaryProvider(ValueObject &valobj, Stream &stream, } // namespace formatters } // namespace lldb_private -#endif // liblldb_CF_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CF_H diff --git a/lldb/source/Plugins/Language/ObjC/CFBasicHash.cpp b/lldb/source/Plugins/Language/ObjC/CFBasicHash.cpp new file mode 100644 index 000000000000..42cda0146f2e --- /dev/null +++ b/lldb/source/Plugins/Language/ObjC/CFBasicHash.cpp @@ -0,0 +1,114 @@ +#include "CFBasicHash.h" + +#include "lldb/Utility/Endian.h" + +using namespace lldb; +using namespace lldb_private; + +bool CFBasicHash::IsValid() const { + if (m_address != LLDB_INVALID_ADDRESS) { + if (m_ptr_size == 4 && m_ht_32) + return true; + else if (m_ptr_size == 8 && m_ht_64) + return true; + else + return false; + } + return false; +} + +bool CFBasicHash::Update(addr_t addr, ExecutionContextRef exe_ctx_rf) { + if (addr == LLDB_INVALID_ADDRESS || !addr) + return false; + + m_address = addr; + m_exe_ctx_ref = exe_ctx_rf; + m_ptr_size = + m_exe_ctx_ref.GetTargetSP()->GetArchitecture().GetAddressByteSize(); + m_byte_order = m_exe_ctx_ref.GetTargetSP()->GetArchitecture().GetByteOrder(); + + if (m_ptr_size == 4) + return UpdateFor(m_ht_32); + else if (m_ptr_size == 8) + return UpdateFor(m_ht_64); + return false; + + llvm_unreachable( + "Unsupported architecture. Only 32bits and 64bits supported."); +} + +template <typename T> +bool CFBasicHash::UpdateFor(std::unique_ptr<__CFBasicHash<T>> &m_ht) { + if (m_byte_order != endian::InlHostByteOrder()) + return false; + + Status error; + Target *target = m_exe_ctx_ref.GetTargetSP().get(); + addr_t addr = m_address.GetLoadAddress(target); + size_t size = sizeof(typename __CFBasicHash<T>::RuntimeBase) + + sizeof(typename __CFBasicHash<T>::Bits); + + m_ht = std::make_unique<__CFBasicHash<T>>(); + m_exe_ctx_ref.GetProcessSP()->ReadMemory(addr, m_ht.get(), + size, error); + if (error.Fail()) + return false; + + m_mutable = !(m_ht->base.cfinfoa & (1 << 6)); + m_multi = m_ht->bits.counts_offset; + m_type = static_cast<HashType>(m_ht->bits.keys_offset); + addr_t ptr_offset = addr + size; + size_t ptr_count = GetPointerCount(); + size = ptr_count * sizeof(T); + + m_exe_ctx_ref.GetProcessSP()->ReadMemory(ptr_offset, m_ht->pointers, size, + error); + + if (error.Fail()) { + m_ht = nullptr; + return false; + } + + return true; +} + +size_t CFBasicHash::GetCount() const { + if (!IsValid()) + return 0; + + if (!m_multi) + return (m_ptr_size == 4) ? m_ht_32->bits.used_buckets + : m_ht_64->bits.used_buckets; + + // FIXME: Add support for multi + return 0; +} + +size_t CFBasicHash::GetPointerCount() const { + if (!IsValid()) + return 0; + + if (m_multi) + return 3; // Bits::counts_offset; + return (m_type == HashType::dict) + 1; +} + +addr_t CFBasicHash::GetKeyPointer() const { + if (!IsValid()) + return LLDB_INVALID_ADDRESS; + + if (m_ptr_size == 4) + return m_ht_32->pointers[m_ht_32->bits.keys_offset]; + + return m_ht_64->pointers[m_ht_64->bits.keys_offset]; +} + +addr_t CFBasicHash::GetValuePointer() const { + if (!IsValid()) + return LLDB_INVALID_ADDRESS; + + if (m_ptr_size == 4) + return m_ht_32->pointers[0]; + + return m_ht_64->pointers[0]; +} diff --git a/lldb/source/Plugins/Language/ObjC/CFBasicHash.h b/lldb/source/Plugins/Language/ObjC/CFBasicHash.h new file mode 100644 index 000000000000..fd30f5f7845f --- /dev/null +++ b/lldb/source/Plugins/Language/ObjC/CFBasicHash.h @@ -0,0 +1,76 @@ +//===-- CFBasicHash.h -------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CFBASICHASH_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CFBASICHASH_H + +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" + +namespace lldb_private { + +class CFBasicHash { +public: + enum class HashType { set = 0, dict }; + + CFBasicHash() = default; + ~CFBasicHash() = default; + + bool Update(lldb::addr_t addr, ExecutionContextRef exe_ctx_rf); + + bool IsValid() const; + + bool IsMutable() const { return m_mutable; }; + bool IsMultiVariant() const { return m_multi; } + HashType GetType() const { return m_type; } + + size_t GetCount() const; + lldb::addr_t GetKeyPointer() const; + lldb::addr_t GetValuePointer() const; + +private: + template <typename T> struct __CFBasicHash { + struct RuntimeBase { + T cfisa; + T cfinfoa; + } base; + + struct Bits { + uint16_t __reserved0; + uint16_t __reserved1 : 2; + uint16_t keys_offset : 1; + uint16_t counts_offset : 2; + uint16_t counts_width : 2; + uint16_t __reserved2 : 9; + uint32_t used_buckets; // number of used buckets + uint64_t deleted : 16; // number of elements deleted + uint64_t num_buckets_idx : 8; // index to number of buckets + uint64_t __reserved3 : 40; + uint64_t __reserved4; + } bits; + + T pointers[3]; + }; + template <typename T> bool UpdateFor(std::unique_ptr<__CFBasicHash<T>> &m_ht); + + size_t GetPointerCount() const; + + uint32_t m_ptr_size = UINT32_MAX; + lldb::ByteOrder m_byte_order = lldb::eByteOrderInvalid; + Address m_address = LLDB_INVALID_ADDRESS; + std::unique_ptr<__CFBasicHash<uint32_t>> m_ht_32 = nullptr; + std::unique_ptr<__CFBasicHash<uint64_t>> m_ht_64 = nullptr; + ExecutionContextRef m_exe_ctx_ref; + bool m_mutable = true; + bool m_multi = false; + HashType m_type; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_CFBASICHASH_H diff --git a/lldb/source/Plugins/Language/ObjC/Cocoa.cpp b/lldb/source/Plugins/Language/ObjC/Cocoa.cpp index 8a81abbaedbe..648fc4adf24f 100644 --- a/lldb/source/Plugins/Language/ObjC/Cocoa.cpp +++ b/lldb/source/Plugins/Language/ObjC/Cocoa.cpp @@ -1,4 +1,4 @@ -//===-- Cocoa.cpp -----------------------------------------------*- C++ -*-===// +//===-- Cocoa.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,6 +8,7 @@ #include "Cocoa.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" @@ -15,7 +16,6 @@ #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/Host/Time.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/Process.h" #include "lldb/Target/ProcessStructReader.h" @@ -818,13 +818,14 @@ bool lldb_private::formatters::NSDateSummaryProvider( static const ConstString g___NSDate("__NSDate"); static const ConstString g___NSTaggedDate("__NSTaggedDate"); static const ConstString g_NSCalendarDate("NSCalendarDate"); + static const ConstString g_NSConstantDate("NSConstantDate"); if (class_name.IsEmpty()) return false; uint64_t info_bits = 0, value_bits = 0; if ((class_name == g_NSDate) || (class_name == g___NSDate) || - (class_name == g___NSTaggedDate)) { + (class_name == g___NSTaggedDate) || (class_name == g_NSConstantDate)) { if (descriptor->GetTaggedPointerInfo(&info_bits, &value_bits)) { date_value_bits = ((value_bits << 8) | (info_bits << 4)); memcpy(&date_value, &date_value_bits, sizeof(date_value_bits)); @@ -850,8 +851,14 @@ bool lldb_private::formatters::NSDateSummaryProvider( } else return false; - if (date_value == -63114076800) { - stream.Printf("0001-12-30 00:00:00 +0000"); + // FIXME: It seems old dates are not formatted according to NSDate's calendar + // so we hardcode distantPast's value so that it looks like LLDB is doing + // the right thing. + + // The relative time in seconds from Cocoa Epoch to [NSDate distantPast]. + const double RelSecondsFromCocoaEpochToNSDateDistantPast = -63114076800; + if (date_value == RelSecondsFromCocoaEpochToNSDateDistantPast) { + stream.Printf("0001-01-01 00:00:00 UTC"); return true; } @@ -867,7 +874,7 @@ bool lldb_private::formatters::NSDateSummaryProvider( // is generally true and POSIXly happy, but might break if a library vendor // decides to get creative time_t epoch = GetOSXEpoch(); - epoch = epoch + (time_t)date_value; + epoch = epoch + static_cast<time_t>(std::floor(date_value)); tm *tm_date = gmtime(&epoch); if (!tm_date) return false; @@ -902,8 +909,7 @@ bool lldb_private::formatters::ObjCClassSummaryProvider( if (class_name.IsEmpty()) return false; - if (ConstString cs = - Mangled(class_name).GetDemangledName(lldb::eLanguageTypeUnknown)) + if (ConstString cs = Mangled(class_name).GetDemangledName()) class_name = cs; stream.Printf("%s", class_name.AsCString("<unknown class>")); diff --git a/lldb/source/Plugins/Language/ObjC/Cocoa.h b/lldb/source/Plugins/Language/ObjC/Cocoa.h index 388e6f03aa0f..a195d622ce58 100644 --- a/lldb/source/Plugins/Language/ObjC/Cocoa.h +++ b/lldb/source/Plugins/Language/ObjC/Cocoa.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Cocoa_h_ -#define liblldb_Cocoa_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COCOA_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COCOA_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -113,4 +113,4 @@ public: } // namespace formatters } // namespace lldb_private -#endif // liblldb_Cocoa_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COCOA_H diff --git a/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp b/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp index 247429da1b06..ac2f45b8354f 100644 --- a/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp +++ b/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp @@ -1,5 +1,4 @@ -//===-- CoreMedia.cpp --------------------------------------------*- C++ -//-*-===// +//===-- CoreMedia.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Plugins/Language/ObjC/CoreMedia.h b/lldb/source/Plugins/Language/ObjC/CoreMedia.h index 79abb67b9d7e..7fd8560d20e1 100644 --- a/lldb/source/Plugins/Language/ObjC/CoreMedia.h +++ b/lldb/source/Plugins/Language/ObjC/CoreMedia.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_CoreMedia_h_ -#define liblldb_CoreMedia_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COREMEDIA_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COREMEDIA_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -22,4 +22,4 @@ bool CMTimeSummaryProvider(ValueObject &valobj, Stream &stream, } // namespace formatters } // namespace lldb_private -#endif // liblldb_CF_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_COREMEDIA_H diff --git a/lldb/source/Plugins/Language/ObjC/NSArray.cpp b/lldb/source/Plugins/Language/ObjC/NSArray.cpp index 73335aff2fd7..8d648d8a0861 100644 --- a/lldb/source/Plugins/Language/ObjC/NSArray.cpp +++ b/lldb/source/Plugins/Language/ObjC/NSArray.cpp @@ -1,4 +1,4 @@ -//===-- NSArray.cpp ---------------------------------------------*- C++ -*-===// +//===-- NSArray.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,16 +7,17 @@ //===----------------------------------------------------------------------===// #include "clang/AST/ASTContext.h" +#include "clang/Basic/TargetInfo.h" #include "Cocoa.h" #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/Expression/FunctionCaller.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" @@ -97,42 +98,46 @@ private: }; namespace Foundation1010 { - struct DataDescriptor_32 { - uint32_t _used; - uint32_t _offset; - uint32_t _size : 28; - uint64_t _priv1 : 4; - uint32_t _priv2; - uint32_t _data; - }; - - struct DataDescriptor_64 { - uint64_t _used; - uint64_t _offset; - uint64_t _size : 60; - uint64_t _priv1 : 4; - uint32_t _priv2; - uint64_t _data; - }; + namespace { + struct DataDescriptor_32 { + uint32_t _used; + uint32_t _offset; + uint32_t _size : 28; + uint64_t _priv1 : 4; + uint32_t _priv2; + uint32_t _data; + }; + + struct DataDescriptor_64 { + uint64_t _used; + uint64_t _offset; + uint64_t _size : 60; + uint64_t _priv1 : 4; + uint32_t _priv2; + uint64_t _data; + }; + } using NSArrayMSyntheticFrontEnd = GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>; } namespace Foundation1428 { - struct DataDescriptor_32 { - uint32_t _used; - uint32_t _offset; - uint32_t _size; - uint32_t _data; - }; - - struct DataDescriptor_64 { - uint64_t _used; - uint64_t _offset; - uint64_t _size; - uint64_t _data; - }; + namespace { + struct DataDescriptor_32 { + uint32_t _used; + uint32_t _offset; + uint32_t _size; + uint32_t _data; + }; + + struct DataDescriptor_64 { + uint64_t _used; + uint64_t _offset; + uint64_t _size; + uint64_t _data; + }; + } using NSArrayMSyntheticFrontEnd = GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>; @@ -436,7 +441,7 @@ lldb_private::formatters::NSArrayMSyntheticFrontEndBase::NSArrayMSyntheticFrontE : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), m_id_type() { if (valobj_sp) { - auto *clang_ast_context = ClangASTContext::GetScratch( + auto *clang_ast_context = TypeSystemClang::GetScratch( *valobj_sp->GetExecutionContextRef().GetTargetSP()); if (clang_ast_context) m_id_type = CompilerType( @@ -528,7 +533,7 @@ lldb_private::formatters::NSArrayMSyntheticFrontEndBase::GetIndexOfChildWithName template <typename D32, typename D64> lldb_private::formatters:: GenericNSArrayMSyntheticFrontEnd<D32, D64>:: - ~GenericNSArrayMSyntheticFrontEnd() { + ~GenericNSArrayMSyntheticFrontEnd<D32, D64>() { delete m_data_32; m_data_32 = nullptr; delete m_data_64; @@ -584,7 +589,7 @@ lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>:: if (valobj_sp) { CompilerType type = valobj_sp->GetCompilerType(); if (type) { - auto *clang_ast_context = ClangASTContext::GetScratch( + auto *clang_ast_context = TypeSystemClang::GetScratch( *valobj_sp->GetExecutionContextRef().GetTargetSP()); if (clang_ast_context) m_id_type = clang_ast_context->GetType( @@ -595,7 +600,7 @@ lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>:: template <typename D32, typename D64, bool Inline> lldb_private::formatters::GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>:: - ~GenericNSArrayISyntheticFrontEnd() { + ~GenericNSArrayISyntheticFrontEnd<D32, D64, Inline>() { delete m_data_32; m_data_32 = nullptr; delete m_data_64; @@ -753,7 +758,7 @@ lldb_private::formatters::NSArray1SyntheticFrontEnd::GetChildAtIndex( if (idx == 0) { auto *clang_ast_context = - ClangASTContext::GetScratch(*m_backend.GetTargetSP()); + TypeSystemClang::GetScratch(*m_backend.GetTargetSP()); if (clang_ast_context) { CompilerType id_type( clang_ast_context->GetBasicType(lldb::eBasicTypeObjCID)); diff --git a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp index ae00674c49f3..3dc07678f92f 100644 --- a/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp +++ b/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp @@ -1,4 +1,4 @@ -//===-- NSDictionary.cpp ----------------------------------------*- C++ -*-===// +//===-- NSDictionary.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,14 +10,15 @@ #include "clang/AST/DeclCXX.h" +#include "CFBasicHash.h" #include "NSDictionary.h" #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" @@ -65,7 +66,7 @@ NSDictionary_Additionals::GetAdditionalSynthetics() { static CompilerType GetLLDBNSPairType(TargetSP target_sp) { CompilerType compiler_type; - ClangASTContext *target_ast_context = ClangASTContext::GetScratch(*target_sp); + TypeSystemClang *target_ast_context = TypeSystemClang::GetScratch(*target_sp); if (target_ast_context) { ConstString g___lldb_autogen_nspair("__lldb_autogen_nspair"); @@ -76,18 +77,19 @@ static CompilerType GetLLDBNSPairType(TargetSP target_sp) { if (!compiler_type) { compiler_type = target_ast_context->CreateRecordType( - nullptr, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(), - clang::TTK_Struct, lldb::eLanguageTypeC); + nullptr, OptionalClangModuleID(), lldb::eAccessPublic, + g___lldb_autogen_nspair.GetCString(), clang::TTK_Struct, + lldb::eLanguageTypeC); if (compiler_type) { - ClangASTContext::StartTagDeclarationDefinition(compiler_type); + TypeSystemClang::StartTagDeclarationDefinition(compiler_type); CompilerType id_compiler_type = target_ast_context->GetBasicType(eBasicTypeObjCID); - ClangASTContext::AddFieldToRecordType( + TypeSystemClang::AddFieldToRecordType( compiler_type, "key", id_compiler_type, lldb::eAccessPublic, 0); - ClangASTContext::AddFieldToRecordType( + TypeSystemClang::AddFieldToRecordType( compiler_type, "value", id_compiler_type, lldb::eAccessPublic, 0); - ClangASTContext::CompleteTagDeclarationDefinition(compiler_type); + TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type); } } } @@ -139,6 +141,37 @@ private: std::vector<DictionaryItemDescriptor> m_children; }; +class NSCFDictionarySyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: + NSCFDictionarySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + + size_t CalculateNumChildren() override; + + lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + + bool Update() override; + + bool MightHaveChildren() override; + + size_t GetIndexOfChildWithName(ConstString name) override; + +private: + struct DictionaryItemDescriptor { + lldb::addr_t key_ptr; + lldb::addr_t val_ptr; + lldb::ValueObjectSP valobj_sp; + }; + + ExecutionContextRef m_exe_ctx_ref; + uint8_t m_ptr_size; + lldb::ByteOrder m_order; + + CFBasicHash m_hashtable; + + CompilerType m_pair_type; + std::vector<DictionaryItemDescriptor> m_children; +}; + class NSDictionary1SyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: NSDictionary1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); @@ -245,64 +278,67 @@ namespace Foundation1100 { } namespace Foundation1428 { - struct DataDescriptor_32 { - uint32_t _used : 26; - uint32_t _kvo : 1; - uint32_t _size; - uint32_t _buffer; - uint64_t GetSize() { return _size; } - }; - - struct DataDescriptor_64 { - uint64_t _used : 58; - uint32_t _kvo : 1; - uint64_t _size; - uint64_t _buffer; - uint64_t GetSize() { return _size; } - }; - - - + namespace { + struct DataDescriptor_32 { + uint32_t _used : 26; + uint32_t _kvo : 1; + uint32_t _size; + uint32_t _buffer; + uint64_t GetSize() { return _size; } + }; + + struct DataDescriptor_64 { + uint64_t _used : 58; + uint32_t _kvo : 1; + uint64_t _size; + uint64_t _buffer; + uint64_t GetSize() { return _size; } + }; + } + using NSDictionaryMSyntheticFrontEnd = GenericNSDictionaryMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>; } namespace Foundation1437 { - static const uint64_t NSDictionaryCapacities[] = { - 0, 3, 7, 13, 23, 41, 71, 127, 191, 251, 383, 631, 1087, 1723, - 2803, 4523, 7351, 11959, 19447, 31231, 50683, 81919, 132607, - 214519, 346607, 561109, 907759, 1468927, 2376191, 3845119, - 6221311, 10066421, 16287743, 26354171, 42641881, 68996069, - 111638519, 180634607, 292272623, 472907251 - }; - - static const size_t NSDictionaryNumSizeBuckets = sizeof(NSDictionaryCapacities) / sizeof(uint64_t); - - struct DataDescriptor_32 { - uint32_t _buffer; - uint32_t _muts; - uint32_t _used : 25; - uint32_t _kvo : 1; - uint32_t _szidx : 6; + namespace { + static const uint64_t NSDictionaryCapacities[] = { + 0, 3, 7, 13, 23, 41, 71, 127, 191, 251, 383, 631, 1087, 1723, + 2803, 4523, 7351, 11959, 19447, 31231, 50683, 81919, 132607, + 214519, 346607, 561109, 907759, 1468927, 2376191, 3845119, + 6221311, 10066421, 16287743, 26354171, 42641881, 68996069, + 111638519, 180634607, 292272623, 472907251 + }; + + static const size_t NSDictionaryNumSizeBuckets = + sizeof(NSDictionaryCapacities) / sizeof(uint64_t); + + struct DataDescriptor_32 { + uint32_t _buffer; + uint32_t _muts; + uint32_t _used : 25; + uint32_t _kvo : 1; + uint32_t _szidx : 6; - uint64_t GetSize() { - return (_szidx) >= NSDictionaryNumSizeBuckets ? - 0 : NSDictionaryCapacities[_szidx]; - } - }; - - struct DataDescriptor_64 { - uint64_t _buffer; - uint32_t _muts; - uint32_t _used : 25; - uint32_t _kvo : 1; - uint32_t _szidx : 6; + uint64_t GetSize() { + return (_szidx) >= NSDictionaryNumSizeBuckets ? + 0 : NSDictionaryCapacities[_szidx]; + } + }; + + struct DataDescriptor_64 { + uint64_t _buffer; + uint32_t _muts; + uint32_t _used : 25; + uint32_t _kvo : 1; + uint32_t _szidx : 6; - uint64_t GetSize() { - return (_szidx) >= NSDictionaryNumSizeBuckets ? - 0 : NSDictionaryCapacities[_szidx]; - } - }; + uint64_t GetSize() { + return (_szidx) >= NSDictionaryNumSizeBuckets ? + 0 : NSDictionaryCapacities[_szidx]; + } + }; + } using NSDictionaryMSyntheticFrontEnd = GenericNSDictionaryMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>; @@ -375,7 +411,9 @@ bool lldb_private::formatters::NSDictionarySummaryProvider( static const ConstString g_DictionaryMImmutable("__NSDictionaryM_Immutable"); static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI"); static const ConstString g_Dictionary0("__NSDictionary0"); - static const ConstString g_DictionaryCF("__NSCFDictionary"); + static const ConstString g_DictionaryCF("__CFDictionary"); + static const ConstString g_DictionaryNSCF("__NSCFDictionary"); + static const ConstString g_DictionaryCFRef("CFDictionaryRef"); if (class_name.IsEmpty()) return false; @@ -386,9 +424,9 @@ bool lldb_private::formatters::NSDictionarySummaryProvider( ptr_size, 0, error); if (error.Fail()) return false; + value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); - } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy || - class_name == g_DictionaryCF) { + } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy) { AppleObjCRuntime *apple_runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime); Status error; @@ -406,8 +444,15 @@ bool lldb_private::formatters::NSDictionarySummaryProvider( value = 1; } else if (class_name == g_Dictionary0) { value = 0; - } - else { + } else if (class_name == g_DictionaryCF || + class_name == g_DictionaryNSCF || + class_name == g_DictionaryCFRef) { + ExecutionContext exe_ctx(process_sp); + CFBasicHash cfbh; + if (!cfbh.Update(valobj_addr, exe_ctx)) + return false; + value = cfbh.GetCount(); + } else { auto &map(NSDictionary_Additionals::GetAdditionalSummaries()); for (auto &candidate : map) { if (candidate.first && candidate.first->Match(class_name)) @@ -465,6 +510,9 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator( static const ConstString g_DictionaryImmutable("__NSDictionaryM_Immutable"); static const ConstString g_DictionaryMLegacy("__NSDictionaryM_Legacy"); static const ConstString g_Dictionary0("__NSDictionary0"); + static const ConstString g_DictionaryCF("__CFDictionary"); + static const ConstString g_DictionaryNSCF("__NSCFDictionary"); + static const ConstString g_DictionaryCFRef("CFDictionaryRef"); if (class_name.IsEmpty()) return nullptr; @@ -483,6 +531,10 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator( return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp)); } else if (class_name == g_Dictionary1) { return (new NSDictionary1SyntheticFrontEnd(valobj_sp)); + } else if (class_name == g_DictionaryCF || + class_name == g_DictionaryNSCF || + class_name == g_DictionaryCFRef) { + return (new NSCFDictionarySyntheticFrontEnd(valobj_sp)); } else { auto &map(NSDictionary_Additionals::GetAdditionalSynthetics()); for (auto &candidate : map) { @@ -640,6 +692,140 @@ lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex( return dict_item.valobj_sp; } +lldb_private::formatters::NSCFDictionarySyntheticFrontEnd:: + NSCFDictionarySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) + : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), + m_order(lldb::eByteOrderInvalid), m_hashtable(), m_pair_type() {} + +size_t lldb_private::formatters::NSCFDictionarySyntheticFrontEnd:: + GetIndexOfChildWithName(ConstString name) { + const char *item_name = name.GetCString(); + const uint32_t idx = ExtractIndexFromString(item_name); + if (idx < UINT32_MAX && idx >= CalculateNumChildren()) + return UINT32_MAX; + return idx; +} + +size_t lldb_private::formatters::NSCFDictionarySyntheticFrontEnd:: + CalculateNumChildren() { + if (!m_hashtable.IsValid()) + return 0; + return m_hashtable.GetCount(); +} + +bool lldb_private::formatters::NSCFDictionarySyntheticFrontEnd::Update() { + m_children.clear(); + ValueObjectSP valobj_sp = m_backend.GetSP(); + m_ptr_size = 0; + if (!valobj_sp) + return false; + m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); + + lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); + if (!process_sp) + return false; + m_ptr_size = process_sp->GetAddressByteSize(); + m_order = process_sp->GetByteOrder(); + return m_hashtable.Update(valobj_sp->GetValueAsUnsigned(0), m_exe_ctx_ref); +} + +bool lldb_private::formatters::NSCFDictionarySyntheticFrontEnd:: + MightHaveChildren() { + return true; +} + +lldb::ValueObjectSP +lldb_private::formatters::NSCFDictionarySyntheticFrontEnd::GetChildAtIndex( + size_t idx) { + lldb::addr_t m_keys_ptr = m_hashtable.GetKeyPointer(); + lldb::addr_t m_values_ptr = m_hashtable.GetValuePointer(); + + const uint32_t num_children = CalculateNumChildren(); + + if (idx >= num_children) + return lldb::ValueObjectSP(); + + if (m_children.empty()) { + ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP(); + if (!process_sp) + return lldb::ValueObjectSP(); + + Status error; + lldb::addr_t key_at_idx = 0, val_at_idx = 0; + + uint32_t tries = 0; + uint32_t test_idx = 0; + + // Iterate over inferior memory, reading key/value pointers by shifting each + // cursor by test_index * m_ptr_size. Returns an empty ValueObject if a read + // fails, otherwise, continue until the number of tries matches the number + // of childen. + while (tries < num_children) { + key_at_idx = m_keys_ptr + (test_idx * m_ptr_size); + val_at_idx = m_values_ptr + (test_idx * m_ptr_size); + + key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error); + if (error.Fail()) + return lldb::ValueObjectSP(); + val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error); + if (error.Fail()) + return lldb::ValueObjectSP(); + + test_idx++; + + if (!key_at_idx || !val_at_idx) + continue; + tries++; + + DictionaryItemDescriptor descriptor = {key_at_idx, val_at_idx, + lldb::ValueObjectSP()}; + + m_children.push_back(descriptor); + } + } + + if (idx >= m_children.size()) // should never happen + return lldb::ValueObjectSP(); + + DictionaryItemDescriptor &dict_item = m_children[idx]; + if (!dict_item.valobj_sp) { + if (!m_pair_type.IsValid()) { + TargetSP target_sp(m_backend.GetTargetSP()); + if (!target_sp) + return ValueObjectSP(); + m_pair_type = GetLLDBNSPairType(target_sp); + } + if (!m_pair_type.IsValid()) + return ValueObjectSP(); + + DataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0)); + + switch (m_ptr_size) { + case 0: // architecture has no clue - fail + return lldb::ValueObjectSP(); + case 4: { + uint32_t *data_ptr = reinterpret_cast<uint32_t *>(buffer_sp->GetBytes()); + *data_ptr = dict_item.key_ptr; + *(data_ptr + 1) = dict_item.val_ptr; + } break; + case 8: { + uint64_t *data_ptr = reinterpret_cast<uint64_t *>(buffer_sp->GetBytes()); + *data_ptr = dict_item.key_ptr; + *(data_ptr + 1) = dict_item.val_ptr; + } break; + default: + lldbassert(false && "pointer size is not 4 nor 8"); + } + + StreamString idx_name; + idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); + DataExtractor data(buffer_sp, m_order, m_ptr_size); + dict_item.valobj_sp = CreateValueObjectFromData(idx_name.GetString(), data, + m_exe_ctx_ref, m_pair_type); + } + return dict_item.valobj_sp; +} + lldb_private::formatters::NSDictionary1SyntheticFrontEnd:: NSDictionary1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_pair(nullptr) {} @@ -724,7 +910,7 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: template <typename D32, typename D64> lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: - ~GenericNSDictionaryMSyntheticFrontEnd() { + ~GenericNSDictionaryMSyntheticFrontEnd<D32,D64>() { delete m_data_32; m_data_32 = nullptr; delete m_data_64; @@ -732,8 +918,8 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: } template <typename D32, typename D64> -size_t -lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: GetIndexOfChildWithName(ConstString name) { +size_t lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd< + D32, D64>::GetIndexOfChildWithName(ConstString name) { const char *item_name = name.GetCString(); uint32_t idx = ExtractIndexFromString(item_name); if (idx < UINT32_MAX && idx >= CalculateNumChildren()) @@ -782,7 +968,7 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: } if (error.Fail()) return false; - return false; + return true; } template <typename D32, typename D64> @@ -794,9 +980,8 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: template <typename D32, typename D64> lldb::ValueObjectSP -lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: - GetChildAtIndex( - size_t idx) { +lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd< + D32, D64>::GetChildAtIndex(size_t idx) { lldb::addr_t m_keys_ptr; lldb::addr_t m_values_ptr; if (m_data_32) { @@ -884,7 +1069,6 @@ lldb_private::formatters::GenericNSDictionaryMSyntheticFrontEnd<D32,D64>:: return dict_item.valobj_sp; } - lldb_private::formatters::Foundation1100:: NSDictionaryMSyntheticFrontEnd:: NSDictionaryMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) diff --git a/lldb/source/Plugins/Language/ObjC/NSDictionary.h b/lldb/source/Plugins/Language/ObjC/NSDictionary.h index 44d56f9c2c68..57dacd6759d2 100644 --- a/lldb/source/Plugins/Language/ObjC/NSDictionary.h +++ b/lldb/source/Plugins/Language/ObjC/NSDictionary.h @@ -1,5 +1,4 @@ -//===-- NSDictionary.h ---------------------------------------------------*- C++ -//-*-===// +//===-- NSDictionary.h ------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_NSDictionary_h_ -#define liblldb_NSDictionary_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSDICTIONARY_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSDICTIONARY_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -91,4 +90,4 @@ public: } // namespace formatters } // namespace lldb_private -#endif // liblldb_NSDictionary_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSDICTIONARY_H diff --git a/lldb/source/Plugins/Language/ObjC/NSError.cpp b/lldb/source/Plugins/Language/ObjC/NSError.cpp index 94a97c8ad039..aa1103cb342c 100644 --- a/lldb/source/Plugins/Language/ObjC/NSError.cpp +++ b/lldb/source/Plugins/Language/ObjC/NSError.cpp @@ -1,4 +1,4 @@ -//===-- NSError.cpp ---------------------------------------------*- C++ -*-===// +//===-- NSError.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,10 +10,10 @@ #include "Cocoa.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/ProcessStructReader.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" @@ -87,7 +87,7 @@ bool lldb_private::formatters::NSError_SummaryProvider( ValueObjectSP domain_str_sp = ValueObject::CreateValueObjectFromData( "domain_str", isw.GetAsData(process_sp->GetByteOrder()), valobj.GetExecutionContextRef(), - ClangASTContext::GetScratch(process_sp->GetTarget()) + TypeSystemClang::GetScratch(process_sp->GetTarget()) ->GetBasicType(lldb::eBasicTypeVoid) .GetPointerType()); @@ -156,7 +156,7 @@ public: m_child_sp = CreateValueObjectFromData( "_userInfo", isw.GetAsData(process_sp->GetByteOrder()), m_backend.GetExecutionContextRef(), - ClangASTContext::GetScratch(process_sp->GetTarget()) + TypeSystemClang::GetScratch(process_sp->GetTarget()) ->GetBasicType(lldb::eBasicTypeObjCID)); return false; } diff --git a/lldb/source/Plugins/Language/ObjC/NSException.cpp b/lldb/source/Plugins/Language/ObjC/NSException.cpp index 9150787361c5..c6bae5e1c008 100644 --- a/lldb/source/Plugins/Language/ObjC/NSException.cpp +++ b/lldb/source/Plugins/Language/ObjC/NSException.cpp @@ -1,4 +1,4 @@ -//===-- NSException.cpp -----------------------------------------*- C++ -*-===// +//===-- NSException.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,7 +13,6 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/ProcessStructReader.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" @@ -23,6 +22,7 @@ #include "Plugins/Language/ObjC/NSString.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" using namespace lldb; using namespace lldb_private; @@ -69,7 +69,7 @@ static bool ExtractFields(ValueObject &valobj, ValueObjectSP *name_sp, InferiorSizedWord userinfo_isw(userinfo, *process_sp); InferiorSizedWord reserved_isw(reserved, *process_sp); - auto *clang_ast_context = ClangASTContext::GetScratch(process_sp->GetTarget()); + auto *clang_ast_context = TypeSystemClang::GetScratch(process_sp->GetTarget()); if (!clang_ast_context) return false; diff --git a/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp b/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp index 587dd13870a0..d962f39611b6 100644 --- a/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp +++ b/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp @@ -1,4 +1,4 @@ -//===-- NSIndexPath.cpp -----------------------------------------*- C++ -*-===// +//===-- NSIndexPath.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,11 +8,11 @@ #include "Cocoa.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/DataFormatters/TypeSynthetic.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -53,7 +53,7 @@ public: if (!type_system) return false; - ClangASTContext *ast = ClangASTContext::GetScratch( + TypeSystemClang *ast = TypeSystemClang::GetScratch( *m_backend.GetExecutionContextRef().GetTargetSP()); if (!ast) return false; diff --git a/lldb/source/Plugins/Language/ObjC/NSSet.cpp b/lldb/source/Plugins/Language/ObjC/NSSet.cpp index ebaa990fb74b..4dbbe6fbddff 100644 --- a/lldb/source/Plugins/Language/ObjC/NSSet.cpp +++ b/lldb/source/Plugins/Language/ObjC/NSSet.cpp @@ -1,4 +1,4 @@ -//===-- NSSet.cpp -----------------------------------------------*- C++ -*-===// +//===-- NSSet.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,12 +7,13 @@ //===----------------------------------------------------------------------===// #include "NSSet.h" +#include "CFBasicHash.h" #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" @@ -79,6 +80,36 @@ private: std::vector<SetItemDescriptor> m_children; }; +class NSCFSetSyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: + NSCFSetSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + + size_t CalculateNumChildren() override; + + lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + + bool Update() override; + + bool MightHaveChildren() override; + + size_t GetIndexOfChildWithName(ConstString name) override; + +private: + struct SetItemDescriptor { + lldb::addr_t item_ptr; + lldb::ValueObjectSP valobj_sp; + }; + + ExecutionContextRef m_exe_ctx_ref; + uint8_t m_ptr_size; + lldb::ByteOrder m_order; + + CFBasicHash m_hashtable; + + CompilerType m_pair_type; + std::vector<SetItemDescriptor> m_children; +}; + template <typename D32, typename D64> class GenericNSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: @@ -245,21 +276,25 @@ bool lldb_private::formatters::NSSetSummaryProvider( uint64_t value = 0; - ConstString class_name_cs = descriptor->GetClassName(); - const char *class_name = class_name_cs.GetCString(); + ConstString class_name(descriptor->GetClassName()); - if (!class_name || !*class_name) + static const ConstString g_SetI("__NSSetI"); + static const ConstString g_OrderedSetI("__NSOrderedSetI"); + static const ConstString g_SetM("__NSSetM"); + static const ConstString g_SetCF("__NSCFSet"); + static const ConstString g_SetCFRef("CFSetRef"); + + if (class_name.IsEmpty()) return false; - if (!strcmp(class_name, "__NSSetI") || - !strcmp(class_name, "__NSOrderedSetI")) { + if (class_name == g_SetI || class_name == g_OrderedSetI) { Status error; value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error); if (error.Fail()) return false; value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); - } else if (!strcmp(class_name, "__NSSetM")) { + } else if (class_name == g_SetM) { AppleObjCRuntime *apple_runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime); Status error; @@ -272,9 +307,15 @@ bool lldb_private::formatters::NSSetSummaryProvider( } if (error.Fail()) return false; + } else if (class_name == g_SetCF || class_name == g_SetCFRef) { + ExecutionContext exe_ctx(process_sp); + CFBasicHash cfbh; + if (!cfbh.Update(valobj_addr, exe_ctx)) + return false; + value = cfbh.GetCount(); } else { auto &map(NSSet_Additionals::GetAdditionalSummaries()); - auto iter = map.find(class_name_cs), end = map.end(); + auto iter = map.find(class_name), end = map.end(); if (iter != end) return iter->second(valobj, stream, options); else @@ -321,16 +362,20 @@ lldb_private::formatters::NSSetSyntheticFrontEndCreator( if (!descriptor || !descriptor->IsValid()) return nullptr; - ConstString class_name_cs = descriptor->GetClassName(); - const char *class_name = class_name_cs.GetCString(); + ConstString class_name = descriptor->GetClassName(); - if (!class_name || !*class_name) + static const ConstString g_SetI("__NSSetI"); + static const ConstString g_OrderedSetI("__NSOrderedSetI"); + static const ConstString g_SetM("__NSSetM"); + static const ConstString g_SetCF("__NSCFSet"); + static const ConstString g_SetCFRef("CFSetRef"); + + if (class_name.IsEmpty()) return nullptr; - if (!strcmp(class_name, "__NSSetI") || - !strcmp(class_name, "__NSOrderedSetI")) { + if (class_name == g_SetI || class_name == g_OrderedSetI) { return (new NSSetISyntheticFrontEnd(valobj_sp)); - } else if (!strcmp(class_name, "__NSSetM")) { + } else if (class_name == g_SetM) { AppleObjCRuntime *apple_runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime); if (apple_runtime) { @@ -343,9 +388,11 @@ lldb_private::formatters::NSSetSyntheticFrontEndCreator( } else { return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp)); } + } else if (class_name == g_SetCF || class_name == g_SetCFRef) { + return (new NSCFSetSyntheticFrontEnd(valobj_sp)); } else { auto &map(NSSet_Additionals::GetAdditionalSynthetics()); - auto iter = map.find(class_name_cs), end = map.end(); + auto iter = map.find(class_name), end = map.end(); if (iter != end) return iter->second(synth, valobj_sp); return nullptr; @@ -475,16 +522,18 @@ lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex(size_t idx) { auto ptr_size = process_sp->GetAddressByteSize(); DataBufferHeap buffer(ptr_size, 0); switch (ptr_size) { - case 0: // architecture has no clue?? - fail + case 0: // architecture has no clue - fail return lldb::ValueObjectSP(); case 4: - *((uint32_t *)buffer.GetBytes()) = (uint32_t)set_item.item_ptr; + *reinterpret_cast<uint32_t *>(buffer.GetBytes()) = + static_cast<uint32_t>(set_item.item_ptr); break; case 8: - *((uint64_t *)buffer.GetBytes()) = (uint64_t)set_item.item_ptr; + *reinterpret_cast<uint64_t *>(buffer.GetBytes()) = + static_cast<uint64_t>(set_item.item_ptr); break; default: - assert(false && "pointer size is not 4 nor 8 - get out of here ASAP"); + lldbassert(false && "pointer size is not 4 nor 8"); } StreamString idx_name; idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); @@ -501,6 +550,128 @@ lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex(size_t idx) { return set_item.valobj_sp; } +lldb_private::formatters::NSCFSetSyntheticFrontEnd::NSCFSetSyntheticFrontEnd( + lldb::ValueObjectSP valobj_sp) + : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8), + m_order(lldb::eByteOrderInvalid), m_hashtable(), m_pair_type() {} + +size_t +lldb_private::formatters::NSCFSetSyntheticFrontEnd::GetIndexOfChildWithName( + ConstString name) { + const char *item_name = name.GetCString(); + const uint32_t idx = ExtractIndexFromString(item_name); + if (idx < UINT32_MAX && idx >= CalculateNumChildren()) + return UINT32_MAX; + return idx; +} + +size_t +lldb_private::formatters::NSCFSetSyntheticFrontEnd::CalculateNumChildren() { + if (!m_hashtable.IsValid()) + return 0; + return m_hashtable.GetCount(); +} + +bool lldb_private::formatters::NSCFSetSyntheticFrontEnd::Update() { + m_children.clear(); + ValueObjectSP valobj_sp = m_backend.GetSP(); + m_ptr_size = 0; + if (!valobj_sp) + return false; + m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); + + lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); + if (!process_sp) + return false; + m_ptr_size = process_sp->GetAddressByteSize(); + m_order = process_sp->GetByteOrder(); + return m_hashtable.Update(valobj_sp->GetValueAsUnsigned(0), m_exe_ctx_ref); +} + +bool lldb_private::formatters::NSCFSetSyntheticFrontEnd::MightHaveChildren() { + return true; +} + +lldb::ValueObjectSP +lldb_private::formatters::NSCFSetSyntheticFrontEnd::GetChildAtIndex( + size_t idx) { + lldb::addr_t m_values_ptr = m_hashtable.GetValuePointer(); + + const uint32_t num_children = CalculateNumChildren(); + + if (idx >= num_children) + return lldb::ValueObjectSP(); + + if (m_children.empty()) { + ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP(); + if (!process_sp) + return lldb::ValueObjectSP(); + + Status error; + lldb::addr_t val_at_idx = 0; + + uint32_t tries = 0; + uint32_t test_idx = 0; + + // Iterate over inferior memory, reading value pointers by shifting the + // cursor by test_index * m_ptr_size. Returns an empty ValueObject if a read + // fails, otherwise, continue until the number of tries matches the number + // of childen. + while (tries < num_children) { + val_at_idx = m_values_ptr + (test_idx * m_ptr_size); + + val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error); + if (error.Fail()) + return lldb::ValueObjectSP(); + + test_idx++; + + if (!val_at_idx) + continue; + tries++; + + SetItemDescriptor descriptor = {val_at_idx, lldb::ValueObjectSP()}; + + m_children.push_back(descriptor); + } + } + + if (idx >= m_children.size()) // should never happen + return lldb::ValueObjectSP(); + + SetItemDescriptor &set_item = m_children[idx]; + if (!set_item.valobj_sp) { + + DataBufferSP buffer_sp(new DataBufferHeap(m_ptr_size, 0)); + + switch (m_ptr_size) { + case 0: // architecture has no clue - fail + return lldb::ValueObjectSP(); + case 4: + *reinterpret_cast<uint32_t *>(buffer_sp->GetBytes()) = + static_cast<uint32_t>(set_item.item_ptr); + break; + case 8: + *reinterpret_cast<uint64_t *>(buffer_sp->GetBytes()) = + static_cast<uint64_t>(set_item.item_ptr); + break; + default: + lldbassert(false && "pointer size is not 4 nor 8"); + } + StreamString idx_name; + idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); + + DataExtractor data(buffer_sp, m_order, m_ptr_size); + + set_item.valobj_sp = CreateValueObjectFromData( + idx_name.GetString(), data, m_exe_ctx_ref, + m_backend.GetCompilerType().GetBasicTypeFromAST( + lldb::eBasicTypeObjCID)); + } + + return set_item.valobj_sp; +} + template <typename D32, typename D64> lldb_private::formatters:: GenericNSSetMSyntheticFrontEnd<D32, D64>::GenericNSSetMSyntheticFrontEnd( @@ -513,7 +684,7 @@ lldb_private::formatters:: template <typename D32, typename D64> lldb_private::formatters:: - GenericNSSetMSyntheticFrontEnd<D32, D64>::~GenericNSSetMSyntheticFrontEnd() { + GenericNSSetMSyntheticFrontEnd<D32, D64>::~GenericNSSetMSyntheticFrontEnd<D32, D64>() { delete m_data_32; m_data_32 = nullptr; delete m_data_64; diff --git a/lldb/source/Plugins/Language/ObjC/NSSet.h b/lldb/source/Plugins/Language/ObjC/NSSet.h index f11b6d406dec..3ad1f694befe 100644 --- a/lldb/source/Plugins/Language/ObjC/NSSet.h +++ b/lldb/source/Plugins/Language/ObjC/NSSet.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_NSSet_h_ -#define liblldb_NSSet_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSET_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSET_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -36,4 +36,4 @@ public: } // namespace formatters } // namespace lldb_private -#endif // liblldb_NSSet_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSET_H diff --git a/lldb/source/Plugins/Language/ObjC/NSString.cpp b/lldb/source/Plugins/Language/ObjC/NSString.cpp index ce54d657374b..b9d0d73cbc2e 100644 --- a/lldb/source/Plugins/Language/ObjC/NSString.cpp +++ b/lldb/source/Plugins/Language/ObjC/NSString.cpp @@ -1,5 +1,4 @@ -//===-- NSString.cpp ----------------------------------------------*- C++ -//-*-===// +//===-- NSString.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,11 +8,11 @@ #include "NSString.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/DataFormatters/StringPrinter.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/ProcessStructReader.h" #include "lldb/Target/Target.h" @@ -35,7 +34,7 @@ NSString_Additionals::GetAdditionalSummaries() { static CompilerType GetNSPathStore2Type(Target &target) { static ConstString g_type_name("__lldb_autogen_nspathstore2"); - ClangASTContext *ast_ctx = ClangASTContext::GetScratch(target); + TypeSystemClang *ast_ctx = TypeSystemClang::GetScratch(target); if (!ast_ctx) return CompilerType(); @@ -171,11 +170,11 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetStream(&stream); options.SetQuote('"'); options.SetSourceSize(explicit_length); + options.SetHasSourceSize(has_explicit_length); options.SetNeedsZeroTermination(false); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(false); - options.SetLanguage(summary_options.GetLanguage()); return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF16>(options); } else { @@ -183,11 +182,11 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetSourceSize(explicit_length); + options.SetHasSourceSize(has_explicit_length); options.SetNeedsZeroTermination(false); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(false); - options.SetLanguage(summary_options.GetLanguage()); return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::ASCII>(options); } @@ -200,9 +199,9 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetStream(&stream); options.SetQuote('"'); options.SetSourceSize(explicit_length); + options.SetHasSourceSize(has_explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); - options.SetLanguage(summary_options.GetLanguage()); return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::ASCII>(options); } else if (is_unicode) { @@ -222,11 +221,11 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetStream(&stream); options.SetQuote('"'); options.SetSourceSize(explicit_length); + options.SetHasSourceSize(has_explicit_length); options.SetNeedsZeroTermination(!has_explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(!has_explicit_length); - options.SetLanguage(summary_options.GetLanguage()); return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF16>(options); } else if (is_path_store) { @@ -242,11 +241,11 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetStream(&stream); options.SetQuote('"'); options.SetSourceSize(explicit_length); + options.SetHasSourceSize(has_explicit_length); options.SetNeedsZeroTermination(!has_explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(!has_explicit_length); - options.SetLanguage(summary_options.GetLanguage()); return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF16>(options); } else if (is_inline) { @@ -264,11 +263,11 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetSourceSize(explicit_length); + options.SetHasSourceSize(has_explicit_length); options.SetNeedsZeroTermination(!has_explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(!has_explicit_length); - options.SetLanguage(summary_options.GetLanguage()); if (has_explicit_length) return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF8>(options); @@ -287,9 +286,9 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetSourceSize(explicit_length); + options.SetHasSourceSize(has_explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); - options.SetLanguage(summary_options.GetLanguage()); return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::ASCII>(options); } diff --git a/lldb/source/Plugins/Language/ObjC/NSString.h b/lldb/source/Plugins/Language/ObjC/NSString.h index 699d8eb36f88..a68cc6c056b0 100644 --- a/lldb/source/Plugins/Language/ObjC/NSString.h +++ b/lldb/source/Plugins/Language/ObjC/NSString.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_NSString_h_ -#define liblldb_NSString_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSTRING_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSTRING_H #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSummary.h" @@ -39,4 +39,4 @@ public: } // namespace formatters } // namespace lldb_private -#endif // liblldb_CF_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_NSSTRING_H diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp index 3be548ad4144..29391daaab93 100644 --- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp +++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp @@ -1,4 +1,4 @@ -//===-- ObjCLanguage.cpp ----------------------------------------*- C++ -*-===// +//===-- ObjCLanguage.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,12 +10,12 @@ #include "ObjCLanguage.h" +#include "Plugins/ExpressionParser/Clang/ClangUtil.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/DataVisualization.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/Target.h" #include "lldb/Utility/ConstString.h" @@ -37,6 +37,8 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; +LLDB_PLUGIN_DEFINE(ObjCLanguage) + void ObjCLanguage::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), "Objective-C Language", CreateInstance); @@ -446,6 +448,10 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, + "NSDictionary summary provider", ConstString("__CFDictionary"), + appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFMutableDictionaryRef"), appkit_flags); @@ -466,6 +472,9 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { "__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, + "__CFSet summary", ConstString("__CFSet"), appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSSetSummaryProvider<false>, "__NSSetI summary", ConstString("__NSSetI"), appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, @@ -582,6 +591,11 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"), ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic( + objc_category_sp, + lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, + "NSDictionary synthetic children", ConstString("__CFDictionary"), + ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSErrorSyntheticFrontEndCreator, @@ -604,6 +618,15 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSSetM synthetic children", ConstString("__NSSetM"), ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic(objc_category_sp, + lldb_private::formatters::NSSetSyntheticFrontEndCreator, + "__NSCFSet synthetic children", ConstString("__NSCFSet"), + ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic(objc_category_sp, + lldb_private::formatters::NSSetSyntheticFrontEndCreator, + "CFSetRef synthetic children", ConstString("CFSetRef"), + ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic( objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSMutableSet synthetic children", ConstString("NSMutableSet"), @@ -620,6 +643,10 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "__NSOrderedSetM synthetic children", ConstString("__NSOrderedSetM"), ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic(objc_category_sp, + lldb_private::formatters::NSSetSyntheticFrontEndCreator, + "__CFSet synthetic children", ConstString("__CFSet"), + ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator, diff --git a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h index 3e2cc0972993..bed62a5c447a 100644 --- a/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h +++ b/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ObjCLanguage_h_ -#define liblldb_ObjCLanguage_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H #include <cstring> #include <vector> @@ -160,4 +160,4 @@ public: } // namespace lldb_private -#endif // liblldb_ObjCLanguage_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H diff --git a/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp index 81b3c5807c41..0a4017eda434 100644 --- a/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp @@ -1,5 +1,4 @@ -//===-- ObjCPlusPlusLanguage.cpp --------------------------------------*- C++ -//-*-===// +//===-- ObjCPlusPlusLanguage.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,6 +14,8 @@ using namespace lldb; using namespace lldb_private; +LLDB_PLUGIN_DEFINE(ObjCPlusPlusLanguage) + bool ObjCPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const { const auto suffixes = {".h", ".mm"}; for (auto suffix : suffixes) { diff --git a/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h b/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h index 6224a3f47b3b..4b3d23653347 100644 --- a/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h +++ b/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_ObjCPlusPlusLanguage_h_ -#define liblldb_ObjCPlusPlusLanguage_h_ +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJCPLUSPLUS_OBJCPLUSPLUSLANGUAGE_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJCPLUSPLUS_OBJCPLUSPLUSLANGUAGE_H #include "Plugins/Language/ClangCommon/ClangHighlighter.h" #include "lldb/Target/Language.h" @@ -48,4 +48,4 @@ public: } // namespace lldb_private -#endif // liblldb_CPlusPlusLanguage_h_ +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJCPLUSPLUS_OBJCPLUSPLUSLANGUAGE_H |