ClangFunctionCaller.cpp revision 341825
1//===-- ClangFunctionCaller.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 "ClangFunctionCaller.h" 11 12#include "ASTStructExtractor.h" 13#include "ClangExpressionParser.h" 14 15// C Includes 16// C++ Includes 17// Other libraries and framework includes 18#include "clang/AST/ASTContext.h" 19#include "clang/AST/RecordLayout.h" 20#include "clang/CodeGen/CodeGenAction.h" 21#include "clang/CodeGen/ModuleBuilder.h" 22#include "clang/Frontend/CompilerInstance.h" 23#include "llvm/ADT/StringRef.h" 24#include "llvm/ADT/Triple.h" 25#include "llvm/ExecutionEngine/ExecutionEngine.h" 26#include "llvm/IR/Module.h" 27 28// Project includes 29#include "lldb/Core/Module.h" 30#include "lldb/Core/State.h" 31#include "lldb/Core/ValueObject.h" 32#include "lldb/Core/ValueObjectList.h" 33#include "lldb/Expression/IRExecutionUnit.h" 34#include "lldb/Interpreter/CommandReturnObject.h" 35#include "lldb/Symbol/ClangASTContext.h" 36#include "lldb/Symbol/Function.h" 37#include "lldb/Symbol/Type.h" 38#include "lldb/Target/ExecutionContext.h" 39#include "lldb/Target/Process.h" 40#include "lldb/Target/RegisterContext.h" 41#include "lldb/Target/Target.h" 42#include "lldb/Target/Thread.h" 43#include "lldb/Target/ThreadPlan.h" 44#include "lldb/Target/ThreadPlanCallFunction.h" 45#include "lldb/Utility/DataExtractor.h" 46#include "lldb/Utility/Log.h" 47 48using namespace lldb_private; 49 50//---------------------------------------------------------------------- 51// ClangFunctionCaller constructor 52//---------------------------------------------------------------------- 53ClangFunctionCaller::ClangFunctionCaller(ExecutionContextScope &exe_scope, 54 const CompilerType &return_type, 55 const Address &functionAddress, 56 const ValueList &arg_value_list, 57 const char *name) 58 : FunctionCaller(exe_scope, return_type, functionAddress, arg_value_list, 59 name), 60 m_type_system_helper(*this) { 61 m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess()); 62 // Can't make a ClangFunctionCaller without a process. 63 assert(m_jit_process_wp.lock()); 64} 65 66//---------------------------------------------------------------------- 67// Destructor 68//---------------------------------------------------------------------- 69ClangFunctionCaller::~ClangFunctionCaller() {} 70 71unsigned 72 73ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp, 74 DiagnosticManager &diagnostic_manager) { 75 if (m_compiled) 76 return 0; 77 78 // Compilation might call code, make sure to keep on the thread the caller 79 // indicated. 80 ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher( 81 thread_to_use_sp); 82 83 // FIXME: How does clang tell us there's no return value? We need to handle 84 // that case. 85 unsigned num_errors = 0; 86 87 std::string return_type_str( 88 m_function_return_type.GetTypeName().AsCString("")); 89 90 // Cons up the function we're going to wrap our call in, then compile it... 91 // We declare the function "extern "C"" because the compiler might be in C++ 92 // mode which would mangle the name and then we couldn't find it again... 93 m_wrapper_function_text.clear(); 94 m_wrapper_function_text.append("extern \"C\" void "); 95 m_wrapper_function_text.append(m_wrapper_function_name); 96 m_wrapper_function_text.append(" (void *input)\n{\n struct "); 97 m_wrapper_function_text.append(m_wrapper_struct_name); 98 m_wrapper_function_text.append(" \n {\n"); 99 m_wrapper_function_text.append(" "); 100 m_wrapper_function_text.append(return_type_str); 101 m_wrapper_function_text.append(" (*fn_ptr) ("); 102 103 // Get the number of arguments. If we have a function type and it is 104 // prototyped, trust that, otherwise use the values we were given. 105 106 // FIXME: This will need to be extended to handle Variadic functions. We'll 107 // need 108 // to pull the defined arguments out of the function, then add the types from 109 // the arguments list for the variable arguments. 110 111 uint32_t num_args = UINT32_MAX; 112 bool trust_function = false; 113 // GetArgumentCount returns -1 for an unprototyped function. 114 CompilerType function_clang_type; 115 if (m_function_ptr) { 116 function_clang_type = m_function_ptr->GetCompilerType(); 117 if (function_clang_type) { 118 int num_func_args = function_clang_type.GetFunctionArgumentCount(); 119 if (num_func_args >= 0) { 120 trust_function = true; 121 num_args = num_func_args; 122 } 123 } 124 } 125 126 if (num_args == UINT32_MAX) 127 num_args = m_arg_values.GetSize(); 128 129 std::string args_buffer; // This one stores the definition of all the args in 130 // "struct caller". 131 std::string args_list_buffer; // This one stores the argument list called from 132 // the structure. 133 for (size_t i = 0; i < num_args; i++) { 134 std::string type_name; 135 136 if (trust_function) { 137 type_name = function_clang_type.GetFunctionArgumentTypeAtIndex(i) 138 .GetTypeName() 139 .AsCString(""); 140 } else { 141 CompilerType clang_qual_type = 142 m_arg_values.GetValueAtIndex(i)->GetCompilerType(); 143 if (clang_qual_type) { 144 type_name = clang_qual_type.GetTypeName().AsCString(""); 145 } else { 146 diagnostic_manager.Printf( 147 eDiagnosticSeverityError, 148 "Could not determine type of input value %" PRIu64 ".", 149 (uint64_t)i); 150 return 1; 151 } 152 } 153 154 m_wrapper_function_text.append(type_name); 155 if (i < num_args - 1) 156 m_wrapper_function_text.append(", "); 157 158 char arg_buf[32]; 159 args_buffer.append(" "); 160 args_buffer.append(type_name); 161 snprintf(arg_buf, 31, "arg_%" PRIu64, (uint64_t)i); 162 args_buffer.push_back(' '); 163 args_buffer.append(arg_buf); 164 args_buffer.append(";\n"); 165 166 args_list_buffer.append("__lldb_fn_data->"); 167 args_list_buffer.append(arg_buf); 168 if (i < num_args - 1) 169 args_list_buffer.append(", "); 170 } 171 m_wrapper_function_text.append( 172 ");\n"); // Close off the function calling prototype. 173 174 m_wrapper_function_text.append(args_buffer); 175 176 m_wrapper_function_text.append(" "); 177 m_wrapper_function_text.append(return_type_str); 178 m_wrapper_function_text.append(" return_value;"); 179 m_wrapper_function_text.append("\n };\n struct "); 180 m_wrapper_function_text.append(m_wrapper_struct_name); 181 m_wrapper_function_text.append("* __lldb_fn_data = (struct "); 182 m_wrapper_function_text.append(m_wrapper_struct_name); 183 m_wrapper_function_text.append(" *) input;\n"); 184 185 m_wrapper_function_text.append( 186 " __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr ("); 187 m_wrapper_function_text.append(args_list_buffer); 188 m_wrapper_function_text.append(");\n}\n"); 189 190 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 191 if (log) 192 log->Printf("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str()); 193 194 // Okay, now compile this expression 195 196 lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock()); 197 if (jit_process_sp) { 198 const bool generate_debug_info = true; 199 m_parser.reset(new ClangExpressionParser(jit_process_sp.get(), *this, 200 generate_debug_info)); 201 202 num_errors = m_parser->Parse(diagnostic_manager); 203 } else { 204 diagnostic_manager.PutString(eDiagnosticSeverityError, 205 "no process - unable to inject function"); 206 num_errors = 1; 207 } 208 209 m_compiled = (num_errors == 0); 210 211 if (!m_compiled) 212 return num_errors; 213 214 return num_errors; 215} 216 217clang::ASTConsumer * 218ClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer( 219 clang::ASTConsumer *passthrough) { 220 m_struct_extractor.reset(new ASTStructExtractor( 221 passthrough, m_owner.GetWrapperStructName(), m_owner)); 222 223 return m_struct_extractor.get(); 224} 225