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"
|
2010-10-05 11:13:51 +08:00
|
|
|
#include "lldb/Core/ValueObjectConstResult.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/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"
|
2010-11-04 09:54:29 +08:00
|
|
|
#include "lldb/Target/Process.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"
|
2010-11-30 10:22:11 +08:00
|
|
|
#include "lldb/Target/ThreadPlan.h"
|
|
|
|
#include "lldb/Target/ThreadPlanCallUserExpression.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
|
|
|
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
2010-10-29 08:29:03 +08:00
|
|
|
ClangUserExpression::ClangUserExpression (const char *expr,
|
|
|
|
const char *expr_prefix) :
|
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
|
|
|
m_expr_text(expr),
|
2010-10-30 04:19:44 +08:00
|
|
|
m_expr_prefix(expr_prefix ? expr_prefix : ""),
|
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),
|
2010-11-19 10:52:21 +08:00
|
|
|
m_needs_object_ptr(false),
|
|
|
|
m_desired_type(NULL, 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
|
|
|
{
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
{
|
2010-11-19 10:52:21 +08:00
|
|
|
return new ASTResultSynthesizer(passthrough,
|
|
|
|
m_desired_type);
|
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
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-10-23 07:25:16 +08:00
|
|
|
// This is a really nasty hack, meant to fix Objective-C expressions of the form
|
|
|
|
// (int)[myArray count]. Right now, because the type information for count is
|
|
|
|
// not available, [myArray count] returns id, which can't be directly cast to
|
|
|
|
// int without causing a clang error.
|
|
|
|
static void
|
|
|
|
ApplyObjcCastHack(std::string &expr)
|
|
|
|
{
|
|
|
|
#define OBJC_CAST_HACK_FROM "(int)["
|
|
|
|
#define OBJC_CAST_HACK_TO "(int)(long long)["
|
|
|
|
|
|
|
|
size_t from_offset;
|
|
|
|
|
|
|
|
while ((from_offset = expr.find(OBJC_CAST_HACK_FROM)) != expr.npos)
|
|
|
|
expr.replace(from_offset, sizeof(OBJC_CAST_HACK_FROM) - 1, OBJC_CAST_HACK_TO);
|
|
|
|
|
|
|
|
#undef OBJC_CAST_HACK_TO
|
|
|
|
#undef OBJC_CAST_HACK_FROM
|
|
|
|
}
|
|
|
|
|
2010-10-25 04:45:49 +08:00
|
|
|
// Another hack, meant to allow use of unichar despite it not being available in
|
|
|
|
// the type information. Although we could special-case it in type lookup,
|
|
|
|
// hopefully we'll figure out a way to #include the same environment as is
|
|
|
|
// present in the original source file rather than try to hack specific type
|
|
|
|
// definitions in as needed.
|
|
|
|
static void
|
|
|
|
ApplyUnicharHack(std::string &expr)
|
|
|
|
{
|
|
|
|
#define UNICHAR_HACK_FROM "unichar"
|
|
|
|
#define UNICHAR_HACK_TO "unsigned short"
|
|
|
|
|
|
|
|
size_t from_offset;
|
|
|
|
|
|
|
|
while ((from_offset = expr.find(UNICHAR_HACK_FROM)) != expr.npos)
|
|
|
|
expr.replace(from_offset, sizeof(UNICHAR_HACK_FROM) - 1, UNICHAR_HACK_TO);
|
|
|
|
|
|
|
|
#undef UNICHAR_HACK_TO
|
|
|
|
#undef UNICHAR_HACK_FROM
|
|
|
|
}
|
|
|
|
|
2010-10-23 07:25:16 +08:00
|
|
|
bool
|
2010-11-19 10:52:21 +08:00
|
|
|
ClangUserExpression::Parse (Stream &error_stream,
|
|
|
|
ExecutionContext &exe_ctx,
|
|
|
|
TypeFromUser desired_type)
|
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-11-06 09:53:30 +08:00
|
|
|
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
|
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
|
|
|
|
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
|
|
|
|
//
|
2010-10-23 07:25:16 +08:00
|
|
|
|
|
|
|
ApplyObjcCastHack(m_expr_text);
|
2010-10-27 11:32:59 +08:00
|
|
|
//ApplyUnicharHack(m_expr_text);
|
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_cplusplus)
|
|
|
|
{
|
2010-10-29 08:29:03 +08:00
|
|
|
m_transformed_stream.Printf("%s \n"
|
|
|
|
"typedef unsigned short unichar; \n"
|
2010-10-27 11:32:59 +08:00
|
|
|
"void \n"
|
2010-10-23 07:25:16 +08:00
|
|
|
"$__lldb_class::%s(void *$__lldb_arg) \n"
|
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
|
|
|
"{ \n"
|
|
|
|
" %s; \n"
|
|
|
|
"} \n",
|
2010-10-29 08:29:03 +08:00
|
|
|
m_expr_prefix.c_str(),
|
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
|
|
|
FunctionName(),
|
|
|
|
m_expr_text.c_str());
|
|
|
|
|
|
|
|
m_needs_object_ptr = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-10-29 08:29:03 +08:00
|
|
|
m_transformed_stream.Printf("%s \n"
|
|
|
|
"typedef unsigned short unichar;\n"
|
2010-10-27 11:32:59 +08:00
|
|
|
"void \n"
|
2010-10-23 07:25:16 +08:00
|
|
|
"%s(void *$__lldb_arg) \n"
|
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
|
|
|
"{ \n"
|
|
|
|
" %s; \n"
|
|
|
|
"} \n",
|
2010-10-29 08:29:03 +08:00
|
|
|
m_expr_prefix.c_str(),
|
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
|
|
|
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
|
|
|
|
//
|
|
|
|
|
2010-11-19 10:52:21 +08:00
|
|
|
m_desired_type = desired_type;
|
|
|
|
|
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
|
|
|
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())
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error_stream.Printf ("error: expression can't be interpreted or run\n", num_errors);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2010-10-15 07:45:03 +08:00
|
|
|
ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
|
2010-10-20 07:57:21 +08:00
|
|
|
ExecutionContext &exe_ctx,
|
|
|
|
lldb::addr_t &struct_address,
|
|
|
|
lldb::addr_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
|
|
|
{
|
2010-11-06 09:53:30 +08:00
|
|
|
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
|
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-10-15 07:45:03 +08:00
|
|
|
if (m_jit_addr != LLDB_INVALID_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
|
|
|
{
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
2010-10-15 07:45:03 +08:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
ThreadPlan *
|
|
|
|
ClangUserExpression::GetThreadPlanToExecuteJITExpression (Stream &error_stream,
|
|
|
|
ExecutionContext &exe_ctx)
|
|
|
|
{
|
|
|
|
lldb::addr_t struct_address;
|
|
|
|
|
|
|
|
lldb::addr_t object_ptr = NULL;
|
|
|
|
|
|
|
|
PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr);
|
|
|
|
|
2010-11-30 10:22:11 +08:00
|
|
|
// FIXME: This should really return a ThreadPlanCallUserExpression, in order to make sure that we don't release the
|
|
|
|
// ClangUserExpression resources before the thread plan finishes execution in the target. But because we are
|
|
|
|
// forcing unwind_on_error to be true here, in practical terms that can't happen.
|
2010-10-15 07:45:03 +08:00
|
|
|
return ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
|
|
|
|
m_jit_addr,
|
|
|
|
struct_address,
|
|
|
|
error_stream,
|
|
|
|
true,
|
|
|
|
true,
|
|
|
|
(m_needs_object_ptr ? &object_ptr : NULL));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
|
|
|
|
ExecutionContext &exe_ctx,
|
|
|
|
ClangExpressionVariable *&result)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-11-30 10:22:11 +08:00
|
|
|
Process::ExecutionResults
|
2010-10-15 07:45:03 +08:00
|
|
|
ClangUserExpression::Execute (Stream &error_stream,
|
|
|
|
ExecutionContext &exe_ctx,
|
2010-11-06 03:25:48 +08:00
|
|
|
bool discard_on_error,
|
2010-11-30 10:22:11 +08:00
|
|
|
ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me,
|
2010-10-15 07:45:03 +08:00
|
|
|
ClangExpressionVariable *&result)
|
|
|
|
{
|
|
|
|
if (m_dwarf_opcodes.get())
|
|
|
|
{
|
|
|
|
// TODO execute the JITted opcodes
|
|
|
|
|
|
|
|
error_stream.Printf("We don't currently support executing DWARF expressions");
|
|
|
|
|
2010-11-30 10:22:11 +08:00
|
|
|
return Process::eExecutionSetupError;
|
2010-10-15 07:45:03 +08:00
|
|
|
}
|
|
|
|
else if (m_jit_addr != LLDB_INVALID_ADDRESS)
|
|
|
|
{
|
|
|
|
lldb::addr_t struct_address;
|
|
|
|
|
|
|
|
lldb::addr_t object_ptr = NULL;
|
|
|
|
|
|
|
|
PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, 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
|
|
|
|
2010-11-06 03:25:48 +08:00
|
|
|
const bool stop_others = true;
|
|
|
|
const bool try_all_threads = 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
|
|
|
|
2010-11-30 10:22:11 +08:00
|
|
|
Address wrapper_address (NULL, m_jit_addr);
|
|
|
|
lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (*(exe_ctx.thread), wrapper_address, struct_address,
|
|
|
|
stop_others, discard_on_error,
|
|
|
|
(m_needs_object_ptr ? &object_ptr : NULL),
|
|
|
|
shared_ptr_to_me));
|
|
|
|
if (call_plan_sp == NULL || !call_plan_sp->ValidatePlan (NULL))
|
|
|
|
return Process::eExecutionSetupError;
|
|
|
|
|
|
|
|
call_plan_sp->SetPrivate(true);
|
|
|
|
|
|
|
|
uint32_t single_thread_timeout_usec = 10000000;
|
|
|
|
Process::ExecutionResults execution_result =
|
|
|
|
exe_ctx.process->RunThreadPlan (exe_ctx, call_plan_sp, stop_others, try_all_threads, discard_on_error,
|
|
|
|
single_thread_timeout_usec, error_stream);
|
|
|
|
|
|
|
|
if (execution_result == Process::eExecutionInterrupted)
|
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-11-30 10:22:11 +08:00
|
|
|
if (discard_on_error)
|
|
|
|
error_stream.Printf ("Expression execution was interrupted. The process has been returned to the state before execution.");
|
|
|
|
else
|
|
|
|
error_stream.Printf ("Expression execution was interrupted. The process has been left at the point where it was interrupted.");
|
|
|
|
|
|
|
|
return execution_result;
|
|
|
|
}
|
|
|
|
else if (execution_result != Process::eExecutionCompleted)
|
|
|
|
{
|
|
|
|
error_stream.Printf ("Couldn't execute function; result was %s\n", Process::ExecutionResultAsCString (execution_result));
|
|
|
|
return execution_result;
|
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-11-30 10:22:11 +08:00
|
|
|
if (FinalizeJITExecution (error_stream, exe_ctx, result))
|
|
|
|
return Process::eExecutionCompleted;
|
|
|
|
else
|
|
|
|
return Process::eExecutionSetupError;
|
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
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-11-11 03:02:11 +08:00
|
|
|
error_stream.Printf("Expression can't be run; neither DWARF nor a JIT compiled function is present");
|
2010-11-30 10:22:11 +08:00
|
|
|
return Process::eExecutionSetupError;
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
2010-11-30 10:22:11 +08:00
|
|
|
Process::ExecutionResults
|
2010-10-29 08:29:03 +08:00
|
|
|
ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
|
2010-11-06 03:25:48 +08:00
|
|
|
bool discard_on_error,
|
2010-10-29 08:29:03 +08:00
|
|
|
const char *expr_cstr,
|
2010-11-30 10:22:11 +08:00
|
|
|
const char *expr_prefix,
|
|
|
|
lldb::ValueObjectSP &result_valobj_sp)
|
2010-10-05 08:31:29 +08:00
|
|
|
{
|
|
|
|
Error error;
|
2010-11-30 10:22:11 +08:00
|
|
|
Process::ExecutionResults execution_results = Process::eExecutionSetupError;
|
2010-11-04 09:54:29 +08:00
|
|
|
|
|
|
|
if (exe_ctx.process == NULL)
|
2010-11-30 10:22:11 +08:00
|
|
|
{
|
|
|
|
error.SetErrorString ("Must have a process to evaluate expressions.");
|
|
|
|
|
|
|
|
result_valobj_sp.reset (new ValueObjectConstResult (error));
|
|
|
|
return Process::eExecutionSetupError;
|
|
|
|
}
|
|
|
|
|
2010-11-04 09:54:29 +08:00
|
|
|
if (!exe_ctx.process->GetDynamicCheckers())
|
|
|
|
{
|
|
|
|
DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
|
|
|
|
|
|
|
|
StreamString install_errors;
|
|
|
|
|
|
|
|
if (!dynamic_checkers->Install(install_errors, exe_ctx))
|
2010-11-05 08:57:06 +08:00
|
|
|
{
|
|
|
|
if (install_errors.GetString().empty())
|
|
|
|
error.SetErrorString ("couldn't install checkers, unknown error");
|
|
|
|
else
|
|
|
|
error.SetErrorString (install_errors.GetString().c_str());
|
|
|
|
|
|
|
|
result_valobj_sp.reset (new ValueObjectConstResult (error));
|
2010-11-30 10:22:11 +08:00
|
|
|
return Process::eExecutionSetupError;
|
2010-11-05 08:57:06 +08:00
|
|
|
}
|
|
|
|
|
2010-11-04 09:54:29 +08:00
|
|
|
exe_ctx.process->SetDynamicCheckers(dynamic_checkers);
|
|
|
|
}
|
|
|
|
|
2010-11-30 10:22:11 +08:00
|
|
|
ClangUserExpressionSP user_expression_sp (new ClangUserExpression (expr_cstr, expr_prefix));
|
|
|
|
|
2010-10-05 08:31:29 +08:00
|
|
|
StreamString error_stream;
|
|
|
|
|
2010-11-30 10:22:11 +08:00
|
|
|
if (!user_expression_sp->Parse (error_stream, exe_ctx, TypeFromUser(NULL, NULL)))
|
2010-10-05 08:31:29 +08:00
|
|
|
{
|
|
|
|
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();
|
|
|
|
|
2010-11-30 10:22:11 +08:00
|
|
|
execution_results = user_expression_sp->Execute (error_stream,
|
|
|
|
exe_ctx,
|
|
|
|
discard_on_error,
|
|
|
|
user_expression_sp,
|
|
|
|
expr_result);
|
|
|
|
if (execution_results != Process::eExecutionCompleted)
|
2010-10-05 08:31:29 +08:00
|
|
|
{
|
|
|
|
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
|
|
|
|
{
|
2010-10-20 04:15:00 +08:00
|
|
|
error.SetErrorString ("Expression did not return a result");
|
2010-10-05 08:31:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-10-20 04:15:00 +08:00
|
|
|
|
2010-10-05 11:13:51 +08:00
|
|
|
if (result_valobj_sp.get() == NULL)
|
|
|
|
result_valobj_sp.reset (new ValueObjectConstResult (error));
|
|
|
|
|
2010-11-30 10:22:11 +08:00
|
|
|
return execution_results;
|
2010-10-30 04:19:44 +08:00
|
|
|
}
|