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"
|
2011-01-19 03:36:39 +08:00
|
|
|
#include "lldb/Core/StreamFile.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/Core/StreamString.h"
|
2010-10-05 11:13:51 +08:00
|
|
|
#include "lldb/Core/ValueObjectConstResult.h"
|
2010-12-16 11:17:46 +08:00
|
|
|
#include "lldb/Expression/ASTResultSynthesizer.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/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) :
|
2011-01-20 07:00:49 +08:00
|
|
|
ClangExpression (),
|
|
|
|
m_expr_text (expr),
|
|
|
|
m_expr_prefix (expr_prefix ? expr_prefix : ""),
|
|
|
|
m_transformed_text (),
|
2011-04-12 03:41:40 +08:00
|
|
|
m_desired_type (NULL, NULL),
|
2011-01-20 07:00:49 +08:00
|
|
|
m_cplusplus (false),
|
|
|
|
m_objectivec (false),
|
|
|
|
m_needs_object_ptr (false),
|
2011-05-07 09:06:41 +08:00
|
|
|
m_const_object (false),
|
|
|
|
m_const_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-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;
|
|
|
|
|
2010-12-02 05:35:54 +08:00
|
|
|
lldb::VariableSP this_var(vars->FindVariable(ConstString("this")));
|
|
|
|
lldb::VariableSP self_var(vars->FindVariable(ConstString("self")));
|
|
|
|
|
|
|
|
if (this_var.get())
|
|
|
|
{
|
|
|
|
Type *this_type = this_var->GetType();
|
|
|
|
|
|
|
|
lldb::clang_type_t pointer_target_type;
|
|
|
|
|
2011-02-17 07:00:21 +08:00
|
|
|
if (ClangASTContext::IsPointerType(this_type->GetClangForwardType(),
|
2010-12-02 05:35:54 +08:00
|
|
|
&pointer_target_type))
|
|
|
|
{
|
|
|
|
TypeFromUser target_ast_type(pointer_target_type, this_type->GetClangAST());
|
|
|
|
|
2011-02-17 07:00:21 +08:00
|
|
|
if (ClangASTContext::IsCXXClassType(target_ast_type.GetOpaqueQualType()))
|
2011-01-24 16:11:45 +08:00
|
|
|
{
|
2010-12-02 05:35:54 +08:00
|
|
|
m_cplusplus = true;
|
|
|
|
|
2011-01-24 16:11:45 +08:00
|
|
|
if (target_ast_type.IsConst())
|
|
|
|
m_const_object = true;
|
|
|
|
}
|
2010-12-02 05:35:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (self_var.get())
|
|
|
|
{
|
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_objectivec = true;
|
2010-12-02 05:35:54 +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
|
|
|
}
|
|
|
|
|
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,
|
2010-12-16 11:17:46 +08:00
|
|
|
TypeFromUser desired_type,
|
2011-05-07 09:06:41 +08:00
|
|
|
bool keep_result_in_memory)
|
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-12-02 05:35:54 +08:00
|
|
|
"$__lldb_class::%s(void *$__lldb_arg) %s\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(),
|
2010-12-02 05:35:54 +08:00
|
|
|
(m_const_object ? "const" : ""),
|
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_expr_text.c_str());
|
|
|
|
|
|
|
|
m_needs_object_ptr = true;
|
|
|
|
}
|
2010-12-14 06:46:15 +08:00
|
|
|
else if(m_objectivec)
|
|
|
|
{
|
|
|
|
const char *function_name = FunctionName();
|
|
|
|
|
|
|
|
m_transformed_stream.Printf("%s \n"
|
2010-12-17 10:26:24 +08:00
|
|
|
"typedef unsigned short unichar; \n"
|
2010-12-14 06:46:15 +08:00
|
|
|
"@interface $__lldb_objc_class ($__lldb_category) \n"
|
|
|
|
"-(void)%s:(void *)$__lldb_arg; \n"
|
|
|
|
"@end \n"
|
|
|
|
"@implementation $__lldb_objc_class ($__lldb_category) \n"
|
|
|
|
"-(void)%s:(void *)$__lldb_arg \n"
|
|
|
|
"{ \n"
|
|
|
|
" %s; \n"
|
|
|
|
"} \n"
|
|
|
|
"@end \n",
|
|
|
|
m_expr_prefix.c_str(),
|
|
|
|
function_name,
|
|
|
|
function_name,
|
|
|
|
m_expr_text.c_str());
|
|
|
|
|
|
|
|
m_needs_object_ptr = true;
|
|
|
|
}
|
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
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////
|
|
|
|
// Parse the expression
|
|
|
|
//
|
|
|
|
|
2010-11-19 10:52:21 +08:00
|
|
|
m_desired_type = desired_type;
|
|
|
|
|
2011-01-13 16:53:35 +08:00
|
|
|
m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory));
|
2010-12-03 09:38:59 +08:00
|
|
|
|
|
|
|
m_expr_decl_map->WillParse(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
|
|
|
|
2011-02-16 05:59:32 +08:00
|
|
|
ClangExpressionParser parser(exe_ctx.process, *this);
|
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
|
|
|
|
|
|
|
unsigned num_errors = parser.Parse (error_stream);
|
|
|
|
|
|
|
|
if (num_errors)
|
|
|
|
{
|
|
|
|
error_stream.Printf ("error: %d errors parsing expression\n", num_errors);
|
2010-12-03 09:38:59 +08:00
|
|
|
|
|
|
|
m_expr_decl_map->DidParse();
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
// Convert the output of the parser to DWARF
|
|
|
|
//
|
|
|
|
|
|
|
|
m_dwarf_opcodes.reset(new StreamString);
|
2011-02-01 09:31:41 +08:00
|
|
|
m_dwarf_opcodes->SetByteOrder (lldb::endian::InlHostByteOrder());
|
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_dwarf_opcodes->GetFlags ().Set (Stream::eBinary);
|
|
|
|
|
2010-12-14 10:59:59 +08:00
|
|
|
m_local_variables.reset(new ClangExpressionVariableList());
|
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 dwarf_error = parser.MakeDWARF ();
|
|
|
|
|
|
|
|
if (dwarf_error.Success())
|
|
|
|
{
|
|
|
|
if (log)
|
|
|
|
log->Printf("Code can be interpreted.");
|
|
|
|
|
2010-12-03 09:38:59 +08:00
|
|
|
m_expr_decl_map->DidParse();
|
|
|
|
|
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 true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////
|
|
|
|
// JIT the output of the parser
|
|
|
|
//
|
|
|
|
|
|
|
|
m_dwarf_opcodes.reset();
|
|
|
|
|
2011-05-07 09:06:41 +08:00
|
|
|
Error jit_error = parser.MakeJIT (m_jit_alloc, m_jit_start_addr, m_jit_end_addr, exe_ctx, m_const_result, 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-12-03 09:38:59 +08:00
|
|
|
m_expr_decl_map->DidParse();
|
|
|
|
|
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())
|
|
|
|
{
|
2011-01-20 07:00:49 +08:00
|
|
|
if (exe_ctx.process && m_jit_alloc != LLDB_INVALID_ADDRESS)
|
|
|
|
m_jit_process_sp = exe_ctx.process->GetSP();
|
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 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,
|
2010-12-14 08:42:36 +08:00
|
|
|
lldb::addr_t &object_ptr,
|
|
|
|
lldb::addr_t &cmd_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
|
|
|
|
2011-01-20 07:00:49 +08:00
|
|
|
if (m_jit_start_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;
|
|
|
|
|
2010-12-14 06:46:15 +08:00
|
|
|
if (m_needs_object_ptr)
|
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
|
|
|
{
|
2010-12-14 06:46:15 +08:00
|
|
|
ConstString object_name;
|
|
|
|
|
|
|
|
if (m_cplusplus)
|
|
|
|
{
|
|
|
|
object_name.SetCString("this");
|
|
|
|
}
|
|
|
|
else if (m_objectivec)
|
|
|
|
{
|
|
|
|
object_name.SetCString("self");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error_stream.Printf("Need object pointer but don't know the language\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(m_expr_decl_map->GetObjectPointer(object_ptr, object_name, exe_ctx, materialize_error)))
|
|
|
|
{
|
|
|
|
error_stream.Printf("Couldn't get required object pointer: %s\n", materialize_error.AsCString());
|
|
|
|
return false;
|
|
|
|
}
|
2010-12-14 08:42:36 +08:00
|
|
|
|
|
|
|
if (m_objectivec)
|
|
|
|
{
|
|
|
|
ConstString cmd_name("_cmd");
|
|
|
|
|
|
|
|
if (!(m_expr_decl_map->GetObjectPointer(cmd_ptr, cmd_name, exe_ctx, materialize_error, true)))
|
|
|
|
{
|
|
|
|
error_stream.Printf("Couldn't get required object pointer: %s\n", materialize_error.AsCString());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
2010-12-03 09:38:59 +08:00
|
|
|
if (!m_expr_decl_map->Materialize(exe_ctx, struct_address, materialize_error))
|
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
|
|
|
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;
|
|
|
|
}
|
2011-01-19 03:36:39 +08:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
// jingham: look here
|
|
|
|
StreamFile logfile ("/tmp/exprs.txt", "a");
|
2011-01-20 07:00:49 +08:00
|
|
|
logfile.Printf("0x%16.16llx: thread = 0x%4.4x, expr = '%s'\n", m_jit_start_addr, exe_ctx.thread ? exe_ctx.thread->GetID() : -1, m_expr_text.c_str());
|
2011-01-19 03:36:39 +08:00
|
|
|
#endif
|
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 (log)
|
|
|
|
{
|
2010-12-08 06:55:01 +08:00
|
|
|
log->Printf("-- [ClangUserExpression::PrepareToExecuteJITExpression] Materializing for execution --");
|
2010-12-07 18:00:20 +08:00
|
|
|
|
2011-01-20 07:00:49 +08:00
|
|
|
log->Printf(" Function address : 0x%llx", (uint64_t)m_jit_start_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)
|
2010-12-07 18:00:20 +08:00
|
|
|
log->Printf(" Object pointer : 0x%llx", (uint64_t)object_ptr);
|
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
|
|
|
|
2010-12-07 18:00:20 +08:00
|
|
|
log->Printf(" Structure address : 0x%llx", (uint64_t)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
|
|
|
|
|
|
|
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-12-03 09:38:59 +08:00
|
|
|
if (!m_expr_decl_map->DumpMaterializedStruct(exe_ctx, args, dump_error))
|
2010-09-14 05:34:21 +08:00
|
|
|
{
|
2010-12-07 18:00:20 +08:00
|
|
|
log->Printf(" Couldn't extract variable values : %s", dump_error.AsCString("unknown error"));
|
2010-09-14 05:34:21 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-12-07 18:00:20 +08:00
|
|
|
log->Printf(" Structure contents:\n%s", args.GetData());
|
2010-09-14 05:34:21 +08:00
|
|
|
}
|
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,
|
2011-01-13 16:53:35 +08:00
|
|
|
ExecutionContext &exe_ctx)
|
2010-10-15 07:45:03 +08:00
|
|
|
{
|
|
|
|
lldb::addr_t struct_address;
|
|
|
|
|
|
|
|
lldb::addr_t object_ptr = NULL;
|
2010-12-14 06:46:15 +08:00
|
|
|
lldb::addr_t cmd_ptr = NULL;
|
2010-10-15 07:45:03 +08:00
|
|
|
|
2010-12-14 08:42:36 +08:00
|
|
|
PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr);
|
2010-10-15 07:45:03 +08:00
|
|
|
|
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
|
2010-12-14 06:46:15 +08:00
|
|
|
// 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,
|
2011-01-20 07:00:49 +08:00
|
|
|
m_jit_start_addr,
|
2010-12-01 09:28:23 +08:00
|
|
|
struct_address,
|
|
|
|
error_stream,
|
|
|
|
true,
|
|
|
|
true,
|
2010-12-14 06:46:15 +08:00
|
|
|
(m_needs_object_ptr ? &object_ptr : NULL),
|
|
|
|
(m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL);
|
2010-10-15 07:45:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
|
|
|
|
ExecutionContext &exe_ctx,
|
2011-05-10 06:04:36 +08:00
|
|
|
lldb::ClangExpressionVariableSP &result,
|
|
|
|
lldb::addr_t function_stack_pointer)
|
2010-10-15 07:45:03 +08:00
|
|
|
{
|
|
|
|
Error expr_error;
|
|
|
|
|
2010-12-07 18:00:20 +08:00
|
|
|
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
{
|
2010-12-08 06:55:01 +08:00
|
|
|
log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --");
|
2010-12-07 18:00:20 +08:00
|
|
|
|
|
|
|
StreamString args;
|
|
|
|
|
|
|
|
Error dump_error;
|
|
|
|
|
|
|
|
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());
|
|
|
|
}
|
|
|
|
}
|
2011-05-10 06:04:36 +08:00
|
|
|
|
|
|
|
lldb::addr_t function_stack_bottom = function_stack_pointer - Host::GetPageSize();
|
|
|
|
|
2010-12-07 18:00:20 +08:00
|
|
|
|
2011-05-10 06:04:36 +08:00
|
|
|
if (!m_expr_decl_map->Dematerialize(exe_ctx, result, function_stack_pointer, function_stack_bottom, expr_error))
|
2010-10-15 07:45:03 +08:00
|
|
|
{
|
|
|
|
error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error"));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-03-25 05:19:54 +08:00
|
|
|
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-12-14 10:59:59 +08:00
|
|
|
lldb::ClangExpressionVariableSP &result)
|
2010-10-15 07:45:03 +08:00
|
|
|
{
|
2011-01-19 06:20:08 +08:00
|
|
|
// The expression log is quite verbose, and if you're just tracking the execution of the
|
|
|
|
// expression, it's quite convenient to have these logs come out with the STEP log as well.
|
|
|
|
lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
|
2010-12-07 18:00:20 +08:00
|
|
|
|
2010-10-15 07:45:03 +08:00
|
|
|
if (m_dwarf_opcodes.get())
|
|
|
|
{
|
|
|
|
// TODO execute the JITted opcodes
|
|
|
|
|
|
|
|
error_stream.Printf("We don't currently support executing DWARF expressions");
|
|
|
|
|
2011-03-25 05:19:54 +08:00
|
|
|
return eExecutionSetupError;
|
2010-10-15 07:45:03 +08:00
|
|
|
}
|
2011-01-20 07:00:49 +08:00
|
|
|
else if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
|
2010-10-15 07:45:03 +08:00
|
|
|
{
|
|
|
|
lldb::addr_t struct_address;
|
|
|
|
|
|
|
|
lldb::addr_t object_ptr = NULL;
|
2010-12-14 06:46:15 +08:00
|
|
|
lldb::addr_t cmd_ptr = NULL;
|
2010-10-15 07:45:03 +08:00
|
|
|
|
2010-12-14 08:42:36 +08:00
|
|
|
if (!PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr, cmd_ptr))
|
2011-03-25 05:19:54 +08:00
|
|
|
return 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
|
|
|
|
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
|
|
|
|
2011-01-20 07:00:49 +08:00
|
|
|
Address wrapper_address (NULL, m_jit_start_addr);
|
2010-12-14 06:46:15 +08:00
|
|
|
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),
|
|
|
|
((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL),
|
|
|
|
shared_ptr_to_me));
|
|
|
|
|
2010-11-30 10:22:11 +08:00
|
|
|
if (call_plan_sp == NULL || !call_plan_sp->ValidatePlan (NULL))
|
2011-03-25 05:19:54 +08:00
|
|
|
return eExecutionSetupError;
|
2011-05-10 06:04:36 +08:00
|
|
|
|
|
|
|
lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
|
2010-11-30 10:22:11 +08:00
|
|
|
|
|
|
|
call_plan_sp->SetPrivate(true);
|
|
|
|
|
2011-01-19 15:54:15 +08:00
|
|
|
uint32_t single_thread_timeout_usec = 500000;
|
2010-12-07 18:00:20 +08:00
|
|
|
|
|
|
|
if (log)
|
2010-12-08 06:55:01 +08:00
|
|
|
log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
|
2010-12-07 18:00:20 +08:00
|
|
|
|
2011-03-25 05:19:54 +08:00
|
|
|
ExecutionResults execution_result = exe_ctx.process->RunThreadPlan (exe_ctx,
|
2011-05-10 06:04:36 +08:00
|
|
|
call_plan_sp,
|
|
|
|
stop_others,
|
|
|
|
try_all_threads,
|
|
|
|
discard_on_error,
|
|
|
|
single_thread_timeout_usec,
|
|
|
|
error_stream);
|
2010-12-07 18:00:20 +08:00
|
|
|
|
|
|
|
if (log)
|
2010-12-08 06:55:01 +08:00
|
|
|
log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
|
2010-11-30 10:22:11 +08:00
|
|
|
|
2011-03-25 05:19:54 +08:00
|
|
|
if (execution_result == 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;
|
|
|
|
}
|
2011-03-25 05:19:54 +08:00
|
|
|
else if (execution_result != eExecutionCompleted)
|
2010-11-30 10:22:11 +08:00
|
|
|
{
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2011-05-10 06:04:36 +08:00
|
|
|
if (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_pointer))
|
2011-03-25 05:19:54 +08:00
|
|
|
return eExecutionCompleted;
|
2010-11-30 10:22:11 +08:00
|
|
|
else
|
2011-03-25 05:19:54 +08:00
|
|
|
return 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");
|
2011-03-25 05:19:54 +08:00
|
|
|
return 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
|
|
|
|
2011-03-25 05:19:54 +08:00
|
|
|
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
|
|
|
{
|
2011-01-19 06:20:08 +08:00
|
|
|
lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
|
2010-12-08 06:55:01 +08:00
|
|
|
|
2010-10-05 08:31:29 +08:00
|
|
|
Error error;
|
2011-03-25 05:19:54 +08:00
|
|
|
ExecutionResults execution_results = 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.");
|
|
|
|
|
2011-04-23 07:53:53 +08:00
|
|
|
result_valobj_sp = ValueObjectConstResult::Create (NULL, error);
|
2011-03-25 05:19:54 +08:00
|
|
|
return eExecutionSetupError;
|
2010-11-30 10:22:11 +08:00
|
|
|
}
|
|
|
|
|
2010-11-04 09:54:29 +08:00
|
|
|
if (!exe_ctx.process->GetDynamicCheckers())
|
|
|
|
{
|
2010-12-08 06:55:01 +08:00
|
|
|
if (log)
|
|
|
|
log->Printf("== [ClangUserExpression::Evaluate] Installing dynamic checkers ==");
|
|
|
|
|
2010-11-04 09:54:29 +08:00
|
|
|
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());
|
|
|
|
|
2011-04-23 07:53:53 +08:00
|
|
|
result_valobj_sp = ValueObjectConstResult::Create (NULL, error);
|
2011-03-25 05:19:54 +08:00
|
|
|
return eExecutionSetupError;
|
2010-11-05 08:57:06 +08:00
|
|
|
}
|
|
|
|
|
2010-11-04 09:54:29 +08:00
|
|
|
exe_ctx.process->SetDynamicCheckers(dynamic_checkers);
|
2010-12-08 06:55:01 +08:00
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
|
2010-11-04 09:54:29 +08:00
|
|
|
}
|
|
|
|
|
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;
|
2011-05-07 09:06:41 +08:00
|
|
|
|
2010-12-08 06:55:01 +08:00
|
|
|
if (log)
|
|
|
|
log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr);
|
|
|
|
|
2011-05-07 09:06:41 +08:00
|
|
|
if (!user_expression_sp->Parse (error_stream, exe_ctx, TypeFromUser(NULL, NULL), true))
|
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
|
|
|
|
{
|
2010-12-14 10:59:59 +08:00
|
|
|
lldb::ClangExpressionVariableSP expr_result;
|
2010-10-05 08:31:29 +08:00
|
|
|
|
2011-05-07 09:06:41 +08:00
|
|
|
if (user_expression_sp->m_const_result.get())
|
2010-10-05 08:31:29 +08:00
|
|
|
{
|
2010-12-08 06:55:01 +08:00
|
|
|
if (log)
|
2010-12-16 11:17:46 +08:00
|
|
|
log->Printf("== [ClangUserExpression::Evaluate] Expression evaluated as a constant ==");
|
2010-12-08 06:55:01 +08:00
|
|
|
|
2011-05-07 09:06:41 +08:00
|
|
|
result_valobj_sp = user_expression_sp->m_const_result->GetValueObject();
|
2010-10-05 08:31:29 +08:00
|
|
|
}
|
2010-12-16 11:17:46 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
error_stream.GetString().clear();
|
|
|
|
|
|
|
|
if (log)
|
|
|
|
log->Printf("== [ClangUserExpression::Evaluate] Executing expression ==");
|
|
|
|
|
|
|
|
execution_results = user_expression_sp->Execute (error_stream,
|
|
|
|
exe_ctx,
|
2011-01-13 16:53:35 +08:00
|
|
|
discard_on_error,
|
2010-12-16 11:17:46 +08:00
|
|
|
user_expression_sp,
|
|
|
|
expr_result);
|
|
|
|
|
2011-03-25 05:19:54 +08:00
|
|
|
if (execution_results != eExecutionCompleted)
|
2010-10-05 08:31:29 +08:00
|
|
|
{
|
2010-12-08 06:55:01 +08:00
|
|
|
if (log)
|
2010-12-16 11:17:46 +08:00
|
|
|
log->Printf("== [ClangUserExpression::Evaluate] Execution completed abnormally ==");
|
|
|
|
|
|
|
|
if (error_stream.GetString().empty())
|
|
|
|
error.SetErrorString ("expression failed to execute, unknown error");
|
|
|
|
else
|
|
|
|
error.SetErrorString (error_stream.GetString().c_str());
|
2010-10-05 08:31:29 +08:00
|
|
|
}
|
2010-12-16 11:17:46 +08:00
|
|
|
else
|
2010-10-05 08:31:29 +08:00
|
|
|
{
|
2010-12-16 11:17:46 +08:00
|
|
|
if (expr_result)
|
|
|
|
{
|
|
|
|
result_valobj_sp = expr_result->GetValueObject();
|
|
|
|
|
|
|
|
if (log)
|
2011-03-31 08:19:25 +08:00
|
|
|
log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString());
|
2010-12-16 11:17:46 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (log)
|
|
|
|
log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with no result ==");
|
|
|
|
|
|
|
|
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)
|
2011-04-23 07:53:53 +08:00
|
|
|
result_valobj_sp = ValueObjectConstResult::Create (NULL, error);
|
2010-10-05 11:13:51 +08:00
|
|
|
|
2010-11-30 10:22:11 +08:00
|
|
|
return execution_results;
|
2010-10-30 04:19:44 +08:00
|
|
|
}
|