[Lldb-commits] [lldb] r247720 - This patch makes Clang-independent base classes for all the expression types that lldb currently vends.

Jim Ingham via lldb-commits lldb-commits at lists.llvm.org
Tue Sep 15 14:13:51 PDT 2015


Author: jingham
Date: Tue Sep 15 16:13:50 2015
New Revision: 247720

URL: http://llvm.org/viewvc/llvm-project?rev=247720&view=rev
Log:
This patch makes Clang-independent base classes for all the expression types that lldb currently vends. 

Before we had:

ClangFunction
ClangUtilityFunction
ClangUserExpression

and code all over in lldb that explicitly made Clang-based expressions. This patch adds an Expression 
base class, and three pure virtual implementations for the Expression kinds:

FunctionCaller
UtilityFunction
UserExpression

You can request one of these expression types from the Target using the Get<ExpressionType>ForLanguage. 
The Target will then consult all the registered TypeSystem plugins, and if the type system that matches 
the language can make an expression of that kind, it will do so and return it.

Because all of the real expression types need to communicate with their ExpressionParser in a uniform way, 
I also added a ExpressionTypeSystemHelper class that expressions generically can vend, and a ClangExpressionHelper 
that encapsulates the operations that the ClangExpressionParser needs to perform on the ClangExpression types. 
Then each of the Clang* expression kinds constructs the appropriate helper to do what it needs.

The patch also fixes a wart in the UtilityFunction that to use it you had to create a parallel FunctionCaller 
to actually call the function made by the UtilityFunction. Now the UtilityFunction can be asked to vend a 
FunctionCaller that will run its function. This cleaned up a lot of boiler plate code using UtilityFunctions.

Note, in this patch all the expression types explicitly depend on the LLVM JIT and IR, and all the common 
JIT running code is in the FunctionCaller etc base classes. At some point we could also abstract that dependency 
but I don't see us adding another back end in the near term, so I'll leave that exercise till it is actually necessary.


Added:
    lldb/trunk/include/lldb/Expression/ClangExpressionHelper.h
      - copied, changed from r247353, lldb/trunk/include/lldb/Expression/ClangExpression.h
    lldb/trunk/include/lldb/Expression/ClangFunctionCaller.h
      - copied, changed from r247584, lldb/trunk/include/lldb/Expression/ClangFunction.h
    lldb/trunk/include/lldb/Expression/Expression.h
    lldb/trunk/include/lldb/Expression/ExpressionParser.h
    lldb/trunk/include/lldb/Expression/ExpressionTypeSystemHelper.h
    lldb/trunk/include/lldb/Expression/FunctionCaller.h
    lldb/trunk/include/lldb/Expression/UserExpression.h
    lldb/trunk/include/lldb/Expression/UtilityFunction.h
    lldb/trunk/source/Expression/ClangFunctionCaller.cpp
      - copied, changed from r247584, lldb/trunk/source/Expression/ClangFunction.cpp
    lldb/trunk/source/Expression/Expression.cpp
    lldb/trunk/source/Expression/FunctionCaller.cpp
    lldb/trunk/source/Expression/UserExpression.cpp
    lldb/trunk/source/Expression/UtilityFunction.cpp
Removed:
    lldb/trunk/include/lldb/Expression/ClangExpression.h
    lldb/trunk/include/lldb/Expression/ClangFunction.h
    lldb/trunk/source/Expression/ClangFunction.cpp
Modified:
    lldb/trunk/include/lldb/Breakpoint/BreakpointLocation.h
    lldb/trunk/include/lldb/Breakpoint/Watchpoint.h
    lldb/trunk/include/lldb/Expression/ASTStructExtractor.h
    lldb/trunk/include/lldb/Expression/ClangExpressionParser.h
    lldb/trunk/include/lldb/Expression/ClangUserExpression.h
    lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h
    lldb/trunk/include/lldb/Expression/IRDynamicChecks.h
    lldb/trunk/include/lldb/Expression/IRExecutionUnit.h
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/include/lldb/Symbol/TypeSystem.h
    lldb/trunk/include/lldb/Target/LanguageRuntime.h
    lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/include/lldb/Target/Target.h
    lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h
    lldb/trunk/include/lldb/Target/ThreadPlanCallUserExpression.h
    lldb/trunk/include/lldb/lldb-forward.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/API/SBFrame.cpp
    lldb/trunk/source/Breakpoint/BreakpointLocation.cpp
    lldb/trunk/source/Breakpoint/BreakpointOptions.cpp
    lldb/trunk/source/Breakpoint/Watchpoint.cpp
    lldb/trunk/source/Breakpoint/WatchpointOptions.cpp
    lldb/trunk/source/Commands/CommandObjectArgs.cpp
    lldb/trunk/source/Commands/CommandObjectExpression.cpp
    lldb/trunk/source/DataFormatters/VectorType.cpp
    lldb/trunk/source/Expression/ASTStructExtractor.cpp
    lldb/trunk/source/Expression/CMakeLists.txt
    lldb/trunk/source/Expression/ClangASTSource.cpp
    lldb/trunk/source/Expression/ClangExpressionParser.cpp
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Expression/ClangUtilityFunction.cpp
    lldb/trunk/source/Expression/IRDynamicChecks.cpp
    lldb/trunk/source/Plugins/Language/ObjC/CoreMedia.cpp
    lldb/trunk/source/Plugins/Language/ObjC/NSArray.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
    lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
    lldb/trunk/source/Symbol/ClangASTContext.cpp
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/source/Target/StopInfo.cpp
    lldb/trunk/source/Target/Target.cpp
    lldb/trunk/source/Target/ThreadPlanCallUserExpression.cpp

Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointLocation.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointLocation.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointLocation.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointLocation.h Tue Sep 15 16:13:50 2015
@@ -74,6 +74,9 @@ public:
     //------------------------------------------------------------------
     Breakpoint &
     GetBreakpoint ();
+    
+    Target &
+    GetTarget();
 
     //------------------------------------------------------------------
     /// Determines whether we should stop due to a hit at this
@@ -458,7 +461,7 @@ private:
     Breakpoint &m_owner; ///< The breakpoint that produced this object.
     std::unique_ptr<BreakpointOptions> m_options_ap; ///< Breakpoint options pointer, NULL if we're using our breakpoint's options.
     lldb::BreakpointSiteSP m_bp_site_sp; ///< Our breakpoint site (it may be shared by more than one location.)
-    lldb::ClangUserExpressionSP m_user_expression_sp; ///< The compiled expression to use in testing our condition.
+    lldb::UserExpressionSP m_user_expression_sp; ///< The compiled expression to use in testing our condition.
     Mutex m_condition_mutex; ///< Guards parsing and evaluation of the condition, which could be evaluated by multiple processes.
     size_t m_condition_hash; ///< For testing whether the condition source code changed.
 

Modified: lldb/trunk/include/lldb/Breakpoint/Watchpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/Watchpoint.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/Watchpoint.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/Watchpoint.h Tue Sep 15 16:13:50 2015
@@ -243,7 +243,7 @@ private:
                                        // the callback machinery.
     bool        m_being_created;
 
-    std::unique_ptr<ClangUserExpression> m_condition_ap;  // The condition to test.
+    std::unique_ptr<UserExpression> m_condition_ap;  // The condition to test.
 
     void SetID(lldb::watch_id_t id) { m_loc_id = id; }
     

Modified: lldb/trunk/include/lldb/Expression/ASTStructExtractor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ASTStructExtractor.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ASTStructExtractor.h (original)
+++ lldb/trunk/include/lldb/Expression/ASTStructExtractor.h Tue Sep 15 16:13:50 2015
@@ -13,7 +13,7 @@
 #include "clang/Sema/SemaConsumer.h"
 #include "lldb/Core/ClangForward.h"
 #include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
-#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/ClangFunctionCaller.h"
 
 namespace lldb_private {
     
@@ -21,9 +21,9 @@ namespace lldb_private {
 /// @class ASTStructExtractor ASTStructExtractor.h "lldb/Expression/ASTStructExtractor.h"
 /// @brief Extracts and describes the argument structure for a wrapped function.
 ///
-/// This pass integrates with ClangFunction, which calls functions with custom
+/// This pass integrates with ClangFunctionCaller, which calls functions with custom
 /// sets of arguments.  To avoid having to implement the full calling convention
-/// for the target's architecture, ClangFunction writes a simple wrapper
+/// for the target's architecture, ClangFunctionCaller writes a simple wrapper
 /// function that takes a pointer to an argument structure that contains room
 /// for the address of the function to be called, the values of all its
 /// arguments, and room for the function's return value.
@@ -49,12 +49,12 @@ public:
     ///
     /// @param[in] function
     ///     The caller object whose members should be populated with information
-    ///     about the argument struct.  ClangFunction friends ASTStructExtractor
+    ///     about the argument struct.  ClangFunctionCaller friends ASTStructExtractor
     ///     for this purpose.
     //----------------------------------------------------------------------
     ASTStructExtractor(clang::ASTConsumer *passthrough,
                        const char *struct_name,
-                       ClangFunction &function);
+                       ClangFunctionCaller &function);
     
     //----------------------------------------------------------------------
     /// Destructor
@@ -148,7 +148,7 @@ private:
     clang::Sema                    *m_sema;                 ///< The Sema to use.
     clang::Action                  *m_action;               ///< The Sema to use, cast to an Action so it's usable.
     
-    ClangFunction                  &m_function;             ///< The function to populate with information about the argument structure.
+    ClangFunctionCaller            &m_function;             ///< The function to populate with information about the argument structure.
     std::string                     m_struct_name;          ///< The name of the structure to extract.
 };
     

Removed: lldb/trunk/include/lldb/Expression/ClangExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpression.h?rev=247719&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpression.h (removed)
@@ -1,153 +0,0 @@
-//===-- ClangExpression.h ---------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ClangExpression_h_
-#define liblldb_ClangExpression_h_
-
-// C Includes
-// C++ Includes
-#include <string>
-#include <map>
-#include <vector>
-
-// Other libraries and framework includes
-// Project includes
-
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
-#include "lldb/Core/ClangForward.h"
-#include "lldb/Target/Process.h"
-
-namespace lldb_private {
-
-class RecordingMemoryManager;
-
-//----------------------------------------------------------------------
-/// @class ClangExpression ClangExpression.h "lldb/Expression/ClangExpression.h"
-/// @brief Encapsulates a single expression for use with Clang
-///
-/// LLDB uses expressions for various purposes, notably to call functions
-/// and as a backend for the expr command.  ClangExpression encapsulates
-/// the objects needed to parse and interpret or JIT an expression.  It
-/// uses the Clang parser to produce LLVM IR from the expression.
-//----------------------------------------------------------------------
-class ClangExpression
-{
-public:
-    enum ResultType {
-        eResultTypeAny,
-        eResultTypeId
-    };
-    
-    ClangExpression () :
-        m_jit_process_wp(),
-        m_jit_start_addr (LLDB_INVALID_ADDRESS),
-        m_jit_end_addr (LLDB_INVALID_ADDRESS)
-    {
-    }
-
-    //------------------------------------------------------------------
-    /// Destructor
-    //------------------------------------------------------------------
-    virtual ~ClangExpression ()
-    {
-    }
-    
-    //------------------------------------------------------------------
-    /// Return the string that the parser should parse.  Must be a full
-    /// translation unit.
-    //------------------------------------------------------------------
-    virtual const char *
-    Text () = 0;
-    
-    //------------------------------------------------------------------
-    /// Return the function name that should be used for executing the
-    /// expression.  Text() should contain the definition of this
-    /// function.
-    //------------------------------------------------------------------
-    virtual const char *
-    FunctionName () = 0;
-    
-    //------------------------------------------------------------------
-    /// Return the language that should be used when parsing.  To use
-    /// the default, return eLanguageTypeUnknown.
-    //------------------------------------------------------------------
-    virtual lldb::LanguageType
-    Language ()
-    {
-        return lldb::eLanguageTypeUnknown;
-    }
-    
-    //------------------------------------------------------------------
-    /// Return the object that the parser should use when resolving external
-    /// values.  May be NULL if everything should be self-contained.
-    //------------------------------------------------------------------
-    virtual ClangExpressionDeclMap *
-    DeclMap () = 0;
-    
-    //------------------------------------------------------------------
-    /// Return the object that the parser should allow to access ASTs.
-    /// May be NULL if the ASTs do not need to be transformed.
-    ///
-    /// @param[in] passthrough
-    ///     The ASTConsumer that the returned transformer should send
-    ///     the ASTs to after transformation.
-    //------------------------------------------------------------------
-    virtual clang::ASTConsumer *
-    ASTTransformer (clang::ASTConsumer *passthrough) = 0;
-    
-    //------------------------------------------------------------------
-    /// Return the desired result type of the function, or 
-    /// eResultTypeAny if indifferent.
-    //------------------------------------------------------------------
-    virtual ResultType
-    DesiredResultType ()
-    {
-        return eResultTypeAny;
-    }
-    
-    //------------------------------------------------------------------
-    /// Flags
-    //------------------------------------------------------------------
-    
-    //------------------------------------------------------------------
-    /// Return true if validation code should be inserted into the
-    /// expression.
-    //------------------------------------------------------------------
-    virtual bool
-    NeedsValidation () = 0;
-    
-    //------------------------------------------------------------------
-    /// Return true if external variables in the expression should be
-    /// resolved.
-    //------------------------------------------------------------------
-    virtual bool
-    NeedsVariableResolution () = 0;
-
-    //------------------------------------------------------------------
-    /// Return the address of the function's JIT-compiled code, or
-    /// LLDB_INVALID_ADDRESS if the function is not JIT compiled
-    //------------------------------------------------------------------
-    lldb::addr_t
-    StartAddress ()
-    {
-        return m_jit_start_addr;
-    }
-
-protected:
-
-    lldb::ProcessWP m_jit_process_wp;
-    lldb::addr_t    m_jit_start_addr;       ///< The address of the JITted function within the JIT allocation.  LLDB_INVALID_ADDRESS if invalid.
-    lldb::addr_t    m_jit_end_addr;         ///< The address of the JITted function within the JIT allocation.  LLDB_INVALID_ADDRESS if invalid.
-
-};
-
-} // namespace lldb_private
-
-#endif  // liblldb_ClangExpression_h_

Copied: lldb/trunk/include/lldb/Expression/ClangExpressionHelper.h (from r247353, lldb/trunk/include/lldb/Expression/ClangExpression.h)
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionHelper.h?p2=lldb/trunk/include/lldb/Expression/ClangExpressionHelper.h&p1=lldb/trunk/include/lldb/Expression/ClangExpression.h&r1=247353&r2=247720&rev=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionHelper.h Tue Sep 15 16:13:50 2015
@@ -22,66 +22,33 @@
 #include "lldb/lldb-forward.h"
 #include "lldb/lldb-private.h"
 #include "lldb/Core/ClangForward.h"
-#include "lldb/Target/Process.h"
+#include "lldb/Expression/ExpressionTypeSystemHelper.h"
 
 namespace lldb_private {
 
 class RecordingMemoryManager;
 
 //----------------------------------------------------------------------
-/// @class ClangExpression ClangExpression.h "lldb/Expression/ClangExpression.h"
-/// @brief Encapsulates a single expression for use with Clang
-///
-/// LLDB uses expressions for various purposes, notably to call functions
-/// and as a backend for the expr command.  ClangExpression encapsulates
-/// the objects needed to parse and interpret or JIT an expression.  It
-/// uses the Clang parser to produce LLVM IR from the expression.
+// ClangExpressionHelper
 //----------------------------------------------------------------------
-class ClangExpression
+class ClangExpressionHelper : public ExpressionTypeSystemHelper
 {
 public:
-    enum ResultType {
-        eResultTypeAny,
-        eResultTypeId
-    };
-    
-    ClangExpression () :
-        m_jit_process_wp(),
-        m_jit_start_addr (LLDB_INVALID_ADDRESS),
-        m_jit_end_addr (LLDB_INVALID_ADDRESS)
+    static bool classof(const ExpressionTypeSystemHelper *ts)
     {
+        return ts->getKind() == eKindClangHelper;
     }
 
-    //------------------------------------------------------------------
-    /// Destructor
-    //------------------------------------------------------------------
-    virtual ~ClangExpression ()
+    ClangExpressionHelper () :
+        ExpressionTypeSystemHelper(ExpressionTypeSystemHelper::LLVMCastKind::eKindClangHelper)
     {
     }
-    
-    //------------------------------------------------------------------
-    /// Return the string that the parser should parse.  Must be a full
-    /// translation unit.
-    //------------------------------------------------------------------
-    virtual const char *
-    Text () = 0;
-    
-    //------------------------------------------------------------------
-    /// Return the function name that should be used for executing the
-    /// expression.  Text() should contain the definition of this
-    /// function.
-    //------------------------------------------------------------------
-    virtual const char *
-    FunctionName () = 0;
-    
+
     //------------------------------------------------------------------
-    /// Return the language that should be used when parsing.  To use
-    /// the default, return eLanguageTypeUnknown.
+    /// Destructor
     //------------------------------------------------------------------
-    virtual lldb::LanguageType
-    Language ()
+    virtual ~ClangExpressionHelper ()
     {
-        return lldb::eLanguageTypeUnknown;
     }
     
     //------------------------------------------------------------------
@@ -102,50 +69,9 @@ public:
     virtual clang::ASTConsumer *
     ASTTransformer (clang::ASTConsumer *passthrough) = 0;
     
-    //------------------------------------------------------------------
-    /// Return the desired result type of the function, or 
-    /// eResultTypeAny if indifferent.
-    //------------------------------------------------------------------
-    virtual ResultType
-    DesiredResultType ()
-    {
-        return eResultTypeAny;
-    }
-    
-    //------------------------------------------------------------------
-    /// Flags
-    //------------------------------------------------------------------
-    
-    //------------------------------------------------------------------
-    /// Return true if validation code should be inserted into the
-    /// expression.
-    //------------------------------------------------------------------
-    virtual bool
-    NeedsValidation () = 0;
-    
-    //------------------------------------------------------------------
-    /// Return true if external variables in the expression should be
-    /// resolved.
-    //------------------------------------------------------------------
-    virtual bool
-    NeedsVariableResolution () = 0;
-
-    //------------------------------------------------------------------
-    /// Return the address of the function's JIT-compiled code, or
-    /// LLDB_INVALID_ADDRESS if the function is not JIT compiled
-    //------------------------------------------------------------------
-    lldb::addr_t
-    StartAddress ()
-    {
-        return m_jit_start_addr;
-    }
 
 protected:
 
-    lldb::ProcessWP m_jit_process_wp;
-    lldb::addr_t    m_jit_start_addr;       ///< The address of the JITted function within the JIT allocation.  LLDB_INVALID_ADDRESS if invalid.
-    lldb::addr_t    m_jit_end_addr;         ///< The address of the JITted function within the JIT allocation.  LLDB_INVALID_ADDRESS if invalid.
-
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionParser.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionParser.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionParser.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionParser.h Tue Sep 15 16:13:50 2015
@@ -14,6 +14,7 @@
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/ClangForward.h"
 #include "lldb/Core/Error.h"
+#include "lldb/Expression/ExpressionParser.h"
 #include "lldb/Expression/IRForTarget.h"
 
 #include <string>
@@ -34,7 +35,7 @@ class IRExecutionUnit;
 /// conversion to formats (DWARF bytecode, or JIT compiled machine code)
 /// that can be executed.
 //----------------------------------------------------------------------
-class ClangExpressionParser
+class ClangExpressionParser : public ExpressionParser
 {
 public:
     //------------------------------------------------------------------
@@ -51,13 +52,13 @@ public:
     ///     The expression to be parsed.
     //------------------------------------------------------------------
     ClangExpressionParser (ExecutionContextScope *exe_scope,
-                           ClangExpression &expr,
+                           Expression &expr,
                            bool generate_debug_info);
     
     //------------------------------------------------------------------
     /// Destructor
     //------------------------------------------------------------------
-    ~ClangExpressionParser ();
+    ~ClangExpressionParser () override;
     
     //------------------------------------------------------------------
     /// Parse a single expression and convert it to IR using Clang.  Don't
@@ -71,7 +72,7 @@ public:
     ///     success.
     //------------------------------------------------------------------
     unsigned
-    Parse (Stream &stream);
+    Parse (Stream &stream) override;
     
     //------------------------------------------------------------------
     /// Ready an already-parsed expression for execution, possibly
@@ -116,30 +117,9 @@ public:
                          std::shared_ptr<IRExecutionUnit> &execution_unit_sp,
                          ExecutionContext &exe_ctx,
                          bool &can_interpret,
-                         lldb_private::ExecutionPolicy execution_policy);
+                         lldb_private::ExecutionPolicy execution_policy) override;
         
-    //------------------------------------------------------------------
-    /// Disassemble the machine code for a JITted function from the target 
-    /// process's memory and print the result to a stream.
-    ///
-    /// @param[in] stream
-    ///     The stream to print disassembly to.
-    ///
-    /// @param[in] exc_context
-    ///     The execution context to get the machine code from.
-    ///
-    /// @return
-    ///     The error generated.  If .Success() is true, disassembly succeeded.
-    //------------------------------------------------------------------
-    Error
-    DisassembleFunction (Stream &stream, 
-                         ExecutionContext &exe_ctx);
-    
-    bool
-    GetGenerateDebugInfo () const;
-    
 private:
-    ClangExpression &                       m_expr;                 ///< The expression to be parsed
     std::unique_ptr<llvm::LLVMContext>       m_llvm_context;         ///< The LLVM context to generate IR into
     std::unique_ptr<clang::FileManager>      m_file_manager;         ///< The Clang file manager object used by the compiler
     std::unique_ptr<clang::CompilerInstance> m_compiler;             ///< The Clang compiler used to parse expressions into IR

Removed: lldb/trunk/include/lldb/Expression/ClangFunction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangFunction.h?rev=247719&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangFunction.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangFunction.h (removed)
@@ -1,450 +0,0 @@
-//===-- ClangFunction.h -----------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ClangFunction_h_
-#define liblldb_ClangFunction_h_
-
-// C Includes
-// C++ Includes
-#include <vector>
-#include <list>
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ClangForward.h"
-#include "lldb/Core/Address.h"
-#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/Value.h"
-#include "lldb/Core/ValueObjectList.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Target/Process.h"
-
-namespace lldb_private
-{
-    
-class ASTStructExtractor;
-class ClangExpressionParser;
-
-//----------------------------------------------------------------------
-/// @class ClangFunction ClangFunction.h "lldb/Expression/ClangFunction.h"
-/// @brief Encapsulates a function that can be called.
-///
-/// A given ClangFunction object can handle a single function signature.
-/// Once constructed, it can set up any number of concurrent calls to
-/// functions with that signature.
-///
-/// It performs the call by synthesizing a structure that contains the pointer
-/// to the function and the arguments that should be passed to that function,
-/// and producing a special-purpose JIT-compiled function that accepts a void*
-/// pointing to this struct as its only argument and calls the function in the 
-/// struct with the written arguments.  This method lets Clang handle the
-/// vagaries of function calling conventions.
-///
-/// The simplest use of the ClangFunction is to construct it with a
-/// function representative of the signature you want to use, then call
-/// ExecuteFunction(ExecutionContext &, Stream &, Value &).
-///
-/// If you need to reuse the arguments for several calls, you can call
-/// InsertFunction() followed by WriteFunctionArguments(), which will return
-/// the location of the args struct for the wrapper function in args_addr_ref.
-///
-/// If you need to call the function on the thread plan stack, you can also 
-/// call InsertFunction() followed by GetThreadPlanToCallFunction().
-///
-/// Any of the methods that take arg_addr_ptr or arg_addr_ref can be passed
-/// a pointer set to LLDB_INVALID_ADDRESS and new structure will be allocated
-/// and its address returned in that variable.
-/// 
-/// Any of the methods that take arg_addr_ptr can be passed NULL, and the
-/// argument space will be managed for you.
-//----------------------------------------------------------------------    
-class ClangFunction : public ClangExpression
-{
-    friend class ASTStructExtractor;
-public:
-    //------------------------------------------------------------------
-    /// Constructor
-    ///
-    /// @param[in] exe_scope
-    ///     An execution context scope that gets us at least a target and 
-    ///     process.
-    ///
-    /// @param[in] function_ptr
-    ///     The default function to be called.  Can be overridden using
-    ///     WriteFunctionArguments().
-    ///
-    /// @param[in] ast_context
-    ///     The AST context to evaluate argument types in.
-    ///
-    /// @param[in] arg_value_list
-    ///     The default values to use when calling this function.  Can
-    ///     be overridden using WriteFunctionArguments().
-    //------------------------------------------------------------------  
-    ClangFunction (ExecutionContextScope &exe_scope,
-                   Function &function_ptr, 
-                   ClangASTContext *ast_context, 
-                   const ValueList &arg_value_list,
-                   const char *name);
-    
-    //------------------------------------------------------------------
-    /// Constructor
-    ///
-    /// @param[in] exe_scope
-    ///     An execution context scope that gets us at least a target and 
-    ///     process.
-    ///
-    /// @param[in] ast_context
-    ///     The AST context to evaluate argument types in.
-    ///
-    /// @param[in] return_qualtype
-    ///     An opaque Clang QualType for the function result.  Should be
-    ///     defined in ast_context.
-    ///
-    /// @param[in] function_address
-    ///     The address of the function to call.
-    ///
-    /// @param[in] arg_value_list
-    ///     The default values to use when calling this function.  Can
-    ///     be overridden using WriteFunctionArguments().
-    //------------------------------------------------------------------
-    ClangFunction (ExecutionContextScope &exe_scope,
-                   const CompilerType &return_type,
-                   const Address& function_address, 
-                   const ValueList &arg_value_list,
-                   const char *name);
-    
-    //------------------------------------------------------------------
-    /// Destructor
-    //------------------------------------------------------------------
-    ~ClangFunction() override;
-
-    //------------------------------------------------------------------
-    /// Compile the wrapper function
-    ///
-    /// @param[in] errors
-    ///     The stream to print parser errors to.
-    ///
-    /// @return
-    ///     The number of errors.
-    //------------------------------------------------------------------
-    unsigned
-    CompileFunction (Stream &errors);
-    
-    //------------------------------------------------------------------
-    /// Insert the default function wrapper and its default argument struct  
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to insert the function and its arguments
-    ///     into.
-    ///
-    /// @param[in,out] args_addr_ref
-    ///     The address of the structure to write the arguments into.  May
-    ///     be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
-    ///     and args_addr_ref is pointed to it.
-    ///
-    /// @param[in] errors
-    ///     The stream to write errors to.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool
-    InsertFunction (ExecutionContext &exe_ctx,
-                    lldb::addr_t &args_addr_ref,
-                    Stream &errors);
-
-    //------------------------------------------------------------------
-    /// Insert the default function wrapper (using the JIT)
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to insert the function and its arguments
-    ///     into.
-    ///
-    /// @param[in] errors
-    ///     The stream to write errors to.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool WriteFunctionWrapper (ExecutionContext &exe_ctx, 
-                               Stream &errors);
-    
-    //------------------------------------------------------------------
-    /// Insert the default function argument struct  
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to insert the function and its arguments
-    ///     into.
-    ///
-    /// @param[in,out] args_addr_ref
-    ///     The address of the structure to write the arguments into.  May
-    ///     be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
-    ///     and args_addr_ref is pointed to it.
-    ///
-    /// @param[in] errors
-    ///     The stream to write errors to.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool WriteFunctionArguments (ExecutionContext &exe_ctx, 
-                                 lldb::addr_t &args_addr_ref, 
-                                 Stream &errors);
-    
-    //------------------------------------------------------------------
-    /// Insert an argument struct with a non-default function address and
-    /// non-default argument values
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to insert the function and its arguments
-    ///     into.
-    ///
-    /// @param[in,out] args_addr_ref
-    ///     The address of the structure to write the arguments into.  May
-    ///     be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
-    ///     and args_addr_ref is pointed to it.
-    ///
-    /// @param[in] function_address
-    ///     The address of the function to call.
-    ///
-    /// @param[in] arg_values
-    ///     The values of the function's arguments.
-    ///
-    /// @param[in] errors
-    ///     The stream to write errors to.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool WriteFunctionArguments (ExecutionContext &exe_ctx, 
-                                 lldb::addr_t &args_addr_ref, 
-                                 Address function_address, 
-                                 ValueList &arg_values, 
-                                 Stream &errors);
-
-    //------------------------------------------------------------------
-    /// Run the function this ClangFunction was created with.
-    ///
-    /// This is the full version.
-    ///
-    /// @param[in] exe_ctx
-    ///     The thread & process in which this function will run.
-    ///
-    /// @param[in] args_addr_ptr
-    ///     If NULL, the function will take care of allocating & deallocating the wrapper
-    ///     args structure.  Otherwise, if set to LLDB_INVALID_ADDRESS, a new structure
-    ///     will be allocated, filled and the address returned to you.  You are responsible
-    ///     for deallocating it.  And if passed in with a value other than LLDB_INVALID_ADDRESS,
-    ///     this should point to an already allocated structure with the values already written.
-    ///
-    /// @param[in] errors
-    ///     Errors will be written here if there are any.
-    ///
-    /// @param[in] options
-    ///     The options for this expression execution.
-    ///
-    /// @param[out] results
-    ///     The result value will be put here after running the function.
-    ///
-    /// @return
-    ///     Returns one of the ExpressionResults enum indicating function call status.
-    //------------------------------------------------------------------
-    lldb::ExpressionResults
-    ExecuteFunction(ExecutionContext &exe_ctx, 
-                    lldb::addr_t *args_addr_ptr, 
-                    const EvaluateExpressionOptions &options,
-                    Stream &errors,
-                    Value &results);
-    
-    //------------------------------------------------------------------
-    /// Get a thread plan to run the function this ClangFunction was created with.
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to insert the function and its arguments
-    ///     into.
-    ///
-    /// @param[in] func_addr
-    ///     The address of the function in the target process.
-    ///
-    /// @param[in] args_addr
-    ///     The address of the argument struct.
-    ///
-    /// @param[in] errors
-    ///     The stream to write errors to.
-    ///
-    /// @param[in] stop_others
-    ///     True if other threads should pause during execution.
-    ///
-    /// @param[in] unwind_on_error
-    ///     True if the thread plan may simply be discarded if an error occurs.
-    ///
-    /// @return
-    ///     A ThreadPlan shared pointer for executing the function.
-    //------------------------------------------------------------------
-    lldb::ThreadPlanSP
-    GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, 
-                                 lldb::addr_t args_addr,
-                                 const EvaluateExpressionOptions &options,
-                                 Stream &errors);
-    
-    //------------------------------------------------------------------
-    /// Get the result of the function from its struct
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to retrieve the result from.
-    ///
-    /// @param[in] args_addr
-    ///     The address of the argument struct.
-    ///
-    /// @param[out] ret_value
-    ///     The value returned by the function.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool FetchFunctionResults (ExecutionContext &exe_ctx, 
-                               lldb::addr_t args_addr, 
-                               Value &ret_value);
-    
-    //------------------------------------------------------------------
-    /// Deallocate the arguments structure
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to insert the function and its arguments
-    ///     into.
-    ///
-    /// @param[in] args_addr
-    ///     The address of the argument struct.
-    //------------------------------------------------------------------
-    void DeallocateFunctionResults (ExecutionContext &exe_ctx, 
-                                    lldb::addr_t args_addr);
-    
-    //------------------------------------------------------------------
-    /// Interface for ClangExpression
-    //------------------------------------------------------------------
-    
-    //------------------------------------------------------------------
-    /// Return the string that the parser should parse.  Must be a full
-    /// translation unit.
-    //------------------------------------------------------------------
-    const char *
-    Text() override
-    {
-        return m_wrapper_function_text.c_str();
-    }
-    
-    //------------------------------------------------------------------
-    /// Return the function name that should be used for executing the
-    /// expression.  Text() should contain the definition of this
-    /// function.
-    //------------------------------------------------------------------
-    const char *
-    FunctionName() override
-    {
-        return m_wrapper_function_name.c_str();
-    }
-    
-    //------------------------------------------------------------------
-    /// Return the object that the parser should use when resolving external
-    /// values.  May be NULL if everything should be self-contained.
-    //------------------------------------------------------------------
-    ClangExpressionDeclMap *
-    DeclMap() override
-    {
-        return NULL;
-    }
-    
-    //------------------------------------------------------------------
-    /// Return the object that the parser should use when registering
-    /// local variables.  May be NULL if the Expression doesn't care.
-    //------------------------------------------------------------------
-    ExpressionVariableList *
-    LocalVariables ()
-    {
-        return NULL;
-    }
-    
-    //------------------------------------------------------------------
-    /// Return the object that the parser should allow to access ASTs.
-    /// May be NULL if the ASTs do not need to be transformed.
-    ///
-    /// @param[in] passthrough
-    ///     The ASTConsumer that the returned transformer should send
-    ///     the ASTs to after transformation.
-    //------------------------------------------------------------------
-    clang::ASTConsumer *
-    ASTTransformer(clang::ASTConsumer *passthrough) override;
-    
-    //------------------------------------------------------------------
-    /// Return true if validation code should be inserted into the
-    /// expression.
-    //------------------------------------------------------------------
-    bool
-    NeedsValidation() override
-    {
-        return false;
-    }
-    
-    //------------------------------------------------------------------
-    /// Return true if external variables in the expression should be
-    /// resolved.
-    //------------------------------------------------------------------
-    bool
-    NeedsVariableResolution() override
-    {
-        return false;
-    }
-    
-    ValueList
-    GetArgumentValues () const
-    {
-        return m_arg_values;
-    }
-private:
-    //------------------------------------------------------------------
-    // For ClangFunction only
-    //------------------------------------------------------------------
-
-    // Note: the parser needs to be destructed before the execution unit, so
-    // declare the execution unit first.
-    std::shared_ptr<IRExecutionUnit> m_execution_unit_sp;
-    std::unique_ptr<ClangExpressionParser> m_parser;                 ///< The parser responsible for compiling the function.
-    lldb::ModuleWP                  m_jit_module_wp;
-    std::string                     m_name;                         ///< The name of this clang function - for debugging purposes.
-    
-    Function                       *m_function_ptr;                 ///< The function we're going to call.  May be NULL if we don't have debug info for the function.
-    Address                         m_function_addr;                ///< If we don't have the FunctionSP, we at least need the address & return type.
-    CompilerType                    m_function_return_type;         ///< The opaque clang qual type for the function return type.
-
-    std::string                     m_wrapper_function_name;        ///< The name of the wrapper function.
-    std::string                     m_wrapper_function_text;        ///< The contents of the wrapper function.
-    std::string                     m_wrapper_struct_name;          ///< The name of the struct that contains the target function address, arguments, and result.
-    std::list<lldb::addr_t>         m_wrapper_args_addrs;           ///< The addresses of the arguments to the wrapper function.
-    
-    std::unique_ptr<ASTStructExtractor> m_struct_extractor;         ///< The class that generates the argument struct below.
-
-    bool                            m_struct_valid;                 ///< True if the ASTStructExtractor has populated the variables below.
-    
-    //------------------------------------------------------------------
-    /// These values are populated by the ASTStructExtractor
-    size_t                          m_struct_size;                  ///< The size of the argument struct, in bytes.
-    std::vector<uint64_t>           m_member_offsets;               ///< The offset of each member in the struct, in bytes.
-    uint64_t                        m_return_size;                  ///< The size of the result variable, in bytes.
-    uint64_t                        m_return_offset;                ///< The offset of the result variable in the struct, in bytes.
-    //------------------------------------------------------------------
-
-    ValueList                       m_arg_values;                   ///< The default values of the arguments.
-    
-    bool                            m_compiled;                     ///< True if the wrapper function has already been parsed.
-    bool                            m_JITted;                       ///< True if the wrapper function has already been JIT-compiled.
-};
-
-} // Namespace lldb_private
-
-#endif // liblldb_ClangFunction_h_

Copied: lldb/trunk/include/lldb/Expression/ClangFunctionCaller.h (from r247584, lldb/trunk/include/lldb/Expression/ClangFunction.h)
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangFunctionCaller.h?p2=lldb/trunk/include/lldb/Expression/ClangFunctionCaller.h&p1=lldb/trunk/include/lldb/Expression/ClangFunction.h&r1=247584&r2=247720&rev=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangFunction.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangFunctionCaller.h Tue Sep 15 16:13:50 2015
@@ -1,4 +1,4 @@
-//===-- ClangFunction.h -----------------------------------------*- C++ -*-===//
+//===-- ClangFunctionCaller.h -----------------------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,8 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef liblldb_ClangFunction_h_
-#define liblldb_ClangFunction_h_
+#ifndef liblldb_ClangFunctionCaller_h_
+#define liblldb_ClangFunctionCaller_h_
 
 // C Includes
 // C++ Includes
@@ -21,7 +21,8 @@
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/Value.h"
 #include "lldb/Core/ValueObjectList.h"
-#include "lldb/Expression/ClangExpression.h"
+#include "lldb/Expression/ClangExpressionHelper.h"
+#include "lldb/Expression/FunctionCaller.h"
 #include "lldb/Symbol/CompilerType.h"
 #include "lldb/Target/Process.h"
 
@@ -32,10 +33,10 @@ class ASTStructExtractor;
 class ClangExpressionParser;
 
 //----------------------------------------------------------------------
-/// @class ClangFunction ClangFunction.h "lldb/Expression/ClangFunction.h"
+/// @class ClangFunctionCaller ClangFunctionCaller.h "lldb/Expression/ClangFunctionCaller.h"
 /// @brief Encapsulates a function that can be called.
 ///
-/// A given ClangFunction object can handle a single function signature.
+/// A given ClangFunctionCaller object can handle a single function signature.
 /// Once constructed, it can set up any number of concurrent calls to
 /// functions with that signature.
 ///
@@ -46,7 +47,7 @@ class ClangExpressionParser;
 /// struct with the written arguments.  This method lets Clang handle the
 /// vagaries of function calling conventions.
 ///
-/// The simplest use of the ClangFunction is to construct it with a
+/// The simplest use of the ClangFunctionCaller is to construct it with a
 /// function representative of the signature you want to use, then call
 /// ExecuteFunction(ExecutionContext &, Stream &, Value &).
 ///
@@ -64,34 +65,46 @@ class ClangExpressionParser;
 /// Any of the methods that take arg_addr_ptr can be passed NULL, and the
 /// argument space will be managed for you.
 //----------------------------------------------------------------------    
-class ClangFunction : public ClangExpression
+class ClangFunctionCaller : public FunctionCaller
 {
     friend class ASTStructExtractor;
-public:
-    //------------------------------------------------------------------
-    /// Constructor
-    ///
-    /// @param[in] exe_scope
-    ///     An execution context scope that gets us at least a target and 
-    ///     process.
-    ///
-    /// @param[in] function_ptr
-    ///     The default function to be called.  Can be overridden using
-    ///     WriteFunctionArguments().
-    ///
-    /// @param[in] ast_context
-    ///     The AST context to evaluate argument types in.
-    ///
-    /// @param[in] arg_value_list
-    ///     The default values to use when calling this function.  Can
-    ///     be overridden using WriteFunctionArguments().
-    //------------------------------------------------------------------  
-    ClangFunction (ExecutionContextScope &exe_scope,
-                   Function &function_ptr, 
-                   ClangASTContext *ast_context, 
-                   const ValueList &arg_value_list,
-                   const char *name);
     
+    class ClangFunctionCallerHelper : public ClangExpressionHelper
+    {
+    public:
+        ClangFunctionCallerHelper (ClangFunctionCaller &owner) :
+            m_owner(owner)
+        {
+        }
+        
+        ~ClangFunctionCallerHelper() {}
+        
+        //------------------------------------------------------------------
+        /// Return the object that the parser should use when resolving external
+        /// values.  May be NULL if everything should be self-contained.
+        //------------------------------------------------------------------
+        ClangExpressionDeclMap *
+        DeclMap() override
+        {
+            return NULL;
+        }
+        
+        //------------------------------------------------------------------
+        /// Return the object that the parser should allow to access ASTs.
+        /// May be NULL if the ASTs do not need to be transformed.
+        ///
+        /// @param[in] passthrough
+        ///     The ASTConsumer that the returned transformer should send
+        ///     the ASTs to after transformation.
+        //------------------------------------------------------------------
+        clang::ASTConsumer *
+        ASTTransformer(clang::ASTConsumer *passthrough) override;
+    private:
+        ClangFunctionCaller                      &m_owner;
+        std::unique_ptr<ASTStructExtractor> m_struct_extractor;         ///< The class that generates the argument struct layout.
+    };
+
+public:
     //------------------------------------------------------------------
     /// Constructor
     ///
@@ -113,16 +126,16 @@ public:
     ///     The default values to use when calling this function.  Can
     ///     be overridden using WriteFunctionArguments().
     //------------------------------------------------------------------
-    ClangFunction (ExecutionContextScope &exe_scope,
-                   const CompilerType &return_type,
-                   const Address& function_address, 
-                   const ValueList &arg_value_list,
-                   const char *name);
+    ClangFunctionCaller (ExecutionContextScope &exe_scope,
+                         const CompilerType &return_type,
+                         const Address& function_address,
+                         const ValueList &arg_value_list,
+                         const char *name);
     
     //------------------------------------------------------------------
     /// Destructor
     //------------------------------------------------------------------
-    ~ClangFunction() override;
+    ~ClangFunctionCaller() override;
 
     //------------------------------------------------------------------
     /// Compile the wrapper function
@@ -134,317 +147,29 @@ public:
     ///     The number of errors.
     //------------------------------------------------------------------
     unsigned
-    CompileFunction (Stream &errors);
-    
-    //------------------------------------------------------------------
-    /// Insert the default function wrapper and its default argument struct  
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to insert the function and its arguments
-    ///     into.
-    ///
-    /// @param[in,out] args_addr_ref
-    ///     The address of the structure to write the arguments into.  May
-    ///     be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
-    ///     and args_addr_ref is pointed to it.
-    ///
-    /// @param[in] errors
-    ///     The stream to write errors to.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool
-    InsertFunction (ExecutionContext &exe_ctx,
-                    lldb::addr_t &args_addr_ref,
-                    Stream &errors);
-
-    //------------------------------------------------------------------
-    /// Insert the default function wrapper (using the JIT)
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to insert the function and its arguments
-    ///     into.
-    ///
-    /// @param[in] errors
-    ///     The stream to write errors to.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool WriteFunctionWrapper (ExecutionContext &exe_ctx, 
-                               Stream &errors);
-    
-    //------------------------------------------------------------------
-    /// Insert the default function argument struct  
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to insert the function and its arguments
-    ///     into.
-    ///
-    /// @param[in,out] args_addr_ref
-    ///     The address of the structure to write the arguments into.  May
-    ///     be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
-    ///     and args_addr_ref is pointed to it.
-    ///
-    /// @param[in] errors
-    ///     The stream to write errors to.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool WriteFunctionArguments (ExecutionContext &exe_ctx, 
-                                 lldb::addr_t &args_addr_ref, 
-                                 Stream &errors);
-    
-    //------------------------------------------------------------------
-    /// Insert an argument struct with a non-default function address and
-    /// non-default argument values
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to insert the function and its arguments
-    ///     into.
-    ///
-    /// @param[in,out] args_addr_ref
-    ///     The address of the structure to write the arguments into.  May
-    ///     be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
-    ///     and args_addr_ref is pointed to it.
-    ///
-    /// @param[in] function_address
-    ///     The address of the function to call.
-    ///
-    /// @param[in] arg_values
-    ///     The values of the function's arguments.
-    ///
-    /// @param[in] errors
-    ///     The stream to write errors to.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool WriteFunctionArguments (ExecutionContext &exe_ctx, 
-                                 lldb::addr_t &args_addr_ref, 
-                                 Address function_address, 
-                                 ValueList &arg_values, 
-                                 Stream &errors);
-
-    //------------------------------------------------------------------
-    /// Run the function this ClangFunction was created with.
-    ///
-    /// This is the full version.
-    ///
-    /// @param[in] exe_ctx
-    ///     The thread & process in which this function will run.
-    ///
-    /// @param[in] args_addr_ptr
-    ///     If NULL, the function will take care of allocating & deallocating the wrapper
-    ///     args structure.  Otherwise, if set to LLDB_INVALID_ADDRESS, a new structure
-    ///     will be allocated, filled and the address returned to you.  You are responsible
-    ///     for deallocating it.  And if passed in with a value other than LLDB_INVALID_ADDRESS,
-    ///     this should point to an already allocated structure with the values already written.
-    ///
-    /// @param[in] errors
-    ///     Errors will be written here if there are any.
-    ///
-    /// @param[in] options
-    ///     The options for this expression execution.
-    ///
-    /// @param[out] results
-    ///     The result value will be put here after running the function.
-    ///
-    /// @return
-    ///     Returns one of the ExpressionResults enum indicating function call status.
-    //------------------------------------------------------------------
-    lldb::ExpressionResults
-    ExecuteFunction(ExecutionContext &exe_ctx, 
-                    lldb::addr_t *args_addr_ptr, 
-                    const EvaluateExpressionOptions &options,
-                    Stream &errors,
-                    Value &results);
+    CompileFunction (Stream &errors) override;
     
-    //------------------------------------------------------------------
-    /// Get a thread plan to run the function this ClangFunction was created with.
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to insert the function and its arguments
-    ///     into.
-    ///
-    /// @param[in] func_addr
-    ///     The address of the function in the target process.
-    ///
-    /// @param[in] args_addr
-    ///     The address of the argument struct.
-    ///
-    /// @param[in] errors
-    ///     The stream to write errors to.
-    ///
-    /// @param[in] stop_others
-    ///     True if other threads should pause during execution.
-    ///
-    /// @param[in] unwind_on_error
-    ///     True if the thread plan may simply be discarded if an error occurs.
-    ///
-    /// @return
-    ///     A ThreadPlan shared pointer for executing the function.
-    //------------------------------------------------------------------
-    lldb::ThreadPlanSP
-    GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, 
-                                 lldb::addr_t args_addr,
-                                 const EvaluateExpressionOptions &options,
-                                 Stream &errors);
-    
-    //------------------------------------------------------------------
-    /// Get the result of the function from its struct
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to retrieve the result from.
-    ///
-    /// @param[in] args_addr
-    ///     The address of the argument struct.
-    ///
-    /// @param[out] ret_value
-    ///     The value returned by the function.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool FetchFunctionResults (ExecutionContext &exe_ctx, 
-                               lldb::addr_t args_addr, 
-                               Value &ret_value);
-    
-    //------------------------------------------------------------------
-    /// Deallocate the arguments structure
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to insert the function and its arguments
-    ///     into.
-    ///
-    /// @param[in] args_addr
-    ///     The address of the argument struct.
-    //------------------------------------------------------------------
-    void DeallocateFunctionResults (ExecutionContext &exe_ctx, 
-                                    lldb::addr_t args_addr);
-    
-    //------------------------------------------------------------------
-    /// Interface for ClangExpression
-    //------------------------------------------------------------------
-    
-    //------------------------------------------------------------------
-    /// Return the string that the parser should parse.  Must be a full
-    /// translation unit.
-    //------------------------------------------------------------------
-    const char *
-    Text() override
-    {
-        return m_wrapper_function_text.c_str();
-    }
-    
-    //------------------------------------------------------------------
-    /// Return the function name that should be used for executing the
-    /// expression.  Text() should contain the definition of this
-    /// function.
-    //------------------------------------------------------------------
-    const char *
-    FunctionName() override
-    {
-        return m_wrapper_function_name.c_str();
-    }
-    
-    //------------------------------------------------------------------
-    /// Return the object that the parser should use when resolving external
-    /// values.  May be NULL if everything should be self-contained.
-    //------------------------------------------------------------------
-    ClangExpressionDeclMap *
-    DeclMap() override
-    {
-        return NULL;
-    }
-    
-    //------------------------------------------------------------------
-    /// Return the object that the parser should use when registering
-    /// local variables.  May be NULL if the Expression doesn't care.
-    //------------------------------------------------------------------
-    ExpressionVariableList *
-    LocalVariables ()
-    {
-        return NULL;
-    }
-    
-    //------------------------------------------------------------------
-    /// Return the object that the parser should allow to access ASTs.
-    /// May be NULL if the ASTs do not need to be transformed.
-    ///
-    /// @param[in] passthrough
-    ///     The ASTConsumer that the returned transformer should send
-    ///     the ASTs to after transformation.
-    //------------------------------------------------------------------
-    clang::ASTConsumer *
-    ASTTransformer(clang::ASTConsumer *passthrough) override;
-    
-    //------------------------------------------------------------------
-    /// Return true if validation code should be inserted into the
-    /// expression.
-    //------------------------------------------------------------------
-    bool
-    NeedsValidation() override
+    ExpressionTypeSystemHelper *
+    GetTypeSystemHelper () override
     {
-        return false;
+        return &m_type_system_helper;
     }
-    
-    //------------------------------------------------------------------
-    /// Return true if external variables in the expression should be
-    /// resolved.
-    //------------------------------------------------------------------
-    bool
-    NeedsVariableResolution() override
-    {
-        return false;
-    }
-    
-    ValueList
-    GetArgumentValues () const
+protected:
+    const char *GetWrapperStructName()
     {
-        return m_arg_values;
+        return m_wrapper_struct_name.c_str();
     }
 private:
     //------------------------------------------------------------------
-    // For ClangFunction only
+    // For ClangFunctionCaller only
     //------------------------------------------------------------------
 
     // Note: the parser needs to be destructed before the execution unit, so
     // declare the execution unit first.
-    std::shared_ptr<IRExecutionUnit> m_execution_unit_sp;
-    std::unique_ptr<ClangExpressionParser> m_parser;                 ///< The parser responsible for compiling the function.
-    lldb::ModuleWP                  m_jit_module_wp;
-    std::string                     m_name;                         ///< The name of this clang function - for debugging purposes.
-    
-    Function                       *m_function_ptr;                 ///< The function we're going to call.  May be NULL if we don't have debug info for the function.
-    Address                         m_function_addr;                ///< If we don't have the FunctionSP, we at least need the address & return type.
-    CompilerType                    m_function_return_type;         ///< The opaque clang qual type for the function return type.
-
-    std::string                     m_wrapper_function_name;        ///< The name of the wrapper function.
-    std::string                     m_wrapper_function_text;        ///< The contents of the wrapper function.
-    std::string                     m_wrapper_struct_name;          ///< The name of the struct that contains the target function address, arguments, and result.
-    std::list<lldb::addr_t>         m_wrapper_args_addrs;           ///< The addresses of the arguments to the wrapper function.
-    
-    std::unique_ptr<ASTStructExtractor> m_struct_extractor;         ///< The class that generates the argument struct below.
-
-    bool                            m_struct_valid;                 ///< True if the ASTStructExtractor has populated the variables below.
-    
-    //------------------------------------------------------------------
-    /// These values are populated by the ASTStructExtractor
-    size_t                          m_struct_size;                  ///< The size of the argument struct, in bytes.
-    std::vector<uint64_t>           m_member_offsets;               ///< The offset of each member in the struct, in bytes.
-    uint64_t                        m_return_size;                  ///< The size of the result variable, in bytes.
-    uint64_t                        m_return_offset;                ///< The offset of the result variable in the struct, in bytes.
-    //------------------------------------------------------------------
+    ClangFunctionCallerHelper   m_type_system_helper;
 
-    ValueList                       m_arg_values;                   ///< The default values of the arguments.
-    
-    bool                            m_compiled;                     ///< True if the wrapper function has already been parsed.
-    bool                            m_JITted;                       ///< True if the wrapper function has already been JIT-compiled.
 };
 
 } // Namespace lldb_private
 
-#endif // liblldb_ClangFunction_h_
+#endif // liblldb_ClangFunctionCaller_h_

Modified: lldb/trunk/include/lldb/Expression/ClangUserExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangUserExpression.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangUserExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangUserExpression.h Tue Sep 15 16:13:50 2015
@@ -23,7 +23,9 @@
 #include "lldb/lldb-private.h"
 #include "lldb/Core/Address.h"
 #include "lldb/Core/ClangForward.h"
-#include "lldb/Expression/ClangExpression.h"
+#include "lldb/Expression/UserExpression.h"
+#include "lldb/Expression/ClangExpressionHelper.h"
+#include "lldb/Expression/ASTStructExtractor.h"
 #include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
 #include "lldb/Expression/IRForTarget.h"
 #include "lldb/Expression/Materializer.h"
@@ -42,11 +44,59 @@ namespace lldb_private
 /// 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 ClangExpression
+class ClangUserExpression : public UserExpression
 {
 public:
 
     enum { kDefaultTimeout = 500000u };
+
+
+    class ClangUserExpressionHelper : public ClangExpressionHelper
+    {
+    public:
+        ClangUserExpressionHelper (Target &target) :
+            m_target(target)
+        {
+        }
+        
+        ~ClangUserExpressionHelper() {}
+        
+        //------------------------------------------------------------------
+        /// Return the object that the parser should use when resolving external
+        /// values.  May be NULL if everything should be self-contained.
+        //------------------------------------------------------------------
+        ClangExpressionDeclMap *
+        DeclMap() override
+        {
+            return m_expr_decl_map_up.get();
+        }
+        
+        void
+        ResetDeclMap()
+        {
+            m_expr_decl_map_up.reset();
+        }
+        
+        void
+        ResetDeclMap (ExecutionContext & exe_ctx, bool keep_result_in_memory);
+        
+        //------------------------------------------------------------------
+        /// Return the object that the parser should allow to access ASTs.
+        /// May be NULL if the ASTs do not need to be transformed.
+        ///
+        /// @param[in] passthrough
+        ///     The ASTConsumer that the returned transformer should send
+        ///     the ASTs to after transformation.
+        //------------------------------------------------------------------
+        clang::ASTConsumer *
+        ASTTransformer(clang::ASTConsumer *passthrough) override;
+    private:
+        Target                                  &m_target;
+        std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
+        std::unique_ptr<ASTStructExtractor> m_struct_extractor_up;         ///< The class that generates the argument struct layout.
+        std::unique_ptr<ASTResultSynthesizer> m_result_synthesizer_up;
+    };
+
     //------------------------------------------------------------------
     /// Constructor
     ///
@@ -66,7 +116,8 @@ public:
     ///     If not eResultTypeAny, the type to use for the expression
     ///     result.
     //------------------------------------------------------------------
-    ClangUserExpression (const char *expr,
+    ClangUserExpression (ExecutionContextScope &exe_scope,
+                         const char *expr,
                          const char *expr_prefix,
                          lldb::LanguageType language,
                          ResultType desired_type);
@@ -102,207 +153,32 @@ public:
            ExecutionContext &exe_ctx,
            lldb_private::ExecutionPolicy execution_policy,
            bool keep_result_in_memory,
-           bool generate_debug_info);
-
-    bool
-    CanInterpret ()
-    {
-        return m_can_interpret;
-    }
-
-    bool
-    MatchesContext (ExecutionContext &exe_ctx);
-
-    //------------------------------------------------------------------
-    /// Execute the parsed expression
-    ///
-    /// @param[in] error_stream
-    ///     A stream to print errors to.
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to use when looking up entities that
-    ///     are needed for parsing (locations of variables, etc.)
-    ///
-    /// @param[in] options
-    ///     Expression evaluation options.
-    ///
-    /// @param[in] shared_ptr_to_me
-    ///     This is a shared pointer to this ClangUserExpression.  This is
-    ///     needed because Execute can push a thread plan that will hold onto
-    ///     the ClangUserExpression for an unbounded period of time.  So you
-    ///     need to give the thread plan a reference to this object that can
-    ///     keep it alive.
-    ///
-    /// @param[in] result
-    ///     A pointer to direct at the persistent variable in which the
-    ///     expression's result is stored.
-    ///
-    /// @return
-    ///     A Process::Execution results value.
-    //------------------------------------------------------------------
-    lldb::ExpressionResults
-    Execute (Stream &error_stream,
-             ExecutionContext &exe_ctx,
-             const EvaluateExpressionOptions& options,
-             lldb::ClangUserExpressionSP &shared_ptr_to_me,
-             lldb::ExpressionVariableSP &result);
-
-    //------------------------------------------------------------------
-    /// Apply the side effects of the function to program state.
-    ///
-    /// @param[in] error_stream
-    ///     A stream to print errors to.
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to use when looking up entities that
-    ///     are needed for parsing (locations of variables, etc.)
-    ///
-    /// @param[in] result
-    ///     A pointer to direct at the persistent variable in which the
-    ///     expression's result is stored.
-    ///
-    /// @param[in] function_stack_pointer
-    ///     A pointer to the base of the function's stack frame.  This
-    ///     is used to determine whether the expression result resides in
-    ///     memory that will still be valid, or whether it needs to be
-    ///     treated as homeless for the purpose of future expressions.
-    ///
-    /// @return
-    ///     A Process::Execution results value.
-    //------------------------------------------------------------------
-    bool
-    FinalizeJITExecution (Stream &error_stream,
-                          ExecutionContext &exe_ctx,
-                          lldb::ExpressionVariableSP &result,
-                          lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
-                          lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS);
-
-    //------------------------------------------------------------------
-    /// Return the string that the parser should parse.  Must be a full
-    /// translation unit.
-    //------------------------------------------------------------------
-    const char *
-    Text() override
-    {
-        return m_transformed_text.c_str();
-    }
-
-    //------------------------------------------------------------------
-    /// Return the string that the user typed.
-    //------------------------------------------------------------------
-    const char *
-    GetUserText ()
-    {
-        return m_expr_text.c_str();
-    }
-
-    //------------------------------------------------------------------
-    /// Return the function name that should be used for executing the
-    /// expression.  Text() should contain the definition of this
-    /// function.
-    //------------------------------------------------------------------
-    const char *
-    FunctionName() override
-    {
-        return "$__lldb_expr";
-    }
+           bool generate_debug_info) override;
 
-    //------------------------------------------------------------------
-    /// Return the language that should be used when parsing.  To use
-    /// the default, return eLanguageTypeUnknown.
-    //------------------------------------------------------------------
-    lldb::LanguageType
-    Language() override
+    ExpressionTypeSystemHelper *
+    GetTypeSystemHelper () override
     {
-        return m_language;
+        return &m_type_system_helper;
     }
-
-    //------------------------------------------------------------------
-    /// Return the object that the parser should use when resolving external
-    /// values.  May be NULL if everything should be self-contained.
-    //------------------------------------------------------------------
+    
     ClangExpressionDeclMap *
-    DeclMap() override
-    {
-        return m_expr_decl_map.get();
-    }
-
-    //------------------------------------------------------------------
-    /// Return the object that the parser should allow to access ASTs.
-    /// May be NULL if the ASTs do not need to be transformed.
-    ///
-    /// @param[in] passthrough
-    ///     The ASTConsumer that the returned transformer should send
-    ///     the ASTs to after transformation.
-    //------------------------------------------------------------------
-    clang::ASTConsumer *
-    ASTTransformer(clang::ASTConsumer *passthrough) override;
-
-    //------------------------------------------------------------------
-    /// Return the desired result type of the function, or
-    /// eResultTypeAny if indifferent.
-    //------------------------------------------------------------------
-    ResultType
-    DesiredResultType() override
+    DeclMap ()
     {
-        return m_desired_type;
+        return m_type_system_helper.DeclMap();
     }
-
-    //------------------------------------------------------------------
-    /// Return true if validation code should be inserted into the
-    /// expression.
-    //------------------------------------------------------------------
-    bool
-    NeedsValidation() override
+    
+    void
+    ResetDeclMap ()
     {
-        return true;
+        m_type_system_helper.ResetDeclMap();
     }
-
-    //------------------------------------------------------------------
-    /// Return true if external variables in the expression should be
-    /// resolved.
-    //------------------------------------------------------------------
-    bool
-    NeedsVariableResolution() override
+    
+    void
+    ResetDeclMap (ExecutionContext & exe_ctx, bool keep_result_in_memory)
     {
-        return true;
+        m_type_system_helper.ResetDeclMap(exe_ctx, keep_result_in_memory);
     }
-
-    //------------------------------------------------------------------
-    /// Evaluate one expression and return its result.
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to use when evaluating the expression.
-    ///
-    /// @param[in] options
-    ///     Expression evaluation options.
-    ///
-    /// @param[in] expr_cstr
-    ///     A C string containing the expression to be evaluated.
-    ///
-    /// @param[in] expr_prefix
-    ///     If non-NULL, a C string containing translation-unit level
-    ///     definitions to be included when the expression is parsed.
-    ///
-    /// @param[in,out] result_valobj_sp
-    ///      If execution is successful, the result valobj is placed here.
-    ///
-    /// @param[out]
-    ///     Filled in with an error in case the expression evaluation
-    ///     fails to parse, run, or evaluated.
-    ///
-    /// @result
-    ///      A Process::ExpressionResults value.  eExpressionCompleted for success.
-    //------------------------------------------------------------------
-    static lldb::ExpressionResults
-    Evaluate (ExecutionContext &exe_ctx,
-              const EvaluateExpressionOptions& options,
-              const char *expr_cstr,
-              const char *expr_prefix,
-              lldb::ValueObjectSP &result_valobj_sp,
-              Error &error);
-
-    static const Error::ValueType kNoResult = 0x1001; ///< ValueObject::GetError() returns this if there is no result from the expression.
+    
 private:
     //------------------------------------------------------------------
     /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the environment.
@@ -310,53 +186,14 @@ private:
 
     void
     ScanContext (ExecutionContext &exe_ctx,
-                 lldb_private::Error &err);
-
-    bool
-    PrepareToExecuteJITExpression (Stream &error_stream,
-                                   ExecutionContext &exe_ctx,
-                                   lldb::addr_t &struct_address,
-                                   lldb::addr_t &object_ptr,
-                                   lldb::addr_t &cmd_ptr);
-
-    void
-    InstallContext (ExecutionContext &exe_ctx);
+                 lldb_private::Error &err) override;
 
     bool
-    LockAndCheckContext (ExecutionContext &exe_ctx,
-                         lldb::TargetSP &target_sp,
-                         lldb::ProcessSP &process_sp,
-                         lldb::StackFrameSP &frame_sp);
-
-    lldb::ProcessWP                             m_process_wp;           ///< The process used as the context for the expression.
-    Address                                     m_address;              ///< The address the process is stopped in.
-    lldb::addr_t                                m_stack_frame_bottom;   ///< The bottom of the allocated stack frame.
-    lldb::addr_t                                m_stack_frame_top;      ///< The top of the allocated stack frame.
-
-    std::string                                 m_expr_text;            ///< The text of the expression, as typed by the user
-    std::string                                 m_expr_prefix;          ///< The text of the translation-level definitions, as provided by the user
-    lldb::LanguageType                          m_language;             ///< The language to use when parsing (eLanguageTypeUnknown means use defaults)
-    bool                                        m_allow_cxx;            ///< True if the language allows C++.
-    bool                                        m_allow_objc;           ///< True if the language allows Objective-C.
-    std::string                                 m_transformed_text;     ///< The text of the expression, as send to the parser
-    ResultType                                  m_desired_type;         ///< The type to coerce the expression's result to.  If eResultTypeAny, inferred from the expression.
-
-    std::unique_ptr<ClangExpressionDeclMap>     m_expr_decl_map;        ///< The map to use when parsing the expression.
-    std::shared_ptr<IRExecutionUnit>            m_execution_unit_sp;    ///< The execution unit the expression is stored in.
-    std::unique_ptr<Materializer>               m_materializer_ap;      ///< The materializer to use when running the expression.
-    std::unique_ptr<ASTResultSynthesizer>       m_result_synthesizer;   ///< The result synthesizer, if one is needed.
-    lldb::ModuleWP                              m_jit_module_wp;
-    bool                                        m_enforce_valid_object; ///< True if the expression parser should enforce the presence of a valid class pointer in order to generate the expression as a method.
-    bool                                        m_in_cplusplus_method;  ///< True if the expression is compiled as a C++ member function (true if it was parsed when exe_ctx was in a C++ method).
-    bool                                        m_in_objectivec_method; ///< True if the expression is compiled as an Objective-C method (true if it was parsed when exe_ctx was in an Objective-C method).
-    bool                                        m_in_static_method;     ///< True if the expression is compiled as a static (or class) method (currently true if it was parsed when exe_ctx was in an Objective-C class method).
-    bool                                        m_needs_object_ptr;     ///< True if "this" or "self" must be looked up and passed in.  False if the expression doesn't really use them and they can be NULL.
-    bool                                        m_const_object;         ///< True if "this" is const.
-    Target                                     *m_target;               ///< The target for storing persistent data like types and variables.
-
-    bool                                        m_can_interpret;        ///< True if the expression could be evaluated statically; false otherwise.
-    lldb::addr_t                                m_materialized_address; ///< The address at which the arguments to the expression have been materialized.
-    Materializer::DematerializerSP              m_dematerializer_sp;    ///< The dematerializer.
+    AddInitialArguments (ExecutionContext &exe_ctx,
+                         std::vector<lldb::addr_t> &args,
+                         Stream &error_stream) override;
+    
+    ClangUserExpressionHelper   m_type_system_helper;
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h Tue Sep 15 16:13:50 2015
@@ -22,7 +22,8 @@
 #include "lldb/lldb-forward.h"
 #include "lldb/lldb-private.h"
 #include "lldb/Core/ClangForward.h"
-#include "lldb/Expression/ClangExpression.h"
+#include "lldb/Expression/ClangExpressionHelper.h"
+#include "lldb/Expression/UtilityFunction.h"
 
 namespace lldb_private 
 {
@@ -34,11 +35,57 @@ namespace lldb_private
 /// LLDB uses expressions for various purposes, notably to call functions
 /// and as a backend for the expr command.  ClangUtilityFunction encapsulates
 /// a self-contained function meant to be used from other code.  Utility
-/// functions can perform error-checking for ClangUserExpressions, 
+/// functions can perform error-checking for ClangUserExpressions, or can
+/// simply provide a way to push a function into the target for the debugger to
+/// call later on.
 //----------------------------------------------------------------------
-class ClangUtilityFunction : public ClangExpression
+class ClangUtilityFunction : public UtilityFunction
 {
 public:
+    class ClangUtilityFunctionHelper : public ClangExpressionHelper
+    {
+    public:
+        ClangUtilityFunctionHelper ()
+        {
+        }
+        
+        ~ClangUtilityFunctionHelper() override {}
+        
+        //------------------------------------------------------------------
+        /// Return the object that the parser should use when resolving external
+        /// values.  May be NULL if everything should be self-contained.
+        //------------------------------------------------------------------
+        ClangExpressionDeclMap *
+        DeclMap() override
+        {
+            return m_expr_decl_map_up.get();
+        }
+        
+        void
+        ResetDeclMap()
+        {
+            m_expr_decl_map_up.reset();
+        }
+        
+        void
+        ResetDeclMap (ExecutionContext & exe_ctx, bool keep_result_in_memory);
+
+        //------------------------------------------------------------------
+        /// Return the object that the parser should allow to access ASTs.
+        /// May be NULL if the ASTs do not need to be transformed.
+        ///
+        /// @param[in] passthrough
+        ///     The ASTConsumer that the returned transformer should send
+        ///     the ASTs to after transformation.
+        //------------------------------------------------------------------
+        clang::ASTConsumer *
+        ASTTransformer(clang::ASTConsumer *passthrough) override
+        {
+            return nullptr;
+        }
+    private:
+        std::unique_ptr<ClangExpressionDeclMap> m_expr_decl_map_up;
+    };
     //------------------------------------------------------------------
     /// Constructor
     ///
@@ -48,129 +95,41 @@ public:
     /// @param[in] name
     ///     The name of the function, as used in the text.
     //------------------------------------------------------------------
-    ClangUtilityFunction (const char *text, 
+    ClangUtilityFunction (ExecutionContextScope &exe_scope,
+                          const char *text,
                           const char *name);
     
     ~ClangUtilityFunction() override;
-
-    //------------------------------------------------------------------
-    /// Install the utility function into a process
-    ///
-    /// @param[in] error_stream
-    ///     A stream to print parse errors and warnings to.
-    ///
-    /// @param[in] exe_ctx
-    ///     The execution context to install the utility function to.
-    ///
-    /// @return
-    ///     True on success (no errors); false otherwise.
-    //------------------------------------------------------------------
-    bool
-    Install (Stream &error_stream, ExecutionContext &exe_ctx);
-    
-    //------------------------------------------------------------------
-    /// Check whether the given PC is inside the function
-    ///
-    /// Especially useful if the function dereferences NULL to indicate a failed
-    /// assert.
-    ///
-    /// @param[in] pc
-    ///     The program counter to check.
-    ///
-    /// @return
-    ///     True if the program counter falls within the function's bounds;
-    ///     false if not (or the function is not JIT compiled)
-    //------------------------------------------------------------------
-    bool
-    ContainsAddress (lldb::addr_t address)
-    {
-        // nothing is both >= LLDB_INVALID_ADDRESS and < LLDB_INVALID_ADDRESS,
-        // so this always returns false if the function is not JIT compiled yet
-        return (address >= m_jit_start_addr && address < m_jit_end_addr);
-    }
     
-    
-    //------------------------------------------------------------------
-    /// Return the string that the parser should parse.  Must be a full
-    /// translation unit.
-    //------------------------------------------------------------------
-    const char *
-    Text() override
+    ExpressionTypeSystemHelper *
+    GetTypeSystemHelper () override
     {
-        return m_function_text.c_str();
+        return &m_type_system_helper;
     }
-    
-    //------------------------------------------------------------------
-    /// Return the function name that should be used for executing the
-    /// expression.  Text() should contain the definition of this
-    /// function.
-    //------------------------------------------------------------------
-    const char *
-    FunctionName() override
-    {
-        return m_function_name.c_str();
-    }
-    
-    //------------------------------------------------------------------
-    /// Return the object that the parser should use when resolving external
-    /// values.  May be NULL if everything should be self-contained.
-    //------------------------------------------------------------------
+
     ClangExpressionDeclMap *
-    DeclMap() override
+    DeclMap()
     {
-        return m_expr_decl_map.get();
+        return m_type_system_helper.DeclMap();
     }
-    
-    //------------------------------------------------------------------
-    /// Return the object that the parser should use when registering
-    /// local variables.  May be NULL if the Expression doesn't care.
-    //------------------------------------------------------------------
-    ExpressionVariableList *
-    LocalVariables ()
-    {
-        return NULL;
-    }
-    
-    //------------------------------------------------------------------
-    /// Return the object that the parser should allow to access ASTs.
-    /// May be NULL if the ASTs do not need to be transformed.
-    ///
-    /// @param[in] passthrough
-    ///     The ASTConsumer that the returned transformer should send
-    ///     the ASTs to after transformation.
-    //------------------------------------------------------------------
-    clang::ASTConsumer *
-    ASTTransformer(clang::ASTConsumer *passthrough) override
+
+    void
+    ResetDeclMap ()
     {
-        return NULL;
+        m_type_system_helper.ResetDeclMap();
     }
     
-    //------------------------------------------------------------------
-    /// Return true if validation code should be inserted into the
-    /// expression.
-    //------------------------------------------------------------------
-    bool
-    NeedsValidation() override
+    void
+    ResetDeclMap (ExecutionContext & exe_ctx, bool keep_result_in_memory)
     {
-        return false;
+        m_type_system_helper.ResetDeclMap(exe_ctx, keep_result_in_memory);
     }
     
-    //------------------------------------------------------------------
-    /// Return true if external variables in the expression should be
-    /// resolved.
-    //------------------------------------------------------------------
     bool
-    NeedsVariableResolution() override
-    {
-        return false;
-    }
+    Install (Stream &error_stream, ExecutionContext &exe_ctx) override;
     
 private:
-    std::unique_ptr<ClangExpressionDeclMap>  m_expr_decl_map;    ///< The map to use when parsing and materializing the expression.
-    std::shared_ptr<IRExecutionUnit>         m_execution_unit_sp;
-    lldb::ModuleWP                           m_jit_module_wp;
-    std::string                              m_function_text;    ///< The text of the function.  Must be a well-formed translation unit.
-    std::string                              m_function_name;    ///< The name of the function.
+    ClangUtilityFunctionHelper  m_type_system_helper;    ///< The map to use when parsing and materializing the expression.
 };
 
 } // namespace lldb_private

Added: lldb/trunk/include/lldb/Expression/Expression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/Expression.h?rev=247720&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Expression/Expression.h (added)
+++ lldb/trunk/include/lldb/Expression/Expression.h Tue Sep 15 16:13:50 2015
@@ -0,0 +1,140 @@
+//===-- Expression.h --------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Expression_h_
+#define liblldb_Expression_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+#include <map>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Expression/ExpressionTypeSystemHelper.h"
+
+namespace lldb_private {
+
+class RecordingMemoryManager;
+
+//----------------------------------------------------------------------
+/// @class Expression Expression.h "lldb/Expression/Expression.h"
+/// @brief Encapsulates a single expression for use in lldb
+///
+/// LLDB uses expressions for various purposes, notably to call functions
+/// and as a backend for the expr command.  Expression encapsulates
+/// the objects needed to parse and interpret or JIT an expression.  It
+/// uses the expression parser appropriate to the language of the expression
+/// to produce LLVM IR from the expression.
+//----------------------------------------------------------------------
+class Expression
+{
+public:
+    enum ResultType {
+        eResultTypeAny,
+        eResultTypeId
+    };
+    
+    Expression (Target &target);
+    
+    Expression (ExecutionContextScope &exe_scope);
+    
+    //------------------------------------------------------------------
+    /// Destructor
+    //------------------------------------------------------------------
+    virtual ~Expression ()
+    {
+    }
+    
+    //------------------------------------------------------------------
+    /// Return the string that the parser should parse.  Must be a full
+    /// translation unit.
+    //------------------------------------------------------------------
+    virtual const char *
+    Text () = 0;
+    
+    //------------------------------------------------------------------
+    /// Return the function name that should be used for executing the
+    /// expression.  Text() should contain the definition of this
+    /// function.
+    //------------------------------------------------------------------
+    virtual const char *
+    FunctionName () = 0;
+    
+    //------------------------------------------------------------------
+    /// Return the language that should be used when parsing.  To use
+    /// the default, return eLanguageTypeUnknown.
+    //------------------------------------------------------------------
+    virtual lldb::LanguageType
+    Language ()
+    {
+        return lldb::eLanguageTypeUnknown;
+    }
+    
+    //------------------------------------------------------------------
+    /// Return the desired result type of the function, or 
+    /// eResultTypeAny if indifferent.
+    //------------------------------------------------------------------
+    virtual ResultType
+    DesiredResultType ()
+    {
+        return eResultTypeAny;
+    }
+    
+    //------------------------------------------------------------------
+    /// Flags
+    //------------------------------------------------------------------
+    
+    //------------------------------------------------------------------
+    /// Return true if validation code should be inserted into the
+    /// expression.
+    //------------------------------------------------------------------
+    virtual bool
+    NeedsValidation () = 0;
+    
+    //------------------------------------------------------------------
+    /// Return true if external variables in the expression should be
+    /// resolved.
+    //------------------------------------------------------------------
+    virtual bool
+    NeedsVariableResolution () = 0;
+
+    //------------------------------------------------------------------
+    /// Return the address of the function's JIT-compiled code, or
+    /// LLDB_INVALID_ADDRESS if the function is not JIT compiled
+    //------------------------------------------------------------------
+    lldb::addr_t
+    StartAddress ()
+    {
+        return m_jit_start_addr;
+    }
+    
+    virtual ExpressionTypeSystemHelper *
+    GetTypeSystemHelper ()
+    {
+        return nullptr;
+    }
+
+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 it doesn't need to (e.g. calculator mode.)
+    lldb::addr_t    m_jit_start_addr;       ///< The address of the JITted function within the JIT allocation.  LLDB_INVALID_ADDRESS if invalid.
+    lldb::addr_t    m_jit_end_addr;         ///< The address of the JITted function within the JIT allocation.  LLDB_INVALID_ADDRESS if invalid.
+
+};
+
+} // namespace lldb_private
+
+#endif  // liblldb_Expression_h_

Added: lldb/trunk/include/lldb/Expression/ExpressionParser.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ExpressionParser.h?rev=247720&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Expression/ExpressionParser.h (added)
+++ lldb/trunk/include/lldb/Expression/ExpressionParser.h Tue Sep 15 16:13:50 2015
@@ -0,0 +1,129 @@
+//===-- ExpressionParser.h --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ExpressionParser_h_
+#define liblldb_ExpressionParser_h_
+
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Expression/IRForTarget.h"
+
+#include <string>
+#include <vector>
+
+namespace lldb_private
+{
+
+class IRExecutionUnit;
+    
+//----------------------------------------------------------------------
+/// @class ExpressionParser ExpressionParser.h "lldb/Expression/ExpressionParser.h"
+/// @brief Encapsulates an instance of a compiler that can parse expressions.
+///
+/// ExpressionParser is the base class for llvm based Expression parsers.
+//----------------------------------------------------------------------
+class ExpressionParser
+{
+public:
+    //------------------------------------------------------------------
+    /// Constructor
+    ///
+    /// Initializes class variables.
+    ///
+    /// @param[in] exe_scope,
+    ///     If non-NULL, an execution context scope that can help to 
+    ///     correctly create an expression with a valid process for 
+    ///     optional tuning Objective-C runtime support. Can be NULL.
+    ///
+    /// @param[in] expr
+    ///     The expression to be parsed.
+    //------------------------------------------------------------------
+    ExpressionParser (ExecutionContextScope *exe_scope,
+                           Expression &expr,
+                           bool generate_debug_info) :
+        m_expr(expr),
+        m_generate_debug_info(generate_debug_info)
+        {
+        }
+    
+    //------------------------------------------------------------------
+    /// Destructor
+    //------------------------------------------------------------------
+    virtual ~ExpressionParser () {};
+    
+    //------------------------------------------------------------------
+    /// Parse a single expression and convert it to IR using Clang.  Don't
+    /// wrap the expression in anything at all.
+    ///
+    /// @param[in] stream
+    ///     The stream to print errors to.
+    ///
+    /// @return
+    ///     The number of errors encountered during parsing.  0 means
+    ///     success.
+    //------------------------------------------------------------------
+    virtual unsigned
+    Parse (Stream &stream) = 0;
+    
+    //------------------------------------------------------------------
+    /// Ready an already-parsed expression for execution, possibly
+    /// evaluating it statically.
+    ///
+    /// @param[out] func_addr
+    ///     The address to which the function has been written.
+    ///
+    /// @param[out] func_end
+    ///     The end of the function's allocated memory region.  (func_addr
+    ///     and func_end do not delimit an allocated region; the allocated
+    ///     region may begin before func_addr.)
+    ///
+    /// @param[in] execution_unit_sp
+    ///     After parsing, ownership of the execution unit for
+    ///     for the expression is handed to this shared pointer.
+    ///
+    /// @param[in] exe_ctx
+    ///     The execution context to write the function into.
+    ///
+    /// @param[out] can_interpret
+    ///     Set to true if the expression could be interpreted statically;
+    ///     untouched otherwise.
+    ///
+    /// @param[in] execution_policy
+    ///     Determines whether the expression must be JIT-compiled, must be
+    ///     evaluated statically, or whether this decision may be made
+    ///     opportunistically.
+    ///
+    /// @return
+    ///     An error code indicating the success or failure of the operation.
+    ///     Test with Success().
+    //------------------------------------------------------------------
+    virtual Error
+    PrepareForExecution (lldb::addr_t &func_addr,
+                         lldb::addr_t &func_end,
+                         std::shared_ptr<IRExecutionUnit> &execution_unit_sp,
+                         ExecutionContext &exe_ctx,
+                         bool &can_interpret,
+                         lldb_private::ExecutionPolicy execution_policy) = 0;
+        
+    bool
+    GetGenerateDebugInfo () const
+    {
+        return m_generate_debug_info;
+    }
+    
+protected:
+    Expression &                       m_expr;                       ///< The expression to be parsed
+    bool                               m_generate_debug_info;
+};
+    
+}
+
+#endif  // liblldb_ExpressionParser_h_

Added: lldb/trunk/include/lldb/Expression/ExpressionTypeSystemHelper.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ExpressionTypeSystemHelper.h?rev=247720&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Expression/ExpressionTypeSystemHelper.h (added)
+++ lldb/trunk/include/lldb/Expression/ExpressionTypeSystemHelper.h Tue Sep 15 16:13:50 2015
@@ -0,0 +1,54 @@
+//===-- ExpressionTypeSystemHelper.h ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ExpressionTypeSystemHelper_h
+#define ExpressionTypeSystemHelper_h
+
+#include "llvm/Support/Casting.h"
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+/// @class ExpressionTypeSystemHelper ExpressionTypeSystemHelper.h "lldb/Expression/ExpressionTypeSystemHelper.h"
+/// @brief A helper object that the Expression can pass to its ExpressionParser to provide generic information that
+/// any type of expression will need to supply.  It's only job is to support dyn_cast so that the expression parser
+/// can cast it back to the requisite specific type.
+///
+//----------------------------------------------------------------------
+
+class ExpressionTypeSystemHelper
+{
+public:
+    enum LLVMCastKind {
+        eKindClangHelper,
+        eKindSwiftHelper,
+        eKindGoHelper,
+        kNumKinds
+    };
+
+    LLVMCastKind getKind() const { return m_kind; }
+
+    ExpressionTypeSystemHelper (LLVMCastKind kind) :
+        m_kind(kind)
+    {
+    }
+    
+    ~ExpressionTypeSystemHelper () {}
+
+protected:
+    LLVMCastKind m_kind;
+};
+
+
+
+
+} // namespace lldb_private
+
+#endif /* ExpressionTypeSystemHelper_h */

Added: lldb/trunk/include/lldb/Expression/FunctionCaller.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/FunctionCaller.h?rev=247720&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Expression/FunctionCaller.h (added)
+++ lldb/trunk/include/lldb/Expression/FunctionCaller.h Tue Sep 15 16:13:50 2015
@@ -0,0 +1,404 @@
+//===-- FunctionCaller.h -----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_FunctionCaller_h_
+#define liblldb_FunctionCaller_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+#include <list>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectList.h"
+#include "lldb/Expression/Expression.h"
+#include "lldb/Expression/ExpressionParser.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Target/Process.h"
+
+namespace lldb_private
+{
+    
+class ASTStructExtractor;
+class ClangExpressionParser;
+
+//----------------------------------------------------------------------
+/// @class FunctionCaller FunctionCaller.h "lldb/Expression/FunctionCaller.h"
+/// @brief Encapsulates a function that can be called.
+///
+/// A given FunctionCaller object can handle a single function signature.
+/// Once constructed, it can set up any number of concurrent calls to
+/// functions with that signature.
+///
+/// It performs the call by synthesizing a structure that contains the pointer
+/// to the function and the arguments that should be passed to that function,
+/// and producing a special-purpose JIT-compiled function that accepts a void*
+/// pointing to this struct as its only argument and calls the function in the 
+/// struct with the written arguments.  This method lets Clang handle the
+/// vagaries of function calling conventions.
+///
+/// The simplest use of the FunctionCaller is to construct it with a
+/// function representative of the signature you want to use, then call
+/// ExecuteFunction(ExecutionContext &, Stream &, Value &).
+///
+/// If you need to reuse the arguments for several calls, you can call
+/// InsertFunction() followed by WriteFunctionArguments(), which will return
+/// the location of the args struct for the wrapper function in args_addr_ref.
+///
+/// If you need to call the function on the thread plan stack, you can also 
+/// call InsertFunction() followed by GetThreadPlanToCallFunction().
+///
+/// Any of the methods that take arg_addr_ptr or arg_addr_ref can be passed
+/// a pointer set to LLDB_INVALID_ADDRESS and new structure will be allocated
+/// and its address returned in that variable.
+/// 
+/// Any of the methods that take arg_addr_ptr can be passed NULL, and the
+/// argument space will be managed for you.
+//----------------------------------------------------------------------    
+class FunctionCaller : public Expression
+{
+public:
+    //------------------------------------------------------------------
+    /// Constructor
+    ///
+    /// @param[in] exe_scope
+    ///     An execution context scope that gets us at least a target and 
+    ///     process.
+    ///
+    /// @param[in] ast_context
+    ///     The AST context to evaluate argument types in.
+    ///
+    /// @param[in] return_qualtype
+    ///     An opaque Clang QualType for the function result.  Should be
+    ///     defined in ast_context.
+    ///
+    /// @param[in] function_address
+    ///     The address of the function to call.
+    ///
+    /// @param[in] arg_value_list
+    ///     The default values to use when calling this function.  Can
+    ///     be overridden using WriteFunctionArguments().
+    //------------------------------------------------------------------
+    FunctionCaller (ExecutionContextScope &exe_scope,
+                   const CompilerType &return_type,
+                   const Address& function_address, 
+                   const ValueList &arg_value_list,
+                   const char *name);
+    
+    //------------------------------------------------------------------
+    /// Destructor
+    //------------------------------------------------------------------
+    ~FunctionCaller() override;
+
+    //------------------------------------------------------------------
+    /// Compile the wrapper function
+    ///
+    /// @param[in] errors
+    ///     The stream to print parser errors to.
+    ///
+    /// @return
+    ///     The number of errors.
+    //------------------------------------------------------------------
+    virtual unsigned
+    CompileFunction (Stream &errors) = 0;
+    
+    //------------------------------------------------------------------
+    /// Insert the default function wrapper and its default argument struct  
+    ///
+    /// @param[in] exe_ctx
+    ///     The execution context to insert the function and its arguments
+    ///     into.
+    ///
+    /// @param[in,out] args_addr_ref
+    ///     The address of the structure to write the arguments into.  May
+    ///     be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
+    ///     and args_addr_ref is pointed to it.
+    ///
+    /// @param[in] errors
+    ///     The stream to write errors to.
+    ///
+    /// @return
+    ///     True on success; false otherwise.
+    //------------------------------------------------------------------
+    bool
+    InsertFunction (ExecutionContext &exe_ctx,
+                    lldb::addr_t &args_addr_ref,
+                    Stream &errors);
+
+    //------------------------------------------------------------------
+    /// Insert the default function wrapper (using the JIT)
+    ///
+    /// @param[in] exe_ctx
+    ///     The execution context to insert the function and its arguments
+    ///     into.
+    ///
+    /// @param[in] errors
+    ///     The stream to write errors to.
+    ///
+    /// @return
+    ///     True on success; false otherwise.
+    //------------------------------------------------------------------
+    bool WriteFunctionWrapper (ExecutionContext &exe_ctx, 
+                               Stream &errors);
+    
+    //------------------------------------------------------------------
+    /// Insert the default function argument struct  
+    ///
+    /// @param[in] exe_ctx
+    ///     The execution context to insert the function and its arguments
+    ///     into.
+    ///
+    /// @param[in,out] args_addr_ref
+    ///     The address of the structure to write the arguments into.  May
+    ///     be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
+    ///     and args_addr_ref is pointed to it.
+    ///
+    /// @param[in] errors
+    ///     The stream to write errors to.
+    ///
+    /// @return
+    ///     True on success; false otherwise.
+    //------------------------------------------------------------------
+    bool WriteFunctionArguments (ExecutionContext &exe_ctx, 
+                                 lldb::addr_t &args_addr_ref, 
+                                 Stream &errors);
+    
+    //------------------------------------------------------------------
+    /// Insert an argument struct with a non-default function address and
+    /// non-default argument values
+    ///
+    /// @param[in] exe_ctx
+    ///     The execution context to insert the function and its arguments
+    ///     into.
+    ///
+    /// @param[in,out] args_addr_ref
+    ///     The address of the structure to write the arguments into.  May
+    ///     be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated
+    ///     and args_addr_ref is pointed at it.
+    ///
+    /// @param[in] arg_values
+    ///     The values of the function's arguments.
+    ///
+    /// @param[in] errors
+    ///     The stream to write errors to.
+    ///
+    /// @return
+    ///     True on success; false otherwise.
+    //------------------------------------------------------------------
+    bool WriteFunctionArguments (ExecutionContext &exe_ctx, 
+                                 lldb::addr_t &args_addr_ref, 
+                                 ValueList &arg_values,
+                                 Stream &errors);
+
+    //------------------------------------------------------------------
+    /// Run the function this FunctionCaller was created with.
+    ///
+    /// This is the full version.
+    ///
+    /// @param[in] exe_ctx
+    ///     The thread & process in which this function will run.
+    ///
+    /// @param[in] args_addr_ptr
+    ///     If NULL, the function will take care of allocating & deallocating the wrapper
+    ///     args structure.  Otherwise, if set to LLDB_INVALID_ADDRESS, a new structure
+    ///     will be allocated, filled and the address returned to you.  You are responsible
+    ///     for deallocating it.  And if passed in with a value other than LLDB_INVALID_ADDRESS,
+    ///     this should point to an already allocated structure with the values already written.
+    ///
+    /// @param[in] errors
+    ///     Errors will be written here if there are any.
+    ///
+    /// @param[in] options
+    ///     The options for this expression execution.
+    ///
+    /// @param[out] results
+    ///     The result value will be put here after running the function.
+    ///
+    /// @return
+    ///     Returns one of the ExpressionResults enum indicating function call status.
+    //------------------------------------------------------------------
+    lldb::ExpressionResults
+    ExecuteFunction(ExecutionContext &exe_ctx, 
+                    lldb::addr_t *args_addr_ptr, 
+                    const EvaluateExpressionOptions &options,
+                    Stream &errors,
+                    Value &results);
+    
+    //------------------------------------------------------------------
+    /// Get a thread plan to run the function this FunctionCaller was created with.
+    ///
+    /// @param[in] exe_ctx
+    ///     The execution context to insert the function and its arguments
+    ///     into.
+    ///
+    /// @param[in] func_addr
+    ///     The address of the function in the target process.
+    ///
+    /// @param[in] args_addr
+    ///     The address of the argument struct.
+    ///
+    /// @param[in] errors
+    ///     The stream to write errors to.
+    ///
+    /// @param[in] stop_others
+    ///     True if other threads should pause during execution.
+    ///
+    /// @param[in] unwind_on_error
+    ///     True if the thread plan may simply be discarded if an error occurs.
+    ///
+    /// @return
+    ///     A ThreadPlan shared pointer for executing the function.
+    //------------------------------------------------------------------
+    lldb::ThreadPlanSP
+    GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, 
+                                 lldb::addr_t args_addr,
+                                 const EvaluateExpressionOptions &options,
+                                 Stream &errors);
+    
+    //------------------------------------------------------------------
+    /// Get the result of the function from its struct
+    ///
+    /// @param[in] exe_ctx
+    ///     The execution context to retrieve the result from.
+    ///
+    /// @param[in] args_addr
+    ///     The address of the argument struct.
+    ///
+    /// @param[out] ret_value
+    ///     The value returned by the function.
+    ///
+    /// @return
+    ///     True on success; false otherwise.
+    //------------------------------------------------------------------
+    bool FetchFunctionResults (ExecutionContext &exe_ctx, 
+                               lldb::addr_t args_addr, 
+                               Value &ret_value);
+    
+    //------------------------------------------------------------------
+    /// Deallocate the arguments structure
+    ///
+    /// @param[in] exe_ctx
+    ///     The execution context to insert the function and its arguments
+    ///     into.
+    ///
+    /// @param[in] args_addr
+    ///     The address of the argument struct.
+    //------------------------------------------------------------------
+    void DeallocateFunctionResults (ExecutionContext &exe_ctx, 
+                                    lldb::addr_t args_addr);
+    
+    //------------------------------------------------------------------
+    /// Interface for ClangExpression
+    //------------------------------------------------------------------
+    
+    //------------------------------------------------------------------
+    /// Return the string that the parser should parse.  Must be a full
+    /// translation unit.
+    //------------------------------------------------------------------
+    const char *
+    Text() override
+    {
+        return m_wrapper_function_text.c_str();
+    }
+    
+    //------------------------------------------------------------------
+    /// Return the function name that should be used for executing the
+    /// expression.  Text() should contain the definition of this
+    /// function.
+    //------------------------------------------------------------------
+    const char *
+    FunctionName() override
+    {
+        return m_wrapper_function_name.c_str();
+    }
+    
+    //------------------------------------------------------------------
+    /// Return the object that the parser should use when registering
+    /// local variables.  May be NULL if the Expression doesn't care.
+    //------------------------------------------------------------------
+    ExpressionVariableList *
+    LocalVariables ()
+    {
+        return NULL;
+    }
+    
+    //------------------------------------------------------------------
+    /// Return true if validation code should be inserted into the
+    /// expression.
+    //------------------------------------------------------------------
+    bool
+    NeedsValidation() override
+    {
+        return false;
+    }
+    
+    //------------------------------------------------------------------
+    /// Return true if external variables in the expression should be
+    /// resolved.
+    //------------------------------------------------------------------
+    bool
+    NeedsVariableResolution() override
+    {
+        return false;
+    }
+    
+    ValueList
+    GetArgumentValues () const
+    {
+        return m_arg_values;
+    }
+protected:
+    //------------------------------------------------------------------
+    // For FunctionCaller only
+    //------------------------------------------------------------------
+
+    // Note: the parser needs to be destructed before the execution unit, so
+    // declare the execution unit first.
+    std::shared_ptr<IRExecutionUnit> m_execution_unit_sp;
+    std::unique_ptr<ExpressionParser> m_parser;                     ///< The parser responsible for compiling the function.
+                                                                    ///< This will get made in CompileFunction, so it is
+                                                                    ///< safe to access it after that.
+
+    lldb::ModuleWP                  m_jit_module_wp;
+    std::string                     m_name;                         ///< The name of this clang function - for debugging purposes.
+    
+    Function                       *m_function_ptr;                 ///< The function we're going to call.  May be NULL if we don't have debug info for the function.
+    Address                         m_function_addr;                ///< If we don't have the FunctionSP, we at least need the address & return type.
+    CompilerType                    m_function_return_type;         ///< The opaque clang qual type for the function return type.
+
+    std::string                     m_wrapper_function_name;        ///< The name of the wrapper function.
+    std::string                     m_wrapper_function_text;        ///< The contents of the wrapper function.
+    std::string                     m_wrapper_struct_name;          ///< The name of the struct that contains the target function address, arguments, and result.
+    std::list<lldb::addr_t>         m_wrapper_args_addrs;           ///< The addresses of the arguments to the wrapper function.
+    
+    std::unique_ptr<ASTStructExtractor> m_struct_extractor;         ///< The class that generates the argument struct below.
+
+    bool                            m_struct_valid;                 ///< True if the ASTStructExtractor has populated the variables below.
+    
+    //------------------------------------------------------------------
+    /// These values are populated by the ASTStructExtractor
+    size_t                          m_struct_size;                  ///< The size of the argument struct, in bytes.
+    std::vector<uint64_t>           m_member_offsets;               ///< The offset of each member in the struct, in bytes.
+    uint64_t                        m_return_size;                  ///< The size of the result variable, in bytes.
+    uint64_t                        m_return_offset;                ///< The offset of the result variable in the struct, in bytes.
+    //------------------------------------------------------------------
+
+    ValueList                       m_arg_values;                   ///< The default values of the arguments.
+    
+    bool                            m_compiled;                     ///< True if the wrapper function has already been parsed.
+    bool                            m_JITted;                       ///< True if the wrapper function has already been JIT-compiled.
+};
+
+} // Namespace lldb_private
+
+#endif // liblldb_FunctionCaller_h_

Modified: lldb/trunk/include/lldb/Expression/IRDynamicChecks.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRDynamicChecks.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/IRDynamicChecks.h (original)
+++ lldb/trunk/include/lldb/Expression/IRDynamicChecks.h Tue Sep 15 16:13:50 2015
@@ -28,7 +28,6 @@ namespace lldb_private
 {
 
 class ClangExpressionDeclMap;
-class ClangUtilityFunction;
 class ExecutionContext;
 class Stream;
 
@@ -77,8 +76,8 @@ public:
     
     bool DoCheckersExplainStop (lldb::addr_t addr, Stream &message);
     
-    std::unique_ptr<ClangUtilityFunction> m_valid_pointer_check;
-    std::unique_ptr<ClangUtilityFunction> m_objc_object_check;
+    std::unique_ptr<UtilityFunction> m_valid_pointer_check;
+    std::unique_ptr<UtilityFunction> m_objc_object_check;
 };
 
 //----------------------------------------------------------------------

Modified: lldb/trunk/include/lldb/Expression/IRExecutionUnit.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRExecutionUnit.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/IRExecutionUnit.h (original)
+++ lldb/trunk/include/lldb/Expression/IRExecutionUnit.h Tue Sep 15 16:13:50 2015
@@ -26,7 +26,6 @@
 #include "lldb/Core/ClangForward.h"
 #include "lldb/Core/DataBufferHeap.h"
 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
-#include "lldb/Expression/ClangExpression.h"
 #include "lldb/Expression/ClangExpressionParser.h"
 #include "lldb/Expression/IRMemoryMap.h"
 #include "lldb/Host/Mutex.h"

Added: lldb/trunk/include/lldb/Expression/UserExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/UserExpression.h?rev=247720&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Expression/UserExpression.h (added)
+++ lldb/trunk/include/lldb/Expression/UserExpression.h Tue Sep 15 16:13:50 2015
@@ -0,0 +1,361 @@
+//===-- UserExpression.h -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_UserExpression_h_
+#define liblldb_UserExpression_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+#include <map>
+#include <vector>
+
+// Other libraries and framework includes
+
+#include "llvm/ADT/ArrayRef.h"
+
+// Project includes
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Expression/ClangExpressionHelper.h"
+#include "lldb/Expression/Expression.h"
+#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
+#include "lldb/Expression/IRForTarget.h"
+#include "lldb/Expression/Materializer.h"
+#include "lldb/Symbol/TaggedASTType.h"
+#include "lldb/Target/ExecutionContext.h"
+
+namespace lldb_private
+{
+
+//----------------------------------------------------------------------
+/// @class UserExpression UserExpression.h "lldb/Expression/UserExpression.h"
+/// @brief Encapsulates a one-time expression for use in lldb.
+///
+/// LLDB uses expressions for various purposes, notably to call functions
+/// and as a backend for the expr command.  UserExpression is a virtual base
+/// class that encapsulates the objects needed to parse and interpret or
+/// JIT an expression.  The actual parsing part will be provided by the specific
+/// implementations of UserExpression - which will be vended through the
+/// appropriate TypeSystem.
+//----------------------------------------------------------------------
+class UserExpression : public Expression
+{
+public:
+
+    enum { kDefaultTimeout = 500000u };
+    //------------------------------------------------------------------
+    /// Constructor
+    ///
+    /// @param[in] expr
+    ///     The expression to parse.
+    ///
+    /// @param[in] expr_prefix
+    ///     If non-NULL, a C string containing translation-unit level
+    ///     definitions to be included when the expression is parsed.
+    ///
+    /// @param[in] language
+    ///     If not eLanguageTypeUnknown, a language to use when parsing
+    ///     the expression.  Currently restricted to those languages
+    ///     supported by Clang.
+    ///
+    /// @param[in] desired_type
+    ///     If not eResultTypeAny, the type to use for the expression
+    ///     result.
+    //------------------------------------------------------------------
+    UserExpression (ExecutionContextScope &exe_scope,
+                    const char *expr,
+                    const char *expr_prefix,
+                    lldb::LanguageType language,
+                    ResultType desired_type);
+
+    //------------------------------------------------------------------
+    /// Destructor
+    //------------------------------------------------------------------
+    ~UserExpression() override;
+
+    //------------------------------------------------------------------
+    /// Parse the expression
+    ///
+    /// @param[in] error_stream
+    ///     A stream to print parse errors and warnings to.
+    ///
+    /// @param[in] exe_ctx
+    ///     The execution context to use when looking up entities that
+    ///     are needed for parsing (locations of functions, types of
+    ///     variables, persistent variables, etc.)
+    ///
+    /// @param[in] execution_policy
+    ///     Determines whether interpretation is possible or mandatory.
+    ///
+    /// @param[in] keep_result_in_memory
+    ///     True if the resulting persistent variable should reside in
+    ///     target memory, if applicable.
+    ///
+    /// @return
+    ///     True on success (no errors); false otherwise.
+    //------------------------------------------------------------------
+    virtual bool
+    Parse (Stream &error_stream,
+           ExecutionContext &exe_ctx,
+           lldb_private::ExecutionPolicy execution_policy,
+           bool keep_result_in_memory,
+           bool generate_debug_info) = 0;
+
+    bool
+    CanInterpret ()
+    {
+        return m_can_interpret;
+    }
+
+    bool
+    MatchesContext (ExecutionContext &exe_ctx);
+
+    //------------------------------------------------------------------
+    /// Execute the parsed expression
+    ///
+    /// @param[in] error_stream
+    ///     A stream to print errors to.
+    ///
+    /// @param[in] exe_ctx
+    ///     The execution context to use when looking up entities that
+    ///     are needed for parsing (locations of variables, etc.)
+    ///
+    /// @param[in] options
+    ///     Expression evaluation options.
+    ///
+    /// @param[in] shared_ptr_to_me
+    ///     This is a shared pointer to this UserExpression.  This is
+    ///     needed because Execute can push a thread plan that will hold onto
+    ///     the UserExpression for an unbounded period of time.  So you
+    ///     need to give the thread plan a reference to this object that can
+    ///     keep it alive.
+    ///
+    /// @param[in] result
+    ///     A pointer to direct at the persistent variable in which the
+    ///     expression's result is stored.
+    ///
+    /// @return
+    ///     A Process::Execution results value.
+    //------------------------------------------------------------------
+    lldb::ExpressionResults
+    Execute (Stream &error_stream,
+             ExecutionContext &exe_ctx,
+             const EvaluateExpressionOptions& options,
+             lldb::UserExpressionSP &shared_ptr_to_me,
+             lldb::ExpressionVariableSP &result);
+
+    //------------------------------------------------------------------
+    /// Apply the side effects of the function to program state.
+    ///
+    /// @param[in] error_stream
+    ///     A stream to print errors to.
+    ///
+    /// @param[in] exe_ctx
+    ///     The execution context to use when looking up entities that
+    ///     are needed for parsing (locations of variables, etc.)
+    ///
+    /// @param[in] result
+    ///     A pointer to direct at the persistent variable in which the
+    ///     expression's result is stored.
+    ///
+    /// @param[in] function_stack_pointer
+    ///     A pointer to the base of the function's stack frame.  This
+    ///     is used to determine whether the expression result resides in
+    ///     memory that will still be valid, or whether it needs to be
+    ///     treated as homeless for the purpose of future expressions.
+    ///
+    /// @return
+    ///     A Process::Execution results value.
+    //------------------------------------------------------------------
+    bool
+    FinalizeJITExecution (Stream &error_stream,
+                          ExecutionContext &exe_ctx,
+                          lldb::ExpressionVariableSP &result,
+                          lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
+                          lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS);
+
+    //------------------------------------------------------------------
+    /// Return the string that the parser should parse.  Must be a full
+    /// translation unit.
+    //------------------------------------------------------------------
+    const char *
+    Text() override
+    {
+        return m_transformed_text.c_str();
+    }
+
+    //------------------------------------------------------------------
+    /// Return the string that the user typed.
+    //------------------------------------------------------------------
+    const char *
+    GetUserText ()
+    {
+        return m_expr_text.c_str();
+    }
+
+    //------------------------------------------------------------------
+    /// Return the function name that should be used for executing the
+    /// expression.  Text() should contain the definition of this
+    /// function.
+    //------------------------------------------------------------------
+    const char *
+    FunctionName() override
+    {
+        return "$__lldb_expr";
+    }
+
+    //------------------------------------------------------------------
+    /// Return the language that should be used when parsing.  To use
+    /// the default, return eLanguageTypeUnknown.
+    //------------------------------------------------------------------
+    lldb::LanguageType
+    Language() override
+    {
+        return m_language;
+    }
+
+    //------------------------------------------------------------------
+    /// Return the desired result type of the function, or
+    /// eResultTypeAny if indifferent.
+    //------------------------------------------------------------------
+    ResultType
+    DesiredResultType() override
+    {
+        return m_desired_type;
+    }
+
+    //------------------------------------------------------------------
+    /// Return true if validation code should be inserted into the
+    /// expression.
+    //------------------------------------------------------------------
+    bool
+    NeedsValidation() override
+    {
+        return true;
+    }
+
+    //------------------------------------------------------------------
+    /// Return true if external variables in the expression should be
+    /// resolved.
+    //------------------------------------------------------------------
+    bool
+    NeedsVariableResolution() override
+    {
+        return true;
+    }
+
+    //------------------------------------------------------------------
+    /// Evaluate one expression in the scratch context of the
+    /// target passed in the exe_ctx and return its result.
+    ///
+    /// @param[in] exe_ctx
+    ///     The execution context to use when evaluating the expression.
+    ///
+    /// @param[in] options
+    ///     Expression evaluation options.  N.B. The language in the
+    ///     evaluation options will be used to determine the language used for
+    ///     expression evaluation.
+    ///
+    /// @param[in] expr_cstr
+    ///     A C string containing the expression to be evaluated.
+    ///
+    /// @param[in] expr_prefix
+    ///     If non-NULL, a C string containing translation-unit level
+    ///     definitions to be included when the expression is parsed.
+    ///
+    /// @param[in,out] result_valobj_sp
+    ///      If execution is successful, the result valobj is placed here.
+    ///
+    /// @param[out]
+    ///     Filled in with an error in case the expression evaluation
+    ///     fails to parse, run, or evaluated.
+    ///
+    /// @result
+    ///      A Process::ExpressionResults value.  eExpressionCompleted for success.
+    //------------------------------------------------------------------
+    static lldb::ExpressionResults
+    Evaluate (ExecutionContext &exe_ctx,
+              const EvaluateExpressionOptions& options,
+              const char *expr_cstr,
+              const char *expr_prefix,
+              lldb::ValueObjectSP &result_valobj_sp,
+              Error &error);
+
+    static const Error::ValueType kNoResult = 0x1001; ///< ValueObject::GetError() returns this if there is no result from the expression.
+protected:
+    static lldb::addr_t
+    GetObjectPointer (lldb::StackFrameSP frame_sp,
+                      ConstString &object_name,
+                      Error &err);
+
+    //------------------------------------------------------------------
+    /// Populate m_in_cplusplus_method and m_in_objectivec_method based on the environment.
+    //------------------------------------------------------------------
+
+    virtual void
+    ScanContext (ExecutionContext &exe_ctx,
+                 lldb_private::Error &err) = 0;
+
+    bool
+    PrepareToExecuteJITExpression (Stream &error_stream,
+                                   ExecutionContext &exe_ctx,
+                                   lldb::addr_t &struct_address);
+    
+    virtual bool
+    AddInitialArguments (ExecutionContext &exe_ctx,
+                         std::vector<lldb::addr_t> &args,
+                         Stream &error_stream)
+    {
+        return true;
+    }
+
+    void
+    InstallContext (ExecutionContext &exe_ctx);
+
+    bool
+    LockAndCheckContext (ExecutionContext &exe_ctx,
+                         lldb::TargetSP &target_sp,
+                         lldb::ProcessSP &process_sp,
+                         lldb::StackFrameSP &frame_sp);
+
+    Address                                     m_address;              ///< The address the process is stopped in.
+    lldb::addr_t                                m_stack_frame_bottom;   ///< The bottom of the allocated stack frame.
+    lldb::addr_t                                m_stack_frame_top;      ///< The top of the allocated stack frame.
+
+    std::string                                 m_expr_text;            ///< The text of the expression, as typed by the user
+    std::string                                 m_expr_prefix;          ///< The text of the translation-level definitions, as provided by the user
+    lldb::LanguageType                          m_language;             ///< The language to use when parsing (eLanguageTypeUnknown means use defaults)
+    bool                                        m_allow_cxx;            ///< True if the language allows C++.
+    bool                                        m_allow_objc;           ///< True if the language allows Objective-C.
+    std::string                                 m_transformed_text;     ///< The text of the expression, as send to the parser
+    ResultType                                  m_desired_type;         ///< The type to coerce the expression's result to.  If eResultTypeAny, inferred from the expression.
+
+    std::shared_ptr<IRExecutionUnit>            m_execution_unit_sp;    ///< The execution unit the expression is stored in.
+    std::unique_ptr<Materializer>               m_materializer_ap;      ///< The materializer to use when running the expression.
+    lldb::ModuleWP                              m_jit_module_wp;
+    bool                                        m_enforce_valid_object; ///< True if the expression parser should enforce the presence of a valid class pointer in order to generate the expression as a method.
+    bool                                        m_in_cplusplus_method;  ///< True if the expression is compiled as a C++ member function (true if it was parsed when exe_ctx was in a C++ method).
+    bool                                        m_in_objectivec_method; ///< True if the expression is compiled as an Objective-C method (true if it was parsed when exe_ctx was in an Objective-C method).
+    bool                                        m_in_static_method;     ///< True if the expression is compiled as a static (or class) method (currently true if it was parsed when exe_ctx was in an Objective-C class method).
+    bool                                        m_needs_object_ptr;     ///< True if "this" or "self" must be looked up and passed in.  False if the expression doesn't really use them and they can be NULL.
+    bool                                        m_const_object;         ///< True if "this" is const.
+    Target                                     *m_target;               ///< The target for storing persistent data like types and variables.
+
+    bool                                        m_can_interpret;        ///< True if the expression could be evaluated statically; false otherwise.
+    lldb::addr_t                                m_materialized_address; ///< The address at which the arguments to the expression have been materialized.
+    Materializer::DematerializerSP              m_dematerializer_sp;    ///< The dematerializer.
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_UserExpression_h_

Added: lldb/trunk/include/lldb/Expression/UtilityFunction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/UtilityFunction.h?rev=247720&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Expression/UtilityFunction.h (added)
+++ lldb/trunk/include/lldb/Expression/UtilityFunction.h Tue Sep 15 16:13:50 2015
@@ -0,0 +1,166 @@
+//===-- UtilityFunction.h ----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_UtilityFunction_h_
+#define liblldb_UtilityFunction_h_
+
+// C Includes
+// C++ Includes
+#include <string>
+#include <map>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private.h"
+#include "lldb/Core/ClangForward.h"
+#include "lldb/Expression/Expression.h"
+
+namespace lldb_private 
+{
+
+//----------------------------------------------------------------------
+/// @class UtilityFunction UtilityFunction.h "lldb/Expression/UtilityFunction.h"
+/// @brief Encapsulates a bit of source code that provides a function that is callable
+///
+/// LLDB uses expressions for various purposes, notably to call functions
+/// and as a backend for the expr command.  UtilityFunction encapsulates
+/// a self-contained function meant to be used from other code.  Utility
+/// functions can perform error-checking for ClangUserExpressions, 
+//----------------------------------------------------------------------
+class UtilityFunction : public Expression
+{
+public:
+    //------------------------------------------------------------------
+    /// Constructor
+    ///
+    /// @param[in] text
+    ///     The text of the function.  Must be a full translation unit.
+    ///
+    /// @param[in] name
+    ///     The name of the function, as used in the text.
+    //------------------------------------------------------------------
+    UtilityFunction (ExecutionContextScope &exe_scope,
+                     const char *text,
+                     const char *name);
+    
+    ~UtilityFunction() override;
+
+    //------------------------------------------------------------------
+    /// Install the utility function into a process
+    ///
+    /// @param[in] error_stream
+    ///     A stream to print parse errors and warnings to.
+    ///
+    /// @param[in] exe_ctx
+    ///     The execution context to install the utility function to.
+    ///
+    /// @return
+    ///     True on success (no errors); false otherwise.
+    //------------------------------------------------------------------
+    virtual bool
+    Install (Stream &error_stream, ExecutionContext &exe_ctx) = 0;
+    
+    //------------------------------------------------------------------
+    /// Check whether the given PC is inside the function
+    ///
+    /// Especially useful if the function dereferences NULL to indicate a failed
+    /// assert.
+    ///
+    /// @param[in] pc
+    ///     The program counter to check.
+    ///
+    /// @return
+    ///     True if the program counter falls within the function's bounds;
+    ///     false if not (or the function is not JIT compiled)
+    //------------------------------------------------------------------
+    bool
+    ContainsAddress (lldb::addr_t address)
+    {
+        // nothing is both >= LLDB_INVALID_ADDRESS and < LLDB_INVALID_ADDRESS,
+        // so this always returns false if the function is not JIT compiled yet
+        return (address >= m_jit_start_addr && address < m_jit_end_addr);
+    }
+    
+    
+    //------------------------------------------------------------------
+    /// Return the string that the parser should parse.  Must be a full
+    /// translation unit.
+    //------------------------------------------------------------------
+    const char *
+    Text() override
+    {
+        return m_function_text.c_str();
+    }
+    
+    //------------------------------------------------------------------
+    /// Return the function name that should be used for executing the
+    /// expression.  Text() should contain the definition of this
+    /// function.
+    //------------------------------------------------------------------
+    const char *
+    FunctionName() override
+    {
+        return m_function_name.c_str();
+    }
+    
+    //------------------------------------------------------------------
+    /// Return the object that the parser should use when registering
+    /// local variables.  May be NULL if the Expression doesn't care.
+    //------------------------------------------------------------------
+    ExpressionVariableList *
+    LocalVariables ()
+    {
+        return NULL;
+    }
+    
+    //------------------------------------------------------------------
+    /// Return true if validation code should be inserted into the
+    /// expression.
+    //------------------------------------------------------------------
+    bool
+    NeedsValidation() override
+    {
+        return false;
+    }
+    
+    //------------------------------------------------------------------
+    /// Return true if external variables in the expression should be
+    /// resolved.
+    //------------------------------------------------------------------
+    bool
+    NeedsVariableResolution() override
+    {
+        return false;
+    }
+    
+    // This makes the function caller function.
+    FunctionCaller *
+    MakeFunctionCaller(const CompilerType &return_type, const ValueList &arg_value_list, Error &error);
+    
+    // This one retrieves the function caller that is already made.  If you haven't made it yet, this returns nullptr
+    FunctionCaller *
+    GetFunctionCaller()
+    {
+        return m_caller_up.get();
+    }
+    
+protected:
+    std::shared_ptr<IRExecutionUnit>         m_execution_unit_sp;
+    lldb::ModuleWP                           m_jit_module_wp;
+    std::string                              m_function_text;    ///< The text of the function.  Must be a well-formed translation unit.
+    std::string                              m_function_name;    ///< The name of the function.
+    std::unique_ptr<FunctionCaller>          m_caller_up;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_UtilityFunction_h_

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Tue Sep 15 16:13:50 2015
@@ -1109,6 +1109,7 @@ protected:
     void *                                          m_callback_baton;
     uint32_t                                        m_pointer_byte_size;
     bool                                            m_ast_owned;
+    bool                                            m_can_evaluate_expressions;
 
 private:
     //------------------------------------------------------------------
@@ -1118,6 +1119,31 @@ private:
     const ClangASTContext& operator=(const ClangASTContext&);
 };
 
+class ClangASTContextForExpressions : public ClangASTContext
+{
+public:
+    ClangASTContextForExpressions (Target &target);
+    
+    virtual ~ClangASTContextForExpressions () {}
+    
+    UserExpression *
+    GetUserExpression (const char *expr,
+                       const char *expr_prefix,
+                       lldb::LanguageType language,
+                       Expression::ResultType desired_type) override;
+    
+    FunctionCaller *
+    GetFunctionCaller (const CompilerType &return_type,
+                       const Address& function_address,
+                       const ValueList &arg_value_list,
+                       const char *name) override;
+    
+    UtilityFunction *
+    GetUtilityFunction(const char *text, const char *name) override;
+private:
+    lldb::TargetWP m_target_wp;
+};
+
 } // namespace lldb_private
 
 #endif // liblldb_ClangASTContext_h_

Modified: lldb/trunk/include/lldb/Symbol/TypeSystem.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/TypeSystem.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/TypeSystem.h (original)
+++ lldb/trunk/include/lldb/Symbol/TypeSystem.h Tue Sep 15 16:13:50 2015
@@ -14,6 +14,7 @@
 #include <string>
 #include "lldb/lldb-private.h"
 #include "lldb/Core/ClangForward.h"
+#include "lldb/Expression/Expression.h"
 #include "lldb/Symbol/CompilerDeclContext.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/Type.h"
@@ -438,6 +439,31 @@ public:
     
     virtual bool
     IsReferenceType (void *type, CompilerType *pointee_type, bool* is_rvalue) = 0;
+    
+    virtual UserExpression *
+    GetUserExpression (const char *expr,
+                       const char *expr_prefix,
+                       lldb::LanguageType language,
+                       Expression::ResultType desired_type)
+    {
+        return nullptr;
+    }
+    
+    virtual FunctionCaller *
+    GetFunctionCaller (const CompilerType &return_type,
+                       const Address& function_address,
+                       const ValueList &arg_value_list,
+                       const char *name)
+    {
+        return nullptr;
+    }
+    
+    virtual UtilityFunction *
+    GetUtilityFunction(const char *text, const char *name)
+    {
+        return nullptr;
+    }
+    
 protected:
     const LLVMCastKind m_kind; // Support for llvm casting
     SymbolFile *m_sym_file;

Modified: lldb/trunk/include/lldb/Target/LanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/LanguageRuntime.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/LanguageRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/LanguageRuntime.h Tue Sep 15 16:13:50 2015
@@ -97,6 +97,12 @@ public:
     {
         return m_process;
     }
+    
+    Target&
+    GetTargetRef()
+    {
+        return m_process->GetTarget();
+    }
 
     virtual lldb::BreakpointResolverSP
     CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp) = 0;

Modified: lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h Tue Sep 15 16:13:50 2015
@@ -30,7 +30,7 @@ class CommandObjectObjC_ClassTable_Dump;
 
 namespace lldb_private {
     
-class ClangUtilityFunction;
+class UtilityFunction;
 
 class ObjCLanguageRuntime :
     public LanguageRuntime
@@ -289,7 +289,7 @@ public:
     lldb::TypeSP
     LookupInCompleteClassCache (ConstString &name);
     
-    virtual ClangUtilityFunction *
+    virtual UtilityFunction *
     CreateObjectChecker (const char *) = 0;
     
     virtual ObjCRuntimeVersions

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Tue Sep 15 16:13:50 2015
@@ -742,7 +742,7 @@ class Process :
     public ExecutionContextScope,
     public PluginInterface
 {
-    friend class ClangFunction;     // For WaitForStateChangeEventsPrivate
+    friend class FunctionCaller;     // For WaitForStateChangeEventsPrivate
     friend class Debugger;          // For PopProcessIOHandler and ProcessIOHandlerIsActive
     friend class ProcessEventData;
     friend class StopInfo;

Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Tue Sep 15 16:13:50 2015
@@ -24,6 +24,7 @@
 #include "lldb/Core/Disassembler.h"
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/UserSettingsController.h"
+#include "lldb/Expression/Expression.h"
 #include "lldb/Target/ExecutionContextScope.h"
 #include "lldb/Target/PathMappingList.h"
 #include "lldb/Target/ProcessLaunchInfo.h"
@@ -1227,12 +1228,47 @@ public:
     PathMappingList &
     GetImageSearchPathList ();
     
+    TypeSystem *
+    GetScratchTypeSystemForLanguage (lldb::LanguageType language, bool create_on_demand = true);
+    
+    // Creates a UserExpression for the given language, the rest of the parameters have the
+    // same meaning as for the UserExpression constructor.
+    // Returns a new-ed object which the caller owns.
+    
+    UserExpression *
+    GetUserExpressionForLanguage(const char *expr,
+                                 const char *expr_prefix,
+                                 lldb::LanguageType language,
+                                 Expression::ResultType desired_type,
+                                 Error &error);
+    
+    // Creates a FunctionCaller for the given language, the rest of the parameters have the
+    // same meaning as for the FunctionCaller constructor.  Since a FunctionCaller can't be
+    // IR Interpreted, it makes no sense to call this with an ExecutionContextScope that lacks
+    // a Process.
+    // Returns a new-ed object which the caller owns.
+    
+    FunctionCaller *
+    GetFunctionCallerForLanguage (lldb::LanguageType language,
+                                  const CompilerType &return_type,
+                                  const Address& function_address,
+                                  const ValueList &arg_value_list,
+                                  const char *name,
+                                  Error &error);
+    
+    // Creates a UtilityFunction for the given language, the rest of the parameters have the
+    // same meaning as for the UtilityFunction constructor.
+    // Returns a new-ed object which the caller owns.
+    
+    UtilityFunction *
+    GetUtilityFunctionForLanguage (const char *expr,
+                                   lldb::LanguageType language,
+                                   const char *name,
+                                   Error &error);
+
     ClangASTContext *
     GetScratchClangASTContext(bool create_on_demand=true);
     
-    TypeSystem*
-    GetTypeSystemForLanguage (lldb::LanguageType language);
-    
     ClangASTImporter *
     GetClangASTImporter();
     

Modified: lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h Tue Sep 15 16:13:50 2015
@@ -92,7 +92,7 @@ public:
         return m_function_sp;
     }
     
-    // Classes that derive from ClangFunction, and implement
+    // Classes that derive from FunctionCaller, and implement
     // their own WillPop methods should call this so that the
     // thread state gets restored if the plan gets discarded.
     void

Modified: lldb/trunk/include/lldb/Target/ThreadPlanCallUserExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanCallUserExpression.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanCallUserExpression.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanCallUserExpression.h Tue Sep 15 16:13:50 2015
@@ -30,7 +30,7 @@ public:
                                   Address &function,
                                   llvm::ArrayRef<lldb::addr_t> args,
                                   const EvaluateExpressionOptions &options,
-                                  lldb::ClangUserExpressionSP &user_expression_sp);
+                                  lldb::UserExpressionSP &user_expression_sp);
     
     ~ThreadPlanCallUserExpression() override;
 
@@ -60,7 +60,7 @@ public:
     
 protected:
 private:
-    lldb::ClangUserExpressionSP m_user_expression_sp;    // This is currently just used to ensure the
+    lldb::UserExpressionSP m_user_expression_sp;    // This is currently just used to ensure the
                                                          // User expression the initiated this ThreadPlan
                                                          // lives as long as the thread plan does.
     bool m_manage_materialization = false;

Modified: lldb/trunk/include/lldb/lldb-forward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Tue Sep 15 16:13:50 2015
@@ -27,6 +27,7 @@ class   AddressResolver;
 class   ArchSpec;
 class   Args;
 class   ASTResultSynthesizer;
+class   ASTStructExtractor;
 class   Baton;
 class   Block;
 class   Breakpoint;
@@ -48,16 +49,12 @@ class   ClangASTContext;
 class   ClangASTImporter;
 class   ClangASTMetadata;
 class   ClangASTSource;
-class   ClangExpression;
 class   ClangExpressionDeclMap;
 class   ClangExpressionParser;
 class   ClangExpressionVariable;
 class   ClangExpressionVariables;
-class   ClangFunction;
 class   ClangModulesDeclVendor;
 class   ClangPersistentVariables;
-class   ClangUserExpression;
-class   ClangUtilityFunction;
 class   CommandInterpreter;
 class   CommandInterpreterRunOptions;
 class   CommandObject;
@@ -93,8 +90,10 @@ class   ExecutionContext;
 class   ExecutionContextRef;
 class   ExecutionContextRefLocker;
 class   ExecutionContextScope;
+class   Expression;
 class   ExpressionVariable;
 class   ExpressionVariableList;
+class   ExpressionTypeSystemHelper;
 class   File;
 class   FileSpec;
 class   FileSpecList;
@@ -163,6 +162,7 @@ class   OptionValueUInt64;
 class   OptionValueUUID;
 class   NamedOption;
 class   PathMappingList;
+class   FunctionCaller;
 class   Platform;
 class   Process;
 class   ProcessAttachInfo;
@@ -268,6 +268,8 @@ class   Unwind;
 class   UnwindAssembly;
 class   UnwindPlan;
 class   UnwindTable;
+class   UserExpression;
+class   UtilityFunction;
 class   VMRange;
 class   Value;
 class   ValueList;
@@ -308,7 +310,7 @@ namespace lldb {
     typedef std::unique_ptr<lldb_private::ClangASTSource> ClangASTSourceUP;
     typedef std::unique_ptr<lldb_private::ClangModulesDeclVendor> ClangModulesDeclVendorUP;
     typedef std::unique_ptr<lldb_private::ClangPersistentVariables> ClangPersistentVariablesUP;
-    typedef std::shared_ptr<lldb_private::ClangUserExpression> ClangUserExpressionSP;
+    typedef std::shared_ptr<lldb_private::UserExpression> UserExpressionSP;
     typedef std::shared_ptr<lldb_private::CommandObject> CommandObjectSP;
     typedef std::shared_ptr<lldb_private::Communication> CommunicationSP;
     typedef std::shared_ptr<lldb_private::Connection> ConnectionSP;
@@ -326,6 +328,7 @@ namespace lldb {
     typedef std::shared_ptr<lldb_private::ExpressionVariable> ExpressionVariableSP;
     typedef std::shared_ptr<lldb_private::File> FileSP;
     typedef std::shared_ptr<lldb_private::Function> FunctionSP;
+    typedef std::shared_ptr<lldb_private::FunctionCaller> FunctionCallerSP;
     typedef std::shared_ptr<lldb_private::FuncUnwinders> FuncUnwindersSP;
     typedef std::unique_ptr<lldb_private::GoASTContext> GoASTContextUP;
     typedef std::shared_ptr<lldb_private::InlineFunctionInfo> InlineFunctionInfoSP;
@@ -434,6 +437,7 @@ namespace lldb {
     typedef std::weak_ptr<lldb_private::UnixSignals> UnixSignalsWP;
     typedef std::shared_ptr<lldb_private::UnwindAssembly> UnwindAssemblySP;
     typedef std::shared_ptr<lldb_private::UnwindPlan> UnwindPlanSP;
+    typedef std::shared_ptr<lldb_private::UtilityFunction> UtilityFunctionSP;
     typedef lldb_private::SharingPtr<lldb_private::ValueObject> ValueObjectSP;
     typedef std::shared_ptr<lldb_private::Value> ValueSP;
     typedef std::shared_ptr<lldb_private::ValueList> ValueListSP;

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Sep 15 16:13:50 2015
@@ -387,7 +387,7 @@
 		2689005C13353E0400698AC0 /* ValueObjectVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E9D10F1B85900F91463 /* ValueObjectVariable.cpp */; };
 		2689005D13353E0400698AC0 /* VMRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E9E10F1B85900F91463 /* VMRange.cpp */; };
 		2689005E13353E0E00698AC0 /* ClangASTSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D7072811B5AD11001AD875 /* ClangASTSource.cpp */; };
-		2689005F13353E0E00698AC0 /* ClangFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C98D3DA118FB96F00E575D0 /* ClangFunction.cpp */; };
+		2689005F13353E0E00698AC0 /* ClangFunctionCaller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C98D3DA118FB96F00E575D0 /* ClangFunctionCaller.cpp */; };
 		2689006013353E0E00698AC0 /* ClangExpressionDeclMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49F1A74511B3388F003ED505 /* ClangExpressionDeclMap.cpp */; };
 		2689006113353E0E00698AC0 /* ClangExpressionParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49445C2512245E3600C11A81 /* ClangExpressionParser.cpp */; };
 		2689006313353E0E00698AC0 /* ClangPersistentVariables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */; };
@@ -680,11 +680,15 @@
 		49DA65031485C92A005FF180 /* AppleObjCDeclVendor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DA65021485C92A005FF180 /* AppleObjCDeclVendor.cpp */; };
 		49DCF6FE170E6B4A0092F75E /* IRMemoryMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DCF6FD170E6B4A0092F75E /* IRMemoryMap.cpp */; };
 		49DCF702170E70120092F75E /* Materializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DCF700170E70120092F75E /* Materializer.cpp */; };
+		4C0083401B9F9BA900D5CF24 /* UtilityFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C00833F1B9F9BA900D5CF24 /* UtilityFunction.cpp */; settings = {ASSET_TAGS = (); }; };
+		4C2479BD1BA39295009C9A7B /* FunctionCaller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0083321B9A5DE200D5CF24 /* FunctionCaller.cpp */; settings = {ASSET_TAGS = (); }; };
 		4C3ADCD61810D88B00357218 /* BreakpointResolverFileRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CAA56141422D986001FFA01 /* BreakpointResolverFileRegex.cpp */; };
 		4C56543119D1EFAA002E9C44 /* ThreadPlanPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C56543019D1EFAA002E9C44 /* ThreadPlanPython.cpp */; };
 		4C56543519D2297A002E9C44 /* SBThreadPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C56543419D2297A002E9C44 /* SBThreadPlan.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		4C56543719D22B32002E9C44 /* SBThreadPlan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C56543619D22B32002E9C44 /* SBThreadPlan.cpp */; };
 		4C6649A314EEE81000B0316F /* StreamCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C6649A214EEE81000B0316F /* StreamCallback.cpp */; };
+		4C88BC2A1BA3722B00AA0964 /* Expression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C88BC291BA3722B00AA0964 /* Expression.cpp */; settings = {ASSET_TAGS = (); }; };
+		4C88BC2D1BA391B000AA0964 /* UserExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0083331B9A5DE200D5CF24 /* UserExpression.cpp */; settings = {ASSET_TAGS = (); }; };
 		4CABA9E0134A8BCD00539BDD /* ValueObjectMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CABA9DF134A8BCD00539BDD /* ValueObjectMemory.cpp */; };
 		4CCA644D13B40B82003BDF98 /* ItaniumABILanguageRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CCA643D13B40B82003BDF98 /* ItaniumABILanguageRuntime.cpp */; };
 		4CCA645013B40B82003BDF98 /* AppleObjCRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CCA644213B40B82003BDF98 /* AppleObjCRuntime.cpp */; };
@@ -1875,7 +1879,7 @@
 		26BC7D8410F1B77400F91463 /* ValueObjectList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectList.h; path = include/lldb/Core/ValueObjectList.h; sourceTree = "<group>"; };
 		26BC7D8510F1B77400F91463 /* ValueObjectVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectVariable.h; path = include/lldb/Core/ValueObjectVariable.h; sourceTree = "<group>"; };
 		26BC7D8610F1B77400F91463 /* VMRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VMRange.h; path = include/lldb/Core/VMRange.h; sourceTree = "<group>"; };
-		26BC7DC010F1B79500F91463 /* ClangExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangExpression.h; path = include/lldb/Expression/ClangExpression.h; sourceTree = "<group>"; };
+		26BC7DC010F1B79500F91463 /* ClangExpressionHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangExpressionHelper.h; path = include/lldb/Expression/ClangExpressionHelper.h; sourceTree = "<group>"; };
 		26BC7DC310F1B79500F91463 /* DWARFExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DWARFExpression.h; path = include/lldb/Expression/DWARFExpression.h; sourceTree = "<group>"; };
 		26BC7DD210F1B7D500F91463 /* Condition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Condition.h; path = include/lldb/Host/Condition.h; sourceTree = "<group>"; };
 		26BC7DD310F1B7D500F91463 /* Endian.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Endian.h; path = include/lldb/Host/Endian.h; sourceTree = "<group>"; };
@@ -2289,12 +2293,21 @@
 		49EC3E9C118F90D400B1265E /* ThreadPlanCallFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanCallFunction.h; path = include/lldb/Target/ThreadPlanCallFunction.h; sourceTree = "<group>"; };
 		49F1A74511B3388F003ED505 /* ClangExpressionDeclMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangExpressionDeclMap.cpp; path = source/Expression/ClangExpressionDeclMap.cpp; sourceTree = "<group>"; };
 		49F1A74911B338AE003ED505 /* ClangExpressionDeclMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangExpressionDeclMap.h; path = include/lldb/Expression/ClangExpressionDeclMap.h; sourceTree = "<group>"; };
+		4C00832C1B9A58A700D5CF24 /* Expression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Expression.h; path = include/lldb/Expression/Expression.h; sourceTree = "<group>"; };
+		4C00832D1B9A58A700D5CF24 /* FunctionCaller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FunctionCaller.h; path = include/lldb/Expression/FunctionCaller.h; sourceTree = "<group>"; };
+		4C00832E1B9A58A700D5CF24 /* UserExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UserExpression.h; path = include/lldb/Expression/UserExpression.h; sourceTree = "<group>"; };
+		4C0083321B9A5DE200D5CF24 /* FunctionCaller.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FunctionCaller.cpp; path = source/Expression/FunctionCaller.cpp; sourceTree = "<group>"; };
+		4C0083331B9A5DE200D5CF24 /* UserExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UserExpression.cpp; path = source/Expression/UserExpression.cpp; sourceTree = "<group>"; };
+		4C00833D1B9F9B8400D5CF24 /* UtilityFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UtilityFunction.h; path = include/lldb/Expression/UtilityFunction.h; sourceTree = "<group>"; };
+		4C00833F1B9F9BA900D5CF24 /* UtilityFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UtilityFunction.cpp; path = source/Expression/UtilityFunction.cpp; sourceTree = "<group>"; };
 		4C00986F11500B4300F316B0 /* UnixSignals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UnixSignals.h; path = include/lldb/Target/UnixSignals.h; sourceTree = "<group>"; };
 		4C00987011500B4300F316B0 /* UnixSignals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UnixSignals.cpp; path = source/Target/UnixSignals.cpp; sourceTree = "<group>"; };
 		4C08CDE711C81EF8001610A8 /* ThreadSpec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadSpec.cpp; path = source/Target/ThreadSpec.cpp; sourceTree = "<group>"; };
 		4C08CDEB11C81F1E001610A8 /* ThreadSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadSpec.h; path = include/lldb/Target/ThreadSpec.h; sourceTree = "<group>"; };
 		4C09CB73116BD98B00C7A725 /* CommandCompletions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandCompletions.h; path = include/lldb/Interpreter/CommandCompletions.h; sourceTree = "<group>"; };
 		4C09CB74116BD98B00C7A725 /* CommandCompletions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandCompletions.cpp; path = source/Commands/CommandCompletions.cpp; sourceTree = "<group>"; };
+		4C2479BE1BA39843009C9A7B /* ExpressionParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ExpressionParser.h; path = include/lldb/Expression/ExpressionParser.h; sourceTree = "<group>"; };
+		4C29E77D1BA2403F00DFF855 /* ExpressionTypeSystemHelper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = ExpressionTypeSystemHelper.h; path = include/lldb/Expression/ExpressionTypeSystemHelper.h; sourceTree = "<group>"; };
 		4C2FAE2E135E3A70001EDE44 /* SharedCluster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SharedCluster.h; path = include/lldb/Utility/SharedCluster.h; sourceTree = "<group>"; };
 		4C43DEF9110641F300E55CBF /* ThreadPlanShouldStopHere.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanShouldStopHere.h; path = include/lldb/Target/ThreadPlanShouldStopHere.h; sourceTree = "<group>"; };
 		4C43DEFA110641F300E55CBF /* ThreadPlanShouldStopHere.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanShouldStopHere.cpp; path = source/Target/ThreadPlanShouldStopHere.cpp; sourceTree = "<group>"; };
@@ -2315,9 +2328,10 @@
 		4C73152119B7D71700F865A4 /* Iterable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Iterable.h; path = include/lldb/Utility/Iterable.h; sourceTree = "<group>"; };
 		4C7CF7E31295E10E00B4FBB5 /* ThreadPlanCallUserExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanCallUserExpression.h; path = include/lldb/Target/ThreadPlanCallUserExpression.h; sourceTree = "<group>"; };
 		4C7CF7E51295E12B00B4FBB5 /* ThreadPlanCallUserExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanCallUserExpression.cpp; path = source/Target/ThreadPlanCallUserExpression.cpp; sourceTree = "<group>"; };
-		4C98D3DA118FB96F00E575D0 /* ClangFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangFunction.cpp; path = source/Expression/ClangFunction.cpp; sourceTree = "<group>"; };
+		4C88BC291BA3722B00AA0964 /* Expression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Expression.cpp; path = source/Expression/Expression.cpp; sourceTree = "<group>"; };
+		4C98D3DA118FB96F00E575D0 /* ClangFunctionCaller.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangFunctionCaller.cpp; path = source/Expression/ClangFunctionCaller.cpp; sourceTree = "<group>"; };
 		4C98D3DB118FB96F00E575D0 /* IRExecutionUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRExecutionUnit.cpp; path = source/Expression/IRExecutionUnit.cpp; sourceTree = "<group>"; };
-		4C98D3E0118FB98F00E575D0 /* ClangFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangFunction.h; path = include/lldb/Expression/ClangFunction.h; sourceTree = "<group>"; };
+		4C98D3E0118FB98F00E575D0 /* ClangFunctionCaller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangFunctionCaller.h; path = include/lldb/Expression/ClangFunctionCaller.h; sourceTree = "<group>"; };
 		4C98D3E1118FB98F00E575D0 /* IRExecutionUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IRExecutionUnit.h; path = include/lldb/Expression/IRExecutionUnit.h; sourceTree = "<group>"; };
 		4CA9637911B6E99A00780E28 /* CommandObjectApropos.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectApropos.cpp; path = source/Commands/CommandObjectApropos.cpp; sourceTree = "<group>"; };
 		4CA9637A11B6E99A00780E28 /* CommandObjectApropos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectApropos.h; path = source/Commands/CommandObjectApropos.h; sourceTree = "<group>"; };
@@ -4374,27 +4388,37 @@
 		26BC7DBE10F1B78200F91463 /* Expression */ = {
 			isa = PBXGroup;
 			children = (
+				4C00832C1B9A58A700D5CF24 /* Expression.h */,
+				4C88BC291BA3722B00AA0964 /* Expression.cpp */,
+				4C29E77D1BA2403F00DFF855 /* ExpressionTypeSystemHelper.h */,
+				26BC7DC010F1B79500F91463 /* ClangExpressionHelper.h */,
+				4C00832D1B9A58A700D5CF24 /* FunctionCaller.h */,
+				4C0083321B9A5DE200D5CF24 /* FunctionCaller.cpp */,
+				4C98D3E0118FB98F00E575D0 /* ClangFunctionCaller.h */,
+				4C98D3DA118FB96F00E575D0 /* ClangFunctionCaller.cpp */,
+				4C00832E1B9A58A700D5CF24 /* UserExpression.h */,
+				4C0083331B9A5DE200D5CF24 /* UserExpression.cpp */,
+				49445E341225AB6A00C11A81 /* ClangUserExpression.h */,
+				26BC7ED510F1B86700F91463 /* ClangUserExpression.cpp */,
+				497C86C1122823F300B54702 /* ClangUtilityFunction.h */,
+				497C86BD122823D800B54702 /* ClangUtilityFunction.cpp */,
+				4C00833D1B9F9B8400D5CF24 /* UtilityFunction.h */,
+				4C00833F1B9F9BA900D5CF24 /* UtilityFunction.cpp */,
 				49A1CAC11430E21D00306AC9 /* ExpressionSourceCode.h */,
 				49A1CAC31430E8BD00306AC9 /* ExpressionSourceCode.cpp */,
 				4984BA171B979C08008658D4 /* ExpressionVariable.h */,
 				4984BA151B979973008658D4 /* ExpressionVariable.cpp */,
 				49D7072611B5AD03001AD875 /* ClangASTSource.h */,
 				49D7072811B5AD11001AD875 /* ClangASTSource.cpp */,
-				26BC7DC010F1B79500F91463 /* ClangExpression.h */,
-				4C98D3E0118FB98F00E575D0 /* ClangFunction.h */,
-				4C98D3DA118FB96F00E575D0 /* ClangFunction.cpp */,
 				49F1A74911B338AE003ED505 /* ClangExpressionDeclMap.h */,
 				49F1A74511B3388F003ED505 /* ClangExpressionDeclMap.cpp */,
+				4C2479BE1BA39843009C9A7B /* ExpressionParser.h */,
 				49445C2912245E5500C11A81 /* ClangExpressionParser.h */,
 				49445C2512245E3600C11A81 /* ClangExpressionParser.cpp */,
 				4959511B1A1BC48100F6F8FC /* ClangModulesDeclVendor.h */,
 				4959511E1A1BC4BC00F6F8FC /* ClangModulesDeclVendor.cpp */,
 				49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */,
 				49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */,
-				49445E341225AB6A00C11A81 /* ClangUserExpression.h */,
-				26BC7ED510F1B86700F91463 /* ClangUserExpression.cpp */,
-				497C86C1122823F300B54702 /* ClangUtilityFunction.h */,
-				497C86BD122823D800B54702 /* ClangUtilityFunction.cpp */,
 				26BC7DC310F1B79500F91463 /* DWARFExpression.h */,
 				26BC7ED810F1B86700F91463 /* DWARFExpression.cpp */,
 				4906FD4412F2257600A2A77C /* ASTDumper.h */,
@@ -6124,6 +6148,7 @@
 				33E5E8471A674FB60024ED68 /* StringConvert.cpp in Sources */,
 				26D1804216CEDF0700EDFB5B /* TimeSpecTimeout.cpp in Sources */,
 				2689FFDA13353D9D00698AC0 /* lldb.cpp in Sources */,
+				4C0083401B9F9BA900D5CF24 /* UtilityFunction.cpp in Sources */,
 				26474CCD18D0CB5B0073DEBA /* RegisterContextPOSIX_x86.cpp in Sources */,
 				2689FFEF13353DB600698AC0 /* Breakpoint.cpp in Sources */,
 				267A47FB1B1411C40021A5BC /* NativeRegisterContext.cpp in Sources */,
@@ -6159,6 +6184,7 @@
 				2689000F13353DB600698AC0 /* StoppointLocation.cpp in Sources */,
 				2689001113353DB600698AC0 /* Watchpoint.cpp in Sources */,
 				2689001213353DDE00698AC0 /* CommandObjectApropos.cpp in Sources */,
+				4C88BC2A1BA3722B00AA0964 /* Expression.cpp in Sources */,
 				23042D121976CA1D00621B2C /* PlatformKalimba.cpp in Sources */,
 				2689001313353DDE00698AC0 /* CommandObjectArgs.cpp in Sources */,
 				2689001413353DDE00698AC0 /* CommandObjectBreakpoint.cpp in Sources */,
@@ -6278,7 +6304,7 @@
 				2689005D13353E0400698AC0 /* VMRange.cpp in Sources */,
 				2689005E13353E0E00698AC0 /* ClangASTSource.cpp in Sources */,
 				3FDFED0F19B7D269009756A7 /* ThisThread.cpp in Sources */,
-				2689005F13353E0E00698AC0 /* ClangFunction.cpp in Sources */,
+				2689005F13353E0E00698AC0 /* ClangFunctionCaller.cpp in Sources */,
 				2689006013353E0E00698AC0 /* ClangExpressionDeclMap.cpp in Sources */,
 				2689006113353E0E00698AC0 /* ClangExpressionParser.cpp in Sources */,
 				B5EFAE861AE53B1D007059F3 /* RegisterContextFreeBSD_arm.cpp in Sources */,
@@ -6402,6 +6428,7 @@
 				268900CC13353E5F00698AC0 /* SymbolFileDWARFDebugMap.cpp in Sources */,
 				268900CD13353E5F00698AC0 /* UniqueDWARFASTType.cpp in Sources */,
 				944372DC171F6B4300E57C32 /* RegisterContextDummy.cpp in Sources */,
+				4C88BC2D1BA391B000AA0964 /* UserExpression.cpp in Sources */,
 				268900CE13353E5F00698AC0 /* SymbolFileSymtab.cpp in Sources */,
 				266E82971B8CE3AC008FCA06 /* DWARFDIE.cpp in Sources */,
 				268900CF13353E5F00698AC0 /* SymbolVendorMacOSX.cpp in Sources */,
@@ -6444,6 +6471,7 @@
 				268900EC13353E6F00698AC0 /* LanguageRuntime.cpp in Sources */,
 				268900ED13353E6F00698AC0 /* ObjCLanguageRuntime.cpp in Sources */,
 				268900EE13353E6F00698AC0 /* PathMappingList.cpp in Sources */,
+				4C2479BD1BA39295009C9A7B /* FunctionCaller.cpp in Sources */,
 				268900EF13353E6F00698AC0 /* Platform.cpp in Sources */,
 				268900F013353E6F00698AC0 /* Process.cpp in Sources */,
 				26BC17AD18C7F4CB00D2196D /* RegisterContextPOSIXCore_mips64.cpp in Sources */,

Modified: lldb/trunk/source/API/SBFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFrame.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/API/SBFrame.cpp (original)
+++ lldb/trunk/source/API/SBFrame.cpp Tue Sep 15 16:13:50 2015
@@ -22,7 +22,7 @@
 #include "lldb/Core/ValueObjectRegister.h"
 #include "lldb/Core/ValueObjectVariable.h"
 #include "lldb/Expression/ClangPersistentVariables.h"
-#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/UserExpression.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Symbol/Block.h"
 #include "lldb/Symbol/Function.h"

Modified: lldb/trunk/source/Breakpoint/BreakpointLocation.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointLocation.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointLocation.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointLocation.cpp Tue Sep 15 16:13:50 2015
@@ -21,9 +21,10 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/ValueObject.h"
-#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/UserExpression.h"
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/TypeSystem.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Thread.h"
@@ -88,6 +89,12 @@ BreakpointLocation::GetBreakpoint ()
     return m_owner;
 }
 
+Target &
+BreakpointLocation::GetTarget()
+{
+    return m_owner.GetTarget();
+}
+
 bool
 BreakpointLocation::IsEnabled () const
 {
@@ -278,10 +285,26 @@ BreakpointLocation::ConditionSaysStop (E
         !m_user_expression_sp ||
         !m_user_expression_sp->MatchesContext(exe_ctx))
     {
-        m_user_expression_sp.reset(new ClangUserExpression(condition_text,
-                                                           NULL,
-                                                           lldb::eLanguageTypeUnknown,
-                                                           ClangUserExpression::eResultTypeAny));
+        LanguageType language = eLanguageTypeUnknown;
+        // See if we can figure out the language from the frame, otherwise use the default language:
+        CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit();
+        if (comp_unit)
+            language = comp_unit->GetLanguage();
+        
+        Error error;
+        m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(condition_text,
+                                                                             NULL,
+                                                                             language,
+                                                                             Expression::eResultTypeAny,
+                                                                             error));
+        if (error.Fail())
+        {
+            if (log)
+                log->Printf("Error getting condition expression: %s.", error.AsCString());
+            m_user_expression_sp.reset();
+            return true;
+        }
+        
         
         StreamString errors;
         

Modified: lldb/trunk/source/Breakpoint/BreakpointOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointOptions.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointOptions.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointOptions.cpp Tue Sep 15 16:13:50 2015
@@ -20,7 +20,6 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/ThreadSpec.h"
-#include "lldb/Expression/ClangUserExpression.h"
 
 using namespace lldb;
 using namespace lldb_private;

Modified: lldb/trunk/source/Breakpoint/Watchpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/Watchpoint.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/Watchpoint.cpp (original)
+++ lldb/trunk/source/Breakpoint/Watchpoint.cpp Tue Sep 15 16:13:50 2015
@@ -22,7 +22,7 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/ThreadSpec.h"
-#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/UserExpression.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -371,7 +371,17 @@ Watchpoint::SetCondition (const char *co
     else
     {
         // Pass NULL for expr_prefix (no translation-unit level definitions).
-        m_condition_ap.reset(new ClangUserExpression (condition, NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
+        Error error;
+        m_condition_ap.reset(m_target.GetUserExpressionForLanguage (condition,
+                                                                      NULL,
+                                                                      lldb::eLanguageTypeUnknown,
+                                                                      UserExpression::eResultTypeAny,
+                                                                      error));
+        if (error.Fail())
+        {
+            // FIXME: Log something...
+            m_condition_ap.reset();
+        }
     }
     SendWatchpointChangedEvent (eWatchpointEventTypeConditionChanged);
 }

Modified: lldb/trunk/source/Breakpoint/WatchpointOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/WatchpointOptions.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/WatchpointOptions.cpp (original)
+++ lldb/trunk/source/Breakpoint/WatchpointOptions.cpp Tue Sep 15 16:13:50 2015
@@ -20,7 +20,6 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/ThreadSpec.h"
-#include "lldb/Expression/ClangUserExpression.h"
 
 using namespace lldb;
 using namespace lldb_private;

Modified: lldb/trunk/source/Commands/CommandObjectArgs.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectArgs.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectArgs.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectArgs.cpp Tue Sep 15 16:13:50 2015
@@ -17,9 +17,7 @@
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/Value.h"
-#include "lldb/Expression/ClangExpression.h"
 #include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
-#include "lldb/Expression/ClangFunction.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandReturnObject.h"

Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Tue Sep 15 16:13:50 2015
@@ -17,8 +17,7 @@
 #include "lldb/Core/ValueObjectVariable.h"
 #include "lldb/DataFormatters/ValueObjectPrinter.h"
 #include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
-#include "lldb/Expression/ClangUserExpression.h"
-#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/UserExpression.h"
 #include "lldb/Expression/DWARFExpression.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/StringConvert.h"
@@ -345,7 +344,7 @@ CommandObjectExpression::EvaluateExpress
             }
             else
             {
-                if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
+                if (result_valobj_sp->GetError().GetError() == UserExpression::kNoResult)
                 {
                     if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
                     {

Modified: lldb/trunk/source/DataFormatters/VectorType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/VectorType.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/DataFormatters/VectorType.cpp (original)
+++ lldb/trunk/source/DataFormatters/VectorType.cpp Tue Sep 15 16:13:50 2015
@@ -235,7 +235,7 @@ namespace lldb_private {
                 TargetSP target_sp(m_backend.GetTargetSP());
                 m_child_type = ::GetCompilerTypeForFormat(m_parent_format,
                                                           element_type,
-                                                          target_sp ? target_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeC) : nullptr);
+                                                          target_sp ? target_sp->GetScratchTypeSystemForLanguage(lldb::eLanguageTypeC) : nullptr);
                 m_num_children = ::CalculateNumChildren(parent_type,
                                                         m_child_type);
                 m_item_format = GetItemFormatForFormat(m_parent_format,

Modified: lldb/trunk/source/Expression/ASTStructExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ASTStructExtractor.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ASTStructExtractor.cpp (original)
+++ lldb/trunk/source/Expression/ASTStructExtractor.cpp Tue Sep 15 16:13:50 2015
@@ -28,7 +28,7 @@ using namespace lldb_private;
 
 ASTStructExtractor::ASTStructExtractor(ASTConsumer *passthrough,
                                        const char *struct_name,
-                                       ClangFunction &function) :
+                                       ClangFunctionCaller &function) :
     m_ast_context (NULL),
     m_passthrough (passthrough),
     m_passthrough_sema (NULL),

Modified: lldb/trunk/source/Expression/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/CMakeLists.txt?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Expression/CMakeLists.txt (original)
+++ lldb/trunk/source/Expression/CMakeLists.txt Tue Sep 15 16:13:50 2015
@@ -5,18 +5,22 @@ add_lldb_library(lldbExpression
   ClangASTSource.cpp
   ClangExpressionDeclMap.cpp
   ClangExpressionParser.cpp
-  ClangFunction.cpp
+  ClangFunctionCaller.cpp
   ClangModulesDeclVendor.cpp
   ClangPersistentVariables.cpp
   ClangUserExpression.cpp
   ClangUtilityFunction.cpp
   DWARFExpression.cpp
+  Expression.cpp
   ExpressionSourceCode.cpp
   ExpressionVariable.cpp
+  FunctionCaller.cpp
   IRDynamicChecks.cpp
   IRExecutionUnit.cpp
   IRForTarget.cpp
   IRInterpreter.cpp
   IRMemoryMap.cpp
   Materializer.cpp
+  UserExpression.cpp
+  UtilityFunction.cpp
   )

Modified: lldb/trunk/source/Expression/ClangASTSource.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangASTSource.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangASTSource.cpp (original)
+++ lldb/trunk/source/Expression/ClangASTSource.cpp Tue Sep 15 16:13:50 2015
@@ -15,7 +15,6 @@
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Expression/ASTDumper.h"
 #include "lldb/Expression/ClangASTSource.h"
-#include "lldb/Expression/ClangExpression.h"
 #include "lldb/Expression/ClangModulesDeclVendor.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/CompilerDeclContext.h"

Modified: lldb/trunk/source/Expression/ClangExpressionParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Tue Sep 15 16:13:50 2015
@@ -19,7 +19,7 @@
 #include "lldb/Core/StreamFile.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Expression/ClangASTSource.h"
-#include "lldb/Expression/ClangExpression.h"
+#include "lldb/Expression/ClangExpressionHelper.h"
 #include "lldb/Expression/ClangExpressionDeclMap.h"
 #include "lldb/Expression/ClangModulesDeclVendor.h"
 #include "lldb/Expression/ClangPersistentVariables.h"
@@ -37,6 +37,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ExternalASTSource.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/Version.h"
 #include "clang/CodeGen/CodeGenAction.h"
@@ -108,7 +109,7 @@ public:
     }
     
     virtual void moduleImport(SourceLocation import_location,
-                              ModuleIdPath path,
+                              clang::ModuleIdPath path,
                               const clang::Module * /*null*/)
     {
         std::vector<ConstString> string_path;
@@ -149,9 +150,9 @@ public:
 //===----------------------------------------------------------------------===//
 
 ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
-                                              ClangExpression &expr,
+                                              Expression &expr,
                                               bool generate_debug_info) :
-    m_expr (expr),
+    ExpressionParser (exe_scope, expr, generate_debug_info),
     m_compiler (),
     m_code_generator (),
     m_pp_callbacks(nullptr)
@@ -255,7 +256,7 @@ ClangExpressionParser::ClangExpressionPa
     m_compiler->getLangOpts().WChar = true;
     m_compiler->getLangOpts().Blocks = true;
     m_compiler->getLangOpts().DebuggerSupport = true; // Features specifically for debugger clients
-    if (expr.DesiredResultType() == ClangExpression::eResultTypeId)
+    if (expr.DesiredResultType() == Expression::eResultTypeId)
         m_compiler->getLangOpts().DebuggerCastResultToId = true;
 
     m_compiler->getLangOpts().CharIsSigned =
@@ -346,7 +347,8 @@ ClangExpressionParser::ClangExpressionPa
     
     ast_context->InitBuiltinTypes(m_compiler->getTarget());
 
-    ClangExpressionDeclMap *decl_map = m_expr.DeclMap();
+    ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
+    ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap();
 
     if (decl_map)
     {
@@ -430,9 +432,11 @@ ClangExpressionParser::Parse (Stream &st
 
     diag_buf->BeginSourceFile(m_compiler->getLangOpts(), &m_compiler->getPreprocessor());
 
-    ASTConsumer *ast_transformer = m_expr.ASTTransformer(m_code_generator.get());
+    ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
 
-    if (ClangExpressionDeclMap *decl_map = m_expr.DeclMap())
+    ASTConsumer *ast_transformer = type_system_helper->ASTTransformer(m_code_generator.get());
+
+    if (ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap())
         decl_map->InstallCodeGenerator(m_code_generator.get());
 
     if (ast_transformer)
@@ -479,7 +483,7 @@ ClangExpressionParser::Parse (Stream &st
 
     if (!num_errors)
     {
-        if (m_expr.DeclMap() && !m_expr.DeclMap()->ResolveUnknownTypes())
+        if (type_system_helper->DeclMap() && !type_system_helper->DeclMap()->ResolveUnknownTypes())
         {
             stream.Printf("error: Couldn't infer the type of a variable\n");
             num_errors++;
@@ -552,7 +556,8 @@ ClangExpressionParser::PrepareForExecuti
                                                  exe_ctx.GetTargetSP(),
                                                  m_compiler->getTargetOpts().Features));
 
-    ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL
+    ClangExpressionHelper *type_system_helper = dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
+    ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap(); // result can be NULL
 
     if (decl_map)
     {
@@ -640,11 +645,3 @@ ClangExpressionParser::PrepareForExecuti
 
     return err;
 }
-
-bool
-ClangExpressionParser::GetGenerateDebugInfo () const
-{
-    if (m_compiler)
-        return m_compiler->getCodeGenOpts().getDebugInfo() == CodeGenOptions::FullDebugInfo;
-    return false;
-}

Removed: lldb/trunk/source/Expression/ClangFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangFunction.cpp?rev=247719&view=auto
==============================================================================
--- lldb/trunk/source/Expression/ClangFunction.cpp (original)
+++ lldb/trunk/source/Expression/ClangFunction.cpp (removed)
@@ -1,596 +0,0 @@
-//===-- ClangFunction.cpp ---------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/CodeGen/CodeGenAction.h"
-#include "clang/CodeGen/ModuleBuilder.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/IR/Module.h"
-
-// Project includes
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/State.h"
-#include "lldb/Core/ValueObject.h"
-#include "lldb/Core/ValueObjectList.h"
-#include "lldb/Expression/ASTStructExtractor.h"
-#include "lldb/Expression/ClangExpressionParser.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/IRExecutionUnit.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/Type.h"
-#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Target/ThreadPlan.h"
-#include "lldb/Target/ThreadPlanCallFunction.h"
-
-using namespace lldb_private;
-
-//----------------------------------------------------------------------
-// ClangFunction constructor
-//----------------------------------------------------------------------
-ClangFunction::ClangFunction 
-(
-    ExecutionContextScope &exe_scope,
-    const CompilerType &return_type, 
-    const Address& functionAddress, 
-    const ValueList &arg_value_list,
-    const char *name
-) :
-    m_execution_unit_sp(),
-    m_parser(),
-    m_jit_module_wp(),
-    m_name (name ? name : "<unknown>"),
-    m_function_ptr (NULL),
-    m_function_addr (functionAddress),
-    m_function_return_type(return_type),
-    m_wrapper_function_name ("__lldb_caller_function"),
-    m_wrapper_struct_name ("__lldb_caller_struct"),
-    m_wrapper_args_addrs (),
-    m_arg_values (arg_value_list),
-    m_compiled (false),
-    m_JITted (false)
-{
-    m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess());
-    // Can't make a ClangFunction without a process.
-    assert (m_jit_process_wp.lock());
-}
-
-ClangFunction::ClangFunction
-(
-    ExecutionContextScope &exe_scope,
-    Function &function, 
-    ClangASTContext *ast_context, 
-    const ValueList &arg_value_list,
-    const char *name
-) :
-    m_name (name ? name : "<unknown>"),
-    m_function_ptr (&function),
-    m_function_addr (),
-    m_function_return_type (),
-    m_wrapper_function_name ("__lldb_function_caller"),
-    m_wrapper_struct_name ("__lldb_caller_struct"),
-    m_wrapper_args_addrs (),
-    m_arg_values (arg_value_list),
-    m_compiled (false),
-    m_JITted (false)
-{
-    m_jit_process_wp = exe_scope.CalculateProcess();
-    // Can't make a ClangFunction without a process.
-    assert (m_jit_process_wp.lock());
-
-    m_function_addr = m_function_ptr->GetAddressRange().GetBaseAddress();
-    m_function_return_type = m_function_ptr->GetCompilerType().GetFunctionReturnType();
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-ClangFunction::~ClangFunction()
-{
-    lldb::ProcessSP process_sp (m_jit_process_wp.lock());
-    if (process_sp)
-    {
-        lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
-        if (jit_module_sp)
-            process_sp->GetTarget().GetImages().Remove(jit_module_sp);
-    }    
-}
-
-unsigned
-ClangFunction::CompileFunction (Stream &errors)
-{
-    if (m_compiled)
-        return 0;
-    
-    // FIXME: How does clang tell us there's no return value?  We need to handle that case.
-    unsigned num_errors = 0;
-    
-    std::string return_type_str (m_function_return_type.GetTypeName().AsCString(""));
-    
-    // Cons up the function we're going to wrap our call in, then compile it...
-    // We declare the function "extern "C"" because the compiler might be in C++
-    // mode which would mangle the name and then we couldn't find it again...
-    m_wrapper_function_text.clear();
-    m_wrapper_function_text.append ("extern \"C\" void ");
-    m_wrapper_function_text.append (m_wrapper_function_name);
-    m_wrapper_function_text.append (" (void *input)\n{\n    struct ");
-    m_wrapper_function_text.append (m_wrapper_struct_name);
-    m_wrapper_function_text.append (" \n  {\n");
-    m_wrapper_function_text.append ("    ");
-    m_wrapper_function_text.append (return_type_str);
-    m_wrapper_function_text.append (" (*fn_ptr) (");
-
-    // Get the number of arguments.  If we have a function type and it is prototyped,
-    // trust that, otherwise use the values we were given.
-
-    // FIXME: This will need to be extended to handle Variadic functions.  We'll need
-    // to pull the defined arguments out of the function, then add the types from the
-    // arguments list for the variable arguments.
-
-    uint32_t num_args = UINT32_MAX;
-    bool trust_function = false;
-    // GetArgumentCount returns -1 for an unprototyped function.
-    CompilerType function_clang_type;
-    if (m_function_ptr)
-    {
-        function_clang_type = m_function_ptr->GetCompilerType();
-        if (function_clang_type)
-        {
-            int num_func_args = function_clang_type.GetFunctionArgumentCount();
-            if (num_func_args >= 0)
-            {
-                trust_function = true;
-                num_args = num_func_args;
-            }
-        }
-    }
-
-    if (num_args == UINT32_MAX)
-        num_args = m_arg_values.GetSize();
-
-    std::string args_buffer;  // This one stores the definition of all the args in "struct caller".
-    std::string args_list_buffer;  // This one stores the argument list called from the structure.
-    for (size_t i = 0; i < num_args; i++)
-    {
-        std::string type_name;
-
-        if (trust_function)
-        {
-            type_name = function_clang_type.GetFunctionArgumentTypeAtIndex(i).GetTypeName().AsCString("");
-        }
-        else
-        {
-            CompilerType clang_qual_type = m_arg_values.GetValueAtIndex(i)->GetCompilerType ();
-            if (clang_qual_type)
-            {
-                type_name = clang_qual_type.GetTypeName().AsCString("");
-            }
-            else
-            {   
-                errors.Printf("Could not determine type of input value %" PRIu64 ".", (uint64_t)i);
-                return 1;
-            }
-        }
-
-        m_wrapper_function_text.append (type_name);
-        if (i < num_args - 1)
-            m_wrapper_function_text.append (", ");
-
-        char arg_buf[32];
-        args_buffer.append ("    ");
-        args_buffer.append (type_name);
-        snprintf(arg_buf, 31, "arg_%" PRIu64, (uint64_t)i);
-        args_buffer.push_back (' ');
-        args_buffer.append (arg_buf);
-        args_buffer.append (";\n");
-
-        args_list_buffer.append ("__lldb_fn_data->");
-        args_list_buffer.append (arg_buf);
-        if (i < num_args - 1)
-            args_list_buffer.append (", ");
-
-    }
-    m_wrapper_function_text.append (");\n"); // Close off the function calling prototype.
-
-    m_wrapper_function_text.append (args_buffer);
-
-    m_wrapper_function_text.append ("    ");
-    m_wrapper_function_text.append (return_type_str);
-    m_wrapper_function_text.append (" return_value;");
-    m_wrapper_function_text.append ("\n  };\n  struct ");
-    m_wrapper_function_text.append (m_wrapper_struct_name);
-    m_wrapper_function_text.append ("* __lldb_fn_data = (struct ");
-    m_wrapper_function_text.append (m_wrapper_struct_name);
-    m_wrapper_function_text.append (" *) input;\n");
-
-    m_wrapper_function_text.append ("  __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr (");
-    m_wrapper_function_text.append (args_list_buffer);
-    m_wrapper_function_text.append (");\n}\n");
-
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-    if (log)
-        log->Printf ("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str());
-        
-    // Okay, now compile this expression
-    
-    lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
-    if (jit_process_sp)
-    {
-        const bool generate_debug_info = true;
-        m_parser.reset(new ClangExpressionParser(jit_process_sp.get(), *this, generate_debug_info));
-        
-        num_errors = m_parser->Parse (errors);
-    }
-    else
-    {
-        errors.Printf("no process - unable to inject function");
-        num_errors = 1;
-    }
-    
-    m_compiled = (num_errors == 0);
-    
-    if (!m_compiled)
-        return num_errors;
-
-    return num_errors;
-}
-
-bool
-ClangFunction::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
-{
-    Process *process = exe_ctx.GetProcessPtr();
-
-    if (!process)
-        return false;
-    
-    lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
-    
-    if (process != jit_process_sp.get())
-        return false;
-    
-    if (!m_compiled)
-        return false;
-
-    if (m_JITted)
-        return true;
-        
-    bool can_interpret = false; // should stay that way
-    
-    Error jit_error (m_parser->PrepareForExecution (m_jit_start_addr,
-                                                    m_jit_end_addr,
-                                                    m_execution_unit_sp,
-                                                    exe_ctx, 
-                                                    can_interpret,
-                                                    eExecutionPolicyAlways));
-    
-    if (!jit_error.Success())
-        return false;
-    
-    if (m_parser->GetGenerateDebugInfo())
-    {
-        lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
-        
-        if (jit_module_sp)
-        {
-            ConstString const_func_name(FunctionName());
-            FileSpec jit_file;
-            jit_file.GetFilename() = const_func_name;
-            jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
-            m_jit_module_wp = jit_module_sp;
-            process->GetTarget().GetImages().Append(jit_module_sp);
-        }
-    }
-    if (process && m_jit_start_addr)
-        m_jit_process_wp = process->shared_from_this();
-    
-    m_JITted = true;
-
-    return true;
-}
-
-bool
-ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
-{
-    return WriteFunctionArguments(exe_ctx, args_addr_ref, m_function_addr, m_arg_values, errors);    
-}
-
-// FIXME: Assure that the ValueList we were passed in is consistent with the one that defined this function.
-
-bool
-ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, 
-                                       lldb::addr_t &args_addr_ref, 
-                                       Address function_address, 
-                                       ValueList &arg_values, 
-                                       Stream &errors)
-{
-    // All the information to reconstruct the struct is provided by the
-    // StructExtractor.
-    if (!m_struct_valid)
-    {
-        errors.Printf("Argument information was not correctly parsed, so the function cannot be called.");
-        return false;
-    }
-        
-    Error error;
-    using namespace clang;
-    lldb::ExpressionResults return_value = lldb::eExpressionSetupError;
-
-    Process *process = exe_ctx.GetProcessPtr();
-
-    if (process == NULL)
-        return return_value;
-
-    lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
-    
-    if (process != jit_process_sp.get())
-        return false;
-                
-    if (args_addr_ref == LLDB_INVALID_ADDRESS)
-    {
-        args_addr_ref = process->AllocateMemory(m_struct_size, lldb::ePermissionsReadable|lldb::ePermissionsWritable, error);
-        if (args_addr_ref == LLDB_INVALID_ADDRESS)
-            return false;
-        m_wrapper_args_addrs.push_back (args_addr_ref);
-    } 
-    else 
-    {
-        // Make sure this is an address that we've already handed out.
-        if (find (m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr_ref) == m_wrapper_args_addrs.end())
-        {
-            return false;
-        }
-    }
-
-    // TODO: verify fun_addr needs to be a callable address
-    Scalar fun_addr (function_address.GetCallableLoadAddress(exe_ctx.GetTargetPtr()));
-    uint64_t first_offset = m_member_offsets[0];
-    process->WriteScalarToMemory(args_addr_ref + first_offset, fun_addr, process->GetAddressByteSize(), error);
-
-    // FIXME: We will need to extend this for Variadic functions.
-
-    Error value_error;
-    
-    size_t num_args = arg_values.GetSize();
-    if (num_args != m_arg_values.GetSize())
-    {
-        errors.Printf ("Wrong number of arguments - was: %" PRIu64 " should be: %" PRIu64 "", (uint64_t)num_args, (uint64_t)m_arg_values.GetSize());
-        return false;
-    }
-    
-    for (size_t i = 0; i < num_args; i++)
-    {
-        // FIXME: We should sanity check sizes.
-
-        uint64_t offset = m_member_offsets[i+1]; // Clang sizes are in bytes.
-        Value *arg_value = arg_values.GetValueAtIndex(i);
-        
-        // FIXME: For now just do scalars:
-        
-        // Special case: if it's a pointer, don't do anything (the ABI supports passing cstrings)
-        
-        if (arg_value->GetValueType() == Value::eValueTypeHostAddress &&
-            arg_value->GetContextType() == Value::eContextTypeInvalid &&
-            arg_value->GetCompilerType().IsPointerType())
-            continue;
-        
-        const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx);
-
-        if (!process->WriteScalarToMemory(args_addr_ref + offset, arg_scalar, arg_scalar.GetByteSize(), error))
-            return false;
-    }
-
-    return true;
-}
-
-bool
-ClangFunction::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
-{
-    using namespace clang;
-    
-    if (CompileFunction(errors) != 0)
-        return false;
-    if (!WriteFunctionWrapper(exe_ctx, errors))
-        return false;
-    if (!WriteFunctionArguments(exe_ctx, args_addr_ref, errors))
-        return false;
-
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    if (log)
-        log->Printf ("Call Address: 0x%" PRIx64 " Struct Address: 0x%" PRIx64 ".\n", m_jit_start_addr, args_addr_ref);
-        
-    return true;
-}
-
-lldb::ThreadPlanSP
-ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, 
-                                            lldb::addr_t args_addr,
-                                            const EvaluateExpressionOptions &options,
-                                            Stream &errors)
-{
-    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
-    
-    if (log)
-        log->Printf("-- [ClangFunction::GetThreadPlanToCallFunction] Creating thread plan to call function \"%s\" --", m_name.c_str());
-    
-    // FIXME: Use the errors Stream for better error reporting.
-    Thread *thread = exe_ctx.GetThreadPtr();
-    if (thread == NULL)
-    {
-        errors.Printf("Can't call a function without a valid thread.");
-        return NULL;
-    }
-
-    // Okay, now run the function:
-
-    Address wrapper_address (m_jit_start_addr);
-    
-    lldb::addr_t args = { args_addr };
-    
-    lldb::ThreadPlanSP new_plan_sp (new ThreadPlanCallFunction (*thread,
-                                                       wrapper_address,
-                                                       CompilerType(),
-                                                       args,
-                                                       options));
-    new_plan_sp->SetIsMasterPlan(true);
-    new_plan_sp->SetOkayToDiscard (false);
-    return new_plan_sp;
-}
-
-bool
-ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr, Value &ret_value)
-{
-    // Read the return value - it is the last field in the struct:
-    // FIXME: How does clang tell us there's no return value?  We need to handle that case.
-    // FIXME: Create our ThreadPlanCallFunction with the return CompilerType, and then use GetReturnValueObject
-    // to fetch the value.  That way we can fetch any values we need.
-    
-    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
-    
-    if (log)
-        log->Printf("-- [ClangFunction::FetchFunctionResults] Fetching function results for \"%s\"--", m_name.c_str());
-    
-    Process *process = exe_ctx.GetProcessPtr();
-    
-    if (process == NULL)
-        return false;
-
-    lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
-    
-    if (process != jit_process_sp.get())
-        return false;
-                
-    Error error;
-    ret_value.GetScalar() = process->ReadUnsignedIntegerFromMemory (args_addr + m_return_offset, m_return_size, 0, error);
-
-    if (error.Fail())
-        return false;
-
-    ret_value.SetCompilerType(m_function_return_type);
-    ret_value.SetValueType(Value::eValueTypeScalar);
-    return true;
-}
-
-void
-ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr)
-{
-    std::list<lldb::addr_t>::iterator pos;
-    pos = std::find(m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr);
-    if (pos != m_wrapper_args_addrs.end())
-        m_wrapper_args_addrs.erase(pos);
-    
-    exe_ctx.GetProcessRef().DeallocateMemory(args_addr);
-}
-
-lldb::ExpressionResults
-ClangFunction::ExecuteFunction(
-        ExecutionContext &exe_ctx, 
-        lldb::addr_t *args_addr_ptr,
-        const EvaluateExpressionOptions &options,
-        Stream &errors, 
-        Value &results)
-{
-    using namespace clang;
-    lldb::ExpressionResults return_value = lldb::eExpressionSetupError;
-    
-    // ClangFunction::ExecuteFunction execution is always just to get the result.  Do make sure we ignore
-    // breakpoints, unwind on error, and don't try to debug it.
-    EvaluateExpressionOptions real_options = options;
-    real_options.SetDebug(false);
-    real_options.SetUnwindOnError(true);
-    real_options.SetIgnoreBreakpoints(true);
-    
-    lldb::addr_t args_addr;
-    
-    if (args_addr_ptr != NULL)
-        args_addr = *args_addr_ptr;
-    else
-        args_addr = LLDB_INVALID_ADDRESS;
-        
-    if (CompileFunction(errors) != 0)
-        return lldb::eExpressionSetupError;
-    
-    if (args_addr == LLDB_INVALID_ADDRESS)
-    {
-        if (!InsertFunction(exe_ctx, args_addr, errors))
-            return lldb::eExpressionSetupError;
-    }
-
-    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
-
-    if (log)
-        log->Printf("== [ClangFunction::ExecuteFunction] Executing function \"%s\" ==", m_name.c_str());
-    
-    lldb::ThreadPlanSP call_plan_sp = GetThreadPlanToCallFunction (exe_ctx,
-                                                                   args_addr,
-                                                                   real_options,
-                                                                   errors);
-    if (!call_plan_sp)
-        return lldb::eExpressionSetupError;
-        
-    // We need to make sure we record the fact that we are running an expression here
-    // otherwise this fact will fail to be recorded when fetching an Objective-C object description
-    if (exe_ctx.GetProcessPtr())
-        exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
-    
-    return_value = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
-                                                          call_plan_sp,
-                                                          real_options,
-                                                          errors);
-    
-    if (log)
-    {
-        if (return_value != lldb::eExpressionCompleted)
-        {
-            log->Printf("== [ClangFunction::ExecuteFunction] Execution of \"%s\" completed abnormally ==", m_name.c_str());
-        }
-        else
-        {
-            log->Printf("== [ClangFunction::ExecuteFunction] Execution of \"%s\" completed normally ==", m_name.c_str());
-        }
-    }
-    
-    if (exe_ctx.GetProcessPtr())
-        exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
-    
-    if (args_addr_ptr != NULL)
-        *args_addr_ptr = args_addr;
-    
-    if (return_value != lldb::eExpressionCompleted)
-        return return_value;
-
-    FetchFunctionResults(exe_ctx, args_addr, results);
-    
-    if (args_addr_ptr == NULL)
-        DeallocateFunctionResults(exe_ctx, args_addr);
-        
-    return lldb::eExpressionCompleted;
-}
-
-clang::ASTConsumer *
-ClangFunction::ASTTransformer (clang::ASTConsumer *passthrough)
-{
-    m_struct_extractor.reset(new ASTStructExtractor(passthrough, m_wrapper_struct_name.c_str(), *this));
-    
-    return m_struct_extractor.get();
-}

Copied: lldb/trunk/source/Expression/ClangFunctionCaller.cpp (from r247584, lldb/trunk/source/Expression/ClangFunction.cpp)
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangFunctionCaller.cpp?p2=lldb/trunk/source/Expression/ClangFunctionCaller.cpp&p1=lldb/trunk/source/Expression/ClangFunction.cpp&r1=247584&r2=247720&rev=247720&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangFunction.cpp (original)
+++ lldb/trunk/source/Expression/ClangFunctionCaller.cpp Tue Sep 15 16:13:50 2015
@@ -1,4 +1,4 @@
-//===-- ClangFunction.cpp ---------------------------------------*- C++ -*-===//
+//===-- ClangFunctionCallerCaller.cpp ---------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -30,7 +30,7 @@
 #include "lldb/Core/ValueObjectList.h"
 #include "lldb/Expression/ASTStructExtractor.h"
 #include "lldb/Expression/ClangExpressionParser.h"
-#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/ClangFunctionCaller.h"
 #include "lldb/Expression/IRExecutionUnit.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Symbol/ClangASTContext.h"
@@ -47,9 +47,9 @@
 using namespace lldb_private;
 
 //----------------------------------------------------------------------
-// ClangFunction constructor
+// ClangFunctionCaller constructor
 //----------------------------------------------------------------------
-ClangFunction::ClangFunction 
+ClangFunctionCaller::ClangFunctionCaller 
 (
     ExecutionContextScope &exe_scope,
     const CompilerType &return_type, 
@@ -57,68 +57,23 @@ ClangFunction::ClangFunction
     const ValueList &arg_value_list,
     const char *name
 ) :
-    m_execution_unit_sp(),
-    m_parser(),
-    m_jit_module_wp(),
-    m_name (name ? name : "<unknown>"),
-    m_function_ptr (NULL),
-    m_function_addr (functionAddress),
-    m_function_return_type(return_type),
-    m_wrapper_function_name ("__lldb_caller_function"),
-    m_wrapper_struct_name ("__lldb_caller_struct"),
-    m_wrapper_args_addrs (),
-    m_arg_values (arg_value_list),
-    m_compiled (false),
-    m_JITted (false)
+    FunctionCaller(exe_scope, return_type, functionAddress, arg_value_list, name),
+    m_type_system_helper (*this)
 {
     m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess());
-    // Can't make a ClangFunction without a process.
+    // Can't make a ClangFunctionCaller without a process.
     assert (m_jit_process_wp.lock());
 }
 
-ClangFunction::ClangFunction
-(
-    ExecutionContextScope &exe_scope,
-    Function &function, 
-    ClangASTContext *ast_context, 
-    const ValueList &arg_value_list,
-    const char *name
-) :
-    m_name (name ? name : "<unknown>"),
-    m_function_ptr (&function),
-    m_function_addr (),
-    m_function_return_type (),
-    m_wrapper_function_name ("__lldb_function_caller"),
-    m_wrapper_struct_name ("__lldb_caller_struct"),
-    m_wrapper_args_addrs (),
-    m_arg_values (arg_value_list),
-    m_compiled (false),
-    m_JITted (false)
-{
-    m_jit_process_wp = exe_scope.CalculateProcess();
-    // Can't make a ClangFunction without a process.
-    assert (m_jit_process_wp.lock());
-
-    m_function_addr = m_function_ptr->GetAddressRange().GetBaseAddress();
-    m_function_return_type = m_function_ptr->GetCompilerType().GetFunctionReturnType();
-}
-
 //----------------------------------------------------------------------
 // Destructor
 //----------------------------------------------------------------------
-ClangFunction::~ClangFunction()
+ClangFunctionCaller::~ClangFunctionCaller()
 {
-    lldb::ProcessSP process_sp (m_jit_process_wp.lock());
-    if (process_sp)
-    {
-        lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
-        if (jit_module_sp)
-            process_sp->GetTarget().GetImages().Remove(jit_module_sp);
-    }    
 }
 
 unsigned
-ClangFunction::CompileFunction (Stream &errors)
+ClangFunctionCaller::CompileFunction (Stream &errors)
 {
     if (m_compiled)
         return 0;
@@ -256,341 +211,10 @@ ClangFunction::CompileFunction (Stream &
     return num_errors;
 }
 
-bool
-ClangFunction::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
-{
-    Process *process = exe_ctx.GetProcessPtr();
-
-    if (!process)
-        return false;
-    
-    lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
-    
-    if (process != jit_process_sp.get())
-        return false;
-    
-    if (!m_compiled)
-        return false;
-
-    if (m_JITted)
-        return true;
-        
-    bool can_interpret = false; // should stay that way
-    
-    Error jit_error (m_parser->PrepareForExecution (m_jit_start_addr,
-                                                    m_jit_end_addr,
-                                                    m_execution_unit_sp,
-                                                    exe_ctx, 
-                                                    can_interpret,
-                                                    eExecutionPolicyAlways));
-    
-    if (!jit_error.Success())
-        return false;
-    
-    if (m_parser->GetGenerateDebugInfo())
-    {
-        lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
-        
-        if (jit_module_sp)
-        {
-            ConstString const_func_name(FunctionName());
-            FileSpec jit_file;
-            jit_file.GetFilename() = const_func_name;
-            jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
-            m_jit_module_wp = jit_module_sp;
-            process->GetTarget().GetImages().Append(jit_module_sp);
-        }
-    }
-    if (process && m_jit_start_addr)
-        m_jit_process_wp = process->shared_from_this();
-    
-    m_JITted = true;
-
-    return true;
-}
-
-bool
-ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
-{
-    return WriteFunctionArguments(exe_ctx, args_addr_ref, m_function_addr, m_arg_values, errors);    
-}
-
-// FIXME: Assure that the ValueList we were passed in is consistent with the one that defined this function.
-
-bool
-ClangFunction::WriteFunctionArguments (ExecutionContext &exe_ctx, 
-                                       lldb::addr_t &args_addr_ref, 
-                                       Address function_address, 
-                                       ValueList &arg_values, 
-                                       Stream &errors)
-{
-    // All the information to reconstruct the struct is provided by the
-    // StructExtractor.
-    if (!m_struct_valid)
-    {
-        errors.Printf("Argument information was not correctly parsed, so the function cannot be called.");
-        return false;
-    }
-        
-    Error error;
-    using namespace clang;
-    lldb::ExpressionResults return_value = lldb::eExpressionSetupError;
-
-    Process *process = exe_ctx.GetProcessPtr();
-
-    if (process == NULL)
-        return return_value;
-
-    lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
-    
-    if (process != jit_process_sp.get())
-        return false;
-                
-    if (args_addr_ref == LLDB_INVALID_ADDRESS)
-    {
-        args_addr_ref = process->AllocateMemory(m_struct_size, lldb::ePermissionsReadable|lldb::ePermissionsWritable, error);
-        if (args_addr_ref == LLDB_INVALID_ADDRESS)
-            return false;
-        m_wrapper_args_addrs.push_back (args_addr_ref);
-    } 
-    else 
-    {
-        // Make sure this is an address that we've already handed out.
-        if (find (m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr_ref) == m_wrapper_args_addrs.end())
-        {
-            return false;
-        }
-    }
-
-    // TODO: verify fun_addr needs to be a callable address
-    Scalar fun_addr (function_address.GetCallableLoadAddress(exe_ctx.GetTargetPtr()));
-    uint64_t first_offset = m_member_offsets[0];
-    process->WriteScalarToMemory(args_addr_ref + first_offset, fun_addr, process->GetAddressByteSize(), error);
-
-    // FIXME: We will need to extend this for Variadic functions.
-
-    Error value_error;
-    
-    size_t num_args = arg_values.GetSize();
-    if (num_args != m_arg_values.GetSize())
-    {
-        errors.Printf ("Wrong number of arguments - was: %" PRIu64 " should be: %" PRIu64 "", (uint64_t)num_args, (uint64_t)m_arg_values.GetSize());
-        return false;
-    }
-    
-    for (size_t i = 0; i < num_args; i++)
-    {
-        // FIXME: We should sanity check sizes.
-
-        uint64_t offset = m_member_offsets[i+1]; // Clang sizes are in bytes.
-        Value *arg_value = arg_values.GetValueAtIndex(i);
-        
-        // FIXME: For now just do scalars:
-        
-        // Special case: if it's a pointer, don't do anything (the ABI supports passing cstrings)
-        
-        if (arg_value->GetValueType() == Value::eValueTypeHostAddress &&
-            arg_value->GetContextType() == Value::eContextTypeInvalid &&
-            arg_value->GetCompilerType().IsPointerType())
-            continue;
-        
-        const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx);
-
-        if (!process->WriteScalarToMemory(args_addr_ref + offset, arg_scalar, arg_scalar.GetByteSize(), error))
-            return false;
-    }
-
-    return true;
-}
-
-bool
-ClangFunction::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
-{
-    using namespace clang;
-    
-    if (CompileFunction(errors) != 0)
-        return false;
-    if (!WriteFunctionWrapper(exe_ctx, errors))
-        return false;
-    if (!WriteFunctionArguments(exe_ctx, args_addr_ref, errors))
-        return false;
-
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    if (log)
-        log->Printf ("Call Address: 0x%" PRIx64 " Struct Address: 0x%" PRIx64 ".\n", m_jit_start_addr, args_addr_ref);
-        
-    return true;
-}
-
-lldb::ThreadPlanSP
-ClangFunction::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, 
-                                            lldb::addr_t args_addr,
-                                            const EvaluateExpressionOptions &options,
-                                            Stream &errors)
-{
-    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
-    
-    if (log)
-        log->Printf("-- [ClangFunction::GetThreadPlanToCallFunction] Creating thread plan to call function \"%s\" --", m_name.c_str());
-    
-    // FIXME: Use the errors Stream for better error reporting.
-    Thread *thread = exe_ctx.GetThreadPtr();
-    if (thread == NULL)
-    {
-        errors.Printf("Can't call a function without a valid thread.");
-        return NULL;
-    }
-
-    // Okay, now run the function:
-
-    Address wrapper_address (m_jit_start_addr);
-    
-    lldb::addr_t args = { args_addr };
-    
-    lldb::ThreadPlanSP new_plan_sp (new ThreadPlanCallFunction (*thread,
-                                                       wrapper_address,
-                                                       CompilerType(),
-                                                       args,
-                                                       options));
-    new_plan_sp->SetIsMasterPlan(true);
-    new_plan_sp->SetOkayToDiscard (false);
-    return new_plan_sp;
-}
-
-bool
-ClangFunction::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr, Value &ret_value)
-{
-    // Read the return value - it is the last field in the struct:
-    // FIXME: How does clang tell us there's no return value?  We need to handle that case.
-    // FIXME: Create our ThreadPlanCallFunction with the return CompilerType, and then use GetReturnValueObject
-    // to fetch the value.  That way we can fetch any values we need.
-    
-    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
-    
-    if (log)
-        log->Printf("-- [ClangFunction::FetchFunctionResults] Fetching function results for \"%s\"--", m_name.c_str());
-    
-    Process *process = exe_ctx.GetProcessPtr();
-    
-    if (process == NULL)
-        return false;
-
-    lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
-    
-    if (process != jit_process_sp.get())
-        return false;
-                
-    Error error;
-    ret_value.GetScalar() = process->ReadUnsignedIntegerFromMemory (args_addr + m_return_offset, m_return_size, 0, error);
-
-    if (error.Fail())
-        return false;
-
-    ret_value.SetCompilerType(m_function_return_type);
-    ret_value.SetValueType(Value::eValueTypeScalar);
-    return true;
-}
-
-void
-ClangFunction::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr)
-{
-    std::list<lldb::addr_t>::iterator pos;
-    pos = std::find(m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr);
-    if (pos != m_wrapper_args_addrs.end())
-        m_wrapper_args_addrs.erase(pos);
-    
-    exe_ctx.GetProcessRef().DeallocateMemory(args_addr);
-}
-
-lldb::ExpressionResults
-ClangFunction::ExecuteFunction(
-        ExecutionContext &exe_ctx, 
-        lldb::addr_t *args_addr_ptr,
-        const EvaluateExpressionOptions &options,
-        Stream &errors, 
-        Value &results)
-{
-    using namespace clang;
-    lldb::ExpressionResults return_value = lldb::eExpressionSetupError;
-    
-    // ClangFunction::ExecuteFunction execution is always just to get the result.  Do make sure we ignore
-    // breakpoints, unwind on error, and don't try to debug it.
-    EvaluateExpressionOptions real_options = options;
-    real_options.SetDebug(false);
-    real_options.SetUnwindOnError(true);
-    real_options.SetIgnoreBreakpoints(true);
-    
-    lldb::addr_t args_addr;
-    
-    if (args_addr_ptr != NULL)
-        args_addr = *args_addr_ptr;
-    else
-        args_addr = LLDB_INVALID_ADDRESS;
-        
-    if (CompileFunction(errors) != 0)
-        return lldb::eExpressionSetupError;
-    
-    if (args_addr == LLDB_INVALID_ADDRESS)
-    {
-        if (!InsertFunction(exe_ctx, args_addr, errors))
-            return lldb::eExpressionSetupError;
-    }
-
-    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
-
-    if (log)
-        log->Printf("== [ClangFunction::ExecuteFunction] Executing function \"%s\" ==", m_name.c_str());
-    
-    lldb::ThreadPlanSP call_plan_sp = GetThreadPlanToCallFunction (exe_ctx,
-                                                                   args_addr,
-                                                                   real_options,
-                                                                   errors);
-    if (!call_plan_sp)
-        return lldb::eExpressionSetupError;
-        
-    // We need to make sure we record the fact that we are running an expression here
-    // otherwise this fact will fail to be recorded when fetching an Objective-C object description
-    if (exe_ctx.GetProcessPtr())
-        exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
-    
-    return_value = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
-                                                          call_plan_sp,
-                                                          real_options,
-                                                          errors);
-    
-    if (log)
-    {
-        if (return_value != lldb::eExpressionCompleted)
-        {
-            log->Printf("== [ClangFunction::ExecuteFunction] Execution of \"%s\" completed abnormally ==", m_name.c_str());
-        }
-        else
-        {
-            log->Printf("== [ClangFunction::ExecuteFunction] Execution of \"%s\" completed normally ==", m_name.c_str());
-        }
-    }
-    
-    if (exe_ctx.GetProcessPtr())
-        exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
-    
-    if (args_addr_ptr != NULL)
-        *args_addr_ptr = args_addr;
-    
-    if (return_value != lldb::eExpressionCompleted)
-        return return_value;
-
-    FetchFunctionResults(exe_ctx, args_addr, results);
-    
-    if (args_addr_ptr == NULL)
-        DeallocateFunctionResults(exe_ctx, args_addr);
-        
-    return lldb::eExpressionCompleted;
-}
-
 clang::ASTConsumer *
-ClangFunction::ASTTransformer (clang::ASTConsumer *passthrough)
+ClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer (clang::ASTConsumer *passthrough)
 {
-    m_struct_extractor.reset(new ASTStructExtractor(passthrough, m_wrapper_struct_name.c_str(), *this));
+    m_struct_extractor.reset(new ASTStructExtractor(passthrough, m_owner.GetWrapperStructName(), m_owner));
     
     return m_struct_extractor.get();
 }

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Tue Sep 15 16:13:50 2015
@@ -25,7 +25,6 @@
 #include "lldb/Expression/ASTResultSynthesizer.h"
 #include "lldb/Expression/ClangExpressionDeclMap.h"
 #include "lldb/Expression/ClangExpressionParser.h"
-#include "lldb/Expression/ClangFunction.h"
 #include "lldb/Expression/ClangModulesDeclVendor.h"
 #include "lldb/Expression/ClangPersistentVariables.h"
 #include "lldb/Expression/ClangUserExpression.h"
@@ -54,32 +53,13 @@
 
 using namespace lldb_private;
 
-ClangUserExpression::ClangUserExpression (const char *expr,
+ClangUserExpression::ClangUserExpression (ExecutionContextScope &exe_scope,
+                                          const char *expr,
                                           const char *expr_prefix,
                                           lldb::LanguageType language,
                                           ResultType desired_type) :
-    ClangExpression (),
-    m_stack_frame_bottom (LLDB_INVALID_ADDRESS),
-    m_stack_frame_top (LLDB_INVALID_ADDRESS),
-    m_expr_text (expr),
-    m_expr_prefix (expr_prefix ? expr_prefix : ""),
-    m_language (language),
-    m_transformed_text (),
-    m_desired_type (desired_type),
-    m_expr_decl_map(),
-    m_execution_unit_sp(),
-    m_materializer_ap(),
-    m_result_synthesizer(),
-    m_jit_module_wp(),
-    m_enforce_valid_object (true),
-    m_in_cplusplus_method (false),
-    m_in_objectivec_method (false),
-    m_in_static_method(false),
-    m_needs_object_ptr (false),
-    m_const_object (false),
-    m_target (NULL),
-    m_can_interpret (false),
-    m_materialized_address (LLDB_INVALID_ADDRESS)
+    UserExpression (exe_scope, expr, expr_prefix, language, desired_type),
+    m_type_system_helper(*m_target_wp.lock().get())
 {
     switch (m_language)
     {
@@ -99,21 +79,6 @@ ClangUserExpression::ClangUserExpression
 
 ClangUserExpression::~ClangUserExpression ()
 {
-    if (m_target)
-    {
-        lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
-        if (jit_module_sp)
-            m_target->GetImages().Remove(jit_module_sp);
-    }
-}
-
-clang::ASTConsumer *
-ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
-{
-    m_result_synthesizer.reset(new ASTResultSynthesizer(passthrough,
-                                                        *m_target));
-
-    return m_result_synthesizer.get();
 }
 
 void
@@ -338,54 +303,6 @@ ClangUserExpression::ScanContext(Executi
     }
 }
 
-void
-ClangUserExpression::InstallContext (ExecutionContext &exe_ctx)
-{
-    m_process_wp = exe_ctx.GetProcessSP();
-
-    lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
-
-    if (frame_sp)
-        m_address = frame_sp->GetFrameCodeAddress();
-}
-
-bool
-ClangUserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
-                                          lldb::TargetSP &target_sp,
-                                          lldb::ProcessSP &process_sp,
-                                          lldb::StackFrameSP &frame_sp)
-{
-    lldb::ProcessSP expected_process_sp = m_process_wp.lock();
-    process_sp = exe_ctx.GetProcessSP();
-
-    if (process_sp != expected_process_sp)
-        return false;
-
-    process_sp = exe_ctx.GetProcessSP();
-    target_sp = exe_ctx.GetTargetSP();
-    frame_sp = exe_ctx.GetFrameSP();
-
-    if (m_address.IsValid())
-    {
-        if (!frame_sp)
-            return false;
-        else
-            return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
-    }
-
-    return true;
-}
-
-bool
-ClangUserExpression::MatchesContext (ExecutionContext &exe_ctx)
-{
-    lldb::TargetSP target_sp;
-    lldb::ProcessSP process_sp;
-    lldb::StackFrameSP frame_sp;
-
-    return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
-}
-
 // This is a really nasty hack, meant to fix Objective-C expressions of the form
 // (int)[myArray count].  Right now, because the type information for count is
 // not available, [myArray count] returns id, which can't be directly cast to
@@ -405,26 +322,6 @@ ApplyObjcCastHack(std::string &expr)
 #undef OBJC_CAST_HACK_FROM
 }
 
-// Another hack, meant to allow use of unichar despite it not being available in
-// the type information.  Although we could special-case it in type lookup,
-// hopefully we'll figure out a way to #include the same environment as is
-// present in the original source file rather than try to hack specific type
-// definitions in as needed.
-//static void
-//ApplyUnicharHack(std::string &expr)
-//{
-//#define UNICHAR_HACK_FROM "unichar"
-//#define UNICHAR_HACK_TO   "unsigned short"
-//
-//    size_t from_offset;
-//
-//    while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
-//        expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
-//
-//#undef UNICHAR_HACK_TO
-//#undef UNICHAR_HACK_FROM
-//}
-
 bool
 ClangUserExpression::Parse (Stream &error_stream,
                             ExecutionContext &exe_ctx,
@@ -525,7 +422,7 @@ ClangUserExpression::Parse (Stream &erro
 
     m_materializer_ap.reset(new Materializer());
 
-    m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
+    ResetDeclMap(exe_ctx, keep_result_in_memory);
 
     class OnExit
     {
@@ -545,13 +442,13 @@ ClangUserExpression::Parse (Stream &erro
         Callback m_callback;
     };
 
-    OnExit on_exit([this]() { m_expr_decl_map.reset(); });
+    OnExit on_exit([this]() { ResetDeclMap(); });
 
-    if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get()))
+    if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get()))
     {
         error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
 
-        m_expr_decl_map.reset(); // We are being careful here in the case of breakpoint conditions.
+        ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
 
         return false;
     }
@@ -570,7 +467,7 @@ ClangUserExpression::Parse (Stream &erro
     {
         error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
 
-        m_expr_decl_map.reset(); // We are being careful here in the case of breakpoint conditions.
+        ResetDeclMap(); // We are being careful here in the case of breakpoint conditions.
 
         return false;
     }
@@ -617,7 +514,7 @@ ClangUserExpression::Parse (Stream &erro
 //        }
     }
 
-    m_expr_decl_map.reset(); // Make this go away since we don't need any of its state after parsing.  This also gets rid of any ClangASTImporter::Minions.
+    ResetDeclMap(); // Make this go away since we don't need any of its state after parsing.  This also gets rid of any ClangASTImporter::Minions.
 
     if (jit_error.Success())
     {
@@ -636,537 +533,81 @@ ClangUserExpression::Parse (Stream &erro
     }
 }
 
-static lldb::addr_t
-GetObjectPointer (lldb::StackFrameSP frame_sp,
-                  ConstString &object_name,
-                  Error &err)
-{
-    err.Clear();
-
-    if (!frame_sp)
-    {
-        err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
-        return LLDB_INVALID_ADDRESS;
-    }
-
-    lldb::VariableSP var_sp;
-    lldb::ValueObjectSP valobj_sp;
-
-    valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
-                                                            lldb::eNoDynamicValues,
-                                                            StackFrame::eExpressionPathOptionCheckPtrVsMember |
-                                                            StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
-                                                            StackFrame::eExpressionPathOptionsNoSyntheticChildren |
-                                                            StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
-                                                            var_sp,
-                                                            err);
-
-    if (!err.Success() || !valobj_sp.get())
-        return LLDB_INVALID_ADDRESS;
-
-    lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-
-    if (ret == LLDB_INVALID_ADDRESS)
-    {
-        err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
-        return LLDB_INVALID_ADDRESS;
-    }
-
-    return ret;
-}
-
 bool
-ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
-                                                    ExecutionContext &exe_ctx,
-                                                    lldb::addr_t &struct_address,
-                                                    lldb::addr_t &object_ptr,
-                                                    lldb::addr_t &cmd_ptr)
+ClangUserExpression::AddInitialArguments (ExecutionContext &exe_ctx,
+                                          std::vector<lldb::addr_t> &args,
+                                          Stream &error_stream)
 {
-    lldb::TargetSP target;
-    lldb::ProcessSP process;
-    lldb::StackFrameSP frame;
-
-    if (!LockAndCheckContext(exe_ctx,
-                             target,
-                             process,
-                             frame))
-    {
-        error_stream.Printf("The context has changed before we could JIT the expression!\n");
-        return false;
-    }
-
-    if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
+    lldb::addr_t object_ptr = LLDB_INVALID_ADDRESS;
+    lldb::addr_t cmd_ptr    = LLDB_INVALID_ADDRESS;
+    
+    if (m_needs_object_ptr)
     {
-        if (m_needs_object_ptr)
-        {
-            ConstString object_name;
-
-            if (m_in_cplusplus_method)
-            {
-                object_name.SetCString("this");
-            }
-            else if (m_in_objectivec_method)
-            {
-                object_name.SetCString("self");
-            }
-            else
-            {
-                error_stream.Printf("Need object pointer but don't know the language\n");
-                return false;
-            }
-
-            Error object_ptr_error;
-
-            object_ptr = GetObjectPointer(frame, object_name, object_ptr_error);
-
-            if (!object_ptr_error.Success())
-            {
-                error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
-                object_ptr = 0;
-            }
-
-            if (m_in_objectivec_method)
-            {
-                ConstString cmd_name("_cmd");
-
-                cmd_ptr = GetObjectPointer(frame, cmd_name, object_ptr_error);
-
-                if (!object_ptr_error.Success())
-                {
-                    error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
-                    cmd_ptr = 0;
-                }
-            }
-        }
+        lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
+        if (!frame_sp)
+            return true;
+        
+        ConstString object_name;
 
-        if (m_materialized_address == LLDB_INVALID_ADDRESS)
+        if (m_in_cplusplus_method)
         {
-            Error alloc_error;
-
-            IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
-
-            m_materialized_address = m_execution_unit_sp->Malloc(m_materializer_ap->GetStructByteSize(),
-                                                                 m_materializer_ap->GetStructAlignment(),
-                                                                 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
-                                                                 policy,
-                                                                 alloc_error);
-
-            if (!alloc_error.Success())
-            {
-                error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
-                return false;
-            }
+            object_name.SetCString("this");
         }
-
-        struct_address = m_materialized_address;
-
-        if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
+        else if (m_in_objectivec_method)
         {
-            Error alloc_error;
-
-            const size_t stack_frame_size = 512 * 1024;
-
-            m_stack_frame_bottom = m_execution_unit_sp->Malloc(stack_frame_size,
-                                                               8,
-                                                               lldb::ePermissionsReadable | lldb::ePermissionsWritable,
-                                                               IRMemoryMap::eAllocationPolicyHostOnly,
-                                                               alloc_error);
-
-            m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
-
-            if (!alloc_error.Success())
-            {
-                error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
-                return false;
-            }
+            object_name.SetCString("self");
         }
-
-        Error materialize_error;
-
-        m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_sp, struct_address, materialize_error);
-
-        if (!materialize_error.Success())
+        else
         {
-            error_stream.Printf("Couldn't materialize: %s\n", materialize_error.AsCString());
+            error_stream.Printf("Need object pointer but don't know the language\n");
             return false;
         }
-    }
-    return true;
-}
-
-bool
-ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
-                                           ExecutionContext &exe_ctx,
-                                           lldb::ExpressionVariableSP &result,
-                                           lldb::addr_t function_stack_bottom,
-                                           lldb::addr_t function_stack_top)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
-    if (log)
-        log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --");
-
-    if (!m_dematerializer_sp)
-    {
-        error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present");
-        return false;
-    }
 
-    Error dematerialize_error;
+        Error object_ptr_error;
 
-    m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top);
+        object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error);
 
-    if (!dematerialize_error.Success())
-    {
-        error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error"));
-        return false;
-    }
-
-    if (result)
-        result->TransferAddress();
-
-    m_dematerializer_sp.reset();
-
-    return true;
-}
-
-lldb::ExpressionResults
-ClangUserExpression::Execute (Stream &error_stream,
-                              ExecutionContext &exe_ctx,
-                              const EvaluateExpressionOptions& options,
-                              lldb::ClangUserExpressionSP &shared_ptr_to_me,
-                              lldb::ExpressionVariableSP &result)
-{
-    // The expression log is quite verbose, and if you're just tracking the execution of the
-    // expression, it's quite convenient to have these logs come out with the STEP log as well.
-    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
-
-    if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
-    {
-        lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
-
-        lldb::addr_t object_ptr = 0;
-        lldb::addr_t cmd_ptr = 0;
-
-        if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr))
+        if (!object_ptr_error.Success())
         {
-            error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
-            return lldb::eExpressionSetupError;
+            error_stream.Printf("warning: couldn't get required object pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
+            object_ptr = 0;
         }
 
-        lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
-        lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
-
-        if (m_can_interpret)
+        if (m_in_objectivec_method)
         {
-            llvm::Module *module = m_execution_unit_sp->GetModule();
-            llvm::Function *function = m_execution_unit_sp->GetFunction();
+            ConstString cmd_name("_cmd");
 
-            if (!module || !function)
-            {
-                error_stream.Printf("Supposed to interpret, but nothing is there");
-                return lldb::eExpressionSetupError;
-            }
-
-            Error interpreter_error;
-
-            llvm::SmallVector <lldb::addr_t, 3> args;
-
-            if (m_needs_object_ptr)
-            {
-                args.push_back(object_ptr);
-
-                if (m_in_objectivec_method)
-                    args.push_back(cmd_ptr);
-            }
+            cmd_ptr = GetObjectPointer(frame_sp, cmd_name, object_ptr_error);
 
-            args.push_back(struct_address);
-
-            function_stack_bottom = m_stack_frame_bottom;
-            function_stack_top = m_stack_frame_top;
-
-            IRInterpreter::Interpret (*module,
-                                      *function,
-                                      args,
-                                      *m_execution_unit_sp.get(),
-                                      interpreter_error,
-                                      function_stack_bottom,
-                                      function_stack_top,
-                                      exe_ctx);
-
-            if (!interpreter_error.Success())
+            if (!object_ptr_error.Success())
             {
-                error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
-                return lldb::eExpressionDiscarded;
+                error_stream.Printf("warning: couldn't get cmd pointer (substituting NULL): %s\n", object_ptr_error.AsCString());
+                cmd_ptr = 0;
             }
         }
-        else
-        {
-            if (!exe_ctx.HasThreadScope())
-            {
-                error_stream.Printf("ClangUserExpression::Execute called with no thread selected.");
-                return lldb::eExpressionSetupError;
-            }
-
-            Address wrapper_address (m_jit_start_addr);
-
-            llvm::SmallVector <lldb::addr_t, 3> args;
-
-            if (m_needs_object_ptr) {
-                args.push_back(object_ptr);
-                if (m_in_objectivec_method)
-                    args.push_back(cmd_ptr);
-            }
-
-            args.push_back(struct_address);
-         
-            lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
-                                                                              wrapper_address,
-                                                                              args,
-                                                                              options,
-                                                                              shared_ptr_to_me));
-
-            if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
-                return lldb::eExpressionSetupError;
-
-            ThreadPlanCallUserExpression *user_expression_plan = static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get());
-
-            lldb::addr_t function_stack_pointer = user_expression_plan->GetFunctionStackPointer();
-
-            function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize();
-            function_stack_top = function_stack_pointer;
-
-            if (log)
-                log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
-
-            if (exe_ctx.GetProcessPtr())
-                exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
-
-            lldb::ExpressionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
-                                                                                       call_plan_sp,
-                                                                                       options,
-                                                                                       error_stream);
-
-            if (exe_ctx.GetProcessPtr())
-                exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
-
-            if (log)
-                log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
-
-            if (execution_result == lldb::eExpressionInterrupted || execution_result == lldb::eExpressionHitBreakpoint)
-            {
-                const char *error_desc = NULL;
-
-                if (call_plan_sp)
-                {
-                    lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
-                    if (real_stop_info_sp)
-                        error_desc = real_stop_info_sp->GetDescription();
-                }
-                if (error_desc)
-                    error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
-                else
-                    error_stream.PutCString ("Execution was interrupted.");
+        if (object_ptr)
+            args.push_back(object_ptr);
 
-                if ((execution_result == lldb::eExpressionInterrupted && options.DoesUnwindOnError())
-                    || (execution_result == lldb::eExpressionHitBreakpoint && options.DoesIgnoreBreakpoints()))
-                    error_stream.PutCString ("\nThe process has been returned to the state before expression evaluation.");
-                else
-                {
-                    if (execution_result == lldb::eExpressionHitBreakpoint)
-                        user_expression_plan->TransferExpressionOwnership();
-                    error_stream.PutCString ("\nThe process has been left at the point where it was interrupted, "
-                                             "use \"thread return -x\" to return to the state before expression evaluation.");
-                }
+        if (m_in_objectivec_method)
+            args.push_back(cmd_ptr);
 
-                return execution_result;
-            }
-            else if (execution_result == lldb::eExpressionStoppedForDebug)
-            {
-                    error_stream.PutCString ("Execution was halted at the first instruction of the expression "
-                                             "function because \"debug\" was requested.\n"
-                                             "Use \"thread return -x\" to return to the state before expression evaluation.");
-                    return execution_result;
-            }
-            else if (execution_result != lldb::eExpressionCompleted)
-            {
-                error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
-                return execution_result;
-            }
-        }
 
-        if  (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
-        {
-            return lldb::eExpressionCompleted;
-        }
-        else
-        {
-            return lldb::eExpressionResultUnavailable;
-        }
-    }
-    else
-    {
-        error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
-        return lldb::eExpressionSetupError;
     }
+    return true;
 }
 
-lldb::ExpressionResults
-ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
-                               const EvaluateExpressionOptions& options,
-                               const char *expr_cstr,
-                               const char *expr_prefix,
-                               lldb::ValueObjectSP &result_valobj_sp,
-                               Error &error)
+void
+ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory)
 {
-    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
-
-    lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
-    const lldb::LanguageType language = options.GetLanguage();
-    const ResultType desired_type = options.DoesCoerceToId() ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny;
-    lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
-
-    Process *process = exe_ctx.GetProcessPtr();
-
-    if (process == NULL || process->GetState() != lldb::eStateStopped)
-    {
-        if (execution_policy == eExecutionPolicyAlways)
-        {
-            if (log)
-                log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
-
-            error.SetErrorString ("expression needed to run but couldn't");
-
-            return execution_results;
-        }
-    }
-
-    if (process == NULL || !process->CanJIT())
-        execution_policy = eExecutionPolicyNever;
-
-    const char *full_prefix = NULL;
-    const char *option_prefix = options.GetPrefix();
-    std::string full_prefix_storage;
-    if (expr_prefix && option_prefix)
-    {
-        full_prefix_storage.assign(expr_prefix);
-        full_prefix_storage.append(option_prefix);
-        if (!full_prefix_storage.empty())
-            full_prefix = full_prefix_storage.c_str();
-    }
-    else if (expr_prefix)
-        full_prefix = expr_prefix;
-    else
-        full_prefix = option_prefix;
-
-    lldb::ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, full_prefix, language, desired_type));
-
-    StreamString error_stream;
-
-    if (log)
-        log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
-
-    const bool keep_expression_in_memory = true;
-    const bool generate_debug_info = options.GetGenerateDebugInfo();
-
-    if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse))
-    {
-        error.SetErrorString ("expression interrupted by callback before parse");
-        result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
-        return lldb::eExpressionInterrupted;
-    }
-
-    if (!user_expression_sp->Parse (error_stream,
-                                    exe_ctx,
-                                    execution_policy,
-                                    keep_expression_in_memory,
-                                    generate_debug_info))
-    {
-        execution_results = lldb::eExpressionParseError;
-        if (error_stream.GetString().empty())
-            error.SetExpressionError (execution_results, "expression failed to parse, unknown error");
-        else
-            error.SetExpressionError (execution_results, error_stream.GetString().c_str());
-    }
-    else
-    {
-        lldb::ExpressionVariableSP expr_result;
-
-        if (execution_policy == eExecutionPolicyNever &&
-            !user_expression_sp->CanInterpret())
-        {
-            if (log)
-                log->Printf("== [ClangUserExpression::Evaluate] Expression may not run, but is not constant ==");
-
-            if (error_stream.GetString().empty())
-                error.SetExpressionError (lldb::eExpressionSetupError, "expression needed to run but couldn't");
-        }
-        else
-        {
-            if (options.InvokeCancelCallback (lldb::eExpressionEvaluationExecution))
-            {
-                error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback before execution");
-                result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
-                return lldb::eExpressionInterrupted;
-            }
-
-            error_stream.GetString().clear();
-
-            if (log)
-                log->Printf("== [ClangUserExpression::Evaluate] Executing expression ==");
-
-            execution_results = user_expression_sp->Execute (error_stream,
-                                                             exe_ctx,
-                                                             options,
-                                                             user_expression_sp,
-                                                             expr_result);
-
-            if (options.GetResultIsInternal() && expr_result && process)
-            {
-                process->GetTarget().GetPersistentVariables().RemovePersistentVariable (expr_result);
-            }
-
-            if (execution_results != lldb::eExpressionCompleted)
-            {
-                if (log)
-                    log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally ==");
-
-                if (error_stream.GetString().empty())
-                    error.SetExpressionError (execution_results, "expression failed to execute, unknown error");
-                else
-                    error.SetExpressionError (execution_results, error_stream.GetString().c_str());
-            }
-            else
-            {
-                if (expr_result)
-                {
-                    result_valobj_sp = expr_result->GetValueObject();
-
-                    if (log)
-                        log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==",
-                                    result_valobj_sp->GetValueAsCString());
-                }
-                else
-                {
-                    if (log)
-                        log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result ==");
-
-                    error.SetError(ClangUserExpression::kNoResult, lldb::eErrorTypeGeneric);
-                }
-            }
-        }
-    }
-
-    if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete))
-    {
-        error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback after complete");
-        return lldb::eExpressionInterrupted;
-    }
+    m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
+}
 
-    if (result_valobj_sp.get() == NULL)
-    {
-        result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
-    }
+clang::ASTConsumer *
+ClangUserExpression::ClangUserExpressionHelper::ASTTransformer (clang::ASTConsumer *passthrough)
+{
+    m_result_synthesizer_up.reset(new ASTResultSynthesizer(passthrough,
+                                                           m_target));
 
-    return execution_results;
+    return m_result_synthesizer_up.get();
 }
+

Modified: lldb/trunk/source/Expression/ClangUtilityFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUtilityFunction.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUtilityFunction.cpp (original)
+++ lldb/trunk/source/Expression/ClangUtilityFunction.cpp Tue Sep 15 16:13:50 2015
@@ -40,29 +40,15 @@ using namespace lldb_private;
 /// @param[in] name
 ///     The name of the function, as used in the text.
 //------------------------------------------------------------------
-ClangUtilityFunction::ClangUtilityFunction (const char *text, 
+ClangUtilityFunction::ClangUtilityFunction (ExecutionContextScope &exe_scope,
+                                            const char *text,
                                             const char *name) :
-    ClangExpression (),
-    m_expr_decl_map (),
-    m_execution_unit_sp (),
-    m_jit_module_wp (),
-    m_function_text (ExpressionSourceCode::g_expression_prefix),
-    m_function_name (name)
+    UtilityFunction (exe_scope, text, name)
 {
-    if (text && text[0])
-        m_function_text.append (text);
 }
 
 ClangUtilityFunction::~ClangUtilityFunction ()
 {
-    lldb::ProcessSP process_sp (m_jit_process_wp.lock());
-    if (process_sp)
-    {
-        lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
-        if (jit_module_sp)
-            process_sp->GetTarget().GetImages().Remove(jit_module_sp);
-    }
-    
 }
 
 //------------------------------------------------------------------
@@ -113,9 +99,9 @@ ClangUtilityFunction::Install (Stream &e
     
     bool keep_result_in_memory = false;
     
-    m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
+    ResetDeclMap(exe_ctx, keep_result_in_memory);
     
-    if (!m_expr_decl_map->WillParse(exe_ctx, NULL))
+    if (!DeclMap()->WillParse(exe_ctx, NULL))
     {
         error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
         return false;
@@ -130,7 +116,7 @@ ClangUtilityFunction::Install (Stream &e
     {
         error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
         
-        m_expr_decl_map.reset();
+        ResetDeclMap();
         
         return false;
     }
@@ -176,9 +162,9 @@ ClangUtilityFunction::Install (Stream &e
                     m_function_text.c_str());
 #endif
 
-    m_expr_decl_map->DidParse();
+    DeclMap()->DidParse();
     
-    m_expr_decl_map.reset();
+    ResetDeclMap();
     
     if (jit_error.Success())
     {
@@ -195,4 +181,8 @@ ClangUtilityFunction::Install (Stream &e
     }
 }
 
-
+void
+ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(ExecutionContext &exe_ctx, bool keep_result_in_memory)
+{
+    m_expr_decl_map_up.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
+}

Added: lldb/trunk/source/Expression/Expression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/Expression.cpp?rev=247720&view=auto
==============================================================================
--- lldb/trunk/source/Expression/Expression.cpp (added)
+++ lldb/trunk/source/Expression/Expression.cpp Tue Sep 15 16:13:50 2015
@@ -0,0 +1,32 @@
+//===-- Expression.h ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Expression/Expression.h"
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb_private;
+
+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) :
+    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());
+}
+

Added: lldb/trunk/source/Expression/FunctionCaller.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/FunctionCaller.cpp?rev=247720&view=auto
==============================================================================
--- lldb/trunk/source/Expression/FunctionCaller.cpp (added)
+++ lldb/trunk/source/Expression/FunctionCaller.cpp Tue Sep 15 16:13:50 2015
@@ -0,0 +1,422 @@
+//===-- FunctionCaller.cpp ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/CodeGen/CodeGenAction.h"
+#include "clang/CodeGen/ModuleBuilder.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/IR/Module.h"
+
+// Project includes
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/State.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectList.h"
+#include "lldb/Expression/ASTStructExtractor.h"
+#include "lldb/Expression/ClangExpressionParser.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/IRExecutionUnit.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanCallFunction.h"
+
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// 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),
+    m_execution_unit_sp(),
+    m_parser(),
+    m_jit_module_wp(),
+    m_name (name ? name : "<unknown>"),
+    m_function_ptr (NULL),
+    m_function_addr (functionAddress),
+    m_function_return_type(return_type),
+    m_wrapper_function_name ("__lldb_caller_function"),
+    m_wrapper_struct_name ("__lldb_caller_struct"),
+    m_wrapper_args_addrs (),
+    m_arg_values (arg_value_list),
+    m_compiled (false),
+    m_JITted (false)
+{
+    m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess());
+    // Can't make a FunctionCaller without a process.
+    assert (m_jit_process_wp.lock());
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+FunctionCaller::~FunctionCaller()
+{
+    lldb::ProcessSP process_sp (m_jit_process_wp.lock());
+    if (process_sp)
+    {
+        lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
+        if (jit_module_sp)
+            process_sp->GetTarget().GetImages().Remove(jit_module_sp);
+    }    
+}
+
+bool
+FunctionCaller::WriteFunctionWrapper (ExecutionContext &exe_ctx, Stream &errors)
+{
+    Process *process = exe_ctx.GetProcessPtr();
+
+    if (!process)
+        return false;
+    
+    lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
+    
+    if (process != jit_process_sp.get())
+        return false;
+    
+    if (!m_compiled)
+        return false;
+
+    if (m_JITted)
+        return true;
+        
+    bool can_interpret = false; // should stay that way
+    
+    Error jit_error (m_parser->PrepareForExecution (m_jit_start_addr,
+                                                    m_jit_end_addr,
+                                                    m_execution_unit_sp,
+                                                    exe_ctx, 
+                                                    can_interpret,
+                                                    eExecutionPolicyAlways));
+    
+    if (!jit_error.Success())
+        return false;
+    
+    if (m_parser->GetGenerateDebugInfo())
+    {
+        lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
+        
+        if (jit_module_sp)
+        {
+            ConstString const_func_name(FunctionName());
+            FileSpec jit_file;
+            jit_file.GetFilename() = const_func_name;
+            jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
+            m_jit_module_wp = jit_module_sp;
+            process->GetTarget().GetImages().Append(jit_module_sp);
+        }
+    }
+    if (process && m_jit_start_addr)
+        m_jit_process_wp = process->shared_from_this();
+    
+    m_JITted = true;
+
+    return true;
+}
+
+bool
+FunctionCaller::WriteFunctionArguments (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
+{
+    return WriteFunctionArguments(exe_ctx, args_addr_ref, m_arg_values, errors);
+}
+
+// FIXME: Assure that the ValueList we were passed in is consistent with the one that defined this function.
+
+bool
+FunctionCaller::WriteFunctionArguments (ExecutionContext &exe_ctx, 
+                                       lldb::addr_t &args_addr_ref, 
+                                       ValueList &arg_values,
+                                       Stream &errors)
+{
+    // All the information to reconstruct the struct is provided by the
+    // StructExtractor.
+    if (!m_struct_valid)
+    {
+        errors.Printf("Argument information was not correctly parsed, so the function cannot be called.");
+        return false;
+    }
+        
+    Error error;
+    using namespace clang;
+    lldb::ExpressionResults return_value = lldb::eExpressionSetupError;
+
+    Process *process = exe_ctx.GetProcessPtr();
+
+    if (process == NULL)
+        return return_value;
+
+    lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
+    
+    if (process != jit_process_sp.get())
+        return false;
+                
+    if (args_addr_ref == LLDB_INVALID_ADDRESS)
+    {
+        args_addr_ref = process->AllocateMemory(m_struct_size, lldb::ePermissionsReadable|lldb::ePermissionsWritable, error);
+        if (args_addr_ref == LLDB_INVALID_ADDRESS)
+            return false;
+        m_wrapper_args_addrs.push_back (args_addr_ref);
+    } 
+    else 
+    {
+        // Make sure this is an address that we've already handed out.
+        if (find (m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr_ref) == m_wrapper_args_addrs.end())
+        {
+            return false;
+        }
+    }
+
+    // TODO: verify fun_addr needs to be a callable address
+    Scalar fun_addr (m_function_addr.GetCallableLoadAddress(exe_ctx.GetTargetPtr()));
+    uint64_t first_offset = m_member_offsets[0];
+    process->WriteScalarToMemory(args_addr_ref + first_offset, fun_addr, process->GetAddressByteSize(), error);
+
+    // FIXME: We will need to extend this for Variadic functions.
+
+    Error value_error;
+    
+    size_t num_args = arg_values.GetSize();
+    if (num_args != m_arg_values.GetSize())
+    {
+        errors.Printf ("Wrong number of arguments - was: %" PRIu64 " should be: %" PRIu64 "", (uint64_t)num_args, (uint64_t)m_arg_values.GetSize());
+        return false;
+    }
+    
+    for (size_t i = 0; i < num_args; i++)
+    {
+        // FIXME: We should sanity check sizes.
+
+        uint64_t offset = m_member_offsets[i+1]; // Clang sizes are in bytes.
+        Value *arg_value = arg_values.GetValueAtIndex(i);
+        
+        // FIXME: For now just do scalars:
+        
+        // Special case: if it's a pointer, don't do anything (the ABI supports passing cstrings)
+        
+        if (arg_value->GetValueType() == Value::eValueTypeHostAddress &&
+            arg_value->GetContextType() == Value::eContextTypeInvalid &&
+            arg_value->GetCompilerType().IsPointerType())
+            continue;
+        
+        const Scalar &arg_scalar = arg_value->ResolveValue(&exe_ctx);
+
+        if (!process->WriteScalarToMemory(args_addr_ref + offset, arg_scalar, arg_scalar.GetByteSize(), error))
+            return false;
+    }
+
+    return true;
+}
+
+bool
+FunctionCaller::InsertFunction (ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, Stream &errors)
+{
+    using namespace clang;
+    
+    if (CompileFunction(errors) != 0)
+        return false;
+    if (!WriteFunctionWrapper(exe_ctx, errors))
+        return false;
+    if (!WriteFunctionArguments(exe_ctx, args_addr_ref, errors))
+        return false;
+
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    if (log)
+        log->Printf ("Call Address: 0x%" PRIx64 " Struct Address: 0x%" PRIx64 ".\n", m_jit_start_addr, args_addr_ref);
+        
+    return true;
+}
+
+lldb::ThreadPlanSP
+FunctionCaller::GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, 
+                                            lldb::addr_t args_addr,
+                                            const EvaluateExpressionOptions &options,
+                                            Stream &errors)
+{
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
+    
+    if (log)
+        log->Printf("-- [FunctionCaller::GetThreadPlanToCallFunction] Creating thread plan to call function \"%s\" --", m_name.c_str());
+    
+    // FIXME: Use the errors Stream for better error reporting.
+    Thread *thread = exe_ctx.GetThreadPtr();
+    if (thread == NULL)
+    {
+        errors.Printf("Can't call a function without a valid thread.");
+        return NULL;
+    }
+
+    // Okay, now run the function:
+
+    Address wrapper_address (m_jit_start_addr);
+    
+    lldb::addr_t args = { args_addr };
+    
+    lldb::ThreadPlanSP new_plan_sp (new ThreadPlanCallFunction (*thread,
+                                                       wrapper_address,
+                                                       CompilerType(),
+                                                       args,
+                                                       options));
+    new_plan_sp->SetIsMasterPlan(true);
+    new_plan_sp->SetOkayToDiscard (false);
+    return new_plan_sp;
+}
+
+bool
+FunctionCaller::FetchFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr, Value &ret_value)
+{
+    // Read the return value - it is the last field in the struct:
+    // FIXME: How does clang tell us there's no return value?  We need to handle that case.
+    // FIXME: Create our ThreadPlanCallFunction with the return CompilerType, and then use GetReturnValueObject
+    // to fetch the value.  That way we can fetch any values we need.
+    
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
+    
+    if (log)
+        log->Printf("-- [FunctionCaller::FetchFunctionResults] Fetching function results for \"%s\"--", m_name.c_str());
+    
+    Process *process = exe_ctx.GetProcessPtr();
+    
+    if (process == NULL)
+        return false;
+
+    lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
+    
+    if (process != jit_process_sp.get())
+        return false;
+                
+    Error error;
+    ret_value.GetScalar() = process->ReadUnsignedIntegerFromMemory (args_addr + m_return_offset, m_return_size, 0, error);
+
+    if (error.Fail())
+        return false;
+
+    ret_value.SetCompilerType(m_function_return_type);
+    ret_value.SetValueType(Value::eValueTypeScalar);
+    return true;
+}
+
+void
+FunctionCaller::DeallocateFunctionResults (ExecutionContext &exe_ctx, lldb::addr_t args_addr)
+{
+    std::list<lldb::addr_t>::iterator pos;
+    pos = std::find(m_wrapper_args_addrs.begin(), m_wrapper_args_addrs.end(), args_addr);
+    if (pos != m_wrapper_args_addrs.end())
+        m_wrapper_args_addrs.erase(pos);
+    
+    exe_ctx.GetProcessRef().DeallocateMemory(args_addr);
+}
+
+lldb::ExpressionResults
+FunctionCaller::ExecuteFunction(
+        ExecutionContext &exe_ctx, 
+        lldb::addr_t *args_addr_ptr,
+        const EvaluateExpressionOptions &options,
+        Stream &errors, 
+        Value &results)
+{
+    using namespace clang;
+    lldb::ExpressionResults return_value = lldb::eExpressionSetupError;
+    
+    // FunctionCaller::ExecuteFunction execution is always just to get the result.  Do make sure we ignore
+    // breakpoints, unwind on error, and don't try to debug it.
+    EvaluateExpressionOptions real_options = options;
+    real_options.SetDebug(false);
+    real_options.SetUnwindOnError(true);
+    real_options.SetIgnoreBreakpoints(true);
+    
+    lldb::addr_t args_addr;
+    
+    if (args_addr_ptr != NULL)
+        args_addr = *args_addr_ptr;
+    else
+        args_addr = LLDB_INVALID_ADDRESS;
+        
+    if (CompileFunction(errors) != 0)
+        return lldb::eExpressionSetupError;
+    
+    if (args_addr == LLDB_INVALID_ADDRESS)
+    {
+        if (!InsertFunction(exe_ctx, args_addr, errors))
+            return lldb::eExpressionSetupError;
+    }
+
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
+
+    if (log)
+        log->Printf("== [FunctionCaller::ExecuteFunction] Executing function \"%s\" ==", m_name.c_str());
+    
+    lldb::ThreadPlanSP call_plan_sp = GetThreadPlanToCallFunction (exe_ctx,
+                                                                   args_addr,
+                                                                   real_options,
+                                                                   errors);
+    if (!call_plan_sp)
+        return lldb::eExpressionSetupError;
+        
+    // We need to make sure we record the fact that we are running an expression here
+    // otherwise this fact will fail to be recorded when fetching an Objective-C object description
+    if (exe_ctx.GetProcessPtr())
+        exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
+    
+    return_value = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
+                                                          call_plan_sp,
+                                                          real_options,
+                                                          errors);
+    
+    if (log)
+    {
+        if (return_value != lldb::eExpressionCompleted)
+        {
+            log->Printf("== [FunctionCaller::ExecuteFunction] Execution of \"%s\" completed abnormally ==", m_name.c_str());
+        }
+        else
+        {
+            log->Printf("== [FunctionCaller::ExecuteFunction] Execution of \"%s\" completed normally ==", m_name.c_str());
+        }
+    }
+    
+    if (exe_ctx.GetProcessPtr())
+        exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
+    
+    if (args_addr_ptr != NULL)
+        *args_addr_ptr = args_addr;
+    
+    if (return_value != lldb::eExpressionCompleted)
+        return return_value;
+
+    FetchFunctionResults(exe_ctx, args_addr, results);
+    
+    if (args_addr_ptr == NULL)
+        DeallocateFunctionResults(exe_ctx, args_addr);
+        
+    return lldb::eExpressionCompleted;
+}

Modified: lldb/trunk/source/Expression/IRDynamicChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRDynamicChecks.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRDynamicChecks.cpp (original)
+++ lldb/trunk/source/Expression/IRDynamicChecks.cpp Tue Sep 15 16:13:50 2015
@@ -11,11 +11,12 @@
 
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/Log.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/UtilityFunction.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
 
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/IR/Constants.h"
@@ -52,8 +53,14 @@ bool
 DynamicCheckerFunctions::Install(Stream &error_stream,
                                  ExecutionContext &exe_ctx)
 {
-    m_valid_pointer_check.reset(new ClangUtilityFunction(g_valid_pointer_check_text,
-                                                         VALID_POINTER_CHECK_NAME));
+    Error error;
+    m_valid_pointer_check.reset(exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(g_valid_pointer_check_text,
+                                                                                     lldb::eLanguageTypeC,
+                                                                                     VALID_POINTER_CHECK_NAME,
+                                                                                     error));
+    if (error.Fail())
+        return false;
+        
     if (!m_valid_pointer_check->Install(error_stream, exe_ctx))
         return false;
 

Added: lldb/trunk/source/Expression/UserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/UserExpression.cpp?rev=247720&view=auto
==============================================================================
--- lldb/trunk/source/Expression/UserExpression.cpp (added)
+++ lldb/trunk/source/Expression/UserExpression.cpp Tue Sep 15 16:13:50 2015
@@ -0,0 +1,644 @@
+//===-- UserExpression.cpp ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+#  include <sys/types.h>
+#endif
+
+#include <cstdlib>
+#include <string>
+#include <map>
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Expression/ASTResultSynthesizer.h"
+#include "lldb/Expression/ClangExpressionDeclMap.h"
+#include "lldb/Expression/ClangExpressionParser.h"
+#include "lldb/Expression/ClangModulesDeclVendor.h"
+#include "lldb/Expression/ClangPersistentVariables.h"
+#include "lldb/Expression/ExpressionSourceCode.h"
+#include "lldb/Expression/IRExecutionUnit.h"
+#include "lldb/Expression/IRInterpreter.h"
+#include "lldb/Expression/Materializer.h"
+#include "lldb/Expression/UserExpression.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/Block.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanCallUserExpression.h"
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+
+using namespace lldb_private;
+
+UserExpression::UserExpression (ExecutionContextScope &exe_scope,
+                                const char *expr,
+                                const char *expr_prefix,
+                                lldb::LanguageType language,
+                                ResultType desired_type) :
+    Expression (exe_scope),
+    m_stack_frame_bottom (LLDB_INVALID_ADDRESS),
+    m_stack_frame_top (LLDB_INVALID_ADDRESS),
+    m_expr_text (expr),
+    m_expr_prefix (expr_prefix ? expr_prefix : ""),
+    m_language (language),
+    m_transformed_text (),
+    m_desired_type (desired_type),
+    m_execution_unit_sp(),
+    m_materializer_ap(),
+    m_jit_module_wp(),
+    m_enforce_valid_object (true),
+    m_in_cplusplus_method (false),
+    m_in_objectivec_method (false),
+    m_in_static_method(false),
+    m_needs_object_ptr (false),
+    m_const_object (false),
+    m_target (NULL),
+    m_can_interpret (false),
+    m_materialized_address (LLDB_INVALID_ADDRESS)
+{
+}
+
+UserExpression::~UserExpression ()
+{
+    if (m_target)
+    {
+        lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
+        if (jit_module_sp)
+            m_target->GetImages().Remove(jit_module_sp);
+    }
+}
+
+void
+UserExpression::InstallContext (ExecutionContext &exe_ctx)
+{
+    m_jit_process_wp = exe_ctx.GetProcessSP();
+
+    lldb::StackFrameSP frame_sp = exe_ctx.GetFrameSP();
+
+    if (frame_sp)
+        m_address = frame_sp->GetFrameCodeAddress();
+}
+
+bool
+UserExpression::LockAndCheckContext (ExecutionContext &exe_ctx,
+                                          lldb::TargetSP &target_sp,
+                                          lldb::ProcessSP &process_sp,
+                                          lldb::StackFrameSP &frame_sp)
+{
+    lldb::ProcessSP expected_process_sp = m_jit_process_wp.lock();
+    process_sp = exe_ctx.GetProcessSP();
+
+    if (process_sp != expected_process_sp)
+        return false;
+
+    process_sp = exe_ctx.GetProcessSP();
+    target_sp = exe_ctx.GetTargetSP();
+    frame_sp = exe_ctx.GetFrameSP();
+
+    if (m_address.IsValid())
+    {
+        if (!frame_sp)
+            return false;
+        else
+            return (0 == Address::CompareLoadAddress(m_address, frame_sp->GetFrameCodeAddress(), target_sp.get()));
+    }
+
+    return true;
+}
+
+bool
+UserExpression::MatchesContext (ExecutionContext &exe_ctx)
+{
+    lldb::TargetSP target_sp;
+    lldb::ProcessSP process_sp;
+    lldb::StackFrameSP frame_sp;
+
+    return LockAndCheckContext(exe_ctx, target_sp, process_sp, frame_sp);
+}
+
+lldb::addr_t
+UserExpression::GetObjectPointer (lldb::StackFrameSP frame_sp,
+                  ConstString &object_name,
+                  Error &err)
+{
+    err.Clear();
+
+    if (!frame_sp)
+    {
+        err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
+        return LLDB_INVALID_ADDRESS;
+    }
+
+    lldb::VariableSP var_sp;
+    lldb::ValueObjectSP valobj_sp;
+
+    valobj_sp = frame_sp->GetValueForVariableExpressionPath(object_name.AsCString(),
+                                                            lldb::eNoDynamicValues,
+                                                            StackFrame::eExpressionPathOptionCheckPtrVsMember |
+                                                            StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
+                                                            StackFrame::eExpressionPathOptionsNoSyntheticChildren |
+                                                            StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
+                                                            var_sp,
+                                                            err);
+
+    if (!err.Success() || !valobj_sp.get())
+        return LLDB_INVALID_ADDRESS;
+
+    lldb::addr_t ret = valobj_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+
+    if (ret == LLDB_INVALID_ADDRESS)
+    {
+        err.SetErrorStringWithFormat("Couldn't load '%s' because its value couldn't be evaluated", object_name.AsCString());
+        return LLDB_INVALID_ADDRESS;
+    }
+
+    return ret;
+}
+
+bool
+UserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
+                                                    ExecutionContext &exe_ctx,
+                                                    lldb::addr_t &struct_address)
+{
+    lldb::TargetSP target;
+    lldb::ProcessSP process;
+    lldb::StackFrameSP frame;
+
+    if (!LockAndCheckContext(exe_ctx,
+                             target,
+                             process,
+                             frame))
+    {
+        error_stream.Printf("The context has changed before we could JIT the expression!\n");
+        return false;
+    }
+
+    if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
+    {
+        if (m_materialized_address == LLDB_INVALID_ADDRESS)
+        {
+            Error alloc_error;
+
+            IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
+
+            m_materialized_address = m_execution_unit_sp->Malloc(m_materializer_ap->GetStructByteSize(),
+                                                                 m_materializer_ap->GetStructAlignment(),
+                                                                 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+                                                                 policy,
+                                                                 alloc_error);
+
+            if (!alloc_error.Success())
+            {
+                error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
+                return false;
+            }
+        }
+
+        struct_address = m_materialized_address;
+
+        if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
+        {
+            Error alloc_error;
+
+            const size_t stack_frame_size = 512 * 1024;
+
+            m_stack_frame_bottom = m_execution_unit_sp->Malloc(stack_frame_size,
+                                                               8,
+                                                               lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+                                                               IRMemoryMap::eAllocationPolicyHostOnly,
+                                                               alloc_error);
+
+            m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
+
+            if (!alloc_error.Success())
+            {
+                error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
+                return false;
+            }
+        }
+
+        Error materialize_error;
+
+        m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_sp, struct_address, materialize_error);
+
+        if (!materialize_error.Success())
+        {
+            error_stream.Printf("Couldn't materialize: %s\n", materialize_error.AsCString());
+            return false;
+        }
+    }
+    return true;
+}
+
+bool
+UserExpression::FinalizeJITExecution (Stream &error_stream,
+                                           ExecutionContext &exe_ctx,
+                                           lldb::ExpressionVariableSP &result,
+                                           lldb::addr_t function_stack_bottom,
+                                           lldb::addr_t function_stack_top)
+{
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+    if (log)
+        log->Printf("-- [UserExpression::FinalizeJITExecution] Dematerializing after execution --");
+
+    if (!m_dematerializer_sp)
+    {
+        error_stream.Printf ("Couldn't apply expression side effects : no dematerializer is present");
+        return false;
+    }
+
+    Error dematerialize_error;
+
+    m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top);
+
+    if (!dematerialize_error.Success())
+    {
+        error_stream.Printf ("Couldn't apply expression side effects : %s\n", dematerialize_error.AsCString("unknown error"));
+        return false;
+    }
+
+    if (result)
+        result->TransferAddress();
+
+    m_dematerializer_sp.reset();
+
+    return true;
+}
+
+lldb::ExpressionResults
+UserExpression::Execute (Stream &error_stream,
+                              ExecutionContext &exe_ctx,
+                              const EvaluateExpressionOptions& options,
+                              lldb::UserExpressionSP &shared_ptr_to_me,
+                              lldb::ExpressionVariableSP &result)
+{
+    // The expression log is quite verbose, and if you're just tracking the execution of the
+    // expression, it's quite convenient to have these logs come out with the STEP log as well.
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
+
+    if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret)
+    {
+        lldb::addr_t struct_address = LLDB_INVALID_ADDRESS;
+
+        if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address))
+        {
+            error_stream.Printf("Errored out in %s, couldn't PrepareToExecuteJITExpression", __FUNCTION__);
+            return lldb::eExpressionSetupError;
+        }
+
+        lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
+        lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
+
+        if (m_can_interpret)
+        {
+            llvm::Module *module = m_execution_unit_sp->GetModule();
+            llvm::Function *function = m_execution_unit_sp->GetFunction();
+
+            if (!module || !function)
+            {
+                error_stream.Printf("Supposed to interpret, but nothing is there");
+                return lldb::eExpressionSetupError;
+            }
+
+            Error interpreter_error;
+
+            std::vector<lldb::addr_t> args;
+            
+            if (!AddInitialArguments(exe_ctx, args, error_stream))
+            {
+                error_stream.Printf ("Errored out in %s, couldn't AddInitialArguments", __FUNCTION__);
+                return lldb::eExpressionSetupError;
+            }
+            
+            args.push_back(struct_address);
+
+            function_stack_bottom = m_stack_frame_bottom;
+            function_stack_top = m_stack_frame_top;
+
+            IRInterpreter::Interpret (*module,
+                                      *function,
+                                      args,
+                                      *m_execution_unit_sp.get(),
+                                      interpreter_error,
+                                      function_stack_bottom,
+                                      function_stack_top,
+                                      exe_ctx);
+
+            if (!interpreter_error.Success())
+            {
+                error_stream.Printf("Supposed to interpret, but failed: %s", interpreter_error.AsCString());
+                return lldb::eExpressionDiscarded;
+            }
+        }
+        else
+        {
+            if (!exe_ctx.HasThreadScope())
+            {
+                error_stream.Printf("UserExpression::Execute called with no thread selected.");
+                return lldb::eExpressionSetupError;
+            }
+
+            Address wrapper_address (m_jit_start_addr);
+
+            std::vector<lldb::addr_t> args;
+            
+            if (!AddInitialArguments(exe_ctx, args, error_stream))
+            {
+                error_stream.Printf ("Errored out in %s, couldn't AddInitialArguments", __FUNCTION__);
+                return lldb::eExpressionSetupError;
+            }
+
+            args.push_back(struct_address);
+         
+            lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
+                                                                              wrapper_address,
+                                                                              args,
+                                                                              options,
+                                                                              shared_ptr_to_me));
+
+            if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
+                return lldb::eExpressionSetupError;
+
+            ThreadPlanCallUserExpression *user_expression_plan = static_cast<ThreadPlanCallUserExpression *>(call_plan_sp.get());
+
+            lldb::addr_t function_stack_pointer = user_expression_plan->GetFunctionStackPointer();
+
+            function_stack_bottom = function_stack_pointer - HostInfo::GetPageSize();
+            function_stack_top = function_stack_pointer;
+
+            if (log)
+                log->Printf("-- [UserExpression::Execute] Execution of expression begins --");
+
+            if (exe_ctx.GetProcessPtr())
+                exe_ctx.GetProcessPtr()->SetRunningUserExpression(true);
+
+            lldb::ExpressionResults execution_result = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx,
+                                                                                       call_plan_sp,
+                                                                                       options,
+                                                                                       error_stream);
+
+            if (exe_ctx.GetProcessPtr())
+                exe_ctx.GetProcessPtr()->SetRunningUserExpression(false);
+
+            if (log)
+                log->Printf("-- [UserExpression::Execute] Execution of expression completed --");
+
+            if (execution_result == lldb::eExpressionInterrupted || execution_result == lldb::eExpressionHitBreakpoint)
+            {
+                const char *error_desc = NULL;
+
+                if (call_plan_sp)
+                {
+                    lldb::StopInfoSP real_stop_info_sp = call_plan_sp->GetRealStopInfo();
+                    if (real_stop_info_sp)
+                        error_desc = real_stop_info_sp->GetDescription();
+                }
+                if (error_desc)
+                    error_stream.Printf ("Execution was interrupted, reason: %s.", error_desc);
+                else
+                    error_stream.PutCString ("Execution was interrupted.");
+
+                if ((execution_result == lldb::eExpressionInterrupted && options.DoesUnwindOnError())
+                    || (execution_result == lldb::eExpressionHitBreakpoint && options.DoesIgnoreBreakpoints()))
+                    error_stream.PutCString ("\nThe process has been returned to the state before expression evaluation.");
+                else
+                {
+                    if (execution_result == lldb::eExpressionHitBreakpoint)
+                        user_expression_plan->TransferExpressionOwnership();
+                    error_stream.PutCString ("\nThe process has been left at the point where it was interrupted, "
+                                             "use \"thread return -x\" to return to the state before expression evaluation.");
+                }
+
+                return execution_result;
+            }
+            else if (execution_result == lldb::eExpressionStoppedForDebug)
+            {
+                    error_stream.PutCString ("Execution was halted at the first instruction of the expression "
+                                             "function because \"debug\" was requested.\n"
+                                             "Use \"thread return -x\" to return to the state before expression evaluation.");
+                    return execution_result;
+            }
+            else if (execution_result != lldb::eExpressionCompleted)
+            {
+                error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
+                return execution_result;
+            }
+        }
+
+        if  (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
+        {
+            return lldb::eExpressionCompleted;
+        }
+        else
+        {
+            return lldb::eExpressionResultUnavailable;
+        }
+    }
+    else
+    {
+        error_stream.Printf("Expression can't be run, because there is no JIT compiled function");
+        return lldb::eExpressionSetupError;
+    }
+}
+
+lldb::ExpressionResults
+UserExpression::Evaluate (ExecutionContext &exe_ctx,
+                               const EvaluateExpressionOptions& options,
+                               const char *expr_cstr,
+                               const char *expr_prefix,
+                               lldb::ValueObjectSP &result_valobj_sp,
+                               Error &error)
+{
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
+
+    lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
+    const lldb::LanguageType language = options.GetLanguage();
+    const ResultType desired_type = options.DoesCoerceToId() ? UserExpression::eResultTypeId : UserExpression::eResultTypeAny;
+    lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
+    
+    Target *target = exe_ctx.GetTargetPtr();
+    if (!target)
+    {
+        if (log)
+            log->Printf("== [UserExpression::Evaluate] Passed a NULL target, can't run expressions.");
+        return lldb::eExpressionSetupError;
+    }
+
+    Process *process = exe_ctx.GetProcessPtr();
+
+    if (process == NULL || process->GetState() != lldb::eStateStopped)
+    {
+        if (execution_policy == eExecutionPolicyAlways)
+        {
+            if (log)
+                log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant ==");
+
+            error.SetErrorString ("expression needed to run but couldn't");
+
+            return execution_results;
+        }
+    }
+
+    if (process == NULL || !process->CanJIT())
+        execution_policy = eExecutionPolicyNever;
+
+    const char *full_prefix = NULL;
+    const char *option_prefix = options.GetPrefix();
+    std::string full_prefix_storage;
+    if (expr_prefix && option_prefix)
+    {
+        full_prefix_storage.assign(expr_prefix);
+        full_prefix_storage.append(option_prefix);
+        if (!full_prefix_storage.empty())
+            full_prefix = full_prefix_storage.c_str();
+    }
+    else if (expr_prefix)
+        full_prefix = expr_prefix;
+    else
+        full_prefix = option_prefix;
+
+    lldb::UserExpressionSP user_expression_sp(target->GetUserExpressionForLanguage (expr_cstr,
+                                                                                    full_prefix,
+                                                                                    language,
+                                                                                    desired_type,
+                                                                                    error));
+    if (error.Fail())
+    {
+        if (log)
+            log->Printf ("== [UserExpression::Evaluate] Getting expression: %s ==", error.AsCString());
+        return lldb::eExpressionSetupError;
+    }
+ 
+    StreamString error_stream;
+
+    if (log)
+        log->Printf("== [UserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
+
+    const bool keep_expression_in_memory = true;
+    const bool generate_debug_info = options.GetGenerateDebugInfo();
+
+    if (options.InvokeCancelCallback (lldb::eExpressionEvaluationParse))
+    {
+        error.SetErrorString ("expression interrupted by callback before parse");
+        result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
+        return lldb::eExpressionInterrupted;
+    }
+
+    if (!user_expression_sp->Parse (error_stream,
+                                    exe_ctx,
+                                    execution_policy,
+                                    keep_expression_in_memory,
+                                    generate_debug_info))
+    {
+        execution_results = lldb::eExpressionParseError;
+        if (error_stream.GetString().empty())
+            error.SetExpressionError (execution_results, "expression failed to parse, unknown error");
+        else
+            error.SetExpressionError (execution_results, error_stream.GetString().c_str());
+    }
+    else
+    {
+        lldb::ExpressionVariableSP expr_result;
+
+        if (execution_policy == eExecutionPolicyNever &&
+            !user_expression_sp->CanInterpret())
+        {
+            if (log)
+                log->Printf("== [UserExpression::Evaluate] Expression may not run, but is not constant ==");
+
+            if (error_stream.GetString().empty())
+                error.SetExpressionError (lldb::eExpressionSetupError, "expression needed to run but couldn't");
+        }
+        else
+        {
+            if (options.InvokeCancelCallback (lldb::eExpressionEvaluationExecution))
+            {
+                error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback before execution");
+                result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
+                return lldb::eExpressionInterrupted;
+            }
+
+            error_stream.GetString().clear();
+
+            if (log)
+                log->Printf("== [UserExpression::Evaluate] Executing expression ==");
+
+            execution_results = user_expression_sp->Execute (error_stream,
+                                                             exe_ctx,
+                                                             options,
+                                                             user_expression_sp,
+                                                             expr_result);
+
+            if (options.GetResultIsInternal() && expr_result && process)
+            {
+                process->GetTarget().GetPersistentVariables().RemovePersistentVariable (expr_result);
+            }
+
+            if (execution_results != lldb::eExpressionCompleted)
+            {
+                if (log)
+                    log->Printf("== [UserExpression::Evaluate] Execution completed abnormally ==");
+
+                if (error_stream.GetString().empty())
+                    error.SetExpressionError (execution_results, "expression failed to execute, unknown error");
+                else
+                    error.SetExpressionError (execution_results, error_stream.GetString().c_str());
+            }
+            else
+            {
+                if (expr_result)
+                {
+                    result_valobj_sp = expr_result->GetValueObject();
+
+                    if (log)
+                        log->Printf("== [UserExpression::Evaluate] Execution completed normally with result %s ==",
+                                    result_valobj_sp->GetValueAsCString());
+                }
+                else
+                {
+                    if (log)
+                        log->Printf("== [UserExpression::Evaluate] Execution completed normally with no result ==");
+
+                    error.SetError(UserExpression::kNoResult, lldb::eErrorTypeGeneric);
+                }
+            }
+        }
+    }
+
+    if (options.InvokeCancelCallback(lldb::eExpressionEvaluationComplete))
+    {
+        error.SetExpressionError (lldb::eExpressionInterrupted, "expression interrupted by callback after complete");
+        return lldb::eExpressionInterrupted;
+    }
+
+    if (result_valobj_sp.get() == NULL)
+    {
+        result_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), error);
+    }
+
+    return execution_results;
+}

Added: lldb/trunk/source/Expression/UtilityFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/UtilityFunction.cpp?rev=247720&view=auto
==============================================================================
--- lldb/trunk/source/Expression/UtilityFunction.cpp (added)
+++ lldb/trunk/source/Expression/UtilityFunction.cpp Tue Sep 15 16:13:50 2015
@@ -0,0 +1,123 @@
+//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+#  include <sys/types.h>
+#endif
+
+// C++ Includes
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
+#include "lldb/Expression/ExpressionSourceCode.h"
+#include "lldb/Expression/IRExecutionUnit.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+//------------------------------------------------------------------
+/// Constructor
+///
+/// @param[in] text
+///     The text of the function.  Must be a full translation unit.
+///
+/// @param[in] name
+///     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 (),
+    m_function_text (ExpressionSourceCode::g_expression_prefix),
+    m_function_name (name)
+{
+    if (text && text[0])
+        m_function_text.append (text);
+}
+
+UtilityFunction::~UtilityFunction ()
+{
+    lldb::ProcessSP process_sp (m_jit_process_wp.lock());
+    if (process_sp)
+    {
+        lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
+        if (jit_module_sp)
+            process_sp->GetTarget().GetImages().Remove(jit_module_sp);
+    }
+    
+}
+
+// FIXME: We should check that every time this is called it is called with the same return type & arguments...
+
+FunctionCaller *
+UtilityFunction::MakeFunctionCaller (const CompilerType &return_type, const ValueList &arg_value_list, Error &error)
+{
+    if (m_caller_up)
+        return m_caller_up.get();
+    
+    ProcessSP process_sp = m_jit_process_wp.lock();
+    if (!process_sp)
+        return nullptr;
+    
+    Address impl_code_address;
+    impl_code_address.SetOffset(StartAddress());
+    std::string name(m_function_name);
+    name.append("-caller");
+    
+    m_caller_up.reset (process_sp->GetTarget().GetFunctionCallerForLanguage (Language(),
+                                                                             return_type,
+                                                                             impl_code_address,
+                                                                             arg_value_list,
+                                                                             name.c_str(),
+                                                                             error));
+    if (error.Fail())
+    {
+        
+        return nullptr;
+    }
+    if (m_caller_up)
+    {
+        StreamString errors;
+        errors.Clear();
+        unsigned num_errors = m_caller_up->CompileFunction(errors);
+        if (num_errors)
+        {
+            error.SetErrorStringWithFormat ("Error compiling %s caller function: \"%s\".",
+                                                m_function_name.c_str(),
+                                                errors.GetData());
+            m_caller_up.reset();
+            return nullptr;
+        }
+        
+        errors.Clear();
+        ExecutionContext exe_ctx(process_sp);
+        
+        if (!m_caller_up->WriteFunctionWrapper(exe_ctx, errors))
+        {
+            error.SetErrorStringWithFormat ("Error inserting caller function for %s: \"%s\".",
+                                                m_function_name.c_str(),
+                                                errors.GetData());
+            m_caller_up.reset();
+            return nullptr;
+        }
+    }
+    return m_caller_up.get();
+}

Modified: lldb/trunk/source/Plugins/Language/ObjC/CoreMedia.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/CoreMedia.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/ObjC/CoreMedia.cpp (original)
+++ lldb/trunk/source/Plugins/Language/ObjC/CoreMedia.cpp Tue Sep 15 16:13:50 2015
@@ -25,7 +25,7 @@ lldb_private::formatters::CMTimeSummaryP
     if (!type.IsValid())
         return false;
 
-    TypeSystem *type_system = valobj.GetExecutionContextRef().GetTargetSP()->GetTypeSystemForLanguage(lldb::eLanguageTypeC);
+    TypeSystem *type_system = valobj.GetExecutionContextRef().GetTargetSP()->GetScratchTypeSystemForLanguage(lldb::eLanguageTypeC);
     if (!type_system)
         return false;
     

Modified: lldb/trunk/source/Plugins/Language/ObjC/NSArray.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/NSArray.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/ObjC/NSArray.cpp (original)
+++ lldb/trunk/source/Plugins/Language/ObjC/NSArray.cpp Tue Sep 15 16:13:50 2015
@@ -15,6 +15,7 @@
 #include "lldb/Core/ValueObject.h"
 #include "lldb/Core/ValueObjectConstResult.h"
 #include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/Expression/FunctionCaller.h"
 #include "lldb/Host/Endian.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp Tue Sep 15 16:13:50 2015
@@ -8,7 +8,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "AppleObjCClassDescriptorV2.h"
+
 #include "lldb/Core/Log.h"
+#include "lldb/Expression/FunctionCaller.h"
 
 using namespace lldb;
 using namespace lldb_private;

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp Tue Sep 15 16:13:50 2015
@@ -1,4 +1,4 @@
-//===-- AppleObjCRuntime.cpp --------------------------------------*- C++ -*-===//
+//===-- AppleObjCRuntime.cpp -------------------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -22,7 +22,8 @@
 #include "lldb/Core/Scalar.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/StreamString.h"
-#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/FunctionCaller.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/ExecutionContext.h"
@@ -39,6 +40,10 @@ using namespace lldb_private;
 
 #define PO_FUNCTION_TIMEOUT_USEC 15*1000*1000
 
+AppleObjCRuntime::~AppleObjCRuntime()
+{
+}
+
 AppleObjCRuntime::AppleObjCRuntime(Process *process) :
     ObjCLanguageRuntime (process),
     m_read_objc_library (false),
@@ -135,16 +140,36 @@ AppleObjCRuntime::GetObjectDescription (
     }
     
     // Now we're ready to call the function:
-    ClangFunction func (*exe_ctx.GetBestExecutionContextScope(),
-                        return_clang_type, 
-                        *function_address, 
-                        arg_value_list,
-                        "objc-object-description");
-
-    StreamString error_stream;
     
+    StreamString error_stream;
     lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS;
-    func.InsertFunction(exe_ctx, wrapper_struct_addr, error_stream);
+
+    if (!m_print_object_caller_up)
+    {
+        Error error;
+         m_print_object_caller_up.reset(exe_scope->CalculateTarget()->GetFunctionCallerForLanguage (eLanguageTypeObjC,
+                                                                                                    return_clang_type,
+                                                                                                    *function_address,
+                                                                                                    arg_value_list,
+                                                                                                    "objc-object-description",
+                                                                                                    error));
+        if (error.Fail())
+        {
+            m_print_object_caller_up.reset();
+            strm.Printf("Could not get function runner to call print for debugger function: %s.", error.AsCString());
+            return false;
+        }
+        m_print_object_caller_up->InsertFunction(exe_ctx, wrapper_struct_addr, error_stream);
+    }
+    else
+    {
+        m_print_object_caller_up->WriteFunctionArguments(exe_ctx,
+                                                         wrapper_struct_addr,
+                                                         arg_value_list,
+                                                         error_stream);
+    }
+
+    
 
     EvaluateExpressionOptions options;
     options.SetUnwindOnError(true);
@@ -153,11 +178,11 @@ AppleObjCRuntime::GetObjectDescription (
     options.SetIgnoreBreakpoints(true);
     options.SetTimeoutUsec(PO_FUNCTION_TIMEOUT_USEC);
     
-    ExpressionResults results = func.ExecuteFunction (exe_ctx, 
-                                                     &wrapper_struct_addr,
-                                                     options,
-                                                     error_stream, 
-                                                     ret);
+    ExpressionResults results = m_print_object_caller_up->ExecuteFunction (exe_ctx,
+                                                                           &wrapper_struct_addr,
+                                                                           options,
+                                                                           error_stream,
+                                                                           ret);
     if (results != eExpressionCompleted)
     {
         strm.Printf("Error evaluating Print Object function: %d.\n", results);

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h Tue Sep 15 16:13:50 2015
@@ -20,7 +20,6 @@
 #include "lldb/lldb-private.h"
 #include "lldb/Target/LanguageRuntime.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
-#include "lldb/Core/ValueObject.h"
 #include "AppleObjCTrampolineHandler.h"
 #include "AppleThreadPlanStepThroughObjCTrampoline.h"
 
@@ -31,7 +30,7 @@ class AppleObjCRuntime :
 {
 public:
     
-    virtual ~AppleObjCRuntime() { }
+    virtual ~AppleObjCRuntime();
     
     // These are generic runtime functions:
     bool
@@ -127,6 +126,7 @@ protected:
     std::unique_ptr<lldb_private::AppleObjCTrampolineHandler> m_objc_trampoline_handler_ap;
     lldb::BreakpointSP m_objc_exception_bp_sp;
     lldb::ModuleWP m_objc_module_wp;
+    std::unique_ptr<FunctionCaller>  m_print_object_caller_up;
     
     llvm::Optional<uint32_t> m_Foundation_major;
 

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp Tue Sep 15 16:13:50 2015
@@ -21,8 +21,8 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Scalar.h"
 #include "lldb/Core/StreamString.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/Symbol.h"
 #include "lldb/Target/ExecutionContext.h"
@@ -143,7 +143,7 @@ struct BufStruct {
     char contents[2048];
 };
 
-ClangUtilityFunction *
+UtilityFunction *
 AppleObjCRuntimeV1::CreateObjectChecker(const char *name)
 {
     std::unique_ptr<BufStruct> buf(new BufStruct);
@@ -170,7 +170,8 @@ AppleObjCRuntimeV1::CreateObjectChecker(
                     "}                                                                      \n",
                     name) < (int)sizeof(buf->contents));
 
-    return new ClangUtilityFunction(buf->contents, name);
+    Error error;
+    return GetTargetRef().GetUtilityFunctionForLanguage(buf->contents, eLanguageTypeObjC, name, error);
 }
 
 AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1 (ValueObject &isa_pointer)

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h Tue Sep 15 16:13:50 2015
@@ -102,7 +102,7 @@ public:
                               TypeAndOrName &class_type_or_name, 
                               Address &address);
 
-    virtual ClangUtilityFunction *
+    virtual UtilityFunction *
     CreateObjectChecker (const char *);
 
     //------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Tue Sep 15 16:13:50 2015
@@ -28,8 +28,8 @@
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/Timer.h"
 #include "lldb/Core/ValueObjectVariable.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
 #include "lldb/Host/StringConvert.h"
 #include "lldb/Interpreter/CommandObject.h"
 #include "lldb/Interpreter/CommandObjectMultiword.h"
@@ -348,11 +348,9 @@ ExtractRuntimeGlobalSymbol (Process* pro
 AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process,
                                         const ModuleSP &objc_module_sp) :
     AppleObjCRuntime (process),
-    m_get_class_info_function(),
     m_get_class_info_code(),
     m_get_class_info_args (LLDB_INVALID_ADDRESS),
     m_get_class_info_args_mutex (Mutex::eMutexTypeNormal),
-    m_get_shared_cache_class_info_function(),
     m_get_shared_cache_class_info_code(),
     m_get_shared_cache_class_info_args (LLDB_INVALID_ADDRESS),
     m_get_shared_cache_class_info_args_mutex (Mutex::eMutexTypeNormal),
@@ -722,7 +720,7 @@ AppleObjCRuntimeV2::CreateExceptionResol
     return resolver_sp;
 }
 
-ClangUtilityFunction *
+UtilityFunction *
 AppleObjCRuntimeV2::CreateObjectChecker(const char *name)
 {
     char check_function_code[2048];
@@ -780,7 +778,8 @@ AppleObjCRuntimeV2::CreateObjectChecker(
     
     assert (len < (int)sizeof(check_function_code));
 
-    return new ClangUtilityFunction(check_function_code, name);
+    Error error;
+    return GetTargetRef().GetUtilityFunctionForLanguage(check_function_code, eLanguageTypeObjC, name, error);
 }
 
 size_t
@@ -1248,75 +1247,74 @@ AppleObjCRuntimeV2::UpdateISAToDescripto
     CompilerType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
     CompilerType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
     
+    ValueList arguments;
+    FunctionCaller *get_class_info_function = nullptr;
+
     if (!m_get_class_info_code.get())
     {
-        m_get_class_info_code.reset (new ClangUtilityFunction (g_get_dynamic_class_info_body,
-                                                               g_get_dynamic_class_info_name));
-        
-        errors.Clear();
-        
-        if (!m_get_class_info_code->Install(errors, exe_ctx))
+        Error error;
+        m_get_class_info_code.reset (GetTargetRef().GetUtilityFunctionForLanguage (g_get_dynamic_class_info_body,
+                                                                                   eLanguageTypeObjC,
+                                                                                   g_get_dynamic_class_info_name,
+                                                                                   error));
+        if (error.Fail())
         {
             if (log)
-                log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+                log->Printf ("Failed to get Utility Function for implementation lookup: %s", error.AsCString());
             m_get_class_info_code.reset();
         }
-    }
-    
-    if (m_get_class_info_code.get())
-        function_address.SetOffset(m_get_class_info_code->StartAddress());
-    else
-        return false;
-    
-    ValueList arguments;
-    
-    // Next make the runner function for our implementation utility function.
-    if (!m_get_class_info_function.get())
-    {
+        else
+        {
+            errors.Clear();
+            
+            if (!m_get_class_info_code->Install(errors, exe_ctx))
+            {
+                if (log)
+                    log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+                m_get_class_info_code.reset();
+            }
+        }
+        if (!m_get_class_info_code.get())
+            return false;
+        
+        // Next make the runner function for our implementation utility function.
         Value value;
         value.SetValueType (Value::eValueTypeScalar);
-//        value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
         value.SetCompilerType (clang_void_pointer_type);
         arguments.PushValue (value);
         arguments.PushValue (value);
         
         value.SetValueType (Value::eValueTypeScalar);
-//        value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
         value.SetCompilerType (clang_uint32_t_type);
         arguments.PushValue (value);
         
-        m_get_class_info_function.reset(new ClangFunction (*m_process,
-                                                           clang_uint32_t_type,
-                                                           function_address,
-                                                           arguments,
-                                                           "objc-v2-isa-to-descriptor"));
-        
-        if (m_get_class_info_function.get() == NULL)
-            return false;
-        
-        errors.Clear();
+        get_class_info_function = m_get_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
+                                                                            arguments,
+                                                                            error);
         
-        unsigned num_errors = m_get_class_info_function->CompileFunction(errors);
-        if (num_errors)
+        if (error.Fail())
         {
             if (log)
-                log->Printf ("Error compiling function: \"%s\".", errors.GetData());
+                log->Printf("Failed to make function caller for implementation lookup: %s.", error.AsCString());
             return false;
         }
-        
-        errors.Clear();
-        
-        if (!m_get_class_info_function->WriteFunctionWrapper(exe_ctx, errors))
+    }
+    else
+    {
+        get_class_info_function = m_get_class_info_code->GetFunctionCaller();
+        if (!get_class_info_function)
         {
             if (log)
-                log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
+                log->Printf ("Failed to get implementation lookup function caller: %s.", errors.GetData());
             return false;
         }
+        arguments = get_class_info_function->GetArgumentValues();
     }
-    else
-    {
-        arguments = m_get_class_info_function->GetArgumentValues ();
-    }
+    
+    
+    
+    
+    errors.Clear();
     
     const uint32_t class_info_byte_size = addr_size + 4;
     const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
@@ -1339,9 +1337,8 @@ AppleObjCRuntimeV2::UpdateISAToDescripto
     errors.Clear();
     
     // Write our function arguments into the process so we can run our function
-    if (m_get_class_info_function->WriteFunctionArguments (exe_ctx,
+    if (get_class_info_function->WriteFunctionArguments (exe_ctx,
                                                            m_get_class_info_args,
-                                                           function_address,
                                                            arguments,
                                                            errors))
     {
@@ -1361,11 +1358,11 @@ AppleObjCRuntimeV2::UpdateISAToDescripto
         errors.Clear();
         
         // Run the function
-        ExpressionResults results = m_get_class_info_function->ExecuteFunction (exe_ctx,
-                                                                               &m_get_class_info_args,
-                                                                               options,
-                                                                               errors,
-                                                                               return_value);
+        ExpressionResults results = get_class_info_function->ExecuteFunction (exe_ctx,
+                                                                              &m_get_class_info_args,
+                                                                              options,
+                                                                              errors,
+                                                                              return_value);
         
         if (results == eExpressionCompleted)
         {
@@ -1502,31 +1499,38 @@ AppleObjCRuntimeV2::UpdateISAToDescripto
     CompilerType clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
     CompilerType clang_void_pointer_type = ast->GetBasicType(eBasicTypeVoid).GetPointerType();
     
+    ValueList arguments;
+    FunctionCaller *get_shared_cache_class_info_function = nullptr;
+    
     if (!m_get_shared_cache_class_info_code.get())
     {
-        m_get_shared_cache_class_info_code.reset (new ClangUtilityFunction (g_get_shared_cache_class_info_body,
-                                                                            g_get_shared_cache_class_info_name));
-        
-        errors.Clear();
-        
-        if (!m_get_shared_cache_class_info_code->Install(errors, exe_ctx))
+        Error error;
+        m_get_shared_cache_class_info_code.reset (GetTargetRef().GetUtilityFunctionForLanguage (g_get_shared_cache_class_info_body,
+                                                                                                eLanguageTypeObjC,
+                                                                                                g_get_shared_cache_class_info_name,
+                                                                                                error));
+        if (error.Fail())
         {
             if (log)
-                log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+                log->Printf ("Failed to get Utility function for implementation lookup: %s.", error.AsCString());
             m_get_shared_cache_class_info_code.reset();
         }
-    }
-    
-    if (m_get_shared_cache_class_info_code.get())
-        function_address.SetOffset(m_get_shared_cache_class_info_code->StartAddress());
-    else
-        return DescriptorMapUpdateResult::Fail();
-    
-    ValueList arguments;
+        else
+        {
+            errors.Clear();
+            
+            if (!m_get_shared_cache_class_info_code->Install(errors, exe_ctx))
+            {
+                if (log)
+                    log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+                m_get_shared_cache_class_info_code.reset();
+            }
+        }
+        
+        if (!m_get_shared_cache_class_info_code.get())
+            return DescriptorMapUpdateResult::Fail();
     
-    // Next make the runner function for our implementation utility function.
-    if (!m_get_shared_cache_class_info_function.get())
-    {
+        // Next make the function caller for our implementation utility function.
         Value value;
         value.SetValueType (Value::eValueTypeScalar);
         //value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
@@ -1539,39 +1543,24 @@ AppleObjCRuntimeV2::UpdateISAToDescripto
         value.SetCompilerType (clang_uint32_t_type);
         arguments.PushValue (value);
         
-        m_get_shared_cache_class_info_function.reset(new ClangFunction (*m_process,
-                                                                        clang_uint32_t_type,
-                                                                        function_address,
-                                                                        arguments,
-                                                                        "objc-isa-to-descriptor-shared-cache"));
-        
-        if (m_get_shared_cache_class_info_function.get() == NULL)
-            return DescriptorMapUpdateResult::Fail();
-        
-        errors.Clear();
-        
-        unsigned num_errors = m_get_shared_cache_class_info_function->CompileFunction(errors);
-        if (num_errors)
-        {
-            if (log)
-                log->Printf ("Error compiling function: \"%s\".", errors.GetData());
-            return DescriptorMapUpdateResult::Fail();
-        }
-        
-        errors.Clear();
+        get_shared_cache_class_info_function = m_get_shared_cache_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
+                                                                                                      arguments,
+                                                                                                      error);
         
-        if (!m_get_shared_cache_class_info_function->WriteFunctionWrapper(exe_ctx, errors))
-        {
-            if (log)
-                log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
+        if (get_shared_cache_class_info_function == nullptr)
             return DescriptorMapUpdateResult::Fail();
-        }
+    
     }
     else
     {
-        arguments = m_get_shared_cache_class_info_function->GetArgumentValues ();
+        get_shared_cache_class_info_function = m_get_shared_cache_class_info_code->GetFunctionCaller();
+        if (get_shared_cache_class_info_function == nullptr)
+            return DescriptorMapUpdateResult::Fail();
+        arguments = get_shared_cache_class_info_function->GetArgumentValues();
     }
     
+    errors.Clear();
+    
     const uint32_t class_info_byte_size = addr_size + 4;
     const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
     lldb::addr_t class_infos_addr = process->AllocateMemory (class_infos_byte_size,
@@ -1594,11 +1583,10 @@ AppleObjCRuntimeV2::UpdateISAToDescripto
     errors.Clear();
     
     // Write our function arguments into the process so we can run our function
-    if (m_get_shared_cache_class_info_function->WriteFunctionArguments (exe_ctx,
-                                                                        m_get_shared_cache_class_info_args,
-                                                                        function_address,
-                                                                        arguments,
-                                                                        errors))
+    if (get_shared_cache_class_info_function->WriteFunctionArguments (exe_ctx,
+                                                                      m_get_shared_cache_class_info_args,
+                                                                      arguments,
+                                                                      errors))
     {
         EvaluateExpressionOptions options;
         options.SetUnwindOnError(true);
@@ -1616,11 +1604,11 @@ AppleObjCRuntimeV2::UpdateISAToDescripto
         errors.Clear();
         
         // Run the function
-        ExpressionResults results = m_get_shared_cache_class_info_function->ExecuteFunction (exe_ctx,
-                                                                                            &m_get_shared_cache_class_info_args,
-                                                                                            options,
-                                                                                            errors,
-                                                                                            return_value);
+        ExpressionResults results = get_shared_cache_class_info_function->ExecuteFunction (exe_ctx,
+                                                                                           &m_get_shared_cache_class_info_args,
+                                                                                           options,
+                                                                                           errors,
+                                                                                           return_value);
         
         if (results == eExpressionCompleted)
         {

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h Tue Sep 15 16:13:50 2015
@@ -39,7 +39,7 @@ public:
                               TypeAndOrName &class_type_or_name, 
                               Address &address);
     
-    virtual ClangUtilityFunction *
+    virtual UtilityFunction *
     CreateObjectChecker (const char *);
 
 
@@ -299,22 +299,20 @@ private:
     
     friend class ClassDescriptorV2;
 
-    std::unique_ptr<ClangFunction>            m_get_class_info_function;
-    std::unique_ptr<ClangUtilityFunction>     m_get_class_info_code;
+    std::unique_ptr<UtilityFunction>        m_get_class_info_code;
     lldb::addr_t                            m_get_class_info_args;
     Mutex                                   m_get_class_info_args_mutex;
 
-    std::unique_ptr<ClangFunction>            m_get_shared_cache_class_info_function;
-    std::unique_ptr<ClangUtilityFunction>     m_get_shared_cache_class_info_code;
+    std::unique_ptr<UtilityFunction>        m_get_shared_cache_class_info_code;
     lldb::addr_t                            m_get_shared_cache_class_info_args;
     Mutex                                   m_get_shared_cache_class_info_args_mutex;
 
-    std::unique_ptr<DeclVendor>               m_decl_vendor_ap;
+    std::unique_ptr<DeclVendor>             m_decl_vendor_ap;
     lldb::addr_t                            m_isa_hash_table_ptr;
     HashTableSignature                      m_hash_signature;
     bool                                    m_has_object_getClass;
     bool                                    m_loaded_objc_opt;
-    std::unique_ptr<NonPointerISACache>       m_non_pointer_isa_cache_ap;
+    std::unique_ptr<NonPointerISACache>     m_non_pointer_isa_cache_ap;
     std::unique_ptr<TaggedPointerVendor>    m_tagged_pointer_vendor_ap;
     EncodingToTypeSP                        m_encoding_to_type_sp;
     bool                                    m_noclasses_warning_emitted;

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp Tue Sep 15 16:13:50 2015
@@ -22,9 +22,9 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/StreamFile.h"
 #include "lldb/Core/Value.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/UserExpression.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/Symbol.h"
@@ -741,10 +741,10 @@ lldb::addr_t
 AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &dispatch_values)
 {
     ExecutionContext exe_ctx (thread.shared_from_this());
-    Address impl_code_address;
     StreamString errors;
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
     lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+    FunctionCaller *impl_function_caller = nullptr;
 
     // Scope for mutex locker:
     {
@@ -752,38 +752,23 @@ AppleObjCTrampolineHandler::SetupDispatc
         
         // First stage is to make the ClangUtility to hold our injected function:
 
-    #define USE_BUILTIN_FUNCTION 0  // Define this to 1 and we will use the get_implementation function found in the target.
-                        // This is useful for debugging additions to the get_impl function 'cause you don't have
-                        // to bother with string-ifying the code into g_lookup_implementation_function_code.
-        
-        if (USE_BUILTIN_FUNCTION)
-        {
-            ConstString our_utility_function_name("__lldb_objc_find_implementation_for_selector");
-            SymbolContextList sc_list;
-            
-            exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
-            if (sc_list.GetSize() == 1)
-            {
-                SymbolContext sc;
-                sc_list.GetContextAtIndex(0, sc);
-                if (sc.symbol != NULL)
-                    impl_code_address = sc.symbol->GetAddress();
-                    
-                //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
-                //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
-            }
-            else
-            {
-                //printf ("Could not find implementation function address.\n");
-                return args_addr;
-            }
-        }
-        else if (!m_impl_code.get())
+        if (!m_impl_code.get())
         {
             if (g_lookup_implementation_function_code != NULL)
             {
-                m_impl_code.reset (new ClangUtilityFunction (g_lookup_implementation_function_code,
-                                                             g_lookup_implementation_function_name));
+                Error error;
+                m_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (g_lookup_implementation_function_code,
+                                                                                         eLanguageTypeObjC,
+                                                                                         g_lookup_implementation_function_name,
+                                                                                         error));
+                if (error.Fail())
+                {
+                    if (log)
+                        log->Printf ("Failed to get Utility Function for implementation lookup: %s.", error.AsCString());
+                    m_impl_code.reset();
+                    return args_addr;
+                }
+                
                 if (!m_impl_code->Install(errors, exe_ctx))
                 {
                     if (log)
@@ -800,43 +785,26 @@ AppleObjCTrampolineHandler::SetupDispatc
                 return LLDB_INVALID_ADDRESS;
             }
             
-            impl_code_address.Clear();
-            impl_code_address.SetOffset(m_impl_code->StartAddress());
-        }
-        else
-        {
-            impl_code_address.Clear();
-            impl_code_address.SetOffset(m_impl_code->StartAddress());
-        }
 
-        // Next make the runner function for our implementation utility function.
-        if (!m_impl_function.get())
-        {
+            // Next make the runner function for our implementation utility function.
             ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
             CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
-            m_impl_function.reset(new ClangFunction (thread,
-                                                     clang_void_ptr_type,
-                                                     impl_code_address,
-                                                     dispatch_values,
-                                                     "objc-dispatch-lookup"));
+            Error error;
             
-            errors.Clear();        
-            unsigned num_errors = m_impl_function->CompileFunction(errors);
-            if (num_errors)
+            impl_function_caller = m_impl_code->MakeFunctionCaller(clang_void_ptr_type,
+                                                                   dispatch_values,
+                                                                   error);
+            if (error.Fail())
             {
                 if (log)
-                    log->Printf ("Error compiling function: \"%s\".", errors.GetData());
-                return args_addr;
-            }
-            
-            errors.Clear();
-            if (!m_impl_function->WriteFunctionWrapper(exe_ctx, errors))
-            {
-                if (log)
-                    log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
+                    log->Printf ("Error getting function caller for dispatch lookup: \"%s\".", error.AsCString());
                 return args_addr;
             }
         }
+        else
+        {
+            impl_function_caller = m_impl_code->GetFunctionCaller();
+        }
     }
     
     errors.Clear();
@@ -845,7 +813,7 @@ AppleObjCTrampolineHandler::SetupDispatc
     // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
     // this call by passing args_addr = LLDB_INVALID_ADDRESS...
 
-    if (!m_impl_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, dispatch_values, errors))
+    if (impl_function_caller->WriteFunctionArguments (exe_ctx, args_addr, dispatch_values, errors))
     {
         if (log)
             log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
@@ -1169,8 +1137,8 @@ AppleObjCTrampolineHandler::GetStepThrou
     return ret_plan_sp;
 }
 
-ClangFunction *
-AppleObjCTrampolineHandler::GetLookupImplementationWrapperFunction ()
+FunctionCaller *
+AppleObjCTrampolineHandler::GetLookupImplementationFunctionCaller ()
 {
-    return m_impl_function.get();
+    return m_impl_code->GetFunctionCaller();
 }

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h Tue Sep 15 16:13:50 2015
@@ -35,8 +35,8 @@ public:
     GetStepThroughDispatchPlan (Thread &thread, 
                                 bool stop_others);
     
-    ClangFunction *
-    GetLookupImplementationWrapperFunction ();
+    FunctionCaller *
+    GetLookupImplementationFunctionCaller ();
     
     bool 
     AddrIsMsgForward (lldb::addr_t addr) const
@@ -198,8 +198,7 @@ private:
     MsgsendMap m_msgSend_map;
     lldb::ProcessWP m_process_wp;
     lldb::ModuleSP m_objc_module_sp;
-    std::unique_ptr<ClangFunction> m_impl_function;
-    std::unique_ptr<ClangUtilityFunction> m_impl_code;
+    std::unique_ptr<UtilityFunction> m_impl_code;
     Mutex m_impl_function_mutex;
     lldb::addr_t m_impl_fn_addr;
     lldb::addr_t m_impl_stret_fn_addr;

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp Tue Sep 15 16:13:50 2015
@@ -15,8 +15,8 @@
 #include "AppleObjCTrampolineHandler.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Thread.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/ThreadPlanRunToAddress.h"
@@ -67,11 +67,11 @@ AppleThreadPlanStepThroughObjCTrampoline
 {
     // Setting up the memory space for the called function text might require allocations,
     // i.e. a nested function call.  This needs to be done as a PreResumeAction.
-    m_thread.GetProcess()->AddPreResumeAction (PreResumeInitializeClangFunction, (void *) this);
+    m_thread.GetProcess()->AddPreResumeAction (PreResumeInitializeFunctionCaller, (void *) this);
 }
 
 bool
-AppleThreadPlanStepThroughObjCTrampoline::InitializeClangFunction ()
+AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller ()
 {
     if (!m_func_sp)
     {
@@ -82,7 +82,7 @@ AppleThreadPlanStepThroughObjCTrampoline
         {
             return false;
         }
-        m_impl_function = m_trampoline_handler->GetLookupImplementationWrapperFunction();
+        m_impl_function = m_trampoline_handler->GetLookupImplementationFunctionCaller();
         ExecutionContext exc_ctx;
         EvaluateExpressionOptions options;
         options.SetUnwindOnError(true);
@@ -100,10 +100,10 @@ AppleThreadPlanStepThroughObjCTrampoline
 }
 
 bool
-AppleThreadPlanStepThroughObjCTrampoline::PreResumeInitializeClangFunction(void *void_myself)
+AppleThreadPlanStepThroughObjCTrampoline::PreResumeInitializeFunctionCaller(void *void_myself)
 {
     AppleThreadPlanStepThroughObjCTrampoline *myself = static_cast<AppleThreadPlanStepThroughObjCTrampoline *>(void_myself);
-    return myself->InitializeClangFunction();
+    return myself->InitializeFunctionCaller();
 }
 
 void

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h Tue Sep 15 16:13:50 2015
@@ -66,7 +66,7 @@ public:
     DidPush();
     
     static bool
-    PreResumeInitializeClangFunction(void *myself);
+    PreResumeInitializeFunctionCaller(void *myself);
 
     virtual bool
     WillStop();
@@ -82,7 +82,7 @@ protected:
 	
 private:
     bool
-    InitializeClangFunction ();
+    InitializeFunctionCaller ();
 
 	//------------------------------------------------------------------
 	// For AppleThreadPlanStepThroughObjCTrampoline only
@@ -96,7 +96,7 @@ private:
     lldb::ThreadPlanSP m_func_sp;       // This is the function call plan.  We fill it at start, then set it
                                         // to NULL when this plan is done.  That way we know to go to:
     lldb::ThreadPlanSP m_run_to_sp;     // The plan that runs to the target.
-    ClangFunction *m_impl_function;  // This is a pointer to a impl function that 
+    FunctionCaller *m_impl_function;  // This is a pointer to a impl function that
                                      // is owned by the client that pushes this plan.
     bool m_stop_others;
 };

Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp Tue Sep 15 16:13:50 2015
@@ -22,9 +22,8 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/Value.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/Symbol.h"
 #include "lldb/Target/ExecutionContext.h"
@@ -101,7 +100,6 @@ extern \"C\"
 
 AppleGetItemInfoHandler::AppleGetItemInfoHandler (Process *process) :
     m_process (process),
-    m_get_item_info_function (),
     m_get_item_info_impl_code (),
     m_get_item_info_function_mutex(),
     m_get_item_info_return_buffer_addr (LLDB_INVALID_ADDRESS),
@@ -140,49 +138,33 @@ lldb::addr_t
 AppleGetItemInfoHandler::SetupGetItemInfoFunction (Thread &thread, ValueList &get_item_info_arglist)
 {
     ExecutionContext exe_ctx (thread.shared_from_this());
-    Address impl_code_address;
     StreamString errors;
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
     lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+    FunctionCaller *get_item_info_caller = nullptr;
 
     // Scope for mutex locker:
     {
         Mutex::Locker locker(m_get_item_info_function_mutex);
         
-        // First stage is to make the ClangUtility to hold our injected function:
+        // First stage is to make the UtilityFunction to hold our injected function:
 
-#define USE_BUILTIN_FUNCTION 0  // Define this to 1 and we will use the get_implementation function found in the target.
-                                // This is useful for debugging additions to the get_impl function 'cause you don't have
-                                // to bother with string-ifying the code into g_get_item_info_function_code.
-        
-        if (USE_BUILTIN_FUNCTION)
-        {
-            ConstString our_utility_function_name("__lldb_backtrace_recording_get_item_info");
-            SymbolContextList sc_list;
-            
-            exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
-            if (sc_list.GetSize() == 1)
-            {
-                SymbolContext sc;
-                sc_list.GetContextAtIndex(0, sc);
-                if (sc.symbol != NULL)
-                    impl_code_address = sc.symbol->GetAddress();
-                    
-                //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
-                //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
-            }
-            else
-            {
-                //printf ("Could not find queues introspection function address.\n");
-                return args_addr;
-            }
-        }
-        else if (!m_get_item_info_impl_code.get())
+        if (!m_get_item_info_impl_code.get())
         {
             if (g_get_item_info_function_code != NULL)
             {
-                m_get_item_info_impl_code.reset (new ClangUtilityFunction (g_get_item_info_function_code,
-                                                             g_get_item_info_function_name));
+                Error error;
+                m_get_item_info_impl_code.reset(exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (g_get_item_info_function_code,
+                                                                                                      eLanguageTypeObjC,
+                                                                                                      g_get_item_info_function_name,
+                                                                                                      error));
+                if (error.Fail())
+                {
+                    if (log)
+                        log->Printf ("Failed to get utility function: %s.", error.AsCString());
+                    return args_addr;
+                }
+                
                 if (!m_get_item_info_impl_code->Install(errors, exe_ctx))
                 {
                     if (log)
@@ -198,41 +180,32 @@ AppleGetItemInfoHandler::SetupGetItemInf
                 errors.Printf ("No get-item-info introspection code found.");
                 return LLDB_INVALID_ADDRESS;
             }
-            
-            impl_code_address.Clear();
-            impl_code_address.SetOffset(m_get_item_info_impl_code->StartAddress());
-        }
-        else
-        {
-            impl_code_address.Clear();
-            impl_code_address.SetOffset(m_get_item_info_impl_code->StartAddress());
-        }
 
-        // Next make the runner function for our implementation utility function.
-        if (!m_get_item_info_function.get())
-        {
-            ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
-            CompilerType get_item_info_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
-            m_get_item_info_function.reset(new ClangFunction (thread,
-                                                     get_item_info_return_type,
-                                                     impl_code_address,
-                                                     get_item_info_arglist,
-                                                     "queue-bt-item-info"));
+            // Next make the runner function for our implementation utility function.
+            Error error;
+            
+            TypeSystem *type_system = thread.GetProcess()->GetTarget().GetScratchTypeSystemForLanguage(eLanguageTypeC);
+            CompilerType get_item_info_return_type = type_system->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
             
-            errors.Clear();        
-            unsigned num_errors = m_get_item_info_function->CompileFunction(errors);
-            if (num_errors)
+            get_item_info_caller = m_get_item_info_impl_code->MakeFunctionCaller(get_item_info_return_type,
+                                                                                 get_item_info_arglist,
+                                                                                 error);
+            if (error.Fail())
             {
                 if (log)
-                    log->Printf ("Error compiling get-item-info function: \"%s\".", errors.GetData());
+                    log->Printf ("Error Inserting get-item-info function: \"%s\".", error.AsCString());
                 return args_addr;
             }
-            
-            errors.Clear();
-            if (!m_get_item_info_function->WriteFunctionWrapper(exe_ctx, errors))
+        }
+        else
+        {
+            // If it's already made, then we can just retrieve the caller:
+            get_item_info_caller = m_get_item_info_impl_code->GetFunctionCaller();
+            if (!get_item_info_caller)
             {
                 if (log)
-                    log->Printf ("Error Inserting get-item-info function: \"%s\".", errors.GetData());
+                    log->Printf ("Failed to get get-item-info introspection caller.");
+                m_get_item_info_impl_code.reset();
                 return args_addr;
             }
         }
@@ -244,7 +217,7 @@ AppleGetItemInfoHandler::SetupGetItemInf
     // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
     // this call by passing args_addr = LLDB_INVALID_ADDRESS...
 
-    if (!m_get_item_info_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, get_item_info_arglist, errors))
+    if (!get_item_info_caller->WriteFunctionArguments (exe_ctx, args_addr, get_item_info_arglist, errors))
     {
         if (log)
             log->Printf ("Error writing get-item-info function arguments: \"%s\".", errors.GetData());
@@ -364,7 +337,7 @@ AppleGetItemInfoHandler::GetItemInfo (Th
     options.SetTryAllThreads (false);
     thread.CalculateExecutionContext (exe_ctx);
 
-    if (m_get_item_info_function == NULL)
+    if (!m_get_item_info_impl_code)
     {
         error.SetErrorString ("Unable to compile function to call __introspection_dispatch_queue_item_get_info");
         return return_value;
@@ -373,7 +346,16 @@ AppleGetItemInfoHandler::GetItemInfo (Th
 
     ExpressionResults func_call_ret;
     Value results;
-    func_call_ret =  m_get_item_info_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+    FunctionCaller *func_caller = m_get_item_info_impl_code->GetFunctionCaller();
+    if (!func_caller)
+    {
+        if (log)
+            log->Printf ("Could not retrieve function caller for __introspection_dispatch_queue_item_get_info.");
+        error.SetErrorString("Could not retrieve function caller for __introspection_dispatch_queue_item_get_info.");
+        return return_value;
+    }
+    
+    func_call_ret =  func_caller->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
     if (func_call_ret != eExpressionCompleted || !error.Success())
     {
         if (log)

Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h Tue Sep 15 16:13:50 2015
@@ -18,11 +18,11 @@
 // Project includes
 #include "lldb/lldb-public.h"
 #include "lldb/Core/Error.h"
-#include "lldb/Expression/ClangFunction.h"
+#include "lldb/Expression/UtilityFunction.h"
 #include "lldb/Host/Mutex.h"
 #include "lldb/Symbol/CompilerType.h"
 
-// This class will insert a ClangUtilityFunction into the inferior process for
+// This class will insert a UtilityFunction into the inferior process for
 // calling libBacktraceRecording's __introspection_dispatch_queue_item_get_info()
 // function.  The function in the inferior will return a struct by value
 // with these members:
@@ -37,7 +37,7 @@
 // space (item_buffer_size in size) which must be mach_vm_deallocate'd by
 // lldb.  
 //
-// The AppleGetItemInfoHandler object should persist so that the ClangUtilityFunction
+// The AppleGetItemInfoHandler object should persist so that the UtilityFunction
 // can be reused multiple times.
 
 namespace lldb_private
@@ -104,8 +104,7 @@ private:
     static const char *g_get_item_info_function_code;
 
     lldb_private::Process *m_process;
-    std::unique_ptr<ClangFunction> m_get_item_info_function;
-    std::unique_ptr<ClangUtilityFunction> m_get_item_info_impl_code;
+    std::unique_ptr<UtilityFunction> m_get_item_info_impl_code;
     Mutex m_get_item_info_function_mutex;
 
     lldb::addr_t m_get_item_info_return_buffer_addr;

Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp Tue Sep 15 16:13:50 2015
@@ -22,9 +22,8 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/Value.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/Symbol.h"
 #include "lldb/Target/ExecutionContext.h"
@@ -105,7 +104,6 @@ extern \"C\"
 
 AppleGetPendingItemsHandler::AppleGetPendingItemsHandler (Process *process) :
     m_process (process),
-    m_get_pending_items_function (),
     m_get_pending_items_impl_code (),
     m_get_pending_items_function_mutex(),
     m_get_pending_items_return_buffer_addr (LLDB_INVALID_ADDRESS),
@@ -144,49 +142,33 @@ lldb::addr_t
 AppleGetPendingItemsHandler::SetupGetPendingItemsFunction (Thread &thread, ValueList &get_pending_items_arglist)
 {
     ExecutionContext exe_ctx (thread.shared_from_this());
-    Address impl_code_address;
     StreamString errors;
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
     lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
-
+    FunctionCaller *get_pending_items_caller = nullptr;
+    
     // Scope for mutex locker:
     {
         Mutex::Locker locker(m_get_pending_items_function_mutex);
         
         // First stage is to make the ClangUtility to hold our injected function:
 
-#define USE_BUILTIN_FUNCTION 0  // Define this to 1 and we will use the get_implementation function found in the target.
-                                // This is useful for debugging additions to the get_impl function 'cause you don't have
-                                // to bother with string-ifying the code into g_get_pending_items_function_code.
-        
-        if (USE_BUILTIN_FUNCTION)
-        {
-            ConstString our_utility_function_name("__lldb_backtrace_recording_get_pending_items");
-            SymbolContextList sc_list;
-            
-            exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
-            if (sc_list.GetSize() == 1)
-            {
-                SymbolContext sc;
-                sc_list.GetContextAtIndex(0, sc);
-                if (sc.symbol != NULL)
-                    impl_code_address = sc.symbol->GetAddress();
-                    
-                //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
-                //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
-            }
-            else
-            {
-                //printf ("Could not find queues introspection function address.\n");
-                return args_addr;
-            }
-        }
-        else if (!m_get_pending_items_impl_code.get())
+        if (!m_get_pending_items_impl_code.get())
         {
             if (g_get_pending_items_function_code != NULL)
             {
-                m_get_pending_items_impl_code.reset (new ClangUtilityFunction (g_get_pending_items_function_code,
-                                                             g_get_pending_items_function_name));
+                Error error;
+                m_get_pending_items_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(g_get_pending_items_function_code,
+                                                                                                          eLanguageTypeObjC,
+                                                                                                          g_get_pending_items_function_name,
+                                                                                                          error));
+                if (error.Fail())
+                {
+                    if (log)
+                        log->Printf ("Failed to get UtilityFunction for pending-items introspection: %s.", error.AsCString());
+                    return args_addr;
+                }
+                
                 if (!m_get_pending_items_impl_code->Install(errors, exe_ctx))
                 {
                     if (log)
@@ -203,43 +185,22 @@ AppleGetPendingItemsHandler::SetupGetPen
                 return LLDB_INVALID_ADDRESS;
             }
             
-            impl_code_address.Clear();
-            impl_code_address.SetOffset(m_get_pending_items_impl_code->StartAddress());
-        }
-        else
-        {
-            impl_code_address.Clear();
-            impl_code_address.SetOffset(m_get_pending_items_impl_code->StartAddress());
-        }
-
-        // Next make the runner function for our implementation utility function.
-        if (!m_get_pending_items_function.get())
-        {
+            // Next make the runner function for our implementation utility function.
+            Error error;
             ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
             CompilerType get_pending_items_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
-            m_get_pending_items_function.reset(new ClangFunction (thread,
-                                                     get_pending_items_return_type,
-                                                     impl_code_address,
-                                                     get_pending_items_arglist,
-                                                     "queue-pending-items"));
-            
-            errors.Clear();        
-            unsigned num_errors = m_get_pending_items_function->CompileFunction(errors);
-            if (num_errors)
+            get_pending_items_caller = m_get_pending_items_impl_code->MakeFunctionCaller (get_pending_items_return_type,
+                                                                                          get_pending_items_arglist,
+                                                                                          error);
+            if (error.Fail())
             {
                 if (log)
-                    log->Printf ("Error compiling pending-items function: \"%s\".", errors.GetData());
-                return args_addr;
-            }
-            
-            errors.Clear();
-            if (!m_get_pending_items_function->WriteFunctionWrapper(exe_ctx, errors))
-            {
-                if (log)
-                    log->Printf ("Error Inserting pending-items function: \"%s\".", errors.GetData());
+                    log->Printf ("Failed to install pending-items introspection function caller: %s.", error.AsCString());
+                m_get_pending_items_impl_code.reset();
                 return args_addr;
             }
         }
+
     }
     
     errors.Clear();
@@ -248,7 +209,7 @@ AppleGetPendingItemsHandler::SetupGetPen
     // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
     // this call by passing args_addr = LLDB_INVALID_ADDRESS...
 
-    if (!m_get_pending_items_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, get_pending_items_arglist, errors))
+    if (!get_pending_items_caller->WriteFunctionArguments (exe_ctx, args_addr, get_pending_items_arglist, errors))
     {
         if (log)
             log->Printf ("Error writing pending-items function arguments: \"%s\".", errors.GetData());
@@ -362,6 +323,8 @@ AppleGetPendingItemsHandler::GetPendingI
 
     StreamString errors;
     ExecutionContext exe_ctx;
+    FunctionCaller *get_pending_items_caller = m_get_pending_items_impl_code->GetFunctionCaller();
+    
     EvaluateExpressionOptions options;
     options.SetUnwindOnError (true);
     options.SetIgnoreBreakpoints (true);
@@ -370,7 +333,7 @@ AppleGetPendingItemsHandler::GetPendingI
     options.SetTryAllThreads (false);
     thread.CalculateExecutionContext (exe_ctx);
 
-    if (m_get_pending_items_function == NULL)
+    if (get_pending_items_caller == NULL)
     {
         error.SetErrorString ("Unable to compile function to call __introspection_dispatch_queue_get_pending_items");
         return return_value;
@@ -379,7 +342,7 @@ AppleGetPendingItemsHandler::GetPendingI
 
     ExpressionResults func_call_ret;
     Value results;
-    func_call_ret =  m_get_pending_items_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+    func_call_ret =  get_pending_items_caller->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
     if (func_call_ret != eExpressionCompleted || !error.Success())
     {
         if (log)

Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h Tue Sep 15 16:13:50 2015
@@ -18,11 +18,10 @@
 // Project includes
 #include "lldb/lldb-public.h"
 #include "lldb/Core/Error.h"
-#include "lldb/Expression/ClangFunction.h"
 #include "lldb/Host/Mutex.h"
 #include "lldb/Symbol/CompilerType.h"
 
-// This class will insert a ClangUtilityFunction into the inferior process for
+// This class will insert a UtilityFunction into the inferior process for
 // calling libBacktraceRecording's __introspection_dispatch_queue_get_pending_items()
 // function.  The function in the inferior will return a struct by value
 // with these members:
@@ -38,7 +37,7 @@
 // space (items_buffer_size in size) which must be mach_vm_deallocate'd by
 // lldb.  count is the number of items that were stored in the buffer.
 //
-// The AppleGetPendingItemsHandler object should persist so that the ClangUtilityFunction
+// The AppleGetPendingItemsHandler object should persist so that the UtilityFunction
 // can be reused multiple times.
 
 namespace lldb_private
@@ -107,8 +106,7 @@ private:
     static const char *g_get_pending_items_function_code;
 
     lldb_private::Process *m_process;
-    std::unique_ptr<ClangFunction> m_get_pending_items_function;
-    std::unique_ptr<ClangUtilityFunction> m_get_pending_items_impl_code;
+    std::unique_ptr<UtilityFunction> m_get_pending_items_impl_code;
     Mutex m_get_pending_items_function_mutex;
 
     lldb::addr_t m_get_pending_items_return_buffer_addr;

Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp Tue Sep 15 16:13:50 2015
@@ -21,9 +21,8 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/Value.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/Symbol.h"
 #include "lldb/Target/ExecutionContext.h"
@@ -101,8 +100,7 @@ extern \"C\"
 
 AppleGetQueuesHandler::AppleGetQueuesHandler (Process *process) :
     m_process (process),
-    m_get_queues_function (),
-    m_get_queues_impl_code (),
+    m_get_queues_impl_code_up (),
     m_get_queues_function_mutex(),
     m_get_queues_return_buffer_addr (LLDB_INVALID_ADDRESS),
     m_get_queues_retbuffer_mutex()
@@ -156,6 +154,8 @@ AppleGetQueuesHandler::SetupGetQueuesFun
     StreamString errors;
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
     lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+    
+    FunctionCaller *get_queues_caller = nullptr;
 
     // Scope for mutex locker:
     {
@@ -163,43 +163,27 @@ AppleGetQueuesHandler::SetupGetQueuesFun
         
         // First stage is to make the ClangUtility to hold our injected function:
 
-#define USE_BUILTIN_FUNCTION 0  // Define this to 1 and we will use the get_implementation function found in the target.
-                                // This is useful for debugging additions to the get_impl function 'cause you don't have
-                                // to bother with string-ifying the code into g_get_current_queues_function_code.
-        
-        if (USE_BUILTIN_FUNCTION)
-        {
-            ConstString our_utility_function_name("__lldb_backtrace_recording_get_current_queues");
-            SymbolContextList sc_list;
-            
-            exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
-            if (sc_list.GetSize() == 1)
-            {
-                SymbolContext sc;
-                sc_list.GetContextAtIndex(0, sc);
-                if (sc.symbol != NULL)
-                    impl_code_address = sc.symbol->GetAddress();
-                    
-                //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
-                //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
-            }
-            else
-            {
-                //printf ("Could not find queues introspection function address.\n");
-                return args_addr;
-            }
-        }
-        else if (!m_get_queues_impl_code.get())
+        if (!m_get_queues_impl_code_up.get())
         {
             if (g_get_current_queues_function_code != NULL)
             {
-                m_get_queues_impl_code.reset (new ClangUtilityFunction (g_get_current_queues_function_code,
-                                                             g_get_current_queues_function_name));
-                if (!m_get_queues_impl_code->Install(errors, exe_ctx))
+                Error error;
+                m_get_queues_impl_code_up.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(g_get_current_queues_function_code,
+                                                                                                          eLanguageTypeC,
+                                                                                                          g_get_current_queues_function_name,
+                                                                                                          error));
+                if (error.Fail())
+                {
+                    if (log)
+                        log->Printf ("Failed to get UtilityFunction for queues introspection: %s.", error.AsCString());
+                    return args_addr;
+                }
+                
+                if (!m_get_queues_impl_code_up->Install(errors, exe_ctx))
                 {
                     if (log)
                         log->Printf ("Failed to install queues introspection: %s.", errors.GetData());
-                    m_get_queues_impl_code.reset();
+                    m_get_queues_impl_code_up.reset();
                     return args_addr;
                 }
             }
@@ -210,43 +194,20 @@ AppleGetQueuesHandler::SetupGetQueuesFun
                 errors.Printf ("No queues introspection code found.");
                 return LLDB_INVALID_ADDRESS;
             }
-            
-            impl_code_address.Clear();
-            impl_code_address.SetOffset(m_get_queues_impl_code->StartAddress());
-        }
-        else
-        {
-            impl_code_address.Clear();
-            impl_code_address.SetOffset(m_get_queues_impl_code->StartAddress());
         }
-
+        
         // Next make the runner function for our implementation utility function.
-        if (!m_get_queues_function.get())
+        ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+        CompilerType get_queues_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+        Error error;
+        get_queues_caller = m_get_queues_impl_code_up->MakeFunctionCaller (get_queues_return_type,
+                                                                       get_queues_arglist,
+                                                                       error);
+        if (error.Fail())
         {
-            ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
-            CompilerType get_queues_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
-            m_get_queues_function.reset(new ClangFunction (thread,
-                                                     get_queues_return_type,
-                                                     impl_code_address,
-                                                     get_queues_arglist,
-                                                     "queue-fetch-queues"));
-            
-            errors.Clear();        
-            unsigned num_errors = m_get_queues_function->CompileFunction(errors);
-            if (num_errors)
-            {
-                if (log)
-                    log->Printf ("Error compiling get-queues function: \"%s\".", errors.GetData());
-                return args_addr;
-            }
-            
-            errors.Clear();
-            if (!m_get_queues_function->WriteFunctionWrapper(exe_ctx, errors))
-            {
-                if (log)
-                    log->Printf ("Error Inserting get-queues function: \"%s\".", errors.GetData());
-                return args_addr;
-            }
+            if (log)
+                log->Printf ("Could not get function caller for get-queues function: %s.", error.AsCString());
+            return args_addr;
         }
     }
     
@@ -256,7 +217,7 @@ AppleGetQueuesHandler::SetupGetQueuesFun
     // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
     // this call by passing args_addr = LLDB_INVALID_ADDRESS...
 
-    if (!m_get_queues_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, get_queues_arglist, errors))
+    if (!get_queues_caller->WriteFunctionArguments (exe_ctx, args_addr, get_queues_arglist, errors))
     {
         if (log)
             log->Printf ("Error writing get-queues function arguments: \"%s\".", errors.GetData());
@@ -360,9 +321,17 @@ AppleGetQueuesHandler::GetCurrentQueues
 
     addr_t args_addr = SetupGetQueuesFunction (thread, argument_values);
 
-    if (m_get_queues_function == NULL)
+    if (!m_get_queues_impl_code_up)
+    {
+        error.SetErrorString ("Unable to compile __introspection_dispatch_get_queues.");
+        return return_value;
+    }
+    
+    FunctionCaller *get_queues_caller = m_get_queues_impl_code_up->GetFunctionCaller();
+    
+    if (get_queues_caller == NULL)
     {
-        error.SetErrorString ("Unable to compile function to call __introspection_dispatch_get_queues");
+        error.SetErrorString ("Unable to get caller for call __introspection_dispatch_get_queues");
         return return_value;
     }
 
@@ -378,7 +347,7 @@ AppleGetQueuesHandler::GetCurrentQueues
 
     ExpressionResults func_call_ret;
     Value results;
-    func_call_ret =  m_get_queues_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+    func_call_ret =  get_queues_caller->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
     if (func_call_ret != eExpressionCompleted || !error.Success())
     {
         if (log)

Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h Tue Sep 15 16:13:50 2015
@@ -18,11 +18,10 @@
 // Project includes
 #include "lldb/lldb-public.h"
 #include "lldb/Core/Error.h"
-#include "lldb/Expression/ClangFunction.h"
 #include "lldb/Host/Mutex.h"
 #include "lldb/Symbol/CompilerType.h"
 
-// This class will insert a ClangUtilityFunction into the inferior process for
+// This class will insert a UtilityFunction into the inferior process for
 // calling libBacktraceRecording's introspection_get_dispatch_queues()
 // function.  The function in the inferior will return a struct by value
 // with these members:
@@ -38,7 +37,7 @@
 // space (queues_buffer_size in size) which must be mach_vm_deallocate'd by
 // lldb.  count is the number of queues that were stored in the buffer.
 //
-// The AppleGetQueuesHandler object should persist so that the ClangUtilityFunction
+// The AppleGetQueuesHandler object should persist so that the UtilityFunction
 // can be reused multiple times.
 
 namespace lldb_private
@@ -104,8 +103,7 @@ private:
     static const char *g_get_current_queues_function_code;
 
     lldb_private::Process *m_process;
-    std::unique_ptr<ClangFunction> m_get_queues_function;
-    std::unique_ptr<ClangUtilityFunction> m_get_queues_impl_code;
+    std::unique_ptr<UtilityFunction> m_get_queues_impl_code_up;
     Mutex m_get_queues_function_mutex;
 
     lldb::addr_t m_get_queues_return_buffer_addr;

Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp Tue Sep 15 16:13:50 2015
@@ -17,18 +17,20 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclCXX.h"
 
+#include "lldb/lldb-private.h"
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/Value.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/Expression.h"
+#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UtilityFunction.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/Symbol.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrame.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
 
@@ -105,7 +107,6 @@ extern \"C\"
 
 AppleGetThreadItemInfoHandler::AppleGetThreadItemInfoHandler (Process *process) :
     m_process (process),
-    m_get_thread_item_info_function (),
     m_get_thread_item_info_impl_code (),
     m_get_thread_item_info_function_mutex(),
     m_get_thread_item_info_return_buffer_addr (LLDB_INVALID_ADDRESS),
@@ -148,6 +149,7 @@ AppleGetThreadItemInfoHandler::SetupGetT
     StreamString errors;
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYSTEM_RUNTIME));
     lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+    FunctionCaller *get_thread_item_info_caller = nullptr;
 
     // Scope for mutex locker:
     {
@@ -155,38 +157,24 @@ AppleGetThreadItemInfoHandler::SetupGetT
         
         // First stage is to make the ClangUtility to hold our injected function:
 
-#define USE_BUILTIN_FUNCTION 0  // Define this to 1 and we will use the get_implementation function found in the target.
-                                // This is useful for debugging additions to the get_impl function 'cause you don't have
-                                // to bother with string-ifying the code into g_get_thread_item_info_function_code.
-        
-        if (USE_BUILTIN_FUNCTION)
-        {
-            ConstString our_utility_function_name("__lldb_backtrace_recording_get_thread_item_info");
-            SymbolContextList sc_list;
-            
-            exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
-            if (sc_list.GetSize() == 1)
-            {
-                SymbolContext sc;
-                sc_list.GetContextAtIndex(0, sc);
-                if (sc.symbol != NULL)
-                    impl_code_address = sc.symbol->GetAddress();
-                    
-                //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
-                //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
-            }
-            else
-            {
-                //printf ("Could not find queues introspection function address.\n");
-                return args_addr;
-            }
-        }
-        else if (!m_get_thread_item_info_impl_code.get())
+        if (!m_get_thread_item_info_impl_code.get())
         {
+            Error error;
             if (g_get_thread_item_info_function_code != NULL)
             {
-                m_get_thread_item_info_impl_code.reset (new ClangUtilityFunction (g_get_thread_item_info_function_code,
-                                                             g_get_thread_item_info_function_name));
+                m_get_thread_item_info_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (g_get_thread_item_info_function_code,
+                                                                                                              eLanguageTypeC,
+                                                                                                              g_get_thread_item_info_function_name,
+                                                                                                              error));
+                if (error.Fail())
+                {
+                    if (log)
+                        log->Printf ("Failed to get UtilityFunction for get-thread-item-info introspection: %s.",
+                                     error.AsCString());
+                    m_get_thread_item_info_impl_code.reset();
+                    return args_addr;
+                }
+                
                 if (!m_get_thread_item_info_impl_code->Install(errors, exe_ctx))
                 {
                     if (log)
@@ -203,42 +191,26 @@ AppleGetThreadItemInfoHandler::SetupGetT
                 return LLDB_INVALID_ADDRESS;
             }
             
-            impl_code_address.Clear();
-            impl_code_address.SetOffset(m_get_thread_item_info_impl_code->StartAddress());
-        }
-        else
-        {
-            impl_code_address.Clear();
-            impl_code_address.SetOffset(m_get_thread_item_info_impl_code->StartAddress());
-        }
-
-        // Next make the runner function for our implementation utility function.
-        if (!m_get_thread_item_info_function.get())
-        {
+            // Also make the FunctionCaller for this UtilityFunction:
+            
             ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
             CompilerType get_thread_item_info_return_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
-            m_get_thread_item_info_function.reset(new ClangFunction (thread,
-                                                                     get_thread_item_info_return_type,
-                                                                     impl_code_address,
-                                                                     get_thread_item_info_arglist,
-                                                                     "queue-thread-item-info"));
             
-            errors.Clear();        
-            unsigned num_errors = m_get_thread_item_info_function->CompileFunction(errors);
-            if (num_errors)
+            get_thread_item_info_caller =  m_get_thread_item_info_impl_code->MakeFunctionCaller (get_thread_item_info_return_type,
+                                                                                                 get_thread_item_info_arglist,
+                                                                                                 error);
+            if (error.Fail())
             {
                 if (log)
-                    log->Printf ("Error compiling get-thread-item-info function: \"%s\".", errors.GetData());
+                    log->Printf ("Failed to install get-thread-item-info introspection caller: %s.", error.AsCString());
+                m_get_thread_item_info_impl_code.reset();
                 return args_addr;
             }
             
-            errors.Clear();
-            if (!m_get_thread_item_info_function->WriteFunctionWrapper(exe_ctx, errors))
-            {
-                if (log)
-                    log->Printf ("Error Inserting get-thread-item-info function: \"%s\".", errors.GetData());
-                return args_addr;
-            }
+        }
+        else
+        {
+            get_thread_item_info_caller = m_get_thread_item_info_impl_code->GetFunctionCaller();
         }
     }
     
@@ -248,7 +220,7 @@ AppleGetThreadItemInfoHandler::SetupGetT
     // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
     // this call by passing args_addr = LLDB_INVALID_ADDRESS...
 
-    if (!m_get_thread_item_info_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, get_thread_item_info_arglist, errors))
+    if (!get_thread_item_info_caller->WriteFunctionArguments (exe_ctx, args_addr, get_thread_item_info_arglist, errors))
     {
         if (log)
             log->Printf ("Error writing get-thread-item-info function arguments: \"%s\".", errors.GetData());
@@ -360,6 +332,8 @@ AppleGetThreadItemInfoHandler::GetThread
     StreamString errors;
     ExecutionContext exe_ctx;
     EvaluateExpressionOptions options;
+    FunctionCaller *get_thread_item_info_caller = nullptr;
+    
     options.SetUnwindOnError (true);
     options.SetIgnoreBreakpoints (true);
     options.SetStopOthers (true);
@@ -367,16 +341,23 @@ AppleGetThreadItemInfoHandler::GetThread
     options.SetTryAllThreads (false);
     thread.CalculateExecutionContext (exe_ctx);
 
-    if (m_get_thread_item_info_function == NULL)
+    if (!m_get_thread_item_info_impl_code)
     {
         error.SetErrorString ("Unable to compile function to call __introspection_dispatch_thread_get_item_info");
         return return_value;
     }
 
+    get_thread_item_info_caller = m_get_thread_item_info_impl_code->GetFunctionCaller();
+
+    if (!get_thread_item_info_caller)
+    {
+        error.SetErrorString ("Unable to compile function caller for __introspection_dispatch_thread_get_item_info");
+        return return_value;
+    }
 
     ExpressionResults func_call_ret;
     Value results;
-    func_call_ret =  m_get_thread_item_info_function->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
+    func_call_ret =  get_thread_item_info_caller->ExecuteFunction (exe_ctx, &args_addr, options, errors, results);
     if (func_call_ret != eExpressionCompleted || !error.Success())
     {
         if (log)

Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h Tue Sep 15 16:13:50 2015
@@ -18,11 +18,10 @@
 // Project includes
 #include "lldb/lldb-public.h"
 #include "lldb/Core/Error.h"
-#include "lldb/Expression/ClangFunction.h"
 #include "lldb/Host/Mutex.h"
 #include "lldb/Symbol/CompilerType.h"
 
-// This class will insert a ClangUtilityFunction into the inferior process for
+// This class will insert a UtilityFunction into the inferior process for
 // calling libBacktraceRecording's __introspection_dispatch_thread_get_item_info()
 // function.  The function in the inferior will return a struct by value
 // with these members:
@@ -37,7 +36,7 @@
 // space (item_buffer_size in size) which must be mach_vm_deallocate'd by
 // lldb.  
 //
-// The AppleGetThreadItemInfoHandler object should persist so that the ClangUtilityFunction
+// The AppleGetThreadItemInfoHandler object should persist so that the UtilityFunction
 // can be reused multiple times.
 
 namespace lldb_private
@@ -101,8 +100,7 @@ private:
     static const char *g_get_thread_item_info_function_code;
 
     lldb_private::Process *m_process;
-    std::unique_ptr<ClangFunction> m_get_thread_item_info_function;
-    std::unique_ptr<ClangUtilityFunction> m_get_thread_item_info_impl_code;
+    std::unique_ptr<UtilityFunction> m_get_thread_item_info_impl_code;
     Mutex m_get_thread_item_info_function_mutex;
 
     lldb::addr_t m_get_thread_item_info_return_buffer_addr;

Modified: lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp (original)
+++ lldb/trunk/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp Tue Sep 15 16:13:50 2015
@@ -17,8 +17,6 @@
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/StreamString.h"
-#include "lldb/Expression/ClangFunction.h"
-#include "lldb/Expression/ClangUtilityFunction.h"
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/ObjectFile.h"

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Tue Sep 15 16:13:50 2015
@@ -69,14 +69,20 @@
 #include "lldb/Core/ThreadSafeDenseMap.h"
 #include "lldb/Core/UniqueCStringMap.h"
 #include "lldb/Expression/ASTDumper.h"
+#include "lldb/Expression/ASTResultSynthesizer.h"
+#include "lldb/Expression/ClangExpressionDeclMap.h"
+#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/ClangFunctionCaller.h"
+#include "lldb/Expression/ClangUtilityFunction.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
 #include "lldb/Symbol/ClangExternalASTSourceCommon.h"
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/VerifyDecl.h"
 #include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/Process.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
 
 #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
 
@@ -8942,3 +8948,49 @@ ClangASTContext::DeclContextGetClangASTC
     return nullptr;
 }
 
+ClangASTContextForExpressions::ClangASTContextForExpressions (Target &target) :
+    ClangASTContext (target.GetArchitecture().GetTriple().getTriple().c_str()),
+    m_target_wp(target.shared_from_this())
+{
+}
+
+UserExpression *
+ClangASTContextForExpressions::GetUserExpression (const char *expr,
+                   const char *expr_prefix,
+                   lldb::LanguageType language,
+                   Expression::ResultType desired_type)
+{
+    TargetSP target_sp = m_target_wp.lock();
+    if (!target_sp)
+        return nullptr;
+    
+    return new ClangUserExpression(*target_sp.get(), expr, expr_prefix, language, desired_type);
+}
+
+FunctionCaller *
+ClangASTContextForExpressions::GetFunctionCaller (const CompilerType &return_type,
+                                                  const Address& function_address,
+                                                  const ValueList &arg_value_list,
+                                                  const char *name)
+{
+    TargetSP target_sp = m_target_wp.lock();
+    if (!target_sp)
+        return nullptr;
+    
+   Process *process = target_sp->GetProcessSP().get();
+   if (!process)
+       return nullptr;
+   
+   return new ClangFunctionCaller (*process, return_type, function_address, arg_value_list, name);
+}
+
+UtilityFunction *
+ClangASTContextForExpressions::GetUtilityFunction (const char *text,
+                                                   const char *name)
+{
+     TargetSP target_sp = m_target_wp.lock();
+    if (!target_sp)
+        return nullptr;
+    
+    return new ClangUtilityFunction(*target_sp.get(), text, name);
+}

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Tue Sep 15 16:13:50 2015
@@ -18,7 +18,7 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/State.h"
 #include "lldb/Core/StreamFile.h"
-#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/UserExpression.h"
 #include "lldb/Expression/IRDynamicChecks.h"
 #include "lldb/Host/ConnectionFileDescriptor.h"
 #include "lldb/Host/Host.h"
@@ -1917,6 +1917,7 @@ Process::LoadImage (const FileSpec &imag
                 expr_options.SetIgnoreBreakpoints(true);
                 expr_options.SetExecutionPolicy(eExecutionPolicyAlways);
                 expr_options.SetResultIsInternal(true);
+                expr_options.SetLanguage(eLanguageTypeC_plus_plus);
                 
                 StreamString expr;
                 expr.Printf(R"(
@@ -1939,12 +1940,12 @@ Process::LoadImage (const FileSpec &imag
                                         )";
                 lldb::ValueObjectSP result_valobj_sp;
                 Error expr_error;
-                ClangUserExpression::Evaluate (exe_ctx,
-                                               expr_options,
-                                               expr.GetData(),
-                                               prefix,
-                                               result_valobj_sp,
-                                               expr_error);
+                UserExpression::Evaluate (exe_ctx,
+                                          expr_options,
+                                          expr.GetData(),
+                                          prefix,
+                                          result_valobj_sp,
+                                          expr_error);
                 if (expr_error.Success())
                 {
                     error = result_valobj_sp->GetError();
@@ -2044,17 +2045,19 @@ Process::UnloadImage (uint32_t image_tok
                         expr_options.SetUnwindOnError(true);
                         expr_options.SetIgnoreBreakpoints(true);
                         expr_options.SetExecutionPolicy(eExecutionPolicyAlways);
+                        expr_options.SetLanguage(eLanguageTypeC_plus_plus);
+                        
                         StreamString expr;
                         expr.Printf("dlclose ((void *)0x%" PRIx64 ")", image_addr);
                         const char *prefix = "extern \"C\" int dlclose(void* handle);\n";
                         lldb::ValueObjectSP result_valobj_sp;
                         Error expr_error;
-                        ClangUserExpression::Evaluate (exe_ctx,
-                                                       expr_options,
-                                                       expr.GetData(),
-                                                       prefix,
-                                                       result_valobj_sp,
-                                                       expr_error);
+                        UserExpression::Evaluate (exe_ctx,
+                                                  expr_options,
+                                                  expr.GetData(),
+                                                  prefix,
+                                                  result_valobj_sp,
+                                                  expr_error);
                         if (result_valobj_sp->GetError().Success())
                         {
                             Scalar scalar;

Modified: lldb/trunk/source/Target/StopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StopInfo.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Target/StopInfo.cpp (original)
+++ lldb/trunk/source/Target/StopInfo.cpp Tue Sep 15 16:13:50 2015
@@ -23,7 +23,7 @@
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/ValueObject.h"
-#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/UserExpression.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
 #include "lldb/Target/ThreadPlan.h"
@@ -770,12 +770,13 @@ protected:
                     expr_options.SetIgnoreBreakpoints(true);
                     ValueObjectSP result_value_sp;
                     Error error;
-                    result_code = ClangUserExpression::Evaluate (exe_ctx,
-                                                                 expr_options,
-                                                                 wp_sp->GetConditionText(),
-                                                                 NULL,
-                                                                 result_value_sp,
-                                                                 error);
+                    result_code = UserExpression::Evaluate (exe_ctx,
+                                                            expr_options,
+                                                            wp_sp->GetConditionText(),
+                                                            NULL,
+                                                            result_value_sp,
+                                                            error);
+                                                            
                     if (result_code == eExpressionCompleted)
                     {
                         if (result_value_sp)

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Tue Sep 15 16:13:50 2015
@@ -33,7 +33,7 @@
 #include "lldb/Core/ValueObject.h"
 #include "lldb/Expression/ClangASTSource.h"
 #include "lldb/Expression/ClangPersistentVariables.h"
-#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/UserExpression.h"
 #include "lldb/Expression/ClangModulesDeclVendor.h"
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Host/Host.h"
@@ -46,6 +46,7 @@
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/Language.h"
 #include "lldb/Target/LanguageRuntime.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/Process.h"
@@ -1891,13 +1892,95 @@ Target::ImageSearchPathsChanged
         target->SetExecutableModule (exe_module_sp, true);
 }
 
+TypeSystem *
+Target::GetScratchTypeSystemForLanguage (lldb::LanguageType language, bool create_on_demand)
+{
+    if (Language::LanguageIsC(language)
+       || Language::LanguageIsObjC(language)
+       || Language::LanguageIsCPlusPlus(language)
+       || language == eLanguageTypeUnknown)
+        return GetScratchClangASTContext(create_on_demand);
+    else
+        return NULL;
+}
+
+UserExpression *
+Target::GetUserExpressionForLanguage(const char *expr,
+                             const char *expr_prefix,
+                             lldb::LanguageType language,
+                             Expression::ResultType desired_type,
+                             Error &error)
+{
+    TypeSystem *type_system = GetScratchTypeSystemForLanguage (language);
+    UserExpression *user_expr = nullptr;
+    
+    if (!type_system)
+    {
+        error.SetErrorStringWithFormat("Could not find type system for language: %s", Language::GetNameForLanguageType(language));
+        return nullptr;
+    }
+    
+    user_expr = type_system->GetUserExpression(expr, expr_prefix, language, desired_type);
+    if (!user_expr)
+        error.SetErrorStringWithFormat("Could not create an expression for language %s", Language::GetNameForLanguageType(language));
+    
+    return user_expr;
+}
+
+FunctionCaller *
+Target::GetFunctionCallerForLanguage (lldb::LanguageType language,
+                                      const CompilerType &return_type,
+                                      const Address& function_address,
+                                      const ValueList &arg_value_list,
+                                      const char *name,
+                                      Error &error)
+{
+    TypeSystem *type_system = GetScratchTypeSystemForLanguage (language);
+    FunctionCaller *persistent_fn = nullptr;
+    
+    if (!type_system)
+    {
+        error.SetErrorStringWithFormat("Could not find type system for language: %s", Language::GetNameForLanguageType(language));
+        return persistent_fn;
+    }
+    
+    persistent_fn = type_system->GetFunctionCaller (return_type, function_address, arg_value_list, name);
+    if (!persistent_fn)
+        error.SetErrorStringWithFormat("Could not create an expression for language %s", Language::GetNameForLanguageType(language));
+    
+    return persistent_fn;
+}
+
+UtilityFunction *
+Target::GetUtilityFunctionForLanguage (const char *text,
+                                       lldb::LanguageType language,
+                                       const char *name,
+                                       Error &error)
+{
+    TypeSystem *type_system = GetScratchTypeSystemForLanguage (language);
+    UtilityFunction *utility_fn = nullptr;
+    
+    if (!type_system)
+    {
+        error.SetErrorStringWithFormat("Could not find type system for language: %s", Language::GetNameForLanguageType(language));
+        return utility_fn;
+    }
+    
+    utility_fn = type_system->GetUtilityFunction (text, name);
+    if (!utility_fn)
+        error.SetErrorStringWithFormat("Could not create an expression for language %s", Language::GetNameForLanguageType(language));
+    
+    return utility_fn;
+}
+
+
 ClangASTContext *
 Target::GetScratchClangASTContext(bool create_on_demand)
 {
     // Now see if we know the target triple, and if so, create our scratch AST context:
     if (m_scratch_ast_context_ap.get() == NULL && m_arch.IsValid() && create_on_demand)
     {
-        m_scratch_ast_context_ap.reset (new ClangASTContext(m_arch.GetTriple().str().c_str()));
+        m_scratch_ast_context_ap.reset (new ClangASTContextForExpressions(*this));
         m_scratch_ast_source_ap.reset (new ClangASTSource(shared_from_this()));
         m_scratch_ast_source_ap->InstallASTContext(m_scratch_ast_context_ap->getASTContext());
         llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> proxy_ast_source(m_scratch_ast_source_ap->CreateProxy());
@@ -1906,27 +1989,6 @@ Target::GetScratchClangASTContext(bool c
     return m_scratch_ast_context_ap.get();
 }
 
-TypeSystem*
-Target::GetTypeSystemForLanguage (lldb::LanguageType language)
-{
-    switch (language)
-    {
-        case lldb::eLanguageTypeC:
-        case lldb::eLanguageTypeC11:
-        case lldb::eLanguageTypeC89:
-        case lldb::eLanguageTypeC99:
-        case lldb::eLanguageTypeC_plus_plus:
-        case lldb::eLanguageTypeC_plus_plus_03:
-        case lldb::eLanguageTypeC_plus_plus_11:
-        case lldb::eLanguageTypeC_plus_plus_14:
-        case lldb::eLanguageTypeObjC:
-        case lldb::eLanguageTypeObjC_plus_plus:
-            return GetScratchClangASTContext(true);
-        default:
-            return nullptr;
-    }
-}
-
 ClangASTImporter *
 Target::GetClangASTImporter()
 {
@@ -2067,12 +2129,12 @@ Target::EvaluateExpression
     {
         const char *prefix = GetExpressionPrefixContentsAsCString();
         Error error;
-        execution_results = ClangUserExpression::Evaluate (exe_ctx, 
-                                                           options,
-                                                           expr_cstr,
-                                                           prefix, 
-                                                           result_valobj_sp,
-                                                           error);
+        execution_results = UserExpression::Evaluate (exe_ctx,
+                                                      options,
+                                                      expr_cstr,
+                                                      prefix,
+                                                      result_valobj_sp,
+                                                      error);
     }
     
     m_suppress_stop_hooks = old_suppress_value;

Modified: lldb/trunk/source/Target/ThreadPlanCallUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanCallUserExpression.cpp?rev=247720&r1=247719&r2=247720&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanCallUserExpression.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanCallUserExpression.cpp Tue Sep 15 16:13:50 2015
@@ -19,7 +19,7 @@
 #include "lldb/Core/Address.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Stream.h"
-#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Expression/UserExpression.h"
 #include "lldb/Expression/IRDynamicChecks.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Target/LanguageRuntime.h"
@@ -41,7 +41,7 @@ ThreadPlanCallUserExpression::ThreadPlan
                                                 Address &function,
                                                 llvm::ArrayRef<lldb::addr_t> args,
                                                 const EvaluateExpressionOptions &options,
-                                                lldb::ClangUserExpressionSP &user_expression_sp) :
+                                                lldb::UserExpressionSP &user_expression_sp) :
     ThreadPlanCallFunction (thread, function, CompilerType(), args, options),
     m_user_expression_sp (user_expression_sp)
 {




More information about the lldb-commits mailing list