/// LLVM IR from the expression.
class Expression {
public:
- /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
- enum ExpressionKind {
- eKindFunctionCaller,
- eKindClangFunctionCaller,
- eKindUserExpression,
- eKindLLVMUserExpression,
- eKindClangUserExpression,
- eKindUtilityFunction,
- eKindClangUtilityFunction,
- };
-
enum ResultType { eResultTypeAny, eResultTypeId };
- Expression(Target &target, ExpressionKind kind);
+ Expression(Target &target);
- Expression(ExecutionContextScope &exe_scope, ExpressionKind kind);
+ Expression(ExecutionContextScope &exe_scope);
/// Destructor
virtual ~Expression() {}
virtual ExpressionTypeSystemHelper *GetTypeSystemHelper() { return nullptr; }
- /// LLVM-style RTTI support.
- ExpressionKind getKind() const { return m_kind; }
-
-private:
- /// LLVM-style RTTI support.
- const ExpressionKind m_kind;
+ // LLVM RTTI support
+ virtual bool isA(const void *ClassID) const = 0;
+
protected:
lldb::TargetWP m_target_wp; /// Expression's always have to have a target...
lldb::ProcessWP m_jit_process_wp; /// An expression might have a process, but
/// Any of the methods that take arg_addr_ptr can be passed nullptr, and the
/// argument space will be managed for you.
class FunctionCaller : public Expression {
+ // LLVM RTTI support
+ static char ID;
+
public:
- /// LLVM-style RTTI support.
- static bool classof(const Expression *E) {
- return E->getKind() == eKindFunctionCaller;
- }
-
+ bool isA(const void *ClassID) const override { return ClassID == &ID; }
+ static bool classof(const Expression *obj) { return obj->isA(&ID); }
+
/// Constructor
///
/// \param[in] exe_scope
/// implementations of LLVMUserExpression - which will be vended through the
/// appropriate TypeSystem.
class LLVMUserExpression : public UserExpression {
+ // LLVM RTTI support
+ static char ID;
+
public:
- /// LLVM-style RTTI support.
- static bool classof(const Expression *E) {
- return E->getKind() == eKindLLVMUserExpression;
+ bool isA(const void *ClassID) const override {
+ return ClassID == &ID || UserExpression::isA(ClassID);
}
+ static bool classof(const Expression *obj) { return obj->isA(&ID); }
// The IRPasses struct is filled in by a runtime after an expression is
// compiled and can be used to to run fixups/analysis passes as required.
LLVMUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
llvm::StringRef prefix, lldb::LanguageType language,
ResultType desired_type,
- const EvaluateExpressionOptions &options,
- ExpressionKind kind);
+ const EvaluateExpressionOptions &options);
~LLVMUserExpression() override;
bool FinalizeJITExecution(
/// implementations of UserExpression - which will be vended through the
/// appropriate TypeSystem.
class UserExpression : public Expression {
+ // LLVM RTTI support
+ static char ID;
+
public:
- /// LLVM-style RTTI support.
- static bool classof(const Expression *E) {
- return E->getKind() == eKindUserExpression;
- }
-
+ bool isA(const void *ClassID) const override { return ClassID == &ID; }
+ static bool classof(const Expression *obj) { return obj->isA(&ID); }
+
enum { kDefaultTimeout = 500000u };
/// Constructor
UserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
llvm::StringRef prefix, lldb::LanguageType language,
ResultType desired_type,
- const EvaluateExpressionOptions &options,
- ExpressionKind kind);
+ const EvaluateExpressionOptions &options);
/// Destructor
~UserExpression() override;
/// self-contained function meant to be used from other code. Utility
/// functions can perform error-checking for ClangUserExpressions,
class UtilityFunction : public Expression {
+ // LLVM RTTI support
+ static char ID;
+
public:
- /// LLVM-style RTTI support.
- static bool classof(const Expression *E) {
- return E->getKind() == eKindUtilityFunction;
- }
-
+ bool isA(const void *ClassID) const override { return ClassID == &ID; }
+ static bool classof(const Expression *obj) { return obj->isA(&ID); }
+
/// Constructor
///
/// \param[in] text
/// \param[in] name
/// The name of the function, as used in the text.
UtilityFunction(ExecutionContextScope &exe_scope, const char *text,
- const char *name, ExpressionKind kind);
+ const char *name);
~UtilityFunction() override;
using namespace lldb_private;
-Expression::Expression(Target &target, ExpressionKind kind)
- : m_kind(kind),
- m_target_wp(target.shared_from_this()),
+Expression::Expression(Target &target)
+ : m_target_wp(target.shared_from_this()),
m_jit_start_addr(LLDB_INVALID_ADDRESS),
m_jit_end_addr(LLDB_INVALID_ADDRESS) {
// Can't make any kind of expression without a target.
assert(m_target_wp.lock());
}
-Expression::Expression(ExecutionContextScope &exe_scope, ExpressionKind kind)
- : m_kind(kind),
- m_target_wp(exe_scope.CalculateTarget()),
+Expression::Expression(ExecutionContextScope &exe_scope)
+ : m_target_wp(exe_scope.CalculateTarget()),
m_jit_start_addr(LLDB_INVALID_ADDRESS),
m_jit_end_addr(LLDB_INVALID_ADDRESS) {
assert(m_target_wp.lock());
using namespace lldb_private;
+char FunctionCaller::ID;
+
// FunctionCaller constructor
FunctionCaller::FunctionCaller(ExecutionContextScope &exe_scope,
const CompilerType &return_type,
const Address &functionAddress,
const ValueList &arg_value_list,
const char *name)
- : Expression(exe_scope, eKindFunctionCaller), m_execution_unit_sp(),
- m_parser(), m_jit_module_wp(), m_name(name ? name : "<unknown>"),
+ : Expression(exe_scope), m_execution_unit_sp(), m_parser(),
+ m_jit_module_wp(), m_name(name ? name : "<unknown>"),
m_function_ptr(nullptr), m_function_addr(functionAddress),
m_function_return_type(return_type),
m_wrapper_function_name("__lldb_caller_function"),
using namespace lldb_private;
+char LLVMUserExpression::ID;
+
LLVMUserExpression::LLVMUserExpression(ExecutionContextScope &exe_scope,
llvm::StringRef expr,
llvm::StringRef prefix,
lldb::LanguageType language,
ResultType desired_type,
- const EvaluateExpressionOptions &options,
- ExpressionKind kind)
- : UserExpression(exe_scope, expr, prefix, language, desired_type, options,
- kind),
+ const EvaluateExpressionOptions &options)
+ : UserExpression(exe_scope, expr, prefix, language, desired_type, options),
m_stack_frame_bottom(LLDB_INVALID_ADDRESS),
m_stack_frame_top(LLDB_INVALID_ADDRESS), m_allow_cxx(false),
m_allow_objc(false), m_transformed_text(), m_execution_unit_sp(),
- m_materializer_up(), m_jit_module_wp(),
- m_can_interpret(false), m_materialized_address(LLDB_INVALID_ADDRESS) {}
+ m_materializer_up(), m_jit_module_wp(), m_can_interpret(false),
+ m_materialized_address(LLDB_INVALID_ADDRESS) {}
LLVMUserExpression::~LLVMUserExpression() {
if (m_target) {
using namespace lldb_private;
+char UserExpression::ID;
+
UserExpression::UserExpression(ExecutionContextScope &exe_scope,
llvm::StringRef expr, llvm::StringRef prefix,
lldb::LanguageType language,
ResultType desired_type,
- const EvaluateExpressionOptions &options,
- ExpressionKind kind)
- : Expression(exe_scope, kind), m_expr_text(expr), m_expr_prefix(prefix),
+ const EvaluateExpressionOptions &options)
+ : Expression(exe_scope), m_expr_text(expr), m_expr_prefix(prefix),
m_language(language), m_desired_type(desired_type), m_options(options) {}
UserExpression::~UserExpression() {}
using namespace lldb_private;
using namespace lldb;
+char UtilityFunction::ID;
+
/// Constructor
///
/// \param[in] text
/// \param[in] name
/// The name of the function, as used in the text.
UtilityFunction::UtilityFunction(ExecutionContextScope &exe_scope,
- const char *text, const char *name,
- ExpressionKind kind)
- : Expression(exe_scope, kind),
- m_execution_unit_sp(), m_jit_module_wp(),
- m_function_text(),
- m_function_name(name) {}
+ const char *text, const char *name)
+ : Expression(exe_scope), m_execution_unit_sp(), m_jit_module_wp(),
+ m_function_text(), m_function_name(name) {}
UtilityFunction::~UtilityFunction() {
lldb::ProcessSP process_sp(m_jit_process_wp.lock());
using namespace lldb_private;
+char ClangFunctionCaller::ID;
+
// ClangFunctionCaller constructor
ClangFunctionCaller::ClangFunctionCaller(ExecutionContextScope &exe_scope,
const CompilerType &return_type,
class ClangFunctionCaller : public FunctionCaller {
friend class ASTStructExtractor;
- /// LLVM-style RTTI support.
- static bool classof(const Expression *E) {
- return E->getKind() == eKindClangFunctionCaller;
- }
-
class ClangFunctionCallerHelper : public ClangExpressionHelper {
public:
ClangFunctionCallerHelper(ClangFunctionCaller &owner) : m_owner(owner) {}
///layout.
};
+ // LLVM RTTI support
+ static char ID;
+
public:
+ bool isA(const void *ClassID) const override {
+ return ClassID == &ID || FunctionCaller::isA(ClassID);
+ }
+ static bool classof(const Expression *obj) { return obj->isA(&ID); }
+
/// Constructor
///
/// \param[in] exe_scope
using namespace lldb_private;
+char ClangUserExpression::ID;
+
ClangUserExpression::ClangUserExpression(
ExecutionContextScope &exe_scope, llvm::StringRef expr,
llvm::StringRef prefix, lldb::LanguageType language,
ResultType desired_type, const EvaluateExpressionOptions &options,
ValueObject *ctx_obj)
: LLVMUserExpression(exe_scope, expr, prefix, language, desired_type,
- options, eKindClangUserExpression),
+ options),
m_type_system_helper(*m_target_wp.lock(), options.GetExecutionPolicy() ==
eExecutionPolicyTopLevel),
m_result_delegate(exe_scope.CalculateTarget()), m_ctx_obj(ctx_obj) {
/// the objects needed to parse and interpret or JIT an expression. It uses
/// the Clang parser to produce LLVM IR from the expression.
class ClangUserExpression : public LLVMUserExpression {
+ // LLVM RTTI support
+ static char ID;
+
public:
- /// LLVM-style RTTI support.
- static bool classof(const Expression *E) {
- return E->getKind() == eKindClangUserExpression;
+ bool isA(const void *ClassID) const override {
+ return ClassID == &ID || LLVMUserExpression::isA(ClassID);
}
+ static bool classof(const Expression *obj) { return obj->isA(&ID); }
enum { kDefaultTimeout = 500000u };
using namespace lldb_private;
+char ClangUtilityFunction::ID;
+
/// Constructor
///
/// \param[in] text
/// The name of the function, as used in the text.
ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope,
const char *text, const char *name)
- : UtilityFunction(exe_scope, text, name, eKindClangUtilityFunction) {
+ : UtilityFunction(exe_scope, text, name) {
m_function_text.assign(ClangExpressionSourceCode::g_expression_prefix);
if (text && text[0])
m_function_text.append(text);
/// simply provide a way to push a function into the target for the debugger
/// to call later on.
class ClangUtilityFunction : public UtilityFunction {
+ // LLVM RTTI support
+ static char ID;
+
public:
- /// LLVM-style RTTI support.
- static bool classof(const Expression *E) {
- return E->getKind() == eKindClangUtilityFunction;
+ bool isA(const void *ClassID) const override {
+ return ClassID == &ID || UtilityFunction::isA(ClassID);
}
+ static bool classof(const Expression *obj) { return obj->isA(&ID); }
class ClangUtilityFunctionHelper : public ClangExpressionHelper {
public: