[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:52:51 PDT 2016


N.b., the Clang ASTImporter fixes for this went in as r264669.  Make sure Clang has this fix if your testcases are failing.

Sean

> On Mar 28, 2016, at 2:20 PM, Sean Callanan via lldb-commits <lldb-commits at lists.llvm.org> wrote:
> 
> 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;
> 
> 
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits



More information about the lldb-commits mailing list