[Lldb-commits] [lldb] r353149 - [Expressions] Add support of expressions evaluation in some object's context

Aleksandr Urakov via lldb-commits lldb-commits at lists.llvm.org
Tue Feb 5 01:14:37 PST 2019


Author: aleksandr.urakov
Date: Tue Feb  5 01:14:36 2019
New Revision: 353149

URL: http://llvm.org/viewvc/llvm-project?rev=353149&view=rev
Log:
[Expressions] Add support of expressions evaluation in some object's context

Summary:
This patch adds support of expression evaluation in a context of some object.
Consider the following example:
```
struct S {
  int a = 11;
  int b = 12;
};

int main() {
  S s;
  int a = 1;
  int b = 2;
  // We have stopped here
  return 0;
}
```
This patch allows to do something like that:
```
lldb.frame.FindVariable("s").EvaluateExpression("a + b")
```
and the result will be `33` (not `3`) because fields `a` and `b` of `s` will be
used (not locals `a` and `b`).

This is achieved by replacing of `this` type and object for the expression. This
has some limitations: an expression can be evaluated only for values located in
the debuggee process memory (they must have an address of `eAddressTypeLoad`
type).

Reviewers: teemperor, clayborg, jingham, zturner, labath, davide, spyffe, serge-sans-paille

Reviewed By: jingham

Subscribers: abidh, lldb-commits, leonid.mashinskiy

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D55318

Added:
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/TestContextObjectObjc.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/main.m
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/TestContextObject.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/main.cpp
Modified:
    lldb/trunk/include/lldb/API/SBValue.h
    lldb/trunk/include/lldb/Expression/ExpressionSourceCode.h
    lldb/trunk/include/lldb/Expression/UserExpression.h
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/include/lldb/Symbol/TypeSystem.h
    lldb/trunk/include/lldb/Target/Target.h
    lldb/trunk/scripts/interface/SBValue.i
    lldb/trunk/source/API/SBValue.cpp
    lldb/trunk/source/Breakpoint/BreakpointLocation.cpp
    lldb/trunk/source/Breakpoint/Watchpoint.cpp
    lldb/trunk/source/Commands/CommandObjectExpression.cpp
    lldb/trunk/source/Expression/ExpressionSourceCode.cpp
    lldb/trunk/source/Expression/UserExpression.cpp
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
    lldb/trunk/source/Symbol/ClangASTContext.cpp
    lldb/trunk/source/Target/Target.cpp

Modified: lldb/trunk/include/lldb/API/SBValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValue.h?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBValue.h (original)
+++ lldb/trunk/include/lldb/API/SBValue.h Tue Feb  5 01:14:36 2019
@@ -306,6 +306,13 @@ public:
   bool GetExpressionPath(lldb::SBStream &description,
                          bool qualify_cxx_base_classes);
 
+  lldb::SBValue EvaluateExpression(const char *expr) const;
+  lldb::SBValue EvaluateExpression(const char *expr,
+                                   const SBExpressionOptions &options) const;
+  lldb::SBValue EvaluateExpression(const char *expr,
+                                   const SBExpressionOptions &options,
+                                   const char *name) const;
+
   SBValue(const lldb::ValueObjectSP &value_sp);
 
   //------------------------------------------------------------------

Modified: lldb/trunk/include/lldb/Expression/ExpressionSourceCode.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ExpressionSourceCode.h?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ExpressionSourceCode.h (original)
+++ lldb/trunk/include/lldb/Expression/ExpressionSourceCode.h Tue Feb  5 01:14:36 2019
@@ -36,7 +36,8 @@ public:
   const char *GetName() const { return m_name.c_str(); }
 
   bool GetText(std::string &text, lldb::LanguageType wrapping_language,
-               bool static_method, ExecutionContext &exe_ctx) const;
+               bool static_method, ExecutionContext &exe_ctx,
+               bool add_locals) const;
 
   // Given a string returned by GetText, find the beginning and end of the body
   // passed to CreateWrapped. Return true if the bounds could be found.  This

Modified: lldb/trunk/include/lldb/Expression/UserExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/UserExpression.h?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/UserExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/UserExpression.h Tue Feb  5 01:14:36 2019
@@ -272,6 +272,16 @@ public:
   /// @param[out] jit_module_sp_ptr
   ///     If non-nullptr, used to persist the generated IR module.
   ///
+  /// @param[in] ctx_obj
+  ///     If specified, then the expression will be evaluated in the context of
+  ///     this object. It means that the context object's address will be
+  ///     treated as `this` for the expression (the expression will be
+  ///     evaluated as if it was inside of a method of the context object's
+  ///     class, and its `this` parameter were pointing to the context object).
+  ///     The parameter makes sense for class and union types only.
+  ///     Currently there is a limitation: the context object must be located
+  ///     in the debuggee process' memory (and have the load address).
+  ///
   /// @result
   ///      A Process::ExpressionResults value.  eExpressionCompleted for
   ///      success.
@@ -281,7 +291,8 @@ public:
            llvm::StringRef expr_cstr, llvm::StringRef expr_prefix,
            lldb::ValueObjectSP &result_valobj_sp, Status &error,
            uint32_t line_offset = 0, std::string *fixed_expression = nullptr,
-           lldb::ModuleSP *jit_module_sp_ptr = nullptr);
+           lldb::ModuleSP *jit_module_sp_ptr = nullptr,
+           ValueObject *ctx_obj = nullptr);
 
   static const Status::ValueType kNoResult =
       0x1001; ///< ValueObject::GetError() returns this if there is no result

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Tue Feb  5 01:14:36 2019
@@ -1060,7 +1060,8 @@ public:
   GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix,
                     lldb::LanguageType language,
                     Expression::ResultType desired_type,
-                    const EvaluateExpressionOptions &options) override;
+                    const EvaluateExpressionOptions &options,
+                    ValueObject *ctx_obj) override;
 
   FunctionCaller *GetFunctionCaller(const CompilerType &return_type,
                                     const Address &function_address,

Modified: lldb/trunk/include/lldb/Symbol/TypeSystem.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/TypeSystem.h?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/TypeSystem.h (original)
+++ lldb/trunk/include/lldb/Symbol/TypeSystem.h Tue Feb  5 01:14:36 2019
@@ -449,7 +449,8 @@ public:
   GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix,
                     lldb::LanguageType language,
                     Expression::ResultType desired_type,
-                    const EvaluateExpressionOptions &options) {
+                    const EvaluateExpressionOptions &options,
+                    ValueObject *ctx_obj) {
     return nullptr;
   }
 

Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Tue Feb  5 01:14:36 2019
@@ -1043,7 +1043,8 @@ public:
   UserExpression *GetUserExpressionForLanguage(
       llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
       Expression::ResultType desired_type,
-      const EvaluateExpressionOptions &options, Status &error);
+      const EvaluateExpressionOptions &options,
+      ValueObject *ctx_obj, Status &error);
 
   // Creates a FunctionCaller for the given language, the rest of the
   // parameters have the same meaning as for the FunctionCaller constructor.
@@ -1107,7 +1108,8 @@ public:
       llvm::StringRef expression, ExecutionContextScope *exe_scope,
       lldb::ValueObjectSP &result_valobj_sp,
       const EvaluateExpressionOptions &options = EvaluateExpressionOptions(),
