ClangFunctionCaller.cpp revision 309124
1292932Sdim//===-- ClangFunctionCallerCaller.cpp ---------------------------*- C++ -*-===// 2292932Sdim// 3292932Sdim// The LLVM Compiler Infrastructure 4292932Sdim// 5292932Sdim// This file is distributed under the University of Illinois Open Source 6292932Sdim// License. See LICENSE.TXT for details. 7292932Sdim// 8292932Sdim//===----------------------------------------------------------------------===// 9292932Sdim 10292932Sdim#include "ClangFunctionCaller.h" 11292932Sdim 12292932Sdim#include "ASTStructExtractor.h" 13292932Sdim#include "ClangExpressionParser.h" 14292932Sdim 15292932Sdim// C Includes 16292932Sdim// C++ Includes 17292932Sdim// Other libraries and framework includes 18292932Sdim#include "clang/AST/ASTContext.h" 19292932Sdim#include "clang/AST/RecordLayout.h" 20292932Sdim#include "clang/CodeGen/CodeGenAction.h" 21292932Sdim#include "clang/CodeGen/ModuleBuilder.h" 22292932Sdim#include "clang/Frontend/CompilerInstance.h" 23292932Sdim#include "llvm/ADT/StringRef.h" 24292932Sdim#include "llvm/ADT/Triple.h" 25292932Sdim#include "llvm/ExecutionEngine/ExecutionEngine.h" 26292932Sdim#include "llvm/IR/Module.h" 27292932Sdim 28292932Sdim// Project includes 29292932Sdim#include "lldb/Core/DataExtractor.h" 30292932Sdim#include "lldb/Core/Log.h" 31292932Sdim#include "lldb/Core/Module.h" 32292932Sdim#include "lldb/Core/State.h" 33292932Sdim#include "lldb/Core/ValueObject.h" 34292932Sdim#include "lldb/Core/ValueObjectList.h" 35292932Sdim#include "lldb/Expression/IRExecutionUnit.h" 36292932Sdim#include "lldb/Interpreter/CommandReturnObject.h" 37292932Sdim#include "lldb/Symbol/ClangASTContext.h" 38292932Sdim#include "lldb/Symbol/Function.h" 39292932Sdim#include "lldb/Symbol/Type.h" 40292932Sdim#include "lldb/Target/ExecutionContext.h" 41292932Sdim#include "lldb/Target/Process.h" 42292932Sdim#include "lldb/Target/RegisterContext.h" 43292932Sdim#include "lldb/Target/Target.h" 44292932Sdim#include "lldb/Target/Thread.h" 45292932Sdim#include "lldb/Target/ThreadPlan.h" 46292932Sdim#include "lldb/Target/ThreadPlanCallFunction.h" 47292932Sdim 48292932Sdimusing namespace lldb_private; 49292932Sdim 50292932Sdim//---------------------------------------------------------------------- 51292932Sdim// ClangFunctionCaller constructor 52292932Sdim//---------------------------------------------------------------------- 53292932SdimClangFunctionCaller::ClangFunctionCaller 54292932Sdim( 55292932Sdim ExecutionContextScope &exe_scope, 56292932Sdim const CompilerType &return_type, 57292932Sdim const Address& functionAddress, 58292932Sdim const ValueList &arg_value_list, 59292932Sdim const char *name 60292932Sdim) : 61292932Sdim FunctionCaller(exe_scope, return_type, functionAddress, arg_value_list, name), 62292932Sdim m_type_system_helper (*this) 63292932Sdim{ 64292932Sdim m_jit_process_wp = lldb::ProcessWP(exe_scope.CalculateProcess()); 65292932Sdim // Can't make a ClangFunctionCaller without a process. 66292932Sdim assert (m_jit_process_wp.lock()); 67292932Sdim} 68292932Sdim 69292932Sdim//---------------------------------------------------------------------- 70292932Sdim// Destructor 71292932Sdim//---------------------------------------------------------------------- 72292932SdimClangFunctionCaller::~ClangFunctionCaller() 73292932Sdim{ 74292932Sdim} 75292932Sdim 76292932Sdimunsigned 77309124Sdim 78309124SdimClangFunctionCaller::CompileFunction (lldb::ThreadSP thread_to_use_sp, 79309124Sdim DiagnosticManager &diagnostic_manager) 80292932Sdim{ 81292932Sdim if (m_compiled) 82292932Sdim return 0; 83309124Sdim 84309124Sdim // Compilation might call code, make sure to keep on the thread the caller indicated. 85309124Sdim ThreadList::ExpressionExecutionThreadPusher execution_thread_pusher(thread_to_use_sp); 86292932Sdim 87292932Sdim // FIXME: How does clang tell us there's no return value? We need to handle that case. 88292932Sdim unsigned num_errors = 0; 89292932Sdim 90292932Sdim std::string return_type_str (m_function_return_type.GetTypeName().AsCString("")); 91292932Sdim 92292932Sdim // Cons up the function we're going to wrap our call in, then compile it... 93292932Sdim // We declare the function "extern "C"" because the compiler might be in C++ 94292932Sdim // mode which would mangle the name and then we couldn't find it again... 95292932Sdim m_wrapper_function_text.clear(); 96292932Sdim m_wrapper_function_text.append ("extern \"C\" void "); 97292932Sdim m_wrapper_function_text.append (m_wrapper_function_name); 98292932Sdim m_wrapper_function_text.append (" (void *input)\n{\n struct "); 99292932Sdim m_wrapper_function_text.append (m_wrapper_struct_name); 100292932Sdim m_wrapper_function_text.append (" \n {\n"); 101292932Sdim m_wrapper_function_text.append (" "); 102292932Sdim m_wrapper_function_text.append (return_type_str); 103292932Sdim m_wrapper_function_text.append (" (*fn_ptr) ("); 104292932Sdim 105292932Sdim // Get the number of arguments. If we have a function type and it is prototyped, 106292932Sdim // trust that, otherwise use the values we were given. 107292932Sdim 108292932Sdim // FIXME: This will need to be extended to handle Variadic functions. We'll need 109292932Sdim // to pull the defined arguments out of the function, then add the types from the 110292932Sdim // arguments list for the variable arguments. 111292932Sdim 112292932Sdim uint32_t num_args = UINT32_MAX; 113292932Sdim bool trust_function = false; 114292932Sdim // GetArgumentCount returns -1 for an unprototyped function. 115292932Sdim CompilerType function_clang_type; 116292932Sdim if (m_function_ptr) 117292932Sdim { 118292932Sdim function_clang_type = m_function_ptr->GetCompilerType(); 119292932Sdim if (function_clang_type) 120292932Sdim { 121292932Sdim int num_func_args = function_clang_type.GetFunctionArgumentCount(); 122292932Sdim if (num_func_args >= 0) 123292932Sdim { 124292932Sdim trust_function = true; 125292932Sdim num_args = num_func_args; 126292932Sdim } 127292932Sdim } 128292932Sdim } 129292932Sdim 130292932Sdim if (num_args == UINT32_MAX) 131292932Sdim num_args = m_arg_values.GetSize(); 132292932Sdim 133292932Sdim std::string args_buffer; // This one stores the definition of all the args in "struct caller". 134292932Sdim std::string args_list_buffer; // This one stores the argument list called from the structure. 135292932Sdim for (size_t i = 0; i < num_args; i++) 136292932Sdim { 137292932Sdim std::string type_name; 138292932Sdim 139292932Sdim if (trust_function) 140292932Sdim { 141292932Sdim type_name = function_clang_type.GetFunctionArgumentTypeAtIndex(i).GetTypeName().AsCString(""); 142292932Sdim } 143292932Sdim else 144292932Sdim { 145292932Sdim CompilerType clang_qual_type = m_arg_values.GetValueAtIndex(i)->GetCompilerType (); 146292932Sdim if (clang_qual_type) 147292932Sdim { 148292932Sdim type_name = clang_qual_type.GetTypeName().AsCString(""); 149292932Sdim } 150292932Sdim else 151309124Sdim { 152309124Sdim diagnostic_manager.Printf(eDiagnosticSeverityError, 153309124Sdim "Could not determine type of input value %" PRIu64 ".", (uint64_t)i); 154292932Sdim return 1; 155292932Sdim } 156292932Sdim } 157292932Sdim 158292932Sdim m_wrapper_function_text.append (type_name); 159292932Sdim if (i < num_args - 1) 160292932Sdim m_wrapper_function_text.append (", "); 161292932Sdim 162292932Sdim char arg_buf[32]; 163292932Sdim args_buffer.append (" "); 164292932Sdim args_buffer.append (type_name); 165292932Sdim snprintf(arg_buf, 31, "arg_%" PRIu64, (uint64_t)i); 166292932Sdim args_buffer.push_back (' '); 167292932Sdim args_buffer.append (arg_buf); 168292932Sdim args_buffer.append (";\n"); 169292932Sdim 170292932Sdim args_list_buffer.append ("__lldb_fn_data->"); 171292932Sdim args_list_buffer.append (arg_buf); 172292932Sdim if (i < num_args - 1) 173292932Sdim args_list_buffer.append (", "); 174292932Sdim 175292932Sdim } 176292932Sdim m_wrapper_function_text.append (");\n"); // Close off the function calling prototype. 177292932Sdim 178292932Sdim m_wrapper_function_text.append (args_buffer); 179292932Sdim 180292932Sdim m_wrapper_function_text.append (" "); 181292932Sdim m_wrapper_function_text.append (return_type_str); 182292932Sdim m_wrapper_function_text.append (" return_value;"); 183292932Sdim m_wrapper_function_text.append ("\n };\n struct "); 184292932Sdim m_wrapper_function_text.append (m_wrapper_struct_name); 185292932Sdim m_wrapper_function_text.append ("* __lldb_fn_data = (struct "); 186292932Sdim m_wrapper_function_text.append (m_wrapper_struct_name); 187292932Sdim m_wrapper_function_text.append (" *) input;\n"); 188292932Sdim 189292932Sdim m_wrapper_function_text.append (" __lldb_fn_data->return_value = __lldb_fn_data->fn_ptr ("); 190292932Sdim m_wrapper_function_text.append (args_list_buffer); 191292932Sdim m_wrapper_function_text.append (");\n}\n"); 192292932Sdim 193292932Sdim Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 194292932Sdim if (log) 195292932Sdim log->Printf ("Expression: \n\n%s\n\n", m_wrapper_function_text.c_str()); 196292932Sdim 197292932Sdim // Okay, now compile this expression 198292932Sdim 199292932Sdim lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock()); 200292932Sdim if (jit_process_sp) 201292932Sdim { 202292932Sdim const bool generate_debug_info = true; 203292932Sdim m_parser.reset(new ClangExpressionParser(jit_process_sp.get(), *this, generate_debug_info)); 204309124Sdim 205309124Sdim num_errors = m_parser->Parse(diagnostic_manager); 206292932Sdim } 207292932Sdim else 208292932Sdim { 209309124Sdim diagnostic_manager.PutCString(eDiagnosticSeverityError, "no process - unable to inject function"); 210292932Sdim num_errors = 1; 211292932Sdim } 212309124Sdim 213292932Sdim m_compiled = (num_errors == 0); 214292932Sdim 215292932Sdim if (!m_compiled) 216292932Sdim return num_errors; 217292932Sdim 218292932Sdim return num_errors; 219292932Sdim} 220292932Sdim 221292932Sdimclang::ASTConsumer * 222292932SdimClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer (clang::ASTConsumer *passthrough) 223292932Sdim{ 224292932Sdim m_struct_extractor.reset(new ASTStructExtractor(passthrough, m_owner.GetWrapperStructName(), m_owner)); 225292932Sdim 226292932Sdim return m_struct_extractor.get(); 227292932Sdim} 228