[Lldb-commits] [lldb] r264662 - Expose top-level Clang expressions via the command line and the API.

Sean Callanan via lldb-commits lldb-commits at lists.llvm.org
Mon Mar 28 14:20:06 PDT 2016


Author: spyffe
Date: Mon Mar 28 16:20:05 2016
New Revision: 264662

URL: http://llvm.org/viewvc/llvm-project?rev=264662&view=rev
Log:
Expose top-level Clang expressions via the command line and the API.

Top-level Clang expressions are expressions that act as new translation units,
and define their own symbols.  They do not have function wrappers like regular
expressions do, and declarations are persistent regardless of use of the dollar
sign in identifiers.  Names defined by these are given priority over all other
symbol lookups.

This patch adds a new expression option, '-p' or '--top-level,' which controls
whether the expression is treated this way.  It also adds a flag controlling 
this to SBExpressionOptions so that this API is usable externally.  It also adds
a test that validates that this works.  (The test requires a fix to the Clang
AST importer which I will be committing shortly.)

<rdar://problem/22864976>

Added:
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/TestTopLevelExprs.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/dummy.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/test.cpp
Modified:
    lldb/trunk/include/lldb/API/SBExpressionOptions.h
    lldb/trunk/include/lldb/Target/Target.h
    lldb/trunk/source/API/SBExpressionOptions.cpp
    lldb/trunk/source/Commands/CommandObjectExpression.cpp
    lldb/trunk/source/Commands/CommandObjectExpression.h

Modified: lldb/trunk/include/lldb/API/SBExpressionOptions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBExpressionOptions.h?rev=264662&r1=264661&r2=264662&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBExpressionOptions.h (original)
+++ lldb/trunk/include/lldb/API/SBExpressionOptions.h Mon Mar 28 16:20:05 2016
@@ -116,6 +116,13 @@ public:
     
     bool
     GetAutoApplyFixIts();