-      std::string *fixed_expression = nullptr);
+      std::string *fixed_expression = nullptr,
+      ValueObject *ctx_obj = nullptr);
 
   lldb::ExpressionVariableSP GetPersistentVariable(const ConstString &name);
 

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/Makefile?rev=353149&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/Makefile Tue Feb  5 01:14:36 2019
@@ -0,0 +1,6 @@
+LEVEL = ../../make
+
+OBJC_SOURCES := main.m
+
+include $(LEVEL)/Makefile.rules
+LDFLAGS += -framework Foundation

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/TestContextObjectObjc.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/TestContextObjectObjc.py?rev=353149&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/TestContextObjectObjc.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/TestContextObjectObjc.py Tue Feb  5 01:14:36 2019
@@ -0,0 +1,78 @@
+"""
+Tests expression evaluation in context of an objc class.
+"""
+
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+
+class ContextObjectObjcTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipUnlessDarwin
+    def test_context_object_objc(self):
+        """Tests expression evaluation in context of an objc class."""
+        self.build()
+
+        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, '// Break here', self.main_source_spec)
+        frame = thread.GetFrameAtIndex(0)
+
+        #
+        # Test objc class variable
+        #
+
+        obj_val = frame.FindVariable("objcClass")
+        self.assertTrue(obj_val.IsValid())
+        obj_val = obj_val.Dereference()
+        self.assertTrue(obj_val.IsValid())
+
+        # Test an empty expression evaluation
+        value = obj_val.EvaluateExpression("")
+        self.assertFalse(value.IsValid())
+        self.assertFalse(value.GetError().Success())
+
+        # Test retrieving of a field (not a local with the same name)
+        value = obj_val.EvaluateExpression("field")
+        self.assertTrue(value.IsValid())
+        self.assertTrue(value.GetError().Success())
+        self.assertEqual(value.GetValueAsSigned(), 1111)
+
+        # Test if the self pointer is properly evaluated
+
+        # Test retrieving of an objcClass's property through the self pointer
+        value = obj_val.EvaluateExpression("self.property")
+        self.assertTrue(value.IsValid())
+        self.assertTrue(value.GetError().Success())
+        self.assertEqual(value.GetValueAsSigned(), 2222)
+
+        # Test objcClass's methods evaluation through the self pointer
+        value = obj_val.EvaluateExpression("[self method]")
+        self.assertTrue(value.IsValid())
+        self.assertTrue(value.GetError().Success())
+        self.assertEqual(value.GetValueAsSigned(), 3333)
+
+        # Test if we can use a computation result reference object correctly
+
+        obj_val = frame.EvaluateExpression("[ObjcClass createNew]")
+        self.assertTrue(obj_val.IsValid())
+        obj_val = obj_val.Dereference()
+        self.assertTrue(obj_val.IsValid())
+
+        # Test an expression evaluation on it
+        value = obj_val.EvaluateExpression("1")
+        self.assertTrue(value.IsValid())
+        self.assertTrue(value.GetError().Success())
+
+        # Test retrieving of a field on it
+        value = obj_val.EvaluateExpression("field")
+        self.assertTrue(value.IsValid())
+        self.assertTrue(value.GetError().Success())
+        self.assertEqual(value.GetValueAsSigned(), 1111)
+
+    def setUp(self):
+        TestBase.setUp(self)
+
+        self.main_source = "main.m"
+        self.main_source_spec = lldb.SBFileSpec(self.main_source)

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/main.m
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/main.m?rev=353149&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/main.m (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object-objc/main.m Tue Feb  5 01:14:36 2019
@@ -0,0 +1,47 @@
+#import <Foundation/Foundation.h>
+
+ at interface ObjcClass : NSObject {
+    int field;
+}
+
+ at property int property;
+
++(ObjcClass*)createNew;
+
+-(id)init;
+
+-(int)method;
+
+ at end
+
+ at implementation ObjcClass
+
++(ObjcClass*)createNew {
+    return [ObjcClass new];
+}
+
+-(id)init {
+    self = [super init];
+    if (self) {
+        field = 1111;
+        _property = 2222;
+    }
+    return self;
+}
+
+-(int)method {
+    return 3333;
+}
+
+ at end
+
+int main()
+{
+    @autoreleasepool {
+        ObjcClass* objcClass = [ObjcClass new];
+        
+        int field = 4444;
+        
+        return 0; // Break here
+    }
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/Makefile?rev=353149&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/Makefile Tue Feb  5 01:14:36 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/TestContextObject.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/TestContextObject.py?rev=353149&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/TestContextObject.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/TestContextObject.py Tue Feb  5 01:14:36 2019
@@ -0,0 +1,145 @@
+"""
+Tests expression evaluation in context of an object.
+"""
+
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class ContextObjectTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    def test_context_object(self):
+        """Tests expression evaluation in context of an object."""
+        self.build()
+
+        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, '// Break here', self.main_source_spec)
+        frame = thread.GetFrameAtIndex(0)
+
+        #
+        # Test C++ struct variable
+        #
+
+        obj_val = frame.FindVariable("cpp_struct")
+        self.assertTrue(obj_val.IsValid())
+
+        # Test an empty expression evaluation
+        value = obj_val.EvaluateExpression("")
+        self.assertFalse(value.IsValid())
+        self.assertFalse(value.GetError().Success())
+
+        # Test retrieveing of a field (not a local with the same name)
+        value = obj_val.EvaluateExpression("field")
+        self.assertTrue(value.IsValid())
+        self.assertTrue(value.GetError().Success())
+        self.assertEqual(value.GetValueAsSigned(), 1111)
+
+        # Test functions evaluation
+        value = obj_val.EvaluateExpression("function()")
+        self.assertTrue(value.IsValid())
+        self.assertTrue(value.GetError().Success())
+        self.assertEqual(value.GetValueAsSigned(), 2222)
+
+        # Test that we retrieve the right global
+        value = obj_val.EvaluateExpression("global.field")
+        self.assertTrue(value.IsValid())
+        self.assertTrue(value.GetError().Success())
+        self.assertEqual(value.GetValueAsSigned(), 1111)
+
+        #
+        # Test C++ union variable
+        #
+
+        obj_val = frame.FindVariable("cpp_union")
+        self.assertTrue(obj_val.IsValid())
+
+        # Test retrieveing of a field
+        value = obj_val.EvaluateExpression("field_int")
+        self.assertTrue(value.IsValid())
+        self.assertTrue(value.GetError().Success())
+        self.assertEqual(value.GetValueAsSigned(), 5555)
+
+        #
+        # Test C++ scalar
+        #
+
+        obj_val = frame.FindVariable("cpp_scalar")
+        self.assertTrue(obj_val.IsValid())
+
+        # Test an expression evaluation
+        value = obj_val.EvaluateExpression("1")
+        self.assertFalse(value.IsValid())
+        self.assertFalse(value.GetError().Success())
+
+        #
+        # Test C++ array
+        #
+
+        obj_val = frame.FindVariable("cpp_array")
+        self.assertTrue(obj_val.IsValid())
+
+        # Test an expression evaluation
+        value = obj_val.EvaluateExpression("1")
+        self.assertFalse(value.IsValid())
+        self.assertFalse(value.GetError().Success())
+
+        # Test retrieveing of an element's field
+        value = obj_val.GetValueForExpressionPath("[7]").EvaluateExpression("field")
+        self.assertTrue(value.IsValid())
+        self.assertTrue(value.GetError().Success())
+        self.assertEqual(value.GetValueAsSigned(), 1111)
+
+        #
+        # Test C++ pointer
+        #
+
+        obj_val = frame.FindVariable("cpp_pointer")
+        self.assertTrue(obj_val.IsValid())
+
+        # Test an expression evaluation
+        value = obj_val.EvaluateExpression("1")
+        self.assertFalse(value.IsValid())
+        self.assertFalse(value.GetError().Success())
+
+        # Test retrieveing of a dereferenced object's field
+        value = obj_val.Dereference().EvaluateExpression("field")
+        self.assertTrue(value.IsValid())
+        self.assertTrue(value.GetError().Success())
+        self.assertEqual(value.GetValueAsSigned(), 1111)
+
+        #
+        # Test C++ computation result
+        #
+
+        obj_val = frame.EvaluateExpression("cpp_namespace::GetCppStruct()")
+        self.assertTrue(obj_val.IsValid())
+
+        # Test an expression evaluation
+        value = obj_val.EvaluateExpression("1")
+        self.assertTrue(value.IsValid())
+        self.assertFalse(value.GetError().Success())
+
+        #
+        # Test C++ computation result located in debuggee memory
+        #
+
+        obj_val = frame.EvaluateExpression("cpp_namespace::GetCppStructPtr()")
+        self.assertTrue(obj_val.IsValid())
+
+        # Test an expression evaluation
+        value = obj_val.EvaluateExpression("1")
+        self.assertFalse(value.IsValid())
+        self.assertFalse(value.GetError().Success())
+
+        # Test retrieveing of a dereferenced object's field
+        value = obj_val.Dereference().EvaluateExpression("field")
+        self.assertTrue(value.IsValid())
+        self.assertTrue(value.GetError().Success())
+        self.assertEqual(value.GetValueAsSigned(), 1111)
+
+    def setUp(self):
+        TestBase.setUp(self)
+
+        self.main_source = "main.cpp"
+        self.main_source_spec = lldb.SBFileSpec(self.main_source)

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/main.cpp?rev=353149&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/context-object/main.cpp Tue Feb  5 01:14:36 2019
@@ -0,0 +1,46 @@
+namespace cpp_namespace {
+  struct CppStruct {
+    int field = 1111;
+
+    int function() {
+      return 2222;
+    }
+  };
+
+  union CppUnion {
+    char field_char;
+    short field_short;
+    int field_int;
+  };
+
+  CppStruct GetCppStruct() {
+    return CppStruct();
+  }
+
+  CppStruct global;
+
+  CppStruct *GetCppStructPtr() {
+    return &global;
+  }
+}
+
+int global = 3333;
+
+int main()
+{
+  cpp_namespace::CppStruct cpp_struct = cpp_namespace::GetCppStruct();
+  cpp_struct.function();
+
+  int field = 4444;
+
+  cpp_namespace::CppUnion cpp_union;
+  cpp_union.field_int = 5555;
+
+  int cpp_scalar = 6666;
+
+  cpp_namespace::CppStruct cpp_array[16];
+
+  cpp_namespace::CppStruct *cpp_pointer = cpp_namespace::GetCppStructPtr();
+
+  return 0; // Break here
+}

Modified: lldb/trunk/scripts/interface/SBValue.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBValue.i?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/scripts/interface/SBValue.i (original)
+++ lldb/trunk/scripts/interface/SBValue.i Tue Feb  5 01:14:36 2019
@@ -448,7 +448,19 @@ public:
     ) GetExpressionPath;
     bool
     GetExpressionPath (lldb::SBStream &description, bool qualify_cxx_base_classes);
-    
+
+    lldb::SBValue
+    EvaluateExpression(const char *expr) const;
+
+    lldb::SBValue
+    EvaluateExpression(const char *expr,
+                       const SBExpressionOptions &options) const;
+
+    lldb::SBValue
+    EvaluateExpression(const char *expr,
+                       const SBExpressionOptions &options,
+                       const char *name) const;
+
     %pythoncode %{
         def __get_dynamic__ (self):
             '''Helper function for the "SBValue.dynamic" property.'''

Modified: lldb/trunk/source/API/SBValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/source/API/SBValue.cpp (original)
+++ lldb/trunk/source/API/SBValue.cpp Tue Feb  5 01:14:36 2019
@@ -1294,6 +1294,87 @@ bool SBValue::GetExpressionPath(SBStream
   return false;
 }
 
+lldb::SBValue SBValue::EvaluateExpression(const char* expr) const {
+  ValueLocker locker;
+  lldb::ValueObjectSP value_sp(GetSP(locker));
+  if (!value_sp)
+    return SBValue();
+
+  lldb::TargetSP target_sp = value_sp->GetTargetSP();
+  if (!target_sp)
+    return SBValue();
+
+  lldb::SBExpressionOptions options;
+  options.SetFetchDynamicValue(target_sp->GetPreferDynamicValue());
+  options.SetUnwindOnError(true);
+  options.SetIgnoreBreakpoints(true);
+
+  return EvaluateExpression(expr, options, nullptr);
+}
+
+lldb::SBValue
+SBValue::EvaluateExpression(const char *expr,
+                            const SBExpressionOptions &options) const {
+  return EvaluateExpression(expr, options, nullptr);
+}
+
+lldb::SBValue SBValue::EvaluateExpression(const char *expr,
+                                          const SBExpressionOptions &options,
+                                          const char *name) const {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+  if (!expr || expr[0] == '\0') {
+    LLDB_LOG(log,
+             "SBValue::EvaluateExpression called with an empty expression");
+    return SBValue();
+  }
+
+  LLDB_LOG(log, "SBValue()::EvaluateExpression (expr=\"{0}\")...", expr);
+
+  ValueLocker locker;
+  lldb::ValueObjectSP value_sp(GetSP(locker));
+  if (!value_sp) {
+    LLDB_LOG(log, "SBValue::EvaluateExpression () => error: could not "
+                  "reconstruct value object for this SBValue");
+    return SBValue();
+  }
+
+  lldb::TargetSP target_sp = value_sp->GetTargetSP();
+  if (!target_sp) {
+    LLDB_LOG(
+        log,
+        "SBValue::EvaluateExpression () => error: could not retrieve target");
+    return SBValue();
+  }
+
+  std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+  ExecutionContext exe_ctx(target_sp.get());
+
+  StackFrame *frame = exe_ctx.GetFramePtr();
+  if (!frame) {
+    LLDB_LOG(log, "SBValue::EvaluateExpression () => error: could not retrieve "
+                  "current stack frame");
+    return SBValue();
+  }
+
+  ValueObjectSP res_val_sp;
+  ExpressionResults expr_res = target_sp->EvaluateExpression(
+      expr, frame, res_val_sp, options.ref(), nullptr, value_sp.get());
+
+  if (name)
+    res_val_sp->SetName(ConstString(name));
+
+  LLDB_LOG(log,
+           "SBValue(Name=\"{0}\")::EvaluateExpression (expr=\"{1}\") => "
+           "SBValue(Success={2}) (execution result={3})",
+           value_sp->GetName(), expr, res_val_sp->GetError().Success(),
+           expr_res);
+
+  SBValue result;
+  result.SetSP(res_val_sp, options.GetFetchDynamicValue());
+  return result;
+}
+
 bool SBValue::GetDescription(SBStream &description) {
   Stream &strm = description.ref();
 

Modified: lldb/trunk/source/Breakpoint/BreakpointLocation.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointLocation.cpp?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointLocation.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointLocation.cpp Tue Feb  5 01:14:36 2019
@@ -255,7 +255,7 @@ bool BreakpointLocation::ConditionSaysSt
 
     m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(
         condition_text, llvm::StringRef(), language, Expression::eResultTypeAny,
-        EvaluateExpressionOptions(), error));
+        EvaluateExpressionOptions(), nullptr, error));
     if (error.Fail()) {
       if (log)
         log->Printf("Error getting condition expression: %s.",

Modified: lldb/trunk/source/Breakpoint/Watchpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/Watchpoint.cpp?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/Watchpoint.cpp (original)
+++ lldb/trunk/source/Breakpoint/Watchpoint.cpp Tue Feb  5 01:14:36 2019
@@ -279,7 +279,8 @@ void Watchpoint::SetCondition(const char
     Status error;
     m_condition_ap.reset(m_target.GetUserExpressionForLanguage(
         condition, llvm::StringRef(), lldb::eLanguageTypeUnknown,
-        UserExpression::eResultTypeAny, EvaluateExpressionOptions(), error));
+        UserExpression::eResultTypeAny, EvaluateExpressionOptions(),
+        nullptr, error));
     if (error.Fail()) {
       // FIXME: Log something...
       m_condition_ap.reset();

Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Tue Feb  5 01:14:36 2019
@@ -363,7 +363,7 @@ int CommandObjectExpression::HandleCompl
   Status error;
   lldb::UserExpressionSP expr(target->GetUserExpressionForLanguage(
       code, llvm::StringRef(), language, UserExpression::eResultTypeAny,
-      options, error));
+      options, nullptr, error));
   if (error.Fail())
     return 0;
 

Modified: lldb/trunk/source/Expression/ExpressionSourceCode.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ExpressionSourceCode.cpp?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ExpressionSourceCode.cpp (original)
+++ lldb/trunk/source/Expression/ExpressionSourceCode.cpp Tue Feb  5 01:14:36 2019
@@ -178,7 +178,8 @@ static void AddLocalVariableDecls(const
 bool ExpressionSourceCode::GetText(std::string &text,
                                    lldb::LanguageType wrapping_language,
                                    bool static_method,
-                                   ExecutionContext &exe_ctx) const {
+                                   ExecutionContext &exe_ctx,
+                                   bool add_locals) const {
   const char *target_specific_defines = "typedef signed char BOOL;\n";
   std::string module_macros;
 
@@ -251,12 +252,13 @@ bool ExpressionSourceCode::GetText(std::
       }
     }
 
-    ConstString object_name;
-    if (Language::LanguageIsCPlusPlus(frame->GetLanguage())) {
-      if (target->GetInjectLocalVariables(&exe_ctx)) {
-        lldb::VariableListSP var_list_sp =
-            frame->GetInScopeVariableList(false, true);
-        AddLocalVariableDecls(var_list_sp, lldb_local_var_decls);
+    if (add_locals) {
+      if (Language::LanguageIsCPlusPlus(frame->GetLanguage())) {
+        if (target->GetInjectLocalVariables(&exe_ctx)) {
+          lldb::VariableListSP var_list_sp =
+              frame->GetInScopeVariableList(false, true);
+          AddLocalVariableDecls(var_list_sp, lldb_local_var_decls);
+        }
       }
     }
   }

Modified: lldb/trunk/source/Expression/UserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/UserExpression.cpp?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/source/Expression/UserExpression.cpp (original)
+++ lldb/trunk/source/Expression/UserExpression.cpp Tue Feb  5 01:14:36 2019
@@ -140,10 +140,22 @@ lldb::ExpressionResults UserExpression::
     ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options,
     llvm::StringRef expr, llvm::StringRef prefix,
     lldb::ValueObjectSP &result_valobj_sp, Status &error, uint32_t line_offset,
-    std::string *fixed_expression, lldb::ModuleSP *jit_module_sp_ptr) {
+    std::string *fixed_expression, lldb::ModuleSP *jit_module_sp_ptr,
+    ValueObject *ctx_obj) {
   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS |
                                                   LIBLLDB_LOG_STEP));
 
+  if (ctx_obj) {
+    static unsigned const ctx_type_mask =
+        lldb::TypeFlags::eTypeIsClass | lldb::TypeFlags::eTypeIsStructUnion;
+    if (!(ctx_obj->GetTypeInfo() & ctx_type_mask)) {
+      LLDB_LOG(log, "== [UserExpression::Evaluate] Passed a context object of "
+                    "an invalid type, can't run expressions.");
+      error.SetErrorString("a context object of an invalid type passed");
+      return lldb::eExpressionSetupError;
+    }
+  }
+
   lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
   lldb::LanguageType language = options.GetLanguage();
   const ResultType desired_type = options.DoesCoerceToId()
@@ -208,7 +220,8 @@ lldb::ExpressionResults UserExpression::
 
   lldb::UserExpressionSP user_expression_sp(
       target->GetUserExpressionForLanguage(expr, full_prefix, language,
-                                           desired_type, options, error));
+                                           desired_type, options, ctx_obj,
+                                           error));
   if (error.Fail()) {
     if (log)
       log->Printf("== [UserExpression::Evaluate] Getting expression: %s ==",
@@ -253,7 +266,8 @@ lldb::ExpressionResults UserExpression::
       lldb::UserExpressionSP fixed_expression_sp(
           target->GetUserExpressionForLanguage(fixed_expression->c_str(),
                                                full_prefix, language,
-                                               desired_type, options, error));
+                                               desired_type, options, ctx_obj,
+                                               error));
       DiagnosticManager fixed_diagnostic_manager;
       parse_success = fixed_expression_sp->Parse(
           fixed_diagnostic_manager, exe_ctx, execution_policy,

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp Tue Feb  5 01:14:36 2019
@@ -65,10 +65,12 @@ const char *g_lldb_local_vars_namespace_
 ClangExpressionDeclMap::ClangExpressionDeclMap(
     bool keep_result_in_memory,
     Materializer::PersistentVariableDelegate *result_delegate,
-    ExecutionContext &exe_ctx)
+    ExecutionContext &exe_ctx,
+    ValueObject *ctx_obj)
     : ClangASTSource(exe_ctx.GetTargetSP()), m_found_entities(),
       m_struct_members(), m_keep_result_in_memory(keep_result_in_memory),
-      m_result_delegate(result_delegate), m_parser_vars(), m_struct_vars() {
+      m_result_delegate(result_delegate), m_parser_vars(), m_struct_vars(),
+      m_ctx_obj(ctx_obj) {
   EnableStructVars();
 }
 
@@ -927,6 +929,21 @@ void ClangExpressionDeclMap::FindExterna
     static ConstString g_lldb_class_name("$__lldb_class");
 
     if (name == g_lldb_class_name) {
+      if (m_ctx_obj) {
+        Status status;
+        lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status);
+        if (!ctx_obj_ptr || status.Fail())
+          return;
+
+        AddThisType(context, TypeFromUser(m_ctx_obj->GetCompilerType()),
+                    current_id);
+
+        m_struct_vars->m_object_pointer_type =
+            TypeFromUser(ctx_obj_ptr->GetCompilerType());
+
+        return;
+      }
+
       // Clang is looking for the type of "this"
 
       if (frame == NULL)
@@ -1019,6 +1036,21 @@ void ClangExpressionDeclMap::FindExterna
 
     static ConstString g_lldb_objc_class_name("$__lldb_objc_class");
     if (name == g_lldb_objc_class_name) {
+      if (m_ctx_obj) {
+        Status status;
+        lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status);
+        if (!ctx_obj_ptr || status.Fail())
+          return;
+
+        AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()),
+                    current_id);
+
+        m_struct_vars->m_object_pointer_type =
+            TypeFromUser(ctx_obj_ptr->GetCompilerType());
+
+        return;
+      }
+
       // Clang is looking for the type of "*self"
 
       if (!frame)
@@ -2124,7 +2156,7 @@ void ClangExpressionDeclMap::AddOneFunct
 }
 
 void ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
-                                         TypeFromUser &ut,
+                                         const TypeFromUser &ut,
                                          unsigned int current_id) {
   CompilerType copied_clang_type = GuardedCopyType(ut);
 
@@ -2198,7 +2230,7 @@ void ClangExpressionDeclMap::AddThisType
 }
 
 void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
-                                        TypeFromUser &ut,
+                                        const TypeFromUser &ut,
                                         unsigned int current_id) {
   CompilerType copied_clang_type = GuardedCopyType(ut);
 

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h Tue Feb  5 01:14:36 2019
@@ -72,11 +72,16 @@ public:
   ///
   /// @param[in] exe_ctx
   ///     The execution context to use when parsing.
+  ///
+  /// @param[in] ctx_obj
+  ///     If not empty, then expression is evaluated in context of this object.
+  ///     See the comment to `UserExpression::Evaluate` for details.
   //------------------------------------------------------------------
   ClangExpressionDeclMap(
       bool keep_result_in_memory,
       Materializer::PersistentVariableDelegate *result_delegate,
-      ExecutionContext &exe_ctx);
+      ExecutionContext &exe_ctx,
+      ValueObject *ctx_obj);
 
   //------------------------------------------------------------------
   /// Destructor
@@ -343,6 +348,10 @@ private:
   Materializer::PersistentVariableDelegate
       *m_result_delegate; ///< If non-NULL, used to report expression results to
                           ///ClangUserExpression.
+  ValueObject *m_ctx_obj; ///< If not empty, then expression is
+                          ///evaluated in context of this object.
+                          ///For details see the comment to
+                          ///`UserExpression::Evaluate`.
 
   //----------------------------------------------------------------------
   /// The following values should not live beyond parsing
@@ -581,7 +590,7 @@ private:
   /// @param[in] type
   ///     The type that needs to be created.
   //------------------------------------------------------------------
