[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