This is a major refactoring of the expression parser.
The goal is to separate the parser's data from the data
belonging to the parser's clients. This allows clients
to use the parser to obtain (for example) a JIT compiled
function or some DWARF code, and then discard the parser
state.
Previously, parser state was held in ClangExpression and
used liberally by ClangFunction, which inherited from
ClangExpression. The main effects of this refactoring
are:
- reducing ClangExpression to an abstract class that
declares methods that any client must expose to the
expression parser,
- moving the code specific to implementing the "expr"
command from ClangExpression and
CommandObjectExpression into ClangUserExpression,
a new class,
- moving the common parser interaction code from
ClangExpression into ClangExpressionParser, a new
class, and
- making ClangFunction rely only on
ClangExpressionParser and not depend on the
internal implementation of ClangExpression.
Side effects include:
- the compiler interaction code has been factored
out of ClangFunction and is now in an AST pass
(ASTStructExtractor),
- the header file for ClangFunction is now fully
documented,
- several bugs that only popped up when Clang was
deallocated (which never happened, since the
lifetime of the compiler was essentially infinite)
are now fixed, and
- the developer-only "call" command has been
disabled.
I have tested the expr command and the Objective-C
step-into code, which use ClangUserExpression and
ClangFunction, respectively, and verified that they
work. Please let me know if you encounter bugs or
poor documentation.
llvm-svn: 112249
2010-08-27 09:01:44 +08:00
|
|
|
//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
// C Includes
|
|
|
|
#include <stdio.h>
|
|
|
|
#if HAVE_SYS_TYPES_H
|
|
|
|
# include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// C++ Includes
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <string>
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
#include "lldb/Core/ConstString.h"
|
|
|
|
#include "lldb/Core/Log.h"
|
|
|
|
#include "lldb/Core/StreamString.h"
|
|
|
|
#include "lldb/Expression/ClangExpressionDeclMap.h"
|
|
|
|
#include "lldb/Expression/ClangExpressionParser.h"
|
|
|
|
#include "lldb/Expression/ClangFunction.h"
|
|
|
|
#include "lldb/Expression/ASTResultSynthesizer.h"
|
|
|
|
#include "lldb/Expression/ClangUserExpression.h"
|
|
|
|
#include "lldb/Host/Host.h"
|
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.
llvm-svn: 114384
2010-09-21 08:44:12 +08:00
|
|
|
#include "lldb/Symbol/VariableList.h"
|
This is a major refactoring of the expression parser.
The goal is to separate the parser's data from the data
belonging to the parser's clients. This allows clients
to use the parser to obtain (for example) a JIT compiled
function or some DWARF code, and then discard the parser
state.
Previously, parser state was held in ClangExpression and
used liberally by ClangFunction, which inherited from
ClangExpression. The main effects of this refactoring
are:
- reducing ClangExpression to an abstract class that
declares methods that any client must expose to the
expression parser,
- moving the code specific to implementing the "expr"
command from ClangExpression and
CommandObjectExpression into ClangUserExpression,
a new class,
- moving the common parser interaction code from
ClangExpression into ClangExpressionParser, a new
class, and
- making ClangFunction rely only on
ClangExpressionParser and not depend on the
internal implementation of ClangExpression.
Side effects include:
- the compiler interaction code has been factored
out of ClangFunction and is now in an AST pass
(ASTStructExtractor),
- the header file for ClangFunction is now fully
documented,
- several bugs that only popped up when Clang was
deallocated (which never happened, since the
lifetime of the compiler was essentially infinite)
are now fixed, and
- the developer-only "call" command has been
disabled.
I have tested the expr command and the Objective-C
step-into code, which use ClangUserExpression and
ClangFunction, respectively, and verified that they
work. Please let me know if you encounter bugs or
poor documentation.
llvm-svn: 112249
2010-08-27 09:01:44 +08:00
|
|
|
#include "lldb/Target/ExecutionContext.h"
|
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.
llvm-svn: 114384
2010-09-21 08:44:12 +08:00
|
|
|
#include "lldb/Target/StackFrame.h"
|
This is a major refactoring of the expression parser.
The goal is to separate the parser's data from the data
belonging to the parser's clients. This allows clients
to use the parser to obtain (for example) a JIT compiled
function or some DWARF code, and then discard the parser
state.
Previously, parser state was held in ClangExpression and
used liberally by ClangFunction, which inherited from
ClangExpression. The main effects of this refactoring
are:
- reducing ClangExpression to an abstract class that
declares methods that any client must expose to the
expression parser,
- moving the code specific to implementing the "expr"
command from ClangExpression and
CommandObjectExpression into ClangUserExpression,
a new class,
- moving the common parser interaction code from
ClangExpression into ClangExpressionParser, a new
class, and
- making ClangFunction rely only on
ClangExpressionParser and not depend on the
internal implementation of ClangExpression.
Side effects include:
- the compiler interaction code has been factored
out of ClangFunction and is now in an AST pass
(ASTStructExtractor),
- the header file for ClangFunction is now fully
documented,
- several bugs that only popped up when Clang was
deallocated (which never happened, since the
lifetime of the compiler was essentially infinite)
are now fixed, and
- the developer-only "call" command has been
disabled.
I have tested the expr command and the Objective-C
step-into code, which use ClangUserExpression and
ClangFunction, respectively, and verified that they
work. Please let me know if you encounter bugs or
poor documentation.
llvm-svn: 112249
2010-08-27 09:01:44 +08:00
|
|
|
#include "lldb/Target/Target.h"
|
|
|
|
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
|
|
|
ClangUserExpression::ClangUserExpression (const char *expr) :
|
|
|
|
m_expr_text(expr),
|
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.
llvm-svn: 114384
2010-09-21 08:44:12 +08:00
|
|
|
m_transformed_text(),
|
|
|
|
m_jit_addr(LLDB_INVALID_ADDRESS),
|
|
|
|
m_cplusplus(false),
|
|
|
|
m_objectivec(false),
|
|
|
|
m_needs_object_ptr(false)
|
This is a major refactoring of the expression parser.
The goal is to separate the parser's data from the data
belonging to the parser's clients. This allows clients
to use the parser to obtain (for example) a JIT compiled
function or some DWARF code, and then discard the parser
state.
Previously, parser state was held in ClangExpression and
used liberally by ClangFunction, which inherited from
ClangExpression. The main effects of this refactoring
are:
- reducing ClangExpression to an abstract class that
declares methods that any client must expose to the
expression parser,
- moving the code specific to implementing the "expr"
command from ClangExpression and
CommandObjectExpression into ClangUserExpression,
a new class,
- moving the common parser interaction code from
ClangExpression into ClangExpressionParser, a new
class, and
- making ClangFunction rely only on
ClangExpressionParser and not depend on the
internal implementation of ClangExpression.
Side effects include:
- the compiler interaction code has been factored
out of ClangFunction and is now in an AST pass
(ASTStructExtractor),
- the header file for ClangFunction is now fully
documented,
- several bugs that only popped up when Clang was
deallocated (which never happened, since the
lifetime of the compiler was essentially infinite)
are now fixed, and
- the developer-only "call" command has been
disabled.
I have tested the expr command and the Objective-C
step-into code, which use ClangUserExpression and
ClangFunction, respectively, and verified that they
work. Please let me know if you encounter bugs or
poor documentation.
llvm-svn: 112249
2010-08-27 09:01:44 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2010-08-28 07:31:21 +08:00
|
|
|
ClangUserExpression::~ClangUserExpression ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
This is a major refactoring of the expression parser.
The goal is to separate the parser's data from the data
belonging to the parser's clients. This allows clients
to use the parser to obtain (for example) a JIT compiled
function or some DWARF code, and then discard the parser
state.
Previously, parser state was held in ClangExpression and
used liberally by ClangFunction, which inherited from
ClangExpression. The main effects of this refactoring
are:
- reducing ClangExpression to an abstract class that
declares methods that any client must expose to the
expression parser,
- moving the code specific to implementing the "expr"
command from ClangExpression and
CommandObjectExpression into ClangUserExpression,
a new class,
- moving the common parser interaction code from
ClangExpression into ClangExpressionParser, a new
class, and
- making ClangFunction rely only on
ClangExpressionParser and not depend on the
internal implementation of ClangExpression.
Side effects include:
- the compiler interaction code has been factored
out of ClangFunction and is now in an AST pass
(ASTStructExtractor),
- the header file for ClangFunction is now fully
documented,
- several bugs that only popped up when Clang was
deallocated (which never happened, since the
lifetime of the compiler was essentially infinite)
are now fixed, and
- the developer-only "call" command has been
disabled.
I have tested the expr command and the Objective-C
step-into code, which use ClangUserExpression and
ClangFunction, respectively, and verified that they
work. Please let me know if you encounter bugs or
poor documentation.
llvm-svn: 112249
2010-08-27 09:01:44 +08:00
|
|
|
clang::ASTConsumer *
|
|
|
|
ClangUserExpression::ASTTransformer (clang::ASTConsumer *passthrough)
|
|
|
|
{
|
|
|
|
return new ASTResultSynthesizer(passthrough);
|
|
|
|
}
|
|
|
|
|
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.
llvm-svn: 114384
2010-09-21 08:44:12 +08:00
|
|
|
void
|
|
|
|
ClangUserExpression::ScanContext(ExecutionContext &exe_ctx)
|
|
|
|
{
|
|
|
|
if (!exe_ctx.frame)
|
|
|
|
return;
|
|
|
|
|
|
|
|
VariableList *vars = exe_ctx.frame->GetVariableList(false);
|
|
|
|
|
|
|
|
if (!vars)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (vars->FindVariable(ConstString("this")).get())
|
|
|
|
m_cplusplus = true;
|
|
|
|
else if (vars->FindVariable(ConstString("self")).get())
|
|
|
|
m_objectivec = true;
|
|
|
|
}
|
|
|
|
|
This is a major refactoring of the expression parser.
The goal is to separate the parser's data from the data
belonging to the parser's clients. This allows clients
to use the parser to obtain (for example) a JIT compiled
function or some DWARF code, and then discard the parser
state.
Previously, parser state was held in ClangExpression and
used liberally by ClangFunction, which inherited from
ClangExpression. The main effects of this refactoring
are:
- reducing ClangExpression to an abstract class that
declares methods that any client must expose to the
expression parser,
- moving the code specific to implementing the "expr"
command from ClangExpression and
CommandObjectExpression into ClangUserExpression,
a new class,
- moving the common parser interaction code from
ClangExpression into ClangExpressionParser, a new
class, and
- making ClangFunction rely only on
ClangExpressionParser and not depend on the
internal implementation of ClangExpression.
Side effects include:
- the compiler interaction code has been factored
out of ClangFunction and is now in an AST pass
(ASTStructExtractor),
- the header file for ClangFunction is now fully
documented,
- several bugs that only popped up when Clang was
deallocated (which never happened, since the
lifetime of the compiler was essentially infinite)
are now fixed, and
- the developer-only "call" command has been
disabled.
I have tested the expr command and the Objective-C
step-into code, which use ClangUserExpression and
ClangFunction, respectively, and verified that they
work. Please let me know if you encounter bugs or
poor documentation.
llvm-svn: 112249
2010-08-27 09:01:44 +08:00
|
|
|
bool
|
|
|
|
ClangUserExpression::Parse (Stream &error_stream, ExecutionContext &exe_ctx)
|
|
|
|
{
|
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
|
|
|
|
|
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.
llvm-svn: 114384
2010-09-21 08:44:12 +08:00
|
|
|
ScanContext(exe_ctx);
|
|
|
|
|
|
|
|
StreamString m_transformed_stream;
|
|
|
|
|
|
|
|
////////////////////////////////////
|
|
|
|
// Generate the expression
|
|
|
|
//
|
|
|
|
|
|
|
|
if (m_cplusplus)
|
|
|
|
{
|
|
|
|
m_transformed_stream.Printf("void \n"
|
|
|
|
"___clang_class::%s(void *___clang_arg) \n"
|
|
|
|
"{ \n"
|
|
|
|
" %s; \n"
|
|
|
|
"} \n",
|
|
|
|
FunctionName(),
|
|
|
|
m_expr_text.c_str());
|
|
|
|
|
|
|
|
m_needs_object_ptr = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_transformed_stream.Printf("void \n"
|
|
|
|
"%s(void *___clang_arg) \n"
|
|
|
|
"{ \n"
|
|
|
|
" %s; \n"
|
|
|
|
"} \n",
|
|
|
|
FunctionName(),
|
|
|
|
m_expr_text.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
m_transformed_text = m_transformed_stream.GetData();
|
|
|
|
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
|
|
|
|
|
This is a major refactoring of the expression parser.
The goal is to separate the parser's data from the data
belonging to the parser's clients. This allows clients
to use the parser to obtain (for example) a JIT compiled
function or some DWARF code, and then discard the parser
state.
Previously, parser state was held in ClangExpression and
used liberally by ClangFunction, which inherited from
ClangExpression. The main effects of this refactoring
are:
- reducing ClangExpression to an abstract class that
declares methods that any client must expose to the
expression parser,
- moving the code specific to implementing the "expr"
command from ClangExpression and
CommandObjectExpression into ClangUserExpression,
a new class,
- moving the common parser interaction code from
ClangExpression into ClangExpressionParser, a new
class, and
- making ClangFunction rely only on
ClangExpressionParser and not depend on the
internal implementation of ClangExpression.
Side effects include:
- the compiler interaction code has been factored
out of ClangFunction and is now in an AST pass
(ASTStructExtractor),
- the header file for ClangFunction is now fully
documented,
- several bugs that only popped up when Clang was
deallocated (which never happened, since the
lifetime of the compiler was essentially infinite)
are now fixed, and
- the developer-only "call" command has been
disabled.
I have tested the expr command and the Objective-C
step-into code, which use ClangUserExpression and
ClangFunction, respectively, and verified that they
work. Please let me know if you encounter bugs or
poor documentation.
llvm-svn: 112249
2010-08-27 09:01:44 +08:00
|
|
|
////////////////////////////////////
|
|
|
|
// Set up the target and compiler
|
|
|
|
//
|
|
|
|
|
|
|
|
Target *target = exe_ctx.target;
|
|
|
|
|
|
|
|
if (!target)
|
|
|
|
{
|
|
|
|
error_stream.PutCString ("error: invalid target\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
ConstString target_triple;
|
|
|
|
|
|
|
|
target->GetTargetTriple (target_triple);
|
|
|
|
|
|
|
|
if (!target_triple)
|
|
|
|
target_triple = Host::GetTargetTriple ();
|
|
|
|
|
|
|
|
if (!target_triple)
|
|
|
|
{
|
|
|
|
error_stream.PutCString ("error: invalid target triple\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////
|
|
|
|
// Parse the expression
|
|
|
|
//
|
|
|
|
|
|
|
|
m_expr_decl_map.reset(new ClangExpressionDeclMap(&exe_ctx));
|
|
|
|
|
|
|
|
ClangExpressionParser parser(target_triple.GetCString(), *this);
|
|
|
|
|
|
|
|
unsigned num_errors = parser.Parse (error_stream);
|
|
|
|
|
|
|
|
if (num_errors)
|
|
|
|
{
|
|
|
|
error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
// Convert the output of the parser to DWARF
|
|
|
|
//
|
|
|
|
|
|
|
|
m_dwarf_opcodes.reset(new StreamString);
|
|
|
|
m_dwarf_opcodes->SetByteOrder (lldb::eByteOrderHost);
|
|
|
|
m_dwarf_opcodes->GetFlags ().Set (Stream::eBinary);
|
|
|
|
|
|
|
|
m_local_variables.reset(new ClangExpressionVariableStore());
|
|
|
|
|
|
|
|
Error dwarf_error = parser.MakeDWARF ();
|
|
|
|
|
|
|
|
if (dwarf_error.Success())
|
|
|
|
{
|
|
|
|
if (log)
|
|
|
|
log->Printf("Code can be interpreted.");
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////
|
|
|
|
// JIT the output of the parser
|
|
|
|
//
|
|
|
|
|
|
|
|
m_dwarf_opcodes.reset();
|
|
|
|
|
2010-08-28 07:31:21 +08:00
|
|
|
lldb::addr_t jit_end;
|
|
|
|
|
|
|
|
Error jit_error = parser.MakeJIT (m_jit_addr, jit_end, exe_ctx);
|
This is a major refactoring of the expression parser.
The goal is to separate the parser's data from the data
belonging to the parser's clients. This allows clients
to use the parser to obtain (for example) a JIT compiled
function or some DWARF code, and then discard the parser
state.
Previously, parser state was held in ClangExpression and
used liberally by ClangFunction, which inherited from
ClangExpression. The main effects of this refactoring
are:
- reducing ClangExpression to an abstract class that
declares methods that any client must expose to the
expression parser,
- moving the code specific to implementing the "expr"
command from ClangExpression and
CommandObjectExpression into ClangUserExpression,
a new class,
- moving the common parser interaction code from
ClangExpression into ClangExpressionParser, a new
class, and
- making ClangFunction rely only on
ClangExpressionParser and not depend on the
internal implementation of ClangExpression.
Side effects include:
- the compiler interaction code has been factored
out of ClangFunction and is now in an AST pass
(ASTStructExtractor),
- the header file for ClangFunction is now fully
documented,
- several bugs that only popped up when Clang was
deallocated (which never happened, since the
lifetime of the compiler was essentially infinite)
are now fixed, and
- the developer-only "call" command has been
disabled.
I have tested the expr command and the Objective-C
step-into code, which use ClangUserExpression and
ClangFunction, respectively, and verified that they
work. Please let me know if you encounter bugs or
poor documentation.
llvm-svn: 112249
2010-08-27 09:01:44 +08:00
|
|
|
|
|
|
|
if (jit_error.Success())
|
|
|
|
{
|
|
|
|
if (log)
|
|
|
|
{
|
|
|
|
log->Printf("Code can be run in the target.");
|
|
|
|
|
|
|
|
StreamString disassembly_stream;
|
|
|
|
|
|
|
|
Error err = parser.DisassembleFunction(disassembly_stream, exe_ctx);
|
|
|
|
|
|
|
|
if (!err.Success())
|
|
|
|
{
|
|
|
|
log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error_stream.Printf ("error: expression can't be interpreted or run\n", num_errors);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ClangUserExpression::Execute (Stream &error_stream,
|
|
|
|
ExecutionContext &exe_ctx,
|
|
|
|
ClangExpressionVariable *&result)
|
|
|
|
{
|
|
|
|
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
|
|
|
|
|
|
|
|
if (m_dwarf_opcodes.get())
|
|
|
|
{
|
|
|
|
// TODO execute the JITted opcodes
|
|
|
|
|
|
|
|
error_stream.Printf("We don't currently support executing DWARF expressions");
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else if (m_jit_addr != LLDB_INVALID_ADDRESS)
|
|
|
|
{
|
|
|
|
lldb::addr_t struct_address;
|
|
|
|
|
|
|
|
Error materialize_error;
|
|
|
|
|
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.
llvm-svn: 114384
2010-09-21 08:44:12 +08:00
|
|
|
lldb::addr_t object_ptr = NULL;
|
|
|
|
|
|
|
|
if (m_needs_object_ptr && !(m_expr_decl_map->GetObjectPointer(object_ptr, &exe_ctx, materialize_error)))
|
|
|
|
{
|
|
|
|
error_stream.Printf("Couldn't get required object pointer: %s\n", materialize_error.AsCString());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
This is a major refactoring of the expression parser.
The goal is to separate the parser's data from the data
belonging to the parser's clients. This allows clients
to use the parser to obtain (for example) a JIT compiled
function or some DWARF code, and then discard the parser
state.
Previously, parser state was held in ClangExpression and
used liberally by ClangFunction, which inherited from
ClangExpression. The main effects of this refactoring
are:
- reducing ClangExpression to an abstract class that
declares methods that any client must expose to the
expression parser,
- moving the code specific to implementing the "expr"
command from ClangExpression and
CommandObjectExpression into ClangUserExpression,
a new class,
- moving the common parser interaction code from
ClangExpression into ClangExpressionParser, a new
class, and
- making ClangFunction rely only on
ClangExpressionParser and not depend on the
internal implementation of ClangExpression.
Side effects include:
- the compiler interaction code has been factored
out of ClangFunction and is now in an AST pass
(ASTStructExtractor),
- the header file for ClangFunction is now fully
documented,
- several bugs that only popped up when Clang was
deallocated (which never happened, since the
lifetime of the compiler was essentially infinite)
are now fixed, and
- the developer-only "call" command has been
disabled.
I have tested the expr command and the Objective-C
step-into code, which use ClangUserExpression and
ClangFunction, respectively, and verified that they
work. Please let me know if you encounter bugs or
poor documentation.
llvm-svn: 112249
2010-08-27 09:01:44 +08:00
|
|
|
if (!m_expr_decl_map->Materialize(&exe_ctx, struct_address, materialize_error))
|
|
|
|
{
|
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.
llvm-svn: 114384
2010-09-21 08:44:12 +08:00
|
|
|
error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString());
|
This is a major refactoring of the expression parser.
The goal is to separate the parser's data from the data
belonging to the parser's clients. This allows clients
to use the parser to obtain (for example) a JIT compiled
function or some DWARF code, and then discard the parser
state.
Previously, parser state was held in ClangExpression and
used liberally by ClangFunction, which inherited from
ClangExpression. The main effects of this refactoring
are:
- reducing ClangExpression to an abstract class that
declares methods that any client must expose to the
expression parser,
- moving the code specific to implementing the "expr"
command from ClangExpression and
CommandObjectExpression into ClangUserExpression,
a new class,
- moving the common parser interaction code from
ClangExpression into ClangExpressionParser, a new
class, and
- making ClangFunction rely only on
ClangExpressionParser and not depend on the
internal implementation of ClangExpression.
Side effects include:
- the compiler interaction code has been factored
out of ClangFunction and is now in an AST pass
(ASTStructExtractor),
- the header file for ClangFunction is now fully
documented,
- several bugs that only popped up when Clang was
deallocated (which never happened, since the
lifetime of the compiler was essentially infinite)
are now fixed, and
- the developer-only "call" command has been
disabled.
I have tested the expr command and the Objective-C
step-into code, which use ClangUserExpression and
ClangFunction, respectively, and verified that they
work. Please let me know if you encounter bugs or
poor documentation.
llvm-svn: 112249
2010-08-27 09:01:44 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
{
|
|
|
|
log->Printf("Function address : 0x%llx", (uint64_t)m_jit_addr);
|
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.
llvm-svn: 114384
2010-09-21 08:44:12 +08:00
|
|
|
|
|
|
|
if (m_needs_object_ptr)
|
|
|
|
log->Printf("Object pointer : 0x%llx", (uint64_t)object_ptr);
|
|
|
|
|
This is a major refactoring of the expression parser.
The goal is to separate the parser's data from the data
belonging to the parser's clients. This allows clients
to use the parser to obtain (for example) a JIT compiled
function or some DWARF code, and then discard the parser
state.
Previously, parser state was held in ClangExpression and
used liberally by ClangFunction, which inherited from
ClangExpression. The main effects of this refactoring
are:
- reducing ClangExpression to an abstract class that
declares methods that any client must expose to the
expression parser,
- moving the code specific to implementing the "expr"
command from ClangExpression and
CommandObjectExpression into ClangUserExpression,
a new class,
- moving the common parser interaction code from
ClangExpression into ClangExpressionParser, a new
class, and
- making ClangFunction rely only on
ClangExpressionParser and not depend on the
internal implementation of ClangExpression.
Side effects include:
- the compiler interaction code has been factored
out of ClangFunction and is now in an AST pass
(ASTStructExtractor),
- the header file for ClangFunction is now fully
documented,
- several bugs that only popped up when Clang was
deallocated (which never happened, since the
lifetime of the compiler was essentially infinite)
are now fixed, and
- the developer-only "call" command has been
disabled.
I have tested the expr command and the Objective-C
step-into code, which use ClangUserExpression and
ClangFunction, respectively, and verified that they
work. Please let me know if you encounter bugs or
poor documentation.
llvm-svn: 112249
2010-08-27 09:01:44 +08:00
|
|
|
log->Printf("Structure address : 0x%llx", (uint64_t)struct_address);
|
|
|
|
|
|
|
|
StreamString args;
|
|
|
|
|
|
|
|
Error dump_error;
|
|
|
|
|
2010-09-14 05:34:21 +08:00
|
|
|
if (struct_address)
|
This is a major refactoring of the expression parser.
The goal is to separate the parser's data from the data
belonging to the parser's clients. This allows clients
to use the parser to obtain (for example) a JIT compiled
function or some DWARF code, and then discard the parser
state.
Previously, parser state was held in ClangExpression and
used liberally by ClangFunction, which inherited from
ClangExpression. The main effects of this refactoring
are:
- reducing ClangExpression to an abstract class that
declares methods that any client must expose to the
expression parser,
- moving the code specific to implementing the "expr"
command from ClangExpression and
CommandObjectExpression into ClangUserExpression,
a new class,
- moving the common parser interaction code from
ClangExpression into ClangExpressionParser, a new
class, and
- making ClangFunction rely only on
ClangExpressionParser and not depend on the
internal implementation of ClangExpression.
Side effects include:
- the compiler interaction code has been factored
out of ClangFunction and is now in an AST pass
(ASTStructExtractor),
- the header file for ClangFunction is now fully
documented,
- several bugs that only popped up when Clang was
deallocated (which never happened, since the
lifetime of the compiler was essentially infinite)
are now fixed, and
- the developer-only "call" command has been
disabled.
I have tested the expr command and the Objective-C
step-into code, which use ClangUserExpression and
ClangFunction, respectively, and verified that they
work. Please let me know if you encounter bugs or
poor documentation.
llvm-svn: 112249
2010-08-27 09:01:44 +08:00
|
|
|
{
|
2010-09-14 05:34:21 +08:00
|
|
|
if (!m_expr_decl_map->DumpMaterializedStruct(&exe_ctx, args, dump_error))
|
|
|
|
{
|
|
|
|
log->Printf("Couldn't extract variable values : %s", dump_error.AsCString("unknown error"));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log->Printf("Structure contents:\n%s", args.GetData());
|
|
|
|
}
|
This is a major refactoring of the expression parser.
The goal is to separate the parser's data from the data
belonging to the parser's clients. This allows clients
to use the parser to obtain (for example) a JIT compiled
function or some DWARF code, and then discard the parser
state.
Previously, parser state was held in ClangExpression and
used liberally by ClangFunction, which inherited from
ClangExpression. The main effects of this refactoring
are:
- reducing ClangExpression to an abstract class that
declares methods that any client must expose to the
expression parser,
- moving the code specific to implementing the "expr"
command from ClangExpression and
CommandObjectExpression into ClangUserExpression,
a new class,
- moving the common parser interaction code from
ClangExpression into ClangExpressionParser, a new
class, and
- making ClangFunction rely only on
ClangExpressionParser and not depend on the
internal implementation of ClangExpression.
Side effects include:
- the compiler interaction code has been factored
out of ClangFunction and is now in an AST pass
(ASTStructExtractor),
- the header file for ClangFunction is now fully
documented,
- several bugs that only popped up when Clang was
deallocated (which never happened, since the
lifetime of the compiler was essentially infinite)
are now fixed, and
- the developer-only "call" command has been
disabled.
I have tested the expr command and the Objective-C
step-into code, which use ClangUserExpression and
ClangFunction, respectively, and verified that they
work. Please let me know if you encounter bugs or
poor documentation.
llvm-svn: 112249
2010-08-27 09:01:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ClangFunction::ExecutionResults execution_result =
|
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.
llvm-svn: 114384
2010-09-21 08:44:12 +08:00
|
|
|
ClangFunction::ExecuteFunction (exe_ctx,
|
|
|
|
m_jit_addr,
|
|
|
|
struct_address,
|
|
|
|
true,
|
|
|
|
true,
|
|
|
|
10000,
|
|
|
|
error_stream,
|
|
|
|
(m_needs_object_ptr ? &object_ptr : NULL));
|
This is a major refactoring of the expression parser.
The goal is to separate the parser's data from the data
belonging to the parser's clients. This allows clients
to use the parser to obtain (for example) a JIT compiled
function or some DWARF code, and then discard the parser
state.
Previously, parser state was held in ClangExpression and
used liberally by ClangFunction, which inherited from
ClangExpression. The main effects of this refactoring
are:
- reducing ClangExpression to an abstract class that
declares methods that any client must expose to the
expression parser,
- moving the code specific to implementing the "expr"
command from ClangExpression and
CommandObjectExpression into ClangUserExpression,
a new class,
- moving the common parser interaction code from
ClangExpression into ClangExpressionParser, a new
class, and
- making ClangFunction rely only on
ClangExpressionParser and not depend on the
internal implementation of ClangExpression.
Side effects include:
- the compiler interaction code has been factored
out of ClangFunction and is now in an AST pass
(ASTStructExtractor),
- the header file for ClangFunction is now fully
documented,
- several bugs that only popped up when Clang was
deallocated (which never happened, since the
lifetime of the compiler was essentially infinite)
are now fixed, and
- the developer-only "call" command has been
disabled.
I have tested the expr command and the Objective-C
step-into code, which use ClangUserExpression and
ClangFunction, respectively, and verified that they
work. Please let me know if you encounter bugs or
poor documentation.
llvm-svn: 112249
2010-08-27 09:01:44 +08:00
|
|
|
|
|
|
|
if (execution_result != ClangFunction::eExecutionCompleted)
|
|
|
|
{
|
|
|
|
const char *result_name;
|
|
|
|
|
|
|
|
switch (execution_result)
|
|
|
|
{
|
|
|
|
case ClangFunction::eExecutionCompleted:
|
|
|
|
result_name = "eExecutionCompleted";
|
|
|
|
break;
|
|
|
|
case ClangFunction::eExecutionDiscarded:
|
|
|
|
result_name = "eExecutionDiscarded";
|
|
|
|
break;
|
|
|
|
case ClangFunction::eExecutionInterrupted:
|
|
|
|
result_name = "eExecutionInterrupted";
|
|
|
|
break;
|
|
|
|
case ClangFunction::eExecutionSetupError:
|
|
|
|
result_name = "eExecutionSetupError";
|
|
|
|
break;
|
|
|
|
case ClangFunction::eExecutionTimedOut:
|
|
|
|
result_name = "eExecutionTimedOut";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
error_stream.Printf ("Couldn't execute function; result was %s\n", result_name);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Error expr_error;
|
|
|
|
|
|
|
|
if (!m_expr_decl_map->Dematerialize(&exe_ctx, result, expr_error))
|
|
|
|
{
|
|
|
|
error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error"));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error_stream.Printf("Expression can't be run; neither DWARF nor a JIT compiled function are present");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
StreamString &
|
|
|
|
ClangUserExpression::DwarfOpcodeStream ()
|
|
|
|
{
|
|
|
|
if (!m_dwarf_opcodes.get())
|
|
|
|
m_dwarf_opcodes.reset(new StreamString());
|
|
|
|
|
|
|
|
return *m_dwarf_opcodes.get();
|
|
|
|
}
|
2010-10-05 08:31:29 +08:00
|
|
|
|
|
|
|
|
|
|
|
Error
|
|
|
|
ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, const char *expr_cstr, lldb::ValueObjectSP &result_valobj_sp)
|
|
|
|
{
|
|
|
|
Error error;
|
|
|
|
result_valobj_sp.reset();
|
|
|
|
|
|
|
|
ClangUserExpression user_expression (expr_cstr);
|
|
|
|
|
|
|
|
StreamString error_stream;
|
|
|
|
|
|
|
|
if (!user_expression.Parse (error_stream, exe_ctx))
|
|
|
|
{
|
|
|
|
if (error_stream.GetString().empty())
|
|
|
|
error.SetErrorString ("expression failed to parse, unknown error");
|
|
|
|
else
|
|
|
|
error.SetErrorString (error_stream.GetString().c_str());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ClangExpressionVariable *expr_result = NULL;
|
|
|
|
|
|
|
|
error_stream.GetString().clear();
|
|
|
|
|
|
|
|
if (!user_expression.Execute (error_stream, exe_ctx, expr_result))
|
|
|
|
{
|
|
|
|
if (error_stream.GetString().empty())
|
|
|
|
error.SetErrorString ("expression failed to execute, unknown error");
|
|
|
|
else
|
|
|
|
error.SetErrorString (error_stream.GetString().c_str());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// TODO: seems weird to get a pointer to a result object back from
|
|
|
|
// a function. Do we own it? Feels like we do, but from looking at the
|
|
|
|
// code we don't. Might be best to make this a reference and state
|
|
|
|
// explicitly that we don't own it when we get a reference back from
|
|
|
|
// the execute?
|
|
|
|
if (expr_result)
|
|
|
|
{
|
|
|
|
result_valobj_sp = expr_result->GetExpressionResult (&exe_ctx);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error.SetErrorString ("NULL expression result");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return error;
|
|
|
|
|
|
|
|
}
|