diff options
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/Commands/CommandObjectExpression.cpp | 20 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpression.cpp | 23 | ||||
-rw-r--r-- | lldb/source/Expression/IRForTarget.cpp | 109 | ||||
-rw-r--r-- | lldb/source/Expression/IRToDWARF.cpp | 6 |
4 files changed, 154 insertions, 4 deletions
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index 64106eda2d0..37659f5e697 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -252,11 +252,29 @@ CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream ClangExpressionVariableList expr_local_vars; bool success; + bool canInterpret = false; if (m_options.use_ir) - success = (clang_expr.ConvertIRToDWARF (expr_local_vars, dwarf_opcodes) == 0); + { + canInterpret = clang_expr.ConvertIRToDWARF (expr_local_vars, dwarf_opcodes); + + if (canInterpret) + { + if (log) + log->Printf("Code can be interpreted."); + success = true; + } + else + { + if (log) + log->Printf("Code cannot be interpreted and must be run in the target."); + success = clang_expr.PrepareIRForTarget (expr_local_vars); + } + } else + { success = (clang_expr.ConvertExpressionToDWARF (expr_local_vars, dwarf_opcodes) == 0); + } if (!success) { diff --git a/lldb/source/Expression/ClangExpression.cpp b/lldb/source/Expression/ClangExpression.cpp index 6922ac4acec..a3a58b69a14 100644 --- a/lldb/source/Expression/ClangExpression.cpp +++ b/lldb/source/Expression/ClangExpression.cpp @@ -58,6 +58,7 @@ #include "lldb/Expression/ClangASTSource.h" #include "lldb/Expression/ClangResultSynthesizer.h" #include "lldb/Expression/ClangStmtVisitor.h" +#include "lldb/Expression/IRForTarget.h" #include "lldb/Expression/IRToDWARF.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Expression/RecordingMemoryManager.h" @@ -474,7 +475,7 @@ ClangExpression::ConvertExpressionToDWARF (ClangExpressionVariableList& expr_loc return 0; } -unsigned +bool ClangExpression::ConvertIRToDWARF (ClangExpressionVariableList &expr_local_variable_list, StreamString &dwarf_opcode_strm) { @@ -496,6 +497,26 @@ ClangExpression::ConvertIRToDWARF (ClangExpressionVariableList &expr_local_varia } bool +ClangExpression::PrepareIRForTarget (ClangExpressionVariableList &expr_local_variable_list) +{ + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + + llvm::Module *module = m_code_generator_ptr->GetModule(); + + if (!module) + { + if (log) + log->Printf("IR doesn't contain a module"); + + return 1; + } + + IRForTarget ir_for_target("IR for target", m_decl_map); + + return ir_for_target.runOnModule(*module); +} + +bool ClangExpression::JITFunction (const ExecutionContext &exc_context, const char *name) { diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp new file mode 100644 index 00000000000..a6b50e59127 --- /dev/null +++ b/lldb/source/Expression/IRForTarget.cpp @@ -0,0 +1,109 @@ +//===-- IRForTarget.cpp -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Expression/IRForTarget.h" + +#include "llvm/Support/raw_ostream.h" +#include "llvm/InstrTypes.h" +#include "llvm/Module.h" + +#include "lldb/Core/dwarf.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Scalar.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Expression/ClangExpressionDeclMap.h" + +#include <map> + +using namespace llvm; + +IRForTarget::IRForTarget(const void *pid, + lldb_private::ClangExpressionDeclMap *decl_map) : + ModulePass(pid), + m_decl_map(decl_map) +{ +} + +IRForTarget::~IRForTarget() +{ +} + +bool +IRForTarget::runOnBasicBlock(BasicBlock &BB) +{ + lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + + ///////////////////////////////////////////////////////////////////////// + // Prepare the current basic block for execution in the remote process + // + + if (log) + { + log->Printf("Preparing basic block %s:", + BB.hasName() ? BB.getNameStr().c_str() : "[anonymous]"); + + llvm::BasicBlock::iterator ii; + + for (ii = BB.begin(); + ii != BB.end(); + ++ii) + { + llvm::Instruction &inst = *ii; + + std::string s; + raw_string_ostream os(s); + + inst.print(os); + + if (log) + log->Printf(" %s", s.c_str()); + } + } + + return true; +} + +bool +IRForTarget::runOnModule(Module &M) +{ + lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + + llvm::Function* function = M.getFunction(StringRef("___clang_expr")); + + if (!function) + { + if (log) + log->Printf("Couldn't find ___clang_expr() in the module"); + + return false; + } + + llvm::Function::iterator bbi; + + for (bbi = function->begin(); + bbi != function->end(); + ++bbi) + { + runOnBasicBlock(*bbi); + } + + return true; +} + +void +IRForTarget::assignPassManager(PMStack &PMS, + PassManagerType T) +{ +} + +PassManagerType +IRForTarget::getPotentialPassManagerType() const +{ + return PMT_ModulePassManager; +} diff --git a/lldb/source/Expression/IRToDWARF.cpp b/lldb/source/Expression/IRToDWARF.cpp index 0cca9aa136a..af6d1b17b4c 100644 --- a/lldb/source/Expression/IRToDWARF.cpp +++ b/lldb/source/Expression/IRToDWARF.cpp @@ -207,9 +207,11 @@ IRToDWARF::runOnModule(Module &M) Relocator relocator; - llvm::BasicBlock ¤tBB = function->getEntryBlock(); + if (!runOnBasicBlock(function->getEntryBlock(), relocator)) + return false; - runOnBasicBlock(currentBB, relocator); + // TEMPORARY: Fail in order to force execution in the target. + return false; return relocator.ResolveRelocations(m_strm); } |