Removed the hacky "#define this ___clang_this" handler
for C++ classes. Replaced it with a less hacky approach:
- If an expression is defined in the context of a
method of class A, then that expression is wrapped as
___clang_class::___clang_expr(void*) { ... }
instead of ___clang_expr(void*) { ... }.
- ___clang_class is resolved as the type of the target
of the "this" pointer in the method the expression
is defined in.
- When reporting the type of ___clang_class, a method
with the signature ___clang_expr(void*) is added to
that class, so that Clang doesn't complain about a
method being defined without a corresponding
declaration.
- Whenever the expression gets called, "this" gets
looked up, type-checked, and then passed in as the
first argument.
This required the following changes:
- The ABIs were changed to support passing of the "this"
pointer as part of trivial calls.
- ThreadPlanCallFunction and ClangFunction were changed
to support passing of an optional "this" pointer.
- ClangUserExpression was extended to perform the
wrapping described above.
- ClangASTSource was changed to revert the changes
required by the hack.
- ClangExpressionParser, IRForTarget, and
ClangExpressionDeclMap were changed to handle
different manglings of ___clang_expr flexibly. This
meant no longer searching for a function called
___clang_expr, but rather looking for a function whose
name *contains* ___clang_expr.
- ClangExpressionParser and ClangExpressionDeclMap now
remember whether "this" is required, and know how to
look it up as necessary.
A few inheritance bugs remain, and I'm trying to resolve
these. But it is now possible to use "this" as well as
refer implicitly to member variables, when in the proper
context.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@114384 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangExpressionParser.cpp b/source/Expression/ClangExpressionParser.cpp
index f8b71ed..9059806 100644
--- a/source/Expression/ClangExpressionParser.cpp
+++ b/source/Expression/ClangExpressionParser.cpp
@@ -326,6 +326,24 @@
return num_errors;
}
+static bool FindFunctionInModule (std::string &mangled_name,
+ llvm::Module *module,
+ const char *orig_name)
+{
+ for (llvm::Module::iterator fi = module->getFunctionList().begin(), fe = module->getFunctionList().end();
+ fi != fe;
+ ++fi)
+ {
+ if (fi->getName().str().find(orig_name) != std::string::npos)
+ {
+ mangled_name = fi->getName().str();
+ return true;
+ }
+ }
+
+ return false;
+}
+
Error
ClangExpressionParser::MakeDWARF ()
{
@@ -357,7 +375,16 @@
return err;
}
- IRToDWARF ir_to_dwarf(*local_variables, decl_map, m_expr.DwarfOpcodeStream());
+ std::string function_name;
+
+ if (!FindFunctionInModule(function_name, module, m_expr.FunctionName()))
+ {
+ err.SetErrorToGenericError();
+ err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
+ return err;
+ }
+
+ IRToDWARF ir_to_dwarf(*local_variables, decl_map, m_expr.DwarfOpcodeStream(), function_name.c_str());
if (!ir_to_dwarf.runOnModule(*module))
{
@@ -375,6 +402,8 @@
lldb::addr_t &func_end,
ExecutionContext &exe_ctx)
{
+ Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
+
Error err;
llvm::Module *module = m_code_generator->ReleaseModule();
@@ -386,6 +415,22 @@
return err;
}
+ // Find the actual name of the function (it's often mangled somehow)
+
+ std::string function_name;
+
+ if (!FindFunctionInModule(function_name, module, m_expr.FunctionName()))
+ {
+ err.SetErrorToGenericError();
+ err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
+ return err;
+ }
+ else
+ {
+ if(log)
+ log->Printf("Found function %s for %s", function_name.c_str(), m_expr.FunctionName());
+ }
+
ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL
if (decl_map)
@@ -406,7 +451,7 @@
IRForTarget ir_for_target(decl_map,
target_machine->getTargetData(),
m_expr.NeedsVariableResolution(),
- m_expr.FunctionName());
+ function_name.c_str());
if (!ir_for_target.runOnModule(*module))
{
@@ -417,7 +462,7 @@
if (m_expr.NeedsValidation())
{
- IRDynamicChecks ir_dynamic_checks(*exe_ctx.process->GetDynamicCheckers(), m_expr.FunctionName());
+ IRDynamicChecks ir_dynamic_checks(*exe_ctx.process->GetDynamicCheckers(), function_name.c_str());
if (!ir_dynamic_checks.runOnModule(*module))
{
@@ -448,7 +493,7 @@
m_execution_engine->DisableLazyCompilation();
- llvm::Function *function = module->getFunction (m_expr.FunctionName());
+ llvm::Function *function = module->getFunction (function_name.c_str());
// We don't actually need the function pointer here, this just forces it to get resolved.
@@ -463,7 +508,7 @@
return err;
}
- m_jitted_functions.push_back (ClangExpressionParser::JittedFunction(m_expr.FunctionName(), (lldb::addr_t)fun_ptr));
+ m_jitted_functions.push_back (ClangExpressionParser::JittedFunction(function_name.c_str(), (lldb::addr_t)fun_ptr));
ExecutionContext &exc_context(exe_ctx);
@@ -525,7 +570,7 @@
{
(*pos).m_remote_addr = m_jit_mm->GetRemoteAddressForLocal ((*pos).m_local_addr);
- if (!(*pos).m_name.compare(m_expr.FunctionName()))
+ if (!(*pos).m_name.compare(function_name.c_str()))
{
func_end = m_jit_mm->GetRemoteRangeForLocal ((*pos).m_local_addr).second;
func_addr = (*pos).m_remote_addr;
@@ -554,7 +599,7 @@
for (pos = m_jitted_functions.begin(); pos < end; pos++)
{
- if (strcmp(pos->m_name.c_str(), name) == 0)
+ if (strstr(pos->m_name.c_str(), name))
{
func_local_addr = pos->m_local_addr;
func_remote_addr = pos->m_remote_addr;