]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
Merge lldb trunk r321017 to contrib/llvm/tools/lldb.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / ExpressionParser / Clang / ClangUtilityFunction.cpp
1 //===-- ClangUtilityFunction.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 #include "ClangUtilityFunction.h"
11 #include "ClangExpressionDeclMap.h"
12 #include "ClangExpressionParser.h"
13
14 // C Includes
15 #include <stdio.h>
16 #if HAVE_SYS_TYPES_H
17 #include <sys/types.h>
18 #endif
19
20 // C++ Includes
21
22 #include "lldb/Core/Module.h"
23 #include "lldb/Core/StreamFile.h"
24 #include "lldb/Expression/ExpressionSourceCode.h"
25 #include "lldb/Expression/IRExecutionUnit.h"
26 #include "lldb/Host/Host.h"
27 #include "lldb/Target/ExecutionContext.h"
28 #include "lldb/Target/Target.h"
29 #include "lldb/Utility/ConstString.h"
30 #include "lldb/Utility/Log.h"
31 #include "lldb/Utility/Stream.h"
32
33 using namespace lldb_private;
34
35 //------------------------------------------------------------------
36 /// Constructor
37 ///
38 /// @param[in] text
39 ///     The text of the function.  Must be a full translation unit.
40 ///
41 /// @param[in] name
42 ///     The name of the function, as used in the text.
43 //------------------------------------------------------------------
44 ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope,
45                                            const char *text, const char *name)
46     : UtilityFunction(exe_scope, text, name) {}
47
48 ClangUtilityFunction::~ClangUtilityFunction() {}
49
50 //------------------------------------------------------------------
51 /// Install the utility function into a process
52 ///
53 /// @param[in] diagnostic_manager
54 ///     A diagnostic manager to report errors and warnings to.
55 ///
56 /// @param[in] exe_ctx
57 ///     The execution context to install the utility function to.
58 ///
59 /// @return
60 ///     True on success (no errors); false otherwise.
61 //------------------------------------------------------------------
62 bool ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager,
63                                    ExecutionContext &exe_ctx) {
64   if (m_jit_start_addr != LLDB_INVALID_ADDRESS) {
65     diagnostic_manager.PutString(eDiagnosticSeverityWarning,
66                                  "already installed");
67     return false;
68   }
69
70   ////////////////////////////////////
71   // Set up the target and compiler
72   //
73
74   Target *target = exe_ctx.GetTargetPtr();
75
76   if (!target) {
77     diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid target");
78     return false;
79   }
80
81   Process *process = exe_ctx.GetProcessPtr();
82
83   if (!process) {
84     diagnostic_manager.PutString(eDiagnosticSeverityError, "invalid process");
85     return false;
86   }
87
88   //////////////////////////
89   // Parse the expression
90   //
91
92   bool keep_result_in_memory = false;
93
94   ResetDeclMap(exe_ctx, keep_result_in_memory);
95
96   if (!DeclMap()->WillParse(exe_ctx, NULL)) {
97     diagnostic_manager.PutString(
98         eDiagnosticSeverityError,
99         "current process state is unsuitable for expression parsing");
100     return false;
101   }
102
103   const bool generate_debug_info = true;
104   ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this,
105                                generate_debug_info);
106
107   unsigned num_errors = parser.Parse(diagnostic_manager);
108
109   if (num_errors) {
110     ResetDeclMap();
111
112     return false;
113   }
114
115   //////////////////////////////////
116   // JIT the output of the parser
117   //
118
119   bool can_interpret = false; // should stay that way
120
121   Status jit_error = parser.PrepareForExecution(
122       m_jit_start_addr, m_jit_end_addr, m_execution_unit_sp, exe_ctx,
123       can_interpret, eExecutionPolicyAlways);
124
125   if (m_jit_start_addr != LLDB_INVALID_ADDRESS) {
126     m_jit_process_wp = process->shared_from_this();
127     if (parser.GetGenerateDebugInfo()) {
128       lldb::ModuleSP jit_module_sp(m_execution_unit_sp->GetJITModule());
129
130       if (jit_module_sp) {
131         ConstString const_func_name(FunctionName());
132         FileSpec jit_file;
133         jit_file.GetFilename() = const_func_name;
134         jit_module_sp->SetFileSpecAndObjectName(jit_file, ConstString());
135         m_jit_module_wp = jit_module_sp;
136         target->GetImages().Append(jit_module_sp);
137       }
138     }
139   }
140
141   DeclMap()->DidParse();
142
143   ResetDeclMap();
144
145   if (jit_error.Success()) {
146     return true;
147   } else {
148     const char *error_cstr = jit_error.AsCString();
149     if (error_cstr && error_cstr[0]) {
150       diagnostic_manager.Printf(eDiagnosticSeverityError, "%s", error_cstr);
151     } else {
152       diagnostic_manager.PutString(eDiagnosticSeverityError,
153                                    "expression can't be interpreted or run");
154     }
155     return false;
156   }
157 }
158
159 void ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap(
160     ExecutionContext &exe_ctx, bool keep_result_in_memory) {
161   m_expr_decl_map_up.reset(
162       new ClangExpressionDeclMap(keep_result_in_memory, nullptr, exe_ctx));
163 }