[Lldb-commits] [lldb] r110990 - in /lldb/trunk: include/lldb/Expression/ClangExpression.h source/Commands/CommandObjectExpression.cpp source/Expression/ClangExpression.cpp source/Expression/ClangFunction.cpp
Sean Callanan
scallanan at apple.com
Thu Aug 12 17:28:39 PDT 2010
Author: spyffe
Date: Thu Aug 12 19:28:39 2010
New Revision: 110990
URL: http://llvm.org/viewvc/llvm-project?rev=110990&view=rev
Log:
Documented ClangExpression and made parts of it
more sane (i.e., removed dead arguments, made
sensible defaults, etc.)
Modified:
lldb/trunk/include/lldb/Expression/ClangExpression.h
lldb/trunk/source/Commands/CommandObjectExpression.cpp
lldb/trunk/source/Expression/ClangExpression.cpp
lldb/trunk/source/Expression/ClangFunction.cpp
Modified: lldb/trunk/include/lldb/Expression/ClangExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpression.h?rev=110990&r1=110989&r2=110990&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpression.h Thu Aug 12 19:28:39 2010
@@ -35,94 +35,252 @@
class RecordingMemoryManager;
+//----------------------------------------------------------------------
+/// @class ClangExpression ClangExpression.h "lldb/Expression/ClangExpression.h"
+/// @brief Encapsulates a single expression for use with Clang
+///
+/// LLDB uses expressions for various purposes, notably to call functions
+/// and as a backend for the expr command. ClangExpression encapsulates
+/// the objects needed to parse and interpret or JIT an expression. It
+/// uses the Clang parser to produce LLVM IR from the expression.
+//----------------------------------------------------------------------
class ClangExpression
{
public:
-
//------------------------------------------------------------------
- // Constructors and Destructors
+ /// Constructor
+ ///
+ /// Initializes class variabes.
+ ///
+ /// @param[in] target_triple
+ /// The LLVM-friendly target triple for use in initializing the
+ /// compiler.
+ ///
+ /// @param[in] expr_decl_map
+ /// The object that looks up externally-defined names in LLDB's
+ /// debug information.
//------------------------------------------------------------------
ClangExpression(const char *target_triple,
ClangExpressionDeclMap *expr_decl_map);
+ //------------------------------------------------------------------
+ /// Destructor
+ //------------------------------------------------------------------
~ClangExpression();
-
- unsigned Compile();
-
+
+ //------------------------------------------------------------------
+ /// Parse a single expression and convert it to IR using Clang. Wrap
+ /// the expression in a function with signature void ___clang_expr(void*).
+ ///
+ /// @param[in] expr_text
+ /// The text of the expression to be parsed.
+ ///
+ /// @param[in] stream
+ /// The stream to print errors to.
+ ///
+ /// @param[in] add_result_var
+ /// True if a special result variable should be generated for
+ /// the expression.
+ ///
+ /// @return
+ /// The number of errors encountered during parsing. 0 means
+ /// success.
+ //------------------------------------------------------------------
unsigned
ParseExpression (const char *expr_text,
Stream &stream,
bool add_result_var = false);
+ //------------------------------------------------------------------
+ /// Parse a single expression and convert it to IR using Clang. Don't
+ /// wrap the expression in anything at all.
+ ///
+ /// @param[in] expr_text
+ /// The text of the expression to be parsed.
+ ///
+ /// @param[in] stream
+ /// The stream to print errors to.
+ ///
+ /// @param[in] add_result_var
+ /// True if a special result variable should be generated for
+ /// the expression.
+ ///
+ /// @return
+ /// The number of errors encountered during parsing. 0 means
+ /// success.
+ //------------------------------------------------------------------
unsigned
ParseBareExpression (llvm::StringRef expr_text,
Stream &stream,
bool add_result_var = false);
+ //------------------------------------------------------------------
+ /// Convert the IR for an already-parsed expression to DWARF if possible.
+ ///
+ /// @param[in] expr_local_variable_list
+ /// The list of local variables the expression uses, with types, for
+ /// use by the DWARF parser.
+ ///
+ /// @param[in] dwarf_opcode_strm
+ /// The stream to place the resulting DWARF code into.
+ ///
+ /// @return
+ /// True on success; false on failure. On failure, it may be appropriate
+ /// to call PrepareIRForTarget().
+ //------------------------------------------------------------------
bool
ConvertIRToDWARF (ClangExpressionVariableList &excpr_local_variable_list,
StreamString &dwarf_opcode_strm);
+ //------------------------------------------------------------------
+ /// Prepare the IR for an already-parsed expression for execution in the
+ /// target process by (among other things) making all externally-defined
+ /// variables point to offsets from the void* argument.
+ ///
+ /// @return
+ /// True on success; false on failure. On failure, this expression
+ /// cannot be executed by LLDB.
+ //------------------------------------------------------------------
bool
- PrepareIRForTarget (ClangExpressionVariableList &excpr_local_variable_list);
+ PrepareIRForTarget ();
+ //------------------------------------------------------------------
+ /// Use the JIT to compile an already-prepared expression from IR into
+ /// machine code, but keep the code in the current process for now.
+ ///
+ /// @param[in] func_name
+ /// The name of the function to be JITted. By default, the function
+ /// wrapped by ParseExpression().
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
bool
- JITFunction (const ExecutionContext &exc_context, const char *func_name);
+ JITFunction (const char *func_name = "___clang_expr");
+ //------------------------------------------------------------------
+ /// Write the machine code generated by the JIT into the target's memory.
+ ///
+ /// @param[in] exc_context
+ /// The execution context that the JITted code must be copied into.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
bool
WriteJITCode (const ExecutionContext &exc_context);
+ //------------------------------------------------------------------
+ /// Write the machine code generated by the JIT into the target process.
+ ///
+ /// @param[in] func_name
+ /// The name of the function whose address is being requested.
+ /// By default, the function wrapped by ParseExpression().
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
lldb::addr_t
- GetFunctionAddress (const char *name);
+ GetFunctionAddress (const char *func_name = "___clang_expr");
+ //------------------------------------------------------------------
+ /// 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.
+ ///
+ /// @param[in] func_name
+ /// The name of the function to be disassembled. By default, the
+ /// function wrapped by ParseExpression().
+ ///
+ /// @return
+ /// The error generated. If .Success() is true, disassembly succeeded.
+ //------------------------------------------------------------------
Error
- DisassembleFunction (Stream &stream, ExecutionContext &exc_context, const char *name);
+ DisassembleFunction (Stream &stream, ExecutionContext &exc_context, const char *func_name = "___clang_expr");
+ //------------------------------------------------------------------
+ /// Return the Clang compiler instance being used by this expression.
+ //------------------------------------------------------------------
clang::CompilerInstance *
GetCompilerInstance ()
{
return m_clang_ap.get();
}
+ //------------------------------------------------------------------
+ /// Return the AST context being used by this expression.
+ //------------------------------------------------------------------
clang::ASTContext *
GetASTContext ();
+ //------------------------------------------------------------------
+ /// Return the mutex being used to serialize access to Clang.
+ //------------------------------------------------------------------
static Mutex &
GetClangMutex ();
protected:
-
- // This class is a pass-through for the default JIT memory manager,
- // which just records the memory regions that were handed out so we
- // can copy them into the target later on.
-
-
//------------------------------------------------------------------
// Classes that inherit from ClangExpression can see and modify these
//------------------------------------------------------------------
+ //----------------------------------------------------------------------
+ /// @class JittedFunction ClangExpression.h "lldb/Expression/ClangExpression.h"
+ /// @brief Encapsulates a single function that has been generated by the JIT.
+ ///
+ /// Functions that have been generated by the JIT are first resident in the
+ /// local process, and then placed in the target process. JittedFunction
+ /// represents a function possibly resident in both.
+ //----------------------------------------------------------------------
struct JittedFunction {
- std::string m_name;
- lldb::addr_t m_local_addr;
- lldb::addr_t m_remote_addr;
-
+ std::string m_name; ///< The function's name
+ lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory
+ lldb::addr_t m_remote_addr; ///< The address of the function in the target's memory
+
+ //------------------------------------------------------------------
+ /// Constructor
+ ///
+ /// Initializes class variabes.
+ ///
+ /// @param[in] name
+ /// The name of the function.
+ ///
+ /// @param[in] local_addr
+ /// The address of the function in LLDB, or LLDB_INVALID_ADDRESS if
+ /// it is not present in LLDB's memory.
+ ///
+ /// @param[in] remote_addr
+ /// The address of the function in the target, or LLDB_INVALID_ADDRESS
+ /// if it is not present in the target's memory.
+ //------------------------------------------------------------------
JittedFunction (const char *name,
- lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
- lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) :
+ lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
+ lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) :
m_name (name),
m_local_addr (local_addr),
m_remote_addr (remote_addr) {}
};
- std::string m_target_triple;
- ClangExpressionDeclMap *m_decl_map;
- std::auto_ptr<clang::CompilerInstance> m_clang_ap;
- clang::CodeGenerator *m_code_generator_ptr; // This will be deleted by the Execution Engine.
- RecordingMemoryManager *m_jit_mm_ptr; // This will be deleted by the Execution Engine.
- std::auto_ptr<llvm::ExecutionEngine> m_execution_engine;
- std::vector<JittedFunction> m_jitted_functions;
+ std::string m_target_triple; ///< The target triple used to initialize LLVM
+ ClangExpressionDeclMap *m_decl_map; ///< The class used to look up entities defined in the debug info
+ std::auto_ptr<clang::CompilerInstance> m_clang_ap; ///< The Clang compiler used to parse expressions into IR
+ clang::CodeGenerator *m_code_generator_ptr; ///< [owned by the Execution Engine] The Clang object that generates IR
+ RecordingMemoryManager *m_jit_mm_ptr; ///< [owned by the Execution Engine] The memory manager that allocates code pages on the JIT's behalf
+ std::auto_ptr<llvm::ExecutionEngine> m_execution_engine; ///< The LLVM JIT
+ std::vector<JittedFunction> m_jitted_functions; ///< A vector of all functions that have been JITted into machine code (just one, if ParseExpression() was called)
private:
-
- bool CreateCompilerInstance(bool &IsAST);
+ //------------------------------------------------------------------
+ /// Initialize m_clang_ap to a compiler instance with all the options
+ /// required by the expression parser.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool CreateCompilerInstance();
//------------------------------------------------------------------
// For ClangExpression only
Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=110990&r1=110989&r2=110990&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Thu Aug 12 19:28:39 2010
@@ -267,7 +267,7 @@
{
if (log)
log->Printf("Code cannot be interpreted and must be run in the target.");
- success = clang_expr.PrepareIRForTarget (expr_local_vars);
+ success = clang_expr.PrepareIRForTarget ();
}
if (!success)
@@ -283,7 +283,7 @@
}
else
{
- if (!clang_expr.JITFunction (m_exe_ctx, "___clang_expr"))
+ if (!clang_expr.JITFunction ())
{
error_stream.PutCString ("error: IR could not be JIT compiled\n");
return false;
@@ -295,7 +295,7 @@
return false;
}
- lldb::addr_t function_address(clang_expr.GetFunctionAddress ("___clang_expr"));
+ lldb::addr_t function_address(clang_expr.GetFunctionAddress ());
if (function_address == LLDB_INVALID_ADDRESS)
{
@@ -318,7 +318,7 @@
StreamString insns;
- Error err = clang_expr.DisassembleFunction(insns, m_exe_ctx, "___clang_expr");
+ Error err = clang_expr.DisassembleFunction(insns, m_exe_ctx);
if (!err.Success())
{
Modified: lldb/trunk/source/Expression/ClangExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpression.cpp?rev=110990&r1=110989&r2=110990&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpression.cpp Thu Aug 12 19:28:39 2010
@@ -217,7 +217,7 @@
}
bool
-ClangExpression::CreateCompilerInstance (bool &IsAST)
+ClangExpression::CreateCompilerInstance ()
{
// Initialize targets first, so that --version shows registered targets.
static struct InitializeLLVM {
@@ -313,8 +313,7 @@
TextDiagnosticBuffer text_diagnostic_buffer;
- bool IsAST = false;
- if (!CreateCompilerInstance (IsAST))
+ if (!CreateCompilerInstance ())
{
stream.Printf("error: couldn't create compiler instance\n");
return 1;
@@ -462,7 +461,7 @@
}
bool
-ClangExpression::PrepareIRForTarget (ClangExpressionVariableList &expr_local_variable_list)
+ClangExpression::PrepareIRForTarget ()
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
@@ -498,7 +497,7 @@
}
bool
-ClangExpression::JITFunction (const ExecutionContext &exc_context, const char *name)
+ClangExpression::JITFunction (const char *name)
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
@@ -747,89 +746,3 @@
return ret;
}
-
-unsigned
-ClangExpression::Compile()
-{
- Mutex::Locker locker(GetClangMutex ());
- bool IsAST = false;
-
- if (CreateCompilerInstance(IsAST))
- {
- // Validate/process some options
- if (m_clang_ap->getHeaderSearchOpts().Verbose)
- llvm::errs() << "clang-cc version " CLANG_VERSION_STRING
- << " based upon " << PACKAGE_STRING
- << " hosted on " << llvm::sys::getHostTriple() << "\n";
-
- // Enforce certain implications.
- if (!m_clang_ap->getFrontendOpts().ViewClassInheritance.empty())
- m_clang_ap->getFrontendOpts().ProgramAction = frontend::InheritanceView;
-// if (!compiler_instance->getFrontendOpts().FixItSuffix.empty())
-// compiler_instance->getFrontendOpts().ProgramAction = frontend::FixIt;
-
- for (unsigned i = 0, e = m_clang_ap->getFrontendOpts().Inputs.size(); i != e; ++i) {
-
- // If we aren't using an AST file, setup the file and source managers and
- // the preprocessor.
- if (!IsAST) {
- if (!i) {
- // Create a file manager object to provide access to and cache the
- // filesystem.
- m_clang_ap->createFileManager();
-
- // Create the source manager.
- m_clang_ap->createSourceManager();
- } else {
- // Reset the ID tables if we are reusing the SourceManager.
- m_clang_ap->getSourceManager().clearIDTables();
- }
-
- // Create the preprocessor.
- m_clang_ap->createPreprocessor();
- }
-
- llvm::OwningPtr<FrontendAction> Act(CreateFrontendAction(*m_clang_ap.get()));
- if (!Act)
- break;
-
- if (Act->BeginSourceFile(*m_clang_ap,
- m_clang_ap->getFrontendOpts().Inputs[i].second,
- m_clang_ap->getFrontendOpts().Inputs[i].first)) {
- Act->Execute();
- Act->EndSourceFile();
- }
- }
-
- if (m_clang_ap->getDiagnosticOpts().ShowCarets)
- {
- unsigned NumWarnings = m_clang_ap->getDiagnostics().getNumWarnings();
- unsigned NumErrors = m_clang_ap->getDiagnostics().getNumErrors() -
- m_clang_ap->getDiagnostics().getNumErrorsSuppressed();
-
- if (NumWarnings || NumErrors)
- {
- if (NumWarnings)
- fprintf (stderr, "%u warning%s%s", NumWarnings, (NumWarnings == 1 ? "" : "s"), (NumErrors ? " and " : ""));
- if (NumErrors)
- fprintf (stderr, "%u error%s", NumErrors, (NumErrors == 1 ? "" : "s"));
- fprintf (stderr, " generated.\n");
- }
- }
-
- if (m_clang_ap->getFrontendOpts().ShowStats) {
- m_clang_ap->getFileManager().PrintStats();
- fprintf(stderr, "\n");
- }
-
- // Return the appropriate status when verifying diagnostics.
- //
- // FIXME: If we could make getNumErrors() do the right thing, we wouldn't need
- // this.
- if (m_clang_ap->getDiagnosticOpts().VerifyDiagnostics)
- return static_cast<VerifyDiagnosticsClient&>(m_clang_ap->getDiagnosticClient()).HadErrors();
-
- return m_clang_ap->getDiagnostics().getNumErrors();
- }
- return 1;
-}
Modified: lldb/trunk/source/Expression/ClangFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangFunction.cpp?rev=110990&r1=110989&r2=110990&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangFunction.cpp (original)
+++ lldb/trunk/source/Expression/ClangFunction.cpp Thu Aug 12 19:28:39 2010
@@ -258,7 +258,7 @@
if (!m_JITted)
{
// Next we should JIT it and insert the result into the target program.
- if (!JITFunction (exe_ctx, m_wrapper_function_name.c_str()))
+ if (!JITFunction (m_wrapper_function_name.c_str()))
return false;
if (!WriteJITCode (exe_ctx))
More information about the lldb-commits
mailing list