Index: include/lldb/Expression/Expression.h =================================================================== --- include/lldb/Expression/Expression.h +++ include/lldb/Expression/Expression.h @@ -34,11 +34,22 @@ //---------------------------------------------------------------------- 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); + Expression(Target &target, ExpressionKind kind); - Expression(ExecutionContextScope &exe_scope); + Expression(ExecutionContextScope &exe_scope, ExpressionKind kind); //------------------------------------------------------------------ /// Destructor @@ -103,6 +114,12 @@ virtual ExpressionTypeSystemHelper *GetTypeSystemHelper() { return nullptr; } + /// LLVM-style RTTI support. + ExpressionKind getKind() const { return m_kind; } + +private: + /// LLVM-style RTTI support. + const ExpressionKind m_kind; 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 Index: include/lldb/Expression/FunctionCaller.h =================================================================== --- include/lldb/Expression/FunctionCaller.h +++ include/lldb/Expression/FunctionCaller.h @@ -57,6 +57,11 @@ //---------------------------------------------------------------------- class FunctionCaller : public Expression { public: + /// LLVM-style RTTI support. + static bool classof(const Expression *E) { + return E->getKind() == eKindFunctionCaller; + } + //------------------------------------------------------------------ /// Constructor /// Index: include/lldb/Expression/LLVMUserExpression.h =================================================================== --- include/lldb/Expression/LLVMUserExpression.h +++ include/lldb/Expression/LLVMUserExpression.h @@ -33,6 +33,11 @@ //---------------------------------------------------------------------- class LLVMUserExpression : public UserExpression { public: + /// LLVM-style RTTI support. + static bool classof(const Expression *E) { + return E->getKind() == eKindLLVMUserExpression; + } + // 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. // EarlyPasses are run on the generated module before lldb runs its own IR @@ -48,7 +53,8 @@ LLVMUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, ResultType desired_type, - const EvaluateExpressionOptions &options); + const EvaluateExpressionOptions &options, + ExpressionKind kind); ~LLVMUserExpression() override; bool FinalizeJITExecution( Index: include/lldb/Expression/UserExpression.h =================================================================== --- include/lldb/Expression/UserExpression.h +++ include/lldb/Expression/UserExpression.h @@ -36,6 +36,11 @@ //---------------------------------------------------------------------- class UserExpression : public Expression { public: + /// LLVM-style RTTI support. + static bool classof(const Expression *E) { + return E->getKind() == eKindUserExpression; + } + enum { kDefaultTimeout = 500000u }; //------------------------------------------------------------------ @@ -60,7 +65,8 @@ UserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, ResultType desired_type, - const EvaluateExpressionOptions &options); + const EvaluateExpressionOptions &options, + ExpressionKind kind); //------------------------------------------------------------------ /// Destructor Index: include/lldb/Expression/UtilityFunction.h =================================================================== --- include/lldb/Expression/UtilityFunction.h +++ include/lldb/Expression/UtilityFunction.h @@ -31,6 +31,11 @@ //---------------------------------------------------------------------- class UtilityFunction : public Expression { public: + /// LLVM-style RTTI support. + static bool classof(const Expression *E) { + return E->getKind() == eKindUtilityFunction; + } + //------------------------------------------------------------------ /// Constructor /// @@ -41,7 +46,7 @@ /// The name of the function, as used in the text. //------------------------------------------------------------------ UtilityFunction(ExecutionContextScope &exe_scope, const char *text, - const char *name); + const char *name, ExpressionKind kind); ~UtilityFunction() override; Index: source/Expression/Expression.cpp =================================================================== --- source/Expression/Expression.cpp +++ source/Expression/Expression.cpp @@ -12,16 +12,18 @@ using namespace lldb_private; -Expression::Expression(Target &target) - : m_target_wp(target.shared_from_this()), +Expression::Expression(Target &target, ExpressionKind kind) + : m_kind(kind), + 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) - : m_target_wp(exe_scope.CalculateTarget()), +Expression::Expression(ExecutionContextScope &exe_scope, ExpressionKind kind) + : m_kind(kind), + 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()); Index: source/Expression/FunctionCaller.cpp =================================================================== --- source/Expression/FunctionCaller.cpp +++ source/Expression/FunctionCaller.cpp @@ -37,7 +37,8 @@ const Address &functionAddress, const ValueList &arg_value_list, const char *name) - : Expression(exe_scope), m_execution_unit_sp(), m_parser(), + : Expression(exe_scope, eKindFunctionCaller), + m_execution_unit_sp(), m_parser(), m_jit_module_wp(), m_name(name ? name : ""), m_function_ptr(NULL), m_function_addr(functionAddress), m_function_return_type(return_type), Index: source/Expression/LLVMUserExpression.cpp =================================================================== --- source/Expression/LLVMUserExpression.cpp +++ source/Expression/LLVMUserExpression.cpp @@ -41,8 +41,10 @@ llvm::StringRef prefix, lldb::LanguageType language, ResultType desired_type, - const EvaluateExpressionOptions &options) - : UserExpression(exe_scope, expr, prefix, language, desired_type, options), + const EvaluateExpressionOptions &options, + ExpressionKind kind) + : UserExpression(exe_scope, expr, prefix, language, desired_type, options, + kind), 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(), Index: source/Expression/UserExpression.cpp =================================================================== --- source/Expression/UserExpression.cpp +++ source/Expression/UserExpression.cpp @@ -48,8 +48,9 @@ llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, ResultType desired_type, - const EvaluateExpressionOptions &options) - : Expression(exe_scope), m_expr_text(expr), m_expr_prefix(prefix), + const EvaluateExpressionOptions &options, + ExpressionKind kind) + : Expression(exe_scope, kind), m_expr_text(expr), m_expr_prefix(prefix), m_language(language), m_desired_type(desired_type), m_options(options) {} UserExpression::~UserExpression() {} Index: source/Expression/UtilityFunction.cpp =================================================================== --- source/Expression/UtilityFunction.cpp +++ source/Expression/UtilityFunction.cpp @@ -39,8 +39,10 @@ /// The name of the function, as used in the text. //------------------------------------------------------------------ UtilityFunction::UtilityFunction(ExecutionContextScope &exe_scope, - const char *text, const char *name) - : Expression(exe_scope), m_execution_unit_sp(), m_jit_module_wp(), + 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) {} Index: source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -492,8 +492,8 @@ // long time parsing and importing debug information. lang_opts.SpellChecking = false; - auto &clang_expr = *static_cast(&m_expr); - if (clang_expr.DidImportCxxModules()) { + auto *clang_expr = dyn_cast(&m_expr); + if (clang_expr && clang_expr->DidImportCxxModules()) { LLDB_LOG(log, "Adding lang options for importing C++ modules"); lang_opts.Modules = true; Index: source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h +++ source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h @@ -61,6 +61,11 @@ 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) {} Index: source/Plugins/ExpressionParser/Clang/ClangUserExpression.h =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangUserExpression.h +++ source/Plugins/ExpressionParser/Clang/ClangUserExpression.h @@ -40,6 +40,11 @@ //---------------------------------------------------------------------- class ClangUserExpression : public LLVMUserExpression { public: + /// LLVM-style RTTI support. + static bool classof(const Expression *E) { + return E->getKind() == eKindClangUserExpression; + } + enum { kDefaultTimeout = 500000u }; class ClangUserExpressionHelper : public ClangExpressionHelper { Index: source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -64,7 +64,7 @@ ResultType desired_type, const EvaluateExpressionOptions &options, ValueObject *ctx_obj) : LLVMUserExpression(exe_scope, expr, prefix, language, desired_type, - options), + options, eKindClangUserExpression), m_type_system_helper(*m_target_wp.lock(), options.GetExecutionPolicy() == eExecutionPolicyTopLevel), m_result_delegate(exe_scope.CalculateTarget()), m_ctx_obj(ctx_obj) { Index: source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h +++ source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h @@ -36,6 +36,11 @@ //---------------------------------------------------------------------- class ClangUtilityFunction : public UtilityFunction { public: + /// LLVM-style RTTI support. + static bool classof(const Expression *E) { + return E->getKind() == eKindClangUtilityFunction; + } + class ClangUtilityFunctionHelper : public ClangExpressionHelper { public: ClangUtilityFunctionHelper() {} Index: source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp +++ source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp @@ -40,7 +40,7 @@ //------------------------------------------------------------------ ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope, const char *text, const char *name) - : UtilityFunction(exe_scope, text, name) { + : UtilityFunction(exe_scope, text, name, eKindClangUtilityFunction) { m_function_text.assign(ClangExpressionSourceCode::g_expression_prefix); if (text && text[0]) m_function_text.append(text);