+    
+    bool
+    GetTopLevel ();
+
+    void
+    SetTopLevel (bool b = true);
+
 
 protected:
 

Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=264662&r1=264661&r2=264662&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Mon Mar 28 16:20:05 2016
@@ -260,8 +260,10 @@ class EvaluateExpressionOptions
 {
 public:
     static const uint32_t default_timeout = 500000;
+    static const ExecutionPolicy default_execution_policy = eExecutionPolicyOnlyWhenNeeded;
+    
     EvaluateExpressionOptions() :
-        m_execution_policy(eExecutionPolicyOnlyWhenNeeded),
+        m_execution_policy(default_execution_policy),
         m_language (lldb::eLanguageTypeUnknown),
         m_prefix (), // A prefix specific to this expression that is added after the prefix from the settings (if any)
         m_coerce_to_id (false),

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/Makefile?rev=264662&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/Makefile Mon Mar 28 16:20:05 2016
@@ -0,0 +1,12 @@
+LEVEL = ../../make
+
+default: a.out dummy
+
+CXX_SOURCES := main.cpp test.cpp
+
+dummy: dummy.cpp
+
+clean::
+	rm -rf dummy dummy.dSYM
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/TestTopLevelExprs.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/TestTopLevelExprs.py?rev=264662&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/TestTopLevelExprs.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/TestTopLevelExprs.py Mon Mar 28 16:20:05 2016
@@ -0,0 +1,83 @@
+"""
+Test top-level expressions.
+"""
+
+from __future__ import print_function
+
+
+
+import unittest2
+
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TopLevelExpressionsTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        # Find the line number to break for main.c.
+        self.line = line_number('main.cpp',
+                                '// Set breakpoint here')
+        self.dummy_line = line_number('dummy.cpp',
+                                      '// Set breakpoint here')
+
+        # Disable confirmation prompt to avoid infinite wait
+        self.runCmd("settings set auto-confirm true")
+        self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+
+
+    def build_and_run(self):
+        """Test top-level expressions."""
+        self.build()
+
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=False)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+    def run_dummy(self):
+        self.runCmd("file dummy", CURRENT_EXECUTABLE_SET)
+
+        lldbutil.run_break_set_by_file_and_line (self, "dummy.cpp", self.dummy_line, num_expected_locations=1, loc_exact=False)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+    @add_test_categories(['pyapi'])
+    def test_top_level_expressions(self):
+        self.build_and_run()
+
+        resultFromCode = self.frame().EvaluateExpression("doTest()").GetValueAsUnsigned()
+
+        self.runCmd("kill")
+
+        self.run_dummy()
+
+        codeFile = open('test.cpp', 'r')
+
+        expressions = []
+        current_expression = ""
+
+        for line in codeFile:
+            if line.startswith("// --"):
+                expressions.append(current_expression)
+                current_expression = ""
+            else:
+                current_expression += line
+
+        options = lldb.SBExpressionOptions()
+        options.SetLanguage(lldb.eLanguageTypeC_plus_plus)
+        options.SetTopLevel(True)
+
+        for expression in expressions:
+            self.frame().EvaluateExpression(expression, options)
+
+        resultFromTopLevel = self.frame().EvaluateExpression("doTest()").GetValueAsUnsigned()
+
+        self.assertEqual(resultFromCode, resultFromTopLevel)

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/dummy.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/dummy.cpp?rev=264662&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/dummy.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/dummy.cpp Mon Mar 28 16:20:05 2016
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main()
+{
+    printf("This is a dummy\n"); // Set breakpoint here   
+    return 0;
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/main.cpp?rev=264662&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/main.cpp Mon Mar 28 16:20:05 2016
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+extern int doTest();
+
+int main()
+{
+    printf("%d\n", doTest()); // Set breakpoint here   
+    return 0;
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/test.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/test.cpp?rev=264662&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/test.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/top-level/test.cpp Mon Mar 28 16:20:05 2016
@@ -0,0 +1,63 @@
+class MyClass
+{
+public:
+  int memberResult()
+  {
+    return 1;
+  }
+  static int staticResult()
+  {
+    return 1;
+  }
+  int externResult();
+};
+
+// --
+
+int MyClass::externResult()
+{
+  return 1;
+}
+
+// --
+
+MyClass m;
+
+// --
+
+enum MyEnum {
+  myEnumOne = 1,
+  myEnumTwo,
+  myEnumThree
+};
+
+// --
+
+class AnotherClass
+{
+public:
+    __attribute__ ((always_inline)) int complicatedFunction() 
+    {
+        struct {
+            int i;
+        } s = { 15 };
+    
+        int as[4] = { 2, 3, 4, 5 };
+    
+        for (signed char a : as)
+        {
+            s.i -= a;
+        }
+    
+        return s.i;
+    }
+};
+
+// --
+
+int doTest()
+{
+    return m.memberResult() + MyClass::staticResult() + m.externResult() + MyEnum::myEnumThree + myEnumOne + AnotherClass().complicatedFunction();
+}
+
+// --

Modified: lldb/trunk/source/API/SBExpressionOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBExpressionOptions.cpp?rev=264662&r1=264661&r2=264662&view=diff
==============================================================================
--- lldb/trunk/source/API/SBExpressionOptions.cpp (original)
+++ lldb/trunk/source/API/SBExpressionOptions.cpp Mon Mar 28 16:20:05 2016
@@ -209,6 +209,18 @@ SBExpressionOptions::SetAutoApplyFixIts
     return m_opaque_ap->SetAutoApplyFixIts (b);
 }
 
+bool
+SBExpressionOptions::GetTopLevel ()
+{
+    return m_opaque_ap->GetExecutionPolicy() == eExecutionPolicyTopLevel;
+}
+
+void
+SBExpressionOptions::SetTopLevel (bool b)
+{
+    m_opaque_ap->SetExecutionPolicy(b ? eExecutionPolicyTopLevel : m_opaque_ap->default_execution_policy);
+}
+
 EvaluateExpressionOptions *
 SBExpressionOptions::get() const
 {

Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=264662&r1=264661&r2=264662&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Mon Mar 28 16:20:05 2016
@@ -63,6 +63,7 @@ CommandObjectExpression::CommandOptions:
     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language",           'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage,   "Specifies the Language to use when parsing the expression.  If not set the target.language setting is used." },
     { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "apply-fixits",       'X', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage,   "If true, simple FixIt hints will be automatically applied to the expression." },
     { LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, nullptr, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity,        "How verbose should the output of this expression be, if the object description is asked for."},
+    { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "top-level",          'p', OptionParser::eNoArgument      , NULL, NULL, 0, eArgTypeNone,       "Interpret the expression as top-level definitions rather than code to be immediately executed."}
 };
 
 uint32_t
@@ -149,6 +150,10 @@ CommandObjectExpression::CommandOptions:
         unwind_on_error = false;
         ignore_breakpoints = false;
         break;
+    
+    case 'p':
+        top_level = true;
+        break;
 
     case 'X':
         {
@@ -191,6 +196,7 @@ CommandObjectExpression::CommandOptions:
     language = eLanguageTypeUnknown;
     m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
     auto_apply_fixits = eLazyBoolCalculate;
+    top_level = false;
 }
 
 const OptionDefinition*
@@ -315,6 +321,9 @@ CommandObjectExpression::EvaluateExpress
             auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes ? true : false;
         
         options.SetAutoApplyFixIts(auto_apply_fixits);
+        
+        if (m_command_options.top_level)
+            options.SetExecutionPolicy(eExecutionPolicyTopLevel);
 
         // If there is any chance we are going to stop and want to see
         // what went wrong with our expression, we should generate debug info

Modified: lldb/trunk/source/Commands/CommandObjectExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.h?rev=264662&r1=264661&r2=264662&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.h (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.h Mon Mar 28 16:20:05 2016
@@ -54,6 +54,7 @@ public:
         // Options table: Required for subclasses of Options.
 
         static OptionDefinition g_option_table[];
+        bool        top_level;
         bool        unwind_on_error;
         bool        ignore_breakpoints;
         bool        show_types;




More information about the lldb-commits mailing list