Skip to content

Commit

Permalink
This patch makes Clang-independent base classes for all the expressio…
Browse files Browse the repository at this point in the history
…n types that lldb currently vends.

Before we had:

ClangFunction
ClangUtilityFunction
ClangUserExpression

and code all over in lldb that explicitly made Clang-based expressions. This patch adds an Expression 
base class, and three pure virtual implementations for the Expression kinds:

FunctionCaller
UtilityFunction
UserExpression

You can request one of these expression types from the Target using the Get<ExpressionType>ForLanguage. 
The Target will then consult all the registered TypeSystem plugins, and if the type system that matches 
the language can make an expression of that kind, it will do so and return it.

Because all of the real expression types need to communicate with their ExpressionParser in a uniform way, 
I also added a ExpressionTypeSystemHelper class that expressions generically can vend, and a ClangExpressionHelper 
that encapsulates the operations that the ClangExpressionParser needs to perform on the ClangExpression types. 
Then each of the Clang* expression kinds constructs the appropriate helper to do what it needs.

The patch also fixes a wart in the UtilityFunction that to use it you had to create a parallel FunctionCaller 
to actually call the function made by the UtilityFunction. Now the UtilityFunction can be asked to vend a 
FunctionCaller that will run its function. This cleaned up a lot of boiler plate code using UtilityFunctions.

Note, in this patch all the expression types explicitly depend on the LLVM JIT and IR, and all the common 
JIT running code is in the FunctionCaller etc base classes. At some point we could also abstract that dependency 
but I don't see us adding another back end in the near term, so I'll leave that exercise till it is actually necessary.



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@247720 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
jimingham committed Sep 15, 2015
1 parent 81fffeb commit 97b797f
Show file tree
Hide file tree
Showing 73 changed files with 3,062 additions and 1,957 deletions.
5 changes: 4 additions & 1 deletion include/lldb/Breakpoint/BreakpointLocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ class BreakpointLocation :
//------------------------------------------------------------------
Breakpoint &
GetBreakpoint ();

Target &
GetTarget();

//------------------------------------------------------------------
/// Determines whether we should stop due to a hit at this
Expand Down Expand Up @@ -458,7 +461,7 @@ class BreakpointLocation :
Breakpoint &m_owner; ///< The breakpoint that produced this object.
std::unique_ptr<BreakpointOptions> m_options_ap; ///< Breakpoint options pointer, NULL if we're using our breakpoint's options.
lldb::BreakpointSiteSP m_bp_site_sp; ///< Our breakpoint site (it may be shared by more than one location.)
lldb::ClangUserExpressionSP m_user_expression_sp; ///< The compiled expression to use in testing our condition.
lldb::UserExpressionSP m_user_expression_sp; ///< The compiled expression to use in testing our condition.
Mutex m_condition_mutex; ///< Guards parsing and evaluation of the condition, which could be evaluated by multiple processes.
size_t m_condition_hash; ///< For testing whether the condition source code changed.

Expand Down
2 changes: 1 addition & 1 deletion include/lldb/Breakpoint/Watchpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ class Watchpoint :
// the callback machinery.
bool m_being_created;

std::unique_ptr<ClangUserExpression> m_condition_ap; // The condition to test.
std::unique_ptr<UserExpression> m_condition_ap; // The condition to test.

void SetID(lldb::watch_id_t id) { m_loc_id = id; }

Expand Down
12 changes: 6 additions & 6 deletions include/lldb/Expression/ASTStructExtractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@
#include "clang/Sema/SemaConsumer.h"
#include "lldb/Core/ClangForward.h"
#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
#include "lldb/Expression/ClangFunction.h"
#include "lldb/Expression/ClangFunctionCaller.h"

namespace lldb_private {

//----------------------------------------------------------------------
/// @class ASTStructExtractor ASTStructExtractor.h "lldb/Expression/ASTStructExtractor.h"
/// @brief Extracts and describes the argument structure for a wrapped function.
///
/// This pass integrates with ClangFunction, which calls functions with custom
/// This pass integrates with ClangFunctionCaller, which calls functions with custom
/// sets of arguments. To avoid having to implement the full calling convention
/// for the target's architecture, ClangFunction writes a simple wrapper
/// for the target's architecture, ClangFunctionCaller writes a simple wrapper
/// function that takes a pointer to an argument structure that contains room
/// for the address of the function to be called, the values of all its
/// arguments, and room for the function's return value.
Expand All @@ -49,12 +49,12 @@ class ASTStructExtractor : public clang::SemaConsumer
///
/// @param[in] function
/// The caller object whose members should be populated with information
/// about the argument struct. ClangFunction friends ASTStructExtractor
/// about the argument struct. ClangFunctionCaller friends ASTStructExtractor
/// for this purpose.
//----------------------------------------------------------------------
ASTStructExtractor(clang::ASTConsumer *passthrough,
const char *struct_name,
ClangFunction &function);
ClangFunctionCaller &function);

