]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Expression/ClangUtilityFunction.cpp
Update LLDB snapshot to upstream r225923 (git 2b588ecd)
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Expression / ClangUtilityFunction.cpp
1 //===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // C Includes
11 #include <stdio.h>
12 #if HAVE_SYS_TYPES_H
13 #  include <sys/types.h>
14 #endif
15
16 // C++ Includes
17
18 #include "lldb/Core/ConstString.h"
19 #include "lldb/Core/Log.h"
20 #include "lldb/Core/Module.h"
21 #include "lldb/Core/Stream.h"
22 #include "lldb/Core/StreamFile.h"
23 #include "lldb/Expression/ClangExpressionDeclMap.h"
24 #include "lldb/Expression/ClangExpressionParser.h"
25 #include "lldb/Expression/ClangUtilityFunction.h"
26 #include "lldb/Expression/ExpressionSourceCode.h"
27 #include "lldb/Expression/IRExecutionUnit.h"
28 #include "lldb/Host/Host.h"
29 #include "lldb/Target/ExecutionContext.h"
30 #include "lldb/Target/Target.h"
31
32 using namespace lldb_private;
33
34 //------------------------------------------------------------------
35 /// Constructor
36 ///
37 /// @param[in] text
38 ///     The text of the function.  Must be a full translation unit.
39 ///
40 /// @param[in] name
41 ///     The name of the function, as used in the text.
42 //------------------------------------------------------------------
43 ClangUtilityFunction::ClangUtilityFunction (const char *text, 
44                                             const char *name) :
45     ClangExpression (),
46     m_expr_decl_map (),
47     m_execution_unit_sp (),
48     m_jit_module_wp (),
49     m_function_text (ExpressionSourceCode::g_expression_prefix),
50     m_function_name (name)
51 {
52     if (text && text[0])
53         m_function_text.append (text);
54 }
55
56 ClangUtilityFunction::~ClangUtilityFunction ()
57 {
58     lldb::ProcessSP process_sp (m_jit_process_wp.lock());
59     if (process_sp)
60     {
61         lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock());
62         if (jit_module_sp)
63             process_sp->GetTarget().GetImages().Remove(jit_module_sp);
64     }
65     
66 }
67
68 //------------------------------------------------------------------
69 /// Install the utility function into a process
70 ///
71 /// @param[in] error_stream
72 ///     A stream to print parse errors and warnings to.
73 ///
74 /// @param[in] exe_ctx
75 ///     The execution context to install the utility function to.
76 ///
77 /// @return
78 ///     True on success (no errors); false otherwise.
79 //------------------------------------------------------------------
80 bool
81 ClangUtilityFunction::Install (Stream &error_stream,
82                                ExecutionContext &exe_ctx)
83 {
84     if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
85     {
86         error_stream.PutCString("error: already installed\n");
87         return false;
88     }
89     
90     ////////////////////////////////////
91     // Set up the target and compiler
92     //
93     
94     Target *target = exe_ctx.GetTargetPtr();
95     
96     if (!target)
97     {
98         error_stream.PutCString ("error: invalid target\n");
99         return false;
100     }
101     
102     Process *process = exe_ctx.GetProcessPtr();
103     
104     if (!process)
105     {
106         error_stream.PutCString ("error: invalid process\n");
107         return false;
108     }
109         
110     //////////////////////////
111     // Parse the expression
112     //
113     
114     bool keep_result_in_memory = false;
115     
116     m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
117     
118     if (!m_expr_decl_map->WillParse(exe_ctx, NULL))
119     {
120         error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
121         return false;
122     }
123     
124     const bool generate_debug_info = true;
125     ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this, generate_debug_info);
126     
127     unsigned num_errors = parser.Parse (error_stream);
128     
129     if (num_errors)
130     {
131         error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
132         
133         m_expr_decl_map.reset();
134         
135         return false;
136     }
137     
138     //////////////////////////////////
139     // JIT the output of the parser
140     //
141         
142     bool can_interpret = false; // should stay that way
143     
144     Error jit_error = parser.PrepareForExecution (m_jit_start_addr, 
145                                                   m_jit_end_addr,
146                                                   m_execution_unit_sp,
147                                                   exe_ctx,
148                                                   can_interpret,
149                                                   eExecutionPolicyAlways);
150     
151     if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
152     {
153         m_jit_process_wp = process->shared_from_this();
154         if (parser.GetGenerateDebugInfo())
155         {
156             lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule());
157             
158             if (jit_module_sp)
159             {
160                 ConstString const_func_name(FunctionName());
161                 FileSpec jit_file;
162                 jit_file.GetFilename() = const_func_name;
163                 jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString());
164                 m_jit_module_wp = jit_module_sp;
165                 target->GetImages().Append(jit_module_sp);
166             }
167         }
168     }
169     
170 #if 0
171         // jingham: look here
172     StreamFile logfile ("/tmp/exprs.txt", "a");
173     logfile.Printf ("0x%16.16" PRIx64 ": func = %s, source =\n%s\n",
174                     m_jit_start_addr, 
175                     m_function_name.c_str(), 
176                     m_function_text.c_str());
177 #endif
178
179     m_expr_decl_map->DidParse();
180     
181     m_expr_decl_map.reset();
182     
183     if (jit_error.Success())
184     {
185         return true;
186     }
187     else
188     {
189         const char *error_cstr = jit_error.AsCString();
190         if (error_cstr && error_cstr[0])
191             error_stream.Printf ("error: %s\n", error_cstr);
192         else
193             error_stream.Printf ("error: expression can't be interpreted or run\n");
194         return false;
195     }
196 }
197
198