diff options
-rw-r--r-- | lldb/include/lldb/Expression/ClangExpression.h | 5 | ||||
-rw-r--r-- | lldb/include/lldb/Expression/IRForTarget.h | 41 | ||||
-rw-r--r-- | lldb/lldb.xcodeproj/project.pbxproj | 8 | ||||
-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 |
7 files changed, 207 insertions, 5 deletions
diff --git a/lldb/include/lldb/Expression/ClangExpression.h b/lldb/include/lldb/Expression/ClangExpression.h index 0ec707dfcec..67b885dae9c 100644 --- a/lldb/include/lldb/Expression/ClangExpression.h +++ b/lldb/include/lldb/Expression/ClangExpression.h @@ -62,9 +62,12 @@ public: ConvertExpressionToDWARF (ClangExpressionVariableList &expr_local_variable_list, StreamString &dwarf_opcode_strm); - unsigned + bool ConvertIRToDWARF (ClangExpressionVariableList &excpr_local_variable_list, StreamString &dwarf_opcode_strm); + + bool + PrepareIRForTarget (ClangExpressionVariableList &excpr_local_variable_list); bool JITFunction (const ExecutionContext &exc_context, const char *func_name); diff --git a/lldb/include/lldb/Expression/IRForTarget.h b/lldb/include/lldb/Expression/IRForTarget.h new file mode 100644 index 00000000000..8480a299f20 --- /dev/null +++ b/lldb/include/lldb/Expression/IRForTarget.h @@ -0,0 +1,41 @@ +//===-- IRForTarget.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_IRForTarget_h_ +#define liblldb_IRForTarget_h_ + +#include "llvm/Pass.h" +#include "llvm/PassManager.h" + +namespace llvm { + class BasicBlock; + class Module; +} + +namespace lldb_private { + class ClangExpressionDeclMap; +} + +class IRForTarget : public llvm::ModulePass +{ +public: + IRForTarget(const void *pid, + lldb_private::ClangExpressionDeclMap *decl_map); + ~IRForTarget(); + bool runOnModule(llvm::Module &M); + void assignPassManager(llvm::PMStack &PMS, + llvm::PassManagerType T = llvm::PMT_ModulePassManager); + llvm::PassManagerType getPotentialPassManagerType() const; +private: + bool runOnBasicBlock(llvm::BasicBlock &BB); + + lldb_private::ClangExpressionDeclMap *m_decl_map; +}; + +#endif
\ No newline at end of file diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 0e5dd80e4fe..6213902439c 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -328,6 +328,8 @@ 26F5C32D10F3DFDD009D5894 /* libtermcap.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C32B10F3DFDD009D5894 /* libtermcap.dylib */; }; 26F5C37510F3F61B009D5894 /* libobjc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C37410F3F61B009D5894 /* libobjc.dylib */; }; 26F5C39110F3FA26009D5894 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C39010F3FA26009D5894 /* CoreFoundation.framework */; }; + 49307AAE11DEA4D90081F992 /* IRForTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49307AAD11DEA4D90081F992 /* IRForTarget.cpp */; }; + 49307AB211DEA4F20081F992 /* IRForTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 49307AB111DEA4F20081F992 /* IRForTarget.h */; }; 49A8A3A011D568A300AD3B68 /* ClangResultSynthesizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */; }; 49A8A3A411D568BF00AD3B68 /* ClangResultSynthesizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */; }; 49D7072711B5AD03001AD875 /* ClangASTSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D7072611B5AD03001AD875 /* ClangASTSource.h */; }; @@ -890,6 +892,8 @@ 26F996A8119B79C300412154 /* ARM_GCC_Registers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ARM_GCC_Registers.h; path = source/Utility/ARM_GCC_Registers.h; sourceTree = "<group>"; }; 26FE25221146CADE00F4085A /* GDBRemoteCommunication.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GDBRemoteCommunication.cpp; path = "source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp"; sourceTree = "<group>"; }; 26FE25231146CADE00F4085A /* GDBRemoteCommunication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GDBRemoteCommunication.h; path = "source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h"; sourceTree = "<group>"; }; + 49307AAD11DEA4D90081F992 /* IRForTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRForTarget.cpp; path = source/Expression/IRForTarget.cpp; sourceTree = "<group>"; }; + 49307AB111DEA4F20081F992 /* IRForTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IRForTarget.h; path = include/lldb/Expression/IRForTarget.h; sourceTree = "<group>"; }; 493C63F01189203300914D5E /* ABISysV_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ABISysV_x86_64.h; path = "ABI/SysV-x86_64/ABISysV_x86_64.h"; sourceTree = "<group>"; }; 493C63F11189203300914D5E /* ABISysV_x86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ABISysV_x86_64.cpp; path = "ABI/SysV-x86_64/ABISysV_x86_64.cpp"; sourceTree = "<group>"; }; 495BBACB119A0DBE00418BEA /* PathMappingList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PathMappingList.cpp; path = source/Target/PathMappingList.cpp; sourceTree = "<group>"; }; @@ -1836,6 +1840,8 @@ 26BC7ED710F1B86700F91463 /* ClangStmtVisitor.cpp */, 26BC7DC310F1B79500F91463 /* DWARFExpression.h */, 26BC7ED810F1B86700F91463 /* DWARFExpression.cpp */, + 49307AB111DEA4F20081F992 /* IRForTarget.h */, + 49307AAD11DEA4D90081F992 /* IRForTarget.cpp */, 49DA743411DE6BB2006AEF7E /* IRToDWARF.h */, 49DA742F11DE6A5A006AEF7E /* IRToDWARF.cpp */, 4C98D3E1118FB98F00E575D0 /* RecordingMemoryManager.h */, @@ -2191,6 +2197,7 @@ 4C08CDEC11C81F1E001610A8 /* ThreadSpec.h in Headers */, 49A8A3A411D568BF00AD3B68 /* ClangResultSynthesizer.h in Headers */, 49DA743511DE6BB2006AEF7E /* IRToDWARF.h in Headers */, + 49307AB211DEA4F20081F992 /* IRForTarget.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2641,6 +2648,7 @@ 4C08CDE811C81EF8001610A8 /* ThreadSpec.cpp in Sources */, 49A8A3A011D568A300AD3B68 /* ClangResultSynthesizer.cpp in Sources */, 49DA743011DE6A5A006AEF7E /* IRToDWARF.cpp in Sources */, + 49307AAE11DEA4D90081F992 /* IRForTarget.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 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); } |