Skip to content

Commit b18f7e6

Browse files
Merge pull request #8694 from adrian-prantl/127123509
Make the user code range detection more robust.
2 parents aef9335 + fa9fea9 commit b18f7e6

File tree

6 files changed

+82
-23
lines changed

6 files changed

+82
-23
lines changed

lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,6 @@ func $__lldb_expr(_ $__lldb_arg : UnsafeMutablePointer<Any>) {
502502
wrapped_expr_text.GetData(), availability.c_str(),
503503
current_counter);
504504
}
505-
first_body_line = 5;
506505
} else if (options.GetBindGenericTypes() == lldb::eDontBind) {
507506
auto c = MakeGenericSignaturesAndCalls(local_variables, generic_sig,
508507
needs_object_ptr);
@@ -536,7 +535,6 @@ func $__lldb_expr(_ $__lldb_arg : UnsafeMutablePointer<Any>) {
536535
"%s" // This is the expression text (with newlines).
537536
"}\n",
538537
availability.c_str(), wrapped_expr_text.GetData());
539-
first_body_line = 4;
540538
}
541539
return status;
542540
}
@@ -564,8 +562,6 @@ Status SwiftExpressionSourceCode::GetText(
564562
llvm::ArrayRef<SwiftASTManipulator::VariableInfo> local_variables) const {
565563
Status status;
566564
Target *target = exe_ctx.GetTargetPtr();
567-
568-
569565
if (m_wrap) {
570566
const char *body = m_body.c_str();
571567
const char *pound_file = options.GetPoundLineFilePath();
@@ -630,7 +626,8 @@ Status SwiftExpressionSourceCode::GetText(
630626
bool need_to_declare_log_functions = num_persistent_results == 0;
631627
EvaluateExpressionOptions localOptions(options);
632628

633-
localOptions.SetPreparePlaygroundStubFunctions(need_to_declare_log_functions);
629+
localOptions.SetPreparePlaygroundStubFunctions(
630+
need_to_declare_log_functions);
634631

635632
std::string full_body = m_prefix + m_body;
636633
status = WrapExpression(wrap_stream, full_body.c_str(), needs_object_ptr,
@@ -645,23 +642,34 @@ Status SwiftExpressionSourceCode::GetText(
645642
text.append(m_body);
646643
}
647644

645+
if (!first_body_line) {
646+
// If this is not a playground or REPL expression, compute the
647+
// first line, by locating the marker. While this could be
648+
// determined statically, it's more future-proof to calculate it
649+
// here.
650+
uint32_t start_idx, end_idx;
651+
if (GetOriginalBodyBounds(text, start_idx, end_idx))
652+
first_body_line =
653+
StringRef(text.data(), text.size() - start_idx).count('\n') + 1;
654+
}
648655
return status;
649656
}
650657

651658
bool SwiftExpressionSourceCode::GetOriginalBodyBounds(
652-
std::string transformed_text,
653-
size_t &start_loc, size_t &end_loc) {
654-
const char *start_marker;
655-
const char *end_marker;
656-
657-
start_marker = GetUserCodeStartMarker();
658-
end_marker = GetUserCodeEndMarker();
659+
std::string transformed_text, uint32_t &start_loc, uint32_t &end_loc) {
660+
StringRef start_marker = GetUserCodeStartMarker();
661+
StringRef end_marker = GetUserCodeEndMarker();
662+
size_t found_loc = transformed_text.find(start_marker);
663+
if (found_loc == StringRef::npos ||
664+
found_loc > std::numeric_limits<uint32_t>::max())
665+
return false;
666+
start_loc = found_loc;
659667

660-
start_loc = transformed_text.find(start_marker);
661-
if (start_loc == std::string::npos)
668+
start_loc += start_marker.size();
669+
found_loc = transformed_text.find(end_marker);
670+
if (found_loc == StringRef::npos ||
671+
found_loc > std::numeric_limits<uint32_t>::max())
662672
return false;
663-
start_loc += strlen(start_marker);
664-
end_loc = transformed_text.find(end_marker);
665-
return end_loc != std::string::npos;
666-
return false;
673+
end_loc = found_loc;
674+
return true;
667675
}

lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class SwiftExpressionSourceCode : public ExpressionSourceCode {
3838
// passed to CreateWrapped. Return true if the bounds could be found. This
3939
// will also work on text with FixItHints applied.
4040
static bool GetOriginalBodyBounds(std::string transformed_text,
41-
size_t &start_loc, size_t &end_loc);
41+
uint32_t &start_loc, uint32_t &end_loc);
4242

4343
uint32_t GetNumBodyLines();
4444

@@ -51,8 +51,8 @@ class SwiftExpressionSourceCode : public ExpressionSourceCode {
5151
llvm::ArrayRef<SwiftASTManipulator::VariableInfo> local_variables) const;
5252

5353
private:
54-
SwiftExpressionSourceCode(const char *name, const char *prefix, const char *body,
55-
Wrapping wrap)
54+
SwiftExpressionSourceCode(const char *name, const char *prefix,
55+
const char *body, Wrapping wrap)
5656
: ExpressionSourceCode(name, prefix, body, wrap) {}
5757
uint32_t m_num_body_lines = 0;
5858
};

lldb/source/Plugins/ExpressionParser/Swift/SwiftUserExpression.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -828,8 +828,8 @@ exe_scope = exe_ctx.GetBestExecutionContextScope();
828828
// If fixits are enabled, calculate the fixed expression string.
829829
if (m_options.GetAutoApplyFixIts() && diagnostic_manager.HasFixIts()) {
830830
if (m_parser->RewriteExpression(diagnostic_manager)) {
831-
size_t fixed_start;
832-
size_t fixed_end;
831+
uint32_t fixed_start;
832+
uint32_t fixed_end;
833833
const std::string &fixed_expression =
834834
diagnostic_manager.GetFixedExpression();
835835
if (SwiftExpressionSourceCode::GetOriginalBodyBounds(
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SWIFT_SOURCES := main.swift
2+
3+
include Makefile.rules
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import lldb
2+
from lldbsuite.test.lldbtest import *
3+
from lldbsuite.test.decorators import *
4+
import lldbsuite.test.lldbutil as lldbutil
5+
import unittest2
6+
7+
class TestSwiftExpressionErrorReportingy(TestBase):
8+
NO_DEBUG_INFO_TESTCASE = True
9+
10+
@swiftTest
11+
def test(self):
12+
"""Test error reporting in expressions reports
13+
only diagnostics in user code"""
14+
self.build()
15+
target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
16+
self, 'break here', lldb.SBFileSpec('main.swift'))
17+
18+
options = lldb.SBExpressionOptions()
19+
value = self.frame().EvaluateExpression(
20+
"ceciNestPasUnVar", options)
21+
def check(value):
22+
lines = str(value.GetError()).split('\n')
23+
self.assertTrue(lines[0].startswith('error:'))
24+
self.assertIn('ceciNestPasUnVar', lines[0])
25+
for line in lines[1:]:
26+
self.assertFalse(line.startswith('error:'))
27+
self.assertFalse(line.startswith('warning:'))
28+
29+
check(value)
30+
process.Continue()
31+
value = self.frame().EvaluateExpression(
32+
"ceciNestPasUnVar", options)
33+
check(value)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class State {
2+
init(x: Int) {
3+
number = x
4+
print("in class") // break here
5+
}
6+
7+
var number:Int
8+
}
9+
10+
func f() {
11+
print("in function") // break here
12+
}
13+
14+
f()
15+
State(x: 20)

0 commit comments

Comments
 (0)