//----------------------------------------------------------------------
/// Destructor
Expand Down Expand Up @@ -148,7 +148,7 @@ class ASTStructExtractor : public clang::SemaConsumer
clang::Sema *m_sema; ///< The Sema to use.
clang::Action *m_action; ///< The Sema to use, cast to an Action so it's usable.

ClangFunction &m_function; ///< The function to populate with information about the argument structure.
ClangFunctionCaller &m_function; ///< The function to populate with information about the argument structure.
std::string m_struct_name; ///< The name of the structure to extract.
};

Expand Down
79 changes: 79 additions & 0 deletions include/lldb/Expression/ClangExpressionHelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//===-- ClangExpression.h ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_ClangExpression_h_
#define liblldb_ClangExpression_h_

// C Includes
// C++ Includes
#include <string>
#include <map>
#include <vector>

// Other libraries and framework includes
// Project includes

#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/ExpressionTypeSystemHelper.h"

namespace lldb_private {

class RecordingMemoryManager;

//----------------------------------------------------------------------
// ClangExpressionHelper
//----------------------------------------------------------------------
class ClangExpressionHelper : public ExpressionTypeSystemHelper
{
public:
static bool classof(const ExpressionTypeSystemHelper *ts)
{
return ts->getKind() == eKindClangHelper;
}

ClangExpressionHelper () :
ExpressionTypeSystemHelper(ExpressionTypeSystemHelper::LLVMCastKind::eKindClangHelper)
{
}

//------------------------------------------------------------------
/// Destructor
//------------------------------------------------------------------
virtual ~ClangExpressionHelper ()
{
}

//------------------------------------------------------------------
/// Return the object that the parser should use when resolving external
/// values. May be NULL if everything should be self-contained.
//------------------------------------------------------------------
virtual ClangExpressionDeclMap *
DeclMap () = 0;

//------------------------------------------------------------------
/// Return the object that the parser should allow to access ASTs.
/// May be NULL if the ASTs do not need to be transformed.
///
/// @param[in] passthrough
/// The ASTConsumer that the returned transformer should send
/// the ASTs to after transformation.
//------------------------------------------------------------------
virtual clang::ASTConsumer *
ASTTransformer (clang::ASTConsumer *passthrough) = 0;


protected:

};

} // namespace lldb_private

#endif // liblldb_ClangExpression_h_
32 changes: 6 additions & 26 deletions include/lldb/Expression/ClangExpressionParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Error.h"
#include "lldb/Expression/ExpressionParser.h"
#include "lldb/Expression/IRForTarget.h"

#include <string>
Expand All @@ -34,7 +35,7 @@ class IRExecutionUnit;
/// conversion to formats (DWARF bytecode, or JIT compiled machine code)
/// that can be executed.
//----------------------------------------------------------------------
class ClangExpressionParser
class ClangExpressionParser : public ExpressionParser
{
public:
//------------------------------------------------------------------
Expand All @@ -51,13 +52,13 @@ class ClangExpressionParser
/// The expression to be parsed.
//------------------------------------------------------------------
ClangExpressionParser (ExecutionContextScope *exe_scope,
ClangExpression &expr,
Expression &expr,
bool generate_debug_info);

//------------------------------------------------------------------
/// Destructor
//------------------------------------------------------------------
~ClangExpressionParser ();
~ClangExpressionParser () override;

//------------------------------------------------------------------
/// Parse a single expression and convert it to IR using Clang. Don't
Expand All @@ -71,7 +72,7 @@ class ClangExpressionParser
/// success.
//------------------------------------------------------------------
unsigned
Parse (Stream &stream);
Parse (Stream &stream) override;

//------------------------------------------------------------------
/// Ready an already-parsed expression for execution, possibly
Expand Down Expand Up @@ -116,30 +117,9 @@ class ClangExpressionParser
std::shared_ptr<IRExecutionUnit> &execution_unit_sp,
ExecutionContext &exe_ctx,
bool &can_interpret,
lldb_private::ExecutionPolicy execution_policy);
lldb_private::ExecutionPolicy execution_policy) override;

//------------------------------------------------------------------
/// Disassemble the machine code for a JITted function from the target
/// process's memory and print the result to a stream.
///
/// @param[in] stream
/// The stream to print disassembly to.
///
/// @param[in] exc_context
/// The execution context to get the machine code from.
///
/// @return
/// The error generated. If .Success() is true, disassembly succeeded.
//------------------------------------------------------------------
Error
DisassembleFunction (Stream &stream,
ExecutionContext &exe_ctx);

bool
GetGenerateDebugInfo () const;

private:
ClangExpression & m_expr; ///< The expression to be parsed
std::unique_ptr<llvm::LLVMContext> m_llvm_context; ///< The LLVM context to generate IR into
std::unique_ptr<clang::FileManager> m_file_manager; ///< The Clang file manager object used by the compiler
std::unique_ptr<clang::CompilerInstance> m_compiler; ///< The Clang compiler used to parse expressions into IR
Expand Down
Loading

0 comments on commit 97b797f

Please sign in to comment.