[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