aboutsummaryrefslogtreecommitdiffstats
path: root/source/Symbol
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 20:51:52 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 20:51:52 +0000
commit5f29bb8a675e8f96452b632e7129113f7dec850e (patch)
tree3d3f2a0d3ad10872a4dcaba8ec8d1d20c87ab147 /source/Symbol
parent88c643b6fec27eec436c8d138fee6346e92337d6 (diff)
downloadsrc-5f29bb8a675e8f96452b632e7129113f7dec850e.tar.gz
src-5f29bb8a675e8f96452b632e7129113f7dec850e.zip
Vendor import of stripped lldb trunk r366426 (just before the release_90
Notes
Notes: svn path=/vendor/lldb/dist/; revision=351290
Diffstat (limited to 'source/Symbol')
-rw-r--r--source/Symbol/ArmUnwindInfo.cpp9
-rw-r--r--source/Symbol/Block.cpp28
-rw-r--r--source/Symbol/ClangASTContext.cpp391
-rw-r--r--source/Symbol/ClangASTImporter.cpp250
-rw-r--r--source/Symbol/ClangExternalASTSourceCallbacks.cpp7
-rw-r--r--source/Symbol/ClangExternalASTSourceCommon.cpp7
-rw-r--r--source/Symbol/ClangUtil.cpp7
-rw-r--r--source/Symbol/CompactUnwindInfo.cpp21
-rw-r--r--source/Symbol/CompileUnit.cpp29
-rw-r--r--source/Symbol/CompilerDecl.cpp7
-rw-r--r--source/Symbol/CompilerDeclContext.cpp20
-rw-r--r--source/Symbol/CompilerType.cpp40
-rw-r--r--source/Symbol/CxxModuleHandler.cpp283
-rw-r--r--source/Symbol/DWARFCallFrameInfo.cpp107
-rw-r--r--source/Symbol/DebugMacros.cpp7
-rw-r--r--source/Symbol/DeclVendor.cpp29
-rw-r--r--source/Symbol/Declaration.cpp12
-rw-r--r--source/Symbol/FuncUnwinders.cpp164
-rw-r--r--source/Symbol/Function.cpp29
-rw-r--r--source/Symbol/LineEntry.cpp73
-rw-r--r--source/Symbol/LineTable.cpp24
-rw-r--r--source/Symbol/LocateSymbolFile.cpp390
-rw-r--r--source/Symbol/LocateSymbolFileMacOSX.cpp657
-rw-r--r--source/Symbol/ObjectFile.cpp52
-rw-r--r--source/Symbol/PostfixExpression.cpp227
-rw-r--r--source/Symbol/Symbol.cpp26
-rw-r--r--source/Symbol/SymbolContext.cpp56
-rw-r--r--source/Symbol/SymbolFile.cpp31
-rw-r--r--source/Symbol/SymbolVendor.cpp174
-rw-r--r--source/Symbol/Symtab.cpp127
-rw-r--r--source/Symbol/Type.cpp214
-rw-r--r--source/Symbol/TypeList.cpp15
-rw-r--r--source/Symbol/TypeMap.cpp15
-rw-r--r--source/Symbol/TypeSystem.cpp9
-rw-r--r--source/Symbol/UnwindPlan.cpp46
-rw-r--r--source/Symbol/UnwindTable.cpp40
-rw-r--r--source/Symbol/Variable.cpp13
-rw-r--r--source/Symbol/VariableList.cpp15
-rw-r--r--source/Symbol/VerifyDecl.cpp12
39 files changed, 2647 insertions, 1016 deletions
diff --git a/source/Symbol/ArmUnwindInfo.cpp b/source/Symbol/ArmUnwindInfo.cpp
index 08f28073be21..b9fd84b1e706 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 d0342355911c..6fe617080f96 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 85436b630b7d..205523355ce0 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 621441449c20..32d0c47693b0 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 a96ef19b02f5..c35fc585bfa5 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 992a76352d92..3dcf9051d0a4 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 687fba7c7c33..86be895fadcb 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 6f0f35f278c4..3a2a4d3a09e6 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 &section_sp)
: m_objfile(objfile), m_section_sp(section_sp),
@@ -166,9 +165,7 @@ CompactUnwindInfo::CompactUnwindInfo(ObjectFile &objfile, SectionSP &section_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 74512c891440..5fb9b6b9f729 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 2b632c5eb5d0..2c64113a2bbe 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 43a83bbca77b..a6f046c4eb22 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 7e381abd7d11..bb9a1a642e42 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 000000000000..68a2aab80bd6
--- /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 c8c3a10026a2..0ab9fa4b7bbd 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 &section_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 22576ee1ce26..d119a78868a4 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 000000000000..0a912a2fd214
--- /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 83df578da2e3..d78ba967d280 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 35ce72f32b61..09cb9b00aaf3 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 f792a5c5213e..951392c1f1bf 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 bffcc5321b11..959a3274ec92 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 06e30219f09a..8d4d72c9a2a2 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 000000000000..bfdb6e705f4a
--- /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 000000000000..4e16382d53e7
--- /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 86c18c7beb0b..172d2b3f01e3 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 &section_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 000000000000..148653561a4e
--- /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 &reg, 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 &reg, 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 8d055c1c6712..589f69244a48 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 da00875bfa15..a0b35cf3d0b9 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 6087374969fb..77ab2223ec07 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 &regex,
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 a9badc15a5d6..b9f3a5fe3926 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 &regex,
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 &regex,
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 2472580a41d5..29c390e83878 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 e966c269408a..4ee8330ce288 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 26a646e64693..1813e8ecca9a 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 337278c202ed..bc6e272449f0 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 91d347edfc79..fb9c8e71acb3 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 0f8d9bf7e5a4..774f9cb587ee 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 4f0b875c5c6f..a8f451dc4643 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 ffed48a33bf1..29a7a5191f61 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 e7a482e158b1..51312472e265 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 96ed47a527a8..1873d3a5d03c 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();
+}