diff options
Diffstat (limited to 'source/Symbol')
39 files changed, 2647 insertions, 1016 deletions
diff --git a/source/Symbol/ArmUnwindInfo.cpp b/source/Symbol/ArmUnwindInfo.cpp index 08f28073be21b..b9fd84b1e706e 100644 --- a/source/Symbol/ArmUnwindInfo.cpp +++ b/source/Symbol/ArmUnwindInfo.cpp @@ -1,9 +1,8 @@ //===-- ArmUnwindInfo.cpp ---------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -305,7 +304,7 @@ bool ArmUnwindInfo::GetUnwindPlan(Target &target, const Address &addr, // 11001yyy // Spare (yyy != 000, 001) return false; - } else if ((byte1 & 0xf8) == 0xc0) { + } else if ((byte1 & 0xf8) == 0xd0) { // 11010nnn // Pop VFP double-precision registers D[8]-D[8+nnn] saved (as if) by // FSTMFDD (see remark d) diff --git a/source/Symbol/Block.cpp b/source/Symbol/Block.cpp index d0342355911cf..6fe617080f961 100644 --- a/source/Symbol/Block.cpp +++ b/source/Symbol/Block.cpp @@ -1,9 +1,8 @@ //===-- Block.cpp -----------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -17,6 +16,8 @@ #include "lldb/Symbol/VariableList.h" #include "lldb/Utility/Log.h" +#include <memory> + using namespace lldb; using namespace lldb_private; @@ -211,6 +212,21 @@ Block *Block::GetInlinedParent() { return nullptr; } +Block *Block::GetContainingInlinedBlockWithCallSite( + const Declaration &find_call_site) { + Block *inlined_block = GetContainingInlinedBlock(); + + while (inlined_block) { + const auto *function_info = inlined_block->GetInlinedFunctionInfo(); + + if (function_info && + function_info->GetCallSite().FileAndLineEqual(find_call_site)) + return inlined_block; + inlined_block = inlined_block->GetInlinedParent(); + } + return nullptr; +} + bool Block::GetRangeContainingOffset(const addr_t offset, Range &range) { const Range *range_ptr = m_ranges.FindEntryThatContains(offset); if (range_ptr) { @@ -364,8 +380,8 @@ void Block::AddChild(const BlockSP &child_block_sp) { void Block::SetInlinedFunctionInfo(const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr) { - m_inlineInfoSP.reset( - new InlineFunctionInfo(name, mangled, decl_ptr, call_decl_ptr)); + m_inlineInfoSP = std::make_shared<InlineFunctionInfo>(name, mangled, decl_ptr, + call_decl_ptr); } VariableListSP Block::GetBlockVariableList(bool can_create) { diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp index 85436b630b7d7..205523355ce0b 100644 --- a/source/Symbol/ClangASTContext.cpp +++ b/source/Symbol/ClangASTContext.cpp @@ -1,9 +1,8 @@ //===-- ClangASTContext.cpp -------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -53,6 +52,7 @@ #include "clang/Basic/TargetOptions.h" #include "clang/Frontend/FrontendOptions.h" #include "clang/Frontend/LangStandard.h" +#include "clang/Sema/Sema.h" #ifdef LLDB_DEFINED_NDEBUG_FOR_CLANG #undef NDEBUG @@ -86,7 +86,6 @@ #include "lldb/Symbol/VerifyDecl.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Language.h" -#include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataExtractor.h" @@ -95,6 +94,7 @@ #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Scalar.h" +#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h" #include "Plugins/SymbolFile/PDB/PDBASTParser.h" @@ -654,19 +654,17 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) { } ClangASTContext::ClangASTContext(const char *target_triple) - : TypeSystem(TypeSystem::eKindClang), m_target_triple(), m_ast_ap(), - m_language_options_ap(), m_source_manager_ap(), m_diagnostics_engine_ap(), - m_target_options_rp(), m_target_info_ap(), m_identifier_table_ap(), - m_selector_table_ap(), m_builtins_ap(), m_callback_tag_decl(nullptr), + : TypeSystem(TypeSystem::eKindClang), m_target_triple(), m_ast_up(), + m_language_options_up(), m_source_manager_up(), m_diagnostics_engine_up(), + m_target_options_rp(), m_target_info_up(), m_identifier_table_up(), + m_selector_table_up(), m_builtins_up(), m_callback_tag_decl(nullptr), m_callback_objc_decl(nullptr), m_callback_baton(nullptr), m_pointer_byte_size(0), m_ast_owned(false) { if (target_triple && target_triple[0]) SetTargetTriple(target_triple); } -//---------------------------------------------------------------------- // Destructor -//---------------------------------------------------------------------- ClangASTContext::~ClangASTContext() { Finalize(); } ConstString ClangASTContext::GetPluginNameStatic() { @@ -715,13 +713,13 @@ lldb::TypeSystemSP ClangASTContext::CreateInstance(lldb::LanguageType language, new ClangASTContextForExpressions(*target)); if (ast_sp) { ast_sp->SetArchitecture(fixed_arch); - ast_sp->m_scratch_ast_source_ap.reset( + ast_sp->m_scratch_ast_source_up.reset( new ClangASTSource(target->shared_from_this())); lldbassert(ast_sp->getFileManager()); - ast_sp->m_scratch_ast_source_ap->InstallASTContext( + ast_sp->m_scratch_ast_source_up->InstallASTContext( *ast_sp->getASTContext(), *ast_sp->getFileManager(), true); llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source( - ast_sp->m_scratch_ast_source_ap->CreateProxy()); + ast_sp->m_scratch_ast_source_up->CreateProxy()); ast_sp->SetExternalSource(proxy_ast_source); return ast_sp; } @@ -764,37 +762,43 @@ void ClangASTContext::Terminate() { } void ClangASTContext::Finalize() { - if (m_ast_ap.get()) { - GetASTMap().Erase(m_ast_ap.get()); + if (m_ast_up) { + GetASTMap().Erase(m_ast_up.get()); if (!m_ast_owned) - m_ast_ap.release(); + m_ast_up.release(); } - m_builtins_ap.reset(); - m_selector_table_ap.reset(); - m_identifier_table_ap.reset(); - m_target_info_ap.reset(); + m_builtins_up.reset(); + m_selector_table_up.reset(); + m_identifier_table_up.reset(); + m_target_info_up.reset(); m_target_options_rp.reset(); - m_diagnostics_engine_ap.reset(); - m_source_manager_ap.reset(); - m_language_options_ap.reset(); - m_ast_ap.reset(); - m_scratch_ast_source_ap.reset(); + m_diagnostics_engine_up.reset(); + m_source_manager_up.reset(); + m_language_options_up.reset(); + m_ast_up.reset(); + m_scratch_ast_source_up.reset(); } void ClangASTContext::Clear() { - m_ast_ap.reset(); - m_language_options_ap.reset(); - m_source_manager_ap.reset(); - m_diagnostics_engine_ap.reset(); + m_ast_up.reset(); + m_language_options_up.reset(); + m_source_manager_up.reset(); + m_diagnostics_engine_up.reset(); m_target_options_rp.reset(); - m_target_info_ap.reset(); - m_identifier_table_ap.reset(); - m_selector_table_ap.reset(); - m_builtins_ap.reset(); + m_target_info_up.reset(); + m_identifier_table_up.reset(); + m_selector_table_up.reset(); + m_builtins_up.reset(); m_pointer_byte_size = 0; } +void ClangASTContext::setSema(Sema *s) { + // Ensure that the new sema actually belongs to our ASTContext. + assert(s == nullptr || &s->getASTContext() == m_ast_up.get()); + m_sema = s; +} + const char *ClangASTContext::GetTargetTriple() { return m_target_triple.c_str(); } @@ -816,10 +820,10 @@ bool ClangASTContext::HasExternalSource() { } void ClangASTContext::SetExternalSource( - llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_ap) { + llvm::IntrusiveRefCntPtr<ExternalASTSource> &ast_source_up) { ASTContext *ast = getASTContext(); if (ast) { - ast->setExternalSource(ast_source_ap); + ast->setExternalSource(ast_source_up); ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true); } } @@ -828,52 +832,52 @@ void ClangASTContext::RemoveExternalSource() { ASTContext *ast = getASTContext(); if (ast) { - llvm::IntrusiveRefCntPtr<ExternalASTSource> empty_ast_source_ap; - ast->setExternalSource(empty_ast_source_ap); + llvm::IntrusiveRefCntPtr<ExternalASTSource> empty_ast_source_up; + ast->setExternalSource(empty_ast_source_up); ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false); } } void ClangASTContext::setASTContext(clang::ASTContext *ast_ctx) { if (!m_ast_owned) { - m_ast_ap.release(); + m_ast_up.release(); } m_ast_owned = false; - m_ast_ap.reset(ast_ctx); + m_ast_up.reset(ast_ctx); GetASTMap().Insert(ast_ctx, this); } ASTContext *ClangASTContext::getASTContext() { - if (m_ast_ap.get() == nullptr) { + if (m_ast_up == nullptr) { m_ast_owned = true; - m_ast_ap.reset(new ASTContext(*getLanguageOptions(), *getSourceManager(), + m_ast_up.reset(new ASTContext(*getLanguageOptions(), *getSourceManager(), *getIdentifierTable(), *getSelectorTable(), *getBuiltinContext())); - m_ast_ap->getDiagnostics().setClient(getDiagnosticConsumer(), false); + m_ast_up->getDiagnostics().setClient(getDiagnosticConsumer(), false); // This can be NULL if we don't know anything about the architecture or if // the target for an architecture isn't enabled in the llvm/clang that we // built TargetInfo *target_info = getTargetInfo(); if (target_info) - m_ast_ap->InitBuiltinTypes(*target_info); + m_ast_up->InitBuiltinTypes(*target_info); if ((m_callback_tag_decl || m_callback_objc_decl) && m_callback_baton) { - m_ast_ap->getTranslationUnitDecl()->setHasExternalLexicalStorage(); - // m_ast_ap->getTranslationUnitDecl()->setHasExternalVisibleStorage(); + m_ast_up->getTranslationUnitDecl()->setHasExternalLexicalStorage(); + // m_ast_up->getTranslationUnitDecl()->setHasExternalVisibleStorage(); } - GetASTMap().Insert(m_ast_ap.get(), this); + GetASTMap().Insert(m_ast_up.get(), this); - llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_ap( + llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_up( new ClangExternalASTSourceCallbacks( ClangASTContext::CompleteTagDecl, ClangASTContext::CompleteObjCInterfaceDecl, nullptr, ClangASTContext::LayoutRecordType, this)); - SetExternalSource(ast_source_ap); + SetExternalSource(ast_source_up); } - return m_ast_ap.get(); + return m_ast_up.get(); } ClangASTContext *ClangASTContext::GetASTContext(clang::ASTContext *ast) { @@ -882,61 +886,62 @@ ClangASTContext *ClangASTContext::GetASTContext(clang::ASTContext *ast) { } Builtin::Context *ClangASTContext::getBuiltinContext() { - if (m_builtins_ap.get() == nullptr) - m_builtins_ap.reset(new Builtin::Context()); - return m_builtins_ap.get(); + if (m_builtins_up == nullptr) + m_builtins_up.reset(new Builtin::Context()); + return m_builtins_up.get(); } IdentifierTable *ClangASTContext::getIdentifierTable() { - if (m_identifier_table_ap.get() == nullptr) - m_identifier_table_ap.reset( + if (m_identifier_table_up == nullptr) + m_identifier_table_up.reset( new IdentifierTable(*ClangASTContext::getLanguageOptions(), nullptr)); - return m_identifier_table_ap.get(); + return m_identifier_table_up.get(); } LangOptions *ClangASTContext::getLanguageOptions() { - if (m_language_options_ap.get() == nullptr) { - m_language_options_ap.reset(new LangOptions()); - ParseLangArgs(*m_language_options_ap, InputKind::ObjCXX, GetTargetTriple()); - // InitializeLangOptions(*m_language_options_ap, InputKind::ObjCXX); + if (m_language_options_up == nullptr) { + m_language_options_up.reset(new LangOptions()); + ParseLangArgs(*m_language_options_up, InputKind::ObjCXX, GetTargetTriple()); + // InitializeLangOptions(*m_language_options_up, InputKind::ObjCXX); } - return m_language_options_ap.get(); + return m_language_options_up.get(); } SelectorTable *ClangASTContext::getSelectorTable() { - if (m_selector_table_ap.get() == nullptr) - m_selector_table_ap.reset(new SelectorTable()); - return m_selector_table_ap.get(); + if (m_selector_table_up == nullptr) + m_selector_table_up.reset(new SelectorTable()); + return m_selector_table_up.get(); } clang::FileManager *ClangASTContext::getFileManager() { - if (m_file_manager_ap.get() == nullptr) { + if (m_file_manager_up == nullptr) { clang::FileSystemOptions file_system_options; - m_file_manager_ap.reset(new clang::FileManager(file_system_options)); + m_file_manager_up.reset(new clang::FileManager( + file_system_options, FileSystem::Instance().GetVirtualFileSystem())); } - return m_file_manager_ap.get(); + return m_file_manager_up.get(); } clang::SourceManager *ClangASTContext::getSourceManager() { - if (m_source_manager_ap.get() == nullptr) - m_source_manager_ap.reset( + if (m_source_manager_up == nullptr) + m_source_manager_up.reset( new clang::SourceManager(*getDiagnosticsEngine(), *getFileManager())); - return m_source_manager_ap.get(); + return m_source_manager_up.get(); } clang::DiagnosticsEngine *ClangASTContext::getDiagnosticsEngine() { - if (m_diagnostics_engine_ap.get() == nullptr) { + if (m_diagnostics_engine_up == nullptr) { llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs()); - m_diagnostics_engine_ap.reset( + m_diagnostics_engine_up.reset( new DiagnosticsEngine(diag_id_sp, new DiagnosticOptions())); } - return m_diagnostics_engine_ap.get(); + return m_diagnostics_engine_up.get(); } clang::MangleContext *ClangASTContext::getMangleContext() { - if (m_mangle_ctx_ap.get() == nullptr) - m_mangle_ctx_ap.reset(getASTContext()->createMangleContext()); - return m_mangle_ctx_ap.get(); + if (m_mangle_ctx_up == nullptr) + m_mangle_ctx_up.reset(getASTContext()->createMangleContext()); + return m_mangle_ctx_up.get(); } class NullDiagnosticConsumer : public DiagnosticConsumer { @@ -946,7 +951,7 @@ public: } void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, - const clang::Diagnostic &info) { + const clang::Diagnostic &info) override { if (m_log) { llvm::SmallVector<char, 32> diag_str(10); info.FormatDiagnostic(diag_str); @@ -964,16 +969,16 @@ private: }; DiagnosticConsumer *ClangASTContext::getDiagnosticConsumer() { - if (m_diagnostic_consumer_ap.get() == nullptr) - m_diagnostic_consumer_ap.reset(new NullDiagnosticConsumer); + if (m_diagnostic_consumer_up == nullptr) + m_diagnostic_consumer_up.reset(new NullDiagnosticConsumer); - return m_diagnostic_consumer_ap.get(); + return m_diagnostic_consumer_up.get(); } std::shared_ptr<clang::TargetOptions> &ClangASTContext::getTargetOptions() { - if (m_target_options_rp.get() == nullptr && !m_target_triple.empty()) { + if (m_target_options_rp == nullptr && !m_target_triple.empty()) { m_target_options_rp = std::make_shared<clang::TargetOptions>(); - if (m_target_options_rp.get() != nullptr) + if (m_target_options_rp != nullptr) m_target_options_rp->Triple = m_target_triple; } return m_target_options_rp; @@ -981,10 +986,10 @@ std::shared_ptr<clang::TargetOptions> &ClangASTContext::getTargetOptions() { TargetInfo *ClangASTContext::getTargetInfo() { // target_triple should be something like "x86_64-apple-macosx" - if (m_target_info_ap.get() == nullptr && !m_target_triple.empty()) - m_target_info_ap.reset(TargetInfo::CreateTargetInfo(*getDiagnosticsEngine(), + if (m_target_info_up == nullptr && !m_target_triple.empty()) + m_target_info_up.reset(TargetInfo::CreateTargetInfo(*getDiagnosticsEngine(), getTargetOptions())); - return m_target_info_ap.get(); + return m_target_info_up.get(); } #pragma mark Basic Types @@ -1065,7 +1070,7 @@ CompilerType ClangASTContext::GetBuiltinTypeForEncodingAndBitSize( } lldb::BasicType -ClangASTContext::GetBasicTypeEnumeration(const ConstString &name) { +ClangASTContext::GetBasicTypeEnumeration(ConstString name) { if (name) { typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap; static TypeNameToBasicTypeMap g_type_map; @@ -1131,7 +1136,7 @@ ClangASTContext::GetBasicTypeEnumeration(const ConstString &name) { } CompilerType ClangASTContext::GetBasicType(ASTContext *ast, - const ConstString &name) { + ConstString name) { if (ast) { lldb::BasicType basic_type = ClangASTContext::GetBasicTypeEnumeration(name); return ClangASTContext::GetBasicType(ast, basic_type); @@ -1410,7 +1415,14 @@ clang::Decl *ClangASTContext::CopyDecl(ASTContext *dst_ast, ASTContext *src_ast, FileManager file_manager(file_system_options); ASTImporter importer(*dst_ast, file_manager, *src_ast, file_manager, false); - return importer.Import(source_decl); + if (llvm::Expected<clang::Decl *> ret_or_error = + importer.Import(source_decl)) { + return *ret_or_error; + } else { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + LLDB_LOG_ERROR(log, ret_or_error.takeError(), "Couldn't import decl: {0}"); + return nullptr; + } } bool ClangASTContext::AreTypesSame(CompilerType type1, CompilerType type2, @@ -1550,25 +1562,24 @@ static TemplateParameterList *CreateTemplateParameterList( } } - if (template_param_infos.packed_args && - template_param_infos.packed_args->args.size()) { + if (template_param_infos.packed_args) { IdentifierInfo *identifier_info = nullptr; if (template_param_infos.pack_name && template_param_infos.pack_name[0]) identifier_info = &ast->Idents.get(template_param_infos.pack_name); const bool parameter_pack_true = true; - if (IsValueParam(template_param_infos.packed_args->args[0])) { + + if (!template_param_infos.packed_args->args.empty() && + IsValueParam(template_param_infos.packed_args->args[0])) { template_param_decls.push_back(NonTypeTemplateParmDecl::Create( - *ast, decl_context, - SourceLocation(), SourceLocation(), depth, num_template_params, - identifier_info, + *ast, decl_context, SourceLocation(), SourceLocation(), depth, + num_template_params, identifier_info, template_param_infos.packed_args->args[0].getIntegralType(), parameter_pack_true, nullptr)); } else { template_param_decls.push_back(TemplateTypeParmDecl::Create( - *ast, decl_context, - SourceLocation(), SourceLocation(), depth, num_template_params, - identifier_info, - is_typename, parameter_pack_true)); + *ast, decl_context, SourceLocation(), SourceLocation(), depth, + num_template_params, identifier_info, is_typename, + parameter_pack_true)); } } clang::Expr *const requires_clause = nullptr; // TODO: Concepts @@ -1604,10 +1615,11 @@ clang::FunctionTemplateDecl *ClangASTContext::CreateFunctionTemplateDecl( void ClangASTContext::CreateFunctionTemplateSpecializationInfo( FunctionDecl *func_decl, clang::FunctionTemplateDecl *func_tmpl_decl, const TemplateParameterInfos &infos) { - TemplateArgumentList template_args(TemplateArgumentList::OnStack, infos.args); + TemplateArgumentList *template_args_ptr = + TemplateArgumentList::CreateCopy(func_decl->getASTContext(), infos.args); - func_decl->setFunctionTemplateSpecialization(func_tmpl_decl, &template_args, - nullptr); + func_decl->setFunctionTemplateSpecialization(func_tmpl_decl, + template_args_ptr, nullptr); } ClassTemplateDecl *ClangASTContext::CreateClassTemplateDecl( @@ -1656,6 +1668,7 @@ ClassTemplateDecl *ClangASTContext::CreateClassTemplateDecl( decl_ctx, // What decl context do we use here? TU? The actual decl // context? SourceLocation(), decl_name, template_param_list, template_cxx_decl); + template_cxx_decl->setDescribedClassTemplate(class_template_decl); if (class_template_decl) { if (access_type != eAccessNone) @@ -1893,9 +1906,8 @@ ClangASTContext::GetNumBaseClasses(const CXXRecordDecl *cxx_record_decl, #pragma mark Namespace Declarations -NamespaceDecl * -ClangASTContext::GetUniqueNamespaceDeclaration(const char *name, - DeclContext *decl_ctx) { +NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration( + const char *name, DeclContext *decl_ctx, bool is_inline) { NamespaceDecl *namespace_decl = nullptr; ASTContext *ast = getASTContext(); TranslationUnitDecl *translation_unit_decl = ast->getTranslationUnitDecl(); @@ -1913,7 +1925,7 @@ ClangASTContext::GetUniqueNamespaceDeclaration(const char *name, } namespace_decl = - NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(), + NamespaceDecl::Create(*ast, decl_ctx, is_inline, SourceLocation(), SourceLocation(), &identifier_info, nullptr); decl_ctx->addDecl(namespace_decl); @@ -1943,7 +1955,8 @@ ClangASTContext::GetUniqueNamespaceDeclaration(const char *name, assert(namespace_decl == parent_namespace_decl->getAnonymousNamespace()); } else { - // BAD!!! + assert(false && "GetUniqueNamespaceDeclaration called with no name and " + "no namespace as decl_ctx"); } } } @@ -1954,12 +1967,13 @@ ClangASTContext::GetUniqueNamespaceDeclaration(const char *name, } NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration( - clang::ASTContext *ast, const char *name, clang::DeclContext *decl_ctx) { + clang::ASTContext *ast, const char *name, clang::DeclContext *decl_ctx, + bool is_inline) { ClangASTContext *ast_ctx = ClangASTContext::GetASTContext(ast); if (ast_ctx == nullptr) return nullptr; - return ast_ctx->GetUniqueNamespaceDeclaration(name, decl_ctx); + return ast_ctx->GetUniqueNamespaceDeclaration(name, decl_ctx, is_inline); } clang::BlockDecl * @@ -2158,7 +2172,7 @@ FunctionDecl *ClangASTContext::CreateFunctionDeclaration( *ast, decl_ctx, SourceLocation(), SourceLocation(), declarationName, ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage, is_inline, hasWrittenPrototype, - isConstexprSpecified); + isConstexprSpecified ? CSK_constexpr : CSK_unspecified); if (func_decl) decl_ctx->addDecl(func_decl); @@ -2234,7 +2248,7 @@ void ClangASTContext::SetFunctionParameters(FunctionDecl *function_decl, CompilerType ClangASTContext::CreateBlockPointerType(const CompilerType &function_type) { - QualType block_type = m_ast_ap->getBlockPointerType( + QualType block_type = m_ast_up->getBlockPointerType( clang::QualType::getFromOpaquePtr(function_type.GetOpaqueQualType())); return CompilerType(this, block_type.getAsOpaquePtr()); @@ -2272,7 +2286,7 @@ CompilerType ClangASTContext::CreateArrayType(const CompilerType &element_type, } CompilerType ClangASTContext::CreateStructForIdentifier( - const ConstString &type_name, + ConstString type_name, const std::initializer_list<std::pair<const char *, CompilerType>> &type_fields, bool packed) { @@ -2297,7 +2311,7 @@ CompilerType ClangASTContext::CreateStructForIdentifier( } CompilerType ClangASTContext::GetOrCreateStructForIdentifier( - const ConstString &type_name, + ConstString type_name, const std::initializer_list<std::pair<const char *, CompilerType>> &type_fields, bool packed) { @@ -2435,21 +2449,17 @@ void ClangASTContext::DumpDeclHiearchy(clang::Decl *decl) { bool ClangASTContext::DeclsAreEquivalent(clang::Decl *lhs_decl, clang::Decl *rhs_decl) { if (lhs_decl && rhs_decl) { - //---------------------------------------------------------------------- // Make sure the decl kinds match first - //---------------------------------------------------------------------- const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind(); const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind(); if (lhs_decl_kind == rhs_decl_kind) { - //------------------------------------------------------------------ // Now check that the decl contexts kinds are all equivalent before we // have to check any names of the decl contexts... - //------------------------------------------------------------------ clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext(); clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext(); if (lhs_decl_ctx && rhs_decl_ctx) { - while (1) { + while (true) { if (lhs_decl_ctx && rhs_decl_ctx) { const clang::Decl::Kind lhs_decl_ctx_kind = lhs_decl_ctx->getDeclKind(); @@ -2467,9 +2477,7 @@ bool ClangASTContext::DeclsAreEquivalent(clang::Decl *lhs_decl, return false; } - //-------------------------------------------------------------- // Now make sure the name of the decls match - //-------------------------------------------------------------- clang::NamedDecl *lhs_named_decl = llvm::dyn_cast<clang::NamedDecl>(lhs_decl); clang::NamedDecl *rhs_named_decl = @@ -2485,13 +2493,11 @@ bool ClangASTContext::DeclsAreEquivalent(clang::Decl *lhs_decl, } else return false; - //-------------------------------------------------------------- // We know that the decl context kinds all match, so now we need to // make sure the names match as well - //-------------------------------------------------------------- lhs_decl_ctx = lhs_decl->getDeclContext(); rhs_decl_ctx = rhs_decl->getDeclContext(); - while (1) { + while (true) { switch (lhs_decl_ctx->getDeclKind()) { case clang::Decl::TranslationUnit: // We don't care about the translation unit names @@ -2830,9 +2836,7 @@ ConvertAccessTypeToObjCIvarAccessControl(AccessType access) { return clang::ObjCIvarDecl::None; } -//---------------------------------------------------------------------- // Tests -//---------------------------------------------------------------------- bool ClangASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) { clang::QualType qual_type(GetCanonicalQualType(type)); @@ -3324,7 +3328,7 @@ bool ClangASTContext::IsBlockPointerType( const clang::BlockPointerType *block_pointer_type = qual_type->getAs<clang::BlockPointerType>(); QualType pointee_type = block_pointer_type->getPointeeType(); - QualType function_pointer_type = m_ast_ap->getPointerType(pointee_type); + QualType function_pointer_type = m_ast_up->getPointerType(pointee_type); *function_pointer_type_ptr = CompilerType(getASTContext(), function_pointer_type); } @@ -3909,6 +3913,14 @@ bool ClangASTContext::IsVoidType(lldb::opaque_compiler_type_t type) { return GetCanonicalQualType(type)->isVoidType(); } +bool ClangASTContext::CanPassInRegisters(const CompilerType &type) { + if (auto *record_decl = + ClangASTContext::GetAsRecordDecl(type)) { + return record_decl->canPassInRegisters(); + } + return false; +} + bool ClangASTContext::SupportsLanguage(lldb::LanguageType language) { return ClangASTContextSupportsLanguage(language); } @@ -3994,9 +4006,7 @@ bool ClangASTContext::GetObjCClassName(const CompilerType &type, return false; } -//---------------------------------------------------------------------- // Type Completion -//---------------------------------------------------------------------- bool ClangASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) { if (!type) @@ -4264,9 +4274,11 @@ ClangASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) { if (qual_type->isAnyPointerType()) { if (qual_type->isObjCObjectPointerType()) return lldb::eLanguageTypeObjC; + if (qual_type->getPointeeCXXRecordDecl()) + return lldb::eLanguageTypeC_plus_plus; clang::QualType pointee_type(qual_type->getPointeeType()); - if (pointee_type->getPointeeCXXRecordDecl() != nullptr) + if (pointee_type->getPointeeCXXRecordDecl()) return lldb::eLanguageTypeC_plus_plus; if (pointee_type->isObjCObjectOrInterfaceType()) return lldb::eLanguageTypeObjC; @@ -4474,6 +4486,8 @@ ClangASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) { case clang::Type::DependentAddressSpace: break; + case clang::Type::MacroQualified: + break; } // We don't know hot to display this type... return lldb::eTypeClassOther; @@ -4485,9 +4499,7 @@ unsigned ClangASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) { return 0; } -//---------------------------------------------------------------------- // Creating related types -//---------------------------------------------------------------------- CompilerType ClangASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type, @@ -4999,19 +5011,16 @@ ClangASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) { return CompilerType(); } -//---------------------------------------------------------------------- // Create related types using the current type's AST -//---------------------------------------------------------------------- CompilerType ClangASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) { return ClangASTContext::GetBasicType(getASTContext(), basic_type); } -//---------------------------------------------------------------------- // Exploring the type -//---------------------------------------------------------------------- -uint64_t ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type, - ExecutionContextScope *exe_scope) { +Optional<uint64_t> +ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) { if (GetCompleteType(type)) { clang::QualType qual_type(GetCanonicalQualType(type)); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); @@ -5020,7 +5029,7 @@ uint64_t ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type, if (GetCompleteType(type)) return getASTContext()->getTypeSize(qual_type); else - return 0; + return None; break; case clang::Type::ObjCInterface: @@ -5028,7 +5037,7 @@ uint64_t ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type, ExecutionContext exe_ctx(exe_scope); Process *process = exe_ctx.GetProcessPtr(); if (process) { - ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime(); + ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process); if (objc_runtime) { uint64_t bit_size = 0; if (objc_runtime->GetTypeBitSize( @@ -5065,10 +5074,14 @@ uint64_t ClangASTContext::GetBitSize(lldb::opaque_compiler_type_t type, return bit_size + getASTContext()->getTypeSize( getASTContext()->ObjCBuiltinClassTy); - return bit_size; + // Function types actually have a size of 0, that's not an error. + if (qual_type->isFunctionProtoType()) + return bit_size; + if (bit_size) + return bit_size; } } - return 0; + return None; } size_t ClangASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type) { @@ -5343,6 +5356,8 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type, case clang::Type::DependentAddressSpace: break; + case clang::Type::MacroQualified: + break; } count = 0; return lldb::eEncodingInvalid; @@ -5510,6 +5525,8 @@ lldb::Format ClangASTContext::GetFormat(lldb::opaque_compiler_type_t type) { case clang::Type::DependentAddressSpace: break; + case clang::Type::MacroQualified: + break; } // We don't know hot to display this type... return lldb::eFormatBytes; @@ -5734,7 +5751,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, return num_children; } -CompilerType ClangASTContext::GetBuiltinTypeByName(const ConstString &name) { +CompilerType ClangASTContext::GetBuiltinTypeByName(ConstString name) { return GetBasicType(GetBasicTypeEnumeration(name)); } @@ -5814,7 +5831,7 @@ ClangASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) { void ClangASTContext::ForEachEnumerator( lldb::opaque_compiler_type_t type, std::function<bool(const CompilerType &integer_type, - const ConstString &name, + ConstString name, const llvm::APSInt &value)> const &callback) { const clang::EnumType *enum_type = llvm::dyn_cast<clang::EnumType>(GetCanonicalQualType(type)); @@ -6827,7 +6844,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( process = exe_ctx->GetProcessPtr(); if (process) { ObjCLanguageRuntime *objc_runtime = - process->GetObjCLanguageRuntime(); + ObjCLanguageRuntime::Get(*process); if (objc_runtime != nullptr) { CompilerType parent_ast_type(getASTContext(), parent_qual_type); @@ -6887,7 +6904,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( } else { child_is_deref_of_parent = true; const char *parent_name = - valobj ? valobj->GetName().GetCString() : NULL; + valobj ? valobj->GetName().GetCString() : nullptr; if (parent_name) { child_name.assign(1, '*'); child_name += parent_name; @@ -6968,7 +6985,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( child_is_deref_of_parent = true; const char *parent_name = - valobj ? valobj->GetName().GetCString() : NULL; + valobj ? valobj->GetName().GetCString() : nullptr; if (parent_name) { child_name.assign(1, '*'); child_name += parent_name; @@ -7005,7 +7022,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( language_flags); } else { const char *parent_name = - valobj ? valobj->GetName().GetCString() : NULL; + valobj ? valobj->GetName().GetCString() : nullptr; if (parent_name) { child_name.assign(1, '&'); child_name += parent_name; @@ -7835,7 +7852,7 @@ clang::EnumDecl *ClangASTContext::GetAsEnumDecl(const CompilerType &type) { llvm::dyn_cast<clang::EnumType>(ClangUtil::GetCanonicalQualType(type)); if (enutype) return enutype->getDecl(); - return NULL; + return nullptr; } clang::RecordDecl *ClangASTContext::GetAsRecordDecl(const CompilerType &type) { @@ -8173,6 +8190,10 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType( if (is_artificial) return nullptr; // skip everything artificial + const clang::ExplicitSpecifier explicit_spec( + nullptr /*expr*/, is_explicit + ? clang::ExplicitSpecKind::ResolvedTrue + : clang::ExplicitSpecKind::ResolvedFalse); if (name[0] == '~') { cxx_dtor_decl = clang::CXXDestructorDecl::Create( *getASTContext(), cxx_record_decl, clang::SourceLocation(), @@ -8191,7 +8212,7 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType( clang::SourceLocation()), method_qual_type, nullptr, // TypeSourceInfo * - is_explicit, is_inline, is_artificial, false /*is_constexpr*/); + explicit_spec, is_inline, is_artificial, CSK_unspecified); cxx_method_decl = cxx_ctor_decl; } else { clang::StorageClass SC = is_static ? clang::SC_Static : clang::SC_None; @@ -8214,7 +8235,7 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType( clang::SourceLocation()), method_qual_type, nullptr, // TypeSourceInfo * - SC, is_inline, false /*is_constexpr*/, clang::SourceLocation()); + SC, is_inline, CSK_unspecified, clang::SourceLocation()); } else if (num_params == 0) { // Conversion operators don't take params... cxx_method_decl = clang::CXXConversionDecl::Create( @@ -8226,7 +8247,7 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType( clang::SourceLocation()), method_qual_type, nullptr, // TypeSourceInfo * - is_inline, is_explicit, false /*is_constexpr*/, + is_inline, explicit_spec, CSK_unspecified, clang::SourceLocation()); } } @@ -8237,7 +8258,7 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType( clang::DeclarationNameInfo(decl_name, clang::SourceLocation()), method_qual_type, nullptr, // TypeSourceInfo * - SC, is_inline, false /*is_constexpr*/, clang::SourceLocation()); + SC, is_inline, CSK_unspecified, clang::SourceLocation()); } } @@ -8250,7 +8271,7 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType( if (is_attr_used) cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(*getASTContext())); - if (mangled_name != NULL) { + if (mangled_name != nullptr) { cxx_method_decl->addAttr( clang::AsmLabelAttr::CreateImplicit(*getASTContext(), mangled_name)); } @@ -9076,11 +9097,19 @@ ClangASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, return 0; } -//---------------------------------------------------------------------- // Dumping types -//---------------------------------------------------------------------- #define DEPTH_INCREMENT 2 +#ifndef NDEBUG +LLVM_DUMP_METHOD void +ClangASTContext::dump(lldb::opaque_compiler_type_t type) const { + if (!type) + return; + clang::QualType qual_type(GetQualType(type)); + qual_type.dump(); +} +#endif + void ClangASTContext::Dump(Stream &s) { Decl *tu = Decl::castFromDeclContext(GetTranslationUnitDecl()); tu->dump(s.AsRawOstream()); @@ -9610,7 +9639,7 @@ bool ClangASTContext::DumpTypeValue( break; } } - return 0; + return false; } void ClangASTContext::DumpSummary(lldb::opaque_compiler_type_t type, @@ -9849,7 +9878,7 @@ clang::ClassTemplateDecl *ClangASTContext::ParseClassTemplateDecl( template_basename.c_str(), tag_decl_kind, template_param_infos); } - return NULL; + return nullptr; } void ClangASTContext::CompleteTagDecl(void *baton, clang::TagDecl *decl) { @@ -9874,15 +9903,15 @@ void ClangASTContext::CompleteObjCInterfaceDecl( } DWARFASTParser *ClangASTContext::GetDWARFParser() { - if (!m_dwarf_ast_parser_ap) - m_dwarf_ast_parser_ap.reset(new DWARFASTParserClang(*this)); - return m_dwarf_ast_parser_ap.get(); + if (!m_dwarf_ast_parser_up) + m_dwarf_ast_parser_up.reset(new DWARFASTParserClang(*this)); + return m_dwarf_ast_parser_up.get(); } PDBASTParser *ClangASTContext::GetPDBParser() { - if (!m_pdb_ast_parser_ap) - m_pdb_ast_parser_ap.reset(new PDBASTParser(*this)); - return m_pdb_ast_parser_ap.get(); + if (!m_pdb_ast_parser_up) + m_pdb_ast_parser_up.reset(new PDBASTParser(*this)); + return m_pdb_ast_parser_up.get(); } bool ClangASTContext::LayoutRecordType( @@ -9895,10 +9924,10 @@ bool ClangASTContext::LayoutRecordType( &vbase_offsets) { ClangASTContext *ast = (ClangASTContext *)baton; lldb_private::ClangASTImporter *importer = nullptr; - if (ast->m_dwarf_ast_parser_ap) - importer = &ast->m_dwarf_ast_parser_ap->GetClangASTImporter(); - if (!importer && ast->m_pdb_ast_parser_ap) - importer = &ast->m_pdb_ast_parser_ap->GetClangASTImporter(); + if (ast->m_dwarf_ast_parser_up) + importer = &ast->m_dwarf_ast_parser_up->GetClangASTImporter(); + if (!importer && ast->m_pdb_ast_parser_up) + importer = &ast->m_pdb_ast_parser_up->GetClangASTImporter(); if (!importer) return false; @@ -9906,9 +9935,7 @@ bool ClangASTContext::LayoutRecordType( field_offsets, base_offsets, vbase_offsets); } -//---------------------------------------------------------------------- // CompilerDecl override functions -//---------------------------------------------------------------------- ConstString ClangASTContext::DeclGetName(void *opaque_decl) { if (opaque_decl) { @@ -9996,9 +10023,7 @@ CompilerType ClangASTContext::DeclGetFunctionArgumentType(void *opaque_decl, return CompilerType(); } -//---------------------------------------------------------------------- // CompilerDeclContext functions -//---------------------------------------------------------------------- std::vector<CompilerDecl> ClangASTContext::DeclContextFindDeclByName( void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) { @@ -10249,6 +10274,23 @@ bool ClangASTContext::DeclContextIsClassMethod( return false; } +bool ClangASTContext::DeclContextIsContainedInLookup( + void *opaque_decl_ctx, void *other_opaque_decl_ctx) { + auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx; + auto *other = (clang::DeclContext *)other_opaque_decl_ctx; + + do { + // A decl context always includes its own contents in its lookup. + if (decl_ctx == other) + return true; + + // If we have an inline namespace, then the lookup of the parent context + // also includes the inline namespace contents. + } while (other->isInlineNamespace() && (other = other->getParent())); + + return false; +} + clang::DeclContext * ClangASTContext::DeclContextGetAsDeclContext(const CompilerDeclContext &dc) { if (dc.IsClang()) @@ -10314,13 +10356,14 @@ ClangASTContextForExpressions::ClangASTContextForExpressions(Target &target) UserExpression *ClangASTContextForExpressions::GetUserExpression( llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, Expression::ResultType desired_type, - const EvaluateExpressionOptions &options) { + const EvaluateExpressionOptions &options, + ValueObject *ctx_obj) { TargetSP target_sp = m_target_wp.lock(); if (!target_sp) return nullptr; return new ClangUserExpression(*target_sp.get(), expr, prefix, language, - desired_type, options); + desired_type, options, ctx_obj); } FunctionCaller *ClangASTContextForExpressions::GetFunctionCaller( @@ -10355,6 +10398,6 @@ ClangASTContextForExpressions::GetPersistentExpressionState() { clang::ExternalASTMerger & ClangASTContextForExpressions::GetMergerUnchecked() { - lldbassert(m_scratch_ast_source_ap != nullptr); - return m_scratch_ast_source_ap->GetMergerUnchecked(); + lldbassert(m_scratch_ast_source_up != nullptr); + return m_scratch_ast_source_up->GetMergerUnchecked(); } diff --git a/source/Symbol/ClangASTImporter.cpp b/source/Symbol/ClangASTImporter.cpp index 621441449c208..32d0c47693b0e 100644 --- a/source/Symbol/ClangASTImporter.cpp +++ b/source/Symbol/ClangASTImporter.cpp @@ -1,9 +1,8 @@ //===-- ClangASTImporter.cpp ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -17,8 +16,12 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/Sema/Lookup.h" +#include "clang/Sema/Sema.h" #include "llvm/Support/raw_ostream.h" +#include <memory> + using namespace lldb_private; using namespace clang; @@ -55,12 +58,22 @@ void ClangASTMetrics::DumpCounters(Log *log) { clang::QualType ClangASTImporter::CopyType(clang::ASTContext *dst_ast, clang::ASTContext *src_ast, clang::QualType type) { - MinionSP minion_sp(GetMinion(dst_ast, src_ast)); + ImporterDelegateSP delegate_sp(GetDelegate(dst_ast, src_ast)); - if (minion_sp) - return minion_sp->Import(type); + ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast); - return QualType(); + if (!delegate_sp) + return QualType(); + + llvm::Expected<QualType> ret_or_error = delegate_sp->Import(type); + if (!ret_or_error) { + Log *log = + lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + LLDB_LOG_ERROR(log, ret_or_error.takeError(), + "Couldn't import type: {0}"); + return QualType(); + } + return *ret_or_error; } lldb::opaque_compiler_type_t @@ -94,38 +107,39 @@ CompilerType ClangASTImporter::CopyType(ClangASTContext &dst_ast, clang::Decl *ClangASTImporter::CopyDecl(clang::ASTContext *dst_ast, clang::ASTContext *src_ast, clang::Decl *decl) { - MinionSP minion_sp; + ImporterDelegateSP delegate_sp; - minion_sp = GetMinion(dst_ast, src_ast); + delegate_sp = GetDelegate(dst_ast, src_ast); - if (minion_sp) { - clang::Decl *result = minion_sp->Import(decl); + ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, dst_ast); - if (!result) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + if (!delegate_sp) + return nullptr; - if (log) { - lldb::user_id_t user_id = LLDB_INVALID_UID; - ClangASTMetadata *metadata = GetDeclMetadata(decl); - if (metadata) - user_id = metadata->GetUserID(); - - if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl)) - log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s " - "'%s', metadata 0x%" PRIx64, - decl->getDeclKindName(), - named_decl->getNameAsString().c_str(), user_id); - else - log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s, " - "metadata 0x%" PRIx64, - decl->getDeclKindName(), user_id); - } + llvm::Expected<clang::Decl *> result = delegate_sp->Import(decl); + if (!result) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + LLDB_LOG_ERROR(log, result.takeError(), "Couldn't import decl: {0}"); + if (log) { + lldb::user_id_t user_id = LLDB_INVALID_UID; + ClangASTMetadata *metadata = GetDeclMetadata(decl); + if (metadata) + user_id = metadata->GetUserID(); + + if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl)) + log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s " + "'%s', metadata 0x%" PRIx64, + decl->getDeclKindName(), + named_decl->getNameAsString().c_str(), user_id); + else + log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s, " + "metadata 0x%" PRIx64, + decl->getDeclKindName(), user_id); } - - return result; + return nullptr; } - return nullptr; + return *result; } class DeclContextOverride { @@ -247,9 +261,9 @@ ClangASTImporter::DeportType(clang::ASTContext *dst_ctx, (unsigned long long)type, static_cast<void *>(src_ctx), static_cast<void *>(dst_ctx)); - MinionSP minion_sp(GetMinion(dst_ctx, src_ctx)); + ImporterDelegateSP delegate_sp(GetDelegate(dst_ctx, src_ctx)); - if (!minion_sp) + if (!delegate_sp) return nullptr; std::set<NamedDecl *> decls_to_deport; @@ -263,11 +277,11 @@ ClangASTImporter::DeportType(clang::ASTContext *dst_ctx, tag_type->getDecl()); } - minion_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported); + delegate_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported); lldb::opaque_compiler_type_t result = CopyType(dst_ctx, src_ctx, type); - minion_sp->ExecuteDeportWorkQueues(); + delegate_sp->ExecuteDeportWorkQueues(); if (!result) return nullptr; @@ -286,9 +300,9 @@ clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx, decl->getDeclKindName(), static_cast<void *>(decl), static_cast<void *>(src_ctx), static_cast<void *>(dst_ctx)); - MinionSP minion_sp(GetMinion(dst_ctx, src_ctx)); + ImporterDelegateSP delegate_sp(GetDelegate(dst_ctx, src_ctx)); - if (!minion_sp) + if (!delegate_sp) return nullptr; std::set<NamedDecl *> decls_to_deport; @@ -298,11 +312,11 @@ clang::Decl *ClangASTImporter::DeportDecl(clang::ASTContext *dst_ctx, decl_context_override.OverrideAllDeclsFromContainingFunction(decl); - minion_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported); + delegate_sp->InitDeportWorkQueues(&decls_to_deport, &decls_already_deported); clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl); - minion_sp->ExecuteDeportWorkQueues(); + delegate_sp->ExecuteDeportWorkQueues(); if (!result) return nullptr; @@ -332,7 +346,7 @@ bool ClangASTImporter::CanImport(const CompilerType &type) { const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); if (cxx_record_decl) { - if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL)) + if (ResolveDeclOrigin(cxx_record_decl, nullptr, nullptr)) return true; } } break; @@ -341,7 +355,7 @@ bool ClangASTImporter::CanImport(const CompilerType &type) { clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); if (enum_decl) { - if (ResolveDeclOrigin(enum_decl, NULL, NULL)) + if (ResolveDeclOrigin(enum_decl, nullptr, nullptr)) return true; } } break; @@ -356,7 +370,7 @@ bool ClangASTImporter::CanImport(const CompilerType &type) { // We currently can't complete objective C types through the newly added // ASTContext because it only supports TagDecl objects right now... if (class_interface_decl) { - if (ResolveDeclOrigin(class_interface_decl, NULL, NULL)) + if (ResolveDeclOrigin(class_interface_decl, nullptr, nullptr)) return true; } } @@ -408,7 +422,7 @@ bool ClangASTImporter::Import(const CompilerType &type) { const clang::CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); if (cxx_record_decl) { - if (ResolveDeclOrigin(cxx_record_decl, NULL, NULL)) + if (ResolveDeclOrigin(cxx_record_decl, nullptr, nullptr)) return CompleteAndFetchChildren(qual_type); } } break; @@ -417,7 +431,7 @@ bool ClangASTImporter::Import(const CompilerType &type) { clang::EnumDecl *enum_decl = llvm::cast<clang::EnumType>(qual_type)->getDecl(); if (enum_decl) { - if (ResolveDeclOrigin(enum_decl, NULL, NULL)) + if (ResolveDeclOrigin(enum_decl, nullptr, nullptr)) return CompleteAndFetchChildren(qual_type); } } break; @@ -432,7 +446,7 @@ bool ClangASTImporter::Import(const CompilerType &type) { // We currently can't complete objective C types through the newly added // ASTContext because it only supports TagDecl objects right now... if (class_interface_decl) { - if (ResolveDeclOrigin(class_interface_decl, NULL, NULL)) + if (ResolveDeclOrigin(class_interface_decl, nullptr, nullptr)) return CompleteAndFetchChildren(qual_type); } } @@ -554,10 +568,13 @@ bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) { if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) return false; - MinionSP minion_sp(GetMinion(&decl->getASTContext(), decl_origin.ctx)); + ImporterDelegateSP delegate_sp( + GetDelegate(&decl->getASTContext(), decl_origin.ctx)); - if (minion_sp) - minion_sp->ImportDefinitionTo(decl, decl_origin.decl); + ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, + &decl->getASTContext()); + if (delegate_sp) + delegate_sp->ImportDefinitionTo(decl, decl_origin.decl); return true; } @@ -571,10 +588,11 @@ bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl, if (!ClangASTContext::GetCompleteDecl(origin_ast_ctx, origin_decl)) return false; - MinionSP minion_sp(GetMinion(&decl->getASTContext(), origin_ast_ctx)); + ImporterDelegateSP delegate_sp( + GetDelegate(&decl->getASTContext(), origin_ast_ctx)); - if (minion_sp) - minion_sp->ImportDefinitionTo(decl, origin_decl); + if (delegate_sp) + delegate_sp->ImportDefinitionTo(decl, origin_decl); ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext()); @@ -597,11 +615,11 @@ bool ClangASTImporter::CompleteObjCInterfaceDecl( if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) return false; - MinionSP minion_sp( - GetMinion(&interface_decl->getASTContext(), decl_origin.ctx)); + ImporterDelegateSP delegate_sp( + GetDelegate(&interface_decl->getASTContext(), decl_origin.ctx)); - if (minion_sp) - minion_sp->ImportDefinitionTo(interface_decl, decl_origin.decl); + if (delegate_sp) + delegate_sp->ImportDefinitionTo(interface_decl, decl_origin.decl); if (ObjCInterfaceDecl *super_class = interface_decl->getSuperClass()) RequireCompleteType(clang::QualType(super_class->getTypeForDecl(), 0)); @@ -613,6 +631,8 @@ bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) { if (!RequireCompleteType(type)) return false; + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + if (const TagType *tag_type = type->getAs<TagType>()) { TagDecl *tag_decl = tag_type->getDecl(); @@ -621,12 +641,22 @@ bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) { if (!decl_origin.Valid()) return false; - MinionSP minion_sp(GetMinion(&tag_decl->getASTContext(), decl_origin.ctx)); + ImporterDelegateSP delegate_sp( + GetDelegate(&tag_decl->getASTContext(), decl_origin.ctx)); + + ASTImporterDelegate::CxxModuleScope std_scope(*delegate_sp, + &tag_decl->getASTContext()); TagDecl *origin_tag_decl = llvm::dyn_cast<TagDecl>(decl_origin.decl); for (Decl *origin_child_decl : origin_tag_decl->decls()) { - minion_sp->Import(origin_child_decl); + llvm::Expected<Decl *> imported_or_err = + delegate_sp->Import(origin_child_decl); + if (!imported_or_err) { + LLDB_LOG_ERROR(log, imported_or_err.takeError(), + "Couldn't import decl: {0}"); + return false; + } } if (RecordDecl *record_decl = dyn_cast<RecordDecl>(origin_tag_decl)) { @@ -644,14 +674,20 @@ bool ClangASTImporter::CompleteAndFetchChildren(clang::QualType type) { if (!decl_origin.Valid()) return false; - MinionSP minion_sp( - GetMinion(&objc_interface_decl->getASTContext(), decl_origin.ctx)); + ImporterDelegateSP delegate_sp( + GetDelegate(&objc_interface_decl->getASTContext(), decl_origin.ctx)); ObjCInterfaceDecl *origin_interface_decl = llvm::dyn_cast<ObjCInterfaceDecl>(decl_origin.decl); for (Decl *origin_child_decl : origin_interface_decl->decls()) { - minion_sp->Import(origin_child_decl); + llvm::Expected<Decl *> imported_or_err = + delegate_sp->Import(origin_child_decl); + if (!imported_or_err) { + LLDB_LOG_ERROR(log, imported_or_err.takeError(), + "Couldn't import decl: {0}"); + return false; + } } return true; @@ -766,7 +802,7 @@ void ClangASTImporter::BuildNamespaceMap(const clang::NamespaceDecl *decl) { NamespaceMapSP new_map; - new_map.reset(new NamespaceMap); + new_map = std::make_shared<NamespaceMap>(); if (context_md->m_map_completer) { std::string namespace_string = decl->getDeclName().getAsString(); @@ -802,7 +838,7 @@ void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast, if (!md) return; - md->m_minions.erase(src_ast); + md->m_delegates.erase(src_ast); for (OriginMap::iterator iter = md->m_origins.begin(); iter != md->m_origins.end();) { @@ -815,7 +851,25 @@ void ClangASTImporter::ForgetSource(clang::ASTContext *dst_ast, ClangASTImporter::MapCompleter::~MapCompleter() { return; } -void ClangASTImporter::Minion::InitDeportWorkQueues( +llvm::Expected<Decl *> +ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) { + if (m_std_handler) { + llvm::Optional<Decl *> D = m_std_handler->Import(From); + if (D) { + // Make sure we don't use this decl later to map it back to it's original + // decl. The decl the CxxModuleHandler created has nothing to do with + // the one from debug info, and linking those two would just cause the + // ASTImporter to try 'updating' the module decl with the minimal one from + // the debug info. + m_decls_to_ignore.insert(*D); + return *D; + } + } + + return ASTImporter::ImportImpl(From); +} + +void ClangASTImporter::ASTImporterDelegate::InitDeportWorkQueues( std::set<clang::NamedDecl *> *decls_to_deport, std::set<clang::NamedDecl *> *decls_already_deported) { assert(!m_decls_to_deport); @@ -825,7 +879,7 @@ void ClangASTImporter::Minion::InitDeportWorkQueues( m_decls_already_deported = decls_already_deported; } -void ClangASTImporter::Minion::ExecuteDeportWorkQueues() { +void ClangASTImporter::ASTImporterDelegate::ExecuteDeportWorkQueues() { assert(m_decls_to_deport); assert(m_decls_already_deported); @@ -872,8 +926,8 @@ void ClangASTImporter::Minion::ExecuteDeportWorkQueues() { m_decls_already_deported = nullptr; } -void ClangASTImporter::Minion::ImportDefinitionTo(clang::Decl *to, - clang::Decl *from) { +void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo( + clang::Decl *to, clang::Decl *from) { ASTImporter::Imported(from, to); /* @@ -886,11 +940,39 @@ void ClangASTImporter::Minion::ImportDefinitionTo(clang::Decl *to, to_cxx_record->startDefinition(); */ - ImportDefinition(from); + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + + if (llvm::Error err = ImportDefinition(from)) { + LLDB_LOG_ERROR(log, std::move(err), + "[ClangASTImporter] Error during importing definition: {0}"); + return; + } if (clang::TagDecl *to_tag = dyn_cast<clang::TagDecl>(to)) { if (clang::TagDecl *from_tag = dyn_cast<clang::TagDecl>(from)) { to_tag->setCompleteDefinition(from_tag->isCompleteDefinition()); + + if (Log *log_ast = + lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST)) { + std::string name_string; + if (NamedDecl *from_named_decl = dyn_cast<clang::NamedDecl>(from)) { + llvm::raw_string_ostream name_stream(name_string); + from_named_decl->printName(name_stream); + name_stream.flush(); + } + LLDB_LOG(log_ast, "==== [ClangASTImporter][TUDecl: {0}] Imported " + "({1}Decl*){2}, named {3} (from " + "(Decl*){4})", + static_cast<void *>(to->getTranslationUnitDecl()), + from->getDeclKindName(), static_cast<void *>(to), name_string, + static_cast<void *>(from)); + + // Log the AST of the TU. + std::string ast_string; + llvm::raw_string_ostream ast_stream(ast_string); + to->getTranslationUnitDecl()->dump(ast_stream); + LLDB_LOG(log_ast, "{0}", ast_string); + } } } @@ -916,13 +998,17 @@ void ClangASTImporter::Minion::ImportDefinitionTo(clang::Decl *to, if (!from_superclass) break; - Decl *imported_from_superclass_decl = Import(from_superclass); + llvm::Expected<Decl *> imported_from_superclass_decl = + Import(from_superclass); - if (!imported_from_superclass_decl) + if (!imported_from_superclass_decl) { + LLDB_LOG_ERROR(log, imported_from_superclass_decl.takeError(), + "Couldn't import decl: {0}"); break; + } ObjCInterfaceDecl *imported_from_superclass = - dyn_cast<ObjCInterfaceDecl>(imported_from_superclass_decl); + dyn_cast<ObjCInterfaceDecl>(*imported_from_superclass_decl); if (!imported_from_superclass) break; @@ -932,16 +1018,21 @@ void ClangASTImporter::Minion::ImportDefinitionTo(clang::Decl *to, to_objc_interface->setSuperClass(m_source_ctx->getTrivialTypeSourceInfo( m_source_ctx->getObjCInterfaceType(imported_from_superclass))); - } while (0); + } while (false); } } -clang::Decl *ClangASTImporter::Minion::Imported(clang::Decl *from, - clang::Decl *to) { +void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from, + clang::Decl *to) { ClangASTMetrics::RegisterClangImport(); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + // Some decls shouldn't be tracked here because they were not created by + // copying 'from' to 'to'. Just exit early for those. + if (m_decls_to_ignore.find(to) != m_decls_to_ignore.end()) + return clang::ASTImporter::Imported(from, to); + lldb::user_id_t user_id = LLDB_INVALID_UID; ClangASTMetadata *metadata = m_master.GetDeclMetadata(from); if (metadata) @@ -983,8 +1074,8 @@ clang::Decl *ClangASTImporter::Minion::Imported(clang::Decl *from, to_context_md->m_origins[to] = origin_iter->second; } - MinionSP direct_completer = - m_master.GetMinion(&to->getASTContext(), origin_iter->second.ctx); + ImporterDelegateSP direct_completer = + m_master.GetDelegate(&to->getASTContext(), origin_iter->second.ctx); if (direct_completer.get() != this) direct_completer->ASTImporter::Imported(origin_iter->second.decl, to); @@ -1095,11 +1186,10 @@ clang::Decl *ClangASTImporter::Minion::Imported(clang::Decl *from, } } } - - return clang::ASTImporter::Imported(from, to); } -clang::Decl *ClangASTImporter::Minion::GetOriginalDecl(clang::Decl *To) { +clang::Decl * +ClangASTImporter::ASTImporterDelegate::GetOriginalDecl(clang::Decl *To) { ASTContextMetadataSP to_context_md = m_master.GetContextMetadata(&To->getASTContext()); diff --git a/source/Symbol/ClangExternalASTSourceCallbacks.cpp b/source/Symbol/ClangExternalASTSourceCallbacks.cpp index a96ef19b02f5d..c35fc585bfa56 100644 --- a/source/Symbol/ClangExternalASTSourceCallbacks.cpp +++ b/source/Symbol/ClangExternalASTSourceCallbacks.cpp @@ -1,9 +1,8 @@ //===-- ClangExternalASTSourceCallbacks.cpp ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/source/Symbol/ClangExternalASTSourceCommon.cpp b/source/Symbol/ClangExternalASTSourceCommon.cpp index 992a76352d927..3dcf9051d0a48 100644 --- a/source/Symbol/ClangExternalASTSourceCommon.cpp +++ b/source/Symbol/ClangExternalASTSourceCommon.cpp @@ -1,9 +1,8 @@ //===-- ClangExternalASTSourceCommon.cpp ------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/source/Symbol/ClangUtil.cpp b/source/Symbol/ClangUtil.cpp index 687fba7c7c330..86be895fadcba 100644 --- a/source/Symbol/ClangUtil.cpp +++ b/source/Symbol/ClangUtil.cpp @@ -1,9 +1,8 @@ //===-- ClangUtil.cpp -------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // // A collection of helper methods and data structures for manipulating clang // types and decls. diff --git a/source/Symbol/CompactUnwindInfo.cpp b/source/Symbol/CompactUnwindInfo.cpp index 6f0f35f278c4d..3a2a4d3a09e62 100644 --- a/source/Symbol/CompactUnwindInfo.cpp +++ b/source/Symbol/CompactUnwindInfo.cpp @@ -1,9 +1,8 @@ //===-- CompactUnwindInfo.cpp -----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -18,10 +17,12 @@ #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" -#include <algorithm> #include "llvm/Support/MathExtras.h" +#include <algorithm> +#include <memory> + using namespace lldb; using namespace lldb_private; @@ -156,9 +157,7 @@ FLAGS_ANONYMOUS_ENUM(){ llvm::countTrailingZeros(static_cast<uint32_t>(mask), llvm::ZB_Width)) & \ (((1 << llvm::countPopulation(static_cast<uint32_t>(mask)))) - 1)) -//---------------------- // constructor -//---------------------- CompactUnwindInfo::CompactUnwindInfo(ObjectFile &objfile, SectionSP §ion_sp) : m_objfile(objfile), m_section_sp(section_sp), @@ -166,9 +165,7 @@ CompactUnwindInfo::CompactUnwindInfo(ObjectFile &objfile, SectionSP §ion_sp) m_indexes_computed(eLazyBoolCalculate), m_unwindinfo_data(), m_unwindinfo_data_computed(false), m_unwind_header() {} -//---------------------- // destructor -//---------------------- CompactUnwindInfo::~CompactUnwindInfo() {} @@ -189,7 +186,7 @@ bool CompactUnwindInfo::GetUnwindPlan(Target &target, Address addr, if (log && log->GetVerbose()) { StreamString strm; addr.Dump( - &strm, NULL, + &strm, nullptr, Address::DumpStyle::DumpStyleResolvedDescriptionNoFunctionArguments, Address::DumpStyle::DumpStyleFileAddress, arch.GetAddressByteSize()); @@ -264,8 +261,8 @@ void CompactUnwindInfo::ScanIndex(const ProcessSP &process_sp) { // have a live process and can read them out of memory. if (process_sp.get() == nullptr) return; - m_section_contents_if_encrypted.reset( - new DataBufferHeap(m_section_sp->GetByteSize(), 0)); + m_section_contents_if_encrypted = + std::make_shared<DataBufferHeap>(m_section_sp->GetByteSize(), 0); Status error; if (process_sp->ReadMemory( m_section_sp->GetLoadBaseAddress(&process_sp->GetTarget()), diff --git a/source/Symbol/CompileUnit.cpp b/source/Symbol/CompileUnit.cpp index 74512c8914402..5fb9b6b9f7292 100644 --- a/source/Symbol/CompileUnit.cpp +++ b/source/Symbol/CompileUnit.cpp @@ -1,9 +1,8 @@ //===-- CompileUnit.cpp -----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -23,7 +22,7 @@ CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, lldb_private::LazyBool is_optimized) : ModuleChild(module_sp), FileSpec(pathname), UserID(cu_sym_id), m_user_data(user_data), m_language(language), m_flags(0), - m_support_files(), m_line_table_ap(), m_variables(), + m_support_files(), m_line_table_up(), m_variables(), m_is_optimized(is_optimized) { if (language != eLanguageTypeUnknown) m_flags.Set(flagsParsedLanguage); @@ -36,7 +35,7 @@ CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, lldb_private::LazyBool is_optimized) : ModuleChild(module_sp), FileSpec(fspec), UserID(cu_sym_id), m_user_data(user_data), m_language(language), m_flags(0), - m_support_files(), m_line_table_ap(), m_variables(), + m_support_files(), m_line_table_up(), m_variables(), m_is_optimized(is_optimized) { if (language != eLanguageTypeUnknown) m_flags.Set(flagsParsedLanguage); @@ -82,12 +81,10 @@ void CompileUnit::ForeachFunction( return; } -//---------------------------------------------------------------------- // Dump the current contents of this object. No functions that cause on demand // parsing of functions, globals, statics are called, so this is a good // function to call to get an idea of the current contents of the CompileUnit // object. -//---------------------------------------------------------------------- void CompileUnit::Dump(Stream *s, bool show_context) const { const char *language = Language::GetNameForLanguageType(m_language); @@ -117,14 +114,11 @@ void CompileUnit::Dump(Stream *s, bool show_context) const { } } -//---------------------------------------------------------------------- // Add a function to this compile unit -//---------------------------------------------------------------------- void CompileUnit::AddFunction(FunctionSP &funcSP) { m_functions_by_uid[funcSP->GetID()] = funcSP; } -//---------------------------------------------------------------------- // Find functions using the Mangled::Tokens token list. This function currently // implements an interactive approach designed to find all instances of certain // functions. It isn't designed to the quickest way to lookup functions as it @@ -146,7 +140,6 @@ void CompileUnit::AddFunction(FunctionSP &funcSP) { // method should be able to take advantage of any accelerator tables available // in the debug information (which is parsed by the SymbolFile parser plug-ins // and registered with each Module). -//---------------------------------------------------------------------- // void // CompileUnit::FindFunctions(const Mangled::Tokens& tokens) //{ @@ -190,7 +183,7 @@ lldb::LanguageType CompileUnit::GetLanguage() { } LineTable *CompileUnit::GetLineTable() { - if (m_line_table_ap.get() == nullptr) { + if (m_line_table_up == nullptr) { if (m_flags.IsClear(flagsParsedLineTable)) { m_flags.Set(flagsParsedLineTable); SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor(); @@ -198,7 +191,7 @@ LineTable *CompileUnit::GetLineTable() { symbol_vendor->ParseLineTable(*this); } } - return m_line_table_ap.get(); + return m_line_table_up.get(); } void CompileUnit::SetLineTable(LineTable *line_table) { @@ -206,7 +199,7 @@ void CompileUnit::SetLineTable(LineTable *line_table) { m_flags.Clear(flagsParsedLineTable); else m_flags.Set(flagsParsedLineTable); - m_line_table_ap.reset(line_table); + m_line_table_up.reset(line_table); } DebugMacros *CompileUnit::GetDebugMacros() { @@ -255,7 +248,7 @@ uint32_t CompileUnit::FindLineEntry(uint32_t start_idx, uint32_t line, // All the line table entries actually point to the version of the Compile // Unit that is in the support files (the one at 0 was artificially added.) // So prefer the one further on in the support files if it exists... - FileSpecList &support_files = GetSupportFiles(); + const FileSpecList &support_files = GetSupportFiles(); const bool full = true; file_idx = support_files.FindFileIndex( 1, support_files.GetFileSpecAtIndex(0), full); @@ -391,7 +384,7 @@ void CompileUnit::SetVariableList(VariableListSP &variables) { m_variables = variables; } -const std::vector<ConstString> &CompileUnit::GetImportedModules() { +const std::vector<SourceModule> &CompileUnit::GetImportedModules() { if (m_imported_modules.empty() && m_flags.IsClear(flagsParsedImportedModules)) { m_flags.Set(flagsParsedImportedModules); @@ -404,7 +397,7 @@ const std::vector<ConstString> &CompileUnit::GetImportedModules() { return m_imported_modules; } -FileSpecList &CompileUnit::GetSupportFiles() { +const FileSpecList &CompileUnit::GetSupportFiles() { if (m_support_files.GetSize() == 0) { if (m_flags.IsClear(flagsParsedSupportFiles)) { m_flags.Set(flagsParsedSupportFiles); diff --git a/source/Symbol/CompilerDecl.cpp b/source/Symbol/CompilerDecl.cpp index 2b632c5eb5d04..2c64113a2bbeb 100644 --- a/source/Symbol/CompilerDecl.cpp +++ b/source/Symbol/CompilerDecl.cpp @@ -1,9 +1,8 @@ //===-- CompilerDecl.cpp ----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/source/Symbol/CompilerDeclContext.cpp b/source/Symbol/CompilerDeclContext.cpp index 43a83bbca77bd..a6f046c4eb22e 100644 --- a/source/Symbol/CompilerDeclContext.cpp +++ b/source/Symbol/CompilerDeclContext.cpp @@ -1,9 +1,8 @@ //===-- CompilerDeclContext.cpp ---------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -60,6 +59,19 @@ bool CompilerDeclContext::IsClassMethod(lldb::LanguageType *language_ptr, return false; } +bool CompilerDeclContext::IsContainedInLookup(CompilerDeclContext other) const { + if (!IsValid()) + return false; + + // If the other context is just the current context, we don't need to go + // over the type system to know that the lookup is identical. + if (this == &other) + return true; + + return m_type_system->DeclContextIsContainedInLookup(m_opaque_decl_ctx, + other.m_opaque_decl_ctx); +} + bool lldb_private::operator==(const lldb_private::CompilerDeclContext &lhs, const lldb_private::CompilerDeclContext &rhs) { return lhs.GetTypeSystem() == rhs.GetTypeSystem() && diff --git a/source/Symbol/CompilerType.cpp b/source/Symbol/CompilerType.cpp index 7e381abd7d11e..bb9a1a642e422 100644 --- a/source/Symbol/CompilerType.cpp +++ b/source/Symbol/CompilerType.cpp @@ -1,9 +1,8 @@ //===-- CompilerType.cpp ----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -36,17 +35,13 @@ CompilerType::CompilerType(TypeSystem *type_system, CompilerType::CompilerType(clang::ASTContext *ast, clang::QualType qual_type) : m_type(qual_type.getAsOpaquePtr()), m_type_system(ClangASTContext::GetASTContext(ast)) { -#ifdef LLDB_CONFIGURATION_DEBUG if (m_type) assert(m_type_system != nullptr); -#endif } CompilerType::~CompilerType() {} -//---------------------------------------------------------------------- // Tests -//---------------------------------------------------------------------- bool CompilerType::IsAggregateType() const { if (IsValid()) @@ -149,7 +144,7 @@ bool CompilerType::IsBlockPointerType( CompilerType *function_pointer_type_ptr) const { if (IsValid()) return m_type_system->IsBlockPointerType(m_type, function_pointer_type_ptr); - return 0; + return false; } bool CompilerType::IsIntegerType(bool &is_signed) const { @@ -273,9 +268,7 @@ bool CompilerType::IsBeingDefined() const { return m_type_system->IsBeingDefined(m_type); } -//---------------------------------------------------------------------- // Type Completion -//---------------------------------------------------------------------- bool CompilerType::GetCompleteType() const { if (!IsValid()) @@ -283,9 +276,7 @@ bool CompilerType::GetCompleteType() const { return m_type_system->GetCompleteType(m_type); } -//---------------------------------------------------------------------- // AST related queries -//---------------------------------------------------------------------- size_t CompilerType::GetPointerByteSize() const { if (m_type_system) return m_type_system->GetPointerByteSize(); @@ -354,9 +345,7 @@ unsigned CompilerType::GetTypeQualifiers() const { return 0; } -//---------------------------------------------------------------------- // Creating related types -//---------------------------------------------------------------------- CompilerType CompilerType::GetArrayElementType(uint64_t *stride) const { if (IsValid()) { @@ -490,9 +479,7 @@ CompilerType CompilerType::GetTypedefedType() const { return CompilerType(); } -//---------------------------------------------------------------------- // Create related types using the current type's AST -//---------------------------------------------------------------------- CompilerType CompilerType::GetBasicTypeFromAST(lldb::BasicType basic_type) const { @@ -500,9 +487,7 @@ CompilerType::GetBasicTypeFromAST(lldb::BasicType basic_type) const { return m_type_system->GetBasicTypeFromAST(basic_type); return CompilerType(); } -//---------------------------------------------------------------------- // Exploring the type -//---------------------------------------------------------------------- llvm::Optional<uint64_t> CompilerType::GetBitSize(ExecutionContextScope *exe_scope) const { @@ -554,7 +539,7 @@ lldb::BasicType CompilerType::GetBasicTypeEnumeration() const { void CompilerType::ForEachEnumerator( std::function<bool(const CompilerType &integer_type, - const ConstString &name, + ConstString name, const llvm::APSInt &value)> const &callback) const { if (IsValid()) return m_type_system->ForEachEnumerator(m_type, callback); @@ -751,9 +736,7 @@ size_t CompilerType::ConvertStringToFloatValue(const char *s, uint8_t *dst, return 0; } -//---------------------------------------------------------------------- // Dumping types -//---------------------------------------------------------------------- #define DEPTH_INCREMENT 2 void CompilerType::DumpValue(ExecutionContext *exe_ctx, Stream *s, @@ -803,6 +786,15 @@ void CompilerType::DumpTypeDescription(Stream *s) const { } } +#ifndef NDEBUG +LLVM_DUMP_METHOD void CompilerType::dump() const { + if (IsValid()) + m_type_system->dump(m_type); + else + llvm::errs() << "<invalid>\n"; +} +#endif + bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data, lldb::offset_t data_byte_offset, size_t data_byte_size, @@ -1003,7 +995,7 @@ bool CompilerType::ReadFromMemory(lldb_private::ExecutionContext *exe_ctx, return false; auto byte_size = - GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); + GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); if (!byte_size) return false; @@ -1048,7 +1040,7 @@ bool CompilerType::WriteToMemory(lldb_private::ExecutionContext *exe_ctx, return false; auto byte_size = - GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); + GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); if (!byte_size) return false; diff --git a/source/Symbol/CxxModuleHandler.cpp b/source/Symbol/CxxModuleHandler.cpp new file mode 100644 index 0000000000000..68a2aab80bd6e --- /dev/null +++ b/source/Symbol/CxxModuleHandler.cpp @@ -0,0 +1,283 @@ +//===-- CxxModuleHandler.cpp ------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Symbol/CxxModuleHandler.h" + +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Utility/Log.h" +#include "clang/Sema/Lookup.h" +#include "llvm/Support/Error.h" + +using namespace lldb_private; +using namespace clang; + +CxxModuleHandler::CxxModuleHandler(ASTImporter &importer, ASTContext *target) + : m_importer(&importer), + m_sema(ClangASTContext::GetASTContext(target)->getSema()) { + + std::initializer_list<const char *> supported_names = { + // containers + "deque", + "forward_list", + "list", + "queue", + "stack", + "vector", + // pointers + "shared_ptr", + "unique_ptr", + "weak_ptr", + // utility + "allocator", + }; + m_supported_templates.insert(supported_names.begin(), supported_names.end()); +} + +/// Builds a list of scopes that point into the given context. +/// +/// \param sema The sema that will be using the scopes. +/// \param ctxt The context that the scope should look into. +/// \param result A list of scopes. The scopes need to be freed by the caller +/// (except the TUScope which is owned by the sema). +static void makeScopes(Sema &sema, DeclContext *ctxt, + std::vector<Scope *> &result) { + // FIXME: The result should be a list of unique_ptrs, but the TUScope makes + // this currently impossible as it's owned by the Sema. + + if (auto parent = ctxt->getParent()) { + makeScopes(sema, parent, result); + + Scope *scope = + new Scope(result.back(), Scope::DeclScope, sema.getDiagnostics()); + scope->setEntity(ctxt); + result.push_back(scope); + } else + result.push_back(sema.TUScope); +} + +/// Uses the Sema to look up the given name in the given DeclContext. +static std::unique_ptr<LookupResult> +emulateLookupInCtxt(Sema &sema, llvm::StringRef name, DeclContext *ctxt) { + IdentifierInfo &ident = sema.getASTContext().Idents.get(name); + + std::unique_ptr<LookupResult> lookup_result; + lookup_result.reset(new LookupResult(sema, DeclarationName(&ident), + SourceLocation(), + Sema::LookupOrdinaryName)); + + // Usually during parsing we already encountered the scopes we would use. But + // here don't have these scopes so we have to emulate the behavior of the + // Sema during parsing. + std::vector<Scope *> scopes; + makeScopes(sema, ctxt, scopes); + + // Now actually perform the lookup with the sema. + sema.LookupName(*lookup_result, scopes.back()); + + // Delete all the allocated scopes beside the translation unit scope (which + // has depth 0). + for (Scope *s : scopes) + if (s->getDepth() != 0) + delete s; + + return lookup_result; +} + +/// Error class for handling problems when finding a certain DeclContext. +struct MissingDeclContext : public llvm::ErrorInfo<MissingDeclContext> { + + static char ID; + + MissingDeclContext(DeclContext *context, std::string error) + : m_context(context), m_error(error) {} + + DeclContext *m_context; + std::string m_error; + + void log(llvm::raw_ostream &OS) const override { + OS << llvm::formatv("error when reconstructing context of kind {0}:{1}", + m_context->getDeclKindName(), m_error); + } + + std::error_code convertToErrorCode() const override { + return llvm::inconvertibleErrorCode(); + } +}; + +char MissingDeclContext::ID = 0; + +/// Given a foreign decl context, this function finds the equivalent local +/// decl context in the ASTContext of the given Sema. Potentially deserializes +/// decls from the 'std' module if necessary. +static llvm::Expected<DeclContext *> +getEqualLocalDeclContext(Sema &sema, DeclContext *foreign_ctxt) { + + // Inline namespaces don't matter for lookups, so let's skip them. + while (foreign_ctxt && foreign_ctxt->isInlineNamespace()) + foreign_ctxt = foreign_ctxt->getParent(); + + // If the foreign context is the TU, we just return the local TU. + if (foreign_ctxt->isTranslationUnit()) + return sema.getASTContext().getTranslationUnitDecl(); + + // Recursively find/build the parent DeclContext. + llvm::Expected<DeclContext *> parent = + getEqualLocalDeclContext(sema, foreign_ctxt->getParent()); + if (!parent) + return parent; + + // We currently only support building namespaces. + if (foreign_ctxt->isNamespace()) { + NamedDecl *ns = llvm::dyn_cast<NamedDecl>(foreign_ctxt); + llvm::StringRef ns_name = ns->getName(); + + auto lookup_result = emulateLookupInCtxt(sema, ns_name, *parent); + for (NamedDecl *named_decl : *lookup_result) { + if (DeclContext *DC = llvm::dyn_cast<DeclContext>(named_decl)) + return DC->getPrimaryContext(); + } + return llvm::make_error<MissingDeclContext>( + foreign_ctxt, + "Couldn't find namespace " + ns->getQualifiedNameAsString()); + } + + return llvm::make_error<MissingDeclContext>(foreign_ctxt, "Unknown context "); +} + +/// Returns true iff tryInstantiateStdTemplate supports instantiating a template +/// with the given template arguments. +static bool templateArgsAreSupported(ArrayRef<TemplateArgument> a) { + for (const TemplateArgument &arg : a) { + switch (arg.getKind()) { + case TemplateArgument::Type: + case TemplateArgument::Integral: + break; + default: + // TemplateArgument kind hasn't been handled yet. + return false; + } + } + return true; +} + +/// Constructor function for Clang declarations. Ensures that the created +/// declaration is registered with the ASTImporter. +template <typename T, typename... Args> +T *createDecl(ASTImporter &importer, Decl *from_d, Args &&... args) { + T *to_d = T::Create(std::forward<Args>(args)...); + importer.RegisterImportedDecl(from_d, to_d); + return to_d; +} + +llvm::Optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) { + // If we don't have a template to instiantiate, then there is nothing to do. + auto td = dyn_cast<ClassTemplateSpecializationDecl>(d); + if (!td) + return {}; + + // We only care about templates in the std namespace. + if (!td->getDeclContext()->isStdNamespace()) + return {}; + + // We have a whitelist of supported template names. + if (m_supported_templates.find(td->getName()) == m_supported_templates.end()) + return {}; + + // Early check if we even support instantiating this template. We do this + // before we import anything into the target AST. + auto &foreign_args = td->getTemplateInstantiationArgs(); + if (!templateArgsAreSupported(foreign_args.asArray())) + return {}; + + // Find the local DeclContext that corresponds to the DeclContext of our + // decl we want to import. + auto to_context = getEqualLocalDeclContext(*m_sema, td->getDeclContext()); + if (!to_context) + return {}; + + // Look up the template in our local context. + std::unique_ptr<LookupResult> lookup = + emulateLookupInCtxt(*m_sema, td->getName(), *to_context); + + ClassTemplateDecl *new_class_template = nullptr; + for (auto LD : *lookup) { + if ((new_class_template = dyn_cast<ClassTemplateDecl>(LD))) + break; + } + if (!new_class_template) + return {}; + + // Import the foreign template arguments. + llvm::SmallVector<TemplateArgument, 4> imported_args; + + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); + + // If this logic is changed, also update templateArgsAreSupported. + for (const TemplateArgument &arg : foreign_args.asArray()) { + switch (arg.getKind()) { + case TemplateArgument::Type: { + llvm::Expected<QualType> type = m_importer->Import(arg.getAsType()); + if (!type) { + LLDB_LOG_ERROR(log, type.takeError(), "Couldn't import type: {0}"); + return {}; + } + imported_args.push_back(TemplateArgument(*type)); + break; + } + case TemplateArgument::Integral: { + llvm::APSInt integral = arg.getAsIntegral(); + llvm::Expected<QualType> type = + m_importer->Import(arg.getIntegralType()); + if (!type) { + LLDB_LOG_ERROR(log, type.takeError(), "Couldn't import type: {0}"); + return {}; + } + imported_args.push_back( + TemplateArgument(d->getASTContext(), integral, *type)); + break; + } + default: + assert(false && "templateArgsAreSupported not updated?"); + } + } + + // Find the class template specialization declaration that + // corresponds to these arguments. + void *InsertPos = nullptr; + ClassTemplateSpecializationDecl *result = + new_class_template->findSpecialization(imported_args, InsertPos); + + if (result) { + // We found an existing specialization in the module that fits our arguments + // so we can treat it as the result and register it with the ASTImporter. + m_importer->RegisterImportedDecl(d, result); + return result; + } + + // Instantiate the template. + result = createDecl<ClassTemplateSpecializationDecl>( + *m_importer, d, m_sema->getASTContext(), + new_class_template->getTemplatedDecl()->getTagKind(), + new_class_template->getDeclContext(), + new_class_template->getTemplatedDecl()->getLocation(), + new_class_template->getLocation(), new_class_template, imported_args, + nullptr); + + new_class_template->AddSpecialization(result, InsertPos); + if (new_class_template->isOutOfLine()) + result->setLexicalDeclContext( + new_class_template->getLexicalDeclContext()); + return result; +} + +llvm::Optional<Decl *> CxxModuleHandler::Import(Decl *d) { + if (!isValid()) + return {}; + + return tryInstantiateStdTemplate(d); +} diff --git a/source/Symbol/DWARFCallFrameInfo.cpp b/source/Symbol/DWARFCallFrameInfo.cpp index c8c3a10026a27..0ab9fa4b7bbdd 100644 --- a/source/Symbol/DWARFCallFrameInfo.cpp +++ b/source/Symbol/DWARFCallFrameInfo.cpp @@ -1,9 +1,8 @@ //===-- DWARFCallFrameInfo.cpp ----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -24,12 +23,10 @@ using namespace lldb; using namespace lldb_private; -//---------------------------------------------------------------------- // GetDwarfEHPtr // // Used for calls when the value type is specified by a DWARF EH Frame pointer // encoding. -//---------------------------------------------------------------------- static uint64_t GetGNUEHPointer(const DataExtractor &DE, offset_t *offset_ptr, uint32_t eh_ptr_enc, addr_t pc_rel_addr, addr_t text_addr, @@ -41,9 +38,7 @@ GetGNUEHPointer(const DataExtractor &DE, offset_t *offset_ptr, uint64_t baseAddress = 0; uint64_t addressValue = 0; const uint32_t addr_size = DE.GetAddressByteSize(); -#ifdef LLDB_CONFIGURATION_DEBUG assert(addr_size == 4 || addr_size == 8); -#endif bool signExtendValue = false; // Decode the base part or adjust our offset @@ -151,8 +146,15 @@ DWARFCallFrameInfo::DWARFCallFrameInfo(ObjectFile &objfile, SectionSP §ion_sp, Type type) : m_objfile(objfile), m_section_sp(section_sp), m_type(type) {} -bool DWARFCallFrameInfo::GetUnwindPlan(Address addr, UnwindPlan &unwind_plan) { +bool DWARFCallFrameInfo::GetUnwindPlan(const Address &addr, + UnwindPlan &unwind_plan) { + return GetUnwindPlan(AddressRange(addr, 1), unwind_plan); +} + +bool DWARFCallFrameInfo::GetUnwindPlan(const AddressRange &range, + UnwindPlan &unwind_plan) { FDEEntryMap::Entry fde_entry; + Address addr = range.GetBaseAddress(); // Make sure that the Address we're searching for is the same object file as // this DWARFCallFrameInfo, we only store File offsets in m_fde_index. @@ -161,9 +163,9 @@ bool DWARFCallFrameInfo::GetUnwindPlan(Address addr, UnwindPlan &unwind_plan) { module_sp->GetObjectFile() != &m_objfile) return false; - if (!GetFDEEntryByFileAddress(addr.GetFileAddress(), fde_entry)) - return false; - return FDEToUnwindPlan(fde_entry.data, addr, unwind_plan); + if (llvm::Optional<FDEEntryMap::Entry> entry = GetFirstFDEEntryInRange(range)) + return FDEToUnwindPlan(entry->data, addr, unwind_plan); + return false; } bool DWARFCallFrameInfo::GetAddressRange(Address addr, AddressRange &range) { @@ -188,23 +190,21 @@ bool DWARFCallFrameInfo::GetAddressRange(Address addr, AddressRange &range) { return true; } -bool DWARFCallFrameInfo::GetFDEEntryByFileAddress( - addr_t file_addr, FDEEntryMap::Entry &fde_entry) { - if (m_section_sp.get() == nullptr || m_section_sp->IsEncrypted()) - return false; +llvm::Optional<DWARFCallFrameInfo::FDEEntryMap::Entry> +DWARFCallFrameInfo::GetFirstFDEEntryInRange(const AddressRange &range) { + if (!m_section_sp || m_section_sp->IsEncrypted()) + return llvm::None; GetFDEIndex(); - if (m_fde_index.IsEmpty()) - return false; - - FDEEntryMap::Entry *fde = m_fde_index.FindEntryThatContains(file_addr); + addr_t start_file_addr = range.GetBaseAddress().GetFileAddress(); + const FDEEntryMap::Entry *fde = + m_fde_index.FindEntryThatContainsOrFollows(start_file_addr); + if (fde && fde->DoesIntersect( + FDEEntryMap::Range(start_file_addr, range.GetByteSize()))) + return *fde; - if (fde == nullptr) - return false; - - fde_entry = *fde; - return true; + return llvm::None; } void DWARFCallFrameInfo::GetFunctionAddressAndSizeVector( @@ -231,7 +231,7 @@ DWARFCallFrameInfo::GetCIE(dw_offset_t cie_offset) { if (pos != m_cie_map.end()) { // Parse and cache the CIE - if (pos->second.get() == nullptr) + if (pos->second == nullptr) pos->second = ParseCIE(cie_offset); return pos->second.get(); @@ -999,61 +999,6 @@ bool DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode, uint32_t block_len = (uint32_t)m_cfi_data.GetULEB128(&offset); const uint8_t *block_data = (const uint8_t *)m_cfi_data.GetData(&offset, block_len); - //#if defined(__i386__) || defined(__x86_64__) - // // The EH frame info for EIP and RIP contains code that - // looks for traps to - // // be a specific type and increments the PC. - // // For i386: - // // DW_CFA_val_expression where: - // // eip = DW_OP_breg6(+28), DW_OP_deref, DW_OP_dup, - // DW_OP_plus_uconst(0x34), - // // DW_OP_deref, DW_OP_swap, DW_OP_plus_uconst(0), - // DW_OP_deref, - // // DW_OP_dup, DW_OP_lit3, DW_OP_ne, DW_OP_swap, - // DW_OP_lit4, DW_OP_ne, - // // DW_OP_and, DW_OP_plus - // // This basically does a: - // // eip = ucontenxt.mcontext32->gpr.eip; - // // if (ucontenxt.mcontext32->exc.trapno != 3 && - // ucontenxt.mcontext32->exc.trapno != 4) - // // eip++; - // // - // // For x86_64: - // // DW_CFA_val_expression where: - // // rip = DW_OP_breg3(+48), DW_OP_deref, DW_OP_dup, - // DW_OP_plus_uconst(0x90), DW_OP_deref, - // // DW_OP_swap, DW_OP_plus_uconst(0), - // DW_OP_deref_size(4), DW_OP_dup, DW_OP_lit3, - // // DW_OP_ne, DW_OP_swap, DW_OP_lit4, DW_OP_ne, - // DW_OP_and, DW_OP_plus - // // This basically does a: - // // rip = ucontenxt.mcontext64->gpr.rip; - // // if (ucontenxt.mcontext64->exc.trapno != 3 && - // ucontenxt.mcontext64->exc.trapno != 4) - // // rip++; - // // The trap comparisons and increments are not needed as - // it hoses up the unwound PC which - // // is expected to point at least past the instruction that - // causes the fault/trap. So we - // // take it out by trimming the expression right at the - // first "DW_OP_swap" opcodes - // if (block_data != NULL && thread->GetPCRegNum(Thread::GCC) - // == reg_num) - // { - // if (thread->Is64Bit()) - // { - // if (block_len > 9 && block_data[8] == DW_OP_swap - // && block_data[9] == DW_OP_plus_uconst) - // block_len = 8; - // } - // else - // { - // if (block_len > 8 && block_data[7] == DW_OP_swap - // && block_data[8] == DW_OP_plus_uconst) - // block_len = 7; - // } - // } - //#endif reg_location.SetIsDWARFExpression(block_data, block_len); row.SetRegisterInfo(reg_num, reg_location); return true; diff --git a/source/Symbol/DebugMacros.cpp b/source/Symbol/DebugMacros.cpp index 22576ee1ce26c..d119a78868a42 100644 --- a/source/Symbol/DebugMacros.cpp +++ b/source/Symbol/DebugMacros.cpp @@ -1,9 +1,8 @@ //===-- DebugMacros.cpp -----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/source/Symbol/DeclVendor.cpp b/source/Symbol/DeclVendor.cpp new file mode 100644 index 0000000000000..0a912a2fd2142 --- /dev/null +++ b/source/Symbol/DeclVendor.cpp @@ -0,0 +1,29 @@ +//===-- DeclVendor.cpp ------------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Symbol/DeclVendor.h" + +#include "lldb/Symbol/ClangASTContext.h" + +#include <vector> + +using namespace lldb; +using namespace lldb_private; + +std::vector<CompilerType> DeclVendor::FindTypes(ConstString name, + uint32_t max_matches) { + // FIXME: This depends on clang, but should be able to support any + // TypeSystem. + std::vector<CompilerType> ret; + std::vector<clang::NamedDecl *> decls; + if (FindDecls(name, /*append*/ true, max_matches, decls)) + for (auto *decl : decls) + if (auto type = ClangASTContext::GetTypeForDecl(decl)) + ret.push_back(type); + return ret; +} diff --git a/source/Symbol/Declaration.cpp b/source/Symbol/Declaration.cpp index 83df578da2e3b..d78ba967d280b 100644 --- a/source/Symbol/Declaration.cpp +++ b/source/Symbol/Declaration.cpp @@ -1,9 +1,8 @@ //===-- Declaration.cpp -----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -84,6 +83,11 @@ int Declaration::Compare(const Declaration &a, const Declaration &b) { return 0; } +bool Declaration::FileAndLineEqual(const Declaration &declaration) const { + int file_compare = FileSpec::Compare(this->m_file, declaration.m_file, true); + return file_compare == 0 && this->m_line == declaration.m_line; +} + bool lldb_private::operator==(const Declaration &lhs, const Declaration &rhs) { #ifdef LLDB_ENABLE_DECLARATION_COLUMNS if (lhs.GetColumn() == rhs.GetColumn()) diff --git a/source/Symbol/FuncUnwinders.cpp b/source/Symbol/FuncUnwinders.cpp index 35ce72f32b61e..09cb9b00aaf3b 100644 --- a/source/Symbol/FuncUnwinders.cpp +++ b/source/Symbol/FuncUnwinders.cpp @@ -1,9 +1,8 @@ //===-- FuncUnwinders.cpp ----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -14,22 +13,24 @@ #include "lldb/Symbol/CompactUnwindInfo.h" #include "lldb/Symbol/DWARFCallFrameInfo.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Symbol/UnwindTable.h" #include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" #include "lldb/Target/RegisterNumber.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/UnwindAssembly.h" +#include <memory> + using namespace lldb; using namespace lldb_private; -//------------------------------------------------ /// constructor -//------------------------------------------------ FuncUnwinders::FuncUnwinders(UnwindTable &unwind_table, AddressRange range) : m_unwind_table(unwind_table), m_range(range), m_mutex(), @@ -43,35 +44,35 @@ FuncUnwinders::FuncUnwinders(UnwindTable &unwind_table, AddressRange range) m_tried_unwind_plan_eh_frame_augmented(false), m_tried_unwind_plan_debug_frame_augmented(false), m_tried_unwind_plan_compact_unwind(false), - m_tried_unwind_plan_arm_unwind(false), m_tried_unwind_fast(false), + m_tried_unwind_plan_arm_unwind(false), + m_tried_unwind_plan_symbol_file(false), m_tried_unwind_fast(false), m_tried_unwind_arch_default(false), m_tried_unwind_arch_default_at_func_entry(false), m_first_non_prologue_insn() {} -//------------------------------------------------ /// destructor -//------------------------------------------------ FuncUnwinders::~FuncUnwinders() {} UnwindPlanSP FuncUnwinders::GetUnwindPlanAtCallSite(Target &target, - int current_offset) { + Thread &thread) { std::lock_guard<std::recursive_mutex> guard(m_mutex); - if (UnwindPlanSP plan_sp = GetEHFrameUnwindPlan(target, current_offset)) + if (UnwindPlanSP plan_sp = GetSymbolFileUnwindPlan(thread)) return plan_sp; - if (UnwindPlanSP plan_sp = GetDebugFrameUnwindPlan(target, current_offset)) + if (UnwindPlanSP plan_sp = GetDebugFrameUnwindPlan(target)) return plan_sp; - if (UnwindPlanSP plan_sp = GetCompactUnwindUnwindPlan(target, current_offset)) + if (UnwindPlanSP plan_sp = GetEHFrameUnwindPlan(target)) return plan_sp; - if (UnwindPlanSP plan_sp = GetArmUnwindUnwindPlan(target, current_offset)) + if (UnwindPlanSP plan_sp = GetCompactUnwindUnwindPlan(target)) + return plan_sp; + if (UnwindPlanSP plan_sp = GetArmUnwindUnwindPlan(target)) return plan_sp; return nullptr; } -UnwindPlanSP FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target, - int current_offset) { +UnwindPlanSP FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target) { std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_unwind_plan_compact_unwind.size() > 0) return m_unwind_plan_compact_unwind[0]; // FIXME support multiple compact @@ -82,8 +83,6 @@ UnwindPlanSP FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target, m_tried_unwind_plan_compact_unwind = true; if (m_range.GetBaseAddress().IsValid()) { Address current_pc(m_range.GetBaseAddress()); - if (current_offset != -1) - current_pc.SetOffset(current_pc.GetOffset() + current_offset); CompactUnwindInfo *compact_unwind = m_unwind_table.GetCompactUnwindInfo(); if (compact_unwind) { UnwindPlanSP unwind_plan_sp(new UnwindPlan(lldb::eRegisterKindGeneric)); @@ -98,53 +97,43 @@ UnwindPlanSP FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target, return UnwindPlanSP(); } -UnwindPlanSP FuncUnwinders::GetEHFrameUnwindPlan(Target &target, - int current_offset) { +UnwindPlanSP FuncUnwinders::GetEHFrameUnwindPlan(Target &target) { std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_unwind_plan_eh_frame_sp.get() || m_tried_unwind_plan_eh_frame) return m_unwind_plan_eh_frame_sp; m_tried_unwind_plan_eh_frame = true; if (m_range.GetBaseAddress().IsValid()) { - Address current_pc(m_range.GetBaseAddress()); - if (current_offset != -1) - current_pc.SetOffset(current_pc.GetOffset() + current_offset); DWARFCallFrameInfo *eh_frame = m_unwind_table.GetEHFrameInfo(); if (eh_frame) { - m_unwind_plan_eh_frame_sp.reset( - new UnwindPlan(lldb::eRegisterKindGeneric)); - if (!eh_frame->GetUnwindPlan(current_pc, *m_unwind_plan_eh_frame_sp)) + m_unwind_plan_eh_frame_sp = + std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); + if (!eh_frame->GetUnwindPlan(m_range, *m_unwind_plan_eh_frame_sp)) m_unwind_plan_eh_frame_sp.reset(); } } return m_unwind_plan_eh_frame_sp; } -UnwindPlanSP FuncUnwinders::GetDebugFrameUnwindPlan(Target &target, - int current_offset) { +UnwindPlanSP FuncUnwinders::GetDebugFrameUnwindPlan(Target &target) { std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_unwind_plan_debug_frame_sp || m_tried_unwind_plan_debug_frame) return m_unwind_plan_debug_frame_sp; m_tried_unwind_plan_debug_frame = true; if (m_range.GetBaseAddress().IsValid()) { - Address current_pc(m_range.GetBaseAddress()); - if (current_offset != -1) - current_pc.SetOffset(current_pc.GetOffset() + current_offset); DWARFCallFrameInfo *debug_frame = m_unwind_table.GetDebugFrameInfo(); if (debug_frame) { - m_unwind_plan_debug_frame_sp.reset( - new UnwindPlan(lldb::eRegisterKindGeneric)); - if (!debug_frame->GetUnwindPlan(current_pc, - *m_unwind_plan_debug_frame_sp)) + m_unwind_plan_debug_frame_sp = + std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); + if (!debug_frame->GetUnwindPlan(m_range, *m_unwind_plan_debug_frame_sp)) m_unwind_plan_debug_frame_sp.reset(); } } return m_unwind_plan_debug_frame_sp; } -UnwindPlanSP FuncUnwinders::GetArmUnwindUnwindPlan(Target &target, - int current_offset) { +UnwindPlanSP FuncUnwinders::GetArmUnwindUnwindPlan(Target &target) { std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_unwind_plan_arm_unwind_sp.get() || m_tried_unwind_plan_arm_unwind) return m_unwind_plan_arm_unwind_sp; @@ -152,12 +141,10 @@ UnwindPlanSP FuncUnwinders::GetArmUnwindUnwindPlan(Target &target, m_tried_unwind_plan_arm_unwind = true; if (m_range.GetBaseAddress().IsValid()) { Address current_pc(m_range.GetBaseAddress()); - if (current_offset != -1) - current_pc.SetOffset(current_pc.GetOffset() + current_offset); ArmUnwindInfo *arm_unwind_info = m_unwind_table.GetArmUnwindInfo(); if (arm_unwind_info) { - m_unwind_plan_arm_unwind_sp.reset( - new UnwindPlan(lldb::eRegisterKindGeneric)); + m_unwind_plan_arm_unwind_sp = + std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); if (!arm_unwind_info->GetUnwindPlan(target, current_pc, *m_unwind_plan_arm_unwind_sp)) m_unwind_plan_arm_unwind_sp.reset(); @@ -166,9 +153,40 @@ UnwindPlanSP FuncUnwinders::GetArmUnwindUnwindPlan(Target &target, return m_unwind_plan_arm_unwind_sp; } +namespace { +class RegisterContextToInfo: public SymbolFile::RegisterInfoResolver { +public: + RegisterContextToInfo(RegisterContext &ctx) : m_ctx(ctx) {} + + const RegisterInfo *ResolveName(llvm::StringRef name) const { + return m_ctx.GetRegisterInfoByName(name); + } + const RegisterInfo *ResolveNumber(lldb::RegisterKind kind, + uint32_t number) const { + return m_ctx.GetRegisterInfo(kind, number); + } + +private: + RegisterContext &m_ctx; +}; +} // namespace + +UnwindPlanSP FuncUnwinders::GetSymbolFileUnwindPlan(Thread &thread) { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + if (m_unwind_plan_symbol_file_sp.get() || m_tried_unwind_plan_symbol_file) + return m_unwind_plan_symbol_file_sp; + + m_tried_unwind_plan_symbol_file = true; + if (SymbolFile *symfile = m_unwind_table.GetSymbolFile()) { + m_unwind_plan_symbol_file_sp = symfile->GetUnwindPlan( + m_range.GetBaseAddress(), + RegisterContextToInfo(*thread.GetRegisterContext())); + } + return m_unwind_plan_symbol_file_sp; +} + UnwindPlanSP FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target, - Thread &thread, - int current_offset) { + Thread &thread) { std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_unwind_plan_eh_frame_augmented_sp.get() || m_tried_unwind_plan_eh_frame_augmented) @@ -186,11 +204,12 @@ UnwindPlanSP FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target, m_tried_unwind_plan_eh_frame_augmented = true; - UnwindPlanSP eh_frame_plan = GetEHFrameUnwindPlan(target, current_offset); + UnwindPlanSP eh_frame_plan = GetEHFrameUnwindPlan(target); if (!eh_frame_plan) return m_unwind_plan_eh_frame_augmented_sp; - m_unwind_plan_eh_frame_augmented_sp.reset(new UnwindPlan(*eh_frame_plan)); + m_unwind_plan_eh_frame_augmented_sp = + std::make_shared<UnwindPlan>(*eh_frame_plan); // Augment the eh_frame instructions with epilogue descriptions if necessary // so the UnwindPlan can be used at any instruction in the function. @@ -207,9 +226,8 @@ UnwindPlanSP FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target, return m_unwind_plan_eh_frame_augmented_sp; } -UnwindPlanSP -FuncUnwinders::GetDebugFrameAugmentedUnwindPlan(Target &target, Thread &thread, - int current_offset) { +UnwindPlanSP FuncUnwinders::GetDebugFrameAugmentedUnwindPlan(Target &target, + Thread &thread) { std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_unwind_plan_debug_frame_augmented_sp.get() || m_tried_unwind_plan_debug_frame_augmented) @@ -227,13 +245,12 @@ FuncUnwinders::GetDebugFrameAugmentedUnwindPlan(Target &target, Thread &thread, m_tried_unwind_plan_debug_frame_augmented = true; - UnwindPlanSP debug_frame_plan = - GetDebugFrameUnwindPlan(target, current_offset); + UnwindPlanSP debug_frame_plan = GetDebugFrameUnwindPlan(target); if (!debug_frame_plan) return m_unwind_plan_debug_frame_augmented_sp; - m_unwind_plan_debug_frame_augmented_sp.reset( - new UnwindPlan(*debug_frame_plan)); + m_unwind_plan_debug_frame_augmented_sp = + std::make_shared<UnwindPlan>(*debug_frame_plan); // Augment the debug_frame instructions with epilogue descriptions if // necessary so the UnwindPlan can be used at any instruction in the @@ -251,8 +268,7 @@ FuncUnwinders::GetDebugFrameAugmentedUnwindPlan(Target &target, Thread &thread, } UnwindPlanSP FuncUnwinders::GetAssemblyUnwindPlan(Target &target, - Thread &thread, - int current_offset) { + Thread &thread) { std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_unwind_plan_assembly_sp.get() || m_tried_unwind_plan_assembly || !m_unwind_table.GetAllowAssemblyEmulationUnwindPlans()) { @@ -263,7 +279,8 @@ UnwindPlanSP FuncUnwinders::GetAssemblyUnwindPlan(Target &target, UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target)); if (assembly_profiler_sp) { - m_unwind_plan_assembly_sp.reset(new UnwindPlan(lldb::eRegisterKindGeneric)); + m_unwind_plan_assembly_sp = + std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); if (!assembly_profiler_sp->GetNonCallSiteUnwindPlanFromAssembly( m_range, thread, *m_unwind_plan_assembly_sp)) { m_unwind_plan_assembly_sp.reset(); @@ -307,16 +324,14 @@ LazyBool FuncUnwinders::CompareUnwindPlansForIdenticalInitialPCLocation( } UnwindPlanSP FuncUnwinders::GetUnwindPlanAtNonCallSite(Target &target, - Thread &thread, - int current_offset) { - UnwindPlanSP eh_frame_sp = GetEHFrameUnwindPlan(target, current_offset); + Thread &thread) { + UnwindPlanSP eh_frame_sp = GetEHFrameUnwindPlan(target); if (!eh_frame_sp) - eh_frame_sp = GetDebugFrameUnwindPlan(target, current_offset); + eh_frame_sp = GetDebugFrameUnwindPlan(target); UnwindPlanSP arch_default_at_entry_sp = GetUnwindPlanArchitectureDefaultAtFunctionEntry(thread); UnwindPlanSP arch_default_sp = GetUnwindPlanArchitectureDefault(thread); - UnwindPlanSP assembly_sp = - GetAssemblyUnwindPlan(target, thread, current_offset); + UnwindPlanSP assembly_sp = GetAssemblyUnwindPlan(target, thread); // This point of this code is to detect when a function is using a non- // standard ABI, and the eh_frame correctly describes that alternate ABI. @@ -345,11 +360,11 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanAtNonCallSite(Target &target, return eh_frame_sp; } - if (UnwindPlanSP plan_sp = - GetEHFrameAugmentedUnwindPlan(target, thread, current_offset)) + if (UnwindPlanSP plan_sp = GetSymbolFileUnwindPlan(thread)) + return plan_sp; + if (UnwindPlanSP plan_sp = GetDebugFrameAugmentedUnwindPlan(target, thread)) return plan_sp; - if (UnwindPlanSP plan_sp = - GetDebugFrameAugmentedUnwindPlan(target, thread, current_offset)) + if (UnwindPlanSP plan_sp = GetEHFrameAugmentedUnwindPlan(target, thread)) return plan_sp; return assembly_sp; @@ -365,7 +380,8 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanFastUnwind(Target &target, UnwindAssemblySP assembly_profiler_sp(GetUnwindAssemblyProfiler(target)); if (assembly_profiler_sp) { - m_unwind_plan_fast_sp.reset(new UnwindPlan(lldb::eRegisterKindGeneric)); + m_unwind_plan_fast_sp = + std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); if (!assembly_profiler_sp->GetFastUnwindPlan(m_range, thread, *m_unwind_plan_fast_sp)) { m_unwind_plan_fast_sp.reset(); @@ -386,8 +402,8 @@ UnwindPlanSP FuncUnwinders::GetUnwindPlanArchitectureDefault(Thread &thread) { if (process_sp) { ABI *abi = process_sp->GetABI().get(); if (abi) { - m_unwind_plan_arch_default_sp.reset( - new UnwindPlan(lldb::eRegisterKindGeneric)); + m_unwind_plan_arch_default_sp = + std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); if (!abi->CreateDefaultUnwindPlan(*m_unwind_plan_arch_default_sp)) { m_unwind_plan_arch_default_sp.reset(); } @@ -411,8 +427,8 @@ FuncUnwinders::GetUnwindPlanArchitectureDefaultAtFunctionEntry(Thread &thread) { if (process_sp) { ABI *abi = process_sp->GetABI().get(); if (abi) { - m_unwind_plan_arch_default_at_func_entry_sp.reset( - new UnwindPlan(lldb::eRegisterKindGeneric)); + m_unwind_plan_arch_default_at_func_entry_sp = + std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); if (!abi->CreateFunctionEntryUnwindPlan( *m_unwind_plan_arch_default_at_func_entry_sp)) { m_unwind_plan_arch_default_at_func_entry_sp.reset(); @@ -453,9 +469,9 @@ FuncUnwinders::GetUnwindAssemblyProfiler(Target &target) { Address FuncUnwinders::GetLSDAAddress(Target &target) { Address lsda_addr; - UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan(target, -1); + UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan(target); if (unwind_plan_sp.get() == nullptr) { - unwind_plan_sp = GetCompactUnwindUnwindPlan(target, -1); + unwind_plan_sp = GetCompactUnwindUnwindPlan(target); } if (unwind_plan_sp.get() && unwind_plan_sp->GetLSDAAddress().IsValid()) { lsda_addr = unwind_plan_sp->GetLSDAAddress(); @@ -466,9 +482,9 @@ Address FuncUnwinders::GetLSDAAddress(Target &target) { Address FuncUnwinders::GetPersonalityRoutinePtrAddress(Target &target) { Address personality_addr; - UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan(target, -1); + UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan(target); if (unwind_plan_sp.get() == nullptr) { - unwind_plan_sp = GetCompactUnwindUnwindPlan(target, -1); + unwind_plan_sp = GetCompactUnwindUnwindPlan(target); } if (unwind_plan_sp.get() && unwind_plan_sp->GetPersonalityFunctionPtr().IsValid()) { diff --git a/source/Symbol/Function.cpp b/source/Symbol/Function.cpp index f792a5c5213e7..951392c1f1bff 100644 --- a/source/Symbol/Function.cpp +++ b/source/Symbol/Function.cpp @@ -1,9 +1,8 @@ //===-- Function.cpp --------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -25,14 +24,12 @@ using namespace lldb; using namespace lldb_private; -//---------------------------------------------------------------------- // Basic function information is contained in the FunctionInfo class. It is // designed to contain the name, linkage name, and declaration location. -//---------------------------------------------------------------------- FunctionInfo::FunctionInfo(const char *name, const Declaration *decl_ptr) : m_name(name), m_declaration(decl_ptr) {} -FunctionInfo::FunctionInfo(const ConstString &name, const Declaration *decl_ptr) +FunctionInfo::FunctionInfo(ConstString name, const Declaration *decl_ptr) : m_name(name), m_declaration(decl_ptr) {} FunctionInfo::~FunctionInfo() {} @@ -69,7 +66,7 @@ InlineFunctionInfo::InlineFunctionInfo(const char *name, const char *mangled, : FunctionInfo(name, decl_ptr), m_mangled(ConstString(mangled), true), m_call_decl(call_decl_ptr) {} -InlineFunctionInfo::InlineFunctionInfo(const ConstString &name, +InlineFunctionInfo::InlineFunctionInfo(ConstString name, const Mangled &mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr) @@ -130,9 +127,7 @@ size_t InlineFunctionInfo::MemorySize() const { return FunctionInfo::MemorySize() + m_mangled.MemorySize(); } -//---------------------------------------------------------------------- // -//---------------------------------------------------------------------- CallEdge::CallEdge(const char *symbol_name, lldb::addr_t return_pc) : return_pc(return_pc), resolved(false) { lazy_callee.symbol_name = symbol_name; @@ -183,15 +178,13 @@ lldb::addr_t CallEdge::GetReturnPCAddress(Function &caller, return base.GetLoadAddress(&target) + return_pc; } -//---------------------------------------------------------------------- // -//---------------------------------------------------------------------- Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, lldb::user_id_t type_uid, const Mangled &mangled, Type *type, const AddressRange &range) : UserID(func_uid), m_comp_unit(comp_unit), m_type_uid(type_uid), m_type(type), m_mangled(mangled), m_block(func_uid), m_range(range), - m_frame_base(nullptr), m_flags(), m_prologue_byte_size(0) { + m_frame_base(), m_flags(), m_prologue_byte_size(0) { m_block.SetParentScope(this); assert(comp_unit != nullptr); } @@ -553,7 +546,7 @@ uint32_t Function::GetPrologueByteSize() { // Now calculate the offset to pass the subsequent line 0 entries. uint32_t first_non_zero_line = prologue_end_line_idx; - while (1) { + while (true) { LineEntry line_entry; if (line_table->GetLineEntryAtIndex(first_non_zero_line, line_entry)) { @@ -596,10 +589,14 @@ uint32_t Function::GetPrologueByteSize() { } lldb::LanguageType Function::GetLanguage() const { + lldb::LanguageType lang = m_mangled.GuessLanguage(); + if (lang != lldb::eLanguageTypeUnknown) + return lang; + if (m_comp_unit) return m_comp_unit->GetLanguage(); - else - return lldb::eLanguageTypeUnknown; + + return lldb::eLanguageTypeUnknown; } ConstString Function::GetName() const { diff --git a/source/Symbol/LineEntry.cpp b/source/Symbol/LineEntry.cpp index bffcc5321b113..959a3274ec925 100644 --- a/source/Symbol/LineEntry.cpp +++ b/source/Symbol/LineEntry.cpp @@ -1,9 +1,8 @@ //===-- LineEntry.cpp -------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -191,40 +190,62 @@ int LineEntry::Compare(const LineEntry &a, const LineEntry &b) { return FileSpec::Compare(a.file, b.file, true); } -AddressRange LineEntry::GetSameLineContiguousAddressRange() const { +AddressRange LineEntry::GetSameLineContiguousAddressRange( + bool include_inlined_functions) const { // Add each LineEntry's range to complete_line_range until we find a // different file / line number. AddressRange complete_line_range = range; + auto symbol_context_scope = lldb::eSymbolContextLineEntry; + Declaration start_call_site(original_file, line); + if (include_inlined_functions) + symbol_context_scope |= lldb::eSymbolContextBlock; while (true) { SymbolContext next_line_sc; Address range_end(complete_line_range.GetBaseAddress()); range_end.Slide(complete_line_range.GetByteSize()); - range_end.CalculateSymbolContext(&next_line_sc, - lldb::eSymbolContextLineEntry); + range_end.CalculateSymbolContext(&next_line_sc, symbol_context_scope); + + if (!next_line_sc.line_entry.IsValid() || + next_line_sc.line_entry.range.GetByteSize() == 0) + break; - if (next_line_sc.line_entry.IsValid() && - next_line_sc.line_entry.range.GetByteSize() > 0 && - original_file == next_line_sc.line_entry.original_file) { + if (original_file == next_line_sc.line_entry.original_file && + (next_line_sc.line_entry.line == 0 || + line == next_line_sc.line_entry.line)) { // Include any line 0 entries - they indicate that this is compiler- // generated code that does not correspond to user source code. - if (next_line_sc.line_entry.line == 0) { - complete_line_range.SetByteSize( - complete_line_range.GetByteSize() + - next_line_sc.line_entry.range.GetByteSize()); - continue; - } - - if (line == next_line_sc.line_entry.line) { - // next_line_sc is the same file & line as this LineEntry, so extend - // our AddressRange by its size and continue to see if there are more - // LineEntries that we can combine. - complete_line_range.SetByteSize( - complete_line_range.GetByteSize() + - next_line_sc.line_entry.range.GetByteSize()); - continue; - } + // next_line_sc is the same file & line as this LineEntry, so extend + // our AddressRange by its size and continue to see if there are more + // LineEntries that we can combine. However, if there was nothing to + // extend we're done. + if (!complete_line_range.Extend(next_line_sc.line_entry.range)) + break; + continue; } + + if (include_inlined_functions && next_line_sc.block && + next_line_sc.block->GetContainingInlinedBlock() != nullptr) { + // The next_line_sc might be in a different file if it's an inlined + // function. If this is the case then we still want to expand our line + // range to include them if the inlined function is at the same call site + // as this line entry. The current block could represent a nested inline + // function call so we need to need to check up the block tree to see if + // we find one. + auto inlined_parent_block = + next_line_sc.block->GetContainingInlinedBlockWithCallSite( + start_call_site); + if (!inlined_parent_block) + // We didn't find any parent inlined block with a call site at this line + // entry so this inlined function is probably at another line. + break; + // Extend our AddressRange by the size of the inlined block, but if there + // was nothing to add then we're done. + if (!complete_line_range.Extend(next_line_sc.line_entry.range)) + break; + continue; + } + break; } return complete_line_range; diff --git a/source/Symbol/LineTable.cpp b/source/Symbol/LineTable.cpp index 06e30219f09a3..8d4d72c9a2a21 100644 --- a/source/Symbol/LineTable.cpp +++ b/source/Symbol/LineTable.cpp @@ -1,9 +1,8 @@ //===-- LineTable.cpp -------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -18,15 +17,11 @@ using namespace lldb; using namespace lldb_private; -//---------------------------------------------------------------------- // LineTable constructor -//---------------------------------------------------------------------- LineTable::LineTable(CompileUnit *comp_unit) : m_comp_unit(comp_unit), m_entries() {} -//---------------------------------------------------------------------- // Destructor -//---------------------------------------------------------------------- LineTable::~LineTable() {} void LineTable::InsertLineEntry(lldb::addr_t file_addr, uint32_t line, @@ -126,7 +121,7 @@ void LineTable::InsertSequence(LineSequence *sequence) { pos++; } -#ifdef LLDB_CONFIGURATION_DEBUG +#ifndef NDEBUG // If we aren't inserting at the beginning, the previous entry should // terminate a sequence. if (pos != begin_pos) { @@ -137,7 +132,6 @@ void LineTable::InsertSequence(LineSequence *sequence) { m_entries.insert(pos, seq->m_entries.begin(), seq->m_entries.end()); } -//---------------------------------------------------------------------- LineTable::Entry::LessThanBinaryPredicate::LessThanBinaryPredicate( LineTable *line_table) : m_line_table(line_table) {} @@ -445,7 +439,7 @@ size_t LineTable::GetContiguousFileAddressRanges(FileAddressRanges &file_ranges, } LineTable *LineTable::LinkLineTable(const FileRangeMap &file_range_map) { - std::unique_ptr<LineTable> line_table_ap(new LineTable(m_comp_unit)); + std::unique_ptr<LineTable> line_table_up(new LineTable(m_comp_unit)); LineSequenceImpl sequence; const size_t count = m_entries.size(); LineEntry line_entry; @@ -508,7 +502,7 @@ LineTable *LineTable::LinkLineTable(const FileRangeMap &file_range_map) { sequence.m_entries.back().is_terminal_entry = true; // Append the sequence since we just terminated the previous one - line_table_ap->InsertSequence(&sequence); + line_table_up->InsertSequence(&sequence); sequence.Clear(); } @@ -524,7 +518,7 @@ LineTable *LineTable::LinkLineTable(const FileRangeMap &file_range_map) { // insert this sequence into our new line table. if (!sequence.m_entries.empty() && sequence.m_entries.back().is_terminal_entry) { - line_table_ap->InsertSequence(&sequence); + line_table_up->InsertSequence(&sequence); sequence.Clear(); prev_entry_was_linked = false; } else { @@ -533,7 +527,7 @@ LineTable *LineTable::LinkLineTable(const FileRangeMap &file_range_map) { prev_file_addr = entry.file_addr; range_changed = false; } - if (line_table_ap->m_entries.empty()) + if (line_table_up->m_entries.empty()) return nullptr; - return line_table_ap.release(); + return line_table_up.release(); } diff --git a/source/Symbol/LocateSymbolFile.cpp b/source/Symbol/LocateSymbolFile.cpp new file mode 100644 index 0000000000000..bfdb6e705f4a0 --- /dev/null +++ b/source/Symbol/LocateSymbolFile.cpp @@ -0,0 +1,390 @@ +//===-- LocateSymbolFile.cpp ------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Symbol/LocateSymbolFile.h" + +#include "lldb/Core/ModuleList.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/Timer.h" +#include "lldb/Utility/UUID.h" + +#include "llvm/Support/FileSystem.h" + +// From MacOSX system header "mach/machine.h" +typedef int cpu_type_t; +typedef int cpu_subtype_t; + +using namespace lldb; +using namespace lldb_private; + +#if defined(__APPLE__) + +// Forward declaration of method defined in source/Host/macosx/Symbols.cpp +int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, + ModuleSpec &return_module_spec); + +#else + +int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, + ModuleSpec &return_module_spec) { + // Cannot find MacOSX files using debug symbols on non MacOSX. + return 0; +} + +#endif + +static bool FileAtPathContainsArchAndUUID(const FileSpec &file_fspec, + const ArchSpec *arch, + const lldb_private::UUID *uuid) { + ModuleSpecList module_specs; + if (ObjectFile::GetModuleSpecifications(file_fspec, 0, 0, module_specs)) { + ModuleSpec spec; + for (size_t i = 0; i < module_specs.GetSize(); ++i) { + bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec); + UNUSED_IF_ASSERT_DISABLED(got_spec); + assert(got_spec); + if ((uuid == nullptr || (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) && + (arch == nullptr || + (spec.GetArchitecturePtr() && + spec.GetArchitecture().IsCompatibleMatch(*arch)))) { + return true; + } + } + } + return false; +} + +// Given a binary exec_fspec, and a ModuleSpec with an architecture/uuid, +// return true if there is a matching dSYM bundle next to the exec_fspec, +// and return that value in dsym_fspec. +// If there is a .dSYM.yaa compressed archive next to the exec_fspec, +// call through Symbols::DownloadObjectAndSymbolFile to download the +// expanded/uncompressed dSYM and return that filepath in dsym_fspec. + +static bool LookForDsymNextToExecutablePath(const ModuleSpec &mod_spec, + const FileSpec &exec_fspec, + FileSpec &dsym_fspec) { + ConstString filename = exec_fspec.GetFilename(); + FileSpec dsym_directory = exec_fspec; + dsym_directory.RemoveLastPathComponent(); + + std::string dsym_filename = filename.AsCString(); + dsym_filename += ".dSYM"; + dsym_directory.AppendPathComponent(dsym_filename); + dsym_directory.AppendPathComponent("Contents"); + dsym_directory.AppendPathComponent("Resources"); + dsym_directory.AppendPathComponent("DWARF"); + + if (FileSystem::Instance().Exists(dsym_directory)) { + + // See if the binary name exists in the dSYM DWARF + // subdir. + dsym_fspec = dsym_directory; + dsym_fspec.AppendPathComponent(filename.AsCString()); + if (FileSystem::Instance().Exists(dsym_fspec) && + FileAtPathContainsArchAndUUID(dsym_fspec, mod_spec.GetArchitecturePtr(), + mod_spec.GetUUIDPtr())) { + return true; + } + + // See if we have "../CF.framework" - so we'll look for + // CF.framework.dSYM/Contents/Resources/DWARF/CF + // We need to drop the last suffix after '.' to match + // 'CF' in the DWARF subdir. + std::string binary_name(filename.AsCString()); + auto last_dot = binary_name.find_last_of('.'); + if (last_dot != std::string::npos) { + binary_name.erase(last_dot); + dsym_fspec = dsym_directory; + dsym_fspec.AppendPathComponent(binary_name); + if (FileSystem::Instance().Exists(dsym_fspec) && + FileAtPathContainsArchAndUUID(dsym_fspec, + mod_spec.GetArchitecturePtr(), + mod_spec.GetUUIDPtr())) { + return true; + } + } + } + + // See if we have a .dSYM.yaa next to this executable path. + FileSpec dsym_yaa_fspec = exec_fspec; + dsym_yaa_fspec.RemoveLastPathComponent(); + std::string dsym_yaa_filename = filename.AsCString(); + dsym_yaa_filename += ".dSYM.yaa"; + dsym_yaa_fspec.AppendPathComponent(dsym_yaa_filename); + + if (FileSystem::Instance().Exists(dsym_yaa_fspec)) { + ModuleSpec mutable_mod_spec = mod_spec; + if (Symbols::DownloadObjectAndSymbolFile(mutable_mod_spec, true) && + FileSystem::Instance().Exists(mutable_mod_spec.GetSymbolFileSpec())) { + dsym_fspec = mutable_mod_spec.GetSymbolFileSpec(); + return true; + } + } + + return false; +} + +// Given a ModuleSpec with a FileSpec and optionally uuid/architecture +// filled in, look for a .dSYM bundle next to that binary. Returns true +// if a .dSYM bundle is found, and that path is returned in the dsym_fspec +// FileSpec. +// +// This routine looks a few directory layers above the given exec_path - +// exec_path might be /System/Library/Frameworks/CF.framework/CF and the +// dSYM might be /System/Library/Frameworks/CF.framework.dSYM. +// +// If there is a .dSYM.yaa compressed archive found next to the binary, +// we'll call DownloadObjectAndSymbolFile to expand it into a plain .dSYM + +static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec, + FileSpec &dsym_fspec) { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + const FileSpec &exec_fspec = module_spec.GetFileSpec(); + if (exec_fspec) { + if (::LookForDsymNextToExecutablePath(module_spec, exec_fspec, + dsym_fspec)) { + if (log) { + log->Printf("dSYM with matching UUID & arch found at %s", + dsym_fspec.GetPath().c_str()); + } + return true; + } else { + FileSpec parent_dirs = exec_fspec; + + // Remove the binary name from the FileSpec + parent_dirs.RemoveLastPathComponent(); + + // Add a ".dSYM" name to each directory component of the path, + // stripping off components. e.g. we may have a binary like + // /S/L/F/Foundation.framework/Versions/A/Foundation and + // /S/L/F/Foundation.framework.dSYM + // + // so we'll need to start with + // /S/L/F/Foundation.framework/Versions/A, add the .dSYM part to the + // "A", and if that doesn't exist, strip off the "A" and try it again + // with "Versions", etc., until we find a dSYM bundle or we've + // stripped off enough path components that there's no need to + // continue. + + for (int i = 0; i < 4; i++) { + // Does this part of the path have a "." character - could it be a + // bundle's top level directory? + const char *fn = parent_dirs.GetFilename().AsCString(); + if (fn == nullptr) + break; + if (::strchr(fn, '.') != nullptr) { + if (::LookForDsymNextToExecutablePath(module_spec, parent_dirs, + dsym_fspec)) { + if (log) { + log->Printf("dSYM with matching UUID & arch found at %s", + dsym_fspec.GetPath().c_str()); + } + return true; + } + } + parent_dirs.RemoveLastPathComponent(); + } + } + } + dsym_fspec.Clear(); + return false; +} + +static FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) { + const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); + const ArchSpec *arch = module_spec.GetArchitecturePtr(); + const UUID *uuid = module_spec.GetUUIDPtr(); + + static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); + Timer scoped_timer( + func_cat, + "LocateExecutableSymbolFileDsym (file = %s, arch = %s, uuid = %p)", + exec_fspec ? exec_fspec->GetFilename().AsCString("<NULL>") : "<NULL>", + arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid); + + FileSpec symbol_fspec; + ModuleSpec dsym_module_spec; + // First try and find the dSYM in the same directory as the executable or in + // an appropriate parent directory + if (!LocateDSYMInVincinityOfExecutable(module_spec, symbol_fspec)) { + // We failed to easily find the dSYM above, so use DebugSymbols + LocateMacOSXFilesUsingDebugSymbols(module_spec, dsym_module_spec); + } else { + dsym_module_spec.GetSymbolFileSpec() = symbol_fspec; + } + return dsym_module_spec.GetSymbolFileSpec(); +} + +ModuleSpec Symbols::LocateExecutableObjectFile(const ModuleSpec &module_spec) { + ModuleSpec result; + const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); + const ArchSpec *arch = module_spec.GetArchitecturePtr(); + const UUID *uuid = module_spec.GetUUIDPtr(); + static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); + Timer scoped_timer( + func_cat, "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)", + exec_fspec ? exec_fspec->GetFilename().AsCString("<NULL>") : "<NULL>", + arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid); + + ModuleSpecList module_specs; + ModuleSpec matched_module_spec; + if (exec_fspec && + ObjectFile::GetModuleSpecifications(*exec_fspec, 0, 0, module_specs) && + module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) { + result.GetFileSpec() = exec_fspec; + } else { + LocateMacOSXFilesUsingDebugSymbols(module_spec, result); + } + return result; +} + +// Keep "symbols.enable-external-lookup" description in sync with this function. + +FileSpec +Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec, + const FileSpecList &default_search_paths) { + FileSpec symbol_file_spec = module_spec.GetSymbolFileSpec(); + if (symbol_file_spec.IsAbsolute() && + FileSystem::Instance().Exists(symbol_file_spec)) + return symbol_file_spec; + + const char *symbol_filename = symbol_file_spec.GetFilename().AsCString(); + if (symbol_filename && symbol_filename[0]) { + FileSpecList debug_file_search_paths = default_search_paths; + + // Add module directory. + FileSpec module_file_spec = module_spec.GetFileSpec(); + // We keep the unresolved pathname if it fails. + FileSystem::Instance().ResolveSymbolicLink(module_file_spec, + module_file_spec); + + ConstString file_dir = module_file_spec.GetDirectory(); + { + FileSpec file_spec(file_dir.AsCString(".")); + FileSystem::Instance().Resolve(file_spec); + debug_file_search_paths.AppendIfUnique(file_spec); + } + + if (ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) { + + // Add current working directory. + { + FileSpec file_spec("."); + FileSystem::Instance().Resolve(file_spec); + debug_file_search_paths.AppendIfUnique(file_spec); + } + +#ifndef _WIN32 +#if defined(__NetBSD__) + // Add /usr/libdata/debug directory. + { + FileSpec file_spec("/usr/libdata/debug"); + FileSystem::Instance().Resolve(file_spec); + debug_file_search_paths.AppendIfUnique(file_spec); + } +#else + // Add /usr/lib/debug directory. + { + FileSpec file_spec("/usr/lib/debug"); + FileSystem::Instance().Resolve(file_spec); + debug_file_search_paths.AppendIfUnique(file_spec); + } +#endif +#endif // _WIN32 + } + + std::string uuid_str; + const UUID &module_uuid = module_spec.GetUUID(); + if (module_uuid.IsValid()) { + // Some debug files are stored in the .build-id directory like this: + // /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug + uuid_str = module_uuid.GetAsString(""); + std::transform(uuid_str.begin(), uuid_str.end(), uuid_str.begin(), + ::tolower); + uuid_str.insert(2, 1, '/'); + uuid_str = uuid_str + ".debug"; + } + + size_t num_directories = debug_file_search_paths.GetSize(); + for (size_t idx = 0; idx < num_directories; ++idx) { + FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx); + FileSystem::Instance().Resolve(dirspec); + if (!FileSystem::Instance().IsDirectory(dirspec)) + continue; + + std::vector<std::string> files; + std::string dirname = dirspec.GetPath(); + + files.push_back(dirname + "/" + symbol_filename); + files.push_back(dirname + "/.debug/" + symbol_filename); + files.push_back(dirname + "/.build-id/" + uuid_str); + + // Some debug files may stored in the module directory like this: + // /usr/lib/debug/usr/lib/library.so.debug + if (!file_dir.IsEmpty()) + files.push_back(dirname + file_dir.AsCString() + "/" + symbol_filename); + + const uint32_t num_files = files.size(); + for (size_t idx_file = 0; idx_file < num_files; ++idx_file) { + const std::string &filename = files[idx_file]; + FileSpec file_spec(filename); + FileSystem::Instance().Resolve(file_spec); + + if (llvm::sys::fs::equivalent(file_spec.GetPath(), + module_file_spec.GetPath())) + continue; + + if (FileSystem::Instance().Exists(file_spec)) { + lldb_private::ModuleSpecList specs; + const size_t num_specs = + ObjectFile::GetModuleSpecifications(file_spec, 0, 0, specs); + assert(num_specs <= 1 && + "Symbol Vendor supports only a single architecture"); + if (num_specs == 1) { + ModuleSpec mspec; + if (specs.GetModuleSpecAtIndex(0, mspec)) { + // Skip the uuids check if module_uuid is invalid. For example, + // this happens for *.dwp files since at the moment llvm-dwp + // doesn't output build ids, nor does binutils dwp. + if (!module_uuid.IsValid() || module_uuid == mspec.GetUUID()) + return file_spec; + } + } + } + } + } + } + + return LocateExecutableSymbolFileDsym(module_spec); +} + +#if !defined(__APPLE__) + +FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &symfile_bundle, + const lldb_private::UUID *uuid, + const ArchSpec *arch) { + // FIXME + return FileSpec(); +} + +bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, + bool force_lookup) { + // Fill in the module_spec.GetFileSpec() for the object file and/or the + // module_spec.GetSymbolFileSpec() for the debug symbols file. + return false; +} + +#endif diff --git a/source/Symbol/LocateSymbolFileMacOSX.cpp b/source/Symbol/LocateSymbolFileMacOSX.cpp new file mode 100644 index 0000000000000..4e16382d53e77 --- /dev/null +++ b/source/Symbol/LocateSymbolFileMacOSX.cpp @@ -0,0 +1,657 @@ +//===-- LocateSymbolFileMacOSX.cpp ------------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Symbol/LocateSymbolFile.h" + +#include <dirent.h> +#include <dlfcn.h> +#include <pwd.h> + +#include <CoreFoundation/CoreFoundation.h> + +#include "Host/macosx/cfcpp/CFCBundle.h" +#include "Host/macosx/cfcpp/CFCData.h" +#include "Host/macosx/cfcpp/CFCReleaser.h" +#include "Host/macosx/cfcpp/CFCString.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Host/Host.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/CleanUp.h" +#include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/Timer.h" +#include "lldb/Utility/UUID.h" +#include "mach/machine.h" + +#include "llvm/Support/FileSystem.h" + +using namespace lldb; +using namespace lldb_private; + +static CFURLRef (*g_dlsym_DBGCopyFullDSYMURLForUUID)(CFUUIDRef uuid, CFURLRef exec_url) = nullptr; +static CFDictionaryRef (*g_dlsym_DBGCopyDSYMPropertyLists)(CFURLRef dsym_url) = nullptr; + +int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, + ModuleSpec &return_module_spec) { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) { + if (log) + log->Printf("Spotlight lookup for .dSYM bundles is disabled."); + return 0; + } + + return_module_spec = module_spec; + return_module_spec.GetFileSpec().Clear(); + return_module_spec.GetSymbolFileSpec().Clear(); + + int items_found = 0; + + if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr || + g_dlsym_DBGCopyDSYMPropertyLists == nullptr) { + void *handle = dlopen ("/System/Library/PrivateFrameworks/DebugSymbols.framework/DebugSymbols", RTLD_LAZY | RTLD_LOCAL); + if (handle) { + g_dlsym_DBGCopyFullDSYMURLForUUID = (CFURLRef (*)(CFUUIDRef, CFURLRef)) dlsym (handle, "DBGCopyFullDSYMURLForUUID"); + g_dlsym_DBGCopyDSYMPropertyLists = (CFDictionaryRef (*)(CFURLRef)) dlsym (handle, "DBGCopyDSYMPropertyLists"); + } + } + + if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr || + g_dlsym_DBGCopyDSYMPropertyLists == nullptr) { + return items_found; + } + + const UUID *uuid = module_spec.GetUUIDPtr(); + const ArchSpec *arch = module_spec.GetArchitecturePtr(); + + if (uuid && uuid->IsValid()) { + // Try and locate the dSYM file using DebugSymbols first + llvm::ArrayRef<uint8_t> module_uuid = uuid->GetBytes(); + if (module_uuid.size() == 16) { + CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes( + NULL, module_uuid[0], module_uuid[1], module_uuid[2], module_uuid[3], + module_uuid[4], module_uuid[5], module_uuid[6], module_uuid[7], + module_uuid[8], module_uuid[9], module_uuid[10], module_uuid[11], + module_uuid[12], module_uuid[13], module_uuid[14], module_uuid[15])); + + if (module_uuid_ref.get()) { + CFCReleaser<CFURLRef> exec_url; + const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); + if (exec_fspec) { + char exec_cf_path[PATH_MAX]; + if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path))) + exec_url.reset(::CFURLCreateFromFileSystemRepresentation( + NULL, (const UInt8 *)exec_cf_path, strlen(exec_cf_path), + FALSE)); + } + + CFCReleaser<CFURLRef> dsym_url( + g_dlsym_DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get())); + char path[PATH_MAX]; + + if (dsym_url.get()) { + if (::CFURLGetFileSystemRepresentation( + dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { + if (log) { + log->Printf("DebugSymbols framework returned dSYM path of %s for " + "UUID %s -- looking for the dSYM", + path, uuid->GetAsString().c_str()); + } + FileSpec dsym_filespec(path); + if (path[0] == '~') + FileSystem::Instance().Resolve(dsym_filespec); + + if (FileSystem::Instance().IsDirectory(dsym_filespec)) { + dsym_filespec = + Symbols::FindSymbolFileInBundle(dsym_filespec, uuid, arch); + ++items_found; + } else { + ++items_found; + } + return_module_spec.GetSymbolFileSpec() = dsym_filespec; + } + + bool success = false; + if (log) { + if (::CFURLGetFileSystemRepresentation( + dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { + log->Printf("DebugSymbols framework returned dSYM path of %s for " + "UUID %s -- looking for an exec file", + path, uuid->GetAsString().c_str()); + } + } + + CFCReleaser<CFDictionaryRef> dict( + g_dlsym_DBGCopyDSYMPropertyLists(dsym_url.get())); + CFDictionaryRef uuid_dict = NULL; + if (dict.get()) { + CFCString uuid_cfstr(uuid->GetAsString().c_str()); + uuid_dict = static_cast<CFDictionaryRef>( + ::CFDictionaryGetValue(dict.get(), uuid_cfstr.get())); + } + if (uuid_dict) { + CFStringRef exec_cf_path = + static_cast<CFStringRef>(::CFDictionaryGetValue( + uuid_dict, CFSTR("DBGSymbolRichExecutable"))); + if (exec_cf_path && ::CFStringGetFileSystemRepresentation( + exec_cf_path, path, sizeof(path))) { + if (log) { + log->Printf("plist bundle has exec path of %s for UUID %s", + path, uuid->GetAsString().c_str()); + } + ++items_found; + FileSpec exec_filespec(path); + if (path[0] == '~') + FileSystem::Instance().Resolve(exec_filespec); + if (FileSystem::Instance().Exists(exec_filespec)) { + success = true; + return_module_spec.GetFileSpec() = exec_filespec; + } + } + } + + if (!success) { + // No dictionary, check near the dSYM bundle for an executable that + // matches... + if (::CFURLGetFileSystemRepresentation( + dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { + char *dsym_extension_pos = ::strstr(path, ".dSYM"); + if (dsym_extension_pos) { + *dsym_extension_pos = '\0'; + if (log) { + log->Printf("Looking for executable binary next to dSYM " + "bundle with name with name %s", + path); + } + FileSpec file_spec(path); + FileSystem::Instance().Resolve(file_spec); + ModuleSpecList module_specs; + ModuleSpec matched_module_spec; + using namespace llvm::sys::fs; + switch (get_file_type(file_spec.GetPath())) { + + case file_type::directory_file: // Bundle directory? + { + CFCBundle bundle(path); + CFCReleaser<CFURLRef> bundle_exe_url( + bundle.CopyExecutableURL()); + if (bundle_exe_url.get()) { + if (::CFURLGetFileSystemRepresentation(bundle_exe_url.get(), + true, (UInt8 *)path, + sizeof(path) - 1)) { + FileSpec bundle_exe_file_spec(path); + FileSystem::Instance().Resolve(bundle_exe_file_spec); + if (ObjectFile::GetModuleSpecifications( + bundle_exe_file_spec, 0, 0, module_specs) && + module_specs.FindMatchingModuleSpec( + module_spec, matched_module_spec)) + + { + ++items_found; + return_module_spec.GetFileSpec() = bundle_exe_file_spec; + if (log) { + log->Printf("Executable binary %s next to dSYM is " + "compatible; using", + path); + } + } + } + } + } break; + + case file_type::fifo_file: // Forget pipes + case file_type::socket_file: // We can't process socket files + case file_type::file_not_found: // File doesn't exist... + case file_type::status_error: + break; + + case file_type::type_unknown: + case file_type::regular_file: + case file_type::symlink_file: + case file_type::block_file: + case file_type::character_file: + if (ObjectFile::GetModuleSpecifications(file_spec, 0, 0, + module_specs) && + module_specs.FindMatchingModuleSpec(module_spec, + matched_module_spec)) + + { + ++items_found; + return_module_spec.GetFileSpec() = file_spec; + if (log) { + log->Printf("Executable binary %s next to dSYM is " + "compatible; using", + path); + } + } + break; + } + } + } + } + } + } + } + } + + return items_found; +} + +FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec, + const lldb_private::UUID *uuid, + const ArchSpec *arch) { + char path[PATH_MAX]; + if (dsym_bundle_fspec.GetPath(path, sizeof(path)) == 0) + return {}; + + ::strncat(path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1); + + DIR *dirp = opendir(path); + if (!dirp) + return {}; + + // Make sure we close the directory before exiting this scope. + CleanUp cleanup_dir(closedir, dirp); + + FileSpec dsym_fspec; + dsym_fspec.GetDirectory().SetCString(path); + struct dirent *dp; + while ((dp = readdir(dirp)) != NULL) { + // Only search directories + if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) { + if (dp->d_namlen == 1 && dp->d_name[0] == '.') + continue; + + if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.') + continue; + } + + if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) { + dsym_fspec.GetFilename().SetCString(dp->d_name); + ModuleSpecList module_specs; + if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs)) { + ModuleSpec spec; + for (size_t i = 0; i < module_specs.GetSize(); ++i) { + bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec); + UNUSED_IF_ASSERT_DISABLED(got_spec); + assert(got_spec); + if ((uuid == NULL || + (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) && + (arch == NULL || + (spec.GetArchitecturePtr() && + spec.GetArchitecture().IsCompatibleMatch(*arch)))) { + return dsym_fspec; + } + } + } + } + } + + return {}; +} + +static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, + ModuleSpec &module_spec) { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + bool success = false; + if (uuid_dict != NULL && CFGetTypeID(uuid_dict) == CFDictionaryGetTypeID()) { + std::string str; + CFStringRef cf_str; + CFDictionaryRef cf_dict; + + cf_str = (CFStringRef)CFDictionaryGetValue( + (CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable")); + if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { + if (CFCString::FileSystemRepresentation(cf_str, str)) { + module_spec.GetFileSpec().SetFile(str.c_str(), FileSpec::Style::native); + FileSystem::Instance().Resolve(module_spec.GetFileSpec()); + if (log) { + log->Printf( + "From dsymForUUID plist: Symbol rich executable is at '%s'", + str.c_str()); + } + } + } + + cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, + CFSTR("DBGDSYMPath")); + if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { + if (CFCString::FileSystemRepresentation(cf_str, str)) { + module_spec.GetSymbolFileSpec().SetFile(str.c_str(), + FileSpec::Style::native); + FileSystem::Instance().Resolve(module_spec.GetFileSpec()); + success = true; + if (log) { + log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str()); + } + } + } + + cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, + CFSTR("DBGArchitecture")); + if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { + if (CFCString::FileSystemRepresentation(cf_str, str)) + module_spec.GetArchitecture().SetTriple(str.c_str()); + } + + std::string DBGBuildSourcePath; + std::string DBGSourcePath; + + // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping. + // If DBGVersion 2, strip last two components of path remappings from + // entries to fix an issue with a specific set of + // DBGSourcePathRemapping entries that lldb worked + // with. + // If DBGVersion 3, trust & use the source path remappings as-is. + // + cf_dict = (CFDictionaryRef)CFDictionaryGetValue( + (CFDictionaryRef)uuid_dict, CFSTR("DBGSourcePathRemapping")); + if (cf_dict && CFGetTypeID(cf_dict) == CFDictionaryGetTypeID()) { + // If we see DBGVersion with a value of 2 or higher, this is a new style + // DBGSourcePathRemapping dictionary + bool new_style_source_remapping_dictionary = false; + bool do_truncate_remapping_names = false; + std::string original_DBGSourcePath_value = DBGSourcePath; + cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, + CFSTR("DBGVersion")); + if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { + std::string version; + CFCString::FileSystemRepresentation(cf_str, version); + if (!version.empty() && isdigit(version[0])) { + int version_number = atoi(version.c_str()); + if (version_number > 1) { + new_style_source_remapping_dictionary = true; + } + if (version_number == 2) { + do_truncate_remapping_names = true; + } + } + } + + CFIndex kv_pair_count = CFDictionaryGetCount((CFDictionaryRef)uuid_dict); + if (kv_pair_count > 0) { + CFStringRef *keys = + (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef)); + CFStringRef *values = + (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef)); + if (keys != nullptr && values != nullptr) { + CFDictionaryGetKeysAndValues((CFDictionaryRef)uuid_dict, + (const void **)keys, + (const void **)values); + } + for (CFIndex i = 0; i < kv_pair_count; i++) { + DBGBuildSourcePath.clear(); + DBGSourcePath.clear(); + if (keys[i] && CFGetTypeID(keys[i]) == CFStringGetTypeID()) { + CFCString::FileSystemRepresentation(keys[i], DBGBuildSourcePath); + } + if (values[i] && CFGetTypeID(values[i]) == CFStringGetTypeID()) { + CFCString::FileSystemRepresentation(values[i], DBGSourcePath); + } + if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) { + // In the "old style" DBGSourcePathRemapping dictionary, the + // DBGSourcePath values (the "values" half of key-value path pairs) + // were wrong. Ignore them and use the universal DBGSourcePath + // string from earlier. + if (new_style_source_remapping_dictionary && + !original_DBGSourcePath_value.empty()) { + DBGSourcePath = original_DBGSourcePath_value; + } + if (DBGSourcePath[0] == '~') { + FileSpec resolved_source_path(DBGSourcePath.c_str()); + FileSystem::Instance().Resolve(resolved_source_path); + DBGSourcePath = resolved_source_path.GetPath(); + } + // With version 2 of DBGSourcePathRemapping, we can chop off the + // last two filename parts from the source remapping and get a more + // general source remapping that still works. Add this as another + // option in addition to the full source path remap. + module_spec.GetSourceMappingList().Append( + ConstString(DBGBuildSourcePath.c_str()), + ConstString(DBGSourcePath.c_str()), true); + if (do_truncate_remapping_names) { + FileSpec build_path(DBGBuildSourcePath.c_str()); + FileSpec source_path(DBGSourcePath.c_str()); + build_path.RemoveLastPathComponent(); + build_path.RemoveLastPathComponent(); + source_path.RemoveLastPathComponent(); + source_path.RemoveLastPathComponent(); + module_spec.GetSourceMappingList().Append( + ConstString(build_path.GetPath().c_str()), + ConstString(source_path.GetPath().c_str()), true); + } + } + } + if (keys) + free(keys); + if (values) + free(values); + } + } + + // If we have a DBGBuildSourcePath + DBGSourcePath pair, append them to the + // source remappings list. + + cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, + CFSTR("DBGBuildSourcePath")); + if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { + CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath); + } + + cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, + CFSTR("DBGSourcePath")); + if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { + CFCString::FileSystemRepresentation(cf_str, DBGSourcePath); + } + + if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) { + if (DBGSourcePath[0] == '~') { + FileSpec resolved_source_path(DBGSourcePath.c_str()); + FileSystem::Instance().Resolve(resolved_source_path); + DBGSourcePath = resolved_source_path.GetPath(); + } + module_spec.GetSourceMappingList().Append( + ConstString(DBGBuildSourcePath.c_str()), + ConstString(DBGSourcePath.c_str()), true); + } + } + return success; +} + +bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, + bool force_lookup) { + bool success = false; + const UUID *uuid_ptr = module_spec.GetUUIDPtr(); + const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr(); + + // It's expensive to check for the DBGShellCommands defaults setting, only do + // it once per lldb run and cache the result. + static bool g_have_checked_for_dbgshell_command = false; + static const char *g_dbgshell_command = NULL; + if (!g_have_checked_for_dbgshell_command) { + g_have_checked_for_dbgshell_command = true; + CFTypeRef defaults_setting = CFPreferencesCopyAppValue( + CFSTR("DBGShellCommands"), CFSTR("com.apple.DebugSymbols")); + if (defaults_setting && + CFGetTypeID(defaults_setting) == CFStringGetTypeID()) { + char cstr_buf[PATH_MAX]; + if (CFStringGetCString((CFStringRef)defaults_setting, cstr_buf, + sizeof(cstr_buf), kCFStringEncodingUTF8)) { + g_dbgshell_command = + strdup(cstr_buf); // this malloc'ed memory will never be freed + } + } + if (defaults_setting) { + CFRelease(defaults_setting); + } + } + + // When g_dbgshell_command is NULL, the user has not enabled the use of an + // external program to find the symbols, don't run it for them. + if (!force_lookup && g_dbgshell_command == NULL) { + return false; + } + + if (uuid_ptr || + (file_spec_ptr && FileSystem::Instance().Exists(*file_spec_ptr))) { + static bool g_located_dsym_for_uuid_exe = false; + static bool g_dsym_for_uuid_exe_exists = false; + static char g_dsym_for_uuid_exe_path[PATH_MAX]; + if (!g_located_dsym_for_uuid_exe) { + g_located_dsym_for_uuid_exe = true; + const char *dsym_for_uuid_exe_path_cstr = + getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE"); + FileSpec dsym_for_uuid_exe_spec; + if (dsym_for_uuid_exe_path_cstr) { + dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, + FileSpec::Style::native); + FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec); + g_dsym_for_uuid_exe_exists = + FileSystem::Instance().Exists(dsym_for_uuid_exe_spec); + } + + if (!g_dsym_for_uuid_exe_exists) { + dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", + FileSpec::Style::native); + g_dsym_for_uuid_exe_exists = + FileSystem::Instance().Exists(dsym_for_uuid_exe_spec); + if (!g_dsym_for_uuid_exe_exists) { + long bufsize; + if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1) { + char buffer[bufsize]; + struct passwd pwd; + struct passwd *tilde_rc = NULL; + // we are a library so we need to use the reentrant version of + // getpwnam() + if (getpwnam_r("rc", &pwd, buffer, bufsize, &tilde_rc) == 0 && + tilde_rc && tilde_rc->pw_dir) { + std::string dsymforuuid_path(tilde_rc->pw_dir); + dsymforuuid_path += "/bin/dsymForUUID"; + dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(), + FileSpec::Style::native); + g_dsym_for_uuid_exe_exists = + FileSystem::Instance().Exists(dsym_for_uuid_exe_spec); + } + } + } + } + if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) { + dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, + FileSpec::Style::native); + FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec); + g_dsym_for_uuid_exe_exists = + FileSystem::Instance().Exists(dsym_for_uuid_exe_spec); + } + + if (g_dsym_for_uuid_exe_exists) + dsym_for_uuid_exe_spec.GetPath(g_dsym_for_uuid_exe_path, + sizeof(g_dsym_for_uuid_exe_path)); + } + if (g_dsym_for_uuid_exe_exists) { + std::string uuid_str; + char file_path[PATH_MAX]; + file_path[0] = '\0'; + + if (uuid_ptr) + uuid_str = uuid_ptr->GetAsString(); + + if (file_spec_ptr) + file_spec_ptr->GetPath(file_path, sizeof(file_path)); + + StreamString command; + if (!uuid_str.empty()) + command.Printf("%s --ignoreNegativeCache --copyExecutable %s", + g_dsym_for_uuid_exe_path, uuid_str.c_str()); + else if (file_path[0] != '\0') + command.Printf("%s --ignoreNegativeCache --copyExecutable %s", + g_dsym_for_uuid_exe_path, file_path); + + if (!command.GetString().empty()) { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + int exit_status = -1; + int signo = -1; + std::string command_output; + if (log) { + if (!uuid_str.empty()) + log->Printf("Calling %s with UUID %s to find dSYM", + g_dsym_for_uuid_exe_path, uuid_str.c_str()); + else if (file_path[0] != '\0') + log->Printf("Calling %s with file %s to find dSYM", + g_dsym_for_uuid_exe_path, file_path); + } + Status error = Host::RunShellCommand( + command.GetData(), + NULL, // current working directory + &exit_status, // Exit status + &signo, // Signal int * + &command_output, // Command output + std::chrono::seconds( + 120), // Large timeout to allow for long dsym download times + false); // Don't run in a shell (we don't need shell expansion) + if (error.Success() && exit_status == 0 && !command_output.empty()) { + CFCData data(CFDataCreateWithBytesNoCopy( + NULL, (const UInt8 *)command_output.data(), command_output.size(), + kCFAllocatorNull)); + + CFCReleaser<CFDictionaryRef> plist( + (CFDictionaryRef)::CFPropertyListCreateFromXMLData( + NULL, data.get(), kCFPropertyListImmutable, NULL)); + + if (plist.get() && + CFGetTypeID(plist.get()) == CFDictionaryGetTypeID()) { + if (!uuid_str.empty()) { + CFCString uuid_cfstr(uuid_str.c_str()); + CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue( + plist.get(), uuid_cfstr.get()); + success = + GetModuleSpecInfoFromUUIDDictionary(uuid_dict, module_spec); + } else { + const CFIndex num_values = ::CFDictionaryGetCount(plist.get()); + if (num_values > 0) { + std::vector<CFStringRef> keys(num_values, NULL); + std::vector<CFDictionaryRef> values(num_values, NULL); + ::CFDictionaryGetKeysAndValues(plist.get(), NULL, + (const void **)&values[0]); + if (num_values == 1) { + return GetModuleSpecInfoFromUUIDDictionary(values[0], + module_spec); + } else { + for (CFIndex i = 0; i < num_values; ++i) { + ModuleSpec curr_module_spec; + if (GetModuleSpecInfoFromUUIDDictionary(values[i], + curr_module_spec)) { + if (module_spec.GetArchitecture().IsCompatibleMatch( + curr_module_spec.GetArchitecture())) { + module_spec = curr_module_spec; + return true; + } + } + } + } + } + } + } + } else { + if (log) { + if (!uuid_str.empty()) + log->Printf("Called %s on %s, no matches", + g_dsym_for_uuid_exe_path, uuid_str.c_str()); + else if (file_path[0] != '\0') + log->Printf("Called %s on %s, no matches", + g_dsym_for_uuid_exe_path, file_path); + } + } + } + } + } + return success; +} diff --git a/source/Symbol/ObjectFile.cpp b/source/Symbol/ObjectFile.cpp index 86c18c7beb0b6..172d2b3f01e32 100644 --- a/source/Symbol/ObjectFile.cpp +++ b/source/Symbol/ObjectFile.cpp @@ -1,9 +1,8 @@ //===-- ObjectFile.cpp ------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -57,13 +56,13 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file, PluginManager::GetObjectContainerCreateCallbackAtIndex( idx)) != nullptr; ++idx) { - std::unique_ptr<ObjectContainer> object_container_ap( + std::unique_ptr<ObjectContainer> object_container_up( create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size)); - if (object_container_ap.get()) - object_file_sp = object_container_ap->GetObjectFile(file); + if (object_container_up) + object_file_sp = object_container_up->GetObjectFile(file); if (object_file_sp.get()) return object_file_sp; @@ -106,13 +105,13 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file, PluginManager::GetObjectContainerCreateCallbackAtIndex( idx)) != nullptr; ++idx) { - std::unique_ptr<ObjectContainer> object_container_ap( + std::unique_ptr<ObjectContainer> object_container_up( create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size)); - if (object_container_ap.get()) - object_file_sp = object_container_ap->GetObjectFile(file); + if (object_container_up) + object_file_sp = object_container_up->GetObjectFile(file); if (object_file_sp.get()) return object_file_sp; @@ -148,12 +147,12 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file, PluginManager::GetObjectContainerCreateCallbackAtIndex( idx)) != nullptr; ++idx) { - std::unique_ptr<ObjectContainer> object_container_ap( + std::unique_ptr<ObjectContainer> object_container_up( create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size)); - if (object_container_ap.get()) - object_file_sp = object_container_ap->GetObjectFile(file); + if (object_container_up) + object_file_sp = object_container_up->GetObjectFile(file); if (object_file_sp.get()) return object_file_sp; @@ -264,9 +263,8 @@ ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp, : ModuleChild(module_sp), m_file(), // This file could be different from the original module's file m_type(eTypeInvalid), m_strata(eStrataInvalid), - m_file_offset(file_offset), m_length(length), m_data(), - m_unwind_table(*this), m_process_wp(), - m_memory_addr(LLDB_INVALID_ADDRESS), m_sections_ap(), m_symtab_ap(), + m_file_offset(file_offset), m_length(length), m_data(), m_process_wp(), + m_memory_addr(LLDB_INVALID_ADDRESS), m_sections_up(), m_symtab_up(), m_synthetic_symbol_idx(0) { if (file_spec_ptr) m_file = *file_spec_ptr; @@ -287,9 +285,8 @@ ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp, DataBufferSP &header_data_sp) : ModuleChild(module_sp), m_file(), m_type(eTypeInvalid), m_strata(eStrataInvalid), m_file_offset(0), m_length(0), m_data(), - m_unwind_table(*this), m_process_wp(process_sp), - m_memory_addr(header_addr), m_sections_ap(), m_symtab_ap(), - m_synthetic_symbol_idx(0) { + m_process_wp(process_sp), m_memory_addr(header_addr), m_sections_up(), + m_symtab_up(), m_synthetic_symbol_idx(0) { if (header_data_sp) m_data.SetData(header_data_sp, 0, header_data_sp->GetByteSize()); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); @@ -368,6 +365,7 @@ AddressClass ObjectFile::GetAddressClass(addr_t file_addr) { case eSectionTypeDWARFDebugStrOffsets: case eSectionTypeDWARFDebugStrOffsetsDwo: case eSectionTypeDWARFDebugTypes: + case eSectionTypeDWARFDebugTypesDwo: case eSectionTypeDWARFAppleNames: case eSectionTypeDWARFAppleTypes: case eSectionTypeDWARFAppleNamespaces: @@ -464,12 +462,12 @@ DataBufferSP ObjectFile::ReadMemory(const ProcessSP &process_sp, lldb::addr_t addr, size_t byte_size) { DataBufferSP data_sp; if (process_sp) { - std::unique_ptr<DataBufferHeap> data_ap(new DataBufferHeap(byte_size, 0)); + std::unique_ptr<DataBufferHeap> data_up(new DataBufferHeap(byte_size, 0)); Status error; const size_t bytes_read = process_sp->ReadMemory( - addr, data_ap->GetBytes(), data_ap->GetByteSize(), error); + addr, data_up->GetBytes(), data_up->GetByteSize(), error); if (bytes_read == byte_size) - data_sp.reset(data_ap.release()); + data_sp.reset(data_up.release()); } return data_sp; } @@ -536,9 +534,7 @@ size_t ObjectFile::ReadSectionData(Section *section, return 0; } -//---------------------------------------------------------------------- // Get the section data the file on disk -//---------------------------------------------------------------------- size_t ObjectFile::ReadSectionData(Section *section, DataExtractor §ion_data) { // If some other objectfile owns this data, pass this to them. @@ -602,13 +598,13 @@ void ObjectFile::ClearSymtab() { if (log) log->Printf("%p ObjectFile::ClearSymtab () symtab = %p", static_cast<void *>(this), - static_cast<void *>(m_symtab_ap.get())); - m_symtab_ap.reset(); + static_cast<void *>(m_symtab_up.get())); + m_symtab_up.reset(); } } SectionList *ObjectFile::GetSectionList(bool update_module_section_list) { - if (m_sections_ap.get() == nullptr) { + if (m_sections_up == nullptr) { if (update_module_section_list) { ModuleSP module_sp(GetModule()); if (module_sp) { @@ -620,7 +616,7 @@ SectionList *ObjectFile::GetSectionList(bool update_module_section_list) { CreateSections(unified_section_list); } } - return m_sections_ap.get(); + return m_sections_up.get(); } lldb::SymbolType diff --git a/source/Symbol/PostfixExpression.cpp b/source/Symbol/PostfixExpression.cpp new file mode 100644 index 0000000000000..148653561a4ed --- /dev/null +++ b/source/Symbol/PostfixExpression.cpp @@ -0,0 +1,227 @@ +//===-- PostfixExpression.cpp -----------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file implements support for postfix expressions found in several symbol +// file formats, and their conversion to DWARF. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Symbol/PostfixExpression.h" +#include "lldb/Core/dwarf.h" +#include "lldb/Utility/Stream.h" +#include "llvm/ADT/StringExtras.h" + +using namespace lldb_private; +using namespace lldb_private::postfix; + +static llvm::Optional<BinaryOpNode::OpType> +GetBinaryOpType(llvm::StringRef token) { + if (token.size() != 1) + return llvm::None; + switch (token[0]) { + case '@': + return BinaryOpNode::Align; + case '-': + return BinaryOpNode::Minus; + case '+': + return BinaryOpNode::Plus; + } + return llvm::None; +} + +static llvm::Optional<UnaryOpNode::OpType> +GetUnaryOpType(llvm::StringRef token) { + if (token == "^") + return UnaryOpNode::Deref; + return llvm::None; +} + +Node *postfix::Parse(llvm::StringRef expr, llvm::BumpPtrAllocator &alloc) { + llvm::SmallVector<Node *, 4> stack; + + llvm::StringRef token; + while (std::tie(token, expr) = getToken(expr), !token.empty()) { + if (auto op_type = GetBinaryOpType(token)) { + // token is binary operator + if (stack.size() < 2) + return nullptr; + + Node *right = stack.pop_back_val(); + Node *left = stack.pop_back_val(); + stack.push_back(MakeNode<BinaryOpNode>(alloc, *op_type, *left, *right)); + continue; + } + + if (auto op_type = GetUnaryOpType(token)) { + // token is unary operator + if (stack.empty()) + return nullptr; + + Node *operand = stack.pop_back_val(); + stack.push_back(MakeNode<UnaryOpNode>(alloc, *op_type, *operand)); + continue; + } + + int64_t value; + if (to_integer(token, value, 10)) { + // token is integer literal + stack.push_back(MakeNode<IntegerNode>(alloc, value)); + continue; + } + + stack.push_back(MakeNode<SymbolNode>(alloc, token)); + } + + if (stack.size() != 1) + return nullptr; + + return stack.back(); +} + +namespace { +class SymbolResolver : public Visitor<bool> { +public: + SymbolResolver(llvm::function_ref<Node *(SymbolNode &symbol)> replacer) + : m_replacer(replacer) {} + + using Visitor<bool>::Dispatch; + +private: + bool Visit(BinaryOpNode &binary, Node *&) override { + return Dispatch(binary.Left()) && Dispatch(binary.Right()); + } + + bool Visit(InitialValueNode &, Node *&) override { return true; } + bool Visit(IntegerNode &, Node *&) override { return true; } + bool Visit(RegisterNode &, Node *&) override { return true; } + + bool Visit(SymbolNode &symbol, Node *&ref) override { + if (Node *replacement = m_replacer(symbol)) { + ref = replacement; + if (replacement != &symbol) + return Dispatch(ref); + return true; + } + return false; + } + + bool Visit(UnaryOpNode &unary, Node *&) override { + return Dispatch(unary.Operand()); + } + + llvm::function_ref<Node *(SymbolNode &symbol)> m_replacer; +}; + +class DWARFCodegen : public Visitor<> { +public: + DWARFCodegen(Stream &stream) : m_out_stream(stream) {} + + using Visitor<>::Dispatch; + +private: + void Visit(BinaryOpNode &binary, Node *&) override; + + void Visit(InitialValueNode &val, Node *&) override; + + void Visit(IntegerNode &integer, Node *&) override { + m_out_stream.PutHex8(DW_OP_consts); + m_out_stream.PutSLEB128(integer.GetValue()); + ++m_stack_depth; + } + + void Visit(RegisterNode ®, Node *&) override; + + void Visit(SymbolNode &symbol, Node *&) override { + llvm_unreachable("Symbols should have been resolved by now!"); + } + + void Visit(UnaryOpNode &unary, Node *&) override; + + Stream &m_out_stream; + + /// The number keeping track of the evaluation stack depth at any given + /// moment. Used for implementing InitialValueNodes. We start with + /// m_stack_depth = 1, assuming that the initial value is already on the + /// stack. This initial value will be the value of all InitialValueNodes. If + /// the expression does not contain InitialValueNodes, then m_stack_depth is + /// not used, and the generated expression will run correctly even without an + /// initial value. + size_t m_stack_depth = 1; +}; +} // namespace + +void DWARFCodegen::Visit(BinaryOpNode &binary, Node *&) { + Dispatch(binary.Left()); + Dispatch(binary.Right()); + + switch (binary.GetOpType()) { + case BinaryOpNode::Plus: + m_out_stream.PutHex8(DW_OP_plus); + // NOTE: can be optimized by using DW_OP_plus_uconst opcpode + // if right child node is constant value + break; + case BinaryOpNode::Minus: + m_out_stream.PutHex8(DW_OP_minus); + break; + case BinaryOpNode::Align: + // emit align operator a @ b as + // a & ~(b - 1) + // NOTE: implicitly assuming that b is power of 2 + m_out_stream.PutHex8(DW_OP_lit1); + m_out_stream.PutHex8(DW_OP_minus); + m_out_stream.PutHex8(DW_OP_not); + + m_out_stream.PutHex8(DW_OP_and); + break; + } + --m_stack_depth; // Two pops, one push. +} + +void DWARFCodegen::Visit(InitialValueNode &, Node *&) { + // We never go below the initial stack, so we can pick the initial value from + // the bottom of the stack at any moment. + assert(m_stack_depth >= 1); + m_out_stream.PutHex8(DW_OP_pick); + m_out_stream.PutHex8(m_stack_depth - 1); + ++m_stack_depth; +} + +void DWARFCodegen::Visit(RegisterNode ®, Node *&) { + uint32_t reg_num = reg.GetRegNum(); + assert(reg_num != LLDB_INVALID_REGNUM); + + if (reg_num > 31) { + m_out_stream.PutHex8(DW_OP_bregx); + m_out_stream.PutULEB128(reg_num); + } else + m_out_stream.PutHex8(DW_OP_breg0 + reg_num); + + m_out_stream.PutSLEB128(0); + ++m_stack_depth; +} + +void DWARFCodegen::Visit(UnaryOpNode &unary, Node *&) { + Dispatch(unary.Operand()); + + switch (unary.GetOpType()) { + case UnaryOpNode::Deref: + m_out_stream.PutHex8(DW_OP_deref); + break; + } + // Stack depth unchanged. +} + +bool postfix::ResolveSymbols( + Node *&node, llvm::function_ref<Node *(SymbolNode &)> replacer) { + return SymbolResolver(replacer).Dispatch(node); +} + +void postfix::ToDWARF(Node &node, Stream &stream) { + Node *ptr = &node; + DWARFCodegen(stream).Dispatch(ptr); +} diff --git a/source/Symbol/Symbol.cpp b/source/Symbol/Symbol.cpp index 8d055c1c6712b..589f69244a480 100644 --- a/source/Symbol/Symbol.cpp +++ b/source/Symbol/Symbol.cpp @@ -1,9 +1,8 @@ //===-- Symbol.cpp ----------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -29,7 +28,8 @@ Symbol::Symbol() m_is_external(false), m_size_is_sibling(false), m_size_is_synthesized(false), m_size_is_valid(false), m_demangled_is_synthesized(false), m_contains_linker_annotations(false), - m_type(eSymbolTypeInvalid), m_mangled(), m_addr_range(), m_flags() {} + m_is_weak(false), m_type(eSymbolTypeInvalid), m_mangled(), m_addr_range(), + m_flags() {} Symbol::Symbol(uint32_t symID, const char *name, bool name_is_mangled, SymbolType type, bool external, bool is_debug, @@ -42,7 +42,8 @@ Symbol::Symbol(uint32_t symID, const char *name, bool name_is_mangled, m_is_debug(is_debug), m_is_external(external), m_size_is_sibling(false), m_size_is_synthesized(false), m_size_is_valid(size_is_valid || size > 0), m_demangled_is_synthesized(false), - m_contains_linker_annotations(contains_linker_annotations), m_type(type), + m_contains_linker_annotations(contains_linker_annotations), + m_is_weak(false), m_type(type), m_mangled(ConstString(name), name_is_mangled), m_addr_range(section_sp, offset, size), m_flags(flags) {} @@ -57,8 +58,9 @@ Symbol::Symbol(uint32_t symID, const Mangled &mangled, SymbolType type, m_size_is_synthesized(false), m_size_is_valid(size_is_valid || range.GetByteSize() > 0), m_demangled_is_synthesized(false), - m_contains_linker_annotations(contains_linker_annotations), m_type(type), - m_mangled(mangled), m_addr_range(range), m_flags(flags) {} + m_contains_linker_annotations(contains_linker_annotations), + m_is_weak(false), m_type(type), m_mangled(mangled), m_addr_range(range), + m_flags(flags) {} Symbol::Symbol(const Symbol &rhs) : SymbolContextScope(rhs), m_uid(rhs.m_uid), m_type_data(rhs.m_type_data), @@ -69,7 +71,7 @@ Symbol::Symbol(const Symbol &rhs) m_size_is_valid(rhs.m_size_is_valid), m_demangled_is_synthesized(rhs.m_demangled_is_synthesized), m_contains_linker_annotations(rhs.m_contains_linker_annotations), - m_type(rhs.m_type), m_mangled(rhs.m_mangled), + m_is_weak(rhs.m_is_weak), m_type(rhs.m_type), m_mangled(rhs.m_mangled), m_addr_range(rhs.m_addr_range), m_flags(rhs.m_flags) {} const Symbol &Symbol::operator=(const Symbol &rhs) { @@ -86,6 +88,7 @@ const Symbol &Symbol::operator=(const Symbol &rhs) { m_size_is_valid = rhs.m_size_is_valid; m_demangled_is_synthesized = rhs.m_demangled_is_synthesized; m_contains_linker_annotations = rhs.m_contains_linker_annotations; + m_is_weak = rhs.m_is_weak; m_type = rhs.m_type; m_mangled = rhs.m_mangled; m_addr_range = rhs.m_addr_range; @@ -107,6 +110,7 @@ void Symbol::Clear() { m_size_is_valid = false; m_demangled_is_synthesized = false; m_contains_linker_annotations = false; + m_is_weak = false; m_type = eSymbolTypeInvalid; m_flags = 0; m_addr_range.Clear(); @@ -146,7 +150,7 @@ FileSpec Symbol::GetReExportedSymbolSharedLibrary() const { return FileSpec(); } -void Symbol::SetReExportedSymbolName(const ConstString &name) { +void Symbol::SetReExportedSymbolName(ConstString name) { SetType(eSymbolTypeReExported); // For eSymbolTypeReExported, the "const char *" from a ConstString is used // as the offset in the address range base address. @@ -326,7 +330,7 @@ uint32_t Symbol::GetPrologueByteSize() { return 0; } -bool Symbol::Compare(const ConstString &name, SymbolType type) const { +bool Symbol::Compare(ConstString name, SymbolType type) const { if (type == eSymbolTypeAny || m_type == type) return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName(GetLanguage()) == name; diff --git a/source/Symbol/SymbolContext.cpp b/source/Symbol/SymbolContext.cpp index da00875bfa151..a0b35cf3d0b99 100644 --- a/source/Symbol/SymbolContext.cpp +++ b/source/Symbol/SymbolContext.cpp @@ -1,9 +1,8 @@ //===-- SymbolContext.cpp ---------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -48,11 +47,6 @@ SymbolContext::SymbolContext(const TargetSP &t, const ModuleSP &m, line_entry = *le; } -SymbolContext::SymbolContext(const SymbolContext &rhs) - : target_sp(rhs.target_sp), module_sp(rhs.module_sp), - comp_unit(rhs.comp_unit), function(rhs.function), block(rhs.block), - line_entry(rhs.line_entry), symbol(rhs.symbol), variable(rhs.variable) {} - SymbolContext::SymbolContext(SymbolContextScope *sc_scope) : target_sp(), module_sp(), comp_unit(nullptr), function(nullptr), block(nullptr), line_entry(), symbol(nullptr), variable(nullptr) { @@ -507,7 +501,7 @@ bool SymbolContext::GetParentOfInlinedScope(const Address &curr_frame_pc, } #ifdef LLDB_CONFIGURATION_DEBUG else { - ObjectFile *objfile = NULL; + ObjectFile *objfile = nullptr; if (module_sp) { SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(); if (symbol_vendor) { @@ -587,10 +581,8 @@ void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const { curr_block->GetContainingInlinedBlock() != nullptr) isInlinedblock = true; - //---------------------------------------------------------------------- // Find all types that match the current block if we have one and put them // first in the list. Keep iterating up through all blocks. - //---------------------------------------------------------------------- while (curr_block != nullptr && !isInlinedblock) { type_map.ForEach( [curr_block, &type_list](const lldb::TypeSP &type_sp) -> bool { @@ -608,10 +600,8 @@ void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const { }); curr_block = curr_block->GetParent(); } - //---------------------------------------------------------------------- // Find all types that match the current function, if we have onem, and put // them next in the list. - //---------------------------------------------------------------------- if (function != nullptr && !type_map.Empty()) { const size_t old_type_list_size = type_list.GetSize(); type_map.ForEach([this, &type_list](const lldb::TypeSP &type_sp) -> bool { @@ -629,10 +619,8 @@ void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const { type_map.Remove(type_list.GetTypeAtIndex(i)); } } - //---------------------------------------------------------------------- // Find all types that match the current compile unit, if we have one, and // put them next in the list. - //---------------------------------------------------------------------- if (comp_unit != nullptr && !type_map.Empty()) { const size_t old_type_list_size = type_list.GetSize(); @@ -651,10 +639,8 @@ void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const { type_map.Remove(type_list.GetTypeAtIndex(i)); } } - //---------------------------------------------------------------------- // Find all types that match the current module, if we have one, and put them // next in the list. - //---------------------------------------------------------------------- if (module_sp && !type_map.Empty()) { const size_t old_type_list_size = type_list.GetSize(); type_map.ForEach([this, &type_list](const lldb::TypeSP &type_sp) -> bool { @@ -671,9 +657,7 @@ void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const { type_map.Remove(type_list.GetTypeAtIndex(i)); } } - //---------------------------------------------------------------------- // Any types that are left get copied into the list an any order. - //---------------------------------------------------------------------- if (!type_map.Empty()) { type_map.ForEach([&type_list](const lldb::TypeSP &type_sp) -> bool { type_list.Insert(type_sp); @@ -745,7 +729,7 @@ bool SymbolContext::GetAddressRangeFromHereToEndLine(uint32_t end_line, uint32_t line_index = 0; bool found = false; - while (1) { + while (true) { LineEntry this_line; line_index = comp_unit->FindLineEntry(line_index, line_entry.line, nullptr, false, &this_line); @@ -794,7 +778,7 @@ bool SymbolContext::GetAddressRangeFromHereToEndLine(uint32_t end_line, } const Symbol * -SymbolContext::FindBestGlobalDataSymbol(const ConstString &name, Status &error) { +SymbolContext::FindBestGlobalDataSymbol(ConstString name, Status &error) { error.Clear(); if (!target_sp) { @@ -950,16 +934,14 @@ SymbolContext::FindBestGlobalDataSymbol(const ConstString &name, Status &error) } -//---------------------------------------------------------------------- // // SymbolContextSpecifier // -//---------------------------------------------------------------------- SymbolContextSpecifier::SymbolContextSpecifier(const TargetSP &target_sp) - : m_target_sp(target_sp), m_module_spec(), m_module_sp(), m_file_spec_ap(), + : m_target_sp(target_sp), m_module_spec(), m_module_sp(), m_file_spec_up(), m_start_line(0), m_end_line(0), m_function_spec(), m_class_name(), - m_address_range_ap(), m_type(eNothingSpecified) {} + m_address_range_up(), m_type(eNothingSpecified) {} SymbolContextSpecifier::~SymbolContextSpecifier() {} @@ -1008,7 +990,7 @@ bool SymbolContextSpecifier::AddSpecification(const char *spec_string, // CompUnits can't necessarily be resolved here, since an inlined function // might show up in a number of CompUnits. Instead we just convert to a // FileSpec and store it away. - m_file_spec_ap.reset(new FileSpec(spec_string)); + m_file_spec_up.reset(new FileSpec(spec_string)); m_type |= eFileSpecified; break; case eLineStartSpecified: @@ -1040,12 +1022,12 @@ bool SymbolContextSpecifier::AddSpecification(const char *spec_string, void SymbolContextSpecifier::Clear() { m_module_spec.clear(); - m_file_spec_ap.reset(); + m_file_spec_up.reset(); m_function_spec.clear(); m_class_name.clear(); m_start_line = 0; m_end_line = 0; - m_address_range_ap.reset(); + m_address_range_up.reset(); m_type = eNothingSpecified; } @@ -1071,7 +1053,7 @@ bool SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) { } } if (m_type & eFileSpecified) { - if (m_file_spec_ap.get()) { + if (m_file_spec_up) { // If we don't have a block or a comp_unit, then we aren't going to match // a source file. if (sc.block == nullptr && sc.comp_unit == nullptr) @@ -1085,7 +1067,7 @@ bool SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) { if (inline_info != nullptr) { was_inlined = true; if (!FileSpec::Equal(inline_info->GetDeclaration().GetFile(), - *(m_file_spec_ap.get()), false)) + *(m_file_spec_up.get()), false)) return false; } } @@ -1093,7 +1075,7 @@ bool SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) { // Next check the comp unit, but only if the SymbolContext was not // inlined. if (!was_inlined && sc.comp_unit != nullptr) { - if (!FileSpec::Equal(*(sc.comp_unit), *(m_file_spec_ap.get()), false)) + if (!FileSpec::Equal(*(sc.comp_unit), *(m_file_spec_up.get()), false)) return false; } } @@ -1166,8 +1148,8 @@ void SymbolContextSpecifier::GetDescription( s->Printf("Module: %s\n", m_module_spec.c_str()); } - if (m_type == eFileSpecified && m_file_spec_ap.get() != nullptr) { - m_file_spec_ap->GetPath(path_str, PATH_MAX); + if (m_type == eFileSpecified && m_file_spec_up != nullptr) { + m_file_spec_up->GetPath(path_str, PATH_MAX); s->Indent(); s->Printf("File: %s", path_str); if (m_type == eLineStartSpecified) { @@ -1204,21 +1186,19 @@ void SymbolContextSpecifier::GetDescription( s->Printf("Class name: %s.\n", m_class_name.c_str()); } - if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != nullptr) { + if (m_type == eAddressRangeSpecified && m_address_range_up != nullptr) { s->Indent(); s->PutCString("Address range: "); - m_address_range_ap->Dump(s, m_target_sp.get(), + m_address_range_up->Dump(s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); s->PutCString("\n"); } } -//---------------------------------------------------------------------- // // SymbolContextList // -//---------------------------------------------------------------------- SymbolContextList::SymbolContextList() : m_symbol_contexts() {} diff --git a/source/Symbol/SymbolFile.cpp b/source/Symbol/SymbolFile.cpp index 6087374969fb7..77ab2223ec07f 100644 --- a/source/Symbol/SymbolFile.cpp +++ b/source/Symbol/SymbolFile.cpp @@ -1,9 +1,8 @@ //===-- SymbolFile.cpp ------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -32,7 +31,7 @@ std::recursive_mutex &SymbolFile::GetModuleMutex() const { } SymbolFile *SymbolFile::FindPlugin(ObjectFile *obj_file) { - std::unique_ptr<SymbolFile> best_symfile_ap; + std::unique_ptr<SymbolFile> best_symfile_up; if (obj_file != nullptr) { // We need to test the abilities of this section list. So create what it @@ -58,13 +57,13 @@ SymbolFile *SymbolFile::FindPlugin(ObjectFile *obj_file) { (create_callback = PluginManager::GetSymbolFileCreateCallbackAtIndex( idx)) != nullptr; ++idx) { - std::unique_ptr<SymbolFile> curr_symfile_ap(create_callback(obj_file)); + std::unique_ptr<SymbolFile> curr_symfile_up(create_callback(obj_file)); - if (curr_symfile_ap.get()) { - const uint32_t sym_file_abilities = curr_symfile_ap->GetAbilities(); + if (curr_symfile_up) { + const uint32_t sym_file_abilities = curr_symfile_up->GetAbilities(); if (sym_file_abilities > best_symfile_abilities) { best_symfile_abilities = sym_file_abilities; - best_symfile_ap.reset(curr_symfile_ap.release()); + best_symfile_up.reset(curr_symfile_up.release()); // If any symbol file parser has all of the abilities, then we should // just stop looking. if ((kAllAbilities & sym_file_abilities) == kAllAbilities) @@ -72,13 +71,13 @@ SymbolFile *SymbolFile::FindPlugin(ObjectFile *obj_file) { } } } - if (best_symfile_ap.get()) { + if (best_symfile_up) { // Let the winning symbol file parser initialize itself more completely // now that it has been chosen - best_symfile_ap->InitializeObject(); + best_symfile_up->InitializeObject(); } } - return best_symfile_ap.release(); + return best_symfile_up.release(); } TypeList *SymbolFile::GetTypeList() { @@ -103,7 +102,7 @@ uint32_t SymbolFile::ResolveSymbolContext(const FileSpec &file_spec, } uint32_t -SymbolFile::FindGlobalVariables(const ConstString &name, +SymbolFile::FindGlobalVariables(ConstString name, const CompilerDeclContext *parent_decl_ctx, uint32_t max_matches, VariableList &variables) { return 0; @@ -115,7 +114,7 @@ uint32_t SymbolFile::FindGlobalVariables(const RegularExpression ®ex, return 0; } -uint32_t SymbolFile::FindFunctions(const ConstString &name, +uint32_t SymbolFile::FindFunctions(ConstString name, const CompilerDeclContext *parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, bool append, @@ -140,7 +139,7 @@ void SymbolFile::GetMangledNamesForFunction( } uint32_t SymbolFile::FindTypes( - const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap &types) { @@ -169,3 +168,5 @@ void SymbolFile::AssertModuleLock() { "Module is not locked"); #endif } + +SymbolFile::RegisterInfoResolver::~RegisterInfoResolver() = default; diff --git a/source/Symbol/SymbolVendor.cpp b/source/Symbol/SymbolVendor.cpp index a9badc15a5d60..b9f3a5fe3926c 100644 --- a/source/Symbol/SymbolVendor.cpp +++ b/source/Symbol/SymbolVendor.cpp @@ -1,9 +1,8 @@ //===-- SymbolVendor.cpp ----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -19,61 +18,60 @@ using namespace lldb; using namespace lldb_private; -//---------------------------------------------------------------------- // FindPlugin // // Platforms can register a callback to use when creating symbol vendors to // allow for complex debug information file setups, and to also allow for // finding separate debug information files. -//---------------------------------------------------------------------- SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm) { - std::unique_ptr<SymbolVendor> instance_ap; + std::unique_ptr<SymbolVendor> instance_up; SymbolVendorCreateInstance create_callback; for (size_t idx = 0; (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex( idx)) != nullptr; ++idx) { - instance_ap.reset(create_callback(module_sp, feedback_strm)); + instance_up.reset(create_callback(module_sp, feedback_strm)); - if (instance_ap.get()) { - return instance_ap.release(); + if (instance_up) { + return instance_up.release(); } } // The default implementation just tries to create debug information using // the file representation for the module. - instance_ap.reset(new SymbolVendor(module_sp)); - if (instance_ap.get()) { - ObjectFile *objfile = module_sp->GetObjectFile(); - if (objfile) - instance_ap->AddSymbolFileRepresentation(objfile->shared_from_this()); + ObjectFileSP sym_objfile_sp; + FileSpec sym_spec = module_sp->GetSymbolFileFileSpec(); + if (sym_spec && sym_spec != module_sp->GetObjectFile()->GetFileSpec()) { + DataBufferSP data_sp; + offset_t data_offset = 0; + sym_objfile_sp = ObjectFile::FindPlugin( + module_sp, &sym_spec, 0, FileSystem::Instance().GetByteSize(sym_spec), + data_sp, data_offset); } - return instance_ap.release(); + if (!sym_objfile_sp) + sym_objfile_sp = module_sp->GetObjectFile()->shared_from_this(); + instance_up.reset(new SymbolVendor(module_sp)); + instance_up->AddSymbolFileRepresentation(sym_objfile_sp); + return instance_up.release(); } -//---------------------------------------------------------------------- // SymbolVendor constructor -//---------------------------------------------------------------------- SymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp) - : ModuleChild(module_sp), m_type_list(), m_compile_units(), - m_sym_file_ap(), m_symtab() {} + : ModuleChild(module_sp), m_type_list(), m_compile_units(), m_sym_file_up(), + m_symtab() {} -//---------------------------------------------------------------------- // Destructor -//---------------------------------------------------------------------- SymbolVendor::~SymbolVendor() {} -//---------------------------------------------------------------------- // Add a representation given an object file. -//---------------------------------------------------------------------- void SymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); if (objfile_sp) { m_objfile_sp = objfile_sp; - m_sym_file_ap.reset(SymbolFile::FindPlugin(objfile_sp.get())); + m_sym_file_up.reset(SymbolFile::FindPlugin(objfile_sp.get())); } } } @@ -106,12 +104,12 @@ size_t SymbolVendor::GetNumCompileUnits() { if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); if (m_compile_units.empty()) { - if (m_sym_file_ap.get()) { + if (m_sym_file_up) { // Resize our array of compile unit shared pointers -- which will each // remain NULL until someone asks for the actual compile unit // information. When this happens, the symbol file will be asked to // parse this compile unit information. - m_compile_units.resize(m_sym_file_ap->GetNumCompileUnits()); + m_compile_units.resize(m_sym_file_up->GetNumCompileUnits()); } } } @@ -122,8 +120,8 @@ lldb::LanguageType SymbolVendor::ParseLanguage(CompileUnit &comp_unit) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseLanguage(comp_unit); + if (m_sym_file_up) + return m_sym_file_up->ParseLanguage(comp_unit); } return eLanguageTypeUnknown; } @@ -132,8 +130,8 @@ size_t SymbolVendor::ParseFunctions(CompileUnit &comp_unit) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseFunctions(comp_unit); + if (m_sym_file_up) + return m_sym_file_up->ParseFunctions(comp_unit); } return 0; } @@ -142,8 +140,8 @@ bool SymbolVendor::ParseLineTable(CompileUnit &comp_unit) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseLineTable(comp_unit); + if (m_sym_file_up) + return m_sym_file_up->ParseLineTable(comp_unit); } return false; } @@ -152,8 +150,8 @@ bool SymbolVendor::ParseDebugMacros(CompileUnit &comp_unit) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseDebugMacros(comp_unit); + if (m_sym_file_up) + return m_sym_file_up->ParseDebugMacros(comp_unit); } return false; } @@ -162,8 +160,8 @@ bool SymbolVendor::ParseSupportFiles(CompileUnit &comp_unit, ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseSupportFiles(comp_unit, support_files); + if (m_sym_file_up) + return m_sym_file_up->ParseSupportFiles(comp_unit, support_files); } return false; } @@ -172,19 +170,19 @@ bool SymbolVendor::ParseIsOptimized(CompileUnit &comp_unit) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseIsOptimized(comp_unit); + if (m_sym_file_up) + return m_sym_file_up->ParseIsOptimized(comp_unit); } return false; } bool SymbolVendor::ParseImportedModules( - const SymbolContext &sc, std::vector<ConstString> &imported_modules) { + const SymbolContext &sc, std::vector<SourceModule> &imported_modules) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseImportedModules(sc, imported_modules); + if (m_sym_file_up) + return m_sym_file_up->ParseImportedModules(sc, imported_modules); } return false; } @@ -193,8 +191,8 @@ size_t SymbolVendor::ParseBlocksRecursive(Function &func) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseBlocksRecursive(func); + if (m_sym_file_up) + return m_sym_file_up->ParseBlocksRecursive(func); } return 0; } @@ -203,8 +201,8 @@ size_t SymbolVendor::ParseTypes(CompileUnit &comp_unit) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseTypes(comp_unit); + if (m_sym_file_up) + return m_sym_file_up->ParseTypes(comp_unit); } return 0; } @@ -213,8 +211,8 @@ size_t SymbolVendor::ParseVariablesForContext(const SymbolContext &sc) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseVariablesForContext(sc); + if (m_sym_file_up) + return m_sym_file_up->ParseVariablesForContext(sc); } return 0; } @@ -223,8 +221,8 @@ Type *SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->ResolveTypeUID(type_uid); + if (m_sym_file_up) + return m_sym_file_up->ResolveTypeUID(type_uid); } return nullptr; } @@ -235,8 +233,8 @@ uint32_t SymbolVendor::ResolveSymbolContext(const Address &so_addr, ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->ResolveSymbolContext(so_addr, resolve_scope, sc); + if (m_sym_file_up) + return m_sym_file_up->ResolveSymbolContext(so_addr, resolve_scope, sc); } return 0; } @@ -248,22 +246,22 @@ uint32_t SymbolVendor::ResolveSymbolContext(const FileSpec &file_spec, ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->ResolveSymbolContext(file_spec, line, check_inlines, + if (m_sym_file_up) + return m_sym_file_up->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list); } return 0; } size_t -SymbolVendor::FindGlobalVariables(const ConstString &name, +SymbolVendor::FindGlobalVariables(ConstString name, const CompilerDeclContext *parent_decl_ctx, size_t max_matches, VariableList &variables) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->FindGlobalVariables(name, parent_decl_ctx, + if (m_sym_file_up) + return m_sym_file_up->FindGlobalVariables(name, parent_decl_ctx, max_matches, variables); } return 0; @@ -275,13 +273,13 @@ size_t SymbolVendor::FindGlobalVariables(const RegularExpression ®ex, ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->FindGlobalVariables(regex, max_matches, variables); + if (m_sym_file_up) + return m_sym_file_up->FindGlobalVariables(regex, max_matches, variables); } return 0; } -size_t SymbolVendor::FindFunctions(const ConstString &name, +size_t SymbolVendor::FindFunctions(ConstString name, const CompilerDeclContext *parent_decl_ctx, FunctionNameType name_type_mask, bool include_inlines, bool append, @@ -289,8 +287,8 @@ size_t SymbolVendor::FindFunctions(const ConstString &name, ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->FindFunctions(name, parent_decl_ctx, name_type_mask, + if (m_sym_file_up) + return m_sym_file_up->FindFunctions(name, parent_decl_ctx, name_type_mask, include_inlines, append, sc_list); } return 0; @@ -302,23 +300,23 @@ size_t SymbolVendor::FindFunctions(const RegularExpression ®ex, ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->FindFunctions(regex, include_inlines, append, + if (m_sym_file_up) + return m_sym_file_up->FindFunctions(regex, include_inlines, append, sc_list); } return 0; } size_t SymbolVendor::FindTypes( - const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap &types) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->FindTypes(name, parent_decl_ctx, append, + if (m_sym_file_up) + return m_sym_file_up->FindTypes(name, parent_decl_ctx, append, max_matches, searched_symbol_files, types); } @@ -332,8 +330,8 @@ size_t SymbolVendor::FindTypes(const std::vector<CompilerContext> &context, ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->FindTypes(context, append, types); + if (m_sym_file_up) + return m_sym_file_up->FindTypes(context, append, types); } if (!append) types.Clear(); @@ -345,21 +343,21 @@ size_t SymbolVendor::GetTypes(SymbolContextScope *sc_scope, TypeClass type_mask, ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - return m_sym_file_ap->GetTypes(sc_scope, type_mask, type_list); + if (m_sym_file_up) + return m_sym_file_up->GetTypes(sc_scope, type_mask, type_list); } return 0; } CompilerDeclContext -SymbolVendor::FindNamespace(const ConstString &name, +SymbolVendor::FindNamespace(ConstString name, const CompilerDeclContext *parent_decl_ctx) { CompilerDeclContext namespace_decl_ctx; ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_sym_file_ap.get()) - namespace_decl_ctx = m_sym_file_ap->FindNamespace(name, parent_decl_ctx); + if (m_sym_file_up) + namespace_decl_ctx = m_sym_file_up->FindNamespace(name, parent_decl_ctx); } return namespace_decl_ctx; } @@ -374,9 +372,9 @@ void SymbolVendor::Dump(Stream *s) { s->Printf("%p: ", static_cast<void *>(this)); s->Indent(); s->PutCString("SymbolVendor"); - if (m_sym_file_ap.get()) { - *s << " " << m_sym_file_ap->GetPluginName(); - ObjectFile *objfile = m_sym_file_ap->GetObjectFile(); + if (m_sym_file_up) { + *s << " " << m_sym_file_up->GetPluginName(); + ObjectFile *objfile = m_sym_file_up->GetObjectFile(); if (objfile) { const FileSpec &objfile_file_spec = objfile->GetFileSpec(); if (objfile_file_spec) { @@ -387,8 +385,8 @@ void SymbolVendor::Dump(Stream *s) { } } s->EOL(); - if (m_sym_file_ap) - m_sym_file_ap->Dump(*s); + if (m_sym_file_up) + m_sym_file_up->Dump(*s); s->IndentMore(); m_type_list.Dump(s, show_context); @@ -396,7 +394,7 @@ void SymbolVendor::Dump(Stream *s) { cu_end = m_compile_units.end(); for (cu_pos = m_compile_units.begin(); cu_pos != cu_end; ++cu_pos) { // We currently only dump the compile units that have been parsed - if (cu_pos->get()) + if (*cu_pos) (*cu_pos)->Dump(s, show_context); } @@ -416,7 +414,7 @@ CompUnitSP SymbolVendor::GetCompileUnitAtIndex(size_t idx) { if (idx < num_compile_units) { cu_sp = m_compile_units[idx]; if (cu_sp.get() == nullptr) { - m_compile_units[idx] = m_sym_file_ap->ParseCompileUnitAtIndex(idx); + m_compile_units[idx] = m_sym_file_up->ParseCompileUnitAtIndex(idx); cu_sp = m_compile_units[idx]; } } @@ -425,8 +423,8 @@ CompUnitSP SymbolVendor::GetCompileUnitAtIndex(size_t idx) { } FileSpec SymbolVendor::GetMainFileSpec() const { - if (m_sym_file_ap.get()) { - const ObjectFile *symfile_objfile = m_sym_file_ap->GetObjectFile(); + if (m_sym_file_up) { + const ObjectFile *symfile_objfile = m_sym_file_up->GetObjectFile(); if (symfile_objfile) return symfile_objfile->GetFileSpec(); } @@ -449,8 +447,8 @@ Symtab *SymbolVendor::GetSymtab() { return nullptr; m_symtab = objfile->GetSymtab(); - if (m_symtab && m_sym_file_ap) - m_sym_file_ap->AddSymbols(*m_symtab); + if (m_symtab && m_sym_file_up) + m_sym_file_up->AddSymbols(*m_symtab); return m_symtab; } @@ -470,8 +468,8 @@ void SymbolVendor::SectionFileAddressesChanged() { ModuleSP module_sp(GetModule()); if (module_sp) { ObjectFile *module_objfile = module_sp->GetObjectFile(); - if (m_sym_file_ap.get()) { - ObjectFile *symfile_objfile = m_sym_file_ap->GetObjectFile(); + if (m_sym_file_up) { + ObjectFile *symfile_objfile = m_sym_file_up->GetObjectFile(); if (symfile_objfile != module_objfile) symfile_objfile->SectionFileAddressesChanged(); } @@ -482,9 +480,7 @@ void SymbolVendor::SectionFileAddressesChanged() { } } -//------------------------------------------------------------------ // PluginInterface protocol -//------------------------------------------------------------------ lldb_private::ConstString SymbolVendor::GetPluginName() { static ConstString g_name("vendor-default"); return g_name; diff --git a/source/Symbol/Symtab.cpp b/source/Symbol/Symtab.cpp index 2472580a41d56..29c390e838781 100644 --- a/source/Symbol/Symtab.cpp +++ b/source/Symbol/Symtab.cpp @@ -1,9 +1,8 @@ //===-- Symtab.cpp ----------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -217,9 +216,6 @@ const Symbol *Symtab::SymbolAtIndex(size_t idx) const { return nullptr; } -//---------------------------------------------------------------------- -// InitNameIndexes -//---------------------------------------------------------------------- static bool lldb_skip_name(llvm::StringRef mangled, Mangled::ManglingScheme scheme) { switch (scheme) { @@ -262,25 +258,7 @@ void Symtab::InitNameIndexes() { Timer scoped_timer(func_cat, "%s", LLVM_PRETTY_FUNCTION); // Create the name index vector to be able to quickly search by name const size_t num_symbols = m_symbols.size(); -#if 1 m_name_to_index.Reserve(num_symbols); -#else - // TODO: benchmark this to see if we save any memory. Otherwise we - // will always keep the memory reserved in the vector unless we pull some - // STL swap magic and then recopy... - uint32_t actual_count = 0; - for (const_iterator pos = m_symbols.begin(), end = m_symbols.end(); - pos != end; ++pos) { - const Mangled &mangled = pos->GetMangled(); - if (mangled.GetMangledName()) - ++actual_count; - - if (mangled.GetDemangledName()) - ++actual_count; - } - - m_name_to_index.Reserve(actual_count); -#endif // The "const char *" in "class_contexts" and backlog::value_type::second // must come from a ConstString::GetCString() @@ -291,10 +269,8 @@ void Symtab::InitNameIndexes() { // Instantiation of the demangler is expensive, so better use a single one // for all entries during batch processing. RichManglingContext rmc; - NameToIndexMap::Entry entry; - - for (entry.value = 0; entry.value < num_symbols; ++entry.value) { - Symbol *symbol = &m_symbols[entry.value]; + for (uint32_t value = 0; value < num_symbols; ++value) { + Symbol *symbol = &m_symbols[value]; // Don't let trampolines get into the lookup by name map If we ever need // the trampoline symbols to be searchable by name we can remove this and @@ -306,52 +282,46 @@ void Symtab::InitNameIndexes() { // If the symbol's name string matched a Mangled::ManglingScheme, it is // stored in the mangled field. Mangled &mangled = symbol->GetMangled(); - entry.cstring = mangled.GetMangledName(); - if (entry.cstring) { - m_name_to_index.Append(entry); + if (ConstString name = mangled.GetMangledName()) { + m_name_to_index.Append(name, value); if (symbol->ContainsLinkerAnnotations()) { // If the symbol has linker annotations, also add the version without // the annotations. - entry.cstring = ConstString(m_objfile->StripLinkerSymbolAnnotations( - entry.cstring.GetStringRef())); - m_name_to_index.Append(entry); + ConstString stripped = ConstString( + m_objfile->StripLinkerSymbolAnnotations(name.GetStringRef())); + m_name_to_index.Append(stripped, value); } const SymbolType type = symbol->GetType(); if (type == eSymbolTypeCode || type == eSymbolTypeResolver) { if (mangled.DemangleWithRichManglingInfo(rmc, lldb_skip_name)) - RegisterMangledNameEntry(entry, class_contexts, backlog, rmc); + RegisterMangledNameEntry(value, class_contexts, backlog, rmc); } } // Symbol name strings that didn't match a Mangled::ManglingScheme, are // stored in the demangled field. - entry.cstring = mangled.GetDemangledName(symbol->GetLanguage()); - if (entry.cstring) { - m_name_to_index.Append(entry); + if (ConstString name = mangled.GetDemangledName(symbol->GetLanguage())) { + m_name_to_index.Append(name, value); if (symbol->ContainsLinkerAnnotations()) { // If the symbol has linker annotations, also add the version without // the annotations. - entry.cstring = ConstString(m_objfile->StripLinkerSymbolAnnotations( - entry.cstring.GetStringRef())); - m_name_to_index.Append(entry); + name = ConstString( + m_objfile->StripLinkerSymbolAnnotations(name.GetStringRef())); + m_name_to_index.Append(name, value); } - } - // If the demangled name turns out to be an ObjC name, and is a category - // name, add the version without categories to the index too. - ObjCLanguage::MethodName objc_method(entry.cstring.GetStringRef(), true); - if (objc_method.IsValid(true)) { - entry.cstring = objc_method.GetSelector(); - m_selector_to_index.Append(entry); - - ConstString objc_method_no_category( - objc_method.GetFullNameWithoutCategory(true)); - if (objc_method_no_category) { - entry.cstring = objc_method_no_category; - m_name_to_index.Append(entry); + // If the demangled name turns out to be an ObjC name, and is a category + // name, add the version without categories to the index too. + ObjCLanguage::MethodName objc_method(name.GetStringRef(), true); + if (objc_method.IsValid(true)) { + m_selector_to_index.Append(objc_method.GetSelector(), value); + + if (ConstString objc_method_no_category = + objc_method.GetFullNameWithoutCategory(true)) + m_name_to_index.Append(objc_method_no_category, value); } } } @@ -372,7 +342,7 @@ void Symtab::InitNameIndexes() { } void Symtab::RegisterMangledNameEntry( - NameToIndexMap::Entry &entry, std::set<const char *> &class_contexts, + uint32_t value, std::set<const char *> &class_contexts, std::vector<std::pair<NameToIndexMap::Entry, const char *>> &backlog, RichManglingContext &rmc) { // Only register functions that have a base name. @@ -382,7 +352,7 @@ void Symtab::RegisterMangledNameEntry( return; // The base name will be our entry's name. - entry.cstring = ConstString(base_name); + NameToIndexMap::Entry entry(ConstString(base_name), value); rmc.ParseFunctionDeclContextName(); llvm::StringRef decl_context = rmc.GetBufferRef(); @@ -450,24 +420,21 @@ void Symtab::AppendSymbolNamesToMap(const IndexCollection &indexes, std::lock_guard<std::recursive_mutex> guard(m_mutex); // Create the name index vector to be able to quickly search by name - NameToIndexMap::Entry entry; const size_t num_indexes = indexes.size(); for (size_t i = 0; i < num_indexes; ++i) { - entry.value = indexes[i]; + uint32_t value = indexes[i]; assert(i < m_symbols.size()); - const Symbol *symbol = &m_symbols[entry.value]; + const Symbol *symbol = &m_symbols[value]; const Mangled &mangled = symbol->GetMangled(); if (add_demangled) { - entry.cstring = mangled.GetDemangledName(symbol->GetLanguage()); - if (entry.cstring) - name_to_index_map.Append(entry); + if (ConstString name = mangled.GetDemangledName(symbol->GetLanguage())) + name_to_index_map.Append(name, value); } if (add_mangled) { - entry.cstring = mangled.GetMangledName(); - if (entry.cstring) - name_to_index_map.Append(entry); + if (ConstString name = mangled.GetMangledName()) + name_to_index_map.Append(name, value); } } } @@ -626,7 +593,7 @@ void Symtab::SortSymbolIndexesByValue(std::vector<uint32_t> &indexes, } } -uint32_t Symtab::AppendSymbolIndexesWithName(const ConstString &symbol_name, +uint32_t Symtab::AppendSymbolIndexesWithName(ConstString symbol_name, std::vector<uint32_t> &indexes) { std::lock_guard<std::recursive_mutex> guard(m_mutex); @@ -641,7 +608,7 @@ uint32_t Symtab::AppendSymbolIndexesWithName(const ConstString &symbol_name, return 0; } -uint32_t Symtab::AppendSymbolIndexesWithName(const ConstString &symbol_name, +uint32_t Symtab::AppendSymbolIndexesWithName(ConstString symbol_name, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t> &indexes) { @@ -668,7 +635,7 @@ uint32_t Symtab::AppendSymbolIndexesWithName(const ConstString &symbol_name, } uint32_t -Symtab::AppendSymbolIndexesWithNameAndType(const ConstString &symbol_name, +Symtab::AppendSymbolIndexesWithNameAndType(ConstString symbol_name, SymbolType symbol_type, std::vector<uint32_t> &indexes) { std::lock_guard<std::recursive_mutex> guard(m_mutex); @@ -687,7 +654,7 @@ Symtab::AppendSymbolIndexesWithNameAndType(const ConstString &symbol_name, } uint32_t Symtab::AppendSymbolIndexesWithNameAndType( - const ConstString &symbol_name, SymbolType symbol_type, + ConstString symbol_name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t> &indexes) { std::lock_guard<std::recursive_mutex> guard(m_mutex); @@ -772,7 +739,7 @@ Symbol *Symtab::FindSymbolWithType(SymbolType symbol_type, } size_t -Symtab::FindAllSymbolsWithNameAndType(const ConstString &name, +Symtab::FindAllSymbolsWithNameAndType(ConstString name, SymbolType symbol_type, std::vector<uint32_t> &symbol_indexes) { std::lock_guard<std::recursive_mutex> guard(m_mutex); @@ -793,7 +760,7 @@ Symtab::FindAllSymbolsWithNameAndType(const ConstString &name, } size_t Symtab::FindAllSymbolsWithNameAndType( - const ConstString &name, SymbolType symbol_type, Debug symbol_debug_type, + ConstString name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t> &symbol_indexes) { std::lock_guard<std::recursive_mutex> guard(m_mutex); @@ -824,7 +791,7 @@ size_t Symtab::FindAllSymbolsMatchingRexExAndType( return symbol_indexes.size(); } -Symbol *Symtab::FindFirstSymbolWithNameAndType(const ConstString &name, +Symbol *Symtab::FindFirstSymbolWithNameAndType(ConstString name, SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility) { @@ -929,8 +896,14 @@ void Symtab::InitAddressIndexes() { for (size_t i = 0; i < num_entries; i++) { FileRangeToIndexMap::Entry *entry = m_file_addr_to_index.GetMutableEntryAtIndex(i); - if (entry->GetByteSize() == 0) { - addr_t curr_base_addr = entry->GetRangeBase(); + if (entry->GetByteSize() > 0) + continue; + addr_t curr_base_addr = entry->GetRangeBase(); + // Symbols with non-zero size will show after zero-sized symbols on the + // same address. So do not set size of a non-last zero-sized symbol. + if (i == num_entries - 1 || + m_file_addr_to_index.GetMutableEntryAtIndex(i + 1) + ->GetRangeBase() != curr_base_addr) { const RangeVector<addr_t, addr_t>::Entry *containing_section = section_ranges.FindEntryThatContains(curr_base_addr); @@ -1051,7 +1024,7 @@ void Symtab::SymbolIndicesToSymbolContextList( } } -size_t Symtab::FindFunctionSymbols(const ConstString &name, +size_t Symtab::FindFunctionSymbols(ConstString name, uint32_t name_type_mask, SymbolContextList &sc_list) { size_t count = 0; @@ -1152,5 +1125,5 @@ const Symbol *Symtab::GetParent(Symbol *child_symbol) const { return symbol; } } - return NULL; + return nullptr; } diff --git a/source/Symbol/Type.cpp b/source/Symbol/Type.cpp index e966c269408a4..4ee8330ce288f 100644 --- a/source/Symbol/Type.cpp +++ b/source/Symbol/Type.cpp @@ -1,9 +1,8 @@ //===-- Type.cpp ------------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -108,7 +107,7 @@ Type *SymbolFileType::GetType() { } Type::Type(lldb::user_id_t uid, SymbolFile *symbol_file, - const ConstString &name, uint64_t byte_size, + ConstString name, llvm::Optional<uint64_t> byte_size, SymbolContextScope *context, user_id_t encoding_uid, EncodingDataType encoding_uid_type, const Declaration &decl, const CompilerType &compiler_type, @@ -116,7 +115,14 @@ Type::Type(lldb::user_id_t uid, SymbolFile *symbol_file, : std::enable_shared_from_this<Type>(), UserID(uid), m_name(name), m_symbol_file(symbol_file), m_context(context), m_encoding_type(nullptr), m_encoding_uid(encoding_uid), m_encoding_uid_type(encoding_uid_type), - m_byte_size(byte_size), m_decl(decl), m_compiler_type(compiler_type) { + m_decl(decl), m_compiler_type(compiler_type) { + if (byte_size) { + m_byte_size = *byte_size; + m_byte_size_has_value = true; + } else { + m_byte_size = 0; + m_byte_size_has_value = false; + } m_flags.compiler_type_resolve_state = (compiler_type ? compiler_type_resolve_state : eResolveStateUnresolved); m_flags.is_complete_objc_class = false; @@ -126,32 +132,19 @@ Type::Type() : std::enable_shared_from_this<Type>(), UserID(0), m_name("<INVALID TYPE>"), m_symbol_file(nullptr), m_context(nullptr), m_encoding_type(nullptr), m_encoding_uid(LLDB_INVALID_UID), m_encoding_uid_type(eEncodingInvalid), - m_byte_size(0), m_decl(), m_compiler_type() { + m_byte_size(0), m_byte_size_has_value(false), m_decl(), + m_compiler_type() { m_flags.compiler_type_resolve_state = eResolveStateUnresolved; m_flags.is_complete_objc_class = false; } -Type::Type(const Type &rhs) - : std::enable_shared_from_this<Type>(rhs), UserID(rhs), m_name(rhs.m_name), - m_symbol_file(rhs.m_symbol_file), m_context(rhs.m_context), - m_encoding_type(rhs.m_encoding_type), m_encoding_uid(rhs.m_encoding_uid), - m_encoding_uid_type(rhs.m_encoding_uid_type), - m_byte_size(rhs.m_byte_size), m_decl(rhs.m_decl), - m_compiler_type(rhs.m_compiler_type), m_flags(rhs.m_flags) {} - -const Type &Type::operator=(const Type &rhs) { - if (this != &rhs) { - } - return *this; -} - void Type::GetDescription(Stream *s, lldb::DescriptionLevel level, bool show_name) { *s << "id = " << (const UserID &)*this; // Call the name accessor to make sure we resolve the type name if (show_name) { - const ConstString &type_name = GetName(); + ConstString type_name = GetName(); if (type_name) { *s << ", name = \"" << type_name << '"'; ConstString qualified_type_name(GetQualifiedName()); @@ -214,7 +207,7 @@ void Type::Dump(Stream *s, bool show_context) { if (m_name) *s << ", name = \"" << m_name << "\""; - if (m_byte_size != 0) + if (m_byte_size_has_value) s->Printf(", size = %" PRIu64, m_byte_size); if (show_context && m_context != nullptr) { @@ -270,7 +263,7 @@ void Type::Dump(Stream *s, bool show_context) { s->EOL(); } -const ConstString &Type::GetName() { +ConstString Type::GetName() { if (!m_name) m_name = GetForwardCompilerType().GetConstTypeName(); return m_name; @@ -293,7 +286,7 @@ void Type::DumpValue(ExecutionContext *exe_ctx, Stream *s, GetForwardCompilerType().DumpValue( exe_ctx, s, format == lldb::eFormatDefault ? GetFormat() : format, data, - data_byte_offset, GetByteSize(), + data_byte_offset, GetByteSize().getValueOr(0), 0, // Bitfield bit size 0, // Bitfield bit offset show_types, show_summary, verbose, 0); @@ -306,36 +299,46 @@ Type *Type::GetEncodingType() { return m_encoding_type; } -uint64_t Type::GetByteSize() { - if (m_byte_size == 0) { - switch (m_encoding_uid_type) { - case eEncodingInvalid: - case eEncodingIsSyntheticUID: - break; - case eEncodingIsUID: - case eEncodingIsConstUID: - case eEncodingIsRestrictUID: - case eEncodingIsVolatileUID: - case eEncodingIsTypedefUID: { - Type *encoding_type = GetEncodingType(); - if (encoding_type) - m_byte_size = encoding_type->GetByteSize(); - if (m_byte_size == 0) - if (llvm::Optional<uint64_t> size = - GetLayoutCompilerType().GetByteSize(nullptr)) - m_byte_size = *size; - } break; +llvm::Optional<uint64_t> Type::GetByteSize() { + if (m_byte_size_has_value) + return m_byte_size; + + switch (m_encoding_uid_type) { + case eEncodingInvalid: + case eEncodingIsSyntheticUID: + break; + case eEncodingIsUID: + case eEncodingIsConstUID: + case eEncodingIsRestrictUID: + case eEncodingIsVolatileUID: + case eEncodingIsTypedefUID: { + Type *encoding_type = GetEncodingType(); + if (encoding_type) + if (llvm::Optional<uint64_t> size = encoding_type->GetByteSize()) { + m_byte_size = *size; + m_byte_size_has_value = true; + return m_byte_size; + } + + if (llvm::Optional<uint64_t> size = + GetLayoutCompilerType().GetByteSize(nullptr)) { + m_byte_size = *size; + m_byte_size_has_value = true; + return m_byte_size; + } + } break; // If we are a pointer or reference, then this is just a pointer size; case eEncodingIsPointerUID: case eEncodingIsLValueReferenceUID: case eEncodingIsRValueReferenceUID: { - if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) + if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) { m_byte_size = arch.GetAddressByteSize(); + m_byte_size_has_value = true; + } } break; - } } - return m_byte_size; + return {}; } uint32_t Type::GetNumChildren(bool omit_empty_base_classes) { @@ -389,7 +392,7 @@ bool Type::ReadFromMemory(ExecutionContext *exe_ctx, lldb::addr_t addr, return false; } - const uint64_t byte_size = GetByteSize(); + const uint64_t byte_size = GetByteSize().getValueOr(0); if (data.GetByteSize() < byte_size) { lldb::DataBufferSP data_sp(new DataBufferHeap(byte_size, '\0')); data.SetData(data_sp); @@ -678,32 +681,21 @@ ModuleSP Type::GetModule() { return ModuleSP(); } -TypeAndOrName::TypeAndOrName() : m_type_pair(), m_type_name() {} - -TypeAndOrName::TypeAndOrName(TypeSP &in_type_sp) : m_type_pair(in_type_sp) { - if (in_type_sp) +TypeAndOrName::TypeAndOrName(TypeSP &in_type_sp) { + if (in_type_sp) { + m_compiler_type = in_type_sp->GetForwardCompilerType(); m_type_name = in_type_sp->GetName(); + } } TypeAndOrName::TypeAndOrName(const char *in_type_str) : m_type_name(in_type_str) {} -TypeAndOrName::TypeAndOrName(const TypeAndOrName &rhs) - : m_type_pair(rhs.m_type_pair), m_type_name(rhs.m_type_name) {} - TypeAndOrName::TypeAndOrName(ConstString &in_type_const_string) : m_type_name(in_type_const_string) {} -TypeAndOrName &TypeAndOrName::operator=(const TypeAndOrName &rhs) { - if (this != &rhs) { - m_type_name = rhs.m_type_name; - m_type_pair = rhs.m_type_pair; - } - return *this; -} - bool TypeAndOrName::operator==(const TypeAndOrName &other) const { - if (m_type_pair != other.m_type_pair) + if (m_compiler_type != other.m_compiler_type) return false; if (m_type_name != other.m_type_name) return false; @@ -717,12 +709,12 @@ bool TypeAndOrName::operator!=(const TypeAndOrName &other) const { ConstString TypeAndOrName::GetName() const { if (m_type_name) return m_type_name; - if (m_type_pair) - return m_type_pair.GetName(); + if (m_compiler_type) + return m_compiler_type.GetTypeName(); return ConstString("<invalid>"); } -void TypeAndOrName::SetName(const ConstString &type_name) { +void TypeAndOrName::SetName(ConstString type_name) { m_type_name = type_name; } @@ -731,42 +723,34 @@ void TypeAndOrName::SetName(const char *type_name_cstr) { } void TypeAndOrName::SetTypeSP(lldb::TypeSP type_sp) { - m_type_pair.SetType(type_sp); - if (m_type_pair) - m_type_name = m_type_pair.GetName(); + if (type_sp) { + m_compiler_type = type_sp->GetForwardCompilerType(); + m_type_name = type_sp->GetName(); + } else + Clear(); } void TypeAndOrName::SetCompilerType(CompilerType compiler_type) { - m_type_pair.SetType(compiler_type); - if (m_type_pair) - m_type_name = m_type_pair.GetName(); + m_compiler_type = compiler_type; + if (m_compiler_type) + m_type_name = m_compiler_type.GetTypeName(); } bool TypeAndOrName::IsEmpty() const { - return !((bool)m_type_name || (bool)m_type_pair); + return !((bool)m_type_name || (bool)m_compiler_type); } void TypeAndOrName::Clear() { m_type_name.Clear(); - m_type_pair.Clear(); + m_compiler_type.Clear(); } bool TypeAndOrName::HasName() const { return (bool)m_type_name; } -bool TypeAndOrName::HasTypeSP() const { - return m_type_pair.GetTypeSP().get() != nullptr; -} - bool TypeAndOrName::HasCompilerType() const { - return m_type_pair.GetCompilerType().IsValid(); + return m_compiler_type.IsValid(); } -TypeImpl::TypeImpl() : m_module_wp(), m_static_type(), m_dynamic_type() {} - -TypeImpl::TypeImpl(const TypeImpl &rhs) - : m_module_wp(rhs.m_module_wp), m_static_type(rhs.m_static_type), - m_dynamic_type(rhs.m_dynamic_type) {} - TypeImpl::TypeImpl(const lldb::TypeSP &type_sp) : m_module_wp(), m_static_type(), m_dynamic_type() { SetType(type_sp); @@ -778,7 +762,7 @@ TypeImpl::TypeImpl(const CompilerType &compiler_type) } TypeImpl::TypeImpl(const lldb::TypeSP &type_sp, const CompilerType &dynamic) - : m_module_wp(), m_static_type(type_sp), m_dynamic_type(dynamic) { + : m_module_wp(), m_static_type(), m_dynamic_type(dynamic) { SetType(type_sp, dynamic); } @@ -788,22 +772,19 @@ TypeImpl::TypeImpl(const CompilerType &static_type, SetType(static_type, dynamic_type); } -TypeImpl::TypeImpl(const TypePair &pair, const CompilerType &dynamic) - : m_module_wp(), m_static_type(), m_dynamic_type() { - SetType(pair, dynamic); -} - void TypeImpl::SetType(const lldb::TypeSP &type_sp) { - m_static_type.SetType(type_sp); - if (type_sp) + if (type_sp) { + m_static_type = type_sp->GetForwardCompilerType(); m_module_wp = type_sp->GetModule(); - else + } else { + m_static_type.Clear(); m_module_wp = lldb::ModuleWP(); + } } void TypeImpl::SetType(const CompilerType &compiler_type) { m_module_wp = lldb::ModuleWP(); - m_static_type.SetType(compiler_type); + m_static_type = compiler_type; } void TypeImpl::SetType(const lldb::TypeSP &type_sp, @@ -815,25 +796,10 @@ void TypeImpl::SetType(const lldb::TypeSP &type_sp, void TypeImpl::SetType(const CompilerType &compiler_type, const CompilerType &dynamic) { m_module_wp = lldb::ModuleWP(); - m_static_type.SetType(compiler_type); + m_static_type = compiler_type; m_dynamic_type = dynamic; } -void TypeImpl::SetType(const TypePair &pair, const CompilerType &dynamic) { - m_module_wp = pair.GetModule(); - m_static_type = pair; - m_dynamic_type = dynamic; -} - -TypeImpl &TypeImpl::operator=(const TypeImpl &rhs) { - if (rhs != *this) { - m_module_wp = rhs.m_module_wp; - m_static_type = rhs.m_static_type; - m_dynamic_type = rhs.m_dynamic_type; - } - return *this; -} - bool TypeImpl::CheckModule(lldb::ModuleSP &module_sp) const { // Check if we have a module for this type. If we do and the shared pointer // is can be successfully initialized with m_module_wp, return true. Else @@ -892,7 +858,7 @@ ConstString TypeImpl::GetName() const { if (CheckModule(module_sp)) { if (m_dynamic_type) return m_dynamic_type.GetTypeName(); - return m_static_type.GetName(); + return m_static_type.GetTypeName(); } return ConstString(); } @@ -935,10 +901,10 @@ TypeImpl TypeImpl::GetReferenceType() const { ModuleSP module_sp; if (CheckModule(module_sp)) { if (m_dynamic_type.IsValid()) { - return TypeImpl(m_static_type.GetReferenceType(), + return TypeImpl(m_static_type.GetLValueReferenceType(), m_dynamic_type.GetLValueReferenceType()); } - return TypeImpl(m_static_type.GetReferenceType()); + return TypeImpl(m_static_type.GetLValueReferenceType()); } return TypeImpl(); } @@ -959,10 +925,10 @@ TypeImpl TypeImpl::GetDereferencedType() const { ModuleSP module_sp; if (CheckModule(module_sp)) { if (m_dynamic_type.IsValid()) { - return TypeImpl(m_static_type.GetDereferencedType(), + return TypeImpl(m_static_type.GetNonReferenceType(), m_dynamic_type.GetNonReferenceType()); } - return TypeImpl(m_static_type.GetDereferencedType()); + return TypeImpl(m_static_type.GetNonReferenceType()); } return TypeImpl(); } @@ -971,10 +937,10 @@ TypeImpl TypeImpl::GetUnqualifiedType() const { ModuleSP module_sp; if (CheckModule(module_sp)) { if (m_dynamic_type.IsValid()) { - return TypeImpl(m_static_type.GetUnqualifiedType(), + return TypeImpl(m_static_type.GetFullyUnqualifiedType(), m_dynamic_type.GetFullyUnqualifiedType()); } - return TypeImpl(m_static_type.GetUnqualifiedType()); + return TypeImpl(m_static_type.GetFullyUnqualifiedType()); } return TypeImpl(); } @@ -998,7 +964,7 @@ CompilerType TypeImpl::GetCompilerType(bool prefer_dynamic) { if (m_dynamic_type.IsValid()) return m_dynamic_type; } - return m_static_type.GetCompilerType(); + return m_static_type; } return CompilerType(); } @@ -1010,9 +976,9 @@ TypeSystem *TypeImpl::GetTypeSystem(bool prefer_dynamic) { if (m_dynamic_type.IsValid()) return m_dynamic_type.GetTypeSystem(); } - return m_static_type.GetCompilerType().GetTypeSystem(); + return m_static_type.GetTypeSystem(); } - return NULL; + return nullptr; } bool TypeImpl::GetDescription(lldb_private::Stream &strm, @@ -1024,7 +990,7 @@ bool TypeImpl::GetDescription(lldb_private::Stream &strm, m_dynamic_type.DumpTypeDescription(&strm); strm.Printf("\nStatic:\n"); } - m_static_type.GetCompilerType().DumpTypeDescription(&strm); + m_static_type.DumpTypeDescription(&strm); } else { strm.PutCString("Invalid TypeImpl module for type has been deleted\n"); } @@ -1092,7 +1058,7 @@ CompilerType TypeMemberFunctionImpl::GetArgumentAtIndex(size_t idx) const { } TypeEnumMemberImpl::TypeEnumMemberImpl(const lldb::TypeImplSP &integer_type_sp, - const ConstString &name, + ConstString name, const llvm::APSInt &value) : m_integer_type_sp(integer_type_sp), m_name(name), m_value(value), m_valid((bool)name && (bool)integer_type_sp) diff --git a/source/Symbol/TypeList.cpp b/source/Symbol/TypeList.cpp index 26a646e64693c..1813e8ecca9a9 100644 --- a/source/Symbol/TypeList.cpp +++ b/source/Symbol/TypeList.cpp @@ -1,9 +1,8 @@ //===-- TypeList.cpp --------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -22,9 +21,7 @@ using namespace lldb_private; TypeList::TypeList() : m_types() {} -//---------------------------------------------------------------------- // Destructor -//---------------------------------------------------------------------- TypeList::~TypeList() {} void TypeList::Insert(const TypeSP &type_sp) { @@ -34,9 +31,7 @@ void TypeList::Insert(const TypeSP &type_sp) { m_types.push_back(type_sp); } -//---------------------------------------------------------------------- // Find a base type by its unique ID. -//---------------------------------------------------------------------- // TypeSP // TypeList::FindType(lldb::user_id_t uid) //{ @@ -46,11 +41,9 @@ void TypeList::Insert(const TypeSP &type_sp) { // return TypeSP(); //} -//---------------------------------------------------------------------- // Find a type by name. -//---------------------------------------------------------------------- // TypeList -// TypeList::FindTypes (const ConstString &name) +// TypeList::FindTypes (ConstString name) //{ // // Do we ever need to make a lookup by name map? Here we are doing // // a linear search which isn't going to be fast. diff --git a/source/Symbol/TypeMap.cpp b/source/Symbol/TypeMap.cpp index 337278c202ed2..bc6e272449f0c 100644 --- a/source/Symbol/TypeMap.cpp +++ b/source/Symbol/TypeMap.cpp @@ -1,9 +1,8 @@ //===-- TypeMap.cpp --------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -35,9 +34,7 @@ using namespace clang; TypeMap::TypeMap() : m_types() {} -//---------------------------------------------------------------------- // Destructor -//---------------------------------------------------------------------- TypeMap::~TypeMap() {} void TypeMap::Insert(const TypeSP &type_sp) { @@ -62,9 +59,7 @@ bool TypeMap::InsertUnique(const TypeSP &type_sp) { return true; } -//---------------------------------------------------------------------- // Find a base type by its unique ID. -//---------------------------------------------------------------------- // TypeSP // TypeMap::FindType(lldb::user_id_t uid) //{ @@ -74,11 +69,9 @@ bool TypeMap::InsertUnique(const TypeSP &type_sp) { // return TypeSP(); //} -//---------------------------------------------------------------------- // Find a type by name. -//---------------------------------------------------------------------- // TypeMap -// TypeMap::FindTypes (const ConstString &name) +// TypeMap::FindTypes (ConstString name) //{ // // Do we ever need to make a lookup by name map? Here we are doing // // a linear search which isn't going to be fast. diff --git a/source/Symbol/TypeSystem.cpp b/source/Symbol/TypeSystem.cpp index 91d347edfc798..fb9c8e71acb35 100644 --- a/source/Symbol/TypeSystem.cpp +++ b/source/Symbol/TypeSystem.cpp @@ -1,9 +1,8 @@ //===-- TypeSystem.cpp ------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -93,7 +92,7 @@ CompilerType TypeSystem::CreateTypedef(lldb::opaque_compiler_type_t type, return CompilerType(); } -CompilerType TypeSystem::GetBuiltinTypeByName(const ConstString &name) { +CompilerType TypeSystem::GetBuiltinTypeByName(ConstString name) { return CompilerType(); } diff --git a/source/Symbol/UnwindPlan.cpp b/source/Symbol/UnwindPlan.cpp index 0f8d9bf7e5a44..774f9cb587eeb 100644 --- a/source/Symbol/UnwindPlan.cpp +++ b/source/Symbol/UnwindPlan.cpp @@ -1,16 +1,17 @@ //===-- UnwindPlan.cpp ----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// #include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Expression/DWARFExpression.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" @@ -65,6 +66,30 @@ void UnwindPlan::Row::RegisterLocation::SetIsDWARFExpression( m_location.expr.length = len; } +static llvm::Optional<std::pair<lldb::ByteOrder, uint32_t>> +GetByteOrderAndAddrSize(Thread *thread) { + if (!thread) + return llvm::None; + ProcessSP process_sp = thread->GetProcess(); + if (!process_sp) + return llvm::None; + ArchSpec arch = process_sp->GetTarget().GetArchitecture(); + return std::make_pair(arch.GetByteOrder(), arch.GetAddressByteSize()); +} + +static void DumpDWARFExpr(Stream &s, llvm::ArrayRef<uint8_t> expr, Thread *thread) { + if (auto order_and_width = GetByteOrderAndAddrSize(thread)) { + DataExtractor extractor(expr.data(), expr.size(), order_and_width->first, + order_and_width->second); + if (!DWARFExpression::PrintDWARFExpression(s, extractor, + order_and_width->second, + /*dwarf_ref_size*/ 4, + /*location_expression*/ false)) + s.PutCString("invalid-dwarf-expr"); + } else + s.PutCString("dwarf-expr"); +} + void UnwindPlan::Row::RegisterLocation::Dump(Stream &s, const UnwindPlan *unwind_plan, const UnwindPlan::Row *row, @@ -121,9 +146,12 @@ void UnwindPlan::Row::RegisterLocation::Dump(Stream &s, case isDWARFExpression: { s.PutChar('='); if (m_type == atDWARFExpression) - s.PutCString("[dwarf-expr]"); - else - s.PutCString("dwarf-expr"); + s.PutChar('['); + DumpDWARFExpr( + s, llvm::makeArrayRef(m_location.expr.opcodes, m_location.expr.length), + thread); + if (m_type == atDWARFExpression) + s.PutChar(']'); } break; } } @@ -173,7 +201,9 @@ void UnwindPlan::Row::FAValue::Dump(Stream &s, const UnwindPlan *unwind_plan, s.PutChar(']'); break; case isDWARFExpression: - s.PutCString("dwarf-expr"); + DumpDWARFExpr(s, + llvm::makeArrayRef(m_value.expr.opcodes, m_value.expr.length), + thread); break; default: s.PutCString("unspecified"); diff --git a/source/Symbol/UnwindTable.cpp b/source/Symbol/UnwindTable.cpp index 4f0b875c5c6fb..a8f451dc46430 100644 --- a/source/Symbol/UnwindTable.cpp +++ b/source/Symbol/UnwindTable.cpp @@ -1,9 +1,8 @@ //===-- UnwindTable.cpp -----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -19,6 +18,7 @@ #include "lldb/Symbol/FuncUnwinders.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/SymbolVendor.h" // There is one UnwindTable object per ObjectFile. It contains a list of Unwind // objects -- one per function, populated lazily -- for the ObjectFile. Each @@ -27,8 +27,8 @@ using namespace lldb; using namespace lldb_private; -UnwindTable::UnwindTable(ObjectFile &objfile) - : m_object_file(objfile), m_unwinds(), m_initialized(false), m_mutex(), +UnwindTable::UnwindTable(Module &module) + : m_module(module), m_unwinds(), m_initialized(false), m_mutex(), m_eh_frame_up(), m_compact_unwind_up(), m_arm_unwind_up() {} // We can't do some of this initialization when the ObjectFile is running its @@ -43,33 +43,36 @@ void UnwindTable::Initialize() { if (m_initialized) // check again once we've acquired the lock return; m_initialized = true; + ObjectFile *object_file = m_module.GetObjectFile(); + if (!object_file) + return; - SectionList *sl = m_object_file.GetSectionList(); + SectionList *sl = m_module.GetSectionList(); if (!sl) return; SectionSP sect = sl->FindSectionByType(eSectionTypeEHFrame, true); if (sect.get()) { m_eh_frame_up.reset( - new DWARFCallFrameInfo(m_object_file, sect, DWARFCallFrameInfo::EH)); + new DWARFCallFrameInfo(*object_file, sect, DWARFCallFrameInfo::EH)); } sect = sl->FindSectionByType(eSectionTypeDWARFDebugFrame, true); if (sect) { m_debug_frame_up.reset( - new DWARFCallFrameInfo(m_object_file, sect, DWARFCallFrameInfo::DWARF)); + new DWARFCallFrameInfo(*object_file, sect, DWARFCallFrameInfo::DWARF)); } sect = sl->FindSectionByType(eSectionTypeCompactUnwind, true); if (sect) { - m_compact_unwind_up.reset(new CompactUnwindInfo(m_object_file, sect)); + m_compact_unwind_up.reset(new CompactUnwindInfo(*object_file, sect)); } sect = sl->FindSectionByType(eSectionTypeARMexidx, true); if (sect) { SectionSP sect_extab = sl->FindSectionByType(eSectionTypeARMextab, true); if (sect_extab.get()) { - m_arm_unwind_up.reset(new ArmUnwindInfo(m_object_file, sect, sect_extab)); + m_arm_unwind_up.reset(new ArmUnwindInfo(*object_file, sect, sect_extab)); } } } @@ -149,8 +152,7 @@ UnwindTable::GetUncachedFuncUnwindersContainingAddress(const Address &addr, void UnwindTable::Dump(Stream &s) { std::lock_guard<std::mutex> guard(m_mutex); - s.Printf("UnwindTable for '%s':\n", - m_object_file.GetFileSpec().GetPath().c_str()); + s.Format("UnwindTable for '{0}':\n", m_module.GetFileSpec()); const_iterator begin = m_unwinds.begin(); const_iterator end = m_unwinds.end(); for (const_iterator pos = begin; pos != end; ++pos) { @@ -180,10 +182,16 @@ ArmUnwindInfo *UnwindTable::GetArmUnwindInfo() { return m_arm_unwind_up.get(); } -ArchSpec UnwindTable::GetArchitecture() { - return m_object_file.GetArchitecture(); +SymbolFile *UnwindTable::GetSymbolFile() { + if (SymbolVendor *vendor = m_module.GetSymbolVendor()) + return vendor->GetSymbolFile(); + return nullptr; } +ArchSpec UnwindTable::GetArchitecture() { return m_module.GetArchitecture(); } + bool UnwindTable::GetAllowAssemblyEmulationUnwindPlans() { - return m_object_file.AllowAssemblyEmulationUnwindPlans(); + if (ObjectFile *object_file = m_module.GetObjectFile()) + return object_file->AllowAssemblyEmulationUnwindPlans(); + return false; } diff --git a/source/Symbol/Variable.cpp b/source/Symbol/Variable.cpp index ffed48a33bf11..29a7a5191f610 100644 --- a/source/Symbol/Variable.cpp +++ b/source/Symbol/Variable.cpp @@ -1,9 +1,8 @@ //===-- Variable.cpp --------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -36,9 +35,7 @@ using namespace lldb; using namespace lldb_private; -//---------------------------------------------------------------------- // Variable constructor -//---------------------------------------------------------------------- Variable::Variable( lldb::user_id_t uid, const char *name, const char *mangled, // The mangled or fully qualified name of the variable. @@ -53,9 +50,7 @@ Variable::Variable( m_artificial(artificial), m_loc_is_const_data(false), m_static_member(static_member) {} -//---------------------------------------------------------------------- // Destructor -//---------------------------------------------------------------------- Variable::~Variable() {} lldb::LanguageType Variable::GetLanguage() const { @@ -75,7 +70,7 @@ ConstString Variable::GetName() const { ConstString Variable::GetUnqualifiedName() const { return m_name; } -bool Variable::NameMatches(const ConstString &name) const { +bool Variable::NameMatches(ConstString name) const { if (m_name == name) return true; SymbolContext variable_sc; diff --git a/source/Symbol/VariableList.cpp b/source/Symbol/VariableList.cpp index e7a482e158b19..51312472e2652 100644 --- a/source/Symbol/VariableList.cpp +++ b/source/Symbol/VariableList.cpp @@ -1,9 +1,8 @@ //===-- VariableList.cpp ----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -17,14 +16,10 @@ using namespace lldb; using namespace lldb_private; -//---------------------------------------------------------------------- // VariableList constructor -//---------------------------------------------------------------------- VariableList::VariableList() : m_variables() {} -//---------------------------------------------------------------------- // Destructor -//---------------------------------------------------------------------- VariableList::~VariableList() {} void VariableList::AddVariable(const VariableSP &var_sp) { @@ -74,7 +69,7 @@ uint32_t VariableList::FindVariableIndex(const VariableSP &var_sp) { return UINT32_MAX; } -VariableSP VariableList::FindVariable(const ConstString &name, +VariableSP VariableList::FindVariable(ConstString name, bool include_static_members) { VariableSP var_sp; iterator pos, end = m_variables.end(); @@ -89,7 +84,7 @@ VariableSP VariableList::FindVariable(const ConstString &name, return var_sp; } -VariableSP VariableList::FindVariable(const ConstString &name, +VariableSP VariableList::FindVariable(ConstString name, lldb::ValueType value_type, bool include_static_members) { VariableSP var_sp; diff --git a/source/Symbol/VerifyDecl.cpp b/source/Symbol/VerifyDecl.cpp index 96ed47a527a88..1873d3a5d03c9 100644 --- a/source/Symbol/VerifyDecl.cpp +++ b/source/Symbol/VerifyDecl.cpp @@ -1,13 +1,15 @@ //===-- VerifyDecl.cpp ------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// #include "lldb/Symbol/VerifyDecl.h" #include "clang/AST/DeclBase.h" -void lldb_private::VerifyDecl(clang::Decl *decl) { decl->getAccess(); } +void lldb_private::VerifyDecl(clang::Decl *decl) { + assert(decl && "VerifyDecl called with nullptr?"); + decl->getAccess(); +} |