-  void AddOneType(NameSearchContext &context, TypeFromUser &type,
+  void AddOneType(NameSearchContext &context, const TypeFromUser &type,
                   unsigned int current_id);
 
   //------------------------------------------------------------------
@@ -594,7 +603,7 @@ private:
   /// @param[in] type
   ///     The type for *this.
   //------------------------------------------------------------------
-  void AddThisType(NameSearchContext &context, TypeFromUser &type,
+  void AddThisType(NameSearchContext &context, const TypeFromUser &type,
                    unsigned int current_id);
 
   //------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp Tue Feb  5 01:14:36 2019
@@ -59,13 +59,15 @@ using namespace lldb_private;
 ClangUserExpression::ClangUserExpression(
     ExecutionContextScope &exe_scope, llvm::StringRef expr,
     llvm::StringRef prefix, lldb::LanguageType language,
-    ResultType desired_type, const EvaluateExpressionOptions &options)
+    ResultType desired_type, const EvaluateExpressionOptions &options,
+    ValueObject *ctx_obj)
     : LLVMUserExpression(exe_scope, expr, prefix, language, desired_type,
                          options),
       m_type_system_helper(*m_target_wp.lock().get(),
                            options.GetExecutionPolicy() ==
                                eExecutionPolicyTopLevel),
-      m_result_delegate(exe_scope.CalculateTarget()) {
+      m_result_delegate(exe_scope.CalculateTarget()),
+      m_ctx_obj(ctx_obj) {
   switch (m_language) {
   case lldb::eLanguageTypeC_plus_plus:
     m_allow_cxx = true;
@@ -130,7 +132,27 @@ void ClangUserExpression::ScanContext(Ex
     return;
   }
 
-  if (clang::CXXMethodDecl *method_decl =
+  if (m_ctx_obj) {
+    switch (m_ctx_obj->GetObjectRuntimeLanguage()) {
+    case lldb::eLanguageTypeC:
+    case lldb::eLanguageTypeC89:
+    case lldb::eLanguageTypeC99:
+    case lldb::eLanguageTypeC11:
+    case lldb::eLanguageTypeC_plus_plus:
+    case lldb::eLanguageTypeC_plus_plus_03:
+    case lldb::eLanguageTypeC_plus_plus_11:
+    case lldb::eLanguageTypeC_plus_plus_14:
+      m_in_cplusplus_method = true;
+      break;
+    case lldb::eLanguageTypeObjC:
+    case lldb::eLanguageTypeObjC_plus_plus:
+      m_in_objectivec_method = true;
+      break;
+    default:
+      break;
+    }
+    m_needs_object_ptr = true;
+  } else if (clang::CXXMethodDecl *method_decl =
           ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context)) {
     if (m_allow_cxx && method_decl->isInstance()) {
       if (m_enforce_valid_object) {
@@ -396,7 +418,8 @@ void ClangUserExpression::UpdateLanguage
       m_expr_lang = lldb::eLanguageTypeC;
 
     if (!source_code->GetText(m_transformed_text, m_expr_lang,
-                              m_in_static_method, exe_ctx)) {
+                              m_in_static_method, exe_ctx,
+                              !m_ctx_obj)) {
       diagnostic_manager.PutString(eDiagnosticSeverityError,
                                    "couldn't construct expression body");
       return;
@@ -733,7 +756,15 @@ bool ClangUserExpression::AddArguments(E
 
     Status object_ptr_error;
 
-    object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
+    if (m_ctx_obj) {
+      AddressType address_type;
+      object_ptr = m_ctx_obj->GetAddressOf(false, &address_type);
+      if (object_ptr == LLDB_INVALID_ADDRESS ||
+          address_type != eAddressTypeLoad)
+        object_ptr_error.SetErrorString("Can't get context object's "
+                                        "debuggee address");
+    } else
+      object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
 
     if (!object_ptr_error.Success()) {
       exe_ctx.GetTargetRef().GetDebugger().GetAsyncOutputStream()->Printf(
@@ -776,9 +807,11 @@ lldb::ExpressionVariableSP ClangUserExpr
 void ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(
     ExecutionContext &exe_ctx,
     Materializer::PersistentVariableDelegate &delegate,
-    bool keep_result_in_memory) {
+    bool keep_result_in_memory,
+    ValueObject *ctx_obj) {
   m_expr_decl_map_up.reset(
-      new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx));
+      new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx,
+                                 ctx_obj));
 }
 
 clang::ASTConsumer *

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h Tue Feb  5 01:14:36 2019
@@ -61,7 +61,8 @@ public:
 
     void ResetDeclMap(ExecutionContext &exe_ctx,
                       Materializer::PersistentVariableDelegate &result_delegate,
-                      bool keep_result_in_memory);
+                      bool keep_result_in_memory,
+                      ValueObject *ctx_obj);
 
     //------------------------------------------------------------------
     /// Return the object that the parser should allow to access ASTs. May be
@@ -105,11 +106,17 @@ public:
   /// @param[in] desired_type
   ///     If not eResultTypeAny, the type to use for the expression
   ///     result.
+  ///
+  /// @param[in] ctx_obj
+  ///     The object (if any) in which context the expression
+  ///     must be evaluated. For details see the comment to
+  ///     `UserExpression::Evaluate`.
   //------------------------------------------------------------------
   ClangUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
                       llvm::StringRef prefix, lldb::LanguageType language,
                       ResultType desired_type,
-                      const EvaluateExpressionOptions &options);
+                      const EvaluateExpressionOptions &options,
+                      ValueObject *ctx_obj);
 
   ~ClangUserExpression() override;
 
@@ -153,7 +160,8 @@ public:
                     Materializer::PersistentVariableDelegate &result_delegate,
                     bool keep_result_in_memory) {
     m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate,
-                                      keep_result_in_memory);
+                                      keep_result_in_memory,
+                                      m_ctx_obj);
   }
 
   lldb::ExpressionVariableSP
@@ -204,6 +212,10 @@ private:
   /// were not able to calculate this position.
   llvm::Optional<size_t> m_user_expression_start_pos;
   ResultDelegate m_result_delegate;
+
+  /// The object (if any) in which context the expression is evaluated.
+  /// See the comment to `UserExpression::Evaluate` for details.
+  ValueObject *m_ctx_obj;
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp Tue Feb  5 01:14:36 2019
@@ -156,5 +156,6 @@ bool ClangUtilityFunction::Install(Diagn
 void ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(
     ExecutionContext &exe_ctx, bool keep_result_in_memory) {
   m_expr_decl_map_up.reset(
-      new ClangExpressionDeclMap(keep_result_in_memory, nullptr, exe_ctx));
+      new ClangExpressionDeclMap(keep_result_in_memory, nullptr, exe_ctx,
+                                 nullptr));
 }

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Tue Feb  5 01:14:36 2019
@@ -10317,13 +10317,14 @@ ClangASTContextForExpressions::ClangASTC
 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(

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=353149&r1=353148&r2=353149&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Tue Feb  5 01:14:36 2019
@@ -2199,7 +2199,8 @@ Target::GetPersistentExpressionStateForL
 UserExpression *Target::GetUserExpressionForLanguage(
     llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
     Expression::ResultType desired_type,
-    const EvaluateExpressionOptions &options, Status &error) {
+    const EvaluateExpressionOptions &options,
+    ValueObject *ctx_obj, Status &error) {
   Status type_system_error;
 
   TypeSystem *type_system =
@@ -2215,7 +2216,7 @@ UserExpression *Target::GetUserExpressio
   }
 
   user_expr = type_system->GetUserExpression(expr, prefix, language,
-                                             desired_type, options);
+                                             desired_type, options, ctx_obj);
   if (!user_expr)
     error.SetErrorStringWithFormat(
         "Could not create an expression for language %s",
@@ -2356,7 +2357,8 @@ Target *Target::GetTargetFromContexts(co
 ExpressionResults Target::EvaluateExpression(
     llvm::StringRef expr, ExecutionContextScope *exe_scope,
     lldb::ValueObjectSP &result_valobj_sp,
-    const EvaluateExpressionOptions &options, std::string *fixed_expression) {
+    const EvaluateExpressionOptions &options, std::string *fixed_expression,
+    ValueObject *ctx_obj) {
   result_valobj_sp.reset();
 
   ExpressionResults execution_results = eExpressionSetupError;
@@ -2397,7 +2399,9 @@ ExpressionResults Target::EvaluateExpres
     execution_results = UserExpression::Evaluate(exe_ctx, options, expr, prefix,
                                                  result_valobj_sp, error,
                                                  0, // Line Number
-                                                 fixed_expression);
+                                                 fixed_expression,
+                                                 nullptr, // Module
+                                                 ctx_obj);
   }
 
   m_suppress_stop_hooks = old_suppress_value;




More information about the lldb-commits mailing list