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@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@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits