diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/API/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/API/SBProcess.cpp | 22 | ||||
-rw-r--r-- | source/API/SBStructuredData.cpp | 81 | ||||
-rw-r--r-- | source/API/SBTrace.cpp | 109 | ||||
-rw-r--r-- | source/API/SBTraceOptions.cpp | 94 | ||||
-rw-r--r-- | source/Core/ValueObject.cpp | 34 | ||||
-rw-r--r-- | source/Host/common/SocketAddress.cpp | 32 | ||||
-rw-r--r-- | source/Host/freebsd/Host.cpp | 164 | ||||
-rw-r--r-- | source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp | 505 | ||||
-rw-r--r-- | source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp | 2 | ||||
-rw-r--r-- | source/Plugins/Language/CPlusPlus/LibCxx.cpp | 3 | ||||
-rw-r--r-- | source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp | 65 | ||||
-rw-r--r-- | source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h | 2 | ||||
-rw-r--r-- | source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 8 |
14 files changed, 671 insertions, 452 deletions
diff --git a/source/API/CMakeLists.txt b/source/API/CMakeLists.txt index 3b852a3d7402..9dd21bcf2aaf 100644 --- a/source/API/CMakeLists.txt +++ b/source/API/CMakeLists.txt @@ -67,6 +67,8 @@ add_lldb_library(liblldb SHARED SBThread.cpp SBThreadCollection.cpp SBThreadPlan.cpp + SBTrace.cpp + SBTraceOptions.cpp SBType.cpp SBTypeCategory.cpp SBTypeEnumMember.cpp diff --git a/source/API/SBProcess.cpp b/source/API/SBProcess.cpp index 4cb367a03ad6..5614cb468a69 100644 --- a/source/API/SBProcess.cpp +++ b/source/API/SBProcess.cpp @@ -44,6 +44,8 @@ #include "lldb/API/SBStructuredData.h" #include "lldb/API/SBThread.h" #include "lldb/API/SBThreadCollection.h" +#include "lldb/API/SBTrace.h" +#include "lldb/API/SBTraceOptions.h" #include "lldb/API/SBUnixSignals.h" using namespace lldb; @@ -349,6 +351,26 @@ size_t SBProcess::GetAsyncProfileData(char *dst, size_t dst_len) const { return bytes_read; } +lldb::SBTrace SBProcess::StartTrace(SBTraceOptions &options, + lldb::SBError &error) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + ProcessSP process_sp(GetSP()); + error.Clear(); + SBTrace trace_instance; + trace_instance.SetSP(process_sp); + lldb::user_id_t uid = LLDB_INVALID_UID; + + if (!process_sp) { + error.SetErrorString("invalid process"); + } else { + + uid = process_sp->StartTrace(options.m_traceoptions_sp, error.ref()); + trace_instance.SetTraceUID(uid); + LLDB_LOG(log, "SBProcess::returned uid - %" PRIx64, uid); + } + return trace_instance; +} + void SBProcess::ReportEventState(const SBEvent &event, FILE *out) const { if (out == NULL) return; diff --git a/source/API/SBStructuredData.cpp b/source/API/SBStructuredData.cpp index 6d4c862306f9..2fca56f2f223 100644 --- a/source/API/SBStructuredData.cpp +++ b/source/API/SBStructuredData.cpp @@ -12,6 +12,7 @@ #include "lldb/API/SBStream.h" #include "lldb/Core/Event.h" #include "lldb/Core/StructuredData.h" +#include "lldb/Core/StructuredDataImpl.h" #include "lldb/Target/StructuredDataPlugin.h" #include "lldb/Utility/Error.h" #include "lldb/Utility/Stream.h" @@ -20,70 +21,6 @@ using namespace lldb; using namespace lldb_private; #pragma mark-- -#pragma mark StructuredDataImpl - -class StructuredDataImpl { -public: - StructuredDataImpl() : m_plugin_wp(), m_data_sp() {} - - StructuredDataImpl(const StructuredDataImpl &rhs) = default; - - StructuredDataImpl(const EventSP &event_sp) - : m_plugin_wp( - EventDataStructuredData::GetPluginFromEvent(event_sp.get())), - m_data_sp(EventDataStructuredData::GetObjectFromEvent(event_sp.get())) { - } - - ~StructuredDataImpl() = default; - - StructuredDataImpl &operator=(const StructuredDataImpl &rhs) = default; - - bool IsValid() const { return m_data_sp.get() != nullptr; } - - void Clear() { - m_plugin_wp.reset(); - m_data_sp.reset(); - } - - SBError GetAsJSON(lldb_private::Stream &stream) const { - SBError sb_error; - - if (!m_data_sp) { - sb_error.SetErrorString("No structured data."); - return sb_error; - } - - m_data_sp->Dump(stream); - return sb_error; - } - - Error GetDescription(lldb_private::Stream &stream) const { - Error error; - - if (!m_data_sp) { - error.SetErrorString("Cannot pretty print structured data: " - "no data to print."); - return error; - } - - // Grab the plugin. - auto plugin_sp = StructuredDataPluginSP(m_plugin_wp); - if (!plugin_sp) { - error.SetErrorString("Cannot pretty print structured data: " - "plugin doesn't exist."); - return error; - } - - // Get the data's description. - return plugin_sp->GetDescription(m_data_sp, stream); - } - -private: - StructuredDataPluginWP m_plugin_wp; - StructuredData::ObjectSP m_data_sp; -}; - -#pragma mark-- #pragma mark SBStructuredData SBStructuredData::SBStructuredData() : m_impl_up(new StructuredDataImpl()) {} @@ -102,12 +39,26 @@ operator=(const lldb::SBStructuredData &rhs) { return *this; } +lldb::SBError SBStructuredData::SetFromJSON(lldb::SBStream &stream) { + lldb::SBError error; + std::string json_str(stream.GetData()); + + StructuredData::ObjectSP json_obj = StructuredData::ParseJSON(json_str); + m_impl_up->SetObjectSP(json_obj); + + if (!json_obj || json_obj->GetType() != StructuredData::Type::eTypeDictionary) + error.SetErrorString("Invalid Syntax"); + return error; +} + bool SBStructuredData::IsValid() const { return m_impl_up->IsValid(); } void SBStructuredData::Clear() { m_impl_up->Clear(); } SBError SBStructuredData::GetAsJSON(lldb::SBStream &stream) const { - return m_impl_up->GetAsJSON(stream.ref()); + SBError error; + error.SetError(m_impl_up->GetAsJSON(stream.ref())); + return error; } lldb::SBError SBStructuredData::GetDescription(lldb::SBStream &stream) const { diff --git a/source/API/SBTrace.cpp b/source/API/SBTrace.cpp new file mode 100644 index 000000000000..18f7d36e7759 --- /dev/null +++ b/source/API/SBTrace.cpp @@ -0,0 +1,109 @@ +//===-- SBTrace.cpp ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/Log.h" +#include "lldb/Target/Process.h" + +#include "lldb/API/SBTrace.h" +#include "lldb/API/SBTraceOptions.h" + +using namespace lldb; +using namespace lldb_private; + +class TraceImpl { +public: + lldb::user_id_t uid; +}; + +lldb::ProcessSP SBTrace::GetSP() const { return m_opaque_wp.lock(); } + +size_t SBTrace::GetTraceData(SBError &error, void *buf, size_t size, + size_t offset, lldb::tid_t thread_id) { + size_t bytes_read = 0; + ProcessSP process_sp(GetSP()); + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + error.Clear(); + + if (!process_sp) { + error.SetErrorString("invalid process"); + } else { + bytes_read = process_sp->GetData(GetTraceUID(), thread_id, error.ref(), buf, + size, offset); + LLDB_LOG(log, "SBTrace::bytes_read - %" PRIx64, bytes_read); + } + return bytes_read; +} + +size_t SBTrace::GetMetaData(SBError &error, void *buf, size_t size, + size_t offset, lldb::tid_t thread_id) { + size_t bytes_read = 0; + ProcessSP process_sp(GetSP()); + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + error.Clear(); + + if (!process_sp) { + error.SetErrorString("invalid process"); + } else { + + bytes_read = process_sp->GetMetaData(GetTraceUID(), thread_id, error.ref(), + buf, size, offset); + LLDB_LOG(log, "SBTrace::bytes_read - %" PRIx64, bytes_read); + } + return bytes_read; +} + +void SBTrace::StopTrace(SBError &error, lldb::tid_t thread_id) { + ProcessSP process_sp(GetSP()); + error.Clear(); + + if (!process_sp) { + error.SetErrorString("invalid process"); + return; + } + process_sp->StopTrace(GetTraceUID(), thread_id, error.ref()); +} + +void SBTrace::GetTraceConfig(SBTraceOptions &options, SBError &error) { + ProcessSP process_sp(GetSP()); + error.Clear(); + + if (!process_sp) { + error.SetErrorString("invalid process"); + } else { + process_sp->GetTraceConfig(GetTraceUID(), error.ref(), + options.m_traceoptions_sp); + } +} + +lldb::user_id_t SBTrace::GetTraceUID() { + if (m_trace_impl_sp) + return m_trace_impl_sp->uid; + return LLDB_INVALID_UID; +} + +void SBTrace::SetTraceUID(lldb::user_id_t uid) { + if (m_trace_impl_sp) + m_trace_impl_sp->uid = uid; +} + +SBTrace::SBTrace() { + m_trace_impl_sp.reset(new TraceImpl); + if (m_trace_impl_sp) + m_trace_impl_sp->uid = LLDB_INVALID_UID; +} + +void SBTrace::SetSP(const ProcessSP &process_sp) { m_opaque_wp = process_sp; } + +bool SBTrace::IsValid() { + if (!m_trace_impl_sp) + return false; + if (!GetSP()) + return false; + return true; +} diff --git a/source/API/SBTraceOptions.cpp b/source/API/SBTraceOptions.cpp new file mode 100644 index 000000000000..474fa911f7ec --- /dev/null +++ b/source/API/SBTraceOptions.cpp @@ -0,0 +1,94 @@ +//===-- SBTraceOptions.cpp --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/API/SBTraceOptions.h" +#include "lldb/API/SBError.h" +#include "lldb/API/SBStructuredData.h" +#include "lldb/Utility/Log.h" +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Core/TraceOptions.h" + +using namespace lldb; +using namespace lldb_private; + +SBTraceOptions::SBTraceOptions() { + m_traceoptions_sp.reset(new TraceOptions()); +} + +lldb::TraceType SBTraceOptions::getType() const { + if (m_traceoptions_sp) + return m_traceoptions_sp->getType(); + return lldb::TraceType::eTraceTypeNone; +} + +uint64_t SBTraceOptions::getTraceBufferSize() const { + if (m_traceoptions_sp) + return m_traceoptions_sp->getTraceBufferSize(); + return 0; +} + +lldb::SBStructuredData SBTraceOptions::getTraceParams(lldb::SBError &error) { + error.Clear(); + const lldb_private::StructuredData::DictionarySP dict_obj = + m_traceoptions_sp->getTraceParams(); + lldb::SBStructuredData structData; + if (dict_obj && structData.m_impl_up) + structData.m_impl_up->SetObjectSP(dict_obj->shared_from_this()); + else + error.SetErrorString("Empty trace params"); + return structData; +} + +uint64_t SBTraceOptions::getMetaDataBufferSize() const { + if (m_traceoptions_sp) + return m_traceoptions_sp->getTraceBufferSize(); + return 0; +} + +void SBTraceOptions::setTraceParams(lldb::SBStructuredData ¶ms) { + if (m_traceoptions_sp && params.m_impl_up) { + StructuredData::ObjectSP obj_sp = params.m_impl_up->GetObjectSP(); + if (obj_sp && obj_sp->GetAsDictionary() != nullptr) + m_traceoptions_sp->setTraceParams( + std::static_pointer_cast<StructuredData::Dictionary>(obj_sp)); + } + return; +} + +void SBTraceOptions::setType(lldb::TraceType type) { + if (m_traceoptions_sp) + m_traceoptions_sp->setType(type); +} + +void SBTraceOptions::setTraceBufferSize(uint64_t size) { + if (m_traceoptions_sp) + m_traceoptions_sp->setTraceBufferSize(size); +} + +void SBTraceOptions::setMetaDataBufferSize(uint64_t size) { + if (m_traceoptions_sp) + m_traceoptions_sp->setMetaDataBufferSize(size); +} + +bool SBTraceOptions::IsValid() { + if (m_traceoptions_sp) + return true; + return false; +} + +void SBTraceOptions::setThreadID(lldb::tid_t thread_id) { + if (m_traceoptions_sp) + m_traceoptions_sp->setThreadID(thread_id); +} + +lldb::tid_t SBTraceOptions::getThreadID() { + if (m_traceoptions_sp) + return m_traceoptions_sp->getThreadID(); + return LLDB_INVALID_THREAD_ID; +} diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp index 381763dab8e1..9e6b9da78b99 100644 --- a/source/Core/ValueObject.cpp +++ b/source/Core/ValueObject.cpp @@ -481,21 +481,8 @@ ValueObjectSP ValueObject::GetChildAtIndex(size_t idx, bool can_create) { return child_sp; } -ValueObjectSP -ValueObject::GetChildAtIndexPath(const std::initializer_list<size_t> &idxs, - size_t *index_of_error) { - return GetChildAtIndexPath(std::vector<size_t>(idxs), index_of_error); -} - -ValueObjectSP ValueObject::GetChildAtIndexPath( - const std::initializer_list<std::pair<size_t, bool>> &idxs, - size_t *index_of_error) { - return GetChildAtIndexPath(std::vector<std::pair<size_t, bool>>(idxs), - index_of_error); -} - lldb::ValueObjectSP -ValueObject::GetChildAtIndexPath(const std::vector<size_t> &idxs, +ValueObject::GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs, size_t *index_of_error) { if (idxs.size() == 0) return GetSP(); @@ -512,7 +499,7 @@ ValueObject::GetChildAtIndexPath(const std::vector<size_t> &idxs, } lldb::ValueObjectSP ValueObject::GetChildAtIndexPath( - const std::vector<std::pair<size_t, bool>> &idxs, size_t *index_of_error) { + llvm::ArrayRef<std::pair<size_t, bool>> idxs, size_t *index_of_error) { if (idxs.size() == 0) return GetSP(); ValueObjectSP root(GetSP()); @@ -528,20 +515,7 @@ lldb::ValueObjectSP ValueObject::GetChildAtIndexPath( } lldb::ValueObjectSP -ValueObject::GetChildAtNamePath(const std::initializer_list<ConstString> &names, - ConstString *name_of_error) { - return GetChildAtNamePath(std::vector<ConstString>(names), name_of_error); -} - -lldb::ValueObjectSP ValueObject::GetChildAtNamePath( - const std::initializer_list<std::pair<ConstString, bool>> &names, - ConstString *name_of_error) { - return GetChildAtNamePath(std::vector<std::pair<ConstString, bool>>(names), - name_of_error); -} - -lldb::ValueObjectSP -ValueObject::GetChildAtNamePath(const std::vector<ConstString> &names, +ValueObject::GetChildAtNamePath(llvm::ArrayRef<ConstString> names, ConstString *name_of_error) { if (names.size() == 0) return GetSP(); @@ -558,7 +532,7 @@ ValueObject::GetChildAtNamePath(const std::vector<ConstString> &names, } lldb::ValueObjectSP ValueObject::GetChildAtNamePath( - const std::vector<std::pair<ConstString, bool>> &names, + llvm::ArrayRef<std::pair<ConstString, bool>> names, ConstString *name_of_error) { if (names.size() == 0) return GetSP(); diff --git a/source/Host/common/SocketAddress.cpp b/source/Host/common/SocketAddress.cpp index 48c3ec1c48ed..b41cef6ca2eb 100644 --- a/source/Host/common/SocketAddress.cpp +++ b/source/Host/common/SocketAddress.cpp @@ -227,6 +227,18 @@ bool SocketAddress::getaddrinfo(const char *host, const char *service, int ai_flags) { Clear(); + auto addresses = GetAddressInfo(host, service, ai_family, ai_socktype, ai_protocol, ai_flags); + if (!addresses.empty()) + *this = addresses[0]; + return IsValid(); +} + +std::vector<SocketAddress> +SocketAddress::GetAddressInfo(const char *hostname, const char *servname, + int ai_family, int ai_socktype, int ai_protocol, + int ai_flags) { + std::vector<SocketAddress> addr_list; + struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = ai_family; @@ -234,26 +246,8 @@ bool SocketAddress::getaddrinfo(const char *host, const char *service, hints.ai_protocol = ai_protocol; hints.ai_flags = ai_flags; - bool result = false; - struct addrinfo *service_info_list = NULL; - int err = ::getaddrinfo(host, service, &hints, &service_info_list); - if (err == 0 && service_info_list) { - *this = service_info_list; - result = IsValid(); - } - - if (service_info_list) - ::freeaddrinfo(service_info_list); - - return result; -} - -std::vector<SocketAddress> SocketAddress::GetAddressInfo(const char *hostname, - const char *servname) { - std::vector<SocketAddress> addr_list; - struct addrinfo *service_info_list = NULL; - int err = ::getaddrinfo(hostname, servname, NULL, &service_info_list); + int err = ::getaddrinfo(hostname, servname, &hints, &service_info_list); if (err == 0 && service_info_list) { for (struct addrinfo *service_ptr = service_info_list; service_ptr != NULL; service_ptr = service_ptr->ai_next) { diff --git a/source/Host/freebsd/Host.cpp b/source/Host/freebsd/Host.cpp index 9415b2bb3fd0..f1abb49055e5 100644 --- a/source/Host/freebsd/Host.cpp +++ b/source/Host/freebsd/Host.cpp @@ -55,49 +55,53 @@ using namespace lldb_private; static bool GetFreeBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr, ProcessInstanceInfo &process_info) { - if (process_info.ProcessIDIsValid()) { - int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ARGS, - (int)process_info.GetProcessID()}; - - char arg_data[8192]; - size_t arg_data_size = sizeof(arg_data); - if (::sysctl(mib, 4, arg_data, &arg_data_size, NULL, 0) == 0) { - DataExtractor data(arg_data, arg_data_size, endian::InlHostByteOrder(), - sizeof(void *)); - lldb::offset_t offset = 0; - const char *cstr; - - cstr = data.GetCStr(&offset); - if (cstr) { - process_info.GetExecutableFile().SetFile(cstr, false); - - if (!(match_info_ptr == NULL || - NameMatches( - process_info.GetExecutableFile().GetFilename().GetCString(), - match_info_ptr->GetNameMatchType(), - match_info_ptr->GetProcessInfo().GetName()))) - return false; - - Args &proc_args = process_info.GetArguments(); - while (1) { - const uint8_t *p = data.PeekData(offset, 1); - while ((p != NULL) && (*p == '\0') && offset < arg_data_size) { - ++offset; - p = data.PeekData(offset, 1); - } - if (p == NULL || offset >= arg_data_size) - return true; - - cstr = data.GetCStr(&offset); - if (cstr) - proc_args.AppendArgument(llvm::StringRef(cstr)); - else - return true; - } - } + if (!process_info.ProcessIDIsValid()) + return false; + + int pid = process_info.GetProcessID(); + + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ARGS, pid}; + + char arg_data[8192]; + size_t arg_data_size = sizeof(arg_data); + if (::sysctl(mib, 4, arg_data, &arg_data_size, NULL, 0) != 0) + return false; + + DataExtractor data(arg_data, arg_data_size, endian::InlHostByteOrder(), + sizeof(void *)); + lldb::offset_t offset = 0; + const char *cstr; + + cstr = data.GetCStr(&offset); + if (!cstr) + return false; + + process_info.GetExecutableFile().SetFile(cstr, false); + + if (!(match_info_ptr == NULL || + NameMatches(process_info.GetExecutableFile().GetFilename().GetCString(), + match_info_ptr->GetNameMatchType(), + match_info_ptr->GetProcessInfo().GetName()))) + return false; + + Args &proc_args = process_info.GetArguments(); + while (1) { + const uint8_t *p = data.PeekData(offset, 1); + while ((p != NULL) && (*p == '\0') && offset < arg_data_size) { + ++offset; + p = data.PeekData(offset, 1); } + if (p == NULL || offset >= arg_data_size) + break; + + cstr = data.GetCStr(&offset); + if (!cstr) + break; + + proc_args.AppendArgument(llvm::StringRef(cstr)); } - return false; + + return true; } static bool GetFreeBSDProcessCPUType(ProcessInstanceInfo &process_info) { @@ -113,26 +117,31 @@ static bool GetFreeBSDProcessCPUType(ProcessInstanceInfo &process_info) { static bool GetFreeBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) { struct kinfo_proc proc_kinfo; size_t proc_kinfo_size; + const int pid = process_info.GetProcessID(); + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; - if (process_info.ProcessIDIsValid()) { - int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, - (int)process_info.GetProcessID()}; - proc_kinfo_size = sizeof(struct kinfo_proc); - - if (::sysctl(mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) { - if (proc_kinfo_size > 0) { - process_info.SetParentProcessID(proc_kinfo.ki_ppid); - process_info.SetUserID(proc_kinfo.ki_ruid); - process_info.SetGroupID(proc_kinfo.ki_rgid); - process_info.SetEffectiveUserID(proc_kinfo.ki_uid); - if (proc_kinfo.ki_ngroups > 0) - process_info.SetEffectiveGroupID(proc_kinfo.ki_groups[0]); - else - process_info.SetEffectiveGroupID(UINT32_MAX); - return true; - } - } - } + if (!process_info.ProcessIDIsValid()) + goto error; + + proc_kinfo_size = sizeof(struct kinfo_proc); + + if (::sysctl(mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) != 0) + goto error; + + if (proc_kinfo_size == 0) + goto error; + + process_info.SetParentProcessID(proc_kinfo.ki_ppid); + process_info.SetUserID(proc_kinfo.ki_ruid); + process_info.SetGroupID(proc_kinfo.ki_rgid); + process_info.SetEffectiveUserID(proc_kinfo.ki_uid); + if (proc_kinfo.ki_ngroups > 0) + process_info.SetEffectiveGroupID(proc_kinfo.ki_groups[0]); + else + process_info.SetEffectiveGroupID(UINT32_MAX); + return true; + +error: process_info.SetParentProcessID(LLDB_INVALID_PROCESS_ID); process_info.SetUserID(UINT32_MAX); process_info.SetGroupID(UINT32_MAX); @@ -143,7 +152,11 @@ static bool GetFreeBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) { uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) { + const ::pid_t our_pid = ::getpid(); + const ::uid_t our_uid = ::getuid(); std::vector<struct kinfo_proc> kinfos; + // Special case, if lldb is being run as root we can attach to anything. + bool all_users = match_info.GetMatchAllUsers() || (our_uid == 0); int mib[3] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; @@ -163,29 +176,24 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc)); - bool all_users = match_info.GetMatchAllUsers(); - const ::pid_t our_pid = getpid(); - const uid_t our_uid = getuid(); for (size_t i = 0; i < actual_pid_count; i++) { const struct kinfo_proc &kinfo = kinfos[i]; - const bool kinfo_user_matches = (all_users || (kinfo.ki_ruid == our_uid) || - // Special case, if lldb is being run as - // root we can attach to anything. - (our_uid == 0)); - - if (kinfo_user_matches == false || // Make sure the user is acceptable - kinfo.ki_pid == our_pid || // Skip this process - kinfo.ki_pid == 0 || // Skip kernel (kernel pid is zero) - kinfo.ki_stat == SZOMB || // Zombies are bad, they like brains... - kinfo.ki_flag & P_TRACED || // Being debugged? - kinfo.ki_flag & P_WEXIT) // Working on exiting + + /* Make sure the user is acceptable */ + if (!all_users && kinfo.ki_ruid != our_uid) + continue; + + if (kinfo.ki_pid == our_pid || // Skip this process + kinfo.ki_pid == 0 || // Skip kernel (kernel pid is 0) + kinfo.ki_stat == SZOMB || // Zombies are bad + kinfo.ki_flag & P_TRACED || // Being debugged? + kinfo.ki_flag & P_WEXIT) // Working on exiting continue; // Every thread is a process in FreeBSD, but all the threads of a single - // process - // have the same pid. Do not store the process info in the result list if a - // process - // with given identifier is already registered there. + // process have the same pid. Do not store the process info in the + // result list if a process with given identifier is already registered + // there. bool already_registered = false; for (uint32_t pi = 0; !already_registered && (const int)kinfo.ki_numthreads > 1 && diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index 70c77e9cde33..1f78fb96bc34 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -814,9 +814,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl, current_id); } - - if (!context.m_found.variable && !context.m_found.local_vars_nsp) - ClangASTSource::FindExternalVisibleDecls(context); + + ClangASTSource::FindExternalVisibleDecls(context); } void ClangExpressionDeclMap::FindExternalVisibleDecls( @@ -1217,7 +1216,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( } } - if (var) { + if (var && !variable_found) { variable_found = true; valobj = ValueObjectVariable::Create(frame, var); AddOneVariable(context, var, valobj, current_id); @@ -1248,303 +1247,297 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( } } - if (!context.m_found.variable) { - const bool include_inlines = false; - const bool append = false; + const bool include_inlines = false; + const bool append = false; - if (namespace_decl && module_sp) { - const bool include_symbols = false; + if (namespace_decl && module_sp) { + const bool include_symbols = false; - module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase, - include_symbols, include_inlines, append, - sc_list); - } else if (target && !namespace_decl) { - const bool include_symbols = true; + module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase, + include_symbols, include_inlines, append, + sc_list); + } else if (target && !namespace_decl) { + const bool include_symbols = true; - // TODO Fix FindFunctions so that it doesn't return - // instance methods for eFunctionNameTypeBase. + // TODO Fix FindFunctions so that it doesn't return + // instance methods for eFunctionNameTypeBase. - target->GetImages().FindFunctions(name, eFunctionNameTypeFull, - include_symbols, include_inlines, - append, sc_list); - } + target->GetImages().FindFunctions(name, eFunctionNameTypeFull, + include_symbols, include_inlines, + append, sc_list); + } - // If we found more than one function, see if we can use the - // frame's decl context to remove functions that are shadowed - // by other functions which match in type but are nearer in scope. - // - // AddOneFunction will not add a function whose type has already been - // added, so if there's another function in the list with a matching - // type, check to see if their decl context is a parent of the current - // frame's or was imported via a and using statement, and pick the - // best match according to lookup rules. - if (sc_list.GetSize() > 1) { - // Collect some info about our frame's context. - StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); - SymbolContext frame_sym_ctx; - if (frame != nullptr) - frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | - lldb::eSymbolContextBlock); - CompilerDeclContext frame_decl_context = - frame_sym_ctx.block != nullptr - ? frame_sym_ctx.block->GetDeclContext() - : CompilerDeclContext(); - - // We can't do this without a compiler decl context for our frame. - if (frame_decl_context) { - clang::DeclContext *frame_decl_ctx = - (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext(); - ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>( - frame_decl_context.GetTypeSystem()); - - // Structure to hold the info needed when comparing function - // declarations. - struct FuncDeclInfo { - ConstString m_name; - CompilerType m_copied_type; - uint32_t m_decl_lvl; - SymbolContext m_sym_ctx; - }; - - // First, symplify things by looping through the symbol contexts - // to remove unwanted functions and separate out the functions we - // want to compare and prune into a separate list. - // Cache the info needed about the function declarations in a - // vector for efficiency. - SymbolContextList sc_sym_list; - uint32_t num_indices = sc_list.GetSize(); - std::vector<FuncDeclInfo> fdi_cache; - fdi_cache.reserve(num_indices); - for (uint32_t index = 0; index < num_indices; ++index) { - FuncDeclInfo fdi; - SymbolContext sym_ctx; - sc_list.GetContextAtIndex(index, sym_ctx); - - // We don't know enough about symbols to compare them, - // but we should keep them in the list. - Function *function = sym_ctx.function; - if (!function) { - sc_sym_list.Append(sym_ctx); - continue; - } - // Filter out functions without declaration contexts, as well as - // class/instance methods, since they'll be skipped in the - // code that follows anyway. - CompilerDeclContext func_decl_context = function->GetDeclContext(); - if (!func_decl_context || - func_decl_context.IsClassMethod(nullptr, nullptr, nullptr)) - continue; - // We can only prune functions for which we can copy the type. - CompilerType func_clang_type = - function->GetType()->GetFullCompilerType(); - CompilerType copied_func_type = GuardedCopyType(func_clang_type); - if (!copied_func_type) { - sc_sym_list.Append(sym_ctx); - continue; - } + // If we found more than one function, see if we can use the + // frame's decl context to remove functions that are shadowed + // by other functions which match in type but are nearer in scope. + // + // AddOneFunction will not add a function whose type has already been + // added, so if there's another function in the list with a matching + // type, check to see if their decl context is a parent of the current + // frame's or was imported via a and using statement, and pick the + // best match according to lookup rules. + if (sc_list.GetSize() > 1) { + // Collect some info about our frame's context. + StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); + SymbolContext frame_sym_ctx; + if (frame != nullptr) + frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | + lldb::eSymbolContextBlock); + CompilerDeclContext frame_decl_context = + frame_sym_ctx.block != nullptr ? frame_sym_ctx.block->GetDeclContext() + : CompilerDeclContext(); - fdi.m_sym_ctx = sym_ctx; - fdi.m_name = function->GetName(); - fdi.m_copied_type = copied_func_type; - fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL; - if (fdi.m_copied_type && func_decl_context) { - // Call CountDeclLevels to get the number of parent scopes we - // have to look through before we find the function declaration. - // When comparing functions of the same type, the one with a - // lower count will be closer to us in the lookup scope and - // shadows the other. - clang::DeclContext *func_decl_ctx = - (clang::DeclContext *) - func_decl_context.GetOpaqueDeclContext(); - fdi.m_decl_lvl = - ast->CountDeclLevels(frame_decl_ctx, func_decl_ctx, - &fdi.m_name, &fdi.m_copied_type); - } - fdi_cache.emplace_back(fdi); - } + // We can't do this without a compiler decl context for our frame. + if (frame_decl_context) { + clang::DeclContext *frame_decl_ctx = + (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext(); + ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>( + frame_decl_context.GetTypeSystem()); - // Loop through the functions in our cache looking for matching types, - // then compare their scope levels to see which is closer. - std::multimap<CompilerType, const FuncDeclInfo *> matches; - for (const FuncDeclInfo &fdi : fdi_cache) { - const CompilerType t = fdi.m_copied_type; - auto q = matches.find(t); - if (q != matches.end()) { - if (q->second->m_decl_lvl > fdi.m_decl_lvl) - // This function is closer; remove the old set. - matches.erase(t); - else if (q->second->m_decl_lvl < fdi.m_decl_lvl) - // The functions in our set are closer - skip this one. - continue; - } - matches.insert(std::make_pair(t, &fdi)); + // Structure to hold the info needed when comparing function + // declarations. + struct FuncDeclInfo { + ConstString m_name; + CompilerType m_copied_type; + uint32_t m_decl_lvl; + SymbolContext m_sym_ctx; + }; + + // First, symplify things by looping through the symbol contexts + // to remove unwanted functions and separate out the functions we + // want to compare and prune into a separate list. + // Cache the info needed about the function declarations in a + // vector for efficiency. + SymbolContextList sc_sym_list; + uint32_t num_indices = sc_list.GetSize(); + std::vector<FuncDeclInfo> fdi_cache; + fdi_cache.reserve(num_indices); + for (uint32_t index = 0; index < num_indices; ++index) { + FuncDeclInfo fdi; + SymbolContext sym_ctx; + sc_list.GetContextAtIndex(index, sym_ctx); + + // We don't know enough about symbols to compare them, + // but we should keep them in the list. + Function *function = sym_ctx.function; + if (!function) { + sc_sym_list.Append(sym_ctx); + continue; + } + // Filter out functions without declaration contexts, as well as + // class/instance methods, since they'll be skipped in the + // code that follows anyway. + CompilerDeclContext func_decl_context = function->GetDeclContext(); + if (!func_decl_context || + func_decl_context.IsClassMethod(nullptr, nullptr, nullptr)) + continue; + // We can only prune functions for which we can copy the type. + CompilerType func_clang_type = + function->GetType()->GetFullCompilerType(); + CompilerType copied_func_type = GuardedCopyType(func_clang_type); + if (!copied_func_type) { + sc_sym_list.Append(sym_ctx); + continue; } - // Loop through our matches and add their symbol contexts to our list. - SymbolContextList sc_func_list; - for (const auto &q : matches) - sc_func_list.Append(q.second->m_sym_ctx); + fdi.m_sym_ctx = sym_ctx; + fdi.m_name = function->GetName(); + fdi.m_copied_type = copied_func_type; + fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL; + if (fdi.m_copied_type && func_decl_context) { + // Call CountDeclLevels to get the number of parent scopes we + // have to look through before we find the function declaration. + // When comparing functions of the same type, the one with a + // lower count will be closer to us in the lookup scope and + // shadows the other. + clang::DeclContext *func_decl_ctx = + (clang::DeclContext *)func_decl_context.GetOpaqueDeclContext(); + fdi.m_decl_lvl = ast->CountDeclLevels( + frame_decl_ctx, func_decl_ctx, &fdi.m_name, &fdi.m_copied_type); + } + fdi_cache.emplace_back(fdi); + } - // Rejoin the lists with the functions in front. - sc_list = sc_func_list; - sc_list.Append(sc_sym_list); + // Loop through the functions in our cache looking for matching types, + // then compare their scope levels to see which is closer. + std::multimap<CompilerType, const FuncDeclInfo *> matches; + for (const FuncDeclInfo &fdi : fdi_cache) { + const CompilerType t = fdi.m_copied_type; + auto q = matches.find(t); + if (q != matches.end()) { + if (q->second->m_decl_lvl > fdi.m_decl_lvl) + // This function is closer; remove the old set. + matches.erase(t); + else if (q->second->m_decl_lvl < fdi.m_decl_lvl) + // The functions in our set are closer - skip this one. + continue; + } + matches.insert(std::make_pair(t, &fdi)); } - } - if (sc_list.GetSize()) { - Symbol *extern_symbol = NULL; - Symbol *non_extern_symbol = NULL; + // Loop through our matches and add their symbol contexts to our list. + SymbolContextList sc_func_list; + for (const auto &q : matches) + sc_func_list.Append(q.second->m_sym_ctx); - for (uint32_t index = 0, num_indices = sc_list.GetSize(); - index < num_indices; ++index) { - SymbolContext sym_ctx; - sc_list.GetContextAtIndex(index, sym_ctx); + // Rejoin the lists with the functions in front. + sc_list = sc_func_list; + sc_list.Append(sc_sym_list); + } + } - if (sym_ctx.function) { - CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext(); + if (sc_list.GetSize()) { + Symbol *extern_symbol = NULL; + Symbol *non_extern_symbol = NULL; - if (!decl_ctx) - continue; + for (uint32_t index = 0, num_indices = sc_list.GetSize(); + index < num_indices; ++index) { + SymbolContext sym_ctx; + sc_list.GetContextAtIndex(index, sym_ctx); - // Filter out class/instance methods. - if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr)) - continue; + if (sym_ctx.function) { + CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext(); - AddOneFunction(context, sym_ctx.function, NULL, current_id); - context.m_found.function_with_type_info = true; - context.m_found.function = true; - } else if (sym_ctx.symbol) { - if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) { - sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target); - if (sym_ctx.symbol == NULL) - continue; - } + if (!decl_ctx) + continue; - if (sym_ctx.symbol->IsExternal()) - extern_symbol = sym_ctx.symbol; - else - non_extern_symbol = sym_ctx.symbol; + // Filter out class/instance methods. + if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr)) + continue; + + AddOneFunction(context, sym_ctx.function, NULL, current_id); + context.m_found.function_with_type_info = true; + context.m_found.function = true; + } else if (sym_ctx.symbol) { + if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) { + sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target); + if (sym_ctx.symbol == NULL) + continue; } + + if (sym_ctx.symbol->IsExternal()) + extern_symbol = sym_ctx.symbol; + else + non_extern_symbol = sym_ctx.symbol; } + } - if (!context.m_found.function_with_type_info) { - for (clang::NamedDecl *decl : decls_from_modules) { - if (llvm::isa<clang::FunctionDecl>(decl)) { - clang::NamedDecl *copied_decl = - llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl( - m_ast_context, &decl->getASTContext(), decl)); - if (copied_decl) { - context.AddNamedDecl(copied_decl); - context.m_found.function_with_type_info = true; - } + if (!context.m_found.function_with_type_info) { + for (clang::NamedDecl *decl : decls_from_modules) { + if (llvm::isa<clang::FunctionDecl>(decl)) { + clang::NamedDecl *copied_decl = + llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl( + m_ast_context, &decl->getASTContext(), decl)); + if (copied_decl) { + context.AddNamedDecl(copied_decl); + context.m_found.function_with_type_info = true; } } } + } - if (!context.m_found.function_with_type_info) { - if (extern_symbol) { - AddOneFunction(context, NULL, extern_symbol, current_id); - context.m_found.function = true; - } else if (non_extern_symbol) { - AddOneFunction(context, NULL, non_extern_symbol, current_id); - context.m_found.function = true; - } + if (!context.m_found.function_with_type_info) { + if (extern_symbol) { + AddOneFunction(context, NULL, extern_symbol, current_id); + context.m_found.function = true; + } else if (non_extern_symbol) { + AddOneFunction(context, NULL, non_extern_symbol, current_id); + context.m_found.function = true; } } + } - if (!context.m_found.function_with_type_info) { - // Try the modules next. + if (!context.m_found.function_with_type_info) { + // Try the modules next. - do { - if (ClangModulesDeclVendor *modules_decl_vendor = - m_target->GetClangModulesDeclVendor()) { - bool append = false; - uint32_t max_matches = 1; - std::vector<clang::NamedDecl *> decls; + do { + if (ClangModulesDeclVendor *modules_decl_vendor = + m_target->GetClangModulesDeclVendor()) { + bool append = false; + uint32_t max_matches = 1; + std::vector<clang::NamedDecl *> decls; - if (!modules_decl_vendor->FindDecls(name, append, max_matches, - decls)) - break; + if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls)) + break; - clang::NamedDecl *const decl_from_modules = decls[0]; + clang::NamedDecl *const decl_from_modules = decls[0]; - if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) { - if (log) { - log->Printf(" CAS::FEVD[%u] Matching function found for " - "\"%s\" in the modules", - current_id, name.GetCString()); - } + if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) { + if (log) { + log->Printf(" CAS::FEVD[%u] Matching function found for " + "\"%s\" in the modules", + current_id, name.GetCString()); + } - clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl( - m_ast_context, &decl_from_modules->getASTContext(), - decl_from_modules); - clang::FunctionDecl *copied_function_decl = - copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl) - : nullptr; + clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl( + m_ast_context, &decl_from_modules->getASTContext(), + decl_from_modules); + clang::FunctionDecl *copied_function_decl = + copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl) + : nullptr; - if (!copied_function_decl) { - if (log) - log->Printf(" CAS::FEVD[%u] - Couldn't export a function " - "declaration from the modules", - current_id); + if (!copied_function_decl) { + if (log) + log->Printf(" CAS::FEVD[%u] - Couldn't export a function " + "declaration from the modules", + current_id); - break; - } + break; + } - MaybeRegisterFunctionBody(copied_function_decl); + MaybeRegisterFunctionBody(copied_function_decl); - context.AddNamedDecl(copied_function_decl); + context.AddNamedDecl(copied_function_decl); - context.m_found.function_with_type_info = true; - context.m_found.function = true; - } else if (llvm::isa<clang::VarDecl>(decl_from_modules)) { - if (log) { - log->Printf(" CAS::FEVD[%u] Matching variable found for " - "\"%s\" in the modules", - current_id, name.GetCString()); - } + context.m_found.function_with_type_info = true; + context.m_found.function = true; + } else if (llvm::isa<clang::VarDecl>(decl_from_modules)) { + if (log) { + log->Printf(" CAS::FEVD[%u] Matching variable found for " + "\"%s\" in the modules", + current_id, name.GetCString()); + } - clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl( - m_ast_context, &decl_from_modules->getASTContext(), - decl_from_modules); - clang::VarDecl *copied_var_decl = - copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl) - : nullptr; + clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl( + m_ast_context, &decl_from_modules->getASTContext(), + decl_from_modules); + clang::VarDecl *copied_var_decl = + copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl) + : nullptr; - if (!copied_var_decl) { - if (log) - log->Printf(" CAS::FEVD[%u] - Couldn't export a variable " - "declaration from the modules", - current_id); + if (!copied_var_decl) { + if (log) + log->Printf(" CAS::FEVD[%u] - Couldn't export a variable " + "declaration from the modules", + current_id); - break; - } + break; + } - context.AddNamedDecl(copied_var_decl); + context.AddNamedDecl(copied_var_decl); - context.m_found.variable = true; - } + context.m_found.variable = true; } - } while (0); - } - - if (target && !context.m_found.variable && !namespace_decl) { - // We couldn't find a non-symbol variable for this. Now we'll hunt for - // a generic - // data symbol, and -- if it is found -- treat it as a variable. - - const Symbol *data_symbol = FindGlobalDataSymbol(*target, name); - - if (data_symbol) { - std::string warning("got name from symbols: "); - warning.append(name.AsCString()); - const unsigned diag_id = - m_ast_context->getDiagnostics().getCustomDiagID( - clang::DiagnosticsEngine::Level::Warning, "%0"); - m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str(); - AddOneGenericVariable(context, *data_symbol, current_id); - context.m_found.variable = true; } + } while (0); + } + + if (target && !context.m_found.variable && !namespace_decl) { + // We couldn't find a non-symbol variable for this. Now we'll hunt for + // a generic + // data symbol, and -- if it is found -- treat it as a variable. + + const Symbol *data_symbol = FindGlobalDataSymbol(*target, name); + + if (data_symbol) { + std::string warning("got name from symbols: "); + warning.append(name.AsCString()); + const unsigned diag_id = + m_ast_context->getDiagnostics().getCustomDiagID( + clang::DiagnosticsEngine::Level::Warning, "%0"); + m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str(); + AddOneGenericVariable(context, *data_symbol, current_id); + context.m_found.variable = true; } } } diff --git a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp index cbc77ebe9987..562d988be837 100644 --- a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp +++ b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp @@ -588,7 +588,7 @@ addr_t ThreadSanitizerRuntime::GetFirstNonInternalFramePc( ModuleSP runtime_module_sp = GetRuntimeModuleSP(); StructuredData::Array *trace_array = trace->GetAsArray(); - for (int i = 0; i < trace_array->GetSize(); i++) { + for (size_t i = 0; i < trace_array->GetSize(); i++) { if (skip_one_frame && i == 0) continue; diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 72d99671612c..659a12b7eecf 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -395,7 +395,8 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj, if (!D) return false; - ValueObjectSP layout_decider(D->GetChildAtIndexPath({0, 0})); + ValueObjectSP layout_decider( + D->GetChildAtIndexPath(llvm::ArrayRef<size_t>({0, 0}))); // this child should exist if (!layout_decider) diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index e2902d5ef787..1d8b759d2fa8 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -3682,7 +3682,7 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) { break; case DW_TAG_lexical_block: - decl_ctx = (clang::DeclContext *)ResolveBlockDIE(die); + decl_ctx = GetDeclContextForBlock(die); try_parsing_type = false; break; @@ -3704,6 +3704,69 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) { return nullptr; } +static bool IsSubroutine(const DWARFDIE &die) { + switch (die.Tag()) { + case DW_TAG_subprogram: + case DW_TAG_inlined_subroutine: + return true; + default: + return false; + } +} + +static DWARFDIE GetContainingFunctionWithAbstractOrigin(const DWARFDIE &die) { + for (DWARFDIE candidate = die; candidate; candidate = candidate.GetParent()) { + if (IsSubroutine(candidate)) { + if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) { + return candidate; + } else { + return DWARFDIE(); + } + } + } + assert(!"Shouldn't call GetContainingFunctionWithAbstractOrigin on something " + "not in a function"); + return DWARFDIE(); +} + +static DWARFDIE FindAnyChildWithAbstractOrigin(const DWARFDIE &context) { + for (DWARFDIE candidate = context.GetFirstChild(); candidate.IsValid(); + candidate = candidate.GetSibling()) { + if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) { + return candidate; + } + } + return DWARFDIE(); +} + +static DWARFDIE FindFirstChildWithAbstractOrigin(const DWARFDIE &block, + const DWARFDIE &function) { + assert(IsSubroutine(function)); + for (DWARFDIE context = block; context != function.GetParent(); + context = context.GetParent()) { + assert(!IsSubroutine(context) || context == function); + if (DWARFDIE child = FindAnyChildWithAbstractOrigin(context)) { + return child; + } + } + return DWARFDIE(); +} + +clang::DeclContext * +DWARFASTParserClang::GetDeclContextForBlock(const DWARFDIE &die) { + assert(die.Tag() == DW_TAG_lexical_block); + DWARFDIE containing_function_with_abstract_origin = + GetContainingFunctionWithAbstractOrigin(die); + if (!containing_function_with_abstract_origin) { + return (clang::DeclContext *)ResolveBlockDIE(die); + } + DWARFDIE child = FindFirstChildWithAbstractOrigin( + die, containing_function_with_abstract_origin); + CompilerDeclContext decl_context = + GetDeclContextContainingUIDFromDWARF(child); + return (clang::DeclContext *)decl_context.GetOpaqueDeclContext(); +} + clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) { if (die && die.Tag() == DW_TAG_lexical_block) { clang::BlockDecl *decl = diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 3d6d08eef9ed..57c1fc07b2b6 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -66,6 +66,8 @@ protected: class DelayedAddObjCClassProperty; typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList; + clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die); + clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die); clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die); diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 856c371636d9..973b5ef9fb46 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3051,7 +3051,13 @@ SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE &orig_die) { case DW_TAG_lexical_block: case DW_TAG_subprogram: return die; - + case DW_TAG_inlined_subroutine: { + DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin); + if (abs_die) { + return abs_die; + } + break; + } default: break; } |