Added the temporary -i option to expr, which

switches the expression parsing over to use the
LLVM IR as opposed to Clang ASTs.  Right now,
that functionality only logs.

llvm-svn: 106695
This commit is contained in:
Sean Callanan 2010-06-23 23:18:04 +00:00
parent f470747a36
commit 1d389c4b02
4 changed files with 90 additions and 9 deletions

View File

@ -57,6 +57,10 @@ public:
unsigned
ConvertExpressionToDWARF (ClangExpressionVariableList &expr_local_variable_list,
StreamString &dwarf_opcode_strm);
unsigned
ConvertIRToDWARF (ClangExpressionVariableList &excpr_local_variable_list,
StreamString &dwarf_opcode_strm);
bool
JITFunction (const ExecutionContext &exc_context, const char *func_name);

View File

@ -69,6 +69,10 @@ CommandObjectExpression::CommandOptions::SetOptionValue (int option_idx, const c
case 'f':
error = Args::StringToFormat(option_arg, format);
break;
case 'i':
use_ir = true;
break;
default:
error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
@ -87,6 +91,7 @@ CommandObjectExpression::CommandOptions::ResetOptionValues ()
format = eFormatDefault;
show_types = true;
show_summary = true;
use_ir = false;
}
const lldb::OptionDefinition*
@ -198,7 +203,6 @@ CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream
if (!target_triple)
target_triple = Host::GetTargetTriple ();
if (target_triple)
{
const bool show_types = m_options.show_types;
@ -221,9 +225,19 @@ CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream
dwarf_opcodes.SetByteOrder(eByteOrderHost);
dwarf_opcodes.GetFlags().Set(Stream::eBinary);
ClangExpressionVariableList expr_local_vars;
clang_expr.ConvertExpressionToDWARF (expr_local_vars, dwarf_opcodes);
success = true;
bool success;
if (m_options.use_ir)
success = (clang_expr.ConvertIRToDWARF (expr_local_vars, dwarf_opcodes) == 0);
else
success = (clang_expr.ConvertExpressionToDWARF (expr_local_vars, dwarf_opcodes) == 0);
if (!success)
{
output_stream << "Expression couldn't be translated to DWARF\n";
return false;
}
DataExtractor dwarf_opcodes_data(dwarf_opcodes.GetData(), dwarf_opcodes.GetSize(), eByteOrderHost, 8);
DWARFExpression expr(dwarf_opcodes_data, 0, dwarf_opcodes_data.GetByteSize(), NULL);
@ -431,7 +445,14 @@ CommandObjectExpression::ExecuteRawCommandString
dwarf_opcodes.SetByteOrder(eByteOrderHost);
dwarf_opcodes.GetFlags().Set(Stream::eBinary);
ClangExpressionVariableList expr_local_vars;
clang_expr.ConvertExpressionToDWARF (expr_local_vars, dwarf_opcodes);
bool success = true;
if (m_options.use_ir)
success = (clang_expr.ConvertIRToDWARF (expr_local_vars, dwarf_opcodes) == 0);
else
success = (clang_expr.ConvertExpressionToDWARF (expr_local_vars, dwarf_opcodes) == 0);
result.SetStatus (eReturnStatusSuccessFinishResult);
@ -439,6 +460,7 @@ CommandObjectExpression::ExecuteRawCommandString
DWARFExpression expr(dwarf_opcodes_data, 0, dwarf_opcodes_data.GetByteSize(), NULL);
expr.SetExpressionLocalVariableList(&expr_local_vars);
expr.SetExpressionDeclMap(&expr_decl_map);
if (debug)
{
output_stream << "Expression parsed ok, dwarf opcodes:";
@ -541,9 +563,10 @@ CommandObjectExpression::ExecuteRawCommandString
lldb::OptionDefinition
CommandObjectExpression::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_1, true, "language", 'l', required_argument, NULL, 0, "[c|c++|objc|objc++]", "Sets the language to use when parsing the expression."},
{ LLDB_OPT_SET_2, false, "format", 'f', required_argument, NULL, 0, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]", "Specify the format that the expression output should use."},
{ LLDB_OPT_SET_3, false, "debug", 'g', no_argument, NULL, 0, NULL, "Enable verbose debug logging of the expression parsing and evaluation."},
{ LLDB_OPT_SET_ALL, true, "language", 'l', required_argument, NULL, 0, "[c|c++|objc|objc++]", "Sets the language to use when parsing the expression."},
{ LLDB_OPT_SET_ALL, false, "format", 'f', required_argument, NULL, 0, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]", "Specify the format that the expression output should use."},
{ LLDB_OPT_SET_ALL, false, "debug", 'g', no_argument, NULL, 0, NULL, "Enable verbose debug logging of the expression parsing and evaluation."},
{ LLDB_OPT_SET_ALL, false, "use-ir", 'i', no_argument, NULL, 0, NULL, "[Temporary] Instructs the expression evaluator to use IR instead of ASTs."},
{ 0, false, NULL, 0, 0, NULL, NULL, NULL, NULL }
};

View File

@ -52,6 +52,7 @@ public:
bool debug;
bool show_types;
bool show_summary;
bool use_ir;
};
CommandObjectExpression ();

View File

@ -50,6 +50,7 @@
#include "llvm/Target/TargetSelect.h"
// Project includes
#include "lldb/Core/Log.h"
#include "lldb/Expression/ClangExpression.h"
#include "lldb/Expression/ClangASTSource.h"
#include "lldb/Expression/ClangStmtVisitor.h"
@ -354,7 +355,7 @@ ClangExpression::ParseBareExpression (llvm::StringRef expr_text, Stream &stream)
// - Call clang::ParseAST (in lib/Sema/ParseAST.cpp) to parse the buffer. The CodeGenerator will generate code for __dbg_expr.
// - Once ParseAST completes, you can grab the llvm::Module from the CodeGenerator, which will have an llvm::Function you can hand off to the JIT.
ParseAST(m_clang_ap->getPreprocessor(), m_code_generator_ptr, m_clang_ap->getASTContext());
text_diagnostic_buffer.EndSourceFile();
//compiler_instance->getASTContext().getTranslationUnitDecl()->dump();
@ -454,6 +455,58 @@ ClangExpression::ConvertExpressionToDWARF (ClangExpressionVariableList& expr_loc
return 0;
}
unsigned
ClangExpression::ConvertIRToDWARF (ClangExpressionVariableList &excpr_local_variable_list,
StreamString &dwarf_opcode_strm)
{
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;
}
llvm::Module::iterator fi;
for (fi = module->begin();
fi != module->end();
++fi)
{
llvm::Function &function = *fi;
if (log)
log->Printf("IR for %s:", function.getName().str().c_str());
llvm::Function::iterator bbi;
for (bbi = function.begin();
bbi != function.end();
++bbi)
{
llvm::BasicBlock &bb = *bbi;
llvm::BasicBlock::iterator ii;
for (ii = bb.begin();
ii != bb.end();
++ii)
{
llvm::Instruction &inst = *ii;
if (log)
log->Printf(" %s", inst.getOpcodeName());
}
}
}
return 0;
}
bool
ClangExpression::JITFunction (const ExecutionContext &exc_context, const char *name)
{