forked from OSchip/llvm-project
[Target] Decouple ObjCLanguageRuntime from LanguageRuntime
Summary: ObjCLanguageRuntime was being pulled into LanguageRuntime because of Breakpoint Preconditions. If we move BreakpointPrecondition out of Breakpoint, we can extend the LanguageRuntime plugin interface so that LanguageRuntimes can give us a BreakpointPrecondition for exceptions. Differential Revision: https://reviews.llvm.org/D63181 llvm-svn: 364098
This commit is contained in:
parent
4649a051bf
commit
7f9c9f2264
|
@ -140,19 +140,6 @@ public:
|
|||
DISALLOW_COPY_AND_ASSIGN(BreakpointEventData);
|
||||
};
|
||||
|
||||
class BreakpointPrecondition {
|
||||
public:
|
||||
virtual ~BreakpointPrecondition() = default;
|
||||
|
||||
virtual bool EvaluatePrecondition(StoppointCallbackContext &context);
|
||||
|
||||
virtual Status ConfigurePrecondition(Args &options);
|
||||
|
||||
virtual void GetDescription(Stream &stream, lldb::DescriptionLevel level);
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<BreakpointPrecondition> BreakpointPreconditionSP;
|
||||
|
||||
// Saving & restoring breakpoints:
|
||||
static lldb::BreakpointSP CreateFromStructuredData(
|
||||
Target &target, StructuredData::ObjectSP &data_object_sp, Status &error);
|
||||
|
@ -558,14 +545,14 @@ public:
|
|||
/// The Precondition should not continue the target, it should return true
|
||||
/// if the condition says to stop and false otherwise.
|
||||
///
|
||||
void SetPrecondition(BreakpointPreconditionSP precondition_sp) {
|
||||
void SetPrecondition(lldb::BreakpointPreconditionSP precondition_sp) {
|
||||
m_precondition_sp = precondition_sp;
|
||||
}
|
||||
|
||||
bool EvaluatePrecondition(StoppointCallbackContext &context);
|
||||
|
||||
BreakpointPreconditionSP GetPrecondition() { return m_precondition_sp; }
|
||||
|
||||
lldb::BreakpointPreconditionSP GetPrecondition() { return m_precondition_sp; }
|
||||
|
||||
// Produces the OR'ed values for all the names assigned to this breakpoint.
|
||||
const BreakpointName::Permissions &GetPermissions() const {
|
||||
return m_permissions;
|
||||
|
@ -659,9 +646,9 @@ private:
|
|||
m_filter_sp; // The filter that constrains the breakpoint's domain.
|
||||
lldb::BreakpointResolverSP
|
||||
m_resolver_sp; // The resolver that defines this breakpoint.
|
||||
BreakpointPreconditionSP m_precondition_sp; // The precondition is a
|
||||
// breakpoint-level hit filter
|
||||
// that can be used
|
||||
lldb::BreakpointPreconditionSP m_precondition_sp; // The precondition is a
|
||||
// breakpoint-level hit
|
||||
// filter that can be used
|
||||
// to skip certain breakpoint hits. For instance, exception breakpoints use
|
||||
// this to limit the stop to certain exception classes, while leaving the
|
||||
// condition & callback free for user specification.
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
//===-- BreakpointPrecondition.h --------------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_BreakpointPrecondition_h_
|
||||
#define liblldb_BreakpointPrecondition_h_
|
||||
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class Args;
|
||||
class Status;
|
||||
class StoppointCallbackContext;
|
||||
class Stream;
|
||||
|
||||
class BreakpointPrecondition {
|
||||
public:
|
||||
virtual ~BreakpointPrecondition() = default;
|
||||
virtual bool EvaluatePrecondition(StoppointCallbackContext &context);
|
||||
virtual Status ConfigurePrecondition(Args &args);
|
||||
virtual void GetDescription(Stream &stream, lldb::DescriptionLevel level);
|
||||
};
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif
|
|
@ -134,10 +134,11 @@ public:
|
|||
GetLanguageCreateCallbackForPluginName(ConstString name);
|
||||
|
||||
// LanguageRuntime
|
||||
static bool
|
||||
RegisterPlugin(ConstString name, const char *description,
|
||||
LanguageRuntimeCreateInstance create_callback,
|
||||
LanguageRuntimeGetCommandObject command_callback = nullptr);
|
||||
static bool RegisterPlugin(
|
||||
ConstString name, const char *description,
|
||||
LanguageRuntimeCreateInstance create_callback,
|
||||
LanguageRuntimeGetCommandObject command_callback = nullptr,
|
||||
LanguageRuntimeGetExceptionPrecondition precondition_callback = nullptr);
|
||||
|
||||
static bool UnregisterPlugin(LanguageRuntimeCreateInstance create_callback);
|
||||
|
||||
|
@ -147,6 +148,9 @@ public:
|
|||
static LanguageRuntimeGetCommandObject
|
||||
GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx);
|
||||
|
||||
static LanguageRuntimeGetExceptionPrecondition
|
||||
GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx);
|
||||
|
||||
static LanguageRuntimeCreateInstance
|
||||
GetLanguageRuntimeCreateCallbackForPluginName(ConstString name);
|
||||
|
||||
|
|
|
@ -115,9 +115,8 @@ public:
|
|||
bool catch_bp, bool throw_bp,
|
||||
bool is_internal = false);
|
||||
|
||||
static Breakpoint::BreakpointPreconditionSP
|
||||
CreateExceptionPrecondition(lldb::LanguageType language, bool catch_bp,
|
||||
bool throw_bp);
|
||||
static lldb::BreakpointPreconditionSP
|
||||
GetExceptionPrecondition(lldb::LanguageType language, bool throw_bp);
|
||||
|
||||
virtual lldb::ValueObjectSP GetExceptionObjectForThread(
|
||||
lldb::ThreadSP thread_sp) {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "llvm/Support/Casting.h"
|
||||
|
||||
#include "lldb/Breakpoint/BreakpointPrecondition.h"
|
||||
#include "lldb/Core/PluginInterface.h"
|
||||
#include "lldb/Core/ThreadSafeDenseMap.h"
|
||||
#include "lldb/Symbol/CompilerType.h"
|
||||
|
@ -154,7 +155,7 @@ public:
|
|||
std::unique_ptr<ClangASTContext> m_scratch_ast_ctx_up;
|
||||
};
|
||||
|
||||
class ObjCExceptionPrecondition : public Breakpoint::BreakpointPrecondition {
|
||||
class ObjCExceptionPrecondition : public BreakpointPrecondition {
|
||||
public:
|
||||
ObjCExceptionPrecondition();
|
||||
|
||||
|
@ -171,6 +172,10 @@ public:
|
|||
std::unordered_set<std::string> m_class_names;
|
||||
};
|
||||
|
||||
static lldb::BreakpointPreconditionSP
|
||||
GetBreakpointExceptionPrecondition(lldb::LanguageType language,
|
||||
bool throw_bp);
|
||||
|
||||
class TaggedPointerVendor {
|
||||
public:
|
||||
virtual ~TaggedPointerVendor() = default;
|
||||
|
|
|
@ -37,6 +37,7 @@ class BreakpointLocationList;
|
|||
class BreakpointName;
|
||||
class BreakpointOptionGroup;
|
||||
class BreakpointOptions;
|
||||
class BreakpointPrecondition;
|
||||
class BreakpointResolver;
|
||||
class BreakpointSite;
|
||||
class BreakpointSiteList;
|
||||
|
@ -298,6 +299,7 @@ typedef std::shared_ptr<lldb_private::BreakpointSite> BreakpointSiteSP;
|
|||
typedef std::weak_ptr<lldb_private::BreakpointSite> BreakpointSiteWP;
|
||||
typedef std::shared_ptr<lldb_private::BreakpointLocation> BreakpointLocationSP;
|
||||
typedef std::weak_ptr<lldb_private::BreakpointLocation> BreakpointLocationWP;
|
||||
typedef std::shared_ptr<lldb_private::BreakpointPrecondition> BreakpointPreconditionSP;
|
||||
typedef std::shared_ptr<lldb_private::BreakpointResolver> BreakpointResolverSP;
|
||||
typedef std::shared_ptr<lldb_private::Broadcaster> BroadcasterSP;
|
||||
typedef std::shared_ptr<lldb_private::BroadcasterManager> BroadcasterManagerSP;
|
||||
|
|
|
@ -55,6 +55,9 @@ typedef LanguageRuntime *(*LanguageRuntimeCreateInstance)(
|
|||
Process *process, lldb::LanguageType language);
|
||||
typedef lldb::CommandObjectSP (*LanguageRuntimeGetCommandObject)(
|
||||
CommandInterpreter &interpreter);
|
||||
typedef lldb::BreakpointPreconditionSP (
|
||||
*LanguageRuntimeGetExceptionPrecondition)(lldb::LanguageType language,
|
||||
bool throw_bp);
|
||||
typedef lldb::StructuredDataPluginSP (*StructuredDataPluginCreateInstance)(
|
||||
Process &process);
|
||||
typedef Status (*StructuredDataFilterLaunchInfo)(ProcessLaunchInfo &launch_info,
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "lldb/Breakpoint/Breakpoint.h"
|
||||
#include "lldb/Breakpoint/BreakpointLocation.h"
|
||||
#include "lldb/Breakpoint/BreakpointLocationCollection.h"
|
||||
#include "lldb/Breakpoint/BreakpointPrecondition.h"
|
||||
#include "lldb/Breakpoint/BreakpointResolver.h"
|
||||
#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
|
||||
#include "lldb/Core/Address.h"
|
||||
|
@ -995,21 +996,6 @@ bool Breakpoint::EvaluatePrecondition(StoppointCallbackContext &context) {
|
|||
return m_precondition_sp->EvaluatePrecondition(context);
|
||||
}
|
||||
|
||||
bool Breakpoint::BreakpointPrecondition::EvaluatePrecondition(
|
||||
StoppointCallbackContext &context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Breakpoint::BreakpointPrecondition::GetDescription(
|
||||
Stream &stream, lldb::DescriptionLevel level) {}
|
||||
|
||||
Status
|
||||
Breakpoint::BreakpointPrecondition::ConfigurePrecondition(Args &options) {
|
||||
Status error;
|
||||
error.SetErrorString("Base breakpoint precondition has no options.");
|
||||
return error;
|
||||
}
|
||||
|
||||
void Breakpoint::SendBreakpointChangedEvent(
|
||||
lldb::BreakpointEventType eventKind) {
|
||||
if (!m_being_created && !IsInternal() &&
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
//===-- BreakpointPrecondition.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/Breakpoint/BreakpointPrecondition.h"
|
||||
#include "lldb/Utility/Status.h"
|
||||
|
||||
using namespace lldb_private;
|
||||
|
||||
bool BreakpointPrecondition::EvaluatePrecondition(
|
||||
StoppointCallbackContext &context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void BreakpointPrecondition::GetDescription(Stream &stream,
|
||||
lldb::DescriptionLevel level) {}
|
||||
|
||||
Status BreakpointPrecondition::ConfigurePrecondition(Args &args) {
|
||||
Status error;
|
||||
error.SetErrorString("Base breakpoint precondition has no options.");
|
||||
return error;
|
||||
}
|
|
@ -8,6 +8,7 @@ add_lldb_library(lldbBreakpoint
|
|||
BreakpointLocationList.cpp
|
||||
BreakpointName.cpp
|
||||
BreakpointOptions.cpp
|
||||
BreakpointPrecondition.cpp
|
||||
BreakpointResolver.cpp
|
||||
BreakpointResolverAddress.cpp
|
||||
BreakpointResolverFileLine.cpp
|
||||
|
|
|
@ -828,6 +828,7 @@ struct LanguageRuntimeInstance {
|
|||
std::string description;
|
||||
LanguageRuntimeCreateInstance create_callback;
|
||||
LanguageRuntimeGetCommandObject command_callback;
|
||||
LanguageRuntimeGetExceptionPrecondition precondition_callback;
|
||||
};
|
||||
|
||||
typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
|
||||
|
@ -845,7 +846,8 @@ static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
|
|||
bool PluginManager::RegisterPlugin(
|
||||
ConstString name, const char *description,
|
||||
LanguageRuntimeCreateInstance create_callback,
|
||||
LanguageRuntimeGetCommandObject command_callback) {
|
||||
LanguageRuntimeGetCommandObject command_callback,
|
||||
LanguageRuntimeGetExceptionPrecondition precondition_callback) {
|
||||
if (create_callback) {
|
||||
LanguageRuntimeInstance instance;
|
||||
assert((bool)name);
|
||||
|
@ -854,6 +856,7 @@ bool PluginManager::RegisterPlugin(
|
|||
instance.description = description;
|
||||
instance.create_callback = create_callback;
|
||||
instance.command_callback = command_callback;
|
||||
instance.precondition_callback = precondition_callback;
|
||||
std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
|
||||
GetLanguageRuntimeInstances().push_back(instance);
|
||||
}
|
||||
|
@ -895,6 +898,15 @@ PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
LanguageRuntimeGetExceptionPrecondition
|
||||
PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) {
|
||||
std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
|
||||
LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
|
||||
if (idx < instances.size())
|
||||
return instances[idx].precondition_callback;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LanguageRuntimeCreateInstance
|
||||
PluginManager::GetLanguageRuntimeCreateCallbackForPluginName(
|
||||
ConstString name) {
|
||||
|
|
|
@ -85,7 +85,8 @@ AppleObjCRuntimeV1::CreateInstance(Process *process,
|
|||
void AppleObjCRuntimeV1::Initialize() {
|
||||
PluginManager::RegisterPlugin(
|
||||
GetPluginNameStatic(), "Apple Objective-C Language Runtime - Version 1",
|
||||
CreateInstance);
|
||||
CreateInstance,
|
||||
/*command_callback = */ nullptr, GetBreakpointExceptionPrecondition);
|
||||
}
|
||||
|
||||
void AppleObjCRuntimeV1::Terminate() {
|
||||
|
|
|
@ -806,7 +806,8 @@ void AppleObjCRuntimeV2::Initialize() {
|
|||
CreateInstance,
|
||||
[](CommandInterpreter &interpreter) -> lldb::CommandObjectSP {
|
||||
return CommandObjectSP(new CommandObjectMultiwordObjC(interpreter));
|
||||
});
|
||||
},
|
||||
GetBreakpointExceptionPrecondition);
|
||||
}
|
||||
|
||||
void AppleObjCRuntimeV2::Terminate() {
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "lldb/Core/SearchFilter.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Target/Language.h"
|
||||
#include "lldb/Target/ObjCLanguageRuntime.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
using namespace lldb;
|
||||
|
@ -224,19 +223,24 @@ LanguageRuntime::LanguageRuntime(Process *process) : m_process(process) {}
|
|||
|
||||
LanguageRuntime::~LanguageRuntime() = default;
|
||||
|
||||
Breakpoint::BreakpointPreconditionSP
|
||||
LanguageRuntime::CreateExceptionPrecondition(lldb::LanguageType language,
|
||||
bool catch_bp, bool throw_bp) {
|
||||
switch (language) {
|
||||
case eLanguageTypeObjC:
|
||||
if (throw_bp)
|
||||
return Breakpoint::BreakpointPreconditionSP(
|
||||
new ObjCLanguageRuntime::ObjCExceptionPrecondition());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
BreakpointPreconditionSP
|
||||
LanguageRuntime::GetExceptionPrecondition(LanguageType language,
|
||||
bool throw_bp) {
|
||||
LanguageRuntimeCreateInstance create_callback;
|
||||
for (uint32_t idx = 0;
|
||||
(create_callback =
|
||||
PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) !=
|
||||
nullptr;
|
||||
idx++) {
|
||||
if (auto precondition_callback =
|
||||
PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(
|
||||
idx)) {
|
||||
if (BreakpointPreconditionSP precond =
|
||||
precondition_callback(language, throw_bp))
|
||||
return precond;
|
||||
}
|
||||
}
|
||||
return Breakpoint::BreakpointPreconditionSP();
|
||||
return BreakpointPreconditionSP();
|
||||
}
|
||||
|
||||
BreakpointSP LanguageRuntime::CreateExceptionBreakpoint(
|
||||
|
@ -252,10 +256,8 @@ BreakpointSP LanguageRuntime::CreateExceptionBreakpoint(
|
|||
target.CreateBreakpoint(filter_sp, resolver_sp, is_internal, hardware,
|
||||
resolve_indirect_functions));
|
||||
if (exc_breakpt_sp) {
|
||||
Breakpoint::BreakpointPreconditionSP precondition_sp =
|
||||
CreateExceptionPrecondition(language, catch_bp, throw_bp);
|
||||
if (precondition_sp)
|
||||
exc_breakpt_sp->SetPrecondition(precondition_sp);
|
||||
if (auto precond = GetExceptionPrecondition(language, throw_bp))
|
||||
exc_breakpt_sp->SetPrecondition(precond);
|
||||
|
||||
if (is_internal)
|
||||
exc_breakpt_sp->SetBreakpointKind("exception");
|
||||
|
@ -292,4 +294,3 @@ void LanguageRuntime::InitializeCommands(CommandObject *parent) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -375,6 +375,18 @@ bool ObjCLanguageRuntime::GetTypeBitSize(const CompilerType &compiler_type,
|
|||
return found;
|
||||
}
|
||||
|
||||
lldb::BreakpointPreconditionSP
|
||||
ObjCLanguageRuntime::GetBreakpointExceptionPrecondition(LanguageType language,
|
||||
bool throw_bp) {
|
||||
if (language != eLanguageTypeObjC)
|
||||
return lldb::BreakpointPreconditionSP();
|
||||
if (!throw_bp)
|
||||
return lldb::BreakpointPreconditionSP();
|
||||
BreakpointPreconditionSP precondition_sp(
|
||||
new ObjCLanguageRuntime::ObjCExceptionPrecondition());
|
||||
return precondition_sp;
|
||||
}
|
||||
|
||||
// Exception breakpoint Precondition class for ObjC:
|
||||
void ObjCLanguageRuntime::ObjCExceptionPrecondition::AddClassName(
|
||||
const char *class_name) {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
|
||||
#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
|
||||
#include "lldb/Breakpoint/BreakpointIDList.h"
|
||||
#include "lldb/Breakpoint/BreakpointPrecondition.h"
|
||||
#include "lldb/Breakpoint/BreakpointResolver.h"
|
||||
#include "lldb/Breakpoint/BreakpointResolverAddress.h"
|
||||
#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
|
||||
|
@ -573,8 +574,7 @@ Target::CreateExceptionBreakpoint(enum lldb::LanguageType language,
|
|||
BreakpointSP exc_bkpt_sp = LanguageRuntime::CreateExceptionBreakpoint(
|
||||
*this, language, catch_bp, throw_bp, internal);
|
||||
if (exc_bkpt_sp && additional_args) {
|
||||
Breakpoint::BreakpointPreconditionSP precondition_sp =
|
||||
exc_bkpt_sp->GetPrecondition();
|
||||
BreakpointPreconditionSP precondition_sp = exc_bkpt_sp->GetPrecondition();
|
||||
if (precondition_sp && additional_args) {
|
||||
if (error)
|
||||
*error = precondition_sp->ConfigurePrecondition(*additional_args);
|
||||
|
|
Loading…
Reference in New Issue