JITed functions can now have debug info and be debugged with debug and source info:

(lldb) b puts
(lldb) expr -g -i0 -- (int)puts("hello")

First we will stop at the entry point of the expression before it runs, then we can step over a few times and hit the breakpoint in "puts", then we can continue and finishing stepping and fininsh the expression.

Main features:
- New ObjectFileJIT class that can be easily created for JIT functions
- debug info can now be enabled when parsing expressions
- source for any function that is run throught the JIT is now saved in LLDB process specific temp directory and cleaned up on exit
- "expr -g --" allows you to single step through your expression function with source code

<rdar://problem/16382881>

llvm-svn: 204682
diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp
index 2b9bd2c..4eefddd 100644
--- a/lldb/source/Expression/ClangUserExpression.cpp
+++ b/lldb/source/Expression/ClangUserExpression.cpp
@@ -20,6 +20,7 @@
 
 #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"
@@ -36,6 +37,8 @@
 #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"
@@ -63,6 +66,11 @@
     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_cplusplus (false),
     m_objectivec (false),
@@ -91,6 +99,12 @@
 
 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 *
@@ -415,7 +429,8 @@
 ClangUserExpression::Parse (Stream &error_stream, 
                             ExecutionContext &exe_ctx,
                             lldb_private::ExecutionPolicy execution_policy,
-                            bool keep_result_in_memory)
+                            bool keep_result_in_memory,
+                            bool generate_debug_info)
 {
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
@@ -514,7 +529,7 @@
     if (!exe_scope)
         exe_scope = exe_ctx.GetTargetPtr();
     
-    ClangExpressionParser parser(exe_scope, *this);
+    ClangExpressionParser parser(exe_scope, *this, generate_debug_info);
     
     unsigned num_errors = parser.Parse (error_stream);
     
@@ -533,11 +548,42 @@
             
     Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
                                                   m_jit_end_addr,
-                                                  m_execution_unit_ap,
+                                                  m_execution_unit_sp,
                                                   exe_ctx,
                                                   m_can_interpret,
                                                   execution_policy);
     
+    if (generate_debug_info)
+    {
+        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;
+            target->GetImages().Append(jit_module_sp);
+        }
+//        lldb_private::ObjectFile *jit_obj_file = jit_module_sp->GetObjectFile();
+//        StreamFile strm (stdout, false);
+//        if (jit_obj_file)
+//        {
+//            jit_obj_file->GetSectionList();
+//            jit_obj_file->GetSymtab();
+//            jit_obj_file->Dump(&strm);
+//        }
+//        lldb_private::SymbolVendor *jit_sym_vendor = jit_module_sp->GetSymbolVendor();
+//        if (jit_sym_vendor)
+//        {
+//            lldb_private::SymbolContextList sc_list;
+//            jit_sym_vendor->FindFunctions(const_func_name, NULL, lldb::eFunctionNameTypeFull, true, false, sc_list);
+//            sc_list.Dump(&strm, target);
+//            jit_sym_vendor->Dump(&strm);
+//        }
+    }
+    
     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.
         
     if (jit_error.Success())
@@ -667,7 +713,7 @@
             
             IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
             
-            m_materialized_address = m_execution_unit_ap->Malloc(m_materializer_ap->GetStructByteSize(),
+            m_materialized_address = m_execution_unit_sp->Malloc(m_materializer_ap->GetStructByteSize(),
                                                                  m_materializer_ap->GetStructAlignment(),
                                                                  lldb::ePermissionsReadable | lldb::ePermissionsWritable,
                                                                  policy,
@@ -688,7 +734,7 @@
 
             const size_t stack_frame_size = 512 * 1024;
             
-            m_stack_frame_bottom = m_execution_unit_ap->Malloc(stack_frame_size,
+            m_stack_frame_bottom = m_execution_unit_sp->Malloc(stack_frame_size,
                                                                8,
                                                                lldb::ePermissionsReadable | lldb::ePermissionsWritable,
                                                                IRMemoryMap::eAllocationPolicyHostOnly,
@@ -705,7 +751,7 @@
                 
         Error materialize_error;
         
-        m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_ap, struct_address, materialize_error);
+        m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_sp, struct_address, materialize_error);
         
         if (!materialize_error.Success())
         {
@@ -781,8 +827,8 @@
         
         if (m_can_interpret)
         {            
-            llvm::Module *module = m_execution_unit_ap->GetModule();
-            llvm::Function *function = m_execution_unit_ap->GetFunction();
+            llvm::Module *module = m_execution_unit_sp->GetModule();
+            llvm::Function *function = m_execution_unit_sp->GetFunction();
             
             if (!module || !function)
             {
@@ -810,7 +856,7 @@
             IRInterpreter::Interpret (*module,
                                       *function,
                                       args,
-                                      *m_execution_unit_ap.get(),
+                                      *m_execution_unit_sp.get(),
                                       interpreter_error,
                                       function_stack_bottom,
                                       function_stack_top);
@@ -965,8 +1011,13 @@
         log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
     
     const bool keep_expression_in_memory = true;
+    const bool generate_debug_info = options.GetGenerateDebugInfo();
     
-    if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory))
+    if (!user_expression_sp->Parse (error_stream,
+                                    exe_ctx,
+                                    execution_policy,
+                                    keep_expression_in_memory,
+                                    generate_debug_info))
     {
         if (error_stream.GetString().empty())
             error.SetErrorString ("expression failed to parse, unknown error");