From e9adcbfad0d31d4d703fe8fcf56cc73b38e59c07 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 24 Sep 2020 16:17:13 +0200 Subject: [PATCH 001/234] release notes: mention zig as an external project --- llvm/docs/ReleaseNotes.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index 2af813fda1aa9..d724ba09502a5 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -342,6 +342,21 @@ Changes to the LLVM tools * llvm-lib supports adding import library objects in addition to regular object files +External Open Source Projects Using LLVM 11 +=========================================== + +Zig Programming Language +------------------------ + +`Zig `_ is a general-purpose programming language and +toolchain for maintaining robust, optimal, and reusable software. In addition +to supporting LLVM as an optional backend, Zig links Clang and LLD to provide +an out-of-the-box cross compilation experience, not only for Zig code but for +C and C++ code as well. Using a sophisticated caching system, Zig lazily builds +from source compiler-rt, mingw-w64, musl, glibc, libcxx, libcxxabi, and +libunwind for the selected target - a "batteries included" drop-in for GCC/Clang +that works the same on every platform. + Additional Information ====================== From 9ddb0910a22432431a372066564dddda06e4724b Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Fri, 7 Aug 2020 14:44:01 -0700 Subject: [PATCH 002/234] Add a setting to force stepping to always run all threads. Also allow ScriptedThreadPlans to set & get their StopOthers state. Differential Revision: https://reviews.llvm.org/D85265 (cherry picked from commit d3dfd8cec44072302818c34193d898903dbaef8f) --- lldb/bindings/interface/SBThreadPlan.i | 8 +++ lldb/include/lldb/API/SBThreadPlan.h | 4 ++ lldb/include/lldb/Target/Process.h | 1 + lldb/include/lldb/Target/ThreadPlanPython.h | 5 +- lldb/source/API/SBThreadPlan.cpp | 19 +++++++ lldb/source/Commands/CommandObjectThread.cpp | 13 ++++- lldb/source/Target/Process.cpp | 6 ++ lldb/source/Target/TargetProperties.td | 3 + lldb/source/Target/Thread.cpp | 2 +- lldb/source/Target/ThreadPlanPython.cpp | 12 +--- .../functionalities/step_scripted/Steps.py | 22 ++++++- .../step_scripted/TestStepScripted.py | 57 ++++++++++++++++++- 12 files changed, 136 insertions(+), 16 deletions(-) diff --git a/lldb/bindings/interface/SBThreadPlan.i b/lldb/bindings/interface/SBThreadPlan.i index 36131d529b7b7..2003c6fdee3a3 100644 --- a/lldb/bindings/interface/SBThreadPlan.i +++ b/lldb/bindings/interface/SBThreadPlan.i @@ -92,6 +92,14 @@ public: bool IsPlanStale(); + %feature("docstring", "Return whether this plan will ask to stop other threads when it runs.") GetStopOthers; + bool + GetStopOthers(); + + %feature("docstring", "Set whether this plan will ask to stop other threads when it runs.") GetStopOthers; + void + SetStopOthers(bool stop_others); + SBThreadPlan QueueThreadPlanForStepOverRange (SBAddress &start_address, lldb::addr_t range_size); diff --git a/lldb/include/lldb/API/SBThreadPlan.h b/lldb/include/lldb/API/SBThreadPlan.h index 6639c10e437b3..0dc48437a6681 100644 --- a/lldb/include/lldb/API/SBThreadPlan.h +++ b/lldb/include/lldb/API/SBThreadPlan.h @@ -77,6 +77,10 @@ class LLDB_API SBThreadPlan { bool IsValid(); + bool GetStopOthers(); + + void SetStopOthers(bool stop_others); + // This section allows an SBThreadPlan to push another of the common types of // plans... SBThreadPlan QueueThreadPlanForStepOverRange(SBAddress &start_address, diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index bf9b64547ed50..2abedb8f6e2ef 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -91,6 +91,7 @@ class ProcessProperties : public Properties { std::chrono::seconds GetUtilityExpressionTimeout() const; bool GetOSPluginReportsAllThreads() const; void SetOSPluginReportsAllThreads(bool does_report); + bool GetSteppingRunsAllThreads() const; protected: Process *m_process; // Can be nullptr for global ProcessProperties diff --git a/lldb/include/lldb/Target/ThreadPlanPython.h b/lldb/include/lldb/Target/ThreadPlanPython.h index 27bf3a560b1ff..c04500ad5de85 100644 --- a/lldb/include/lldb/Target/ThreadPlanPython.h +++ b/lldb/include/lldb/Target/ThreadPlanPython.h @@ -45,7 +45,9 @@ class ThreadPlanPython : public ThreadPlan { bool WillStop() override; - bool StopOthers() override; + bool StopOthers() override { return m_stop_others; } + + void SetStopOthers(bool new_value) { m_stop_others = new_value; } void DidPush() override; @@ -67,6 +69,7 @@ class ThreadPlanPython : public ThreadPlan { std::string m_error_str; StructuredData::ObjectSP m_implementation_sp; bool m_did_push; + bool m_stop_others; ThreadPlanPython(const ThreadPlanPython &) = delete; const ThreadPlanPython &operator=(const ThreadPlanPython &) = delete; diff --git a/lldb/source/API/SBThreadPlan.cpp b/lldb/source/API/SBThreadPlan.cpp index c740c8b7492fc..9af673b0f3a99 100644 --- a/lldb/source/API/SBThreadPlan.cpp +++ b/lldb/source/API/SBThreadPlan.cpp @@ -196,6 +196,23 @@ bool SBThreadPlan::IsValid() { return false; } +bool SBThreadPlan::GetStopOthers() { + LLDB_RECORD_METHOD_NO_ARGS(bool, SBThreadPlan, GetStopOthers); + + ThreadPlanSP thread_plan_sp(GetSP()); + if (thread_plan_sp) + return thread_plan_sp->StopOthers(); + return false; +} + +void SBThreadPlan::SetStopOthers(bool stop_others) { + LLDB_RECORD_METHOD(void, SBThreadPlan, SetStopOthers, (bool), stop_others); + + ThreadPlanSP thread_plan_sp(GetSP()); + if (thread_plan_sp) + thread_plan_sp->SetStopOthers(stop_others); +} + // This section allows an SBThreadPlan to push another of the common types of // plans... // @@ -463,6 +480,8 @@ void RegisterMethods(Registry &R) { LLDB_REGISTER_METHOD(bool, SBThreadPlan, IsPlanComplete, ()); LLDB_REGISTER_METHOD(bool, SBThreadPlan, IsPlanStale, ()); LLDB_REGISTER_METHOD(bool, SBThreadPlan, IsValid, ()); + LLDB_REGISTER_METHOD(void, SBThreadPlan, SetStopOthers, (bool)); + LLDB_REGISTER_METHOD(bool, SBThreadPlan, GetStopOthers, ()); LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan, QueueThreadPlanForStepOverRange, (lldb::SBAddress &, lldb::addr_t)); diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index f0ad1798fec6a..666c208c32067 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -482,8 +482,16 @@ class ThreadStepScopeOptionGroup : public OptionGroup { // Check if we are in Non-Stop mode TargetSP target_sp = execution_context ? execution_context->GetTargetSP() : TargetSP(); - if (target_sp && target_sp->GetNonStopModeEnabled()) + if (target_sp && target_sp->GetNonStopModeEnabled()) { + // NonStopMode runs all threads by definition, so when it is on we don't + // need to check the process setting for runs all threads. m_run_mode = eOnlyThisThread; + } else { + ProcessSP process_sp = + execution_context ? execution_context->GetProcessSP() : ProcessSP(); + if (process_sp && process_sp->GetSteppingRunsAllThreads()) + m_run_mode = eAllThreads; + } m_avoid_regexp.clear(); m_step_in_target.clear(); @@ -612,8 +620,7 @@ class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed { if (m_options.m_run_mode == eAllThreads) bool_stop_other_threads = false; else if (m_options.m_run_mode == eOnlyDuringStepping) - bool_stop_other_threads = - (m_step_type != eStepTypeOut && m_step_type != eStepTypeScripted); + bool_stop_other_threads = (m_step_type != eStepTypeOut); else bool_stop_other_threads = true; diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 3776a90e546ae..d87f57f8ccacd 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -278,6 +278,12 @@ std::chrono::seconds ProcessProperties::GetUtilityExpressionTimeout() const { return std::chrono::seconds(value); } +bool ProcessProperties::GetSteppingRunsAllThreads() const { + const uint32_t idx = ePropertySteppingRunsAllThreads; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_process_properties[idx].default_uint_value != 0); +} + bool ProcessProperties::GetOSPluginReportsAllThreads() const { const bool fail_value = true; const Property *exp_property = diff --git a/lldb/source/Target/TargetProperties.td b/lldb/source/Target/TargetProperties.td index 58aae058d5d43..7fb9b105ceefb 100644 --- a/lldb/source/Target/TargetProperties.td +++ b/lldb/source/Target/TargetProperties.td @@ -217,6 +217,9 @@ let Definition = "process" in { def UtilityExpressionTimeout: Property<"utility-expression-timeout", "UInt64">, DefaultUnsignedValue<15>, Desc<"The time in seconds to wait for LLDB-internal utility expressions.">; + def SteppingRunsAllThreads: Property<"run-all-threads", "Boolean">, + DefaultFalse, + Desc<"If true, stepping operations will run all threads. This is equivalent to setting the run-mode option to 'all-threads'.">; } let Definition = "platform" in { diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 24cf4bf3ee1ed..94e8c560818d7 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -1380,7 +1380,7 @@ lldb::ThreadPlanSP Thread::QueueThreadPlanForStepScripted( ThreadPlanSP thread_plan_sp(new ThreadPlanPython(*this, class_name, extra_args_impl)); - + thread_plan_sp->SetStopOthers(stop_other_threads); status = QueueThreadPlan(thread_plan_sp, abort_other_plans); return thread_plan_sp; } diff --git a/lldb/source/Target/ThreadPlanPython.cpp b/lldb/source/Target/ThreadPlanPython.cpp index 8171186319f5c..e83f0e9e715e4 100644 --- a/lldb/source/Target/ThreadPlanPython.cpp +++ b/lldb/source/Target/ThreadPlanPython.cpp @@ -25,11 +25,12 @@ using namespace lldb_private; // ThreadPlanPython -ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name, +ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name, StructuredDataImpl *args_data) : ThreadPlan(ThreadPlan::eKindPython, "Python based Thread Plan", thread, eVoteNoOpinion, eVoteNoOpinion), - m_class_name(class_name), m_args_data(args_data), m_did_push(false) { + m_class_name(class_name), m_args_data(args_data), m_did_push(false), + m_stop_others(false) { SetIsMasterPlan(true); SetOkayToDiscard(true); SetPrivate(false); @@ -162,13 +163,6 @@ lldb::StateType ThreadPlanPython::GetPlanRunState() { } // The ones below are not currently exported to Python. - -bool ThreadPlanPython::StopOthers() { - // For now Python plans run all threads, but we should add some controls for - // this. - return false; -} - void ThreadPlanPython::GetDescription(Stream *s, lldb::DescriptionLevel level) { s->Printf("Python thread plan implemented by class %s.", m_class_name.c_str()); diff --git a/lldb/test/API/functionalities/step_scripted/Steps.py b/lldb/test/API/functionalities/step_scripted/Steps.py index 4133cbbe6086a..d41d01d43095e 100644 --- a/lldb/test/API/functionalities/step_scripted/Steps.py +++ b/lldb/test/API/functionalities/step_scripted/Steps.py @@ -75,9 +75,29 @@ def should_stop(self, event): if not self.value.IsValid(): return True - print("Got next value: %d"%(self.value.GetValueAsUnsigned())) if not self.value.GetValueDidChange(): self.child_thread_plan = self.queue_child_thread_plan() return False else: return True + +# This plan does nothing, but sets stop_mode to the +# value of GetStopOthers for this plan. +class StepReportsStopOthers(): + stop_mode_dict = {} + + def __init__(self, thread_plan, args_data, dict): + self.thread_plan = thread_plan + self.key = args_data.GetValueForKey("token").GetStringValue(1000) + + def should_stop(self, event): + self.thread_plan.SetPlanComplete(True) + print("Called in should_stop") + StepReportsStopOthers.stop_mode_dict[self.key] = self.thread_plan.GetStopOthers() + return True + + def should_step(self): + return True + + def explains_stop(self, event): + return True diff --git a/lldb/test/API/functionalities/step_scripted/TestStepScripted.py b/lldb/test/API/functionalities/step_scripted/TestStepScripted.py index 3a7665a34a3c4..cee0885da9c31 100644 --- a/lldb/test/API/functionalities/step_scripted/TestStepScripted.py +++ b/lldb/test/API/functionalities/step_scripted/TestStepScripted.py @@ -1,7 +1,7 @@ """ Tests stepping with scripted thread plans. """ - +import threading import lldb import lldbsuite.test.lldbutil as lldbutil from lldbsuite.test.decorators import * @@ -108,3 +108,58 @@ def do_test_checking_variable(self, use_cli): # And foo should have changed: self.assertTrue(foo_val.GetValueDidChange(), "Foo changed") + + def test_stop_others_from_command(self): + """Test that the stop-others flag is set correctly by the command line. + Also test that the run-all-threads property overrides this.""" + self.do_test_stop_others() + + def run_step(self, stop_others_value, run_mode, token): + import Steps + interp = self.dbg.GetCommandInterpreter() + result = lldb.SBCommandReturnObject() + + cmd = "thread step-scripted -C Steps.StepReportsStopOthers -k token -v %s"%(token) + if run_mode != None: + cmd = cmd + " --run-mode %s"%(run_mode) + print(cmd) + interp.HandleCommand(cmd, result) + self.assertTrue(result.Succeeded(), "Step scripted failed: %s."%(result.GetError())) + print(Steps.StepReportsStopOthers.stop_mode_dict) + value = Steps.StepReportsStopOthers.stop_mode_dict[token] + self.assertEqual(value, stop_others_value, "Stop others has the correct value.") + + def do_test_stop_others(self): + self.build() + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + "Set a breakpoint here", + self.main_source_file) + # First run with stop others false and see that we got that. + thread_id = "" + if sys.version_info.major == 2: + thread_id = str(threading._get_ident()) + else: + thread_id = str(threading.get_ident()) + + # all-threads should set stop others to False. + self.run_step(False, "all-threads", thread_id) + + # this-thread should set stop others to True + self.run_step(True, "this-thread", thread_id) + + # The default value should be stop others: + self.run_step(True, None, thread_id) + + # The target.process.run-all-threads should override this: + interp = self.dbg.GetCommandInterpreter() + result = lldb.SBCommandReturnObject() + + interp.HandleCommand("settings set target.process.run-all-threads true", result) + self.assertTrue(result.Succeeded, "setting run-all-threads works.") + + self.run_step(False, None, thread_id) + + + + + From 815b4c0df7080446775bf2c58867b8dedb9c5650 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Thu, 13 Aug 2020 17:41:14 -0700 Subject: [PATCH 003/234] Add python enumerators for SBTypeEnumMemberList, and some tests for this API. Differential Revision: https://reviews.llvm.org/D85951 --- lldb/bindings/interface/SBTypeEnumMember.i | 39 +++++++++++++-- .../API/lang/c/enum_types/TestEnumTypes.py | 50 ++++++++++++++++--- lldb/test/API/lang/c/enum_types/main.c | 4 +- 3 files changed, 80 insertions(+), 13 deletions(-) diff --git a/lldb/bindings/interface/SBTypeEnumMember.i b/lldb/bindings/interface/SBTypeEnumMember.i index 006bdeaa8cee1..518e2bf90115a 100644 --- a/lldb/bindings/interface/SBTypeEnumMember.i +++ b/lldb/bindings/interface/SBTypeEnumMember.i @@ -71,10 +71,18 @@ protected: SBTypeEnumMember (const lldb::TypeEnumMemberImplSP &); }; -%feature( - "docstring", - "Represents a list of SBTypeEnumMembers." -) SBTypeEnumMemberList; +%feature("docstring", +"Represents a list of SBTypeEnumMembers. +SBTypeEnumMemberList supports SBTypeEnumMember iteration. +It also supports [] access either by index, or by enum +element name by doing: + + myType = target.FindFirstType('MyEnumWithElementA') + members = myType.GetEnumMembers() + first_elem = members[0] + elem_A = members['A'] + +") SBTypeEnumMemberList; class SBTypeEnumMemberList { @@ -99,6 +107,29 @@ public: uint32_t GetSize(); +#ifdef SWIGPYTHON + %pythoncode %{ + def __iter__(self): + '''Iterate over all members in a lldb.SBTypeEnumMemberList object.''' + return lldb_iter(self, 'GetSize', 'GetTypeEnumMemberAtIndex') + + def __len__(self): + '''Return the number of members in a lldb.SBTypeEnumMemberList object.''' + return self.GetSize() + + def __getitem__(self, key): + num_elements = self.GetSize() + if type(key) is int: + if key < num_elements: + return self.GetTypeEnumMemberAtIndex(key) + elif type(key) is str: + for idx in range(num_elements): + item = self.GetTypeEnumMemberAtIndex(idx) + if item.name == key: + return item + return None + %} +#endif private: std::unique_ptr m_opaque_ap; diff --git a/lldb/test/API/lang/c/enum_types/TestEnumTypes.py b/lldb/test/API/lang/c/enum_types/TestEnumTypes.py index cb5bb8eccaa29..0442dd34196a2 100644 --- a/lldb/test/API/lang/c/enum_types/TestEnumTypes.py +++ b/lldb/test/API/lang/c/enum_types/TestEnumTypes.py @@ -18,11 +18,9 @@ def setUp(self): # Find the line number to break inside main(). self.line = line_number('main.c', '// Set break point at this line.') - def test(self): - """Test 'image lookup -t days' and check for correct display and enum value printing.""" + def test_command_line(self): + """Test 'image lookup -t enum_test_days' and check for correct display and enum value printing.""" self.build() - exe = self.getBuildArtifact("a.out") - self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) lldbutil.run_to_source_breakpoint( self, '// Breakpoint for bitfield', lldb.SBFileSpec("main.c")) @@ -63,10 +61,10 @@ def test(self): self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, substrs=[' resolved, hit count = 1']) - # Look up information about the 'days' enum type. + # Look up information about the 'enum_test_days' enum type. # Check for correct display. - self.expect("image lookup -t days", DATA_TYPES_DISPLAYED_CORRECTLY, - substrs=['enum days {', + self.expect("image lookup -t enum_test_days", DATA_TYPES_DISPLAYED_CORRECTLY, + substrs=['enum enum_test_days {', 'Monday', 'Tuesday', 'Wednesday', @@ -124,3 +122,41 @@ def test(self): 'check for valid enumeration value', substrs=[enum_value]) lldbutil.continue_to_breakpoint(self.process(), bkpt) + + def check_enum_members(self, members): + name_matches = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "kNumDays"] + value_matches = [-3, -2, -1, 0, 1, 2, 3, 4] + + # First test that the list of members from the type works + num_matches = len(name_matches) + self.assertEqual(len(members), num_matches, "enum_members returns the right number of elements") + for idx in range(0, num_matches): + member = members[idx] + self.assertTrue(member.IsValid(), "Got a valid member for idx: %d"%(idx)) + self.assertEqual(member.name, name_matches[idx], "Name matches for %d"%(idx)) + self.assertEqual(member.signed, value_matches[idx], "Value matches for %d"%(idx)) + + def test_api(self): + """Test the the SBTypeEnumMember API's work correctly for enum_test_days""" + self.build() + target = lldbutil.run_to_breakpoint_make_target(self) + + types = target.FindTypes("enum_test_days") + self.assertEqual(len(types), 1, "Found more than one enum_test_days type...") + type = types.GetTypeAtIndex(0) + + # First check using the Python list returned by the type: + self.check_enum_members(type.enum_members) + + # Now use the SBTypeEnumMemberList. + member_list = type.GetEnumMembers() + self.check_enum_members(member_list) + + # Now check that the by name accessor works: + for member in member_list: + name = member.name + check_member = member_list[name] + self.assertTrue(check_member.IsValid(), "Got a valid member for %s."%(name)) + self.assertEqual(name, check_member.name, "Got back the right name") + self.assertEqual(member.unsigned, check_member.unsigned) + diff --git a/lldb/test/API/lang/c/enum_types/main.c b/lldb/test/API/lang/c/enum_types/main.c index b866044e5e125..0aa73c970ec6f 100644 --- a/lldb/test/API/lang/c/enum_types/main.c +++ b/lldb/test/API/lang/c/enum_types/main.c @@ -25,7 +25,7 @@ int main (int argc, char const *argv[]) Beta = 4 }; - enum days { + enum enum_test_days { Monday = -3, Tuesday, Wednesday, @@ -40,7 +40,7 @@ int main (int argc, char const *argv[]) int nonsense = a + b + c + ab + ac + all; enum non_bitfield omega = Alpha | Beta; - enum days day; + enum enum_test_days day; struct foo f; f.op = NULL; // Breakpoint for bitfield for (day = Monday - 1; day <= kNumDays + 1; day++) From 823f635cb0f11ea7d4c36e4a3c309dc190c3e386 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Mon, 21 Sep 2020 17:26:39 -0700 Subject: [PATCH 004/234] Fix reporting the lack of global variables in "target var". There was a little thinko which meant when stopped in a frame with debug information but whose CU didn't have any global variables we report: no debug info for frame This patch fixes that error message to say the intended: no global variables in current compile unit (cherry picked from commit 94b0d836a105116220052313df5a58473f706cdf) --- lldb/source/Commands/CommandObjectTarget.cpp | 1 + .../target_var/no_vars/Makefile | 3 +++ .../target_var/no_vars/TestTargetVarNoVars.py | 21 +++++++++++++++++++ .../functionalities/target_var/no_vars/main.c | 5 +++++ 4 files changed, 30 insertions(+) create mode 100644 lldb/test/API/functionalities/target_var/no_vars/Makefile create mode 100644 lldb/test/API/functionalities/target_var/no_vars/TestTargetVarNoVars.py create mode 100644 lldb/test/API/functionalities/target_var/no_vars/main.c diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index 9c0620092fb52..c6a7dd3c77baa 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -922,6 +922,7 @@ class CommandObjectTargetVariable : public CommandObjectParsed { CompileUnit *comp_unit = nullptr; if (frame) { SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit); + comp_unit = sc.comp_unit; if (sc.comp_unit) { const bool can_create = true; VariableListSP comp_unit_varlist_sp( diff --git a/lldb/test/API/functionalities/target_var/no_vars/Makefile b/lldb/test/API/functionalities/target_var/no_vars/Makefile new file mode 100644 index 0000000000000..10495940055b6 --- /dev/null +++ b/lldb/test/API/functionalities/target_var/no_vars/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/functionalities/target_var/no_vars/TestTargetVarNoVars.py b/lldb/test/API/functionalities/target_var/no_vars/TestTargetVarNoVars.py new file mode 100644 index 0000000000000..60ca8b1252b35 --- /dev/null +++ b/lldb/test/API/functionalities/target_var/no_vars/TestTargetVarNoVars.py @@ -0,0 +1,21 @@ +""" +Test that target var with no variables returns a correct error +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestTargetVarNoVars(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + NO_DEBUG_INFO_TESTCASE = True + + def test_target_var_no_vars(self): + self.build() + lldbutil.run_to_name_breakpoint(self, 'main') + self.expect("target variable", substrs=['no global variables in current compile unit', 'main.c'], error=True) + diff --git a/lldb/test/API/functionalities/target_var/no_vars/main.c b/lldb/test/API/functionalities/target_var/no_vars/main.c new file mode 100644 index 0000000000000..d7877b0a519bb --- /dev/null +++ b/lldb/test/API/functionalities/target_var/no_vars/main.c @@ -0,0 +1,5 @@ +int +main(int argc, char **argv) +{ + return argc; +} From e6f23784f6f498400a1a2dca2cc85ac9af3aea8d Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Tue, 22 Sep 2020 18:05:46 -0700 Subject: [PATCH 005/234] Add `breakpoint delete --disabled`: deletes all disabled breakpoints. Differential Revision: https://reviews.llvm.org/D88129 (cherry picked from commit 3726ac41e9e00d2f6f87779b68f91ea264223c8a) --- .../Commands/CommandObjectBreakpoint.cpp | 48 +++++++++++++++---- lldb/source/Commands/Options.td | 3 ++ .../TestBreakpointCommand.py | 30 ++++++++++++ 3 files changed, 73 insertions(+), 8 deletions(-) diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp index be7ef8a1b60bd..3ac3905befa10 100644 --- a/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -1407,7 +1407,8 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed { class CommandOptions : public Options { public: - CommandOptions() : Options(), m_use_dummy(false), m_force(false) {} + CommandOptions() : Options(), m_use_dummy(false), m_force(false), + m_delete_disabled(false) {} ~CommandOptions() override = default; @@ -1424,6 +1425,10 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed { case 'D': m_use_dummy = true; break; + + case 'd': + m_delete_disabled = true; + break; default: llvm_unreachable("Unimplemented option"); @@ -1435,6 +1440,7 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed { void OptionParsingStarting(ExecutionContext *execution_context) override { m_use_dummy = false; m_force = false; + m_delete_disabled = false; } llvm::ArrayRef GetDefinitions() override { @@ -1444,16 +1450,18 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed { // Instance variables to hold the values for command options. bool m_use_dummy; bool m_force; + bool m_delete_disabled; }; protected: bool DoExecute(Args &command, CommandReturnObject &result) override { Target &target = GetSelectedOrDummyTarget(m_options.m_use_dummy); - + result.Clear(); + std::unique_lock lock; target.GetBreakpointList().GetListMutex(lock); - const BreakpointList &breakpoints = target.GetBreakpointList(); + BreakpointList &breakpoints = target.GetBreakpointList(); size_t num_breakpoints = breakpoints.GetSize(); @@ -1463,7 +1471,7 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed { return false; } - if (command.empty()) { + if (command.empty() && !m_options.m_delete_disabled) { if (!m_options.m_force && !m_interpreter.Confirm( "About to delete all breakpoints, do you want to do that?", @@ -1479,10 +1487,34 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed { } else { // Particular breakpoint selected; disable that breakpoint. BreakpointIDList valid_bp_ids; - CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( - command, &target, result, &valid_bp_ids, - BreakpointName::Permissions::PermissionKinds::deletePerm); - + + if (m_options.m_delete_disabled) { + BreakpointIDList excluded_bp_ids; + + if (!command.empty()) { + CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( + command, &target, result, &excluded_bp_ids, + BreakpointName::Permissions::PermissionKinds::deletePerm); + } + for (auto breakpoint_sp : breakpoints.Breakpoints()) { + if (!breakpoint_sp->IsEnabled() && breakpoint_sp->AllowDelete()) { + BreakpointID bp_id(breakpoint_sp->GetID()); + size_t pos = 0; + if (!excluded_bp_ids.FindBreakpointID(bp_id, &pos)) + valid_bp_ids.AddBreakpointID(breakpoint_sp->GetID()); + } + } + if (valid_bp_ids.GetSize() == 0) { + result.AppendError("No disabled breakpoints."); + result.SetStatus(eReturnStatusFailed); + return false; + } + } else { + CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs( + command, &target, result, &valid_bp_ids, + BreakpointName::Permissions::PermissionKinds::deletePerm); + } + if (result.Succeeded()) { int delete_count = 0; int disable_count = 0; diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index cdb102202edc5..5397c124ce4f7 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -224,6 +224,9 @@ let Command = "breakpoint delete" in { def breakpoint_delete_dummy_breakpoints : Option<"dummy-breakpoints", "D">, Group<1>, Desc<"Delete Dummy breakpoints - i.e. breakpoints set before a " "file is provided, which prime new targets.">; + def breakpoint_delete_disabled : Option<"disabled", "d">, Group<1>, + Desc<"Delete all breakpoints which are currently disabled. When using the disabled option " + "any breakpoints listed on the command line are EXCLUDED from deletion.">; } let Command = "breakpoint name" in { diff --git a/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py b/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py index 9a66df9a798b7..69e8862808394 100644 --- a/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py +++ b/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py @@ -287,3 +287,33 @@ def breakpoint_commands_on_creation(self): self.assertEqual(com_list.GetStringAtIndex(0), "bt", "First bt") self.assertEqual(com_list.GetStringAtIndex(1), "thread list", "Next thread list") self.assertEqual(com_list.GetStringAtIndex(2), "continue", "Last continue") + + def test_breakpoint_delete_disabled(self): + """Test 'break delete --disabled' works""" + self.build() + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target.IsValid(), "Created an invalid target.") + + bp_1 = target.BreakpointCreateByName("main") + bp_2 = target.BreakpointCreateByName("not_here") + bp_3 = target.BreakpointCreateByName("main") + bp_3.AddName("DeleteMeNot") + + bp_1.SetEnabled(False) + bp_3.SetEnabled(False) + + bp_id_1 = bp_1.GetID() + bp_id_2 = bp_2.GetID() + bp_id_3 = bp_3.GetID() + + self.runCmd("breakpoint delete --disabled DeleteMeNot") + + bp_1 = target.FindBreakpointByID(bp_id_1) + self.assertFalse(bp_1.IsValid(), "Didn't delete disabled breakpoint 1") + + bp_2 = target.FindBreakpointByID(bp_id_2) + self.assertTrue(bp_2.IsValid(), "Deleted enabled breakpoint 2") + + bp_3 = target.FindBreakpointByID(bp_id_3) + self.assertTrue(bp_3.IsValid(), "DeleteMeNot didn't protect disabled breakpoint 3") From 633db02167ce2c7f559620b0f804ad6f174305eb Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Tue, 8 Sep 2020 13:39:52 -0700 Subject: [PATCH 006/234] [Instruction] Add dropLocation and updateLocationAfterHoist helpers Introduce a helper which can be used to update the debug location of an Instruction after the instruction is hoisted. This can be used to safely drop a source location as recommended by the docs. For more context, see the discussion in https://reviews.llvm.org/D60913. Differential Revision: https://reviews.llvm.org/D85670 (cherry picked from commit dfc5a9eb57aaaac972764bf731503419284bd3dc) --- llvm/include/llvm/IR/Instruction.h | 14 ++++ llvm/lib/IR/DebugInfo.cpp | 32 +++++++++ llvm/lib/Transforms/Scalar/GVN.cpp | 4 +- llvm/lib/Transforms/Scalar/LICM.cpp | 5 +- .../DebugInfo/Generic/licm-hoist-debug-loc.ll | 3 +- llvm/test/Transforms/GVN/PRE/phi-translate.ll | 7 +- .../LICM/hoisting-preheader-debugloc.ll | 2 +- llvm/unittests/IR/InstructionsTest.cpp | 72 +++++++++++++++++++ 8 files changed, 125 insertions(+), 14 deletions(-) diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h index a03eac0ad40d6..7ccc679df4906 100644 --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -492,6 +492,20 @@ class Instruction : public User, /// merged DebugLoc. void applyMergedLocation(const DILocation *LocA, const DILocation *LocB); + /// Updates the debug location given that the instruction has been hoisted + /// from a block to a predecessor of that block. + /// Note: it is undefined behavior to call this on an instruction not + /// currently inserted into a function. + void updateLocationAfterHoist(); + + /// Drop the instruction's debug location. This does not guarantee removal + /// of the !dbg source location attachment, as it must set a line 0 location + /// with scope information attached on call instructions. To guarantee + /// removal of the !dbg attachment, use the \ref setDebugLoc() API. + /// Note: it is undefined behavior to call this on an instruction not + /// currently inserted into a function. + void dropLocation(); + private: /// Return true if we have an entry in the on-the-side metadata hash. bool hasMetadataHashEntry() const { diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index a6ee5cbb0b3c3..fd3016710298a 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -696,6 +696,38 @@ void Instruction::applyMergedLocation(const DILocation *LocA, setDebugLoc(DILocation::getMergedLocation(LocA, LocB)); } +void Instruction::updateLocationAfterHoist() { dropLocation(); } + +void Instruction::dropLocation() { + const DebugLoc &DL = getDebugLoc(); + if (!DL) + return; + + // If this isn't a call, drop the location to allow a location from a + // preceding instruction to propagate. + if (!isa(this)) { + setDebugLoc(DebugLoc()); + return; + } + + // Set a line 0 location for calls to preserve scope information in case + // inlining occurs. + const DISubprogram *SP = getFunction()->getSubprogram(); + if (SP) + // If a function scope is available, set it on the line 0 location. When + // hoisting a call to a predecessor block, using the function scope avoids + // making it look like the callee was reached earlier than it should be. + setDebugLoc(DebugLoc::get(0, 0, SP)); + else + // The parent function has no scope. Go ahead and drop the location. If + // the parent function is inlined, and the callee has a subprogram, the + // inliner will attach a location to the call. + // + // One alternative is to set a line 0 location with the existing scope and + // inlinedAt info. The location might be sensitive to when inlining occurs. + setDebugLoc(DebugLoc()); +} + //===----------------------------------------------------------------------===// // LLVM C API implementations. //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index b16f8591b5a46..3953ac52ba277 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -46,7 +46,6 @@ #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" -#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" @@ -1251,8 +1250,7 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock, // Instructions that have been inserted in predecessor(s) to materialize // the load address do not retain their original debug locations. Doing // so could lead to confusing (but correct) source attributions. - if (const DebugLoc &DL = I->getDebugLoc()) - I->setDebugLoc(DebugLoc::get(0, 0, DL.getScope(), DL.getInlinedAt())); + I->updateLocationAfterHoist(); // FIXME: We really _ought_ to insert these value numbers into their // parent's availability map. However, in doing so, we risk getting into diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp index 1a22edaf87266..1adf3c4236aa2 100644 --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -1658,10 +1658,7 @@ static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop, // Move the new node to the destination block, before its terminator. moveInstructionBefore(I, *Dest->getTerminator(), *SafetyInfo, MSSAU, SE); - // Apply line 0 debug locations when we are moving instructions to different - // basic blocks because we want to avoid jumpy line tables. - if (const DebugLoc &DL = I.getDebugLoc()) - I.setDebugLoc(DebugLoc::get(0, 0, DL.getScope(), DL.getInlinedAt())); + I.updateLocationAfterHoist(); if (isa(I)) ++NumMovedLoads; diff --git a/llvm/test/DebugInfo/Generic/licm-hoist-debug-loc.ll b/llvm/test/DebugInfo/Generic/licm-hoist-debug-loc.ll index 0a13e9604f0c8..37c642170aa39 100644 --- a/llvm/test/DebugInfo/Generic/licm-hoist-debug-loc.ll +++ b/llvm/test/DebugInfo/Generic/licm-hoist-debug-loc.ll @@ -18,9 +18,8 @@ ; We make sure that the instruction that is hoisted into the preheader ; does not have a debug location. ; CHECK: for.body.lr.ph: -; CHECK: getelementptr{{.*}}%p.addr, i64 4{{.*}} !dbg [[zero:![0-9]+]] +; CHECK: getelementptr{{.*}}%p.addr, i64 4{{$}} ; CHECK: for.body: -; CHECK: [[zero]] = !DILocation(line: 0 ; ; ModuleID = 't.ll' source_filename = "test.c" diff --git a/llvm/test/Transforms/GVN/PRE/phi-translate.ll b/llvm/test/Transforms/GVN/PRE/phi-translate.ll index f80e002eab0ad..2b6a577d66784 100644 --- a/llvm/test/Transforms/GVN/PRE/phi-translate.ll +++ b/llvm/test/Transforms/GVN/PRE/phi-translate.ll @@ -4,8 +4,8 @@ target datalayout = "e-p:64:64:64" ; CHECK-LABEL: @foo( ; CHECK: entry.end_crit_edge: -; CHECK: %[[INDEX:[a-z0-9.]+]] = sext i32 %x to i64{{.*}} !dbg [[ZERO_LOC:![0-9]+]] -; CHECK: %[[ADDRESS:[a-z0-9.]+]] = getelementptr [100 x i32], [100 x i32]* @G, i64 0, i64 %[[INDEX]]{{.*}} !dbg [[ZERO_LOC]] +; CHECK: %[[INDEX:[a-z0-9.]+]] = sext i32 %x to i64{{$}} +; CHECK: %[[ADDRESS:[a-z0-9.]+]] = getelementptr [100 x i32], [100 x i32]* @G, i64 0, i64 %[[INDEX]]{{$}} ; CHECK: %n.pre = load i32, i32* %[[ADDRESS]], align 4, !dbg [[N_LOC:![0-9]+]] ; CHECK: br label %end ; CHECK: then: @@ -14,8 +14,7 @@ target datalayout = "e-p:64:64:64" ; CHECK: %n = phi i32 [ %n.pre, %entry.end_crit_edge ], [ %z, %then ], !dbg [[N_LOC]] ; CHECK: ret i32 %n -; CHECK-DAG: [[N_LOC]] = !DILocation(line: 47, column: 1, scope: !{{.*}}) -; CHECK-DAG: [[ZERO_LOC]] = !DILocation(line: 0 +; CHECK: [[N_LOC]] = !DILocation(line: 47, column: 1, scope: !{{.*}}) @G = external global [100 x i32] define i32 @foo(i32 %x, i32 %z) !dbg !6 { diff --git a/llvm/test/Transforms/LICM/hoisting-preheader-debugloc.ll b/llvm/test/Transforms/LICM/hoisting-preheader-debugloc.ll index 3721f09eef8fe..381d9c77ecd8b 100644 --- a/llvm/test/Transforms/LICM/hoisting-preheader-debugloc.ll +++ b/llvm/test/Transforms/LICM/hoisting-preheader-debugloc.ll @@ -1,6 +1,6 @@ ; RUN: opt -S -licm < %s | FileCheck %s -; CHECK: %arrayidx4.promoted = load i32, i32* %arrayidx4, align 1, !tbaa !59 +; CHECK: %arrayidx4.promoted = load i32, i32* %arrayidx4, align 1, !tbaa !{{[0-9]+$}} target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/llvm/unittests/IR/InstructionsTest.cpp b/llvm/unittests/IR/InstructionsTest.cpp index b25eee7279af9..1324fe2d1dd70 100644 --- a/llvm/unittests/IR/InstructionsTest.cpp +++ b/llvm/unittests/IR/InstructionsTest.cpp @@ -13,6 +13,7 @@ #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" @@ -1304,5 +1305,76 @@ TEST(InstructionsTest, UnaryOperator) { I->deleteValue(); } +TEST(InstructionsTest, DropLocation) { + LLVMContext C; + std::unique_ptr M = parseIR(C, + R"( + declare void @callee() + + define void @no_parent_scope() { + call void @callee() ; I1: Call with no location. + call void @callee(), !dbg !11 ; I2: Call with location. + ret void, !dbg !11 ; I3: Non-call with location. + } + + define void @with_parent_scope() !dbg !8 { + call void @callee() ; I1: Call with no location. + call void @callee(), !dbg !11 ; I2: Call with location. + ret void, !dbg !11 ; I3: Non-call with location. + } + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!3, !4} + !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) + !1 = !DIFile(filename: "t2.c", directory: "foo") + !2 = !{} + !3 = !{i32 2, !"Dwarf Version", i32 4} + !4 = !{i32 2, !"Debug Info Version", i32 3} + !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, retainedNodes: !2) + !9 = !DISubroutineType(types: !10) + !10 = !{null} + !11 = !DILocation(line: 2, column: 7, scope: !8, inlinedAt: !12) + !12 = !DILocation(line: 3, column: 8, scope: !8) + )"); + ASSERT_TRUE(M); + + { + Function *NoParentScopeF = + cast(M->getNamedValue("no_parent_scope")); + BasicBlock &BB = NoParentScopeF->front(); + + auto *I1 = BB.getFirstNonPHI(); + auto *I2 = I1->getNextNode(); + auto *I3 = BB.getTerminator(); + + EXPECT_EQ(I1->getDebugLoc(), DebugLoc()); + I1->dropLocation(); + EXPECT_EQ(I1->getDebugLoc(), DebugLoc()); + + EXPECT_EQ(I2->getDebugLoc().getLine(), 2U); + I2->dropLocation(); + EXPECT_EQ(I1->getDebugLoc(), DebugLoc()); + + EXPECT_EQ(I3->getDebugLoc().getLine(), 2U); + I3->dropLocation(); + EXPECT_EQ(I3->getDebugLoc(), DebugLoc()); + } + + { + Function *WithParentScopeF = + cast(M->getNamedValue("with_parent_scope")); + BasicBlock &BB = WithParentScopeF->front(); + + auto *I2 = BB.getFirstNonPHI()->getNextNode(); + + MDNode *Scope = cast(WithParentScopeF->getSubprogram()); + EXPECT_EQ(I2->getDebugLoc().getLine(), 2U); + I2->dropLocation(); + EXPECT_EQ(I2->getDebugLoc().getLine(), 0U); + EXPECT_EQ(I2->getDebugLoc().getScope(), Scope); + EXPECT_EQ(I2->getDebugLoc().getInlinedAt(), nullptr); + } +} + } // end anonymous namespace } // end namespace llvm From 3887971e27067b473b0fef7848a2a24cc032e80e Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Thu, 16 Jul 2020 11:34:50 -0700 Subject: [PATCH 007/234] Add an option (-y) to "break set" and "source list" that uses the same file:line:column form that we use to print out locations. Since we print them this way it makes sense we also accept that form. Differential Revision: https://reviews.llvm.org/D83975 (cherry picked from commit bc0a9a17a4a658153f4b524da3274d33a98d1c5b) --- lldb/include/lldb/Interpreter/OptionValue.h | 3 + .../Interpreter/OptionValueFileColonLine.h | 64 ++++++++ lldb/include/lldb/Interpreter/OptionValues.h | 1 + lldb/include/lldb/lldb-defines.h | 2 + lldb/include/lldb/lldb-enumerations.h | 1 + .../Python/lldbsuite/test/lldbutil.py | 36 +++++ .../Commands/CommandObjectBreakpoint.cpp | 18 ++- lldb/source/Commands/CommandObjectSource.cpp | 17 ++ lldb/source/Commands/Options.td | 17 +- lldb/source/Interpreter/CMakeLists.txt | 1 + lldb/source/Interpreter/CommandObject.cpp | 1 + lldb/source/Interpreter/OptionValue.cpp | 2 + lldb/source/Interpreter/OptionValueArray.cpp | 1 + .../Interpreter/OptionValueDictionary.cpp | 1 + .../Interpreter/OptionValueFileColonLine.cpp | 145 ++++++++++++++++++ .../Interpreter/OptionValueFileSpec.cpp | 7 - lldb/source/Interpreter/Property.cpp | 6 + .../breakpoint_by_file_colon_line/Makefile | 4 + .../TestBreakpointByFileColonLine.py | 42 +++++ .../breakpoint_by_file_colon_line/main.c | 14 ++ .../API/source-manager/TestSourceManager.py | 8 + lldb/unittests/Interpreter/CMakeLists.txt | 1 + .../TestOptionValueFileColonLine.cpp | 57 +++++++ 23 files changed, 436 insertions(+), 13 deletions(-) create mode 100644 lldb/include/lldb/Interpreter/OptionValueFileColonLine.h create mode 100644 lldb/source/Interpreter/OptionValueFileColonLine.cpp create mode 100644 lldb/test/API/functionalities/breakpoint/breakpoint_by_file_colon_line/Makefile create mode 100644 lldb/test/API/functionalities/breakpoint/breakpoint_by_file_colon_line/TestBreakpointByFileColonLine.py create mode 100644 lldb/test/API/functionalities/breakpoint/breakpoint_by_file_colon_line/main.c create mode 100644 lldb/unittests/Interpreter/TestOptionValueFileColonLine.cpp diff --git a/lldb/include/lldb/Interpreter/OptionValue.h b/lldb/include/lldb/Interpreter/OptionValue.h index 5b07427094bf2..27a5ddea116b6 100644 --- a/lldb/include/lldb/Interpreter/OptionValue.h +++ b/lldb/include/lldb/Interpreter/OptionValue.h @@ -31,6 +31,7 @@ class OptionValue { eTypeChar, eTypeDictionary, eTypeEnum, + eTypeFileLineColumn, eTypeFileSpec, eTypeFileSpecList, eTypeFormat, @@ -135,6 +136,8 @@ class OptionValue { return eTypeDictionary; case 1u << eTypeEnum: return eTypeEnum; + case 1u << eTypeFileLineColumn: + return eTypeFileLineColumn; case 1u << eTypeFileSpec: return eTypeFileSpec; case 1u << eTypeFileSpecList: diff --git a/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h b/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h new file mode 100644 index 0000000000000..6285c03afa149 --- /dev/null +++ b/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h @@ -0,0 +1,64 @@ +//===-- OptionValueFileColonLine.h -----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_INTERPRETER_OPTIONVALUEFILECOLONLINE_H +#define LLDB_INTERPRETER_OPTIONVALUEFILECOLONLINE_H + +#include "lldb/Interpreter/OptionValue.h" + +#include "lldb/Utility/FileSpec.h" +#include "llvm/Support/Chrono.h" + +namespace lldb_private { + +class OptionValueFileColonLine : public OptionValue { +public: + OptionValueFileColonLine(); + OptionValueFileColonLine(const llvm::StringRef input); + + ~OptionValueFileColonLine() override {} + + OptionValue::Type GetType() const override { return eTypeFileLineColumn; } + + void DumpValue(const ExecutionContext *exe_ctx, Stream &strm, + uint32_t dump_mask) override; + + Status + SetValueFromString(llvm::StringRef value, + VarSetOperationType op = eVarSetOperationAssign) override; + Status + SetValueFromString(const char *, + VarSetOperationType = eVarSetOperationAssign) = delete; + + bool Clear() override { + m_file_spec.Clear(); + m_line_number = LLDB_INVALID_LINE_NUMBER; + m_column_number = 0; + } + + lldb::OptionValueSP DeepCopy() const override; + + void AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) override; + + FileSpec &GetFileSpec() { return m_file_spec; } + uint32_t GetLineNumber() { return m_line_number; } + uint32_t GetColumnNumber() { return m_column_number; } + + void SetCompletionMask(uint32_t mask) { m_completion_mask = mask; } + +protected: + FileSpec m_file_spec; + uint32_t m_line_number; + uint32_t m_column_number; + uint32_t m_completion_mask; +}; + +} // namespace lldb_private + +#endif // LLDB_INTERPRETER_OPTIONVALUEFILECOLONLINE_H diff --git a/lldb/include/lldb/Interpreter/OptionValues.h b/lldb/include/lldb/Interpreter/OptionValues.h index 36e7c192d60a3..6efc9e1ad064c 100644 --- a/lldb/include/lldb/Interpreter/OptionValues.h +++ b/lldb/include/lldb/Interpreter/OptionValues.h @@ -17,6 +17,7 @@ #include "lldb/Interpreter/OptionValueChar.h" #include "lldb/Interpreter/OptionValueDictionary.h" #include "lldb/Interpreter/OptionValueEnumeration.h" +#include "lldb/Interpreter/OptionValueFileColonLine.h" #include "lldb/Interpreter/OptionValueFileSpec.h" #include "lldb/Interpreter/OptionValueFileSpecList.h" #include "lldb/Interpreter/OptionValueFormat.h" diff --git a/lldb/include/lldb/lldb-defines.h b/lldb/include/lldb/lldb-defines.h index fea8079779a13..487cd0b01d5c5 100644 --- a/lldb/include/lldb/lldb-defines.h +++ b/lldb/include/lldb/lldb-defines.h @@ -95,6 +95,7 @@ #define LLDB_INVALID_SIGNAL_NUMBER INT32_MAX #define LLDB_INVALID_OFFSET UINT64_MAX // Must match max of lldb::offset_t #define LLDB_INVALID_LINE_NUMBER UINT32_MAX +#define LLDB_INVALID_COLUMN_NUMBER 0 #define LLDB_INVALID_QUEUE_ID 0 /// CPU Type definitions @@ -119,6 +120,7 @@ #define LLDB_OPT_SET_9 (1U << 8) #define LLDB_OPT_SET_10 (1U << 9) #define LLDB_OPT_SET_11 (1U << 10) +#define LLDB_OPT_SET_12 (1U << 11) #define LLDB_OPT_SET_FROM_TO(A, B) \ (((1U << (B)) - 1) ^ (((1U << (A)) - 1) >> 1)) diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 3ed3d0f74db22..107c3ffe8f955 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -529,6 +529,7 @@ enum CommandArgumentType { eArgTypeExpression, eArgTypeExpressionPath, eArgTypeExprFormat, + eArgTypeFileLineColumn, eArgTypeFilename, eArgTypeFormat, eArgTypeFrameIndex, diff --git a/lldb/packages/Python/lldbsuite/test/lldbutil.py b/lldb/packages/Python/lldbsuite/test/lldbutil.py index 2ba9ec4fcf0c4..a137a065ed7c9 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbutil.py +++ b/lldb/packages/Python/lldbsuite/test/lldbutil.py @@ -539,6 +539,29 @@ def run_break_set_by_source_regexp( return get_bpno_from_match(break_results) +def run_break_set_by_file_colon_line( + test, + specifier, + path, + line_number, + column_number = 0, + extra_options=None, + num_expected_locations=-1): + command = 'breakpoint set -y "%s"'%(specifier) + if extra_options: + command += " " + extra_options + + print("About to run: '%s'", command) + break_results = run_break_set_command(test, command) + check_breakpoint_result( + test, + break_results, + num_locations = num_expected_locations, + file_name = path, + line_number = line_number, + column_number = column_number) + + return get_bpno_from_match(break_results) def run_break_set_command(test, command): """Run the command passed in - it must be some break set variant - and analyze the result. @@ -552,6 +575,7 @@ def run_break_set_command(test, command): If there is only one location, the dictionary MAY contain: file - source file name line_no - source line number + column - source column number symbol - symbol name inline_symbol - inlined symbol name offset - offset from the original symbol @@ -603,6 +627,7 @@ def check_breakpoint_result( break_results, file_name=None, line_number=-1, + column_number=0, symbol_name=None, symbol_match_exact=True, module_name=None, @@ -642,6 +667,17 @@ def check_breakpoint_result( (line_number, out_line_number)) + if column_number != 0: + out_column_number = 0 + if 'column' in break_results: + out_column_number = break_results['column'] + + test.assertTrue( + column_number == out_column_number, + "Breakpoint column number %s doesn't match resultant column %s." % + (column_number, + out_column_number)) + if symbol_name: out_symbol_name = "" # Look first for the inlined symbol name, otherwise use the symbol diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp index be7ef8a1b60bd..b62fe6c93cd8b 100644 --- a/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -17,6 +17,7 @@ #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h" #include "lldb/Interpreter/OptionValueBoolean.h" +#include "lldb/Interpreter/OptionValueFileColonLine.h" #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Interpreter/OptionValueUInt64.h" #include "lldb/Interpreter/Options.h" @@ -443,7 +444,22 @@ class CommandObjectBreakpointSet : public CommandObjectParsed { case 'X': m_source_regex_func_names.insert(std::string(option_arg)); break; - + + case 'y': + { + OptionValueFileColonLine value; + Status fcl_err = value.SetValueFromString(option_arg); + if (!fcl_err.Success()) { + error.SetErrorStringWithFormat( + "Invalid value for file:line specifier: %s", + fcl_err.AsCString()); + } else { + m_filenames.AppendIfUnique(value.GetFileSpec()); + m_line_num = value.GetLineNumber(); + m_column = value.GetColumnNumber(); + } + } break; + default: llvm_unreachable("Unimplemented option"); } diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp index 1ccfd3a5166f4..8fff22a06366c 100644 --- a/lldb/source/Commands/CommandObjectSource.cpp +++ b/lldb/source/Commands/CommandObjectSource.cpp @@ -16,6 +16,7 @@ #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Interpreter/OptionValueFileColonLine.h" #include "lldb/Interpreter/Options.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" @@ -667,6 +668,22 @@ class CommandObjectSourceList : public CommandObjectParsed { case 'r': reverse = true; break; + case 'y': + { + OptionValueFileColonLine value; + Status fcl_err = value.SetValueFromString(option_arg); + if (!fcl_err.Success()) { + error.SetErrorStringWithFormat( + "Invalid value for file:line specifier: %s", + fcl_err.AsCString()); + } else { + file_name = value.GetFileSpec().GetPath(); + start_line = value.GetLineNumber(); + // I don't see anything useful to do with a column number, but I don't + // want to complain since someone may well have cut and pasted a + // listing from somewhere that included a column. + } + } break; default: llvm_unreachable("Unimplemented option"); } diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index cdb102202edc5..a2f2a8e843d84 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -105,7 +105,7 @@ let Command = "breakpoint dummy" in { let Command = "breakpoint set" in { def breakpoint_set_shlib : Option<"shlib", "s">, Arg<"ShlibName">, - Completion<"Module">, Groups<[1,2,3,4,5,6,7,8,9,11]>, // *not* in group 10 + Completion<"Module">, Groups<[1,2,3,4,5,6,7,8,9,11,12]>, // *not* in group 10 Desc<"Set the breakpoint only in this shared library. Can repeat this " "option multiple times to specify multiple shared libraries.">; def breakpoint_set_hardware : Option<"hardware", "H">, @@ -186,21 +186,24 @@ let Command = "breakpoint set" in { "expression (note: currently only implemented for setting breakpoints on " "identifiers). If not set the target.language setting is used.">; def breakpoint_set_skip_prologue : Option<"skip-prologue", "K">, - Arg<"Boolean">, Groups<[1,3,4,5,6,7,8]>, + Arg<"Boolean">, Groups<[1,3,4,5,6,7,8,12]>, Desc<"sKip the prologue if the breakpoint is at the beginning of a " "function. If not set the target.skip-prologue setting is used.">; def breakpoint_set_breakpoint_name : Option<"breakpoint-name", "N">, Arg<"BreakpointName">, Desc<"Adds this to the list of names for this breakpoint.">; def breakpoint_set_address_slide : Option<"address-slide", "R">, - Arg<"Address">, Groups<[1,3,4,5,6,7,8]>, + Arg<"Address">, Groups<[1,3,4,5,6,7,8,12]>, Desc<"Add the specified offset to whatever address(es) the breakpoint " "resolves to. At present this applies the offset directly as given, and " "doesn't try to align it to instruction boundaries.">; def breakpoint_set_move_to_nearest_code : Option<"move-to-nearest-code", "m">, - Groups<[1, 9]>, Arg<"Boolean">, + Groups<[1,9,12]>, Arg<"Boolean">, Desc<"Move breakpoints to nearest code. If not set the " "target.move-to-nearest-codesetting is used.">; + def breakpoint_set_file_colon_line : Option<"joint-specifier", "y">, Group<12>, Arg<"FileLineColumn">, + Required, Completion<"SourceFile">, + Desc<"A specifier in the form filename:line[:column] for setting file & line breakpoints.">; /* Don't add this option till it actually does something useful... def breakpoint_set_exception_typename : Option<"exception-typename", "O">, Arg<"TypeName">, Desc<"The breakpoint will only stop if an " @@ -737,7 +740,7 @@ let Command = "source info" in { let Command = "source list" in { def source_list_count : Option<"count", "c">, Arg<"Count">, Desc<"The number of source lines to display.">; - def source_list_shlib : Option<"shlib", "s">, Groups<[1,2]>, Arg<"ShlibName">, + def source_list_shlib : Option<"shlib", "s">, Groups<[1,2,5]>, Arg<"ShlibName">, Completion<"Module">, Desc<"Look up the source file in the given shared library.">; def source_list_show_breakpoints : Option<"show-breakpoints", "b">, @@ -755,6 +758,10 @@ let Command = "source list" in { " information for the corresponding file and line.">; def source_list_reverse : Option<"reverse", "r">, Group<4>, Desc<"Reverse the" " listing to look backwards from the last displayed block of source.">; + def source_list_file_colon_line : Option<"joint-specifier", "y">, Group<5>, + Arg<"FileLineColumn">, Completion<"SourceFile">, + Desc<"A specifier in the form filename:line[:column] from which to display" + " source.">; } let Command = "target dependents" in { diff --git a/lldb/source/Interpreter/CMakeLists.txt b/lldb/source/Interpreter/CMakeLists.txt index 0ed39869467ec..7a8c826d040cb 100644 --- a/lldb/source/Interpreter/CMakeLists.txt +++ b/lldb/source/Interpreter/CMakeLists.txt @@ -35,6 +35,7 @@ add_lldb_library(lldbInterpreter OptionValueChar.cpp OptionValueDictionary.cpp OptionValueEnumeration.cpp + OptionValueFileColonLine.cpp OptionValueFileSpec.cpp OptionValueFileSpecList.cpp OptionValueFormat.cpp diff --git a/lldb/source/Interpreter/CommandObject.cpp b/lldb/source/Interpreter/CommandObject.cpp index 538f7a1ba6930..6f58b8ba0ea77 100644 --- a/lldb/source/Interpreter/CommandObject.cpp +++ b/lldb/source/Interpreter/CommandObject.cpp @@ -1064,6 +1064,7 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = { { eArgTypeIndex, "index", CommandCompletions::eNoCompletion, { nullptr, false }, "An index into a list." }, { eArgTypeLanguage, "source-language", CommandCompletions::eNoCompletion, { LanguageTypeHelpTextCallback, true }, nullptr }, { eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, { nullptr, false }, "Line number in a source file." }, + { eArgTypeFileLineColumn, "linespec", CommandCompletions::eNoCompletion, { nullptr, false }, "A source specifier in the form file:line[:column]" }, { eArgTypeLogCategory, "log-category", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a category within a log channel, e.g. all (try \"log list\" to see a list of all channels and their categories." }, { eArgTypeLogChannel, "log-channel", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a log channel, e.g. process.gdb-remote (try \"log list\" to see a list of all channels and their categories)." }, { eArgTypeMethod, "method", CommandCompletions::eNoCompletion, { nullptr, false }, "A C++ method name." }, diff --git a/lldb/source/Interpreter/OptionValue.cpp b/lldb/source/Interpreter/OptionValue.cpp index 2e3974b310198..0bd9a591af678 100644 --- a/lldb/source/Interpreter/OptionValue.cpp +++ b/lldb/source/Interpreter/OptionValue.cpp @@ -471,6 +471,8 @@ const char *OptionValue::GetBuiltinTypeAsCString(Type t) { return "dictionary"; case eTypeEnum: return "enum"; + case eTypeFileLineColumn: + return "file:line:column specifier"; case eTypeFileSpec: return "file"; case eTypeFileSpecList: diff --git a/lldb/source/Interpreter/OptionValueArray.cpp b/lldb/source/Interpreter/OptionValueArray.cpp index 9be11e32e2dbc..0b293ccfc248f 100644 --- a/lldb/source/Interpreter/OptionValueArray.cpp +++ b/lldb/source/Interpreter/OptionValueArray.cpp @@ -52,6 +52,7 @@ void OptionValueArray::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, case eTypeChar: case eTypeEnum: case eTypeFileSpec: + case eTypeFileLineColumn: case eTypeFormat: case eTypeSInt64: case eTypeString: diff --git a/lldb/source/Interpreter/OptionValueDictionary.cpp b/lldb/source/Interpreter/OptionValueDictionary.cpp index caadccd042329..79323f502d179 100644 --- a/lldb/source/Interpreter/OptionValueDictionary.cpp +++ b/lldb/source/Interpreter/OptionValueDictionary.cpp @@ -62,6 +62,7 @@ void OptionValueDictionary::DumpValue(const ExecutionContext *exe_ctx, case eTypeBoolean: case eTypeChar: case eTypeEnum: + case eTypeFileLineColumn: case eTypeFileSpec: case eTypeFormat: case eTypeSInt64: diff --git a/lldb/source/Interpreter/OptionValueFileColonLine.cpp b/lldb/source/Interpreter/OptionValueFileColonLine.cpp new file mode 100644 index 0000000000000..dac557c4248aa --- /dev/null +++ b/lldb/source/Interpreter/OptionValueFileColonLine.cpp @@ -0,0 +1,145 @@ +//===-- OptionValueFileColonLine.cpp---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Interpreter/OptionValueFileColonLine.h" + +#include "lldb/DataFormatters/FormatManager.h" +#include "lldb/Interpreter/CommandCompletions.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Utility/Args.h" +#include "lldb/Utility/State.h" + +using namespace lldb; +using namespace lldb_private; + +// This is an OptionValue for parsing file:line:column specifications. +// I set the completer to "source file" which isn't quite right, but we can +// only usefully complete in the file name part of it so it should be good +// enough. +OptionValueFileColonLine::OptionValueFileColonLine() + : OptionValue(), m_file_spec(), m_line_number(LLDB_INVALID_LINE_NUMBER), + m_column_number(LLDB_INVALID_COLUMN_NUMBER), + m_completion_mask(CommandCompletions::eSourceFileCompletion) {} + +OptionValueFileColonLine::OptionValueFileColonLine(llvm::StringRef input) + : OptionValue(), m_file_spec(), m_line_number(LLDB_INVALID_LINE_NUMBER), + m_column_number(LLDB_INVALID_COLUMN_NUMBER), + m_completion_mask(CommandCompletions::eSourceFileCompletion) { + SetValueFromString(input, eVarSetOperationAssign); +} + +void OptionValueFileColonLine::DumpValue(const ExecutionContext *exe_ctx, + Stream &strm, uint32_t dump_mask) { + if (dump_mask & eDumpOptionType) + strm.Printf("(%s)", GetTypeAsCString()); + if (dump_mask & eDumpOptionValue) { + if (dump_mask & eDumpOptionType) + strm.PutCString(" = "); + + if (m_file_spec) + strm << '"' << m_file_spec.GetPath().c_str() << '"'; + if (m_line_number != LLDB_INVALID_LINE_NUMBER) + strm.Printf(":%d", m_line_number); + if (m_column_number != LLDB_INVALID_COLUMN_NUMBER) + strm.Printf(":%d", m_column_number); + } +} + +Status OptionValueFileColonLine::SetValueFromString(llvm::StringRef value, + VarSetOperationType op) { + Status error; + switch (op) { + case eVarSetOperationClear: + Clear(); + NotifyValueChanged(); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: + if (value.size() > 0) { + // This is in the form filename:linenumber:column. + // I wish we could use filename:linenumber.column, that would make the + // parsing unambiguous and so much easier... + // But clang & gcc both print the output with two : so we're stuck with + // the two colons. Practically, the only actual ambiguity this introduces + // is with files like "foo:10", which doesn't seem terribly likely. + + // Providing the column is optional, so the input value might have one or + // two colons. First pick off the last colon separated piece. + // It has to be there, since the line number is required: + llvm::StringRef last_piece; + llvm::StringRef left_of_last_piece; + + std::tie(left_of_last_piece, last_piece) = value.rsplit(':'); + if (last_piece.empty()) { + error.SetErrorStringWithFormat("Line specifier must include file and " + "line: '%s'", + value.str().c_str()); + return error; + } + + // Now see if there's another colon and if so pull out the middle piece: + // Then check whether the middle piece is an integer. If it is, then it + // was the line number, and if it isn't we're going to assume that there + // was a colon in the filename (see note at the beginning of the function) + // and ignore it. + llvm::StringRef file_name; + llvm::StringRef middle_piece; + + std::tie(file_name, middle_piece) = left_of_last_piece.rsplit(':'); + if (middle_piece.empty() || !llvm::to_integer(middle_piece, + m_line_number)) { + // The middle piece was empty or not an integer, so there were only two + // legit pieces; our original division was right. Reassign the file + // name and pull out the line number: + file_name = left_of_last_piece; + if (!llvm::to_integer(last_piece, m_line_number)) { + error.SetErrorStringWithFormat("Bad line number value '%s' in: '%s'", + last_piece.str().c_str(), + value.str().c_str()); + return error; + } + } else { + // There were three pieces, and we've got the line number. So now + // we just need to check the column number which was the last peice. + if (!llvm::to_integer(last_piece, m_column_number)) { + error.SetErrorStringWithFormat("Bad column value '%s' in: '%s'", + last_piece.str().c_str(), + value.str().c_str()); + return error; + } + } + + m_value_was_set = true; + m_file_spec.SetFile(file_name, FileSpec::Style::native); + NotifyValueChanged(); + } else { + error.SetErrorString("invalid value string"); + } + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromString(value, op); + break; + } + return error; +} + +lldb::OptionValueSP OptionValueFileColonLine::DeepCopy() const { + return OptionValueSP(new OptionValueFileColonLine(*this)); +} + +void OptionValueFileColonLine::AutoComplete(CommandInterpreter &interpreter, + CompletionRequest &request) { + CommandCompletions::InvokeCommonCompletionCallbacks( + interpreter, m_completion_mask, request, nullptr); +} diff --git a/lldb/source/Interpreter/OptionValueFileSpec.cpp b/lldb/source/Interpreter/OptionValueFileSpec.cpp index 15acb7e5e5b08..a03fd55d0385a 100644 --- a/lldb/source/Interpreter/OptionValueFileSpec.cpp +++ b/lldb/source/Interpreter/OptionValueFileSpec.cpp @@ -64,13 +64,6 @@ Status OptionValueFileSpec::SetValueFromString(llvm::StringRef value, case eVarSetOperationReplace: case eVarSetOperationAssign: if (value.size() > 0) { - // The setting value may have whitespace, double-quotes, or single-quotes - // around the file path to indicate that internal spaces are not word - // breaks. Strip off any ws & quotes from the start and end of the file - // path - we aren't doing any word // breaking here so the quoting is - // unnecessary. NB this will cause a problem if someone tries to specify - // a file path that legitimately begins or ends with a " or ' character, - // or whitespace. value = value.trim("\"' \t"); m_value_was_set = true; m_current_value.SetFile(value.str(), FileSpec::Style::native); diff --git a/lldb/source/Interpreter/Property.cpp b/lldb/source/Interpreter/Property.cpp index 9238112498533..a02497662ff5f 100644 --- a/lldb/source/Interpreter/Property.cpp +++ b/lldb/source/Interpreter/Property.cpp @@ -99,6 +99,12 @@ Property::Property(const PropertyDefinition &definition) } break; + case OptionValue::eTypeFileLineColumn: + // "definition.default_uint_value" is not used for a + // OptionValue::eTypeFileSpecList + m_value_sp = std::make_shared(); + break; + case OptionValue::eTypeFileSpec: { // "definition.default_uint_value" represents if the // "definition.default_cstr_value" should be resolved or not diff --git a/lldb/test/API/functionalities/breakpoint/breakpoint_by_file_colon_line/Makefile b/lldb/test/API/functionalities/breakpoint/breakpoint_by_file_colon_line/Makefile new file mode 100644 index 0000000000000..ad42b20df4ed5 --- /dev/null +++ b/lldb/test/API/functionalities/breakpoint/breakpoint_by_file_colon_line/Makefile @@ -0,0 +1,4 @@ +C_SOURCES := main.c +CFLAGS_EXTRAS := -std=c99 -gcolumn-info + +include Makefile.rules diff --git a/lldb/test/API/functionalities/breakpoint/breakpoint_by_file_colon_line/TestBreakpointByFileColonLine.py b/lldb/test/API/functionalities/breakpoint/breakpoint_by_file_colon_line/TestBreakpointByFileColonLine.py new file mode 100644 index 0000000000000..011fcdce8da46 --- /dev/null +++ b/lldb/test/API/functionalities/breakpoint/breakpoint_by_file_colon_line/TestBreakpointByFileColonLine.py @@ -0,0 +1,42 @@ +""" +Test setting a breakpoint by line and column. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class BreakpointByLineAndColumnTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def testBreakpointSpecWithLine(self): + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # This one should work: + lldbutil.run_break_set_by_file_colon_line(self, "main.c:11", "main.c", 11, num_expected_locations = 1) + # Let's try an illegal specifier to make sure the command fails. I'm not being exhaustive + # since the UnitTest has more bad patterns. I'm just testing that if the SetFromString + # fails, we propagate the error. + self.expect("break set -y 'foo.c'", error=True) + + ## Skip gcc version less 7.1 since it doesn't support -gcolumn-info + @skipIf(compiler="gcc", compiler_version=['<', '7.1']) + def testBreakpointByLine(self): + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + main_c = lldb.SBFileSpec("main.c") + lldbutil.run_break_set_by_file_colon_line(self, "main.c:11:50", "main.c", 11, num_expected_locations = 1) + diff --git a/lldb/test/API/functionalities/breakpoint/breakpoint_by_file_colon_line/main.c b/lldb/test/API/functionalities/breakpoint/breakpoint_by_file_colon_line/main.c new file mode 100644 index 0000000000000..6e3f7e2ddbf93 --- /dev/null +++ b/lldb/test/API/functionalities/breakpoint/breakpoint_by_file_colon_line/main.c @@ -0,0 +1,14 @@ +int square(int x) +{ + return x * x; +} + +int main (int argc, char const *argv[]) +{ + int did_call = 0; + + // Line 11. v Column 50. + if(square(argc+1) != 0) { did_call = 1; return square(argc); } + // ^ + return square(0); +} diff --git a/lldb/test/API/source-manager/TestSourceManager.py b/lldb/test/API/source-manager/TestSourceManager.py index 714b736da02e6..3ce056f2d0294 100644 --- a/lldb/test/API/source-manager/TestSourceManager.py +++ b/lldb/test/API/source-manager/TestSourceManager.py @@ -197,6 +197,14 @@ def test_modify_source_file_while_debugging(self): SOURCE_DISPLAYED_CORRECTLY, substrs=['Hello world']) + # Do the same thing with a file & line spec: + self.expect( + "source list -y main-copy.c:%d" % + self.line, + SOURCE_DISPLAYED_CORRECTLY, + substrs=['Hello world']) + + # The '-b' option shows the line table locations from the debug information # that indicates valid places to set source level breakpoints. diff --git a/lldb/unittests/Interpreter/CMakeLists.txt b/lldb/unittests/Interpreter/CMakeLists.txt index 0de5b0b72488e..28663ec02a2a9 100644 --- a/lldb/unittests/Interpreter/CMakeLists.txt +++ b/lldb/unittests/Interpreter/CMakeLists.txt @@ -1,6 +1,7 @@ add_lldb_unittest(InterpreterTests TestCompletion.cpp TestOptionArgParser.cpp + TestOptionValueFileColonLine.cpp LINK_LIBS lldbInterpreter diff --git a/lldb/unittests/Interpreter/TestOptionValueFileColonLine.cpp b/lldb/unittests/Interpreter/TestOptionValueFileColonLine.cpp new file mode 100644 index 0000000000000..e5b2c77a16162 --- /dev/null +++ b/lldb/unittests/Interpreter/TestOptionValueFileColonLine.cpp @@ -0,0 +1,57 @@ +//===-- ArgsTest.cpp ------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Interpreter/OptionValueFileColonLine.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Status.h" +#include "gtest/gtest.h" + +using namespace lldb_private; + +void CheckSetting(const char *input, bool success, const char *path = nullptr, + uint32_t line_number = LLDB_INVALID_ADDRESS, + uint32_t column_number = 0) { + + OptionValueFileColonLine value; + Status error; + llvm::StringRef s_ref(input); + error = value.SetValueFromString(s_ref); + ASSERT_EQ(error.Success(), success); + + // If we were meant to fail, we don't need to do more checks: + if (!success) + return; + + ASSERT_EQ(value.GetLineNumber(), line_number); + ASSERT_EQ(value.GetColumnNumber(), column_number); + std::string value_path = value.GetFileSpec().GetPath(); + ASSERT_STREQ(value_path.c_str(), path); +} + +TEST(OptionValueFileColonLine, setFromString) { + OptionValueFileColonLine value; + Status error; + + // Make sure a default constructed value is invalid: + ASSERT_EQ(value.GetLineNumber(), LLDB_INVALID_LINE_NUMBER); + ASSERT_EQ(value.GetColumnNumber(), 0); + ASSERT_FALSE(value.GetFileSpec()); + + // Make sure it is an error to pass a specifier with no line number: + CheckSetting("foo.c", false); + + // Now try with just a file & line: + CheckSetting("foo.c:12", true, "foo.c", 12); + CheckSetting("foo.c:12:20", true, "foo.c", 12, 20); + // Make sure a colon doesn't mess us up: + CheckSetting("foo:bar.c:12", true, "foo:bar.c", 12); + CheckSetting("foo:bar.c:12:20", true, "foo:bar.c", 12, 20); + // Try errors in the line number: + CheckSetting("foo.c:12c", false); + CheckSetting("foo.c:12:20c", false); +} From 81eb1c1fa75c6407713b5657156d8d9149572bfe Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Thu, 24 Sep 2020 15:36:42 -0400 Subject: [PATCH 008/234] AArch64/GlobalISel: Reduced patch for bug 47619 This is the relevant portions of an assert fixed by b98f902f1877c3d679f77645a267edc89ffcd5d6. --- llvm/lib/CodeGen/GlobalISel/CallLowering.cpp | 12 +++++---- llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp | 8 ++++-- .../irtranslator-stack-evt-bug47619.ll | 26 +++++++++++++++++++ 3 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-stack-evt-bug47619.ll diff --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp index a7146515c4c96..1be0ca4412059 100644 --- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp @@ -375,13 +375,15 @@ bool CallLowering::handleAssignments(CCState &CCInfo, << "Load/store a split arg to/from the stack not implemented yet"); return false; } - MVT VT = MVT::getVT(Args[i].Ty); - unsigned Size = VT == MVT::iPTR ? DL.getPointerSize() - : alignTo(VT.getSizeInBits(), 8) / 8; + + EVT LocVT = VA.getValVT(); + unsigned MemSize = LocVT == MVT::iPTR ? DL.getPointerSize() + : LocVT.getStoreSize(); + unsigned Offset = VA.getLocMemOffset(); MachinePointerInfo MPO; - Register StackAddr = Handler.getStackAddress(Size, Offset, MPO); - Handler.assignValueToAddress(Args[i], StackAddr, Size, MPO, VA); + Register StackAddr = Handler.getStackAddress(MemSize, Offset, MPO); + Handler.assignValueToAddress(Args[i], StackAddr, MemSize, MPO, VA); } else { // FIXME: Support byvals and other weirdness return false; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp index 05a4e3462a263..949dcea3aa188 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp @@ -129,13 +129,17 @@ struct IncomingArgHandler : public CallLowering::ValueHandler { } } - void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size, + void assignValueToAddress(Register ValVReg, Register Addr, uint64_t MemSize, MachinePointerInfo &MPO, CCValAssign &VA) override { MachineFunction &MF = MIRBuilder.getMF(); + // The reported memory location may be wider than the value. + const LLT RegTy = MRI.getType(ValVReg); + MemSize = std::min(static_cast(RegTy.getSizeInBytes()), MemSize); + // FIXME: Get alignment auto MMO = MF.getMachineMemOperand( - MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size, + MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, MemSize, inferAlignFromPtrInfo(MF, MPO)); MIRBuilder.buildLoad(ValVReg, Addr, *MMO); } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-stack-evt-bug47619.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-stack-evt-bug47619.ll new file mode 100644 index 0000000000000..552997e44f09c --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-stack-evt-bug47619.ll @@ -0,0 +1,26 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -global-isel -mtriple=aarch64-unknown-unknown -stop-after=irtranslator %s -o - | FileCheck %s + +; Make sure the i3 %arg8 value is correctly handled. This was trying +; to use MVT for EVT values passed on the stack and asserting before +; b98f902f1877c3d679f77645a267edc89ffcd5d6 +define i3 @bug47619(i64 %arg, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %arg5, i64 %arg6, i64 %arg7, i3 %arg8) { + ; CHECK-LABEL: name: bug47619 + ; CHECK: bb.1.bb: + ; CHECK: liveins: $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7 + ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 + ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 + ; CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY $x2 + ; CHECK: [[COPY3:%[0-9]+]]:_(s64) = COPY $x3 + ; CHECK: [[COPY4:%[0-9]+]]:_(s64) = COPY $x4 + ; CHECK: [[COPY5:%[0-9]+]]:_(s64) = COPY $x5 + ; CHECK: [[COPY6:%[0-9]+]]:_(s64) = COPY $x6 + ; CHECK: [[COPY7:%[0-9]+]]:_(s64) = COPY $x7 + ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0 + ; CHECK: [[LOAD:%[0-9]+]]:_(s3) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load 4 from %fixed-stack.0, align 16) + ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[LOAD]](s3) + ; CHECK: $w0 = COPY [[ANYEXT]](s32) + ; CHECK: RET_ReallyLR implicit $w0 +bb: + ret i3 %arg8 +} From 271da2aac13de3f3e34f43ae7308f5505b8164b6 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Thu, 24 Sep 2020 16:59:36 -0700 Subject: [PATCH 009/234] Add a verifier check that rejects non-distinct DISubprogram function attachments. They would crash the backend, which expects all DISubprograms that are not part of the type system to have a unit field. Clang right before https://reviews.llvm.org/D79967 would generate this kind of broken IR. rdar://problem/69534688 (cherry picked from commit e17f52d623cc146b7d9bf5a2e02965043508b4c4) --- llvm/lib/IR/Verifier.cpp | 4 ++++ .../Generic/2009-11-03-InsertExtractValue.ll | 2 +- llvm/test/Verifier/unique-disubprogram.ll | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Verifier/unique-disubprogram.ll diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index f81e947dc94c2..2e9c2e4af90df 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -2404,6 +2404,10 @@ void Verifier::visitFunction(const Function &F) { "function must have a single !dbg attachment", &F, I.second); AssertDI(isa(I.second), "function !dbg attachment must be a subprogram", &F, I.second); + AssertDI(cast(I.second)->isDistinct(), + "function definition may only have a distinct !dbg attachment", + &F); + auto *SP = cast(I.second); const Function *&AttachedTo = DISubprogramAttachments[SP]; AssertDI(!AttachedTo || AttachedTo == &F, diff --git a/llvm/test/DebugInfo/Generic/2009-11-03-InsertExtractValue.ll b/llvm/test/DebugInfo/Generic/2009-11-03-InsertExtractValue.ll index 57ee7ebbb2cb3..81bb5f2457ed9 100644 --- a/llvm/test/DebugInfo/Generic/2009-11-03-InsertExtractValue.ll +++ b/llvm/test/DebugInfo/Generic/2009-11-03-InsertExtractValue.ll @@ -3,7 +3,7 @@ !llvm.module.flags = !{!6} !llvm.dbg.cu = !{!5} -!0 = !DISubprogram(name: "bar", linkageName: "_ZN3foo3barEv", line: 3, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagProtected | DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !4, scope: !1, type: !2) +!0 = distinct !DISubprogram(name: "bar", linkageName: "_ZN3foo3barEv", line: 3, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagProtected | DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !4, scope: !1, type: !2) !1 = !DIFile(filename: "/foo", directory: "bar.cpp") !2 = !DISubroutineType(types: !3) !3 = !{null} diff --git a/llvm/test/Verifier/unique-disubprogram.ll b/llvm/test/Verifier/unique-disubprogram.ll new file mode 100644 index 0000000000000..b4789a9293f7b --- /dev/null +++ b/llvm/test/Verifier/unique-disubprogram.ll @@ -0,0 +1,16 @@ +; RUN: llvm-as -disable-output <%s 2>&1| FileCheck %s +define i32 @_Z3foov() local_unnamed_addr !dbg !9 { + ret i32 5 +} +!llvm.module.flags = !{!2} +!llvm.dbg.cu = !{!5} +!llvm.linker.options = !{} + +!2 = !{i32 2, !"Debug Info Version", i32 3} +!5 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !6, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug) +!6 = !DIFile(filename: "t.cpp", directory: "/") +!7 = !{} +; CHECK: function definition may only have a distinct !dbg attachment +; CHECK: warning: ignoring invalid debug info +!9 = !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !6, file: !6, line: 2, type: !11, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !7) +!11 = !DISubroutineType(types: !7) From 9b4eb3244fa4304249d53bed48ace6d701d6bd5f Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Tue, 8 Sep 2020 14:45:41 -0700 Subject: [PATCH 010/234] [profile] Add %t LLVM_PROFILE_FILE option to substitute $TMPDIR Add support for expanding the %t filename specifier in LLVM_PROFILE_FILE to the TMPDIR environment variable. This is supported on all platforms. On Darwin, TMPDIR is used to specify a temporary application-specific scratch directory. When testing apps on remote devices, it can be challenging for the host device to determine the correct TMPDIR, so it's helpful to have the runtime do this work. rdar://68524185 Differential Revision: https://reviews.llvm.org/D87332 (cherry picked from commit 62c372770d2e87f3e882a20d43c6814e6c4fe0f5) --- clang/docs/SourceBasedCodeCoverage.rst | 3 +++ compiler-rt/lib/profile/InstrProfilingFile.c | 28 +++++++++++++++----- compiler-rt/test/profile/instrprof-tmpdir.c | 22 +++++++++++++++ 3 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 compiler-rt/test/profile/instrprof-tmpdir.c diff --git a/clang/docs/SourceBasedCodeCoverage.rst b/clang/docs/SourceBasedCodeCoverage.rst index 0e9c364fbf6bd..f5b3d05262e93 100644 --- a/clang/docs/SourceBasedCodeCoverage.rst +++ b/clang/docs/SourceBasedCodeCoverage.rst @@ -79,6 +79,9 @@ directory structure will be created. Additionally, the following special * "%h" expands out to the hostname of the machine running the program. +* "%t" expands out to the value of the ``TMPDIR`` environment variable. On + Darwin, this is typically set to a temporary scratch directory. + * "%Nm" expands out to the instrumented binary's signature. When this pattern is specified, the runtime creates a pool of N raw profiles which are used for on-line profile merging. The runtime takes care of selecting a raw profile diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c index 311eb877cdc49..13878f20e1014 100644 --- a/compiler-rt/lib/profile/InstrProfilingFile.c +++ b/compiler-rt/lib/profile/InstrProfilingFile.c @@ -74,6 +74,7 @@ typedef struct lprofFilename { unsigned OwnsFilenamePat; const char *ProfilePathPrefix; char PidChars[MAX_PID_SIZE]; + char *TmpDir; char Hostname[COMPILER_RT_MAX_HOSTLEN]; unsigned NumPids; unsigned NumHosts; @@ -90,8 +91,8 @@ typedef struct lprofFilename { ProfileNameSpecifier PNS; } lprofFilename; -static lprofFilename lprofCurFilename = {0, 0, 0, {0}, {0}, 0, - 0, 0, {0}, 0, PNS_unknown}; +static lprofFilename lprofCurFilename = {0, 0, 0, {0}, NULL, {0}, + 0, 0, 0, {0}, 0, PNS_unknown}; static int ProfileMergeRequested = 0; static int isProfileMergeRequested() { return ProfileMergeRequested; } @@ -773,6 +774,14 @@ static int parseFilenamePattern(const char *FilenamePat, FilenamePat); return -1; } + } else if (FilenamePat[I] == 't') { + lprofCurFilename.TmpDir = getenv("TMPDIR"); + if (!lprofCurFilename.TmpDir) { + PROF_WARN("Unable to get the TMPDIR environment variable, referenced " + "in %s. Using the default path.", + FilenamePat); + return -1; + } } else if (FilenamePat[I] == 'c') { if (__llvm_profile_is_continuous_mode_enabled()) { PROF_WARN("%%c specifier can only be specified once in %s.\n", @@ -874,12 +883,14 @@ static int getCurFilenameLength() { return 0; if (!(lprofCurFilename.NumPids || lprofCurFilename.NumHosts || - lprofCurFilename.MergePoolSize || lprofCurFilename.NumExitSignals)) + lprofCurFilename.TmpDir || lprofCurFilename.MergePoolSize || + lprofCurFilename.NumExitSignals)) return strlen(lprofCurFilename.FilenamePat); Len = strlen(lprofCurFilename.FilenamePat) + lprofCurFilename.NumPids * (strlen(lprofCurFilename.PidChars) - 2) + - lprofCurFilename.NumHosts * (strlen(lprofCurFilename.Hostname) - 2); + lprofCurFilename.NumHosts * (strlen(lprofCurFilename.Hostname) - 2) + + (lprofCurFilename.TmpDir ? (strlen(lprofCurFilename.TmpDir) - 1) : 0); if (lprofCurFilename.MergePoolSize) Len += SIGLEN; for (I = 0; I < lprofCurFilename.NumExitSignals; ++I) { @@ -896,14 +907,14 @@ static int getCurFilenameLength() { * current filename pattern string is directly returned, unless ForceUseBuf * is enabled. */ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) { - int I, J, PidLength, HostNameLength, FilenamePatLength; + int I, J, PidLength, HostNameLength, TmpDirLength, FilenamePatLength; const char *FilenamePat = lprofCurFilename.FilenamePat; if (!lprofCurFilename.FilenamePat || !lprofCurFilename.FilenamePat[0]) return 0; if (!(lprofCurFilename.NumPids || lprofCurFilename.NumHosts || - lprofCurFilename.MergePoolSize || + lprofCurFilename.TmpDir || lprofCurFilename.MergePoolSize || __llvm_profile_is_continuous_mode_enabled() || lprofCurFilename.NumExitSignals)) { if (!ForceUseBuf) @@ -917,6 +928,7 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) { PidLength = strlen(lprofCurFilename.PidChars); HostNameLength = strlen(lprofCurFilename.Hostname); + TmpDirLength = lprofCurFilename.TmpDir ? strlen(lprofCurFilename.TmpDir) : 0; /* Construct the new filename. */ for (I = 0, J = 0; FilenamePat[I]; ++I) if (FilenamePat[I] == '%') { @@ -929,6 +941,10 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) { } else if (containsExitOnSignalSpecifier(FilenamePat, I)) { while (FilenamePat[I] != 'x') ++I; + } else if (FilenamePat[I] == 't') { + memcpy(FilenameBuf + J, lprofCurFilename.TmpDir, TmpDirLength); + FilenameBuf[J + TmpDirLength] = DIR_SEPARATOR; + J += TmpDirLength + 1; } else { if (!getMergePoolSize(FilenamePat, &I)) continue; diff --git a/compiler-rt/test/profile/instrprof-tmpdir.c b/compiler-rt/test/profile/instrprof-tmpdir.c new file mode 100644 index 0000000000000..036313850ed63 --- /dev/null +++ b/compiler-rt/test/profile/instrprof-tmpdir.c @@ -0,0 +1,22 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: cd %t +// RUN: %clang_profgen -o %t/binary %s +// +// Check that a dir separator is appended after %t is subsituted. +// RUN: env TMPDIR="%t" LLVM_PROFILE_FILE="%%traw1.profraw" %run ./binary +// RUN: llvm-profdata show ./raw1.profraw | FileCheck %s -check-prefix TMPDIR +// +// Check that substitution works even if a redundant dir separator is added. +// RUN: env TMPDIR="%t" LLVM_PROFILE_FILE="%%t/raw2.profraw" %run ./binary +// RUN: llvm-profdata show ./raw2.profraw | FileCheck %s -check-prefix TMPDIR +// +// Check that we fall back to the default path if TMPDIR is missing. +// RUN: env -u TMPDIR LLVM_PROFILE_FILE="%%t/raw3.profraw" %run ./binary 2>&1 | FileCheck %s -check-prefix MISSING +// RUN: llvm-profdata show ./default.profraw | FileCheck %s -check-prefix TMPDIR + +// TMPDIR: Maximum function count: 1 + +// MISSING: Unable to get the TMPDIR environment variable, referenced in {{.*}}raw3.profraw. Using the default path. + +int main() { return 0; } From 08d53adaafeb820bc2f55502219f90c3e6050b49 Mon Sep 17 00:00:00 2001 From: Patrick Beard Date: Thu, 30 Jul 2020 14:43:46 -0700 Subject: [PATCH 011/234] Add '<' meta command to read in code from external file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Perform all error handling in ReadCode() Add :help text describing “< path”, add extra line before Commands Differential Revision: https://reviews.llvm.org/D87640 --- lldb/source/Expression/REPL.cpp | 44 +++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/lldb/source/Expression/REPL.cpp b/lldb/source/Expression/REPL.cpp index fd7c39686921d..1f2b009c48935 100644 --- a/lldb/source/Expression/REPL.cpp +++ b/lldb/source/Expression/REPL.cpp @@ -123,10 +123,11 @@ const char *REPL::IOHandlerGetHelpPrologue() { "Valid statements, expressions, and declarations are immediately " "compiled and executed.\n\n" "The complete set of LLDB debugging commands are also available as " - "described below. Commands " + "described below.\n\nCommands " "must be prefixed with a colon at the REPL prompt (:quit for " "example.) Typing just a colon " - "followed by return will switch to the LLDB prompt.\n\n"; + "followed by return will switch to the LLDB prompt.\n\n" + "Type “< path” to read in code from a text file “path”.\n\n"; } bool REPL::IOHandlerIsInputComplete(IOHandler &io_handler, StringList &lines) { @@ -179,6 +180,36 @@ int REPL::IOHandlerFixIndentation(IOHandler &io_handler, return (int)desired_indent - actual_indent; } +static bool ReadCode(const std::string &path, std::string &code, + lldb::StreamFileSP &error_sp) { + auto &fs = FileSystem::Instance(); + llvm::Twine pathTwine(path); + if (!fs.Exists(pathTwine)) { + error_sp->Printf("no such file at path '%s'\n", path.c_str()); + return false; + } + if (!fs.Readable(pathTwine)) { + error_sp->Printf("could not read file at path '%s'\n", path.c_str()); + return false; + } + const size_t file_size = fs.GetByteSize(pathTwine); + const size_t max_size = code.max_size(); + if (file_size > max_size) { + error_sp->Printf("file at path '%s' too large: " + "file_size = %llu, max_size = %llu\n", + path.c_str(), file_size, max_size); + return false; + } + auto data_sp = fs.CreateDataBuffer(pathTwine); + if (data_sp == nullptr) { + error_sp->Printf("could not create buffer for file at path '%s'\n", + path.c_str()); + return false; + } + code.assign((const char *)data_sp->GetBytes(), data_sp->GetByteSize()); + return true; +} + void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { lldb::StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); lldb::StreamFileSP error_sp(io_handler.GetErrorStreamFileSP()); @@ -257,6 +288,15 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { } } } else { + if (code[0] == '<') { + // User wants to read code from a file. + // Interpret rest of line as a literal path. + auto path = llvm::StringRef(code.substr(1)).trim().str(); + if (!ReadCode(path, code, error_sp)) { + return; + } + } + // Unwind any expression we might have been running in case our REPL // expression crashed and the user was looking around if (m_dedicated_repl_mode) { From fdfe9903f5a6f6e8bf25659f918d840eeb3a1f2a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 25 Sep 2020 10:26:35 -0700 Subject: [PATCH 012/234] Fix Assembler/disubprogram.ll after e17f52d623cc146b7d9bf5a2e02965043508b4c4 (cherry picked from commit 6caf3fb8178699ac14fb94fef99aaf1cf297264f) --- llvm/test/Assembler/disubprogram.ll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/test/Assembler/disubprogram.ll b/llvm/test/Assembler/disubprogram.ll index 10bd5520d84dc..6feb27ce48012 100644 --- a/llvm/test/Assembler/disubprogram.ll +++ b/llvm/test/Assembler/disubprogram.ll @@ -25,8 +25,8 @@ define void @_Z3foov() !dbg !9 { isOptimized: true, flags: "-O2", splitDebugFilename: "abc.debug", emissionKind: 2) -; CHECK: !9 = !DISubprogram(scope: null, spFlags: 0) -!9 = !DISubprogram(isDefinition: false) +; CHECK: !9 = distinct !DISubprogram(scope: null, spFlags: 0) +!9 = distinct !DISubprogram(isDefinition: false) ; CHECK: !10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1, file: !2, line: 7, type: !3, scopeLine: 8, containingType: !4, virtualIndex: 10, thisAdjustment: 3, flags: DIFlagPrototyped | DIFlagNoReturn, spFlags: DISPFlagPureVirtual | DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !8, templateParams: !5, declaration: !9, retainedNodes: !6) !10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1, From be39e9d01f6085b75ee343f781607da4a24d3024 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 25 Sep 2020 10:51:54 -0700 Subject: [PATCH 013/234] Revert "Add a verifier check that rejects non-distinct DISubprogram function" This reverts commit e17f52d623cc146b7d9bf5a2e02965043508b4c4. while investigating bot breakage. (cherry picked from commit 8055ae31f46b0a3fafd7b64f6cd77b78b34e6753) --- llvm/lib/IR/Verifier.cpp | 4 ---- .../Generic/2009-11-03-InsertExtractValue.ll | 2 +- llvm/test/Verifier/unique-disubprogram.ll | 16 ---------------- 3 files changed, 1 insertion(+), 21 deletions(-) delete mode 100644 llvm/test/Verifier/unique-disubprogram.ll diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 2e9c2e4af90df..f81e947dc94c2 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -2404,10 +2404,6 @@ void Verifier::visitFunction(const Function &F) { "function must have a single !dbg attachment", &F, I.second); AssertDI(isa(I.second), "function !dbg attachment must be a subprogram", &F, I.second); - AssertDI(cast(I.second)->isDistinct(), - "function definition may only have a distinct !dbg attachment", - &F); - auto *SP = cast(I.second); const Function *&AttachedTo = DISubprogramAttachments[SP]; AssertDI(!AttachedTo || AttachedTo == &F, diff --git a/llvm/test/DebugInfo/Generic/2009-11-03-InsertExtractValue.ll b/llvm/test/DebugInfo/Generic/2009-11-03-InsertExtractValue.ll index 81bb5f2457ed9..57ee7ebbb2cb3 100644 --- a/llvm/test/DebugInfo/Generic/2009-11-03-InsertExtractValue.ll +++ b/llvm/test/DebugInfo/Generic/2009-11-03-InsertExtractValue.ll @@ -3,7 +3,7 @@ !llvm.module.flags = !{!6} !llvm.dbg.cu = !{!5} -!0 = distinct !DISubprogram(name: "bar", linkageName: "_ZN3foo3barEv", line: 3, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagProtected | DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !4, scope: !1, type: !2) +!0 = !DISubprogram(name: "bar", linkageName: "_ZN3foo3barEv", line: 3, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagProtected | DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !4, scope: !1, type: !2) !1 = !DIFile(filename: "/foo", directory: "bar.cpp") !2 = !DISubroutineType(types: !3) !3 = !{null} diff --git a/llvm/test/Verifier/unique-disubprogram.ll b/llvm/test/Verifier/unique-disubprogram.ll deleted file mode 100644 index b4789a9293f7b..0000000000000 --- a/llvm/test/Verifier/unique-disubprogram.ll +++ /dev/null @@ -1,16 +0,0 @@ -; RUN: llvm-as -disable-output <%s 2>&1| FileCheck %s -define i32 @_Z3foov() local_unnamed_addr !dbg !9 { - ret i32 5 -} -!llvm.module.flags = !{!2} -!llvm.dbg.cu = !{!5} -!llvm.linker.options = !{} - -!2 = !{i32 2, !"Debug Info Version", i32 3} -!5 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !6, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug) -!6 = !DIFile(filename: "t.cpp", directory: "/") -!7 = !{} -; CHECK: function definition may only have a distinct !dbg attachment -; CHECK: warning: ignoring invalid debug info -!9 = !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !6, file: !6, line: 2, type: !11, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !7) -!11 = !DISubroutineType(types: !7) From 52f9998ca9c405e555cdd437b2b40a16a6881722 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Thu, 24 Sep 2020 16:59:36 -0700 Subject: [PATCH 014/234] Add a verifier check that rejects non-distinct DISubprogram function attachments. They would crash the backend, which expects all DISubprograms that are not part of the type system to have a unit field. Clang right before https://reviews.llvm.org/D79967 would generate this kind of broken IR. rdar://problem/69534688 Thanks to Fangrui for fixing an assembler test I had missed! https://reviews.llvm.org/D88270 (cherry picked from commit 137597d4f47854bb1701f6883d5c91e8a14d29a2) --- llvm/lib/IR/Verifier.cpp | 4 ++++ .../Generic/2009-11-03-InsertExtractValue.ll | 2 +- llvm/test/Verifier/unique-disubprogram.ll | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Verifier/unique-disubprogram.ll diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index f81e947dc94c2..2e9c2e4af90df 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -2404,6 +2404,10 @@ void Verifier::visitFunction(const Function &F) { "function must have a single !dbg attachment", &F, I.second); AssertDI(isa(I.second), "function !dbg attachment must be a subprogram", &F, I.second); + AssertDI(cast(I.second)->isDistinct(), + "function definition may only have a distinct !dbg attachment", + &F); + auto *SP = cast(I.second); const Function *&AttachedTo = DISubprogramAttachments[SP]; AssertDI(!AttachedTo || AttachedTo == &F, diff --git a/llvm/test/DebugInfo/Generic/2009-11-03-InsertExtractValue.ll b/llvm/test/DebugInfo/Generic/2009-11-03-InsertExtractValue.ll index 57ee7ebbb2cb3..81bb5f2457ed9 100644 --- a/llvm/test/DebugInfo/Generic/2009-11-03-InsertExtractValue.ll +++ b/llvm/test/DebugInfo/Generic/2009-11-03-InsertExtractValue.ll @@ -3,7 +3,7 @@ !llvm.module.flags = !{!6} !llvm.dbg.cu = !{!5} -!0 = !DISubprogram(name: "bar", linkageName: "_ZN3foo3barEv", line: 3, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagProtected | DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !4, scope: !1, type: !2) +!0 = distinct !DISubprogram(name: "bar", linkageName: "_ZN3foo3barEv", line: 3, isLocal: false, isDefinition: false, virtualIndex: 6, flags: DIFlagProtected | DIFlagPrototyped, isOptimized: false, scopeLine: 3, file: !4, scope: !1, type: !2) !1 = !DIFile(filename: "/foo", directory: "bar.cpp") !2 = !DISubroutineType(types: !3) !3 = !{null} diff --git a/llvm/test/Verifier/unique-disubprogram.ll b/llvm/test/Verifier/unique-disubprogram.ll new file mode 100644 index 0000000000000..b4789a9293f7b --- /dev/null +++ b/llvm/test/Verifier/unique-disubprogram.ll @@ -0,0 +1,16 @@ +; RUN: llvm-as -disable-output <%s 2>&1| FileCheck %s +define i32 @_Z3foov() local_unnamed_addr !dbg !9 { + ret i32 5 +} +!llvm.module.flags = !{!2} +!llvm.dbg.cu = !{!5} +!llvm.linker.options = !{} + +!2 = !{i32 2, !"Debug Info Version", i32 3} +!5 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !6, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug) +!6 = !DIFile(filename: "t.cpp", directory: "/") +!7 = !{} +; CHECK: function definition may only have a distinct !dbg attachment +; CHECK: warning: ignoring invalid debug info +!9 = !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !6, file: !6, line: 2, type: !11, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !7) +!11 = !DISubroutineType(types: !7) From 642ea8a73ae117bbe5b5ab9cc6ca87660f7dae3d Mon Sep 17 00:00:00 2001 From: Patrick Beard Date: Fri, 11 Sep 2020 01:35:54 -0700 Subject: [PATCH 015/234] Add RedirectInput.test This loads A.swift into the REPL and executes code defined therein --- lldb/test/Shell/SwiftREPL/RedirectInput.test | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 lldb/test/Shell/SwiftREPL/RedirectInput.test diff --git a/lldb/test/Shell/SwiftREPL/RedirectInput.test b/lldb/test/Shell/SwiftREPL/RedirectInput.test new file mode 100644 index 0000000000000..74c26a1509fd5 --- /dev/null +++ b/lldb/test/Shell/SwiftREPL/RedirectInput.test @@ -0,0 +1,15 @@ +// Test that input can be redirected from a .swift file. + +// RUN: cp %S/Inputs/A.swift /tmp/A.swift +// RUN: %lldb --repl < %s | FileCheck %s + +< /tmp/A.swift + +Foo.foo() +// CHECK: ${{R0}}: String = "A" + +let y = MyPoint(x: 2, y: 2) +// CHECK: {{^}}y: MyPoint = { + +y.magnitudeSquared +// CHECK: {{^}}${{R1}}: Int = 8 From fc354f16f24edcde4f46137aff3dbd488ca6258b Mon Sep 17 00:00:00 2001 From: Patrick Beard Date: Fri, 11 Sep 2020 12:03:57 -0700 Subject: [PATCH 016/234] Use %t, and cd %t to avoid need for absolute path --- lldb/test/Shell/SwiftREPL/RedirectInput.test | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lldb/test/Shell/SwiftREPL/RedirectInput.test b/lldb/test/Shell/SwiftREPL/RedirectInput.test index 74c26a1509fd5..be48c037ffcb9 100644 --- a/lldb/test/Shell/SwiftREPL/RedirectInput.test +++ b/lldb/test/Shell/SwiftREPL/RedirectInput.test @@ -1,9 +1,11 @@ -// Test that input can be redirected from a .swift file. +// Test that input can be redirected from A.swift -// RUN: cp %S/Inputs/A.swift /tmp/A.swift +// RUN: mkdir -p %t +// RUN: cp %S/Inputs/A.swift %t/A.swift +// RUN: cd %t // RUN: %lldb --repl < %s | FileCheck %s -< /tmp/A.swift +< A.swift Foo.foo() // CHECK: ${{R0}}: String = "A" From 4911a66a9ca7c127e9b5a45055cf46afafbfd199 Mon Sep 17 00:00:00 2001 From: Patrick Beard Date: Fri, 11 Sep 2020 12:08:58 -0700 Subject: [PATCH 017/234] Add negative tests: no such file, unreadable file --- lldb/test/Shell/SwiftREPL/RedirectInputNoSuchFile.test | 8 ++++++++ lldb/test/Shell/SwiftREPL/RedirectInputUnreadable.test | 10 ++++++++++ 2 files changed, 18 insertions(+) create mode 100644 lldb/test/Shell/SwiftREPL/RedirectInputNoSuchFile.test create mode 100644 lldb/test/Shell/SwiftREPL/RedirectInputUnreadable.test diff --git a/lldb/test/Shell/SwiftREPL/RedirectInputNoSuchFile.test b/lldb/test/Shell/SwiftREPL/RedirectInputNoSuchFile.test new file mode 100644 index 0000000000000..d0b6c847145cd --- /dev/null +++ b/lldb/test/Shell/SwiftREPL/RedirectInputNoSuchFile.test @@ -0,0 +1,8 @@ +// Test that input can't be redirected from non-existent file A.swift + +// RUN: mkdir -p %t +// RUN: cd %t +// RUN: %lldb --repl < %s 2>&1 | FileCheck %s --check-prefix=LLDB + +< A.swift +// LLDB: no such file at path 'A.swift' diff --git a/lldb/test/Shell/SwiftREPL/RedirectInputUnreadable.test b/lldb/test/Shell/SwiftREPL/RedirectInputUnreadable.test new file mode 100644 index 0000000000000..a252673f43a69 --- /dev/null +++ b/lldb/test/Shell/SwiftREPL/RedirectInputUnreadable.test @@ -0,0 +1,10 @@ +// Test that input can't be redirected from unreadable A.swift + +// RUN: mkdir -p %t +// RUN: cp %S/Inputs/A.swift %t/A.swift +// RUN: chmod -r %t/A.swift +// RUN: cd %t +// RUN: %lldb --repl < %s 2>&1 | FileCheck %s --check-prefix=LLDB + +< A.swift +// LLDB: could not read file at path 'A.swift' From ecf89c52d9c37bfe01554ec7b3f71050f00c85bd Mon Sep 17 00:00:00 2001 From: shafik Date: Thu, 24 Sep 2020 14:31:31 -0700 Subject: [PATCH 018/234] [LLDB] Add a defensive check for member__f_ I only have a crash log and was not able to come up with a test case for this. rdar://problem/69403150 (cherry picked from commit a079f619b5a1959af8af37cabdea27ae542903db) --- .../Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index 8aa803a8553e9..d3a25f37985f1 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -154,6 +154,9 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo( member__f_ = sub_member__f_; } + if (!member__f_) + return optional_info; + lldb::addr_t member__f_pointer_value = member__f_->GetValueAsUnsigned(0); optional_info.member__f_pointer_value = member__f_pointer_value; From 8a75d2b5651b0056ad4fc9ade5546cd59c602e62 Mon Sep 17 00:00:00 2001 From: Zixu Wang Date: Tue, 16 Jun 2020 16:39:50 -0700 Subject: [PATCH 019/234] [clang][module] Improve incomplete-umbrella warning Change the warning message for -Wincomplete-umbrella to report the location of the umbrella header; Differential Revision: https://reviews.llvm.org/D82118 (cherry picked from commit ed79827aea444e6995fb3d36abc2bfd36331773c) --- clang/lib/Lex/PPLexerChange.cpp | 12 +++++++----- clang/test/Modules/incomplete-umbrella.m | 8 ++++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index b7c7e2693ef18..de7b9b73ddf7a 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -263,10 +263,12 @@ static void collectAllSubModulesWithUmbrellaHeader( } void Preprocessor::diagnoseMissingHeaderInUmbrellaDir(const Module &Mod) { - assert(Mod.getUmbrellaHeader() && "Module must use umbrella header"); - SourceLocation StartLoc = - SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); - if (getDiagnostics().isIgnored(diag::warn_uncovered_module_header, StartLoc)) + const Module::Header &UmbrellaHeader = Mod.getUmbrellaHeader(); + assert(UmbrellaHeader.Entry && "Module must use umbrella header"); + const FileID &File = SourceMgr.translateFile(UmbrellaHeader.Entry); + SourceLocation ExpectedHeadersLoc = SourceMgr.getLocForEndOfFile(File); + if (getDiagnostics().isIgnored(diag::warn_uncovered_module_header, + ExpectedHeadersLoc)) return; ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap(); @@ -291,7 +293,7 @@ void Preprocessor::diagnoseMissingHeaderInUmbrellaDir(const Module &Mod) { // Find the relative path that would access this header. SmallString<128> RelativePath; computeRelativePath(FileMgr, Dir, *Header, RelativePath); - Diag(StartLoc, diag::warn_uncovered_module_header) + Diag(ExpectedHeadersLoc, diag::warn_uncovered_module_header) << Mod.getFullModuleName() << RelativePath; } } diff --git a/clang/test/Modules/incomplete-umbrella.m b/clang/test/Modules/incomplete-umbrella.m index 8760b815718b2..0574921203b2d 100644 --- a/clang/test/Modules/incomplete-umbrella.m +++ b/clang/test/Modules/incomplete-umbrella.m @@ -6,8 +6,12 @@ #import @import Foo.Private; -// CHECK: warning: umbrella header for module 'Foo' does not include header 'Bar.h' -// CHECK: warning: umbrella header for module 'Foo.Private' does not include header 'Baz.h' +// CHECK: While building module 'Foo' imported from {{.*[/\]}}incomplete-umbrella.m:4: +// CHECK-NEXT: In file included from :1: +// CHECK-NEXT: {{.*Foo[.]framework[/\]Headers[/\]}}FooPublic.h:2:1: warning: umbrella header for module 'Foo' does not include header 'Bar.h' +// CHECK: While building module 'Foo' imported from {{.*[/\]}}incomplete-umbrella.m:4: +// CHECK-NEXT: In file included from :2: +// CHECK-NEXT: {{.*Foo[.]framework[/\]PrivateHeaders[/\]}}Foo.h:2:1: warning: umbrella header for module 'Foo.Private' does not include header 'Baz.h' int foo() { int a = BAR_PUBLIC; int b = BAZ_PRIVATE; From 8fd613ec6166964bc0bfa2beb6e136f933af4d01 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Sun, 27 Sep 2020 01:15:00 -0700 Subject: [PATCH 020/234] Add support for firmware/standalone LC_NOTE "main bin spec" corefiles (#1864) When a Mach-O corefile has an LC_NOTE "main bin spec" for a standalone binary / firmware, with only a UUID and no load address, try to locate the binary and dSYM by UUID and if found, load it at offset 0 for the user. Add a test case that tests a firmware/standalone corefile with both the "kern ver str" and "main bin spec" LC_NOTEs. Differential Revision: https://reviews.llvm.org/D88282 (cherry picked from commit 1bec6eb3f5cba594698bae5b2789744e0c8ee5f2) --- lldb/include/lldb/Symbol/ObjectFile.h | 24 +- .../ObjectFile/Mach-O/ObjectFileMachO.cpp | 36 +- .../ObjectFile/Mach-O/ObjectFileMachO.h | 4 +- .../Process/mach-core/ProcessMachCore.cpp | 181 +++++---- .../macosx/lc-note/firmware-corefile/Makefile | 14 + .../TestFirmwareCorefiles.py | 133 +++++++ .../macosx/lc-note/firmware-corefile/bout.mk | 10 + .../create-empty-corefile.cpp | 347 ++++++++++++++++++ .../macosx/lc-note/firmware-corefile/main.c | 2 + 9 files changed, 660 insertions(+), 91 deletions(-) create mode 100644 lldb/test/API/macosx/lc-note/firmware-corefile/Makefile create mode 100644 lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py create mode 100644 lldb/test/API/macosx/lc-note/firmware-corefile/bout.mk create mode 100644 lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp create mode 100644 lldb/test/API/macosx/lc-note/firmware-corefile/main.c diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h index e814015c0bf7b..080724cb86bdd 100644 --- a/lldb/include/lldb/Symbol/ObjectFile.h +++ b/lldb/include/lldb/Symbol/ObjectFile.h @@ -91,6 +91,17 @@ class ObjectFile : public std::enable_shared_from_this, eStrataJIT }; + /// If we have a corefile binary hint, this enum + /// specifies the binary type which we can use to + /// select the correct DynamicLoader plugin. + enum BinaryType { + eBinaryTypeInvalid = 0, + eBinaryTypeUnknown, + eBinaryTypeKernel, /// kernel binary + eBinaryTypeUser, /// user process binary + eBinaryTypeStandalone /// standalone binary / firmware + }; + struct LoadableData { lldb::addr_t Dest; llvm::ArrayRef Contents; @@ -500,12 +511,17 @@ class ObjectFile : public std::enable_shared_from_this, /// If the uuid of the binary is specified, this will be set. /// If no UUID is available, will be cleared. /// + /// \param[out] type + /// Return the type of the binary, which will dictate which + /// DynamicLoader plugin should be used. + /// /// \return /// Returns true if either address or uuid has been set. - virtual bool GetCorefileMainBinaryInfo (lldb::addr_t &address, UUID &uuid) { - address = LLDB_INVALID_ADDRESS; - uuid.Clear(); - return false; + virtual bool GetCorefileMainBinaryInfo(lldb::addr_t &address, UUID &uuid, + ObjectFile::BinaryType &type) { + address = LLDB_INVALID_ADDRESS; + uuid.Clear(); + return false; } virtual lldb::RegisterContextSP diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index cb1645f697c6a..9f1d1d576814d 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -5519,7 +5519,8 @@ std::string ObjectFileMachO::GetIdentifierString() { return result; } -bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &address, UUID &uuid) { +bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &address, UUID &uuid, + ObjectFile::BinaryType &type) { address = LLDB_INVALID_ADDRESS; uuid.Clear(); ModuleSP module_sp(GetModule()); @@ -5542,24 +5543,43 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &address, UUID &uuid) { // "main bin spec" (main binary specification) data payload is // formatted: // uint32_t version [currently 1] - // uint32_t type [0 == unspecified, 1 == kernel, 2 == user - // process] uint64_t address [ UINT64_MAX if address not - // specified ] uuid_t uuid [ all zero's if uuid not - // specified ] uint32_t log2_pagesize [ process page size in log base - // 2, e.g. 4k pages are 12. 0 for unspecified ] + // uint32_t type [0 == unspecified, 1 == kernel, + // 2 == user process, 3 == firmware ] + // uint64_t address [ UINT64_MAX if address not specified ] + // uuid_t uuid [ all zero's if uuid not specified ] + // uint32_t log2_pagesize [ process page size in log base + // 2, e.g. 4k pages are 12. + // 0 for unspecified ] + // uint32_t unused [ for alignment ] if (strcmp("main bin spec", data_owner) == 0 && size >= 32) { offset = fileoff; uint32_t version; if (m_data.GetU32(&offset, &version, 1) != nullptr && version == 1) { - uint32_t type = 0; + uint32_t binspec_type = 0; uuid_t raw_uuid; memset(raw_uuid, 0, sizeof(uuid_t)); - if (m_data.GetU32(&offset, &type, 1) && + if (m_data.GetU32(&offset, &binspec_type, 1) && m_data.GetU64(&offset, &address, 1) && m_data.CopyData(offset, sizeof(uuid_t), raw_uuid) != 0) { uuid = UUID::fromOptionalData(raw_uuid, sizeof(uuid_t)); + // convert the "main bin spec" type into our + // ObjectFile::BinaryType enum + switch (binspec_type) { + case 0: + type = eBinaryTypeUnknown; + break; + case 1: + type = eBinaryTypeKernel; + break; + case 2: + type = eBinaryTypeUser; + break; + case 3: + type = eBinaryTypeStandalone; + break; + } return true; } } diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h index 0c1d178b19215..2308c496c4216 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h @@ -112,7 +112,9 @@ class ObjectFileMachO : public lldb_private::ObjectFile { std::string GetIdentifierString() override; - bool GetCorefileMainBinaryInfo (lldb::addr_t &address, lldb_private::UUID &uuid) override; + bool GetCorefileMainBinaryInfo(lldb::addr_t &address, + lldb_private::UUID &uuid, + ObjectFile::BinaryType &type) override; lldb::RegisterContextSP GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) override; diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index b78276d345e1f..bee161bde96b5 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -281,8 +281,9 @@ Status ProcessMachCore::DoLoadCore() { addr_t objfile_binary_addr; UUID objfile_binary_uuid; - if (core_objfile->GetCorefileMainBinaryInfo (objfile_binary_addr, objfile_binary_uuid)) - { + ObjectFile::BinaryType type; + if (core_objfile->GetCorefileMainBinaryInfo(objfile_binary_addr, + objfile_binary_uuid, type)) { if (objfile_binary_addr != LLDB_INVALID_ADDRESS) { m_mach_kernel_addr = objfile_binary_addr; @@ -293,7 +294,7 @@ Status ProcessMachCore::DoLoadCore() { m_mach_kernel_addr); } } - + // This checks for the presence of an LC_IDENT string in a core file; // LC_IDENT is very obsolete and should not be used in new code, but if the // load command is present, let's use the contents. @@ -326,58 +327,80 @@ Status ProcessMachCore::DoLoadCore() { addr, corefile_identifier.c_str()); } } - if (found_main_binary_definitively == false - && corefile_identifier.find("EFI ") != std::string::npos) { - UUID uuid; + + // In the case where we have an LC_NOTE specifying a standalone + // binary with only a UUID (and no load address) (iBoot, EFI, etc), + // then let's try to force a load of the binary and set its + // load address to 0-offset. + // + // The two forms this can come in is either a + // 'kern ver str' LC_NOTE with "EFI UUID=...." + // 'main bin spec' LC_NOTE with UUID and no load address. + + if (found_main_binary_definitively == false && + (corefile_identifier.find("EFI ") != std::string::npos || + (objfile_binary_uuid.IsValid() && + objfile_binary_addr == LLDB_INVALID_ADDRESS))) { + UUID uuid; + if (objfile_binary_uuid.IsValid()) { + uuid = objfile_binary_uuid; + LLDB_LOGF(log, + "ProcessMachCore::DoLoadCore: Using the main bin spec " + "LC_NOTE with UUID %s and no load address", + uuid.GetAsString().c_str()); + } else { if (corefile_identifier.find("UUID=") != std::string::npos) { - size_t p = corefile_identifier.find("UUID=") + strlen("UUID="); - std::string uuid_str = corefile_identifier.substr(p, 36); - uuid.SetFromStringRef(uuid_str); + size_t p = corefile_identifier.find("UUID=") + strlen("UUID="); + std::string uuid_str = corefile_identifier.substr(p, 36); + uuid.SetFromStringRef(uuid_str); + if (uuid.IsValid()) { + LLDB_LOGF(log, + "ProcessMachCore::DoLoadCore: Using the EFI " + "from LC_IDENT/LC_NOTE 'kern ver str' string: '%s'", + corefile_identifier.c_str()); + } } - if (uuid.IsValid()) { - LLDB_LOGF(log, - "ProcessMachCore::DoLoadCore: Using the EFI " - "from LC_IDENT/LC_NOTE 'kern ver str' string: '%s'", - corefile_identifier.c_str()); - - // We're only given a UUID here, not a load address. - // But there are python scripts in the EFI binary's dSYM which - // know how to relocate the binary to the correct load address. - // lldb only needs to locate & load the binary + dSYM. - ModuleSpec module_spec; - module_spec.GetUUID() = uuid; - module_spec.GetArchitecture() = GetTarget().GetArchitecture(); - - // Lookup UUID locally, before attempting dsymForUUID like action - FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); - module_spec.GetSymbolFileSpec() = - Symbols::LocateExecutableSymbolFile(module_spec, search_paths); - if (module_spec.GetSymbolFileSpec()) { - ModuleSpec executable_module_spec = - Symbols::LocateExecutableObjectFile(module_spec); - if (FileSystem::Instance().Exists( - executable_module_spec.GetFileSpec())) { - module_spec.GetFileSpec() = executable_module_spec.GetFileSpec(); - } + } + + if (uuid.IsValid()) { + ModuleSpec module_spec; + module_spec.GetUUID() = uuid; + module_spec.GetArchitecture() = GetTarget().GetArchitecture(); + + // Lookup UUID locally, before attempting dsymForUUID-like action + FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); + module_spec.GetSymbolFileSpec() = + Symbols::LocateExecutableSymbolFile(module_spec, search_paths); + if (module_spec.GetSymbolFileSpec()) { + ModuleSpec executable_module_spec = + Symbols::LocateExecutableObjectFile(module_spec); + if (FileSystem::Instance().Exists( + executable_module_spec.GetFileSpec())) { + module_spec.GetFileSpec() = executable_module_spec.GetFileSpec(); } + } - // Force a a dsymForUUID lookup, if that tool is available. - if (!module_spec.GetSymbolFileSpec()) - Symbols::DownloadObjectAndSymbolFile(module_spec, true); - - if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { - ModuleSP module_sp(new Module(module_spec)); - if (module_sp.get() && module_sp->GetObjectFile()) { - // Get the current target executable - ModuleSP exe_module_sp(GetTarget().GetExecutableModule()); - - // Make sure you don't already have the right module loaded - // and they will be uniqued - if (exe_module_sp.get() != module_sp.get()) - GetTarget().SetExecutableModule(module_sp, eLoadDependentsNo); - } + // Force a a dsymForUUID lookup, if that tool is available. + if (!module_spec.GetSymbolFileSpec()) + Symbols::DownloadObjectAndSymbolFile(module_spec, true); + + // If we found a binary, load it at offset 0 and set our + // dyld_plugin to be the static plugin. + if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { + ModuleSP module_sp(new Module(module_spec)); + if (module_sp.get() && module_sp->GetObjectFile()) { + GetTarget().GetImages().AppendIfNeeded(module_sp, true); + GetTarget().SetExecutableModule(module_sp, eLoadDependentsNo); + found_main_binary_definitively = true; + bool changed = true; + module_sp->SetLoadAddress(GetTarget(), 0, true, changed); + ModuleList added_module; + added_module.Append(module_sp, false); + GetTarget().ModulesDidLoad(added_module); + m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); } } + } } if (!found_main_binary_definitively && @@ -440,35 +463,37 @@ Status ProcessMachCore::DoLoadCore() { } } - // If we found both a user-process dyld and a kernel binary, we need to - // decide which to prefer. - if (GetCorefilePreference() == eKernelCorefile) { - if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { - LLDB_LOGF(log, - "ProcessMachCore::DoLoadCore: Using kernel corefile image " - "at 0x%" PRIx64, - m_mach_kernel_addr); - m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); - } else if (m_dyld_addr != LLDB_INVALID_ADDRESS) { - LLDB_LOGF(log, - "ProcessMachCore::DoLoadCore: Using user process dyld " - "image at 0x%" PRIx64, - m_dyld_addr); - m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); - } - } else { - if (m_dyld_addr != LLDB_INVALID_ADDRESS) { - LLDB_LOGF(log, - "ProcessMachCore::DoLoadCore: Using user process dyld " - "image at 0x%" PRIx64, - m_dyld_addr); - m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); - } else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { - LLDB_LOGF(log, - "ProcessMachCore::DoLoadCore: Using kernel corefile image " - "at 0x%" PRIx64, - m_mach_kernel_addr); - m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); + if (m_dyld_plugin_name.IsEmpty()) { + // If we found both a user-process dyld and a kernel binary, we need to + // decide which to prefer. + if (GetCorefilePreference() == eKernelCorefile) { + if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, + "ProcessMachCore::DoLoadCore: Using kernel corefile image " + "at 0x%" PRIx64, + m_mach_kernel_addr); + m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); + } else if (m_dyld_addr != LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, + "ProcessMachCore::DoLoadCore: Using user process dyld " + "image at 0x%" PRIx64, + m_dyld_addr); + m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); + } + } else { + if (m_dyld_addr != LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, + "ProcessMachCore::DoLoadCore: Using user process dyld " + "image at 0x%" PRIx64, + m_dyld_addr); + m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); + } else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, + "ProcessMachCore::DoLoadCore: Using kernel corefile image " + "at 0x%" PRIx64, + m_mach_kernel_addr); + m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); + } } } diff --git a/lldb/test/API/macosx/lc-note/firmware-corefile/Makefile b/lldb/test/API/macosx/lc-note/firmware-corefile/Makefile new file mode 100644 index 0000000000000..faa5ef2f29f43 --- /dev/null +++ b/lldb/test/API/macosx/lc-note/firmware-corefile/Makefile @@ -0,0 +1,14 @@ +MAKE_DSYM := NO +C_SOURCES := main.c +CFLAGS_EXTRAS := -Wl,-random_uuid + +all: a.out b.out create-empty-corefile + +create-empty-corefile: + $(MAKE) -f $(MAKEFILE_RULES) EXE=create-empty-corefile \ + C_SOURCES=create-empty-corefile.c + +b.out: + $(MAKE) VPATH=$(SRCDIR)/$* -I $(SRCDIR) -f $(SRCDIR)/bout.mk + +include Makefile.rules diff --git a/lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py b/lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py new file mode 100644 index 0000000000000..79a79056476b7 --- /dev/null +++ b/lldb/test/API/macosx/lc-note/firmware-corefile/TestFirmwareCorefiles.py @@ -0,0 +1,133 @@ +"""Test that corefiles with LC_NOTE "kern ver str" and "main bin spec" load commands works.""" + + + +import os +import re +import subprocess + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestFirmwareCorefiles(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIf(debug_info=no_match(["dsym"]), bugnumber="This test is looking explicitly for a dSYM") + @skipIf(archs=no_match(['x86_64'])) + @skipUnlessDarwin + def test_lc_note(self): + self.build() + self.aout_exe = self.getBuildArtifact("a.out") + self.bout_exe = self.getBuildArtifact("b.out") + self.create_corefile = self.getBuildArtifact("create-empty-corefile") + self.dsym_for_uuid = self.getBuildArtifact("dsym-for-uuid.sh") + self.aout_corefile = self.getBuildArtifact("aout.core") + self.bout_corefile = self.getBuildArtifact("bout.core") + + ## We can hook in our dsym-for-uuid shell script to lldb with this env + ## var instead of requiring a defaults write. + os.environ['LLDB_APPLE_DSYMFORUUID_EXECUTABLE'] = self.dsym_for_uuid + self.addTearDownHook(lambda: os.environ.pop('LLDB_APPLE_DSYMFORUUID_EXECUTABLE', None)) + + dwarfdump_uuid_regex = re.compile( + 'UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*') + dwarfdump_cmd_output = subprocess.check_output( + ('/usr/bin/dwarfdump --uuid "%s"' % self.aout_exe), shell=True).decode("utf-8") + aout_uuid = None + for line in dwarfdump_cmd_output.splitlines(): + match = dwarfdump_uuid_regex.search(line) + if match: + aout_uuid = match.group(1) + self.assertNotEqual(aout_uuid, None, "Could not get uuid of built a.out") + + dwarfdump_cmd_output = subprocess.check_output( + ('/usr/bin/dwarfdump --uuid "%s"' % self.bout_exe), shell=True).decode("utf-8") + bout_uuid = None + for line in dwarfdump_cmd_output.splitlines(): + match = dwarfdump_uuid_regex.search(line) + if match: + bout_uuid = match.group(1) + self.assertNotEqual(bout_uuid, None, "Could not get uuid of built b.out") + + ### Create our dsym-for-uuid shell script which returns self.aout_exe + ### or self.bout_exe, depending on the UUID on the command line. + shell_cmds = [ + '#! /bin/sh', + '# the last argument is the uuid', + 'while [ $# -gt 1 ]', + 'do', + ' shift', + 'done', + 'ret=0', + 'echo ""', + 'echo ""', + 'echo ""', + '', + 'if [ "$1" != "%s" -a "$1" != "%s" ]' % (aout_uuid, bout_uuid), + 'then', + ' echo "DBGErrornot found"', + ' echo ""', + ' exit 1', + 'fi', + 'if [ "$1" = "%s" ]' % aout_uuid, + 'then', + ' uuid=%s' % aout_uuid, + ' bin=%s' % self.aout_exe, + ' dsym=%s.dSYM/Contents/Resources/DWARF/%s' % (self.aout_exe, os.path.basename(self.aout_exe)), + 'else', + ' uuid=%s' % bout_uuid, + ' bin=%s' % self.bout_exe, + ' dsym=%s.dSYM/Contents/Resources/DWARF/%s' % (self.bout_exe, os.path.basename(self.bout_exe)), + 'fi', + 'echo "$uuid"', + '', + 'echo "DBGArchitecturex86_64"', + 'echo "DBGDSYMPath$dsym"', + 'echo "DBGSymbolRichExecutable$bin"', + 'echo ""', + 'exit $ret' + ] + + with open(self.dsym_for_uuid, "w") as writer: + for l in shell_cmds: + writer.write(l + '\n') + + os.chmod(self.dsym_for_uuid, 0o755) + + ### Create our corefile + retcode = call(self.create_corefile + " version-string " + self.aout_corefile + " " + self.aout_exe, shell=True) + retcode = call(self.create_corefile + " main-bin-spec " + self.bout_corefile + " " + self.bout_exe, shell=True) + + ### Now run lldb on the corefile + ### which will give us a UUID + ### which we call dsym-for-uuid.sh with + ### which gives us a binary and dSYM + ### which lldb should load! + + # First, try the "kern ver str" corefile + self.target = self.dbg.CreateTarget('') + err = lldb.SBError() + self.process = self.target.LoadCore(self.aout_corefile) + self.assertEqual(self.process.IsValid(), True) + if self.TraceOn(): + self.runCmd("image list") + self.assertEqual(self.target.GetNumModules(), 1) + fspec = self.target.GetModuleAtIndex(0).GetFileSpec() + filepath = fspec.GetDirectory() + "/" + fspec.GetFilename() + self.assertEqual(filepath, self.aout_exe) + + + # Second, try the "main bin spec" corefile + self.target = self.dbg.CreateTarget('') + self.process = self.target.LoadCore(self.bout_corefile) + self.assertEqual(self.process.IsValid(), True) + if self.TraceOn(): + self.runCmd("image list") + self.assertEqual(self.target.GetNumModules(), 1) + fspec = self.target.GetModuleAtIndex(0).GetFileSpec() + filepath = fspec.GetDirectory() + "/" + fspec.GetFilename() + self.assertEqual(filepath, self.bout_exe) diff --git a/lldb/test/API/macosx/lc-note/firmware-corefile/bout.mk b/lldb/test/API/macosx/lc-note/firmware-corefile/bout.mk new file mode 100644 index 0000000000000..049b7b49aa461 --- /dev/null +++ b/lldb/test/API/macosx/lc-note/firmware-corefile/bout.mk @@ -0,0 +1,10 @@ +MAKE_DSYM := NO + +C_SOURCES := main.c +CFLAGS_EXTRAS := -Wl,-random_uuid + +EXE := b.out + +all: b.out + +include Makefile.rules diff --git a/lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp b/lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp new file mode 100644 index 0000000000000..5e02bad51d765 --- /dev/null +++ b/lldb/test/API/macosx/lc-note/firmware-corefile/create-empty-corefile.cpp @@ -0,0 +1,347 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +// Create an empty corefile with a "kern ver str" LC_NOTE +// or a "main bin spec" LC_NOTE.. +// If an existing binary is given as a 3rd argument on the cmd line, +// the UUID from that binary will be encoded in the corefile. +// Otherwise a pre-set UUID will be put in the corefile that +// is created. + +struct main_bin_spec_payload { + uint32_t version; + uint32_t type; + uint64_t address; + uuid_t uuid; + uint32_t log2_pagesize; + uint32_t unused; +}; + +union uint32_buf { + uint8_t bytebuf[4]; + uint32_t val; +}; + +union uint64_buf { + uint8_t bytebuf[8]; + uint64_t val; +}; + +void add_uint64(std::vector &buf, uint64_t val) { + uint64_buf conv; + conv.val = val; + for (int i = 0; i < 8; i++) + buf.push_back(conv.bytebuf[i]); +} + +void add_uint32(std::vector &buf, uint32_t val) { + uint32_buf conv; + conv.val = val; + for (int i = 0; i < 4; i++) + buf.push_back(conv.bytebuf[i]); +} + +std::vector x86_lc_thread_load_command() { + std::vector data; + add_uint32(data, LC_THREAD); // thread_command.cmd + add_uint32(data, 184); // thread_command.cmdsize + add_uint32(data, x86_THREAD_STATE64); // thread_command.flavor + add_uint32(data, x86_THREAD_STATE64_COUNT); // thread_command.count + add_uint64(data, 0x0000000000000000); // rax + add_uint64(data, 0x0000000000000400); // rbx + add_uint64(data, 0x0000000000000000); // rcx + add_uint64(data, 0x0000000000000000); // rdx + add_uint64(data, 0x0000000000000000); // rdi + add_uint64(data, 0x0000000000000000); // rsi + add_uint64(data, 0xffffff9246e2ba20); // rbp + add_uint64(data, 0xffffff9246e2ba10); // rsp + add_uint64(data, 0x0000000000000000); // r8 + add_uint64(data, 0x0000000000000000); // r9 + add_uint64(data, 0x0000000000000000); // r10 + add_uint64(data, 0x0000000000000000); // r11 + add_uint64(data, 0xffffff7f96ce5fe1); // r12 + add_uint64(data, 0x0000000000000000); // r13 + add_uint64(data, 0x0000000000000000); // r14 + add_uint64(data, 0xffffff9246e2bac0); // r15 + add_uint64(data, 0xffffff8015a8f6d0); // rip + add_uint64(data, 0x0000000000011111); // rflags + add_uint64(data, 0x0000000000022222); // cs + add_uint64(data, 0x0000000000033333); // fs + add_uint64(data, 0x0000000000044444); // gs + return data; +} + +void add_lc_note_kern_ver_str_load_command( + std::vector> &loadcmds, std::vector &payload, + int payload_file_offset, std::string uuid) { + std::string ident = "EFI UUID="; + ident += uuid; + std::vector loadcmd_data; + + add_uint32(loadcmd_data, LC_NOTE); // note_command.cmd + add_uint32(loadcmd_data, 40); // note_command.cmdsize + char lc_note_name[16]; + memset(lc_note_name, 0, 16); + strcpy(lc_note_name, "kern ver str"); + + // lc_note.data_owner + for (int i = 0; i < 16; i++) + loadcmd_data.push_back(lc_note_name[i]); + + // we start writing the payload at payload_file_offset to leave + // room at the start for the header & the load commands. + uint64_t current_payload_offset = payload.size() + payload_file_offset; + + add_uint64(loadcmd_data, current_payload_offset); // note_command.offset + add_uint64(loadcmd_data, 4 + ident.size() + 1); // note_command.size + + loadcmds.push_back(loadcmd_data); + + add_uint32(payload, 1); // kerneL_version_string.version + for (int i = 0; i < ident.size() + 1; i++) { + payload.push_back(ident[i]); + } +} + +void add_lc_note_main_bin_spec_load_command( + std::vector> &loadcmds, std::vector &payload, + int payload_file_offset, std::string uuidstr) { + std::vector loadcmd_data; + + add_uint32(loadcmd_data, LC_NOTE); // note_command.cmd + add_uint32(loadcmd_data, 40); // note_command.cmdsize + char lc_note_name[16]; + memset(lc_note_name, 0, 16); + strcpy(lc_note_name, "main bin spec"); + + // lc_note.data_owner + for (int i = 0; i < 16; i++) + loadcmd_data.push_back(lc_note_name[i]); + + // we start writing the payload at payload_file_offset to leave + // room at the start for the header & the load commands. + uint64_t current_payload_offset = payload.size() + payload_file_offset; + + add_uint64(loadcmd_data, current_payload_offset); // note_command.offset + add_uint64(loadcmd_data, + sizeof(struct main_bin_spec_payload)); // note_command.size + + loadcmds.push_back(loadcmd_data); + + // Now write the "main bin spec" payload. + add_uint32(payload, 1); // version + add_uint32(payload, 3); // type == 3 [ firmware, standalone,e tc ] + add_uint64(payload, UINT64_MAX); // load address unknown/unspecified + uuid_t uuid; + uuid_parse(uuidstr.c_str(), uuid); + for (int i = 0; i < sizeof(uuid_t); i++) + payload.push_back(uuid[i]); + add_uint32(payload, 0); // log2_pagesize unspecified + add_uint32(payload, 0); // unused +} + +void add_lc_segment(std::vector> &loadcmds, + std::vector &payload, int payload_file_offset) { + std::vector loadcmd_data; + struct segment_command_64 seg; + seg.cmd = LC_SEGMENT_64; + seg.cmdsize = sizeof(struct segment_command_64); // no sections + memset(seg.segname, 0, 16); + seg.vmaddr = 0xffffff7f96400000; + seg.vmsize = 4096; + seg.fileoff = payload.size() + payload_file_offset; + seg.filesize = 0; + seg.maxprot = 1; + seg.initprot = 1; + seg.nsects = 0; + seg.flags = 0; + + uint8_t *p = (uint8_t *)&seg; + for (int i = 0; i < sizeof(struct segment_command_64); i++) { + loadcmd_data.push_back(*(p + i)); + } + loadcmds.push_back(loadcmd_data); +} + +std::string get_uuid_from_binary(const char *fn) { + FILE *f = fopen(fn, "r"); + if (f == nullptr) { + fprintf(stderr, "Unable to open binary '%s' to get uuid\n", fn); + exit(1); + } + uint32_t num_of_load_cmds = 0; + uint32_t size_of_load_cmds = 0; + std::string uuid; + off_t file_offset = 0; + + uint8_t magic[4]; + if (::fread(magic, 1, 4, f) != 4) { + fprintf(stderr, "Failed to read magic number from input file %s\n", fn); + exit(1); + } + uint8_t magic_32_be[] = {0xfe, 0xed, 0xfa, 0xce}; + uint8_t magic_32_le[] = {0xce, 0xfa, 0xed, 0xfe}; + uint8_t magic_64_be[] = {0xfe, 0xed, 0xfa, 0xcf}; + uint8_t magic_64_le[] = {0xcf, 0xfa, 0xed, 0xfe}; + + if (memcmp(magic, magic_32_be, 4) == 0 || + memcmp(magic, magic_64_be, 4) == 0) { + fprintf(stderr, "big endian corefiles not supported\n"); + exit(1); + } + + ::fseeko(f, 0, SEEK_SET); + if (memcmp(magic, magic_32_le, 4) == 0) { + struct mach_header mh; + if (::fread(&mh, 1, sizeof(mh), f) != sizeof(mh)) { + fprintf(stderr, "error reading mach header from input file\n"); + exit(1); + } + if (mh.cputype != CPU_TYPE_X86_64) { + fprintf(stderr, + "This tool creates an x86_64 corefile but " + "the supplied binary '%s' is cputype 0x%x\n", + fn, (uint32_t)mh.cputype); + exit(1); + } + num_of_load_cmds = mh.ncmds; + size_of_load_cmds = mh.sizeofcmds; + file_offset += sizeof(struct mach_header); + } else { + struct mach_header_64 mh; + if (::fread(&mh, 1, sizeof(mh), f) != sizeof(mh)) { + fprintf(stderr, "error reading mach header from input file\n"); + exit(1); + } + if (mh.cputype != CPU_TYPE_X86_64) { + fprintf(stderr, + "This tool creates an x86_64 corefile but " + "the supplied binary '%s' is cputype 0x%x\n", + fn, (uint32_t)mh.cputype); + exit(1); + } + num_of_load_cmds = mh.ncmds; + size_of_load_cmds = mh.sizeofcmds; + file_offset += sizeof(struct mach_header_64); + } + + off_t load_cmds_offset = file_offset; + + for (int i = 0; i < num_of_load_cmds && + (file_offset - load_cmds_offset) < size_of_load_cmds; + i++) { + ::fseeko(f, file_offset, SEEK_SET); + uint32_t cmd; + uint32_t cmdsize; + ::fread(&cmd, sizeof(uint32_t), 1, f); + ::fread(&cmdsize, sizeof(uint32_t), 1, f); + if (cmd == LC_UUID) { + struct uuid_command uuidcmd; + ::fseeko(f, file_offset, SEEK_SET); + if (::fread(&uuidcmd, 1, sizeof(uuidcmd), f) != sizeof(uuidcmd)) { + fprintf(stderr, "Unable to read LC_UUID load command.\n"); + exit(1); + } + uuid_string_t uuidstr; + uuid_unparse(uuidcmd.uuid, uuidstr); + uuid = uuidstr; + break; + } + file_offset += cmdsize; + } + return uuid; +} + +int main(int argc, char **argv) { + if (argc != 4) { + fprintf(stderr, "usage: create-empty-corefile version-string|main-bin-spec " + " \n"); + fprintf( + stderr, + "Create a Mach-O corefile with an either LC_NOTE 'kern ver str' or \n"); + fprintf(stderr, "an LC_NOTE 'main bin spec' load command without an " + "address specified, depending on\n"); + fprintf(stderr, "whether the 1st arg is version-string or main-bin-spec\n"); + exit(1); + } + if (strcmp(argv[1], "version-string") != 0 && + strcmp(argv[1], "main-bin-spec") != 0) { + fprintf(stderr, "arg1 was not version-string or main-bin-spec\n"); + exit(1); + } + + std::string uuid = get_uuid_from_binary(argv[3]); + + // An array of load commands (in the form of byte arrays) + std::vector> load_commands; + + // An array of corefile contents (page data, lc_note data, etc) + std::vector payload; + + // First add all the load commands / payload so we can figure out how large + // the load commands will actually be. + load_commands.push_back(x86_lc_thread_load_command()); + if (strcmp(argv[1], "version-string") == 0) + add_lc_note_kern_ver_str_load_command(load_commands, payload, 0, uuid); + else + add_lc_note_main_bin_spec_load_command(load_commands, payload, 0, uuid); + add_lc_segment(load_commands, payload, 0); + + int size_of_load_commands = 0; + for (const auto &lc : load_commands) + size_of_load_commands += lc.size(); + + int header_and_load_cmd_room = + sizeof(struct mach_header_64) + size_of_load_commands; + + // Erase the load commands / payload now that we know how much space is + // needed, redo it. + load_commands.clear(); + payload.clear(); + + load_commands.push_back(x86_lc_thread_load_command()); + + if (strcmp(argv[1], "version-string") == 0) + add_lc_note_kern_ver_str_load_command(load_commands, payload, + header_and_load_cmd_room, uuid); + else + add_lc_note_main_bin_spec_load_command(load_commands, payload, + header_and_load_cmd_room, uuid); + + add_lc_segment(load_commands, payload, header_and_load_cmd_room); + + struct mach_header_64 mh; + mh.magic = MH_MAGIC_64; + mh.cputype = CPU_TYPE_X86_64; + + mh.cpusubtype = CPU_SUBTYPE_X86_64_ALL; + mh.filetype = MH_CORE; + mh.ncmds = load_commands.size(); + mh.sizeofcmds = size_of_load_commands; + mh.flags = 0; + mh.reserved = 0; + + FILE *f = fopen(argv[2], "w"); + + if (f == nullptr) { + fprintf(stderr, "Unable to open file %s for writing\n", argv[2]); + exit(1); + } + + fwrite(&mh, sizeof(struct mach_header_64), 1, f); + + for (const auto &lc : load_commands) + fwrite(lc.data(), lc.size(), 1, f); + + fseek(f, header_and_load_cmd_room, SEEK_SET); + + fwrite(payload.data(), payload.size(), 1, f); + + fclose(f); +} diff --git a/lldb/test/API/macosx/lc-note/firmware-corefile/main.c b/lldb/test/API/macosx/lc-note/firmware-corefile/main.c new file mode 100644 index 0000000000000..70a72e0b80b1e --- /dev/null +++ b/lldb/test/API/macosx/lc-note/firmware-corefile/main.c @@ -0,0 +1,2 @@ +#include +int main () { puts ("this is the lc-note test program."); } From 184a13d362e041b1fcd14a5e782ba0b17d13dc3c Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Fri, 25 Sep 2020 10:26:36 -0400 Subject: [PATCH 021/234] AArch64/GlobalISel: Narrow stack passed argument access size This fixes a verifier error in the testcase from bug 47619. The stack passed s3 value was widened to 4-bytes, and producing a 4-byte memory access with a < 1 byte result type. We need to either widen the result type or narrow the access size. This copies the code directly from the AMDGPU handling, which narrows the load size. I don't like that every target has to handle this, but this is currently broken on the 11 release branch and this is the simplest fix. This reverts commit 42bfa7c63b85e76fe16521d1671afcafaf8f64ed. (cherry picked from commit 6cb0d23f2ea6fb25106b0380797ccbc2141d71e1) --- llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp | 9 +++++++-- .../GlobalISel/irtranslator-stack-evt-bug47619.ll | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp index 11a8d5def4296..4832ae8f415f2 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp @@ -84,11 +84,16 @@ struct IncomingArgHandler : public CallLowering::ValueHandler { } } - void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size, + void assignValueToAddress(Register ValVReg, Register Addr, uint64_t MemSize, MachinePointerInfo &MPO, CCValAssign &VA) override { MachineFunction &MF = MIRBuilder.getMF(); + + // The reported memory location may be wider than the value. + const LLT RegTy = MRI.getType(ValVReg); + MemSize = std::min(static_cast(RegTy.getSizeInBytes()), MemSize); + auto MMO = MF.getMachineMemOperand( - MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size, + MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, MemSize, inferAlignFromPtrInfo(MF, MPO)); MIRBuilder.buildLoad(ValVReg, Addr, *MMO); } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-stack-evt-bug47619.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-stack-evt-bug47619.ll index 552997e44f09c..ca36e5da5e5fb 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-stack-evt-bug47619.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-stack-evt-bug47619.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py -; RUN: llc -global-isel -mtriple=aarch64-unknown-unknown -stop-after=irtranslator %s -o - | FileCheck %s +; RUN: llc -global-isel -mtriple=aarch64-unknown-unknown -stop-after=irtranslator -verify-machineinstrs %s -o - | FileCheck %s ; Make sure the i3 %arg8 value is correctly handled. This was trying ; to use MVT for EVT values passed on the stack and asserting before @@ -17,7 +17,7 @@ define i3 @bug47619(i64 %arg, i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %a ; CHECK: [[COPY6:%[0-9]+]]:_(s64) = COPY $x6 ; CHECK: [[COPY7:%[0-9]+]]:_(s64) = COPY $x7 ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0 - ; CHECK: [[LOAD:%[0-9]+]]:_(s3) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load 4 from %fixed-stack.0, align 16) + ; CHECK: [[LOAD:%[0-9]+]]:_(s3) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load 1 from %fixed-stack.0, align 16) ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[LOAD]](s3) ; CHECK: $w0 = COPY [[ANYEXT]](s32) ; CHECK: RET_ReallyLR implicit $w0 From 1e4b179bf821bfff8fad7f46423494ed1f62dac0 Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Fri, 25 Sep 2020 00:01:07 +0300 Subject: [PATCH 022/234] [CodeGen] Do not call `emitGlobalConstantLargeInt` for constant requires 8 bytes to store This is a fix for PR47630. The regression is caused by the D78011. After this change the code starts to call the `emitGlobalConstantLargeInt` even for constants which requires eight bytes to store. Differential revision: https://reviews.llvm.org/D88261 (cherry picked from commit c6c5629f2fb4ddabd376fbe7c218733283e91d09) --- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 2 +- llvm/test/CodeGen/Mips/emit-big-cst.ll | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index f8f7b74baf916..c7eb0257d71b8 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2779,7 +2779,7 @@ static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV, if (const ConstantInt *CI = dyn_cast(CV)) { const uint64_t StoreSize = DL.getTypeStoreSize(CV->getType()); - if (StoreSize < 8) { + if (StoreSize <= 8) { if (AP.isVerbose()) AP.OutStreamer->GetCommentOS() << format("0x%" PRIx64 "\n", CI->getZExtValue()); diff --git a/llvm/test/CodeGen/Mips/emit-big-cst.ll b/llvm/test/CodeGen/Mips/emit-big-cst.ll index 67c2f107db19a..679824ef047b6 100644 --- a/llvm/test/CodeGen/Mips/emit-big-cst.ll +++ b/llvm/test/CodeGen/Mips/emit-big-cst.ll @@ -16,6 +16,14 @@ ; LE-NEXT: .space 5 ; LE-NEXT: .size bigCst, 16 +; BE-LABEL: notSoBigCst: +; BE-NEXT: .8byte 72057594037927935 +; BE-NEXT: .size notSoBigCst, 8 + +; LE-LABEL: notSoBigCst: +; LE-NEXT: .8byte 72057594037927935 +; LE-NEXT: .size notSoBigCst, 8 + ; BE-LABEL: smallCst: ; BE-NEXT: .2byte 4386 ; BE-NEXT: .byte 51 @@ -38,4 +46,14 @@ define void @accessBig(i64* %storage) { ret void } +@notSoBigCst = internal constant i57 72057594037927935 + +define void @accessNotSoBig(i64* %storage) { + %addr = bitcast i64* %storage to i57* + %bigLoadedCst = load volatile i57, i57* @notSoBigCst + %tmp = add i57 %bigLoadedCst, 1 + store i57 %tmp, i57* %addr + ret void +} + @smallCst = internal constant i24 1122867 From 9e367bd69b0d2523237e204b43301e59a5badb29 Mon Sep 17 00:00:00 2001 From: Craig Disselkoen Date: Fri, 25 Sep 2020 14:34:23 -0700 Subject: [PATCH 023/234] C API: functions to get mask of a ShuffleVector This commit fixes a regression (from LLVM 10 to LLVM 11 RC3) in the LLVM C API. Previously, commit 1ee6ec2bf removed the mask operand from the ShuffleVector instruction, storing the mask data separately in the instruction instead; this reduced the number of operands of ShuffleVector from 3 to 2. AFAICT, this change unintentionally caused a regression in the LLVM C API. Specifically, it is no longer possible to get the mask of a ShuffleVector instruction through the C API. This patch introduces new functions which together allow a C API user to get the mask of a ShuffleVector instruction, restoring the functionality which was previously available through LLVMGetOperand(). This patch also adds tests for this change to the llvm-c-test executable, which involved adding support for InsertElement, ExtractElement, and ShuffleVector itself (as well as constant vectors) to echo.cpp. Previously, vector operations weren't tested at all in echo.ll. I also fixed some typos in comments and help-text nearby these changes, which I happened to spot while developing this patch. Since the typo fixes are technically unrelated other than being in the same files, I'm happy to take them out if you'd rather they not be included in the patch. Differential Revision: https://reviews.llvm.org/D88190 (cherry picked from commit 51cad041e0cb26597c7ccc0fbfaa349b8fffbcda) --- llvm/include/llvm-c/Core.h | 15 +++++- llvm/lib/IR/Core.cpp | 14 ++++++ llvm/test/Bindings/llvm-c/echo.ll | 18 +++++++ llvm/tools/llvm-c-test/echo.cpp | 80 ++++++++++++++++++++++++++----- llvm/tools/llvm-c-test/main.c | 9 ++-- 5 files changed, 119 insertions(+), 17 deletions(-) diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index 2c7b4c6eff107..34d23146be40f 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -3636,7 +3636,7 @@ void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest); /* Get the number of clauses on the landingpad instruction */ unsigned LLVMGetNumClauses(LLVMValueRef LandingPad); -/* Get the value of the clause at idnex Idx on the landingpad instruction */ +/* Get the value of the clause at index Idx on the landingpad instruction */ LLVMValueRef LLVMGetClause(LLVMValueRef LandingPad, unsigned Idx); /* Add a catch or filter clause to the landingpad instruction */ @@ -3937,6 +3937,19 @@ LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Ptr, LLVMAtomicOrdering FailureOrdering, LLVMBool SingleThread); +/** + * Get the number of elements in the mask of a ShuffleVector instruction. + */ +unsigned LLVMGetNumMaskElements(LLVMValueRef ShuffleVectorInst); + +/** + * Get the mask value at position Elt in the mask of a ShuffleVector + * instruction. Return LLVMUndefMaskElem if the mask value is undef at that + * position. + */ +int LLVMGetMaskValue(LLVMValueRef ShuffleVectorInst, unsigned Elt); +extern const int LLVMUndefMaskElem; + LLVMBool LLVMIsAtomicSingleThread(LLVMValueRef AtomicInst); void LLVMSetAtomicSingleThread(LLVMValueRef AtomicInst, LLVMBool SingleThread); diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 6f3bbc80d4fd5..9caaea4b1f7a0 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -3952,6 +3952,20 @@ LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Ptr, singleThread ? SyncScope::SingleThread : SyncScope::System)); } +unsigned LLVMGetNumMaskElements(LLVMValueRef SVInst) { + Value *P = unwrap(SVInst); + ShuffleVectorInst *I = cast(P); + return I->getShuffleMask().size(); +} + +int LLVMGetMaskValue(LLVMValueRef SVInst, unsigned Elt) { + Value *P = unwrap(SVInst); + ShuffleVectorInst *I = cast(P); + return I->getMaskValue(Elt); +} +const int LLVMUndefMaskElem = + -1; // not actually accessible as ShuffleVectorInst::UndefMaskElem, so we + // hardcode it here LLVMBool LLVMIsAtomicSingleThread(LLVMValueRef AtomicInst) { Value *P = unwrap(AtomicInst); diff --git a/llvm/test/Bindings/llvm-c/echo.ll b/llvm/test/Bindings/llvm-c/echo.ll index 510798592b9d3..5494170f3cd65 100644 --- a/llvm/test/Bindings/llvm-c/echo.ll +++ b/llvm/test/Bindings/llvm-c/echo.ll @@ -156,6 +156,24 @@ define void @memops(i8* %ptr) { ret void } +define i32 @vectorops(i32, i32) { + %a = insertelement <4 x i32> undef, i32 %0, i32 0 + %b = insertelement <4 x i32> %a, i32 %1, i32 2 + %c = shufflevector <4 x i32> %b, <4 x i32> undef, <4 x i32> zeroinitializer + %d = shufflevector <4 x i32> %c, <4 x i32> %b, <4 x i32> + %e = add <4 x i32> %d, %a + %f = mul <4 x i32> %e, %b + %g = xor <4 x i32> %f, %d + %h = or <4 x i32> %f, %e + %i = lshr <4 x i32> %h, + %j = shl <4 x i32> %i, + %k = shufflevector <4 x i32> %j, <4 x i32> %i, <4 x i32> + %m = shufflevector <4 x i32> %k, <4 x i32> undef, <1 x i32> + %n = shufflevector <4 x i32> %j, <4 x i32> undef, <8 x i32> + %p = extractelement <8 x i32> %n, i32 5 + ret i32 %p +} + declare void @personalityFn() define void @exn() personality void ()* @personalityFn { diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp index b254da28ddc4b..b404048749d39 100644 --- a/llvm/tools/llvm-c-test/echo.cpp +++ b/llvm/tools/llvm-c-test/echo.cpp @@ -30,7 +30,7 @@ template struct CAPIDenseMap {}; // The default DenseMapInfo require to know about pointer alignment. -// Because the C API uses opaques pointer types, their alignment is unknown. +// Because the C API uses opaque pointer types, their alignment is unknown. // As a result, we need to roll out our own implementation. template struct CAPIDenseMap { @@ -306,7 +306,7 @@ static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) { return LLVMConstArray(LLVMGetElementType(Ty), Elts.data(), EltCount); } - // Try contant data array + // Try constant data array if (LLVMIsAConstantDataArray(Cst)) { check_value_kind(Cst, LLVMConstantDataArrayValueKind); LLVMTypeRef Ty = TypeCloner(M).Clone(Cst); @@ -357,9 +357,32 @@ static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) { report_fatal_error("ConstantFP is not supported"); } - // This kind of constant is not supported + // Try ConstantVector + if (LLVMIsAConstantVector(Cst)) { + check_value_kind(Cst, LLVMConstantVectorValueKind); + LLVMTypeRef Ty = TypeCloner(M).Clone(Cst); + unsigned EltCount = LLVMGetVectorSize(Ty); + SmallVector Elts; + for (unsigned i = 0; i < EltCount; i++) + Elts.push_back(clone_constant(LLVMGetOperand(Cst, i), M)); + return LLVMConstVector(Elts.data(), EltCount); + } + + // Try ConstantDataVector + if (LLVMIsAConstantDataVector(Cst)) { + check_value_kind(Cst, LLVMConstantDataVectorValueKind); + LLVMTypeRef Ty = TypeCloner(M).Clone(Cst); + unsigned EltCount = LLVMGetVectorSize(Ty); + SmallVector Elts; + for (unsigned i = 0; i < EltCount; i++) + Elts.push_back(clone_constant(LLVMGetElementAsConstant(Cst, i), M)); + return LLVMConstVector(Elts.data(), EltCount); + } + + // At this point, if it's not a constant expression, it's a kind of constant + // which is not supported if (!LLVMIsAConstantExpr(Cst)) - report_fatal_error("Expected a constant expression"); + report_fatal_error("Unsupported constant kind"); // At this point, it must be a constant expression check_value_kind(Cst, LLVMConstantExprValueKind); @@ -370,7 +393,8 @@ static LLVMValueRef clone_constant_impl(LLVMValueRef Cst, LLVMModuleRef M) { return LLVMConstBitCast(clone_constant(LLVMGetOperand(Cst, 0), M), TypeCloner(M).Clone(Cst)); default: - fprintf(stderr, "%d is not a supported opcode\n", Op); + fprintf(stderr, "%d is not a supported opcode for constant expressions\n", + Op); exit(-1); } } @@ -443,7 +467,7 @@ struct FunCloner { auto i = VMap.find(Src); if (i != VMap.end()) { // If we have a hit, it means we already generated the instruction - // as a dependancy to somethign else. We need to make sure + // as a dependency to something else. We need to make sure // it is ordered properly. auto I = i->second; LLVMInstructionRemoveFromParent(I); @@ -746,8 +770,10 @@ struct FunCloner { } case LLVMExtractValue: { LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0)); - if (LLVMGetNumIndices(Src) != 1) - report_fatal_error("Expected only one indice"); + if (LLVMGetNumIndices(Src) > 1) + report_fatal_error("ExtractValue: Expected only one index"); + else if (LLVMGetNumIndices(Src) < 1) + report_fatal_error("ExtractValue: Expected an index"); auto I = LLVMGetIndices(Src)[0]; Dst = LLVMBuildExtractValue(Builder, Agg, I, Name); break; @@ -755,12 +781,44 @@ struct FunCloner { case LLVMInsertValue: { LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0)); LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 1)); - if (LLVMGetNumIndices(Src) != 1) - report_fatal_error("Expected only one indice"); + if (LLVMGetNumIndices(Src) > 1) + report_fatal_error("InsertValue: Expected only one index"); + else if (LLVMGetNumIndices(Src) < 1) + report_fatal_error("InsertValue: Expected an index"); auto I = LLVMGetIndices(Src)[0]; Dst = LLVMBuildInsertValue(Builder, Agg, V, I, Name); break; } + case LLVMExtractElement: { + LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0)); + LLVMValueRef Index = CloneValue(LLVMGetOperand(Src, 1)); + Dst = LLVMBuildExtractElement(Builder, Agg, Index, Name); + break; + } + case LLVMInsertElement: { + LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0)); + LLVMValueRef V = CloneValue(LLVMGetOperand(Src, 1)); + LLVMValueRef Index = CloneValue(LLVMGetOperand(Src, 2)); + Dst = LLVMBuildInsertElement(Builder, Agg, V, Index, Name); + break; + } + case LLVMShuffleVector: { + LLVMValueRef Agg0 = CloneValue(LLVMGetOperand(Src, 0)); + LLVMValueRef Agg1 = CloneValue(LLVMGetOperand(Src, 1)); + SmallVector MaskElts; + unsigned NumMaskElts = LLVMGetNumMaskElements(Src); + for (unsigned i = 0; i < NumMaskElts; i++) { + int Val = LLVMGetMaskValue(Src, i); + if (Val == LLVMUndefMaskElem) { + MaskElts.push_back(LLVMGetUndef(LLVMInt64Type())); + } else { + MaskElts.push_back(LLVMConstInt(LLVMInt64Type(), Val, true)); + } + } + LLVMValueRef Mask = LLVMConstVector(MaskElts.data(), NumMaskElts); + Dst = LLVMBuildShuffleVector(Builder, Agg0, Agg1, Mask, Name); + break; + } case LLVMFreeze: { LLVMValueRef Arg = CloneValue(LLVMGetOperand(Src, 0)); Dst = LLVMBuildFreeze(Builder, Arg, Name); @@ -1102,7 +1160,7 @@ static void clone_symbols(LLVMModuleRef Src, LLVMModuleRef M) { LLVMGlobalSetMetadata(G, Kind, MD); } LLVMDisposeValueMetadataEntries(AllMetadata); - + LLVMSetGlobalConstant(G, LLVMIsGlobalConstant(Cur)); LLVMSetThreadLocal(G, LLVMIsThreadLocal(Cur)); LLVMSetExternallyInitialized(G, LLVMIsExternallyInitialized(Cur)); diff --git a/llvm/tools/llvm-c-test/main.c b/llvm/tools/llvm-c-test/main.c index 0be48930f0b65..5e8adb45d691e 100644 --- a/llvm/tools/llvm-c-test/main.c +++ b/llvm/tools/llvm-c-test/main.c @@ -36,10 +36,10 @@ static void print_usage(void) { fprintf(stderr, " * --targets-list\n"); fprintf(stderr, " List available targets\n\n"); fprintf(stderr, " * --object-list-sections\n"); - fprintf(stderr, " Read object file form stdin - list sections\n\n"); + fprintf(stderr, " Read object file from stdin - list sections\n\n"); fprintf(stderr, " * --object-list-symbols\n"); fprintf(stderr, - " Read object file form stdin - list symbols (like nm)\n\n"); + " Read object file from stdin - list symbols (like nm)\n\n"); fprintf(stderr, " * --disassemble\n"); fprintf(stderr, " Read lines of triple, hex ascii machine code from stdin " "- print disassembly\n\n"); @@ -48,11 +48,10 @@ static void print_usage(void) { stderr, " Read lines of name, rpn from stdin - print generated module\n\n"); fprintf(stderr, " * --echo\n"); - fprintf(stderr, - " Read bitcode file form stdin - print it back out\n\n"); + fprintf(stderr, " Read bitcode file from stdin - print it back out\n\n"); fprintf(stderr, " * --test-diagnostic-handler\n"); fprintf(stderr, - " Read bitcode file form stdin with a diagnostic handler set\n\n"); + " Read bitcode file from stdin with a diagnostic handler set\n\n"); fprintf(stderr, " * --test-dibuilder\n"); fprintf(stderr, " Run tests for the DIBuilder C API - print generated module\n\n"); From 293924973057e33fcc63521f582bb9fd41e60cc4 Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Sat, 26 Sep 2020 17:32:38 -0600 Subject: [PATCH 024/234] [LLVM-C] Turn a ShuffleVector Constant Into a Getter. It is not a good idea to expose raw constants in the LLVM C API. Replace this with an explicit getter. Differential Revision: https://reviews.llvm.org/D88367 (cherry picked from commit 55f727306e727ea9f013d09c9b8aa70dbce6a1bd) --- llvm/include/llvm-c/Core.h | 13 ++++++++++--- llvm/lib/IR/Core.cpp | 5 ++--- llvm/tools/llvm-c-test/echo.cpp | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index 34d23146be40f..c8a6f970419b3 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -3942,13 +3942,20 @@ LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef Ptr, */ unsigned LLVMGetNumMaskElements(LLVMValueRef ShuffleVectorInst); +/** + * \returns a constant that specifies that the result of a \c ShuffleVectorInst + * is undefined. + */ +int LLVMGetUndefMaskElem(void); + /** * Get the mask value at position Elt in the mask of a ShuffleVector - * instruction. Return LLVMUndefMaskElem if the mask value is undef at that - * position. + * instruction. + * + * \Returns the result of \c LLVMGetUndefMaskElem() if the mask value is undef + * at that position. */ int LLVMGetMaskValue(LLVMValueRef ShuffleVectorInst, unsigned Elt); -extern const int LLVMUndefMaskElem; LLVMBool LLVMIsAtomicSingleThread(LLVMValueRef AtomicInst); void LLVMSetAtomicSingleThread(LLVMValueRef AtomicInst, LLVMBool SingleThread); diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 9caaea4b1f7a0..c1f7329034e09 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -3963,9 +3963,8 @@ int LLVMGetMaskValue(LLVMValueRef SVInst, unsigned Elt) { ShuffleVectorInst *I = cast(P); return I->getMaskValue(Elt); } -const int LLVMUndefMaskElem = - -1; // not actually accessible as ShuffleVectorInst::UndefMaskElem, so we - // hardcode it here + +int LLVMGetUndefMaskElem(void) { return UndefMaskElem; } LLVMBool LLVMIsAtomicSingleThread(LLVMValueRef AtomicInst) { Value *P = unwrap(AtomicInst); diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp index b404048749d39..0b3a10f463dd3 100644 --- a/llvm/tools/llvm-c-test/echo.cpp +++ b/llvm/tools/llvm-c-test/echo.cpp @@ -809,7 +809,7 @@ struct FunCloner { unsigned NumMaskElts = LLVMGetNumMaskElements(Src); for (unsigned i = 0; i < NumMaskElts; i++) { int Val = LLVMGetMaskValue(Src, i); - if (Val == LLVMUndefMaskElem) { + if (Val == LLVMGetUndefMaskElem()) { MaskElts.push_back(LLVMGetUndef(LLVMInt64Type())); } else { MaskElts.push_back(LLVMConstInt(LLVMInt64Type(), Val, true)); From eb83b551d3eb08cf472fe6307fe3809a8005b2cc Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 28 Sep 2020 15:35:01 +0200 Subject: [PATCH 025/234] Fix mysterious failure of SupportTests FileCheckTest.Binop The test would fail in no-asserts release builds using MSVC for 64-bit Windows: Unexpected error message: TestBuffer:1:1: error: implicit format conflict between 'FOO' (%u) and '18\0' (%x), need an explicit format specifier Error message(s) not found: {implicit format conflict between 'FOO' (%u) and 'BAZ' (%x), need an explicit format specifier} It seems a string from a previous test case is finding its way into the latter one. This doesn't reproduce on master anymore after 998709b7d, so let's just hack around it here for the branch. --- llvm/unittests/Support/FileCheckTest.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/unittests/Support/FileCheckTest.cpp b/llvm/unittests/Support/FileCheckTest.cpp index 92975dcd76b74..a4591bc319bbb 100644 --- a/llvm/unittests/Support/FileCheckTest.cpp +++ b/llvm/unittests/Support/FileCheckTest.cpp @@ -714,6 +714,7 @@ TEST_F(FileCheckTest, Binop) { Value = Binop.eval(); expectUndefErrors({"FOO", "BAR"}, Value.takeError()); + { // Literal + Variable has format of variable. ExprStr = bufferize(SM, "FOO+18"); FooStr = ExprStr.take_front(3); @@ -736,6 +737,7 @@ TEST_F(FileCheckTest, Binop) { ImplicitFormat = Binop.getImplicitFormat(SM); ASSERT_THAT_EXPECTED(ImplicitFormat, Succeeded()); EXPECT_EQ(*ImplicitFormat, ExpressionFormat::Kind::Unsigned); + } // Variables with different implicit format conflict. ExprStr = bufferize(SM, "FOO+BAZ"); From 2875ec773d20ecf796a7e532532bdfc90c64ef94 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 25 Sep 2020 10:08:24 -0700 Subject: [PATCH 026/234] Fix DISubprogram-v4.ll after e17f52d623cc146b7d9bf5a2e02965043508b4c4 (cherry picked from commit 7d0556fc137aa07347741b7750e50ecbc2b4c6e2) --- llvm/test/Bitcode/DISubprogram-v4.ll | 4 ++-- llvm/test/Bitcode/DISubprogram-v4.ll.bc | Bin 1372 -> 1336 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/test/Bitcode/DISubprogram-v4.ll b/llvm/test/Bitcode/DISubprogram-v4.ll index ce5521002cafb..9e5caecd7361a 100644 --- a/llvm/test/Bitcode/DISubprogram-v4.ll +++ b/llvm/test/Bitcode/DISubprogram-v4.ll @@ -24,8 +24,8 @@ define void @_Z3foov() !dbg !9 { !8 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang", file: !2, isOptimized: true, flags: "-O2") -; CHECK: !9 = !DISubprogram(scope: null, spFlags: 0) -!9 = !DISubprogram(isDefinition: false) +; CHECK: !9 = distinct !DISubprogram(scope: null, spFlags: 0) +!9 = distinct !DISubprogram(isDefinition: false) ; CHECK: !10 = distinct !DISubprogram({{.*}}, spFlags: DISPFlagPureVirtual | DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, !10 = distinct !DISubprogram(name: "foo", linkageName: "_Zfoov", scope: !1, diff --git a/llvm/test/Bitcode/DISubprogram-v4.ll.bc b/llvm/test/Bitcode/DISubprogram-v4.ll.bc index 392df4aae74d3fb0df0c2196191496a4eb4045dd..41bbcf874ac144ac97196fdf8d5e1300a91441b1 100644 GIT binary patch delta 473 zcmcb^wS&vh$@#!NQxOIRRt5%!Bpw45&&Ykx-d(oSbzw9D2{9=0Ffdp%GB9v6DKant z`N9(o4df??C^)-yEM<^1a$@o1n=n!FNPuHtW6#6pr(GiE@xcyc2{BI*j*l`< W%g-+}*E7&FuqiG{$;`6@s{sH{`fMZs delta 509 zcmdnNb%)E)$@#!NQxOIRRt5%!Bpw45pU8b`?=RcwhV}}uo&bs~@-Q&iF)}c4Gbu7K z0o902G&ImIIHIWRBGld^;5dmXC@!v0SUmYVQz7H6$(hUw^%|`UWupZcx)~T6nSn<7gz|bNW*iq|IUvN~@Bm~- zaAsio_qij zff>U9GzJVH#>7C)VL&oR8ez^E0S0DK2L*-$J}nF>2STPo^};BF!woW>JuGS(+}k&7 zGujlWrgPFHHE~W_^#YGsD^Bg2oWjzU*2s1Qs2t>~XqE(!7a0l_7#KhdBR&D87KYuR zXaIv)VBGKmSwhTH(m(?7QO0Tc`DGS*26_g?WqAtenI*br#>uHE7Dj0nmL@jEB`KMC Ic3`ax0J7bADF6Tf From 815c690f207529286f5d78049692ec1356d041f8 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Fri, 25 Sep 2020 13:09:47 -0700 Subject: [PATCH 027/234] [ubsan] nullability-arg: Fix crash on C++ member pointers Extend -fsanitize=nullability-arg to handle call sites which accept C++ member pointers. rdar://62476022 Differential Revision: https://reviews.llvm.org/D88336 (cherry picked from commit 06bc685fa2400cc28282ab6dd3c917d45bfa662f) --- clang/lib/CodeGen/CGCall.cpp | 5 +- clang/lib/CodeGen/CGExpr.cpp | 7 +++ clang/lib/CodeGen/CodeGenFunction.h | 3 ++ .../test/CodeGenCXX/ubsan-nullability-arg.cpp | 51 +++++++++++++++++++ 4 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 clang/test/CodeGenCXX/ubsan-nullability-arg.cpp diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 69d4a60705718..88ad08279cc07 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -3746,10 +3746,7 @@ void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType, } SanitizerScope SanScope(this); - assert(RV.isScalar()); - llvm::Value *V = RV.getScalarVal(); - llvm::Value *Cond = - Builder.CreateICmpNE(V, llvm::Constant::getNullValue(V->getType())); + llvm::Value *Cond = EmitNonNullRValueCheck(RV, ArgType); llvm::Constant *StaticData[] = { EmitCheckSourceLocation(ArgLoc), EmitCheckSourceLocation(AttrLoc), llvm::ConstantInt::get(Int32Ty, ArgNo + 1), diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index c6cfaf6fe9d6e..b0c44eda43515 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1170,6 +1170,13 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E, return Address(EmitScalarExpr(E), Align); } +llvm::Value *CodeGenFunction::EmitNonNullRValueCheck(RValue RV, QualType T) { + llvm::Value *V = RV.getScalarVal(); + if (auto MPT = T->getAs()) + return CGM.getCXXABI().EmitMemberPointerIsNotNull(*this, V, MPT); + return Builder.CreateICmpNE(V, llvm::Constant::getNullValue(V->getType())); +} + RValue CodeGenFunction::GetUndefRValue(QualType Ty) { if (Ty->isVoidType()) return RValue::get(nullptr); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index d3b11618d5129..cb903a1f9d880 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -3563,6 +3563,9 @@ class CodeGenFunction : public CodeGenTypeCache { // LValue Expression Emission //===--------------------------------------------------------------------===// + /// Create a check that a scalar RValue is non-null. + llvm::Value *EmitNonNullRValueCheck(RValue RV, QualType T); + /// GetUndefRValue - Get an appropriate 'undef' rvalue for the given type. RValue GetUndefRValue(QualType Ty); diff --git a/clang/test/CodeGenCXX/ubsan-nullability-arg.cpp b/clang/test/CodeGenCXX/ubsan-nullability-arg.cpp new file mode 100644 index 0000000000000..fbebd153a9eae --- /dev/null +++ b/clang/test/CodeGenCXX/ubsan-nullability-arg.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -x c++ -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=nullability-arg | FileCheck %s -check-prefixes=ITANIUM,ALL +// RUN: %clang_cc1 -x c++ -triple x86_64-pc-windows-msvc -emit-llvm -o - %s -fsanitize=nullability-arg | FileCheck %s -check-prefixes=MSVC,ALL + +namespace method_ptr { + +struct S0 { + void foo1(); +}; + +void foo1(void (S0::*_Nonnull f)()); + +// ITANIUM-LABEL: @_ZN10method_ptr5test1Ev(){{.*}} { +// ITANIUM: br i1 icmp ne (i64 ptrtoint (void (%"struct.method_ptr::S0"*)* @_ZN10method_ptr2S04foo1Ev to i64), i64 0), label %[[CONT:.*]], label %[[FAIL:[^,]*]] +// ITANIUM-EMPTY: +// ITANIUM-NEXT: [[FAIL]]: +// ITANIUM-NEXT: call void @__ubsan_handle_nullability_arg + +// MSVC-LABEL: @"?test1@method_ptr@@YAXXZ"(){{.*}} { +// MSVC: br i1 true, label %[[CONT:.*]], label %[[FAIL:[^,]*]] +// MSVC-EMPTY: +// MSVC-NEXT: [[FAIL]]: +// MSVC-NEXT: call void @__ubsan_handle_nullability_arg +void test1() { + foo1(&S0::foo1); +} + +} // namespace method_ptr + +namespace data_ptr { + +struct S0 { + int field1; +}; + +using member_ptr = int S0::*; + +void foo1(member_ptr _Nonnull); + +// ITANIUM-LABEL: @_ZN8data_ptr5test1ENS_2S0E( +// MSVC-LABEL: @"?test1@data_ptr@@YAXUS0@1@@Z"( +// ALL: [[DATA_PTR_CHECK:%.*]] = icmp ne {{.*}}, -1, !nosanitize +// ALL-NEXT: br i1 [[DATA_PTR_CHECK]], label %[[CONT:.*]], label %[[FAIL:[^,]+]] +// ALL-EMPTY: +// ALL-NEXT: [[FAIL]]: +// ALL-NEXT: call void @__ubsan_handle_nullability_arg +void test1(S0 s) { + int S0::*member = &S0::field1; + foo1(member); +} + +} // namespace data_ptr From d626bb872333b901ee6147522a48bfa2be994a7d Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Wed, 23 Sep 2020 22:00:57 -0700 Subject: [PATCH 028/234] [dwarfdump] Warn for tags with DW_CHILDREN_yes but no children. Flag DIEs that have DW_CHILDREN_yes set in their abbreviation but don't actually have any children. rdar://59809554 Differential revision: https://reviews.llvm.org/D88048 (cherry picked from commit e1ef7183c6f008fa13cbe273500b020c4fad1252) --- llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp | 9 ++++++++ .../test/DebugInfo/X86/skeleton-unit-verify.s | 4 +++- .../tools/llvm-dwarfdump/X86/no-children.yaml | 23 +++++++++++++++++++ .../llvm-dwarfdump/X86/verify_die_ranges.s | 3 ++- 4 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 llvm/test/tools/llvm-dwarfdump/X86/no-children.yaml diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp index 3a83317a73a3b..895dd7d2a575d 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -172,6 +172,15 @@ unsigned DWARFVerifier::verifyUnitContents(DWARFUnit &Unit) { NumUnitErrors += verifyDebugInfoForm(Die, AttrValue); } + if (Die.hasChildren()) { + if (Die.getFirstChild().isValid() && + Die.getFirstChild().getTag() == DW_TAG_null) { + warn() << dwarf::TagString(Die.getTag()) + << " has DW_CHILDREN_yes but DIE has no children: "; + Die.dump(OS); + } + } + NumUnitErrors += verifyDebugInfoCallSite(Die); } diff --git a/llvm/test/DebugInfo/X86/skeleton-unit-verify.s b/llvm/test/DebugInfo/X86/skeleton-unit-verify.s index d990d918cef6f..95fbd113942a4 100644 --- a/llvm/test/DebugInfo/X86/skeleton-unit-verify.s +++ b/llvm/test/DebugInfo/X86/skeleton-unit-verify.s @@ -3,6 +3,8 @@ # CHECK: Verifying .debug_abbrev... # CHECK-NEXT: Verifying .debug_info Unit Header Chain... +# CHECK-NEXT: warning: DW_TAG_skeleton_unit has DW_CHILDREN_yes but DIE has no children +# CHECK-NEXT: DW_TAG_skeleton_unit # CHECK-NEXT: error: Skeleton compilation unit has children. # CHECK-NEXT: Verifying .debug_info references... # CHECK-NEXT: Verifying .debug_types Unit Header Chain... @@ -30,7 +32,7 @@ .byte 8 # Address Size (in bytes) .long .debug_abbrev # Offset Into Abbrev. Section .quad -6573227469967412476 - .byte 1 # Abbrev [1] + .byte 1 # Abbrev [1] .byte 0 .Lcu_end0: .long .Lcu_end1-.Lcu_start1 # Length of Unit diff --git a/llvm/test/tools/llvm-dwarfdump/X86/no-children.yaml b/llvm/test/tools/llvm-dwarfdump/X86/no-children.yaml new file mode 100644 index 0000000000000..1417ab2bdc3f0 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfdump/X86/no-children.yaml @@ -0,0 +1,23 @@ +# RUN: yaml2obj %s | llvm-dwarfdump -verify - | FileCheck %s +# CHECK: warning: DW_TAG_compile_unit has DW_CHILDREN_yes but DIE has no children + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC +DWARF: + debug_abbrev: + - Table: + - Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_data4 + debug_info: + - Version: 4 + Entries: + - AbbrCode: 1 + Values: + - Value: 0x1234 + - AbbrCode: 0 ## Terminator for the current DIE. diff --git a/llvm/test/tools/llvm-dwarfdump/X86/verify_die_ranges.s b/llvm/test/tools/llvm-dwarfdump/X86/verify_die_ranges.s index ea357b728897e..ea461b27e3e7d 100644 --- a/llvm/test/tools/llvm-dwarfdump/X86/verify_die_ranges.s +++ b/llvm/test/tools/llvm-dwarfdump/X86/verify_die_ranges.s @@ -3,7 +3,8 @@ # RUN: | FileCheck %s # CHECK: Verifying .debug_info Unit Header Chain... -# CHECK-NEXT: error: Invalid address range [0x0000000000000007, 0x0000000000000006) +# CHECK: warning: DW_TAG_compile_unit has DW_CHILDREN_yes but DIE has no children: +# CHECK: error: Invalid address range [0x0000000000000007, 0x0000000000000006) .section __TEXT,__text,regular,pure_instructions .macosx_version_min 10, 12 From 20f43169a6418c93fad4946a3ae08ef8ef70edd2 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Mon, 28 Sep 2020 12:14:26 -0700 Subject: [PATCH 029/234] Add missing cases to TypeSystemSwiftTypeRef::GetTypeInfo() --- .../Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index dde158b52ab98..69d95bf28d4c7 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -780,11 +780,17 @@ static uint32_t collectTypeInfo(Module *M, swift::Demangle::Demangler &dem, swift_flags |= eTypeIsPointer | eTypeIsScalar; else if (node->getText() == swift::BUILTIN_TYPE_NAME_NATIVEOBJECT) swift_flags |= eTypeHasChildren | eTypeIsPointer | eTypeIsScalar; - else if (node->getText() == swift::BUILTIN_TYPE_NAME_BRIDGEOBJECT) + else if (node->getText() == swift::BUILTIN_TYPE_NAME_BRIDGEOBJECT || + node->getText() == swift::BUILTIN_TYPE_NAME_UNKNOWNOBJECT) swift_flags |= eTypeHasChildren | eTypeIsPointer | eTypeIsScalar | eTypeIsObjC; + else if (node->getText() == swift::BUILTIN_TYPE_NAME_FLOAT || + node->getText() == swift::BUILTIN_TYPE_NAME_FLOAT_PPC) + swift_flags |= eTypeIsFloat | eTypeIsScalar; else if (node->getText().startswith(swift::BUILTIN_TYPE_NAME_VEC)) swift_flags |= eTypeHasChildren | eTypeIsVector; + else if (node->getText().startswith(swift::BUILTIN_TYPE_NAME_INT)) + swift_flags |= eTypeIsInteger | eTypeIsScalar; } break; case Node::Kind::Tuple: From f9789906de9c5d43171561bc42de2635673d59f5 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Mon, 28 Sep 2020 15:04:37 -0700 Subject: [PATCH 030/234] Delete leftover dead code. --- lldb/include/lldb/Symbol/Type.h | 1 - 1 file changed, 1 deletion(-) diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h index 284d91011be51..b9cebaeb51a05 100644 --- a/lldb/include/lldb/Symbol/Type.h +++ b/lldb/include/lldb/Symbol/Type.h @@ -220,7 +220,6 @@ class Type : public std::enable_shared_from_this, public UserID { Declaration m_decl; CompilerType m_compiler_type; ResolveState m_compiler_type_resolve_state; - bool m_is_swift_fixed_value_buffer = false; /// Language-specific flags. Payload m_payload; From afada41144add1d1813514c30edd564e788da0ba Mon Sep 17 00:00:00 2001 From: Michelle Casbon Date: Fri, 25 Sep 2020 22:18:30 +0000 Subject: [PATCH 031/234] Add missing NodeType enums --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index d9a2514378273..9ce0e16dfc6f4 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -1380,6 +1380,8 @@ const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const { case AArch64ISD::FIRST_NUMBER: break; MAKE_CASE(AArch64ISD::CALL) + MAKE_CASE(AArch64ISD::AUTH_CALL) + MAKE_CASE(AArch64ISD::AUTH_TC_RETURN) MAKE_CASE(AArch64ISD::ADRP) MAKE_CASE(AArch64ISD::ADR) MAKE_CASE(AArch64ISD::ADDlow) From f7ca6e96f058d6c2f6f193fa0e6c157577d20334 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Mon, 28 Sep 2020 15:59:26 -0700 Subject: [PATCH 032/234] Relax assertion --- .../source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index dde158b52ab98..f92bbe1d25286 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1198,6 +1198,9 @@ bool Equivalent>(llvm::Optional l, // thus assume that a larger number is "better". if (l.hasValue() && r.hasValue() && *l > *r) return true; + // Assume that any value is "better" than none. + if (l.hasValue() && !r.hasValue()) + return true; llvm::dbgs() << l << " != " << r << "\n"; return false; } From 9601689fc4e587ef96ac914465e36842e5680c0b Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Mon, 28 Sep 2020 16:15:40 -0700 Subject: [PATCH 033/234] Remove what appears to be unnecessary code --- .../Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp index 865072fd08298..96f3832b63849 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp @@ -615,10 +615,6 @@ static void AddVariableInfo( var_type = valobj_sp->GetCompilerType(); } - if (!var_type.IsValid()) - if (Type *var_lldb_type = variable_sp->GetType()) - var_type = var_lldb_type->GetFullCompilerType(); - if (!var_type.IsValid()) return; From 8994b1f3d3c2ab4729fc3d429b56bf0065aa8e16 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 28 Sep 2020 16:56:38 -0700 Subject: [PATCH 034/234] Once we've found a firmware binary and loaded it, don't search more (#1872) Add the flag in ProcessMachCore::DoLoadCore that stops additional searches for the binaries when we have an LC_NOTE identifying the firmware/standalone binary as the correct one & we have loaded it successfully. (cherry picked from commit 6e54918db7f4dad0d5a6fbff140009ed6f151d2c) --- lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index bee161bde96b5..744942115016e 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -398,6 +398,7 @@ Status ProcessMachCore::DoLoadCore() { added_module.Append(module_sp, false); GetTarget().ModulesDidLoad(added_module); m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); + found_main_binary_definitively = true; } } } From 861da5bd520fe2875bf41692addc5ff4d564ccae Mon Sep 17 00:00:00 2001 From: Jan Korous Date: Wed, 16 Sep 2020 09:52:51 -0700 Subject: [PATCH 035/234] [clang] Selectively ena/disa-ble format-insufficient-args warning Differential Revision: https://reviews.llvm.org/D87176 --- clang/include/clang/Basic/DiagnosticGroups.td | 4 +++- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/test/Misc/warning-wall.c | 1 + clang/test/Sema/warn-printf-insufficient-data-args.c | 11 +++++++++++ 4 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 clang/test/Sema/warn-printf-insufficient-data-args.c diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 5e0031335e1ce..6dc2e51b434ca 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -234,6 +234,7 @@ def ExtraSemi : DiagGroup<"extra-semi", [CXX98CompatExtraSemi, def GNUFlexibleArrayInitializer : DiagGroup<"gnu-flexible-array-initializer">; def GNUFlexibleArrayUnionMember : DiagGroup<"gnu-flexible-array-union-member">; def GNUFoldingConstant : DiagGroup<"gnu-folding-constant">; +def FormatInsufficientArgs : DiagGroup<"format-insufficient-args">; def FormatExtraArgs : DiagGroup<"format-extra-args">; def FormatZeroLength : DiagGroup<"format-zero-length">; @@ -840,7 +841,8 @@ def FormatPedantic : DiagGroup<"format-pedantic">; def FormatTypeConfusion : DiagGroup<"format-type-confusion">; def Format : DiagGroup<"format", [FormatExtraArgs, FormatZeroLength, NonNull, - FormatSecurity, FormatY2K, FormatInvalidSpecifier]>, + FormatSecurity, FormatY2K, FormatInvalidSpecifier, + FormatInsufficientArgs]>, DiagCategory<"Format String Issue">; def FormatNonLiteral : DiagGroup<"format-nonliteral">; def Format2 : DiagGroup<"format=2", diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index c8cc44b4feb35..685a735bd4518 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8945,7 +8945,7 @@ def note_array_declared_here : Note< "array %0 declared here">; def warn_printf_insufficient_data_args : Warning< - "more '%%' conversions than data arguments">, InGroup; + "more '%%' conversions than data arguments">, InGroup; def warn_printf_data_arg_not_used : Warning< "data argument not used by format string">, InGroup; def warn_format_invalid_conversion : Warning< diff --git a/clang/test/Misc/warning-wall.c b/clang/test/Misc/warning-wall.c index c63d4beecff04..9975323f70286 100644 --- a/clang/test/Misc/warning-wall.c +++ b/clang/test/Misc/warning-wall.c @@ -9,6 +9,7 @@ CHECK-NEXT: -Wdelete-non-virtual-dtor CHECK-NEXT: -Wdelete-non-abstract-non-virtual-dtor CHECK-NEXT: -Wdelete-abstract-non-virtual-dtor CHECK-NEXT: -Wformat +CHECK-NEXT: -Wformat-insufficient-args CHECK-NEXT: -Wformat-extra-args CHECK-NEXT: -Wformat-zero-length CHECK-NEXT: -Wnonnull diff --git a/clang/test/Sema/warn-printf-insufficient-data-args.c b/clang/test/Sema/warn-printf-insufficient-data-args.c new file mode 100644 index 0000000000000..a8de7118e8b1f --- /dev/null +++ b/clang/test/Sema/warn-printf-insufficient-data-args.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -fsyntax-only -verify=WARNING-ON %s +// RUN: %clang_cc1 -fsyntax-only -Wno-format-insufficient-args -verify=WARNING-OFF %s + + +int printf(const char * format, ...); + +int main(void) { + int patatino = 42; + printf("%i %i", patatino); // WARNING-ON-warning {{more '%' conversions than data arguments}} + // WARNING-OFF-no-diagnostics +} From b3b219d6718716e8676c8876e5e87f34339c6cd3 Mon Sep 17 00:00:00 2001 From: Jan Korous Date: Mon, 28 Sep 2020 17:19:31 -0700 Subject: [PATCH 036/234] [clang] Update warning-wall.c test Follow-up to 1e86d637eb4f: [clang] Selectively ena/disa-ble format-insufficient-args warning --- clang/test/Misc/warning-wall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Misc/warning-wall.c b/clang/test/Misc/warning-wall.c index 9975323f70286..ac2b124e3312f 100644 --- a/clang/test/Misc/warning-wall.c +++ b/clang/test/Misc/warning-wall.c @@ -9,13 +9,13 @@ CHECK-NEXT: -Wdelete-non-virtual-dtor CHECK-NEXT: -Wdelete-non-abstract-non-virtual-dtor CHECK-NEXT: -Wdelete-abstract-non-virtual-dtor CHECK-NEXT: -Wformat -CHECK-NEXT: -Wformat-insufficient-args CHECK-NEXT: -Wformat-extra-args CHECK-NEXT: -Wformat-zero-length CHECK-NEXT: -Wnonnull CHECK-NEXT: -Wformat-security CHECK-NEXT: -Wformat-y2k CHECK-NEXT: -Wformat-invalid-specifier +CHECK-NEXT: -Wformat-insufficient-args CHECK-NEXT: -Wfor-loop-analysis CHECK-NEXT: -Wframe-address CHECK-NEXT: -Wimplicit From dda0a1867cc0c4ace4535f179aec85c3ff8cfa96 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 29 Sep 2020 14:58:46 +0200 Subject: [PATCH 037/234] [LLVM 11] Add SystemZ changes to release notes Differential Revision: https://reviews.llvm.org/D88479 --- llvm/docs/ReleaseNotes.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index d724ba09502a5..db64fa2810180 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -241,6 +241,21 @@ Bug fixes: * The correct libcall is now emitted for converting a float/double to a 32-bit signed or unsigned integer on RV64 targets lacking the F or D extensions. +Changes to the SystemZ Target +----------------------------- + +* Added support for the MemorySanitizer and the LeakSanitizer. +* Added support for the ``-fstack-clash-protection`` command line option. +* Enhanced the assembler parser to allow using `%r0` even in an address + register context, and to allow specifying registers using plain integer + numbers instead of register names everywhere. +* Fixed wrong code generation violating the platform ABI when passing + a C++ class (not struct) type having only a single member of + floating-point type. +* Fixed wrong code generation when using the `vec_store_len_r` or + `vec_load_len_r` intrinsics with an immediate length argument of + 16 or larger. +* Miscellaneous codegen enhancements, in particular to improve vector code. Changes to the X86 Target ------------------------- From c460ac28b4248ec50fe42dbfdf14582a21df97e6 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Tue, 29 Sep 2020 16:32:06 -0700 Subject: [PATCH 038/234] [CodeExtractor] Don't create bitcasts when inserting lifetime markers (NFCI) Lifetime marker intrinsics support any pointer type, so CodeExtractor does not need to bitcast to `i8*` in order to use these markers. (cherry picked from commit 26ee8aff2b85ee28a2b2d0b1860d878b512fbdef) --- llvm/lib/Transforms/Utils/CodeExtractor.cpp | 35 +++++-------------- .../PartialInlineInvokeProducesOutVal.ll | 5 ++- .../lifetime-markers-on-inputs-1.ll | 8 ++--- .../lifetime-markers-on-inputs-2.ll | 15 ++++---- .../HotColdSplit/split-phis-in-exit-blocks.ll | 3 +- 5 files changed, 21 insertions(+), 45 deletions(-) diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index 8cdbb9d356523..6e662b22d7f86 100644 --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -1023,32 +1023,21 @@ static void insertLifetimeMarkersSurroundingCall( Module *M, ArrayRef LifetimesStart, ArrayRef LifetimesEnd, CallInst *TheCall) { LLVMContext &Ctx = M->getContext(); - auto Int8PtrTy = Type::getInt8PtrTy(Ctx); auto NegativeOne = ConstantInt::getSigned(Type::getInt64Ty(Ctx), -1); Instruction *Term = TheCall->getParent()->getTerminator(); - // The memory argument to a lifetime marker must be a i8*. Cache any bitcasts - // needed to satisfy this requirement so they may be reused. - DenseMap Bitcasts; - // Emit lifetime markers for the pointers given in \p Objects. Insert the // markers before the call if \p InsertBefore, and after the call otherwise. - auto insertMarkers = [&](Function *MarkerFunc, ArrayRef Objects, + auto insertMarkers = [&](Intrinsic::ID IID, ArrayRef Objects, bool InsertBefore) { for (Value *Mem : Objects) { assert((!isa(Mem) || cast(Mem)->getFunction() == TheCall->getFunction()) && "Input memory not defined in original function"); - Value *&MemAsI8Ptr = Bitcasts[Mem]; - if (!MemAsI8Ptr) { - if (Mem->getType() == Int8PtrTy) - MemAsI8Ptr = Mem; - else - MemAsI8Ptr = - CastInst::CreatePointerCast(Mem, Int8PtrTy, "lt.cast", TheCall); - } - - auto Marker = CallInst::Create(MarkerFunc, {NegativeOne, MemAsI8Ptr}); + assert(Mem->getType()->isPointerTy() && "Expected pointer to memory"); + Function *MarkerFunc = + llvm::Intrinsic::getDeclaration(M, IID, Mem->getType()); + auto Marker = CallInst::Create(MarkerFunc, {NegativeOne, Mem}); if (InsertBefore) Marker->insertBefore(TheCall); else @@ -1056,17 +1045,9 @@ static void insertLifetimeMarkersSurroundingCall( } }; - if (!LifetimesStart.empty()) { - auto StartFn = llvm::Intrinsic::getDeclaration( - M, llvm::Intrinsic::lifetime_start, Int8PtrTy); - insertMarkers(StartFn, LifetimesStart, /*InsertBefore=*/true); - } - - if (!LifetimesEnd.empty()) { - auto EndFn = llvm::Intrinsic::getDeclaration( - M, llvm::Intrinsic::lifetime_end, Int8PtrTy); - insertMarkers(EndFn, LifetimesEnd, /*InsertBefore=*/false); - } + insertMarkers(Intrinsic::lifetime_start, LifetimesStart, + /*InsertBefore=*/true); + insertMarkers(Intrinsic::lifetime_end, LifetimesEnd, /*InsertBefore=*/false); } /// emitCallAndSwitchStatement - This method sets up the caller side by adding diff --git a/llvm/test/Transforms/CodeExtractor/PartialInlineInvokeProducesOutVal.ll b/llvm/test/Transforms/CodeExtractor/PartialInlineInvokeProducesOutVal.ll index 2e0fbf6073ea7..32013579f1844 100644 --- a/llvm/test/Transforms/CodeExtractor/PartialInlineInvokeProducesOutVal.ll +++ b/llvm/test/Transforms/CodeExtractor/PartialInlineInvokeProducesOutVal.ll @@ -26,11 +26,10 @@ bb5: ; preds = %bb4, %bb1, %bb ; CHECK-LABEL: bb: ; CHECK-NEXT: [[CALL26LOC:%.*]] = alloca i8* ; CHECK-LABEL: codeRepl.i: -; CHECK-NEXT: %lt.cast.i = bitcast i8** [[CALL26LOC]] to i8* -; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* %lt.cast.i) +; CHECK-NEXT: call void @llvm.lifetime.start.p0p0i8(i64 -1, i8** [[CALL26LOC]]) ; CHECK-NEXT: call void @bar.1.bb1(i8** [[CALL26LOC]]) ; CHECK-NEXT: %call26.reload.i = load i8*, i8** [[CALL26LOC]] -; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* %lt.cast.i) +; CHECK-NEXT: call void @llvm.lifetime.end.p0p0i8(i64 -1, i8** [[CALL26LOC]]) define i8* @dummy_caller(i32 %arg) { bb: %tmp = tail call i8* @bar(i32 %arg) diff --git a/llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-1.ll b/llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-1.ll index 6d9214482c8ce..d8afa44d514ff 100644 --- a/llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-1.ll +++ b/llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-1.ll @@ -29,10 +29,8 @@ normalPath: ret void ; CHECK-LABEL: codeRepl: -; CHECK: [[local1_cast:%.*]] = bitcast i256* %local1 to i8* -; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[local1_cast]]) -; CHECK-NEXT: [[local2_cast:%.*]] = bitcast i256* %local2 to i8* -; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[local2_cast]]) +; CHECK: call void @llvm.lifetime.start.p0i256(i64 -1, i256* %local1) +; CHECK-NEXT: call void @llvm.lifetime.start.p0i256(i64 -1, i256* %local2) ; CHECK-NEXT: call i1 @foo.cold.1(i8* %local1_cast, i8* %local2_cast) ; CHECK-NEXT: br i1 @@ -61,4 +59,4 @@ outlinedPathExit: } ; CHECK-LABEL: define {{.*}}@foo.cold.1( -; CHECK-NOT: @llvm.lifetime +; CHECK-NOT: call void @llvm.lifetime diff --git a/llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-2.ll b/llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-2.ll index e0df965632abf..3d5a3bb8636ac 100644 --- a/llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-2.ll +++ b/llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-2.ll @@ -37,13 +37,12 @@ declare void @use(i8*) define void @only_lifetime_start_is_cold() { ; CHECK-LABEL: @only_lifetime_start_is_cold( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256 +; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256, align 8 ; CHECK-NEXT: [[LOCAL1_CAST:%.*]] = bitcast i256* [[LOCAL1]] to i8* ; CHECK-NEXT: br i1 undef, label [[CODEREPL:%.*]], label [[NO_EXTRACT1:%.*]] ; CHECK: codeRepl: -; CHECK-NEXT: [[LT_CAST:%.*]] = bitcast i256* [[LOCAL1]] to i8* -; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[LT_CAST]]) -; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @only_lifetime_start_is_cold.cold.1(i8* [[LOCAL1_CAST]]) #3 +; CHECK-NEXT: call void @llvm.lifetime.start.p0i256(i64 -1, i256* [[LOCAL1]]) +; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @only_lifetime_start_is_cold.cold.1(i8* [[LOCAL1_CAST]]) [[ATTR3:#.*]] ; CHECK-NEXT: br i1 [[TARGETBLOCK]], label [[NO_EXTRACT1]], label [[EXIT:%.*]] ; CHECK: no-extract1: ; CHECK-NEXT: br label [[EXIT]] @@ -98,7 +97,7 @@ exit: define void @only_lifetime_end_is_cold() { ; CHECK-LABEL: @only_lifetime_end_is_cold( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256 +; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256, align 8 ; CHECK-NEXT: [[LOCAL1_CAST:%.*]] = bitcast i256* [[LOCAL1]] to i8* ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[LOCAL1_CAST]]) ; CHECK-NEXT: br i1 undef, label [[NO_EXTRACT1:%.*]], label [[CODEREPL:%.*]] @@ -106,7 +105,7 @@ define void @only_lifetime_end_is_cold() { ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* [[LOCAL1_CAST]]) ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: codeRepl: -; CHECK-NEXT: call void @only_lifetime_end_is_cold.cold.1(i8* [[LOCAL1_CAST]]) #3 +; CHECK-NEXT: call void @only_lifetime_end_is_cold.cold.1(i8* [[LOCAL1_CAST]]) [[ATTR3]] ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -138,7 +137,7 @@ exit: define void @do_not_lift_lifetime_end() { ; CHECK-LABEL: @do_not_lift_lifetime_end( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256 +; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256, align 8 ; CHECK-NEXT: [[LOCAL1_CAST:%.*]] = bitcast i256* [[LOCAL1]] to i8* ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[LOCAL1_CAST]]) ; CHECK-NEXT: br label [[HEADER:%.*]] @@ -146,7 +145,7 @@ define void @do_not_lift_lifetime_end() { ; CHECK-NEXT: call void @use(i8* [[LOCAL1_CAST]]) ; CHECK-NEXT: br i1 undef, label [[EXIT:%.*]], label [[CODEREPL:%.*]] ; CHECK: codeRepl: -; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @do_not_lift_lifetime_end.cold.1(i8* [[LOCAL1_CAST]]) #3 +; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @do_not_lift_lifetime_end.cold.1(i8* [[LOCAL1_CAST]]) [[ATTR3]] ; CHECK-NEXT: br i1 [[TARGETBLOCK]], label [[HEADER]], label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void diff --git a/llvm/test/Transforms/HotColdSplit/split-phis-in-exit-blocks.ll b/llvm/test/Transforms/HotColdSplit/split-phis-in-exit-blocks.ll index 2f5360ccb1e7e..0222c57fc6688 100644 --- a/llvm/test/Transforms/HotColdSplit/split-phis-in-exit-blocks.ll +++ b/llvm/test/Transforms/HotColdSplit/split-phis-in-exit-blocks.ll @@ -12,8 +12,7 @@ target triple = "x86_64-apple-macosx10.14.0" ; CHECK-NEXT: ] ; ; CHECK: codeRepl: -; CHECK-NEXT: bitcast -; CHECK-NEXT: lifetime.start +; CHECK: lifetime.start ; CHECK-NEXT: call void @pluto.cold.1(i1* %tmp8.ce.loc) ; CHECK-NEXT: %tmp8.ce.reload = load i1, i1* %tmp8.ce.loc ; CHECK-NEXT: lifetime.end From 88a3b10df3c1f1a6cc52eef0c2924d3daefaeafe Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 29 Sep 2020 23:33:16 -0400 Subject: [PATCH 039/234] [Swift] Update for GenericParamList.h --- lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index 6debdf242ad2b..b1b8eb31d4e22 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -23,6 +23,7 @@ #include "swift/AST/ASTMangler.h" #include "swift/AST/DebuggerClient.h" #include "swift/AST/Decl.h" +#include "swift/AST/GenericParamList.h" #include "swift/AST/DiagnosticEngine.h" #include "swift/AST/DiagnosticsSema.h" #include "swift/AST/ExistentialLayout.h" From fbdc88ef3ae9a21b9555a3bf91ea1ac04d13f592 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 29 Sep 2020 23:16:58 -0700 Subject: [PATCH 040/234] [lldb] Stop unconditionally emitting "could not resolve type" --- lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index 6debdf242ad2b..21f08fcbef743 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -8080,12 +8080,13 @@ void SwiftASTContext::DumpTypeDescription(opaque_compiler_type_t type, } } break; } + } - if (buf.size() > 0) { - s->Write(buf.data(), buf.size()); - } + if (buf.size() > 0) { + s->Write(buf.data(), buf.size()); + } else { + s->Printf(""); } - s->Printf(""); } TypeSP SwiftASTContext::GetCachedType(ConstString mangled) { From a3aee2678d07e249dca18493d2acd898eefd48dd Mon Sep 17 00:00:00 2001 From: Amara Emerson Date: Tue, 29 Sep 2020 14:39:54 -0700 Subject: [PATCH 041/234] [GlobalISel] Fix multiply with overflow intrinsics legalization generating invalid MIR. During lowering of G_UMULO and friends, the previous code moved the builder's insertion point to be after the legalizing instruction. When that happened, if there happened to be a "G_CONSTANT i32 0" immediately after, the CSEMIRBuilder would try to find that constant during the buildConstant(zero) call, and since it dominates itself would return the iterator unchanged, even though the def of the constant was *after* the current insertion point. This resulted in the compare being generated *before* the constant which it was using. There's no need to modify the insertion point before building the mul-hi or constant. Delaying moving the insert point ensures those are built/CSEd before the G_ICMP is built. Fixes PR47679 Differential Revision: https://reviews.llvm.org/D88514 (cherry picked from commit 1d54e75cf26a4c60b66659d5d9c62f4bb9452b03) --- .../CodeGen/GlobalISel/LegalizerHelper.cpp | 5 +- .../AArch64/GlobalISel/legalize-mul.mir | 68 ++++++++++++++++++- .../CodeGen/Mips/GlobalISel/legalizer/mul.mir | 2 +- .../CodeGen/Mips/GlobalISel/llvm-ir/mul.ll | 12 ++-- 4 files changed, 76 insertions(+), 11 deletions(-) diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index da519f99ad7e8..244e7a9583d61 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -2368,11 +2368,12 @@ LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) { MI.RemoveOperand(1); Observer.changedInstr(MI); - MIRBuilder.setInsertPt(MIRBuilder.getMBB(), ++MIRBuilder.getInsertPt()); - auto HiPart = MIRBuilder.buildInstr(Opcode, {Ty}, {LHS, RHS}); auto Zero = MIRBuilder.buildConstant(Ty, 0); + // Move insert point forward so we can use the Res register if needed. + MIRBuilder.setInsertPt(MIRBuilder.getMBB(), ++MIRBuilder.getInsertPt()); + // For *signed* multiply, overflow is detected by checking: // (hi != (lo >> bitwidth-1)) if (Opcode == TargetOpcode::G_SMULH) { diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-mul.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-mul.mir index 3260eb6ca6fd2..187ddebd9804b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-mul.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-mul.mir @@ -28,8 +28,8 @@ body: | ; CHECK-LABEL: name: test_smul_overflow ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 - ; CHECK: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[COPY]], [[COPY1]] ; CHECK: [[SMULH:%[0-9]+]]:_(s64) = G_SMULH [[COPY]], [[COPY1]] + ; CHECK: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[COPY]], [[COPY1]] ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 63 ; CHECK: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[MUL]], [[C]] ; CHECK: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[SMULH]](s64), [[ASHR]] @@ -51,9 +51,9 @@ body: | ; CHECK-LABEL: name: test_umul_overflow ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 - ; CHECK: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[COPY]], [[COPY1]] ; CHECK: [[UMULH:%[0-9]+]]:_(s64) = G_UMULH [[COPY]], [[COPY1]] ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 + ; CHECK: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[COPY]], [[COPY1]] ; CHECK: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[UMULH]](s64), [[C]] ; CHECK: $x0 = COPY [[MUL]](s64) ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY [[ICMP]](s32) @@ -66,3 +66,67 @@ body: | $w0 = COPY %4(s32) ... +--- +name: test_umulo_overflow_no_invalid_mir +alignment: 4 +tracksRegLiveness: true +liveins: + - { reg: '$x0' } + - { reg: '$x1' } + - { reg: '$x2' } +frameInfo: + maxAlignment: 16 +stack: + - { id: 0, size: 8, alignment: 8 } + - { id: 1, size: 8, alignment: 8 } + - { id: 2, size: 16, alignment: 16 } + - { id: 3, size: 16, alignment: 8 } +machineFunctionInfo: {} +body: | + bb.1: + liveins: $x0, $x1, $x2 + ; Check that the overflow result doesn't generate incorrect MIR by using a G_CONSTANT 0 + ; before it's been defined. + ; CHECK-LABEL: name: test_umulo_overflow_no_invalid_mir + ; CHECK: liveins: $x0, $x1, $x2 + ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 + ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 + ; CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY $x2 + ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0 + ; CHECK: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.1 + ; CHECK: [[FRAME_INDEX2:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.3 + ; CHECK: G_STORE [[COPY2]](s64), [[FRAME_INDEX]](p0) :: (store 8) + ; CHECK: G_STORE [[COPY1]](s64), [[FRAME_INDEX1]](p0) :: (store 8) + ; CHECK: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX]](p0) :: (dereferenceable load 8) + ; CHECK: [[LOAD1:%[0-9]+]]:_(s64) = G_LOAD [[FRAME_INDEX1]](p0) :: (dereferenceable load 8) + ; CHECK: [[UMULH:%[0-9]+]]:_(s64) = G_UMULH [[LOAD]], [[LOAD1]] + ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 + ; CHECK: [[MUL:%[0-9]+]]:_(s64) = G_MUL [[LOAD]], [[LOAD1]] + ; CHECK: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[UMULH]](s64), [[C]] + ; CHECK: G_STORE [[C]](s64), [[FRAME_INDEX2]](p0) :: (store 8, align 1) + ; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 + ; CHECK: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ICMP]](s32) + ; CHECK: [[AND:%[0-9]+]]:_(s64) = G_AND [[ANYEXT]], [[C1]] + ; CHECK: $x0 = COPY [[MUL]](s64) + ; CHECK: $x1 = COPY [[AND]](s64) + ; CHECK: RET_ReallyLR implicit $x0 + %0:_(p0) = COPY $x0 + %1:_(s64) = COPY $x1 + %2:_(s64) = COPY $x2 + %25:_(s32) = G_CONSTANT i32 0 + %3:_(p0) = G_FRAME_INDEX %stack.0 + %4:_(p0) = G_FRAME_INDEX %stack.1 + %6:_(p0) = G_FRAME_INDEX %stack.3 + G_STORE %2(s64), %3(p0) :: (store 8) + G_STORE %1(s64), %4(p0) :: (store 8) + %7:_(s64) = G_LOAD %3(p0) :: (dereferenceable load 8) + %8:_(s64) = G_LOAD %4(p0) :: (dereferenceable load 8) + %9:_(s64), %10:_(s1) = G_UMULO %7, %8 + %31:_(s64) = G_CONSTANT i64 0 + G_STORE %31(s64), %6(p0) :: (store 8, align 1) + %16:_(s64) = G_ZEXT %10(s1) + $x0 = COPY %9(s64) + $x1 = COPY %16(s64) + RET_ReallyLR implicit $x0 + +... diff --git a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/mul.mir b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/mul.mir index c92a55d0af322..b146aa5ff13d5 100644 --- a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/mul.mir +++ b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/mul.mir @@ -439,9 +439,9 @@ body: | ; MIPS32: [[COPY1:%[0-9]+]]:_(s32) = COPY $a1 ; MIPS32: [[COPY2:%[0-9]+]]:_(p0) = COPY $a2 ; MIPS32: [[COPY3:%[0-9]+]]:_(p0) = COPY $a3 - ; MIPS32: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[COPY]], [[COPY1]] ; MIPS32: [[UMULH:%[0-9]+]]:_(s32) = G_UMULH [[COPY]], [[COPY1]] ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 + ; MIPS32: [[MUL:%[0-9]+]]:_(s32) = G_MUL [[COPY]], [[COPY1]] ; MIPS32: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[UMULH]](s32), [[C]] ; MIPS32: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 ; MIPS32: [[COPY4:%[0-9]+]]:_(s32) = COPY [[ICMP]](s32) diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/mul.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/mul.ll index 659eadf181c02..f7250ccde898f 100644 --- a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/mul.ll +++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/mul.ll @@ -180,13 +180,13 @@ declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32) define void @umul_with_overflow(i32 %lhs, i32 %rhs, i32* %pmul, i1* %pcarry_flag) { ; MIPS32-LABEL: umul_with_overflow: ; MIPS32: # %bb.0: -; MIPS32-NEXT: mul $1, $4, $5 ; MIPS32-NEXT: multu $4, $5 -; MIPS32-NEXT: mfhi $2 -; MIPS32-NEXT: sltu $2, $zero, $2 -; MIPS32-NEXT: andi $2, $2, 1 -; MIPS32-NEXT: sb $2, 0($7) -; MIPS32-NEXT: sw $1, 0($6) +; MIPS32-NEXT: mfhi $1 +; MIPS32-NEXT: mul $2, $4, $5 +; MIPS32-NEXT: sltu $1, $zero, $1 +; MIPS32-NEXT: andi $1, $1, 1 +; MIPS32-NEXT: sb $1, 0($7) +; MIPS32-NEXT: sw $2, 0($6) ; MIPS32-NEXT: jr $ra ; MIPS32-NEXT: nop %res = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %lhs, i32 %rhs) From 60a25202a7dd1e00067fcfce512086ebf3788537 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 24 Sep 2020 13:44:29 -0400 Subject: [PATCH 042/234] [APFloat] prevent NaN morphing into Inf on conversion (PR43907) We shift the significand right on a truncation, but that needs to be made NaN-safe: always set at least 1 bit in the significand. https://llvm.org/PR43907 See D88238 for the likely follow-up (but needs some plumbing fixes before it can proceed). Differential Revision: https://reviews.llvm.org/D87835 (cherry picked from commit e34bd1e0b03d20a506ada156d87e1b3a96d82fa2) --- llvm/lib/Support/APFloat.cpp | 15 +++++++++++++++ llvm/test/Transforms/ConstProp/cast.ll | 23 +++++++++++++++++++++++ llvm/unittests/ADT/APFloatTest.cpp | 15 +++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp index 569cac790af99..362595d8f8b1c 100644 --- a/llvm/lib/Support/APFloat.cpp +++ b/llvm/lib/Support/APFloat.cpp @@ -2242,6 +2242,21 @@ IEEEFloat::opStatus IEEEFloat::convert(const fltSemantics &toSemantics, if (!X86SpecialNan && semantics == &semX87DoubleExtended) APInt::tcSetBit(significandParts(), semantics->precision - 1); + // If we are truncating NaN, it is possible that we shifted out all of the + // set bits in a signalling NaN payload. But NaN must remain NaN, so some + // bit in the significand must be set (otherwise it is Inf). + // This can only happen with sNaN. Set the 1st bit after the quiet bit, + // so that we still have an sNaN. + // FIXME: Set quiet and return opInvalidOp (on convert of any sNaN). + // But this requires fixing LLVM to parse 32-bit hex FP or ignoring + // conversions while parsing IR. + if (APInt::tcIsZero(significandParts(), newPartCount)) { + assert(shift < 0 && "Should not lose NaN payload on extend"); + assert(semantics->precision >= 3 && "Unexpectedly narrow significand"); + assert(*losesInfo && "Missing payload should have set lost info"); + APInt::tcSetBit(significandParts(), semantics->precision - 3); + } + // gcc forces the Quiet bit on, which means (float)(double)(float_sNan) // does not give you back the same bits. This is dubious, and we // don't currently do it. You're really supposed to get diff --git a/llvm/test/Transforms/ConstProp/cast.ll b/llvm/test/Transforms/ConstProp/cast.ll index 8377df17b3a8a..c07fa1295b42e 100644 --- a/llvm/test/Transforms/ConstProp/cast.ll +++ b/llvm/test/Transforms/ConstProp/cast.ll @@ -38,3 +38,26 @@ define float @overflow_sitofp() { ret float %i } +; https://llvm.org/PR43907 - make sure that NaN doesn't morph into Inf. +; SNaN remains SNaN. + +define float @nan_f64_trunc() { +; CHECK-LABEL: @nan_f64_trunc( +; CHECK-NEXT: ret float 0x7FF4000000000000 +; + %f = fptrunc double 0x7FF0000000000001 to float + ret float %f +} + +; Verify again with a vector and different destination type. +; SNaN remains SNaN (first two elements). +; QNaN remains QNaN (third element). +; Lower 42 bits of NaN source payload are lost. + +define <3 x half> @nan_v3f64_trunc() { +; CHECK-LABEL: @nan_v3f64_trunc( +; CHECK-NEXT: ret <3 x half> +; + %f = fptrunc <3 x double> to <3 x half> + ret <3 x half> %f +} diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp index b24b43d09a403..c798c95e05f6b 100644 --- a/llvm/unittests/ADT/APFloatTest.cpp +++ b/llvm/unittests/ADT/APFloatTest.cpp @@ -1840,6 +1840,21 @@ TEST(APFloatTest, convert) { &losesInfo); EXPECT_TRUE(test.bitwiseIsEqual(X87QNaN)); EXPECT_FALSE(losesInfo); + + // The payload is lost in truncation, but we must retain NaN, so we set the bit after the quiet bit. + APInt payload(52, 1); + test = APFloat::getSNaN(APFloat::IEEEdouble(), false, &payload); + APFloat::opStatus status = test.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo); + EXPECT_EQ(0x7fa00000, test.bitcastToAPInt()); + EXPECT_TRUE(losesInfo); + EXPECT_EQ(status, APFloat::opOK); + + // The payload is lost in truncation. QNaN remains QNaN. + test = APFloat::getQNaN(APFloat::IEEEdouble(), false, &payload); + status = test.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo); + EXPECT_EQ(0x7fc00000, test.bitcastToAPInt()); + EXPECT_TRUE(losesInfo); + EXPECT_EQ(status, APFloat::opOK); } TEST(APFloatTest, PPCDoubleDouble) { From c37f535995e052bb7c36cabc3581dd609af128ad Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Mon, 27 Jul 2020 12:30:09 -0700 Subject: [PATCH 043/234] [lldb] Remove CMAKE_VERSION checks now that the minimum version is 3.13.4 (cherry picked from commit 536baa11cfe12362ea646ad731a2274a07208cc0) --- .../modules/FindPythonInterpAndLibs.cmake | 38 ++++--------------- lldb/cmake/modules/LLDBConfig.cmake | 5 --- 2 files changed, 7 insertions(+), 36 deletions(-) diff --git a/lldb/cmake/modules/FindPythonInterpAndLibs.cmake b/lldb/cmake/modules/FindPythonInterpAndLibs.cmake index 243e0463f48b6..3a64ebbcf9721 100644 --- a/lldb/cmake/modules/FindPythonInterpAndLibs.cmake +++ b/lldb/cmake/modules/FindPythonInterpAndLibs.cmake @@ -61,46 +61,22 @@ if(PYTHON_LIBRARIES AND PYTHON_INCLUDE_DIRS AND PYTHON_EXECUTABLE AND SWIG_EXECU else() find_package(SWIG 2.0) if (SWIG_FOUND) - if(NOT CMAKE_VERSION VERSION_LESS 3.12) - if (LLDB_PYTHON_VERSION) - if (LLDB_PYTHON_VERSION VERSION_EQUAL "2") - FindPython2() - elseif(LLDB_PYTHON_VERSION VERSION_EQUAL "3") - FindPython3() - endif() - else() + if (LLDB_PYTHON_VERSION) + if (LLDB_PYTHON_VERSION VERSION_EQUAL "2") + FindPython2() + elseif(LLDB_PYTHON_VERSION VERSION_EQUAL "3") FindPython3() - if (NOT PYTHON3_FOUND AND NOT CMAKE_SYSTEM_NAME STREQUAL Windows) - FindPython2() - endif() endif() else() - find_package(PythonInterp) - find_package(PythonLibs) - if(PYTHONINTERP_FOUND AND PYTHONLIBS_FOUND AND SWIG_FOUND) - if (NOT CMAKE_CROSSCOMPILING) - string(REPLACE "." ";" pythonlibs_version_list ${PYTHONLIBS_VERSION_STRING}) - list(GET pythonlibs_version_list 0 pythonlibs_major) - list(GET pythonlibs_version_list 1 pythonlibs_minor) - - # Ignore the patch version. Some versions of macOS report a different - # patch version for the system provided interpreter and libraries. - if (CMAKE_CROSSCOMPILING OR (PYTHON_VERSION_MAJOR VERSION_EQUAL pythonlibs_major AND - PYTHON_VERSION_MINOR VERSION_EQUAL pythonlibs_minor)) - mark_as_advanced( - PYTHON_LIBRARIES - PYTHON_INCLUDE_DIRS - PYTHON_EXECUTABLE - SWIG_EXECUTABLE) - endif() - endif() + FindPython3() + if (NOT PYTHON3_FOUND AND NOT CMAKE_SYSTEM_NAME STREQUAL Windows) + FindPython2() endif() endif() else() message(STATUS "SWIG 2 or later is required for Python support in LLDB but could not be found") endif() - include(FindPackageHandleStandardArgs) find_package_handle_standard_args(PythonInterpAndLibs FOUND_VAR diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index 8465cfe3b7b72..7e5848c800f87 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -79,11 +79,6 @@ if(LLDB_BUILD_FRAMEWORK) if(NOT APPLE) message(FATAL_ERROR "LLDB.framework can only be generated when targeting Apple platforms") endif() - # CMake 3.6 did not correctly emit POST_BUILD commands for Apple Framework targets - # CMake < 3.8 did not have the BUILD_RPATH target property - if(CMAKE_VERSION VERSION_LESS 3.8) - message(FATAL_ERROR "LLDB_BUILD_FRAMEWORK is not supported on CMake < 3.8") - endif() set(LLDB_FRAMEWORK_VERSION A CACHE STRING "LLDB.framework version (default is A)") set(LLDB_FRAMEWORK_BUILD_DIR bin CACHE STRING "Output directory for LLDB.framework") From 1249f40424e9ea995ea331029d7f34efd553d96f Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 14 Aug 2020 08:44:29 -0700 Subject: [PATCH 044/234] [lldb] Remove Python 2 fallback and only support Python 3 This removes the fallback to Python 2 and makes Python 3 the only supported configuration. This is the first step to fully migrate to Python 3 over the coming releases as discussed on the mailing list. http://lists.llvm.org/pipermail/lldb-dev/2020-August/016388.html As a reminder, for the current release the test suite and the generated bindings should remain compatible with Python 2. Differential revision: https://reviews.llvm.org/D85942 (cherry picked from commit ce439cb1c962360267fb7a94d44ad57053787607) --- .../modules/FindPythonInterpAndLibs.cmake | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/lldb/cmake/modules/FindPythonInterpAndLibs.cmake b/lldb/cmake/modules/FindPythonInterpAndLibs.cmake index 3a64ebbcf9721..5ac472b036d7f 100644 --- a/lldb/cmake/modules/FindPythonInterpAndLibs.cmake +++ b/lldb/cmake/modules/FindPythonInterpAndLibs.cmake @@ -38,41 +38,12 @@ macro(FindPython3) endif() endmacro() -macro(FindPython2) - # Use PYTHON_HOME as a hint to find Python 2. - set(Python2_ROOT_DIR "${PYTHON_HOME}") - find_package(Python2 COMPONENTS Interpreter Development) - if(Python2_FOUND AND Python2_Interpreter_FOUND) - set(PYTHON_LIBRARIES ${Python2_LIBRARIES}) - set(PYTHON_INCLUDE_DIRS ${Python2_INCLUDE_DIRS}) - set(PYTHON_EXECUTABLE ${Python2_EXECUTABLE}) - - set(PYTHON2_FOUND TRUE) - mark_as_advanced( - PYTHON_LIBRARIES - PYTHON_INCLUDE_DIRS - PYTHON_EXECUTABLE - SWIG_EXECUTABLE) - endif() -endmacro() - if(PYTHON_LIBRARIES AND PYTHON_INCLUDE_DIRS AND PYTHON_EXECUTABLE AND SWIG_EXECUTABLE) set(PYTHONINTERPANDLIBS_FOUND TRUE) else() find_package(SWIG 2.0) if (SWIG_FOUND) - if (LLDB_PYTHON_VERSION) - if (LLDB_PYTHON_VERSION VERSION_EQUAL "2") - FindPython2() - elseif(LLDB_PYTHON_VERSION VERSION_EQUAL "3") - FindPython3() - endif() - else() FindPython3() - if (NOT PYTHON3_FOUND AND NOT CMAKE_SYSTEM_NAME STREQUAL Windows) - FindPython2() - endif() - endif() else() message(STATUS "SWIG 2 or later is required for Python support in LLDB but could not be found") endif() From 192b34147cdd76f90d5f619ef2885f126637a134 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Mon, 17 Aug 2020 08:47:52 -0700 Subject: [PATCH 045/234] [lldb] Get rid of helper CMake variables for Python This patch is a big sed to rename the following variables: s/PYTHON_LIBRARIES/Python3_LIBRARIES/g s/PYTHON_INCLUDE_DIRS/Python3_INCLUDE_DIRS/g s/PYTHON_EXECUTABLE/Python3_EXECUTABLE/g s/PYTHON_RPATH/Python3_RPATH/g I've also renamed the CMake module to better express its purpose and for consistency with FindLuaAndSwig. Differential revision: https://reviews.llvm.org/D85976 (cherry picked from commit 75966ee241a2f1b7712caa1bbe66560347b23359) --- lldb/CMakeLists.txt | 2 +- lldb/bindings/python/CMakeLists.txt | 2 +- ...pAndLibs.cmake => FindPythonAndSwig.cmake} | 29 +++++++++---------- lldb/cmake/modules/LLDBConfig.cmake | 6 ++-- lldb/source/API/CMakeLists.txt | 10 +++---- lldb/source/Plugins/ObjectFile/CMakeLists.txt | 2 +- .../ScriptInterpreter/None/CMakeLists.txt | 2 +- .../ScriptInterpreter/Python/CMakeLists.txt | 2 +- lldb/test/API/CMakeLists.txt | 2 +- lldb/test/API/lit.site.cfg.py.in | 2 +- lldb/test/CMakeLists.txt | 2 +- lldb/test/Shell/lit.site.cfg.py.in | 2 +- lldb/test/Unit/lit.site.cfg.py.in | 2 +- lldb/test/lit.site.cfg.py.in | 2 +- lldb/tools/intel-features/CMakeLists.txt | 2 +- lldb/tools/lldb-test/CMakeLists.txt | 6 ++-- lldb/unittests/API/CMakeLists.txt | 4 +-- lldb/unittests/Process/Linux/CMakeLists.txt | 2 +- .../ScriptInterpreter/Lua/CMakeLists.txt | 2 +- .../ScriptInterpreter/Python/CMakeLists.txt | 6 ++-- lldb/utils/lldb-dotest/lldb-dotest.in | 2 +- 21 files changed, 44 insertions(+), 47 deletions(-) rename lldb/cmake/modules/{FindPythonInterpAndLibs.cmake => FindPythonAndSwig.cmake} (67%) diff --git a/lldb/CMakeLists.txt b/lldb/CMakeLists.txt index a8d7cf7d083f5..8e3f4b7948461 100644 --- a/lldb/CMakeLists.txt +++ b/lldb/CMakeLists.txt @@ -45,7 +45,7 @@ endif() if (LLDB_ENABLE_PYTHON) execute_process( - COMMAND ${PYTHON_EXECUTABLE} + COMMAND ${Python3_EXECUTABLE} -c "import distutils.sysconfig; print(distutils.sysconfig.get_python_lib(True, False, ''))" OUTPUT_VARIABLE LLDB_PYTHON_DEFAULT_RELATIVE_PATH OUTPUT_STRIP_TRAILING_WHITESPACE) diff --git a/lldb/bindings/python/CMakeLists.txt b/lldb/bindings/python/CMakeLists.txt index 129fee99e4b92..baad7e8f0eba7 100644 --- a/lldb/bindings/python/CMakeLists.txt +++ b/lldb/bindings/python/CMakeLists.txt @@ -28,7 +28,7 @@ function(create_python_package swig_target working_dir pkg_dir) set(copy_cmd COMMAND ${CMAKE_COMMAND} -E copy ${ARG_FILES} ${pkg_dir}) endif() if(NOT ARG_NOINIT) - set(init_cmd COMMAND ${PYTHON_EXECUTABLE} + set(init_cmd COMMAND ${Python3_EXECUTABLE} "${LLDB_SOURCE_DIR}/bindings/python/createPythonInit.py" "${pkg_dir}" ${ARG_FILES}) endif() diff --git a/lldb/cmake/modules/FindPythonInterpAndLibs.cmake b/lldb/cmake/modules/FindPythonAndSwig.cmake similarity index 67% rename from lldb/cmake/modules/FindPythonInterpAndLibs.cmake rename to lldb/cmake/modules/FindPythonAndSwig.cmake index 5ac472b036d7f..c8edaaaca3e06 100644 --- a/lldb/cmake/modules/FindPythonInterpAndLibs.cmake +++ b/lldb/cmake/modules/FindPythonAndSwig.cmake @@ -1,5 +1,5 @@ #.rst: -# FindPythonInterpAndLibs +# FindPythonAndSwig # ----------- # # Find the python interpreter and libraries as a whole. @@ -9,9 +9,6 @@ macro(FindPython3) set(Python3_ROOT_DIR "${PYTHON_HOME}") find_package(Python3 COMPONENTS Interpreter Development) if(Python3_FOUND AND Python3_Interpreter_FOUND) - set(PYTHON_LIBRARIES ${Python3_LIBRARIES}) - set(PYTHON_INCLUDE_DIRS ${Python3_INCLUDE_DIRS}) - set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE}) # The install name for the Python 3 framework in Xcode is relative to # the framework's location and not the dylib itself. @@ -25,21 +22,21 @@ macro(FindPython3) # called Python.framework instead of Python3.framework. if (APPLE AND Python3_LIBRARIES MATCHES "Python3.framework") string(FIND "${Python3_LIBRARIES}" "Python3.framework" python_framework_pos) - string(SUBSTRING "${Python3_LIBRARIES}" "0" ${python_framework_pos} PYTHON_RPATH) + string(SUBSTRING "${Python3_LIBRARIES}" "0" ${python_framework_pos} Python3_RPATH) endif() set(PYTHON3_FOUND TRUE) mark_as_advanced( - PYTHON_LIBRARIES - PYTHON_INCLUDE_DIRS - PYTHON_EXECUTABLE - PYTHON_RPATH + Python3_LIBRARIES + Python3_INCLUDE_DIRS + Python3_EXECUTABLE + Python3_RPATH SWIG_EXECUTABLE) endif() endmacro() -if(PYTHON_LIBRARIES AND PYTHON_INCLUDE_DIRS AND PYTHON_EXECUTABLE AND SWIG_EXECUTABLE) - set(PYTHONINTERPANDLIBS_FOUND TRUE) +if(Python3_LIBRARIES AND Python3_INCLUDE_DIRS AND Python3_EXECUTABLE AND SWIG_EXECUTABLE) + set(PYTHONANDSWIG_FOUND TRUE) else() find_package(SWIG 2.0) if (SWIG_FOUND) @@ -49,12 +46,12 @@ else() endif() include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(PythonInterpAndLibs + find_package_handle_standard_args(PythonAndSwig FOUND_VAR - PYTHONINTERPANDLIBS_FOUND + PYTHONANDSWIG_FOUND REQUIRED_VARS - PYTHON_LIBRARIES - PYTHON_INCLUDE_DIRS - PYTHON_EXECUTABLE + Python3_LIBRARIES + Python3_INCLUDE_DIRS + Python3_EXECUTABLE SWIG_EXECUTABLE) endif() diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index 7e5848c800f87..0218ec0c0f1e5 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -56,7 +56,7 @@ add_optional_dependency(LLDB_ENABLE_LIBEDIT "Enable editline support in LLDB" Li add_optional_dependency(LLDB_ENABLE_CURSES "Enable curses support in LLDB" CursesAndPanel CURSESANDPANEL_FOUND) add_optional_dependency(LLDB_ENABLE_LZMA "Enable LZMA compression support in LLDB" LibLZMA LIBLZMA_FOUND) add_optional_dependency(LLDB_ENABLE_LUA "Enable Lua scripting support in LLDB" LuaAndSwig LUAANDSWIG_FOUND) -add_optional_dependency(LLDB_ENABLE_PYTHON "Enable Python scripting support in LLDB" PythonInterpAndLibs PYTHONINTERPANDLIBS_FOUND) +add_optional_dependency(LLDB_ENABLE_PYTHON "Enable Python scripting support in LLDB" PythonAndSwig PYTHONANDSWIG_FOUND) add_optional_dependency(LLDB_ENABLE_LIBXML2 "Enable Libxml 2 support in LLDB" LibXml2 LIBXML2_FOUND VERSION 2.8) option(LLDB_USE_SYSTEM_SIX "Use six.py shipped with system and do not install a copy of it" OFF) @@ -143,9 +143,9 @@ if (LLDB_ENABLE_PYTHON) "Embed PYTHONHOME in the binary. If set to OFF, PYTHONHOME environment variable will be used to to locate Python." ${default_embed_python_home}) - include_directories(${PYTHON_INCLUDE_DIRS}) + include_directories(${Python3_INCLUDE_DIRS}) if (LLDB_EMBED_PYTHON_HOME) - get_filename_component(PYTHON_HOME "${PYTHON_EXECUTABLE}" DIRECTORY) + get_filename_component(PYTHON_HOME "${Python3_EXECUTABLE}" DIRECTORY) set(LLDB_PYTHON_HOME "${PYTHON_HOME}" CACHE STRING "Path to use as PYTHONHOME in lldb. If a relative path is specified, it will be resolved at runtime relative to liblldb directory.") endif() diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt index 48631c96ae18a..329e04359b1a6 100644 --- a/lldb/source/API/CMakeLists.txt +++ b/lldb/source/API/CMakeLists.txt @@ -121,9 +121,9 @@ if(LLDB_ENABLE_PYTHON AND (BUILD_SHARED_LIBS OR LLVM_LINK_LLVM_DYLIB) AND UNIX A set_property(TARGET liblldb APPEND PROPERTY INSTALL_RPATH "\$ORIGIN/../../../../lib${LLVM_LIBDIR_SUFFIX}") endif() -if(PYTHON_RPATH) - set_property(TARGET liblldb APPEND PROPERTY INSTALL_RPATH "${PYTHON_RPATH}") - set_property(TARGET liblldb APPEND PROPERTY BUILD_RPATH "${PYTHON_RPATH}") +if(Python3_RPATH) + set_property(TARGET liblldb APPEND PROPERTY INSTALL_RPATH "${Python3_RPATH}") + set_property(TARGET liblldb APPEND PROPERTY BUILD_RPATH "${Python3_RPATH}") endif() if (MSVC) @@ -187,9 +187,9 @@ endif() if ( CMAKE_SYSTEM_NAME MATCHES "Windows" ) # Only MSVC has the ABI compatibility problem and avoids using FindPythonLibs, - # so only it needs to explicitly link against ${PYTHON_LIBRARIES} + # so only it needs to explicitly link against ${Python3_LIBRARIES} if (MSVC AND LLDB_ENABLE_PYTHON) - target_link_libraries(liblldb PRIVATE ${PYTHON_LIBRARIES}) + target_link_libraries(liblldb PRIVATE ${Python3_LIBRARIES}) endif() else() set_target_properties(liblldb diff --git a/lldb/source/Plugins/ObjectFile/CMakeLists.txt b/lldb/source/Plugins/ObjectFile/CMakeLists.txt index 76f6d7ad0d78a..77ca511bd7cf1 100644 --- a/lldb/source/Plugins/ObjectFile/CMakeLists.txt +++ b/lldb/source/Plugins/ObjectFile/CMakeLists.txt @@ -3,4 +3,4 @@ add_subdirectory(ELF) add_subdirectory(Mach-O) add_subdirectory(PECOFF) add_subdirectory(JIT) -add_subdirectory(wasm) \ No newline at end of file +add_subdirectory(wasm) diff --git a/lldb/source/Plugins/ScriptInterpreter/None/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/None/CMakeLists.txt index 7e7dd5896f7c8..ce4fb4f9c0a03 100644 --- a/lldb/source/Plugins/ScriptInterpreter/None/CMakeLists.txt +++ b/lldb/source/Plugins/ScriptInterpreter/None/CMakeLists.txt @@ -4,4 +4,4 @@ add_lldb_library(lldbPluginScriptInterpreterNone PLUGIN LINK_LIBS lldbCore lldbInterpreter - ) \ No newline at end of file + ) diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt index 761772f3a3718..2cbf8bcbb229d 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt +++ b/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt @@ -19,7 +19,7 @@ add_lldb_library(lldbPluginScriptInterpreterPython PLUGIN lldbHost lldbInterpreter lldbTarget - ${PYTHON_LIBRARIES} + ${Python3_LIBRARIES} ${LLDB_LIBEDIT_LIBS} LINK_COMPONENTS diff --git a/lldb/test/API/CMakeLists.txt b/lldb/test/API/CMakeLists.txt index a80992f287e9e..192c0adc66a23 100644 --- a/lldb/test/API/CMakeLists.txt +++ b/lldb/test/API/CMakeLists.txt @@ -1,6 +1,6 @@ function(add_python_test_target name test_script args comment) set(PYTHON_TEST_COMMAND - ${PYTHON_EXECUTABLE} + ${Python3_EXECUTABLE} ${test_script} ${args} ) diff --git a/lldb/test/API/lit.site.cfg.py.in b/lldb/test/API/lit.site.cfg.py.in index 866dc1675e7cf..3a108ae5c85a2 100644 --- a/lldb/test/API/lit.site.cfg.py.in +++ b/lldb/test/API/lit.site.cfg.py.in @@ -19,7 +19,7 @@ config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@" config.target_triple = "@TARGET_TRIPLE@" config.lldb_build_directory = "@LLDB_TEST_BUILD_DIRECTORY@" config.lldb_reproducer_directory = os.path.join("@LLDB_TEST_BUILD_DIRECTORY@", "reproducers") -config.python_executable = "@PYTHON_EXECUTABLE@" +config.python_executable = "@Python3_EXECUTABLE@" config.dotest_path = "@LLDB_SOURCE_DIR@/test/API/dotest.py" config.dotest_args_str = "@LLDB_DOTEST_ARGS@" config.lldb_enable_python = @LLDB_ENABLE_PYTHON@ diff --git a/lldb/test/CMakeLists.txt b/lldb/test/CMakeLists.txt index dc5af5e2defe7..c0249180253ab 100644 --- a/lldb/test/CMakeLists.txt +++ b/lldb/test/CMakeLists.txt @@ -218,7 +218,7 @@ if(LLDB_BUILT_STANDALONE) if (EXISTS ${LLVM_MAIN_SRC_DIR}/utils/llvm-lit) # LLVM's make_paths_relative uses Python3_EXECUTABLE which isn't set in a # standalone LLDB build. - set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE}) + set(Python3_EXECUTABLE ${Python3_EXECUTABLE}) add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/llvm-lit ${CMAKE_CURRENT_BINARY_DIR}/llvm-lit) endif() endif() diff --git a/lldb/test/Shell/lit.site.cfg.py.in b/lldb/test/Shell/lit.site.cfg.py.in index d998a0ca51c95..ff4de9d527dea 100644 --- a/lldb/test/Shell/lit.site.cfg.py.in +++ b/lldb/test/Shell/lit.site.cfg.py.in @@ -13,7 +13,7 @@ config.lldb_tools_dir = "@LLDB_TOOLS_DIR@" # should not need to be escaped. config.lldb_lit_tools_dir = r"@LLDB_LIT_TOOLS_DIR@" config.target_triple = "@TARGET_TRIPLE@" -config.python_executable = "@PYTHON_EXECUTABLE@" +config.python_executable = "@Python3_EXECUTABLE@" config.have_zlib = @LLVM_ENABLE_ZLIB@ config.lldb_enable_lzma = @LLDB_ENABLE_LZMA@ config.host_triple = "@LLVM_HOST_TRIPLE@" diff --git a/lldb/test/Unit/lit.site.cfg.py.in b/lldb/test/Unit/lit.site.cfg.py.in index 9d9bcd4ba628d..e2035d678cd98 100644 --- a/lldb/test/Unit/lit.site.cfg.py.in +++ b/lldb/test/Unit/lit.site.cfg.py.in @@ -10,7 +10,7 @@ config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" config.lldb_obj_root = "@LLDB_BINARY_DIR@" config.lldb_src_root = "@LLDB_SOURCE_DIR@" config.target_triple = "@TARGET_TRIPLE@" -config.python_executable = "@PYTHON_EXECUTABLE@" +config.python_executable = "@Python3_EXECUTABLE@" # Support substitution of the tools and libs dirs with user parameters. This is # used when we can't determine the tool dir at configuration time. diff --git a/lldb/test/lit.site.cfg.py.in b/lldb/test/lit.site.cfg.py.in index 49d789d42d9a1..24c0a4d5aa04c 100644 --- a/lldb/test/lit.site.cfg.py.in +++ b/lldb/test/lit.site.cfg.py.in @@ -10,7 +10,7 @@ config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" config.lldb_obj_root = "@LLDB_BINARY_DIR@" config.lldb_src_root = "@LLDB_SOURCE_DIR@" config.target_triple = "@TARGET_TRIPLE@" -config.python_executable = "@PYTHON_EXECUTABLE@" +config.python_executable = "@Python3_EXECUTABLE@" # Support substitution of the tools and libs dirs with user parameters. This is # used when we can't determine the tool dir at configuration time. diff --git a/lldb/tools/intel-features/CMakeLists.txt b/lldb/tools/intel-features/CMakeLists.txt index efba2f74904f7..e4979ad5256d9 100644 --- a/lldb/tools/intel-features/CMakeLists.txt +++ b/lldb/tools/intel-features/CMakeLists.txt @@ -56,7 +56,7 @@ add_lldb_library(lldbIntelFeatures SHARED LINK_LIBS ${FEATURE_LIBS} - ${PYTHON_LIBRARY} + ${Python3_LIBRARIES} ) # Add link dependencies for python wrapper diff --git a/lldb/tools/lldb-test/CMakeLists.txt b/lldb/tools/lldb-test/CMakeLists.txt index 2edbd8e56d6ed..562905760e2c8 100644 --- a/lldb/tools/lldb-test/CMakeLists.txt +++ b/lldb/tools/lldb-test/CMakeLists.txt @@ -24,9 +24,9 @@ add_lldb_tool(lldb-test Support ) -if(PYTHON_RPATH) - set_property(TARGET lldb-test APPEND PROPERTY INSTALL_RPATH "${PYTHON_RPATH}") - set_property(TARGET lldb-test APPEND PROPERTY BUILD_RPATH "${PYTHON_RPATH}") +if(Python3_RPATH) + set_property(TARGET lldb-test APPEND PROPERTY INSTALL_RPATH "${Python3_RPATH}") + set_property(TARGET lldb-test APPEND PROPERTY BUILD_RPATH "${Python3_RPATH}") endif() target_include_directories(lldb-test PRIVATE ${LLDB_SOURCE_DIR}/source) diff --git a/lldb/unittests/API/CMakeLists.txt b/lldb/unittests/API/CMakeLists.txt index 308249b63add1..2f066f26d8aaf 100644 --- a/lldb/unittests/API/CMakeLists.txt +++ b/lldb/unittests/API/CMakeLists.txt @@ -5,6 +5,6 @@ add_lldb_unittest(APITests liblldb ) -if(PYTHON_RPATH) - set_property(TARGET APITests APPEND PROPERTY BUILD_RPATH "${PYTHON_RPATH}") +if(Python3_RPATH) + set_property(TARGET APITests APPEND PROPERTY BUILD_RPATH "${Python3_RPATH}") endif() diff --git a/lldb/unittests/Process/Linux/CMakeLists.txt b/lldb/unittests/Process/Linux/CMakeLists.txt index 31e9a57a4e46e..bf71f2b55b85b 100644 --- a/lldb/unittests/Process/Linux/CMakeLists.txt +++ b/lldb/unittests/Process/Linux/CMakeLists.txt @@ -5,4 +5,4 @@ add_lldb_unittest(ProcessorTraceTests LINK_LIBS lldbPluginProcessLinux - ) \ No newline at end of file + ) diff --git a/lldb/unittests/ScriptInterpreter/Lua/CMakeLists.txt b/lldb/unittests/ScriptInterpreter/Lua/CMakeLists.txt index aa8a95c7c54c0..e030070a140f0 100644 --- a/lldb/unittests/ScriptInterpreter/Lua/CMakeLists.txt +++ b/lldb/unittests/ScriptInterpreter/Lua/CMakeLists.txt @@ -9,4 +9,4 @@ add_lldb_unittest(ScriptInterpreterLuaTests LLVMTestingSupport LINK_COMPONENTS Support - ) \ No newline at end of file + ) diff --git a/lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt b/lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt index 913bd629526d7..90a53bf175105 100644 --- a/lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt +++ b/lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt @@ -10,6 +10,6 @@ add_lldb_unittest(ScriptInterpreterPythonTests Support ) -if(PYTHON_RPATH) - set_property(TARGET ScriptInterpreterPythonTests APPEND PROPERTY BUILD_RPATH "${PYTHON_RPATH}") -endif() \ No newline at end of file +if(Python3_RPATH) + set_property(TARGET ScriptInterpreterPythonTests APPEND PROPERTY BUILD_RPATH "${Python3_RPATH}") +endif() diff --git a/lldb/utils/lldb-dotest/lldb-dotest.in b/lldb/utils/lldb-dotest/lldb-dotest.in index ee0ea6dff748c..f573d5bf28d42 100755 --- a/lldb/utils/lldb-dotest/lldb-dotest.in +++ b/lldb/utils/lldb-dotest/lldb-dotest.in @@ -1,4 +1,4 @@ -#!@PYTHON_EXECUTABLE@ +#!@Python3_EXECUTABLE@ import subprocess import sys From f1acd7829582fb9b6d59e4e6e06c0450a6e98e07 Mon Sep 17 00:00:00 2001 From: Xi Ge Date: Wed, 30 Sep 2020 10:37:24 -0700 Subject: [PATCH 046/234] Update lldb for ModuleInterfaceChecker --- .../Plugins/TypeSystem/Swift/SwiftASTContext.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index b1b8eb31d4e22..f8e7ded814baa 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -3363,6 +3363,12 @@ swift::ASTContext *SwiftASTContext::GetASTContext() { m_ast_context_ap->addModuleLoader(std::move(memory_buffer_loader_ap)); } + // Add a module interface checker. + m_ast_context_ap->addModuleInterfaceChecker( + std::make_unique(*m_ast_context_ap, + moduleCachePath, prebuiltModuleCachePath, + swift::ModuleInterfaceLoaderOptions())); + // 2. Create and install the module interface loader. // // The ordering of 2-4 is the same as the Swift compiler's 1-3, @@ -3377,8 +3383,9 @@ swift::ASTContext *SwiftASTContext::GetASTContext() { if (loading_mode != swift::ModuleLoadingMode::OnlySerialized) { std::unique_ptr module_interface_loader_ap( swift::ModuleInterfaceLoader::create( - *m_ast_context_ap, moduleCachePath, prebuiltModuleCachePath, - m_dependency_tracker.get(), loading_mode)); + *m_ast_context_ap, *static_cast( + m_ast_context_ap->getModuleInterfaceChecker()), m_dependency_tracker.get(), + loading_mode)); if (module_interface_loader_ap) m_ast_context_ap->addModuleLoader(std::move(module_interface_loader_ap)); } From 80998d8c3dd2a5aa52b0885559e6806e7601a772 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 30 Sep 2020 12:10:04 -0700 Subject: [PATCH 047/234] Update for Swift changes. --- lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index 51c3a5608c2b1..cac01ac6ae397 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -26,6 +26,7 @@ #include "swift/AST/DiagnosticEngine.h" #include "swift/AST/DiagnosticsSema.h" #include "swift/AST/ExistentialLayout.h" +#include "swift/AST/GenericParamList.h" #include "swift/AST/GenericSignature.h" #include "swift/AST/IRGenOptions.h" #include "swift/AST/ImportCache.h" From 9481d2b4f0aea495085cafdfa7a70e5984f24b7a Mon Sep 17 00:00:00 2001 From: Stella Stamenova Date: Thu, 10 Sep 2020 10:09:35 -0700 Subject: [PATCH 048/234] [lldb, tests] Correctly configure the yaml2obj paths They are currently not being set correctly for the case of multi-config generators like XCode and VS. There's also a typo in one of the cmake files. Reviewed By: JDevlieghere Differential Revision: https://reviews.llvm.org/D87466 (cherry picked from commit c464f1d8f9a04d7b4b6cc81eac0891c46aba5950) --- lldb/test/API/lit.site.cfg.py.in | 1 + lldb/utils/lldb-dotest/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/test/API/lit.site.cfg.py.in b/lldb/test/API/lit.site.cfg.py.in index 3a108ae5c85a2..6f3c0e03be5c3 100644 --- a/lldb/test/API/lit.site.cfg.py.in +++ b/lldb/test/API/lit.site.cfg.py.in @@ -58,6 +58,7 @@ try: config.test_compiler = config.test_compiler % lit_config.params config.dsymutil = config.dsymutil % lit_config.params config.filecheck = config.filecheck % lit_config.params + config.yaml2obj = config.yaml2obj % lit_config.params config.dotest_args_str = config.dotest_args_str % lit_config.params except KeyError as e: key, = e.args diff --git a/lldb/utils/lldb-dotest/CMakeLists.txt b/lldb/utils/lldb-dotest/CMakeLists.txt index 0ef60c1427610..e5a73c2b1dec3 100644 --- a/lldb/utils/lldb-dotest/CMakeLists.txt +++ b/lldb/utils/lldb-dotest/CMakeLists.txt @@ -49,7 +49,7 @@ if(LLDB_BUILT_STANDALONE) string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_FILECHECK_CONFIGURED "${LLDB_TEST_FILECHECK}") - string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_YAML2OBJ_CONFIGURED "${LLDB_TEST_YAML2OBJ_CONFIGURED}") + string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_YAML2OBJ_CONFIGURED "${LLDB_TEST_YAML2OBJ}") string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_LIBS_DIR_CONFIGURED "${LLDB_LIBS_DIR}") endif() From b1b663a95486789994e2bdfe6f47d88181981730 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 28 Aug 2020 15:42:43 -0700 Subject: [PATCH 049/234] [lldb] Dervice dotest.py path from config.lldb_src_root (NFC) (cherry picked from commit 55e7d91072e865d36953e91a7b2c8bfc219464d6) --- lldb/test/API/lit.cfg.py | 2 +- lldb/test/API/lit.site.cfg.py.in | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py index e083e2fd9bebb..238df53b69a50 100644 --- a/lldb/test/API/lit.cfg.py +++ b/lldb/test/API/lit.cfg.py @@ -147,7 +147,7 @@ def find_python_interpreter(): lit_config.warning("Could not set a default per-test timeout. " + errormsg) # Build dotest command. -dotest_cmd = [config.dotest_path] +dotest_cmd = [os.path.join(config.lldb_src_root, 'test', 'API', 'dotest.py')] dotest_cmd += ['--arch', config.test_arch] dotest_cmd.extend(config.dotest_args_str.split(';')) diff --git a/lldb/test/API/lit.site.cfg.py.in b/lldb/test/API/lit.site.cfg.py.in index 6f3c0e03be5c3..4906616ac1862 100644 --- a/lldb/test/API/lit.site.cfg.py.in +++ b/lldb/test/API/lit.site.cfg.py.in @@ -20,7 +20,6 @@ config.target_triple = "@TARGET_TRIPLE@" config.lldb_build_directory = "@LLDB_TEST_BUILD_DIRECTORY@" config.lldb_reproducer_directory = os.path.join("@LLDB_TEST_BUILD_DIRECTORY@", "reproducers") config.python_executable = "@Python3_EXECUTABLE@" -config.dotest_path = "@LLDB_SOURCE_DIR@/test/API/dotest.py" config.dotest_args_str = "@LLDB_DOTEST_ARGS@" config.lldb_enable_python = @LLDB_ENABLE_PYTHON@ config.dotest_lit_args_str = None From 0d0a774b748cd6f2665bbee88af4813af19ec02b Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 28 Aug 2020 15:43:35 -0700 Subject: [PATCH 050/234] [lldb] Get rid of LLDB_LIB_DIR and LLDB_IMPLIB_DIR in dotest This patch removes the rather confusing LLDB_LIB_DIR and LLDB_IMPLIB_DIR environment variables. They are confusing because LLDB_LIB_DIR would point to the bin subdirectory in the build root while LLDB_IMPLIB_DIR would point to the lib subdirectory. The reason far this was LLDB.framework, which gets build under bin. This patch replaces their uses with configuration.lldb_framework_path and configuration.lldb_libs_dir respectively. Differential revision: https://reviews.llvm.org/D86817 (cherry picked from commit 141c8475b693e245388cf7a4ac9ec17303988700) --- .../Python/lldbsuite/test/decorators.py | 5 +- lldb/packages/Python/lldbsuite/test/dotest.py | 9 ---- .../Python/lldbsuite/test/lldbtest.py | 50 +++++++------------ .../intel-pt/test/TestIntelPTSimpleBinary.py | 2 +- .../intel-mpx/test/TestMPXTable.py | 8 +-- 5 files changed, 24 insertions(+), 50 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/decorators.py b/lldb/packages/Python/lldbsuite/test/decorators.py index 1412137b10be1..c54db4b70c71d 100644 --- a/lldb/packages/Python/lldbsuite/test/decorators.py +++ b/lldb/packages/Python/lldbsuite/test/decorators.py @@ -526,10 +526,9 @@ def are_sb_headers_missing(): if lldb.remote_platform: return "skip because SBHeaders tests make no sense remotely" - if lldbplatformutil.getHostPlatform() == 'darwin': + if lldbplatformutil.getHostPlatform() == 'darwin' and configuration.lldb_framework_path: header = os.path.join( - os.environ["LLDB_LIB_DIR"], - 'LLDB.framework', + configuration.lldb_framework_path, 'Versions', 'Current', 'Headers', diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py index c9187e623ee4c..ffa24ce6bc312 100644 --- a/lldb/packages/Python/lldbsuite/test/dotest.py +++ b/lldb/packages/Python/lldbsuite/test/dotest.py @@ -546,13 +546,6 @@ def setupSysPath(): print("The 'lldb' executable cannot be located. Some of the tests may not be run as a result.") sys.exit(-1) - # confusingly, this is the "bin" directory - lldbLibDir = os.path.dirname(lldbtest_config.lldbExec) - os.environ["LLDB_LIB_DIR"] = lldbLibDir - lldbImpLibDir = configuration.lldb_libs_dir - os.environ["LLDB_IMPLIB_DIR"] = lldbImpLibDir - print("LLDB library dir:", os.environ["LLDB_LIB_DIR"]) - print("LLDB import library dir:", os.environ["LLDB_IMPLIB_DIR"]) os.system('%s -v' % lldbtest_config.lldbExec) lldbDir = os.path.dirname(lldbtest_config.lldbExec) @@ -567,8 +560,6 @@ def setupSysPath(): configuration.skip_categories.append("lldb-vscode") lldbPythonDir = None # The directory that contains 'lldb/__init__.py' - if not configuration.lldb_framework_path and os.path.exists(os.path.join(lldbLibDir, "LLDB.framework")): - configuration.lldb_framework_path = os.path.join(lldbLibDir, "LLDB.framework") if configuration.lldb_framework_path: lldbtest_config.lldb_framework_path = configuration.lldb_framework_path candidatePath = os.path.join( diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py index 527750489f02d..fb141616ef6e5 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -846,28 +846,18 @@ def setUp(self): self.setPlatformWorkingDir() self.enableLogChannelsForCurrentTest() - lib_dir = os.environ["LLDB_LIB_DIR"] - self.dsym = None + self.lib_lldb = None self.framework_dir = None - self.darwinWithFramework = self.platformIsDarwin() - if sys.platform.startswith("darwin"): - # Handle the framework environment variable if it is set - if hasattr(lldbtest_config, 'lldb_framework_path'): - framework_path = lldbtest_config.lldb_framework_path - # Framework dir should be the directory containing the framework - self.framework_dir = framework_path[:framework_path.rfind('LLDB.framework')] - # If a framework dir was not specified assume the Xcode build - # directory layout where the framework is in LLDB_LIB_DIR. - else: - self.framework_dir = lib_dir - self.dsym = os.path.join(self.framework_dir, 'LLDB.framework', 'LLDB') - # If the framework binary doesn't exist, assume we didn't actually - # build a framework, and fallback to standard *nix behavior by - # setting framework_dir and dsym to None. - if not os.path.exists(self.dsym): - self.framework_dir = None - self.dsym = None - self.darwinWithFramework = False + self.darwinWithFramework = False + + if sys.platform.startswith("darwin") and configuration.lldb_framework_path: + framework = configuration.lldb_framework_path + lib = os.path.join(framework, 'LLDB') + if os.path.exists(lib): + self.framework_dir = os.path.dirname(framework) + self.lib_lldb = lib + self.darwinWithFramework = self.platformIsDarwin() + self.makeBuildDir() def setAsync(self, value): @@ -1432,7 +1422,7 @@ def buildDriver(self, sources, exe_name): 'EXE': exe_name, 'CFLAGS_EXTRAS': "%s %s" % (stdflag, stdlibflag), 'FRAMEWORK_INCLUDES': "-F%s" % self.framework_dir, - 'LD_EXTRAS': "%s -Wl,-rpath,%s" % (self.dsym, self.framework_dir), + 'LD_EXTRAS': "%s -Wl,-rpath,%s" % (self.lib_lldb, self.framework_dir), } elif sys.platform.startswith('win'): d = { @@ -1443,7 +1433,7 @@ def buildDriver(self, sources, exe_name): os.path.join( os.environ["LLDB_SRC"], "include")), - 'LD_EXTRAS': "-L%s -lliblldb" % os.environ["LLDB_IMPLIB_DIR"]} + 'LD_EXTRAS': "-L%s -lliblldb" % lib_dir} else: d = { 'CXX_SOURCES': sources, @@ -1472,7 +1462,7 @@ def buildLibrary(self, sources, lib_name): 'DYLIB_NAME': lib_name, 'CFLAGS_EXTRAS': "%s -stdlib=libc++" % stdflag, 'FRAMEWORK_INCLUDES': "-F%s" % self.framework_dir, - 'LD_EXTRAS': "%s -Wl,-rpath,%s -dynamiclib" % (self.dsym, self.framework_dir), + 'LD_EXTRAS': "%s -Wl,-rpath,%s -dynamiclib" % (self.lib_lldb, self.framework_dir), } elif self.getPlatform() == 'windows': d = { @@ -1482,7 +1472,7 @@ def buildLibrary(self, sources, lib_name): os.path.join( os.environ["LLDB_SRC"], "include")), - 'LD_EXTRAS': "-shared -l%s\liblldb.lib" % self.os.environ["LLDB_IMPLIB_DIR"]} + 'LD_EXTRAS': "-shared -l%s\liblldb.lib" % lib_dir} else: d = { 'DYLIB_CXX_SOURCES': sources, @@ -1692,13 +1682,11 @@ def getLLDBLibraryEnvVal(self): """ existing_library_path = os.environ[ self.dylibPath] if self.dylibPath in os.environ else None - lib_dir = os.environ["LLDB_LIB_DIR"] if existing_library_path: - return "%s:%s" % (existing_library_path, lib_dir) - elif sys.platform.startswith("darwin"): - return os.path.join(lib_dir, 'LLDB.framework') - else: - return lib_dir + return "%s:%s" % (existing_library_path, configuration.lldb_libs_dir) + if sys.platform.startswith("darwin") and configuration.lldb_framework_path: + return configuration.lldb_framework_path + return configuration.lldb_libs_dir def getLibcPlusPlusLibs(self): if self.getPlatform() in ('freebsd', 'linux', 'netbsd', 'openbsd'): diff --git a/lldb/test/API/tools/intel-features/intel-pt/test/TestIntelPTSimpleBinary.py b/lldb/test/API/tools/intel-features/intel-pt/test/TestIntelPTSimpleBinary.py index e26b9f6f487e3..8c6c9cf4fbb75 100644 --- a/lldb/test/API/tools/intel-features/intel-pt/test/TestIntelPTSimpleBinary.py +++ b/lldb/test/API/tools/intel-features/intel-pt/test/TestIntelPTSimpleBinary.py @@ -21,7 +21,7 @@ def setUp(self): if 'intel-pt' not in configuration.enabled_plugins: self.skipTest("The intel-pt test plugin is not enabled") - plugin_path = os.path.join(os.environ["LLDB_IMPLIB_DIR"], "liblldbIntelFeatures.so") + plugin_path = os.path.join(configuration.lldb_libs_dir, "liblldbIntelFeatures.so") self.runCmd("plugin load " + plugin_path) @skipIf(oslist=no_match(['linux'])) diff --git a/lldb/tools/intel-features/intel-mpx/test/TestMPXTable.py b/lldb/tools/intel-features/intel-mpx/test/TestMPXTable.py index f571252e26f79..5431abcdbca57 100644 --- a/lldb/tools/intel-features/intel-mpx/test/TestMPXTable.py +++ b/lldb/tools/intel-features/intel-mpx/test/TestMPXTable.py @@ -30,9 +30,7 @@ def test_show_command(self): """Test 'mpx-table show' command""" self.build() - lldb_exec_dir = os.environ["LLDB_IMPLIB_DIR"] - lldb_lib_dir = os.path.join(lldb_exec_dir, os.pardir, "lib") - plugin_file = os.path.join(lldb_lib_dir, "liblldbIntelFeatures.so") + plugin_file = os.path.join(configuration.lldb_libs_dir, "liblldbIntelFeatures.so") if not os.path.isfile(plugin_file): self.skipTest("features plugin missing.") plugin_command = " " @@ -122,9 +120,7 @@ def test_set_command(self): """Test 'mpx-table set' command""" self.build() - lldb_exec_dir = os.environ["LLDB_IMPLIB_DIR"] - lldb_lib_dir = os.path.join(lldb_exec_dir, os.pardir, "lib") - plugin_file = os.path.join(lldb_lib_dir, "liblldbIntelFeatures.so") + plugin_file = os.path.join(configuration.lldb_libs_dir, "liblldbIntelFeatures.so") if not os.path.isfile(plugin_file): self.skipTest("features plugin missing.") plugin_command = " " From 0ada67d7478aac30e746ce41b894e2501fd22c38 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 28 Aug 2020 18:05:01 -0700 Subject: [PATCH 051/234] [lldb] Make the lit configuration values optional for the API tests LIT uses a model where the test suite is configurable trough a lit.site.cfg file. Most of the time we use the lit.site.cfg with values that match the current build configuration, generated by CMake. Nothing prevents you from running the test suite with a different configuration, either by overriding some of these values from the command line, or by passing a different lit.site.cfg. The latter is currently tedious. Many configuration values are optional but they still need to be set because lit.cfg.py is accessing them directly. This patch changes the code to use getattr to return the attribute if it exists. This makes it possible to specify a minimal lit.site.cfg with only the mandatory/desired configuration values. Differential revision: https://reviews.llvm.org/D86821 (cherry picked from commit 3f2fb0132f7b09e1309e8f7e0b5ba8ea471b17e7) --- lldb/test/API/lit.cfg.py | 104 +++++++++++++++++++++----------------- lldb/test/API/lldbtest.py | 2 +- 2 files changed, 60 insertions(+), 46 deletions(-) diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py index 238df53b69a50..5da12eea4504f 100644 --- a/lldb/test/API/lit.cfg.py +++ b/lldb/test/API/lit.cfg.py @@ -23,14 +23,14 @@ def mkdir_p(path): - import errno - try: - os.makedirs(path) - except OSError as e: - if e.errno != errno.EEXIST: - raise - if not os.path.isdir(path): - raise OSError(errno.ENOTDIR, "%s is not a directory"%path) + import errno + try: + os.makedirs(path) + except OSError as e: + if e.errno != errno.EEXIST: + raise + if not os.path.isdir(path): + raise OSError(errno.ENOTDIR, "%s is not a directory"%path) def find_sanitizer_runtime(name): @@ -85,22 +85,39 @@ def find_python_interpreter(): return copied_python -if 'Address' in config.llvm_use_sanitizer: - config.environment['ASAN_OPTIONS'] = 'detect_stack_use_after_return=1' - if 'Darwin' in config.host_os and 'x86' in config.host_triple: - config.environment['DYLD_INSERT_LIBRARIES'] = find_sanitizer_runtime( - 'libclang_rt.asan_osx_dynamic.dylib') +def is_configured(attr): + """Return the configuration attribute if it exists and None otherwise. + + This allows us to check if the attribute exists before trying to access it.""" + return getattr(config, attr, None) + + +def delete_module_cache(path): + """Clean the module caches in the test build directory. + + This is necessary in an incremental build whenever clang changes underneath, + so doing it once per lit.py invocation is close enough. """ + if os.path.isdir(path): + print("Deleting module cache at %s." % path) + shutil.rmtree(path) -if 'Thread' in config.llvm_use_sanitizer: - if 'Darwin' in config.host_os and 'x86' in config.host_triple: - config.environment['DYLD_INSERT_LIBRARIES'] = find_sanitizer_runtime( - 'libclang_rt.tsan_osx_dynamic.dylib') +if is_configured('llvm_use_sanitizer'): + if 'Address' in config.llvm_use_sanitizer: + config.environment['ASAN_OPTIONS'] = 'detect_stack_use_after_return=1' + if 'Darwin' in config.host_os and 'x86' in config.host_triple: + config.environment['DYLD_INSERT_LIBRARIES'] = find_sanitizer_runtime( + 'libclang_rt.asan_osx_dynamic.dylib') + + if 'Thread' in config.llvm_use_sanitizer: + if 'Darwin' in config.host_os and 'x86' in config.host_triple: + config.environment['DYLD_INSERT_LIBRARIES'] = find_sanitizer_runtime( + 'libclang_rt.tsan_osx_dynamic.dylib') if 'DYLD_INSERT_LIBRARIES' in config.environment and platform.system() == 'Darwin': config.python_executable = find_python_interpreter() # Shared library build of LLVM may require LD_LIBRARY_PATH or equivalent. -if config.shared_libs: +if is_configured('shared_libs'): for shlibpath_var in find_shlibpath_var(): # In stand-alone build llvm_shlib_dir specifies LLDB's lib directory while # llvm_libs_dir specifies LLVM's lib directory. @@ -129,14 +146,6 @@ def find_python_interpreter(): elif lldb_repro_mode == 'replay': config.available_features.add('lldb-repro-replay') -# Clean the module caches in the test build directory. This is necessary in an -# incremental build whenever clang changes underneath, so doing it once per -# lit.py invocation is close enough. -for cachedir in [config.clang_module_cache, config.lldb_module_cache]: - if os.path.isdir(cachedir): - print("Deleting module cache at %s." % cachedir) - shutil.rmtree(cachedir) - # Set a default per-test timeout of 10 minutes. Setting a timeout per test # requires that killProcessAndChildren() is supported on the platform and # lit complains if the value is set but it is not supported. @@ -148,11 +157,12 @@ def find_python_interpreter(): # Build dotest command. dotest_cmd = [os.path.join(config.lldb_src_root, 'test', 'API', 'dotest.py')] -dotest_cmd += ['--arch', config.test_arch] -dotest_cmd.extend(config.dotest_args_str.split(';')) + +if is_configured('dotest_args_str'): + dotest_cmd.extend(config.dotest_args_str.split(';')) # Library path may be needed to locate just-built clang. -if config.llvm_libs_dir: +if is_configured('llvm_libs_dir'): dotest_cmd += ['--env', 'LLVM_LIBS_DIR=' + config.llvm_libs_dir] # Forward ASan-specific environment variables to tests, as a test may load an @@ -161,49 +171,53 @@ def find_python_interpreter(): if env_var in config.environment: dotest_cmd += ['--inferior-env', env_var + '=' + config.environment[env_var]] -if config.lldb_build_directory: +if is_configured('test_arch'): + dotest_cmd += ['--arch', config.test_arch] + +if is_configured('lldb_build_directory'): dotest_cmd += ['--build-dir', config.lldb_build_directory] -if config.lldb_module_cache: +if is_configured('lldb_module_cache'): + delete_module_cache(config.lldb_module_cache) dotest_cmd += ['--lldb-module-cache-dir', config.lldb_module_cache] -if config.clang_module_cache: +if is_configured('clang_module_cache'): + delete_module_cache(config.clang_module_cache) dotest_cmd += ['--clang-module-cache-dir', config.clang_module_cache] -if config.lldb_executable: +if is_configured('lldb_executable'): dotest_cmd += ['--executable', config.lldb_executable] -if config.test_compiler: +if is_configured('test_compiler'): dotest_cmd += ['--compiler', config.test_compiler] -if config.dsymutil: +if is_configured('dsymutil'): dotest_cmd += ['--dsymutil', config.dsymutil] -if config.filecheck: +if is_configured('filecheck'): dotest_cmd += ['--filecheck', config.filecheck] -if config.yaml2obj: +if is_configured('yaml2obj'): dotest_cmd += ['--yaml2obj', config.yaml2obj] -if config.lldb_libs_dir: +if is_configured('lldb_libs_dir'): dotest_cmd += ['--lldb-libs-dir', config.lldb_libs_dir] if 'lldb-repro-capture' in config.available_features or \ 'lldb-repro-replay' in config.available_features: dotest_cmd += ['--skip-category=lldb-vscode', '--skip-category=std-module'] -if config.enabled_plugins: +if is_configured('enabled_plugins'): for plugin in config.enabled_plugins: dotest_cmd += ['--enable-plugin', plugin] -# We don't want to force users passing arguments to lit to use `;` as a -# separator. We use Python's simple lexical analyzer to turn the args into a -# list. Pass there arguments last so they can override anything that was -# already configured. -if config.dotest_lit_args_str: +if is_configured('dotest_lit_args_str'): + # We don't want to force users passing arguments to lit to use `;` as a + # separator. We use Python's simple lexical analyzer to turn the args into a + # list. Pass there arguments last so they can override anything that was + # already configured. dotest_cmd.extend(shlex.split(config.dotest_lit_args_str)) - # Load LLDB test format. sys.path.append(os.path.join(config.lldb_src_root, "test", "API")) import lldbtest diff --git a/lldb/test/API/lldbtest.py b/lldb/test/API/lldbtest.py index 94eb8ebd054aa..a03390ee38787 100644 --- a/lldb/test/API/lldbtest.py +++ b/lldb/test/API/lldbtest.py @@ -38,7 +38,7 @@ def execute(self, test, litConfig): if litConfig.noExecute: return lit.Test.PASS, '' - if not test.config.lldb_enable_python: + if not getattr(test.config, 'lldb_enable_python', False): return (lit.Test.UNSUPPORTED, 'Python module disabled') if test.config.unsupported: From 28449c9020a08055b15622b4597c0513138b5464 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 28 Aug 2020 18:15:28 -0700 Subject: [PATCH 052/234] [lldb] Hoist --framework argument out of LLDB_TEST_COMMON_ARGS (NFC) Give the framework argument its own variable (LLDB_FRAMEWORK_DIR) so that we can configure it in lit.site.cfg.py if we so desire. (cherry picked from commit 2965e9bd5edb079746a668794865be37f6f4d3d8) --- lldb/test/API/CMakeLists.txt | 2 +- lldb/test/API/lit.cfg.py | 3 +++ lldb/test/API/lit.site.cfg.py.in | 1 + lldb/utils/lldb-dotest/lldb-dotest.in | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lldb/test/API/CMakeLists.txt b/lldb/test/API/CMakeLists.txt index 192c0adc66a23..688eb9039b85d 100644 --- a/lldb/test/API/CMakeLists.txt +++ b/lldb/test/API/CMakeLists.txt @@ -101,7 +101,7 @@ endif() if(CMAKE_HOST_APPLE) if(LLDB_BUILD_FRAMEWORK) - list(APPEND LLDB_TEST_COMMON_ARGS --framework ${LLDB_FRAMEWORK_ABSOLUTE_BUILD_DIR}/LLDB.framework) + set(LLDB_FRAMEWORK_DIR ${LLDB_FRAMEWORK_ABSOLUTE_BUILD_DIR}/LLDB.framework) endif() # Use the same identity for testing diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py index 5da12eea4504f..893418cc16d3a 100644 --- a/lldb/test/API/lit.cfg.py +++ b/lldb/test/API/lit.cfg.py @@ -203,6 +203,9 @@ def delete_module_cache(path): if is_configured('lldb_libs_dir'): dotest_cmd += ['--lldb-libs-dir', config.lldb_libs_dir] +if is_configured('lldb_framework_dir'): + dotest_cmd += ['--framework', config.lldb_framework_dir] + if 'lldb-repro-capture' in config.available_features or \ 'lldb-repro-replay' in config.available_features: dotest_cmd += ['--skip-category=lldb-vscode', '--skip-category=std-module'] diff --git a/lldb/test/API/lit.site.cfg.py.in b/lldb/test/API/lit.site.cfg.py.in index 4906616ac1862..f2e1f855fe390 100644 --- a/lldb/test/API/lit.site.cfg.py.in +++ b/lldb/test/API/lit.site.cfg.py.in @@ -11,6 +11,7 @@ config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" config.lldb_obj_root = "@LLDB_BINARY_DIR@" config.lldb_src_root = "@LLDB_SOURCE_DIR@" config.lldb_libs_dir = "@LLDB_LIBS_DIR@" +config.lldb_framework_dir = "@LLDB_FRAMEWORK_DIR@" config.cmake_cxx_compiler = "@CMAKE_CXX_COMPILER@" config.host_os = "@HOST_OS@" config.host_triple = "@LLVM_HOST_TRIPLE@" diff --git a/lldb/utils/lldb-dotest/lldb-dotest.in b/lldb/utils/lldb-dotest/lldb-dotest.in index f573d5bf28d42..86f05bea9bdcb 100755 --- a/lldb/utils/lldb-dotest/lldb-dotest.in +++ b/lldb/utils/lldb-dotest/lldb-dotest.in @@ -12,6 +12,7 @@ dsymutil = '@LLDB_TEST_DSYMUTIL_CONFIGURED@' filecheck = '@LLDB_TEST_FILECHECK_CONFIGURED@' yaml2obj = '@LLDB_TEST_YAML2OBJ_CONFIGURED@' lldb_libs_dir = "@LLDB_LIBS_DIR_CONFIGURED@" +lldb_framework_dir = "@LLDB_FRAMEWORK_DIR@" lldb_build_intel_pt = "@LLDB_BUILD_INTEL_PT@" if __name__ == '__main__': @@ -28,6 +29,7 @@ if __name__ == '__main__': cmd.extend(['--yaml2obj', yaml2obj]) cmd.extend(['--filecheck', filecheck]) cmd.extend(['--lldb-libs-dir', lldb_libs_dir]) + cmd.extend(['--framework', lldb_framework_dir]) if lldb_build_intel_pt == "1": cmd.extend(['--enable-plugin', 'intel-pt']) cmd.extend(wrapper_args) From ac6fbe13ed59c66f81368c6ac1434608d0fdf81d Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 29 Sep 2020 08:56:27 -0700 Subject: [PATCH 053/234] [lldb] Configure LLDB_FRAMEWORK_DIR in multi-generator builds (cherry picked from commit d0ed45dc920004bb7b6642d6086b4722443eeba2) --- lldb/test/API/CMakeLists.txt | 1 + lldb/utils/lldb-dotest/CMakeLists.txt | 5 +++++ lldb/utils/lldb-dotest/lldb-dotest.in | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lldb/test/API/CMakeLists.txt b/lldb/test/API/CMakeLists.txt index 688eb9039b85d..c890eac2c531a 100644 --- a/lldb/test/API/CMakeLists.txt +++ b/lldb/test/API/CMakeLists.txt @@ -142,6 +142,7 @@ if(LLDB_BUILT_STANDALONE) string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} config_runtime_output_dir ${LLVM_RUNTIME_OUTPUT_INTDIR}) string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_DOTEST_ARGS "${LLDB_DOTEST_ARGS}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_SOURCE_DIR "${LLDB_SOURCE_DIR}") + string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_FRAMEWORK_DIR "${LLDB_FRAMEWORK_DIR}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_BUILD_DIRECTORY "${LLDB_TEST_BUILD_DIRECTORY}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_EXECUTABLE "${LLDB_TEST_EXECUTABLE}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_COMPILER "${LLDB_TEST_COMPILER}") diff --git a/lldb/utils/lldb-dotest/CMakeLists.txt b/lldb/utils/lldb-dotest/CMakeLists.txt index e5a73c2b1dec3..2f9ba72d7b223 100644 --- a/lldb/utils/lldb-dotest/CMakeLists.txt +++ b/lldb/utils/lldb-dotest/CMakeLists.txt @@ -21,6 +21,7 @@ if(LLDB_BUILT_STANDALONE) string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} config_runtime_output_dir ${LLVM_RUNTIME_OUTPUT_INTDIR}) string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_DOTEST_ARGS_CONFIGURED "${LLDB_DOTEST_ARGS}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_SOURCE_DIR_CONFIGURED "${LLDB_SOURCE_DIR}") + string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_FRAMEWORK_DIR_CONFIGURED "${LLDB_FRAMEWORK_DIR}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_BUILD_DIRECTORY_CONFIGURED "${LLDB_TEST_BUILD_DIRECTORY}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_EXECUTABLE_CONFIGURED "${LLDB_TEST_EXECUTABLE}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") @@ -33,6 +34,7 @@ if(LLDB_BUILT_STANDALONE) # Multi-configuration generator like Xcode (with a matching config). string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_DOTEST_ARGS_CONFIGURED "${LLDB_DOTEST_ARGS}") string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_SOURCE_DIR_CONFIGURED "${LLDB_SOURCE_DIR}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_FRAMEWORK_DIR_CONFIGURED "${LLDB_FRAMEWORK_DIR}") string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_BUILD_DIRECTORY_CONFIGURED "${LLDB_TEST_BUILD_DIRECTORY}") string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_EXECUTABLE_CONFIGURED "${LLDB_TEST_EXECUTABLE}") string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") @@ -44,6 +46,7 @@ if(LLDB_BUILT_STANDALONE) # Single-configuration generator like Ninja. string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_DOTEST_ARGS_CONFIGURED "${LLDB_DOTEST_ARGS}") string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_SOURCE_DIR_CONFIGURED "${LLDB_SOURCE_DIR}") + string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_FRAMEWORK_DIR_CONFIGURED "${LLDB_FRAMEWORK_DIR}") string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_BUILD_DIRECTORY_CONFIGURED "${LLDB_TEST_BUILD_DIRECTORY}") string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_EXECUTABLE_CONFIGURED "${LLDB_TEST_EXECUTABLE}") string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") @@ -63,6 +66,7 @@ elseif(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_DOTEST_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR}) string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_DOTEST_ARGS_CONFIGURED "${LLDB_DOTEST_ARGS}") string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_SOURCE_DIR_CONFIGURED "${LLDB_SOURCE_DIR}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_FRAMEWORK_DIR_CONFIGURED "${LLDB_FRAMEWORK_DIR}") string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_BUILD_DIRECTORY_CONFIGURED "${LLDB_TEST_BUILD_DIRECTORY}") string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_EXECUTABLE_CONFIGURED "${LLDB_TEST_EXECUTABLE}") string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") @@ -79,6 +83,7 @@ elseif(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") else() set(LLDB_DOTEST_ARGS_CONFIGURED "${LLDB_DOTEST_ARGS}") set(LLDB_SOURCE_DIR_CONFIGURED "${LLDB_SOURCE_DIR}") + set(LLDB_FRAMEWORK_DIR_CONFIGURED "${LLDB_FRAMEWORK_DIR}") set(LLDB_TEST_BUILD_DIRECTORY_CONFIGURED "${LLDB_TEST_BUILD_DIRECTORY}") set(LLDB_TEST_EXECUTABLE_CONFIGURED "${LLDB_TEST_EXECUTABLE}") set(LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") diff --git a/lldb/utils/lldb-dotest/lldb-dotest.in b/lldb/utils/lldb-dotest/lldb-dotest.in index 86f05bea9bdcb..fedb56e938fe4 100755 --- a/lldb/utils/lldb-dotest/lldb-dotest.in +++ b/lldb/utils/lldb-dotest/lldb-dotest.in @@ -12,7 +12,7 @@ dsymutil = '@LLDB_TEST_DSYMUTIL_CONFIGURED@' filecheck = '@LLDB_TEST_FILECHECK_CONFIGURED@' yaml2obj = '@LLDB_TEST_YAML2OBJ_CONFIGURED@' lldb_libs_dir = "@LLDB_LIBS_DIR_CONFIGURED@" -lldb_framework_dir = "@LLDB_FRAMEWORK_DIR@" +lldb_framework_dir = "@LLDB_FRAMEWORK_DIR_CONFIGURED@" lldb_build_intel_pt = "@LLDB_BUILD_INTEL_PT@" if __name__ == '__main__': From 85c4a16f2b522d1a5fccaddc9dc16a7bd0aa4409 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 29 Sep 2020 09:12:29 -0700 Subject: [PATCH 054/234] [lldb] Also configure lldb_framework_dir in the lit.site.cfg.py Configuring the variable in CMake isn't enought, because the build mode can't be resolved until execution time, which requires the build mode to be substituted by lit. (cherry picked from commit ccbb9827db4c30c93b92a204aeb2b98f9f3a723a) --- lldb/test/API/lit.site.cfg.py.in | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/test/API/lit.site.cfg.py.in b/lldb/test/API/lit.site.cfg.py.in index f2e1f855fe390..144d17965b9ad 100644 --- a/lldb/test/API/lit.site.cfg.py.in +++ b/lldb/test/API/lit.site.cfg.py.in @@ -59,6 +59,7 @@ try: config.dsymutil = config.dsymutil % lit_config.params config.filecheck = config.filecheck % lit_config.params config.yaml2obj = config.yaml2obj % lit_config.params + config.lldb_framework_dir = config.lldb_framework_dir % lit_config.params config.dotest_args_str = config.dotest_args_str % lit_config.params except KeyError as e: key, = e.args From 576f366e6c0d9469bd12a8a9e1057217d339ff7b Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 29 Sep 2020 13:26:09 -0700 Subject: [PATCH 055/234] [lldb] Hoist --server argument out of LLDB_TEST_COMMON_ARGS (NFC) Give the server argument its own variable (LLDB_TEST_SERVER) so that we can configure it in lit.site.cfg.py if we so desire. (cherry picked from commit 3c7070f1a6b89277fce042a943cd83fa65507a67) --- lldb/test/API/CMakeLists.txt | 6 ++++-- lldb/test/API/lit.cfg.py | 3 +++ lldb/test/API/lit.site.cfg.py.in | 2 ++ lldb/utils/lldb-dotest/CMakeLists.txt | 5 +++++ lldb/utils/lldb-dotest/lldb-dotest.in | 6 +++++- 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lldb/test/API/CMakeLists.txt b/lldb/test/API/CMakeLists.txt index c890eac2c531a..a95d7e029e78f 100644 --- a/lldb/test/API/CMakeLists.txt +++ b/lldb/test/API/CMakeLists.txt @@ -122,12 +122,12 @@ if(CMAKE_HOST_APPLE) elseif(TARGET debugserver) set(debugserver_path ${LLVM_RUNTIME_OUTPUT_INTDIR}/debugserver) message(STATUS "LLDB Tests use just-built debugserver: ${debugserver_path}") - list(APPEND LLDB_TEST_COMMON_ARGS --server ${debugserver_path}) + set(LLDB_TEST_SERVER ${debugserver_path}) add_lldb_test_dependency(debugserver) elseif(TARGET lldb-server) set(lldb_server_path ${LLVM_RUNTIME_OUTPUT_INTDIR}/lldb-server) message(STATUS "LLDB Tests use just-built lldb-server: ${lldb_server_path}") - list(APPEND LLDB_TEST_COMMON_ARGS --server ${lldb_server_path}) + set(LLDB_TEST_SERVER ${lldb_server_path}) add_lldb_test_dependency(lldb-server) else() message(WARNING "LLDB Tests enabled, but no server available") @@ -149,6 +149,7 @@ if(LLDB_BUILT_STANDALONE) string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_DSYMUTIL "${LLDB_TEST_DSYMUTIL}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_FILECHECK "${LLDB_TEST_FILECHECK}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_YAML2OBJ "${LLDB_TEST_YAML2OBJ}") + string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_SERVER "${LLDB_TEST_SERVER}") # Remaining ones must be paths to the provided LLVM build-tree. if(LLVM_CONFIGURATION_TYPES) @@ -177,6 +178,7 @@ string(REPLACE ${CMAKE_CFG_INTDIR} ${dotest_args_replacement} LLDB_TEST_COMPILER string(REPLACE ${CMAKE_CFG_INTDIR} ${dotest_args_replacement} LLDB_TEST_DSYMUTIL "${LLDB_TEST_DSYMUTIL}") string(REPLACE ${CMAKE_CFG_INTDIR} ${dotest_args_replacement} LLDB_TEST_FILECHECK "${LLDB_TEST_FILECHECK}") string(REPLACE ${CMAKE_CFG_INTDIR} ${dotest_args_replacement} LLDB_TEST_YAML2OBJ "${LLDB_TEST_YAML2OBJ}") +string(REPLACE ${CMAKE_CFG_INTDIR} ${dotest_args_replacement} LLDB_TEST_SERVER "${LLDB_TEST_SERVER}") # Configure the API test suite. configure_lit_site_cfg( diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py index 893418cc16d3a..d78a1aae54675 100644 --- a/lldb/test/API/lit.cfg.py +++ b/lldb/test/API/lit.cfg.py @@ -200,6 +200,9 @@ def delete_module_cache(path): if is_configured('yaml2obj'): dotest_cmd += ['--yaml2obj', config.yaml2obj] +if is_configured('server'): + dotest_cmd += ['--server', config.server] + if is_configured('lldb_libs_dir'): dotest_cmd += ['--lldb-libs-dir', config.lldb_libs_dir] diff --git a/lldb/test/API/lit.site.cfg.py.in b/lldb/test/API/lit.site.cfg.py.in index 144d17965b9ad..271faf371f9d1 100644 --- a/lldb/test/API/lit.site.cfg.py.in +++ b/lldb/test/API/lit.site.cfg.py.in @@ -31,6 +31,7 @@ config.test_compiler = '@LLDB_TEST_COMPILER@' config.dsymutil = '@LLDB_TEST_DSYMUTIL@' config.filecheck = '@LLDB_TEST_FILECHECK@' config.yaml2obj = '@LLDB_TEST_YAML2OBJ@' +config.server = '@LLDB_TEST_SERVER@' # The API tests use their own module caches. config.lldb_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_LLDB@", "lldb-api") config.clang_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_CLANG@", "lldb-api") @@ -59,6 +60,7 @@ try: config.dsymutil = config.dsymutil % lit_config.params config.filecheck = config.filecheck % lit_config.params config.yaml2obj = config.yaml2obj % lit_config.params + config.server = config.server % lit_config.params config.lldb_framework_dir = config.lldb_framework_dir % lit_config.params config.dotest_args_str = config.dotest_args_str % lit_config.params except KeyError as e: diff --git a/lldb/utils/lldb-dotest/CMakeLists.txt b/lldb/utils/lldb-dotest/CMakeLists.txt index 2f9ba72d7b223..1001fbf04ebe7 100644 --- a/lldb/utils/lldb-dotest/CMakeLists.txt +++ b/lldb/utils/lldb-dotest/CMakeLists.txt @@ -28,6 +28,7 @@ if(LLDB_BUILT_STANDALONE) string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_FILECHECK_CONFIGURED "${LLDB_TEST_FILECHECK}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_YAML2OBJ_CONFIGURED "${LLDB_TEST_YAML2OBJ}") + string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_SERVER_CONFIGURED "${LLDB_TEST_SERVER}") # Remaining ones must be paths to the provided LLVM build-tree. if(${config_type} IN_LIST LLVM_CONFIGURATION_TYPES) @@ -41,6 +42,7 @@ if(LLDB_BUILT_STANDALONE) string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_FILECHECK_CONFIGURED "${LLDB_TEST_FILECHECK}") string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_YAML2OBJ_CONFIGURED "${LLDB_TEST_YAML2OBJ}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_SERVER_CONFIGURED "${LLDB_TEST_SERVER}") string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_LIBS_DIR_CONFIGURED "${LLDB_LIBS_DIR}") else() # Single-configuration generator like Ninja. @@ -53,6 +55,7 @@ if(LLDB_BUILT_STANDALONE) string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_FILECHECK_CONFIGURED "${LLDB_TEST_FILECHECK}") string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_YAML2OBJ_CONFIGURED "${LLDB_TEST_YAML2OBJ}") + string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_SERVER_CONFIGURED "${LLDB_TEST_SERVER}") string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_LIBS_DIR_CONFIGURED "${LLDB_LIBS_DIR}") endif() @@ -73,6 +76,7 @@ elseif(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_FILECHECK_CONFIGURED "${LLDB_TEST_FILECHECK}") string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_YAML2OBJ_CONFIGURED "${LLDB_TEST_YAML2OBJ}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_SERVER_CONFIGURED "${LLDB_TEST_SERVER}") string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_LIBS_DIR_CONFIGURED "${LLDB_LIBS_DIR}") configure_file( @@ -90,6 +94,7 @@ else() set(LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") set(LLDB_TEST_FILECHECK_CONFIGURED "${LLDB_TEST_FILECHECK}") set(LLDB_TEST_YAML2OBJ_CONFIGURED "${LLDB_TEST_YAML2OBJ}") + set(LLDB_TEST_SERVER_CONFIGURED "${LLDB_TEST_SERVER}") set(LLDB_LIBS_DIR_CONFIGURED "${LLDB_LIBS_DIR}") configure_file( diff --git a/lldb/utils/lldb-dotest/lldb-dotest.in b/lldb/utils/lldb-dotest/lldb-dotest.in index fedb56e938fe4..cfd73f5b32a6e 100755 --- a/lldb/utils/lldb-dotest/lldb-dotest.in +++ b/lldb/utils/lldb-dotest/lldb-dotest.in @@ -11,6 +11,7 @@ compiler = '@LLDB_TEST_COMPILER_CONFIGURED@' dsymutil = '@LLDB_TEST_DSYMUTIL_CONFIGURED@' filecheck = '@LLDB_TEST_FILECHECK_CONFIGURED@' yaml2obj = '@LLDB_TEST_YAML2OBJ_CONFIGURED@' +server = '@LLDB_TEST_SERVER_CONFIGURED@' lldb_libs_dir = "@LLDB_LIBS_DIR_CONFIGURED@" lldb_framework_dir = "@LLDB_FRAMEWORK_DIR_CONFIGURED@" lldb_build_intel_pt = "@LLDB_BUILD_INTEL_PT@" @@ -29,7 +30,10 @@ if __name__ == '__main__': cmd.extend(['--yaml2obj', yaml2obj]) cmd.extend(['--filecheck', filecheck]) cmd.extend(['--lldb-libs-dir', lldb_libs_dir]) - cmd.extend(['--framework', lldb_framework_dir]) + if server: + cmd.extend(['--server', server]) + if lldb_framework_dir: + cmd.extend(['--framework', lldb_framework_dir]) if lldb_build_intel_pt == "1": cmd.extend(['--enable-plugin', 'intel-pt']) cmd.extend(wrapper_args) From 90ac61bc81bf8ec5b8af3a7419b9179e53a8601f Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 29 Sep 2020 17:22:16 -0700 Subject: [PATCH 056/234] [lldb] Hoist -s (trace directory) argument out of LLDB_TEST_COMMON_ARGS (NFC) Give the trace directory argument its own variable (LLDB_TEST_TRACE_DIRECTORY) so that we can configure it in lit.site.cfg.py if we so desire. (cherry picked from commit bd14d6ea1517c93ceecaec29dad016d9a122fa1b) --- lldb/test/API/CMakeLists.txt | 7 +++++-- lldb/test/API/lit.cfg.py | 3 +++ lldb/test/API/lit.site.cfg.py.in | 1 + lldb/utils/lldb-dotest/CMakeLists.txt | 5 +++++ lldb/utils/lldb-dotest/lldb-dotest.in | 10 ++++++---- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lldb/test/API/CMakeLists.txt b/lldb/test/API/CMakeLists.txt index a95d7e029e78f..b386fc00ad4ec 100644 --- a/lldb/test/API/CMakeLists.txt +++ b/lldb/test/API/CMakeLists.txt @@ -36,13 +36,14 @@ set(LLDB_TEST_USER_ARGS # hash of filename and .text section, there *will* be conflicts inside # the build directory. set(LLDB_TEST_COMMON_ARGS - -s - ${CMAKE_BINARY_DIR}/lldb-test-traces -S nm -u CXXFLAGS -u CFLAGS ) +# Configure the traces directory. +set(LLDB_TEST_TRACE_DIRECTORY "${PROJECT_BINARY_DIR}/lldb-test-traces" CACHE PATH "The test traces directory.") + # Set the path to the default lldb test executable. set(LLDB_DEFAULT_TEST_EXECUTABLE "${LLVM_RUNTIME_OUTPUT_INTDIR}/lldb${CMAKE_EXECUTABLE_SUFFIX}") @@ -144,6 +145,7 @@ if(LLDB_BUILT_STANDALONE) string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_SOURCE_DIR "${LLDB_SOURCE_DIR}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_FRAMEWORK_DIR "${LLDB_FRAMEWORK_DIR}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_BUILD_DIRECTORY "${LLDB_TEST_BUILD_DIRECTORY}") + string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_TRACE_DIRECTORY "${LLDB_TEST_TRACE_DIRECTORY}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_EXECUTABLE "${LLDB_TEST_EXECUTABLE}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_COMPILER "${LLDB_TEST_COMPILER}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_DSYMUTIL "${LLDB_TEST_DSYMUTIL}") @@ -173,6 +175,7 @@ endif() string(REPLACE ${CMAKE_CFG_INTDIR} ${dotest_args_replacement} LLDB_DOTEST_ARGS "${LLDB_DOTEST_ARGS}") string(REPLACE ${CMAKE_CFG_INTDIR} ${dotest_args_replacement} LLDB_SOURCE_DIR "${LLDB_SOURCE_DIR}") string(REPLACE ${CMAKE_CFG_INTDIR} ${dotest_args_replacement} LLDB_TEST_BUILD_DIRECTORY "${LLDB_TEST_BUILD_DIRECTORY}") +string(REPLACE ${CMAKE_CFG_INTDIR} ${dotest_args_replacement} LLDB_TEST_TRACE_DIRECTORY "${LLDB_TEST_TRACE_DIRECTORY}") string(REPLACE ${CMAKE_CFG_INTDIR} ${dotest_args_replacement} LLDB_TEST_EXECUTABLE "${LLDB_TEST_EXECUTABLE}") string(REPLACE ${CMAKE_CFG_INTDIR} ${dotest_args_replacement} LLDB_TEST_COMPILER "${LLDB_TEST_COMPILER}") string(REPLACE ${CMAKE_CFG_INTDIR} ${dotest_args_replacement} LLDB_TEST_DSYMUTIL "${LLDB_TEST_DSYMUTIL}") diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py index d78a1aae54675..a4d4d83fd366d 100644 --- a/lldb/test/API/lit.cfg.py +++ b/lldb/test/API/lit.cfg.py @@ -177,6 +177,9 @@ def delete_module_cache(path): if is_configured('lldb_build_directory'): dotest_cmd += ['--build-dir', config.lldb_build_directory] +if is_configured('lldb_trace_directory'): + dotest_cmd += ['-s', config.lldb_trace_directory] + if is_configured('lldb_module_cache'): delete_module_cache(config.lldb_module_cache) dotest_cmd += ['--lldb-module-cache-dir', config.lldb_module_cache] diff --git a/lldb/test/API/lit.site.cfg.py.in b/lldb/test/API/lit.site.cfg.py.in index 271faf371f9d1..0481e8fecc73a 100644 --- a/lldb/test/API/lit.site.cfg.py.in +++ b/lldb/test/API/lit.site.cfg.py.in @@ -19,6 +19,7 @@ config.shared_libs = @LLVM_ENABLE_SHARED_LIBS@ config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@" config.target_triple = "@TARGET_TRIPLE@" config.lldb_build_directory = "@LLDB_TEST_BUILD_DIRECTORY@" +config.lldb_trace_directory = "@LLDB_TEST_TRACE_DIRECTORY@" config.lldb_reproducer_directory = os.path.join("@LLDB_TEST_BUILD_DIRECTORY@", "reproducers") config.python_executable = "@Python3_EXECUTABLE@" config.dotest_args_str = "@LLDB_DOTEST_ARGS@" diff --git a/lldb/utils/lldb-dotest/CMakeLists.txt b/lldb/utils/lldb-dotest/CMakeLists.txt index 1001fbf04ebe7..cba04f3499b95 100644 --- a/lldb/utils/lldb-dotest/CMakeLists.txt +++ b/lldb/utils/lldb-dotest/CMakeLists.txt @@ -23,6 +23,7 @@ if(LLDB_BUILT_STANDALONE) string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_SOURCE_DIR_CONFIGURED "${LLDB_SOURCE_DIR}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_FRAMEWORK_DIR_CONFIGURED "${LLDB_FRAMEWORK_DIR}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_BUILD_DIRECTORY_CONFIGURED "${LLDB_TEST_BUILD_DIRECTORY}") + string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_TRACE_DIRECTORY_CONFIGURED "${LLDB_TEST_TRACE_DIRECTORY}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_EXECUTABLE_CONFIGURED "${LLDB_TEST_EXECUTABLE}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") string(REPLACE ${LLVM_RUNTIME_OUTPUT_INTDIR} ${config_runtime_output_dir} LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") @@ -37,6 +38,7 @@ if(LLDB_BUILT_STANDALONE) string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_SOURCE_DIR_CONFIGURED "${LLDB_SOURCE_DIR}") string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_FRAMEWORK_DIR_CONFIGURED "${LLDB_FRAMEWORK_DIR}") string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_BUILD_DIRECTORY_CONFIGURED "${LLDB_TEST_BUILD_DIRECTORY}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_TRACE_DIRECTORY_CONFIGURED "${LLDB_TEST_TRACE_DIRECTORY}") string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_EXECUTABLE_CONFIGURED "${LLDB_TEST_EXECUTABLE}") string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") string(REPLACE ${CMAKE_CFG_INTDIR} ${config_type} LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") @@ -50,6 +52,7 @@ if(LLDB_BUILT_STANDALONE) string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_SOURCE_DIR_CONFIGURED "${LLDB_SOURCE_DIR}") string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_FRAMEWORK_DIR_CONFIGURED "${LLDB_FRAMEWORK_DIR}") string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_BUILD_DIRECTORY_CONFIGURED "${LLDB_TEST_BUILD_DIRECTORY}") + string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_TRACE_DIRECTORY_CONFIGURED "${LLDB_TEST_TRACE_DIRECTORY}") string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_EXECUTABLE_CONFIGURED "${LLDB_TEST_EXECUTABLE}") string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") string(REPLACE ${CMAKE_CFG_INTDIR} "." LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") @@ -71,6 +74,7 @@ elseif(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_SOURCE_DIR_CONFIGURED "${LLDB_SOURCE_DIR}") string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_FRAMEWORK_DIR_CONFIGURED "${LLDB_FRAMEWORK_DIR}") string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_BUILD_DIRECTORY_CONFIGURED "${LLDB_TEST_BUILD_DIRECTORY}") + string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_TRACE_DIRECTORY_CONFIGURED "${LLDB_TEST_TRACE_DIRECTORY}") string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_EXECUTABLE_CONFIGURED "${LLDB_TEST_EXECUTABLE}") string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") @@ -89,6 +93,7 @@ else() set(LLDB_SOURCE_DIR_CONFIGURED "${LLDB_SOURCE_DIR}") set(LLDB_FRAMEWORK_DIR_CONFIGURED "${LLDB_FRAMEWORK_DIR}") set(LLDB_TEST_BUILD_DIRECTORY_CONFIGURED "${LLDB_TEST_BUILD_DIRECTORY}") + set(LLDB_TEST_TRACE_DIRECTORY_CONFIGURED "${LLDB_TEST_TRACE_DIRECTORY}") set(LLDB_TEST_EXECUTABLE_CONFIGURED "${LLDB_TEST_EXECUTABLE}") set(LLDB_TEST_COMPILER_CONFIGURED "${LLDB_TEST_COMPILER}") set(LLDB_TEST_DSYMUTIL_CONFIGURED "${LLDB_TEST_DSYMUTIL}") diff --git a/lldb/utils/lldb-dotest/lldb-dotest.in b/lldb/utils/lldb-dotest/lldb-dotest.in index cfd73f5b32a6e..d66968955a740 100755 --- a/lldb/utils/lldb-dotest/lldb-dotest.in +++ b/lldb/utils/lldb-dotest/lldb-dotest.in @@ -3,7 +3,6 @@ import subprocess import sys dotest_path = '@LLDB_SOURCE_DIR_CONFIGURED@/test/API/dotest.py' -build_dir = '@LLDB_TEST_BUILD_DIRECTORY_CONFIGURED@' dotest_args_str = '@LLDB_DOTEST_ARGS_CONFIGURED@' arch = '@LLDB_TEST_ARCH@' executable = '@LLDB_TEST_EXECUTABLE_CONFIGURED@' @@ -12,9 +11,11 @@ dsymutil = '@LLDB_TEST_DSYMUTIL_CONFIGURED@' filecheck = '@LLDB_TEST_FILECHECK_CONFIGURED@' yaml2obj = '@LLDB_TEST_YAML2OBJ_CONFIGURED@' server = '@LLDB_TEST_SERVER_CONFIGURED@' -lldb_libs_dir = "@LLDB_LIBS_DIR_CONFIGURED@" -lldb_framework_dir = "@LLDB_FRAMEWORK_DIR_CONFIGURED@" +lldb_build_dir = '@LLDB_TEST_BUILD_DIRECTORY_CONFIGURED@' lldb_build_intel_pt = "@LLDB_BUILD_INTEL_PT@" +lldb_framework_dir = "@LLDB_FRAMEWORK_DIR_CONFIGURED@" +lldb_libs_dir = "@LLDB_LIBS_DIR_CONFIGURED@" +lldb_trace_dir = '@LLDB_TEST_TRACE_DIRECTORY_CONFIGURED@' if __name__ == '__main__': wrapper_args = sys.argv[1:] @@ -23,7 +24,8 @@ if __name__ == '__main__': cmd = [sys.executable, dotest_path] cmd.extend(['--arch', arch]) cmd.extend(dotest_args) - cmd.extend(['--build-dir', build_dir]) + cmd.extend(['-s', lldb_trace_dir]) + cmd.extend(['--build-dir', lldb_build_dir]) cmd.extend(['--executable', executable]) cmd.extend(['--compiler', compiler]) cmd.extend(['--dsymutil', dsymutil]) From 330c61af33a02f5fea60c3e6b688999a37308e21 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 29 Sep 2020 23:00:18 -0700 Subject: [PATCH 057/234] [lldb] Use config.lldb_src_root in lit_config.load_config (NFC) Rather than relaying on CMake to substitute the full path to the lldb source root, use the value set in config.lldb_src_root. This makes it slightly easier to write a custom lit.site.cfg.py. (cherry picked from commit 154860af338f7b0c82cb04e91d6f199aa72cfdff) --- lldb/test/API/lit.site.cfg.py.in | 2 +- lldb/test/Shell/lit.site.cfg.py.in | 3 ++- lldb/test/Unit/lit.site.cfg.py.in | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lldb/test/API/lit.site.cfg.py.in b/lldb/test/API/lit.site.cfg.py.in index 0481e8fecc73a..ce2ff8e21d0b9 100644 --- a/lldb/test/API/lit.site.cfg.py.in +++ b/lldb/test/API/lit.site.cfg.py.in @@ -69,4 +69,4 @@ except KeyError as e: lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) # Let the main config do the real work. -lit_config.load_config(config, "@LLDB_SOURCE_DIR@/test/API/lit.cfg.py") +lit_config.load_config(config, os.path.join(config.lldb_src_root, "test", "API", "lit.cfg.py")) diff --git a/lldb/test/Shell/lit.site.cfg.py.in b/lldb/test/Shell/lit.site.cfg.py.in index ff4de9d527dea..6cddd3937628d 100644 --- a/lldb/test/Shell/lit.site.cfg.py.in +++ b/lldb/test/Shell/lit.site.cfg.py.in @@ -6,6 +6,7 @@ config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" config.llvm_libs_dir = "@LLVM_LIBS_DIR@" config.llvm_shlib_dir = "@SHLIBDIR@" config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" +config.lldb_src_root = "@LLDB_SOURCE_DIR@" config.lldb_obj_root = "@LLDB_BINARY_DIR@" config.lldb_libs_dir = "@LLDB_LIBS_DIR@" config.lldb_tools_dir = "@LLDB_TOOLS_DIR@" @@ -42,4 +43,4 @@ import lit.llvm lit.llvm.initialize(lit_config, config) # Let the main config do the real work. -lit_config.load_config(config, "@LLDB_SOURCE_DIR@/test/Shell/lit.cfg.py") +lit_config.load_config(config, os.path.join(config.lldb_src_root, "test", "Shell", "lit.cfg.py")) diff --git a/lldb/test/Unit/lit.site.cfg.py.in b/lldb/test/Unit/lit.site.cfg.py.in index e2035d678cd98..c0627b772362f 100644 --- a/lldb/test/Unit/lit.site.cfg.py.in +++ b/lldb/test/Unit/lit.site.cfg.py.in @@ -26,4 +26,4 @@ import lit.llvm lit.llvm.initialize(lit_config, config) # Let the main config do the real work. -lit_config.load_config(config, "@LLDB_SOURCE_DIR@/test/Unit/lit.cfg.py") +lit_config.load_config(config, os.path.join(config.lldb_src_root, "test", "Unit", "lit.cfg.py")) From 03a3e9a57a27d13e495223c85571d8fb7058d275 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Wed, 30 Sep 2020 15:19:42 -0700 Subject: [PATCH 058/234] [lldb] Account for static bindings in FindPythonAndSwig --- lldb/cmake/modules/FindPythonAndSwig.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lldb/cmake/modules/FindPythonAndSwig.cmake b/lldb/cmake/modules/FindPythonAndSwig.cmake index c8edaaaca3e06..4431707ab2d11 100644 --- a/lldb/cmake/modules/FindPythonAndSwig.cmake +++ b/lldb/cmake/modules/FindPythonAndSwig.cmake @@ -39,7 +39,10 @@ if(Python3_LIBRARIES AND Python3_INCLUDE_DIRS AND Python3_EXECUTABLE AND SWIG_EX set(PYTHONANDSWIG_FOUND TRUE) else() find_package(SWIG 2.0) - if (SWIG_FOUND) + if (SWIG_FOUND OR LLDB_USE_STATIC_BINDINGS) + if (LLDB_USE_STATIC_BINDINGS) + set(SWIG_EXECUTABLE "/not/found") + endif() FindPython3() else() message(STATUS "SWIG 2 or later is required for Python support in LLDB but could not be found") From fab45b00b7a00145c6d65e34b6fa14c8ae25e211 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Tue, 21 Jul 2020 11:32:55 -0700 Subject: [PATCH 059/234] Remove the "bool" return from OptionValue::Clear and its subclasses. Every override returns true and its return value is never checked. I can't see how clearing an OptionValue could fail, or what you would do if it did. The return serves no purpose. Differential Revision: https://reviews.llvm.org/D84253 (cherry picked from commit 8d6aa688eeffea4b9151d1a208ed619ca50c823a) --- lldb/include/lldb/Interpreter/OptionValue.h | 2 +- lldb/include/lldb/Interpreter/OptionValueArch.h | 3 +-- lldb/include/lldb/Interpreter/OptionValueArray.h | 3 +-- lldb/include/lldb/Interpreter/OptionValueBoolean.h | 3 +-- lldb/include/lldb/Interpreter/OptionValueChar.h | 3 +-- lldb/include/lldb/Interpreter/OptionValueDictionary.h | 3 +-- lldb/include/lldb/Interpreter/OptionValueEnumeration.h | 3 +-- lldb/include/lldb/Interpreter/OptionValueFileColonLine.h | 6 +++--- lldb/include/lldb/Interpreter/OptionValueFileSpec.h | 3 +-- lldb/include/lldb/Interpreter/OptionValueFileSpecList.h | 3 +-- lldb/include/lldb/Interpreter/OptionValueFormat.h | 3 +-- lldb/include/lldb/Interpreter/OptionValueFormatEntity.h | 2 +- lldb/include/lldb/Interpreter/OptionValueLanguage.h | 3 +-- lldb/include/lldb/Interpreter/OptionValuePathMappings.h | 3 +-- lldb/include/lldb/Interpreter/OptionValueProperties.h | 2 +- lldb/include/lldb/Interpreter/OptionValueRegex.h | 3 +-- lldb/include/lldb/Interpreter/OptionValueSInt64.h | 3 +-- lldb/include/lldb/Interpreter/OptionValueString.h | 3 +-- lldb/include/lldb/Interpreter/OptionValueUInt64.h | 3 +-- lldb/include/lldb/Interpreter/OptionValueUUID.h | 3 +-- lldb/source/Interpreter/OptionValueFormatEntity.cpp | 3 +-- lldb/source/Interpreter/OptionValueProperties.cpp | 3 +-- 22 files changed, 24 insertions(+), 42 deletions(-) diff --git a/lldb/include/lldb/Interpreter/OptionValue.h b/lldb/include/lldb/Interpreter/OptionValue.h index 27a5ddea116b6..a8176e39940a0 100644 --- a/lldb/include/lldb/Interpreter/OptionValue.h +++ b/lldb/include/lldb/Interpreter/OptionValue.h @@ -85,7 +85,7 @@ class OptionValue { SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign); - virtual bool Clear() = 0; + virtual void Clear() = 0; virtual lldb::OptionValueSP DeepCopy() const = 0; diff --git a/lldb/include/lldb/Interpreter/OptionValueArch.h b/lldb/include/lldb/Interpreter/OptionValueArch.h index 7b63c68fddbf0..809261ef22c36 100644 --- a/lldb/include/lldb/Interpreter/OptionValueArch.h +++ b/lldb/include/lldb/Interpreter/OptionValueArch.h @@ -47,10 +47,9 @@ class OptionValueArch : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/include/lldb/Interpreter/OptionValueArray.h b/lldb/include/lldb/Interpreter/OptionValueArray.h index 000351c2f5867..4546bbb803941 100644 --- a/lldb/include/lldb/Interpreter/OptionValueArray.h +++ b/lldb/include/lldb/Interpreter/OptionValueArray.h @@ -36,10 +36,9 @@ class OptionValueArray : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_values.clear(); m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/include/lldb/Interpreter/OptionValueBoolean.h b/lldb/include/lldb/Interpreter/OptionValueBoolean.h index d221f6d034c2d..1af14a4980ed9 100644 --- a/lldb/include/lldb/Interpreter/OptionValueBoolean.h +++ b/lldb/include/lldb/Interpreter/OptionValueBoolean.h @@ -37,10 +37,9 @@ class OptionValueBoolean : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } void AutoComplete(CommandInterpreter &interpreter, diff --git a/lldb/include/lldb/Interpreter/OptionValueChar.h b/lldb/include/lldb/Interpreter/OptionValueChar.h index 8d0aa91d7076a..a8ecf507a4cfc 100644 --- a/lldb/include/lldb/Interpreter/OptionValueChar.h +++ b/lldb/include/lldb/Interpreter/OptionValueChar.h @@ -38,10 +38,9 @@ class OptionValueChar : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } // Subclass specific functions diff --git a/lldb/include/lldb/Interpreter/OptionValueDictionary.h b/lldb/include/lldb/Interpreter/OptionValueDictionary.h index 1bc45252607c4..dab1c3ea0c1cf 100644 --- a/lldb/include/lldb/Interpreter/OptionValueDictionary.h +++ b/lldb/include/lldb/Interpreter/OptionValueDictionary.h @@ -35,10 +35,9 @@ class OptionValueDictionary : public OptionValue { SetValueFromString(llvm::StringRef value, VarSetOperationType op = eVarSetOperationAssign) override; - bool Clear() override { + void Clear() override { m_values.clear(); m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/include/lldb/Interpreter/OptionValueEnumeration.h b/lldb/include/lldb/Interpreter/OptionValueEnumeration.h index 26ba7ad5f646a..12c6473c7f1c2 100644 --- a/lldb/include/lldb/Interpreter/OptionValueEnumeration.h +++ b/lldb/include/lldb/Interpreter/OptionValueEnumeration.h @@ -47,10 +47,9 @@ class OptionValueEnumeration : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h b/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h index 6285c03afa149..bb504d4644f86 100644 --- a/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h +++ b/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h @@ -35,10 +35,10 @@ class OptionValueFileColonLine : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_file_spec.Clear(); m_line_number = LLDB_INVALID_LINE_NUMBER; - m_column_number = 0; + m_column_number = LLDB_INVALID_COLUMN_NUMBER; } lldb::OptionValueSP DeepCopy() const override; @@ -49,7 +49,7 @@ class OptionValueFileColonLine : public OptionValue { FileSpec &GetFileSpec() { return m_file_spec; } uint32_t GetLineNumber() { return m_line_number; } uint32_t GetColumnNumber() { return m_column_number; } - + void SetCompletionMask(uint32_t mask) { m_completion_mask = mask; } protected: diff --git a/lldb/include/lldb/Interpreter/OptionValueFileSpec.h b/lldb/include/lldb/Interpreter/OptionValueFileSpec.h index 2b18c9533f912..4fde3f6e3c8a2 100644 --- a/lldb/include/lldb/Interpreter/OptionValueFileSpec.h +++ b/lldb/include/lldb/Interpreter/OptionValueFileSpec.h @@ -41,12 +41,11 @@ class OptionValueFileSpec : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; m_data_sp.reset(); m_data_mod_time = llvm::sys::TimePoint<>(); - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h b/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h index 7b762bf6b3098..38773525c8db9 100644 --- a/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h +++ b/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h @@ -39,11 +39,10 @@ class OptionValueFileSpecList : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { std::lock_guard lock(m_mutex); m_current_value.Clear(); m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/include/lldb/Interpreter/OptionValueFormat.h b/lldb/include/lldb/Interpreter/OptionValueFormat.h index 6904c93a2f338..5a83ff3b8983d 100644 --- a/lldb/include/lldb/Interpreter/OptionValueFormat.h +++ b/lldb/include/lldb/Interpreter/OptionValueFormat.h @@ -38,10 +38,9 @@ class OptionValueFormat : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h b/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h index beb5d6843a98b..7c2f9fba0242e 100644 --- a/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h +++ b/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h @@ -34,7 +34,7 @@ class OptionValueFormatEntity : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override; + void Clear() override; lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/include/lldb/Interpreter/OptionValueLanguage.h b/lldb/include/lldb/Interpreter/OptionValueLanguage.h index f4ca2fd69ab59..1293652967596 100644 --- a/lldb/include/lldb/Interpreter/OptionValueLanguage.h +++ b/lldb/include/lldb/Interpreter/OptionValueLanguage.h @@ -41,10 +41,9 @@ class OptionValueLanguage : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/include/lldb/Interpreter/OptionValuePathMappings.h b/lldb/include/lldb/Interpreter/OptionValuePathMappings.h index 18f5cbaf43366..6d1a0816f45b8 100644 --- a/lldb/include/lldb/Interpreter/OptionValuePathMappings.h +++ b/lldb/include/lldb/Interpreter/OptionValuePathMappings.h @@ -35,10 +35,9 @@ class OptionValuePathMappings : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_path_mappings.Clear(m_notify_changes); m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/include/lldb/Interpreter/OptionValueProperties.h b/lldb/include/lldb/Interpreter/OptionValueProperties.h index 76f09cc771235..bd944b6a5adff 100644 --- a/lldb/include/lldb/Interpreter/OptionValueProperties.h +++ b/lldb/include/lldb/Interpreter/OptionValueProperties.h @@ -34,7 +34,7 @@ class OptionValueProperties Type GetType() const override { return eTypeProperties; } - bool Clear() override; + void Clear() override; lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/include/lldb/Interpreter/OptionValueRegex.h b/lldb/include/lldb/Interpreter/OptionValueRegex.h index b09b8414d5bf4..4751a1dc27ed0 100644 --- a/lldb/include/lldb/Interpreter/OptionValueRegex.h +++ b/lldb/include/lldb/Interpreter/OptionValueRegex.h @@ -36,10 +36,9 @@ class OptionValueRegex : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_regex = RegularExpression(m_default_regex_str); m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/include/lldb/Interpreter/OptionValueSInt64.h b/lldb/include/lldb/Interpreter/OptionValueSInt64.h index fbabaaeb2ff4b..87917c1088651 100644 --- a/lldb/include/lldb/Interpreter/OptionValueSInt64.h +++ b/lldb/include/lldb/Interpreter/OptionValueSInt64.h @@ -50,10 +50,9 @@ class OptionValueSInt64 : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/include/lldb/Interpreter/OptionValueString.h b/lldb/include/lldb/Interpreter/OptionValueString.h index cd371c5670204..ed44dae67d1dc 100644 --- a/lldb/include/lldb/Interpreter/OptionValueString.h +++ b/lldb/include/lldb/Interpreter/OptionValueString.h @@ -85,10 +85,9 @@ class OptionValueString : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/include/lldb/Interpreter/OptionValueUInt64.h b/lldb/include/lldb/Interpreter/OptionValueUInt64.h index 0096e87de3677..1164fb802f682 100644 --- a/lldb/include/lldb/Interpreter/OptionValueUInt64.h +++ b/lldb/include/lldb/Interpreter/OptionValueUInt64.h @@ -47,10 +47,9 @@ class OptionValueUInt64 : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_current_value = m_default_value; m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/include/lldb/Interpreter/OptionValueUUID.h b/lldb/include/lldb/Interpreter/OptionValueUUID.h index 2fb8caa3aa531..1f663e999b9d0 100644 --- a/lldb/include/lldb/Interpreter/OptionValueUUID.h +++ b/lldb/include/lldb/Interpreter/OptionValueUUID.h @@ -36,10 +36,9 @@ class OptionValueUUID : public OptionValue { SetValueFromString(const char *, VarSetOperationType = eVarSetOperationAssign) = delete; - bool Clear() override { + void Clear() override { m_uuid.Clear(); m_value_was_set = false; - return true; } lldb::OptionValueSP DeepCopy() const override; diff --git a/lldb/source/Interpreter/OptionValueFormatEntity.cpp b/lldb/source/Interpreter/OptionValueFormatEntity.cpp index 3a32a4721b68e..509a21752e480 100644 --- a/lldb/source/Interpreter/OptionValueFormatEntity.cpp +++ b/lldb/source/Interpreter/OptionValueFormatEntity.cpp @@ -29,11 +29,10 @@ OptionValueFormatEntity::OptionValueFormatEntity(const char *default_format) } } -bool OptionValueFormatEntity::Clear() { +void OptionValueFormatEntity::Clear() { m_current_entry = m_default_entry; m_current_format = m_default_format; m_value_was_set = false; - return true; } static void EscapeBackticks(llvm::StringRef str, std::string &dst) { diff --git a/lldb/source/Interpreter/OptionValueProperties.cpp b/lldb/source/Interpreter/OptionValueProperties.cpp index 24cda056977ea..5b82008ca5717 100644 --- a/lldb/source/Interpreter/OptionValueProperties.cpp +++ b/lldb/source/Interpreter/OptionValueProperties.cpp @@ -517,11 +517,10 @@ bool OptionValueProperties::SetPropertyAtIndexAsUInt64( return false; } -bool OptionValueProperties::Clear() { +void OptionValueProperties::Clear() { const size_t num_properties = m_properties.size(); for (size_t i = 0; i < num_properties; ++i) m_properties[i].GetValue()->Clear(); - return true; } Status OptionValueProperties::SetValueFromString(llvm::StringRef value, From 1cca53fcf4f922ab6f7909e4bacd242e71d2e961 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 30 Sep 2020 16:05:17 -0700 Subject: [PATCH 060/234] Handle unknown OSes in DarwinTargetInfo::getExnObjectAlignment rdar://problem/69727650 (cherry picked from commit 21cf2e6c263d7a50654653bce4e83ab463fae580) --- clang/lib/Basic/Targets/OSTargets.h | 3 ++- clang/test/SemaCXX/warn-overaligned-type-thrown.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index 2a9e4f91d4780..c52da8c0e85e2 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -154,7 +154,8 @@ class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo : public OSTargetInfo { MinVersion = llvm::VersionTuple(5U); break; default: - llvm_unreachable("Unexpected OS"); + // Conservatively return 8 bytes if OS is unknown. + return 64; } unsigned Major, Minor, Micro; diff --git a/clang/test/SemaCXX/warn-overaligned-type-thrown.cpp b/clang/test/SemaCXX/warn-overaligned-type-thrown.cpp index d7468445f8b79..9f2386ddc3c61 100644 --- a/clang/test/SemaCXX/warn-overaligned-type-thrown.cpp +++ b/clang/test/SemaCXX/warn-overaligned-type-thrown.cpp @@ -3,6 +3,7 @@ // RUN: %clang_cc1 -triple arm64-apple-tvos10 -verify -fsyntax-only -std=c++11 -fcxx-exceptions -fexceptions -DUNDERALIGNED %s // RUN: %clang_cc1 -triple arm64-apple-watchos4 -verify -fsyntax-only -std=c++11 -fcxx-exceptions -fexceptions -DUNDERALIGNED %s // RUN: %clang_cc1 -triple arm-linux-gnueabi -verify -fsyntax-only -std=c++11 -fcxx-exceptions -fexceptions -DUNDERALIGNED %s +// RUN: %clang_cc1 -triple thumbv7em-apple-unknown-macho -verify -fsyntax-only -std=c++11 -fcxx-exceptions -fexceptions -DUNDERALIGNED %s // RUN: %clang_cc1 -triple x86_64-apple-macosx10.14 -verify -fsyntax-only -std=c++11 -fcxx-exceptions -fexceptions %s // RUN: %clang_cc1 -triple arm64-apple-ios12 -verify -fsyntax-only -std=c++11 -fcxx-exceptions -fexceptions %s // RUN: %clang_cc1 -triple arm64-apple-tvos12 -verify -fsyntax-only -std=c++11 -fcxx-exceptions -fexceptions %s From b6efbd6b5f22d0a251d2fba9a5d24ac21760b1cc Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 1 Oct 2020 09:22:03 +0200 Subject: [PATCH 061/234] LLVM release notes: JIT changes By Lang Hames! --- llvm/docs/ReleaseNotes.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index db64fa2810180..bd6bbca75d9e1 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -85,6 +85,22 @@ Changes to building LLVM Python 3 as Python 2 has been end-of-life'd by the Python Software Foundation. +Changes to the JIT infrastructure +--------------------------------- + +* LLJIT now supports execution of static inits / deinits via the + LLJIT::initialize and LLJIT::deinitialize methods + +* Static libraries can now be added to a JITDylib using the + StaticLibraryDefinitionGenerator class + +* A C API has been added for OrcV2 (llvm-project/llvm/include/llvm-c/Orc.h) + +* Several OrcV2 example projects have been added to + llvm-project/llvm/examples/OrcV2Examples + +* Many bug fixes and API improvements + Changes to the AArch64 Backend ------------------------------ From 44a25a4a5a3862a93f622c12b7b1b39613448843 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 1 Oct 2020 10:34:39 +0200 Subject: [PATCH 062/234] [lldb][swift] Fix building with disabled swift support This adds the missing ifdefs for code that only compiles/links with an enabled Swift plugin. Also moves a few Swift includes that were embedded in the normal include list to their own section at the end (to prevent automerger issues). --- lldb/source/API/SystemInitializerFull.cpp | 4 ++-- lldb/source/Core/ValueObject.cpp | 4 ++-- lldb/source/Core/ValueObjectDynamicValue.cpp | 2 ++ lldb/source/Expression/IRExecutionUnit.cpp | 5 ++++- lldb/source/Expression/Materializer.cpp | 2 ++ lldb/source/Expression/UserExpression.cpp | 2 ++ lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 7 +++++++ lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp | 8 +++++++- .../source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp | 6 ++++++ lldb/source/Target/ABI.cpp | 2 ++ lldb/source/Target/ThreadPlanCallFunction.cpp | 5 ++++- lldb/source/Target/ThreadPlanStepOut.cpp | 5 ++++- lldb/unittests/Symbol/CMakeLists.txt | 6 +++++- 13 files changed, 49 insertions(+), 9 deletions(-) diff --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp index 689fa076deca6..158989b0f23ce 100644 --- a/lldb/source/API/SystemInitializerFull.cpp +++ b/lldb/source/API/SystemInitializerFull.cpp @@ -17,13 +17,13 @@ #include "lldb/Utility/Timer.h" #include "llvm/Support/TargetSelect.h" -// BEGIN SWIFT +#ifdef LLDB_ENABLE_SWIFT #include "Plugins/ExpressionParser/Swift/SwiftREPL.h" #include "Plugins/InstrumentationRuntime/SwiftRuntimeReporting/SwiftRuntimeReporting.h" #include "Plugins/Language/Swift/SwiftLanguage.h" #include "Plugins/TypeSystem/Swift/SwiftASTContext.h" #include "lldb/Target/SwiftLanguageRuntime.h" -// END SWIFT +#endif //LLDB_ENABLE_SWIFT #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wglobal-constructors" diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index f6338351870da..dd6b12393b309 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -51,9 +51,9 @@ #include "lldb/Utility/StreamString.h" #include "lldb/lldb-private-types.h" -// BEGIN SWIFT +#ifdef LLDB_ENABLE_SWIFT #include "Plugins/TypeSystem/Swift/SwiftASTContext.h" -// END SWIFT +#endif //LLDB_ENABLE_SWIFT #include "llvm/Support/Compiler.h" diff --git a/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp index 066108daae46a..6bd65f451bcc4 100644 --- a/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -22,7 +22,9 @@ #include "lldb/Utility/Status.h" #include "lldb/lldb-types.h" +#ifdef LLDB_ENABLE_SWIFT #include "Plugins/TypeSystem/Swift/SwiftASTContext.h" +#endif // LLDB_ENABLE_SWIFT #include namespace lldb_private { diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp index ed60b36f52024..9ad211d8d83e6 100644 --- a/lldb/source/Expression/IRExecutionUnit.cpp +++ b/lldb/source/Expression/IRExecutionUnit.cpp @@ -25,7 +25,6 @@ #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/LanguageRuntime.h" -#include "lldb/Target/SwiftLanguageRuntime.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" @@ -35,6 +34,10 @@ #include "lldb/../../source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "lldb/../../source/Plugins/ObjectFile/JIT/ObjectFileJIT.h" +#ifdef LLDB_ENABLE_SWIFT +#include "lldb/Target/SwiftLanguageRuntime.h" +#endif //LLDB_ENABLE_SWIFT + using namespace lldb_private; IRExecutionUnit::IRExecutionUnit(std::unique_ptr &context_up, diff --git a/lldb/source/Expression/Materializer.cpp b/lldb/source/Expression/Materializer.cpp index 00ff4982be308..7f7f95f8f4677 100644 --- a/lldb/source/Expression/Materializer.cpp +++ b/lldb/source/Expression/Materializer.cpp @@ -23,7 +23,9 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/RegisterValue.h" +#ifdef LLDB_ENABLE_SWIFT #include "Plugins/TypeSystem/Swift/SwiftASTContext.h" +#endif //LLDB_ENABLE_SWIFT #include diff --git a/lldb/source/Expression/UserExpression.cpp b/lldb/source/Expression/UserExpression.cpp index ab0fa5c476a58..0232aafcb04c0 100644 --- a/lldb/source/Expression/UserExpression.cpp +++ b/lldb/source/Expression/UserExpression.cpp @@ -44,7 +44,9 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" +#ifdef LLDB_ENABLE_SWIFT #include "Plugins/TypeSystem/Swift/SwiftASTContext.h" +#endif //LLDB_ENABLE_SWIFT using namespace lldb_private; diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 442c05c2d9959..3711ae39f7f0f 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -40,7 +40,10 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MipsABIFlags.h" + +#ifdef LLDB_ENABLE_SWIFT #include "swift/ABI/ObjectFile.h" +#endif //LLDB_ENABLE_SWIFT #define CASE_AND_STREAM(s, def, width) \ case def: \ @@ -3407,6 +3410,10 @@ ObjectFileELF::GetLoadableData(Target &target) { llvm::StringRef ObjectFileELF::GetReflectionSectionIdentifier( swift::ReflectionSectionKind section) { +#ifdef LLDB_ENABLE_SWIFT swift::SwiftObjectFileFormatELF file_format_elf; return file_format_elf.getSectionName(section); +#else + llvm_unreachable("Swift support disabled"); +#endif //LLDB_ENABLE_SWIFT } diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 8c88f567ddbd5..0ebcd9c8b4958 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -27,7 +27,6 @@ #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" -#include "lldb/Target/SwiftLanguageRuntime.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadList.h" @@ -47,7 +46,10 @@ #include "llvm/Support/MemoryBuffer.h" #include "ObjectFileMachO.h" +#ifdef LLDB_ENABLE_SWIFT #include "swift/ABI/ObjectFile.h" +#include "lldb/Target/SwiftLanguageRuntime.h" +#endif //LLDB_ENABLE_SWIFT #if defined(__APPLE__) #include @@ -6474,6 +6476,10 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp, llvm::StringRef ObjectFileMachO::GetReflectionSectionIdentifier( swift::ReflectionSectionKind section) { +#ifdef LLDB_ENABLE_SWIFT swift::SwiftObjectFileFormatMachO file_format_mach_o; return file_format_mach_o.getSectionName(section); +#else + llvm_unreachable("Swift support disabled"); +#endif //LLDB_ENABLE_SWIFT } diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp index 095426985f0eb..c966190c536bf 100644 --- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -33,7 +33,9 @@ #include "llvm/Support/Error.h" #include "llvm/Support/MemoryBuffer.h" +#ifdef LLDB_ENABLE_SWIFT #include "swift/ABI/ObjectFile.h" +#endif //LLDB_ENABLE_SWIFT #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ #define IMAGE_NT_SIGNATURE 0x00004550 // PE00 @@ -1257,6 +1259,10 @@ uint32_t ObjectFilePECOFF::GetPluginVersion() { return 1; } llvm::StringRef ObjectFilePECOFF::GetReflectionSectionIdentifier( swift::ReflectionSectionKind section) { +#ifdef LLDB_ENABLE_SWIFT swift::SwiftObjectFileFormatCOFF file_format_coff; return file_format_coff.getSectionName(section); +#else + llvm_unreachable("Swift support disabled"); +#endif //LLDB_ENABLE_SWIFT } diff --git a/lldb/source/Target/ABI.cpp b/lldb/source/Target/ABI.cpp index a7a33aca685e1..e9424cd602a06 100644 --- a/lldb/source/Target/ABI.cpp +++ b/lldb/source/Target/ABI.cpp @@ -19,7 +19,9 @@ #include "llvm/Support/TargetRegistry.h" #include +#ifdef LLDB_ENABLE_SWIFT #include "Plugins/TypeSystem/Swift/SwiftASTContext.h" +#endif //LLDB_ENABLE_SWIFT using namespace lldb; using namespace lldb_private; diff --git a/lldb/source/Target/ThreadPlanCallFunction.cpp b/lldb/source/Target/ThreadPlanCallFunction.cpp index f30ca6d158981..0bb56f351a157 100644 --- a/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -18,7 +18,6 @@ #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" -#include "lldb/Target/SwiftLanguageRuntime.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanRunToAddress.h" @@ -27,6 +26,10 @@ #include +#ifdef LLDB_ENABLE_SWIFT +#include "lldb/Target/SwiftLanguageRuntime.h" +#endif //LLDB_ENABLE_SWIFT + using namespace lldb; using namespace lldb_private; diff --git a/lldb/source/Target/ThreadPlanStepOut.cpp b/lldb/source/Target/ThreadPlanStepOut.cpp index a553fc9799a73..b6fb9bf6e030d 100644 --- a/lldb/source/Target/ThreadPlanStepOut.cpp +++ b/lldb/source/Target/ThreadPlanStepOut.cpp @@ -20,7 +20,6 @@ #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" -#include "lldb/Target/SwiftLanguageRuntime.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadPlanStepOverRange.h" #include "lldb/Target/ThreadPlanStepThrough.h" @@ -28,6 +27,10 @@ #include +#ifdef LLDB_ENABLE_SWIFT +#include "lldb/Target/SwiftLanguageRuntime.h" +#endif // LLDB_ENABLE_SWIFT + using namespace lldb; using namespace lldb_private; diff --git a/lldb/unittests/Symbol/CMakeLists.txt b/lldb/unittests/Symbol/CMakeLists.txt index 0e9a62bedc900..ec07c6b6311a1 100644 --- a/lldb/unittests/Symbol/CMakeLists.txt +++ b/lldb/unittests/Symbol/CMakeLists.txt @@ -2,9 +2,13 @@ set(SWIFT_SOURCES TestSwiftASTContext.cpp TestTypeSystemSwiftTypeRef.cpp ) +set(SWIFT_LIBS + lldbPluginTypeSystemSwift +) set(LLVM_OPTIONAL_SOURCES ${SWIFT_SOURCES}) if (NOT LLDB_ENABLE_SWIFT_SUPPORT) unset(SWIFT_SOURCES) + unset(SWIFT_LIBS) endif() add_lldb_unittest(SymbolTests @@ -27,7 +31,7 @@ add_lldb_unittest(SymbolTests lldbPluginSymbolFileDWARF lldbPluginSymbolFileSymtab lldbPluginTypeSystemClang - lldbPluginTypeSystemSwift + ${SWIFT_LIBS} LLVMTestingSupport ) From 636ecdd147911fa9b51b84308734676ef815ca13 Mon Sep 17 00:00:00 2001 From: Ahsan Saghir Date: Thu, 1 Oct 2020 13:28:35 -0500 Subject: [PATCH 063/234] Fix indentation for PowerPC ReleaseNotes --- llvm/docs/ReleaseNotes.rst | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index bd6bbca75d9e1..a1f00a1a3b3ad 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -178,24 +178,33 @@ Optimization: Codegen: * POWER10 support -* Added PC Relative addressing -* Added __int128 vector bool support + + * Added PC Relative addressing + * Added __int128 vector bool support + * Security enhancement via probe-stack attribute support to protect against stack clash * Floating point support enhancements -* Improved half precision and quad precision support, including GLIBC -* constrained FP operation support for arithmetic/rounding/max/min -* cleaning up fast math flags checks in DAGCombine, Legalizer, and Lowering + + * Improved half precision and quad precision support, including GLIBC + * constrained FP operation support for arithmetic/rounding/max/min + * cleaning up fast math flags checks in DAGCombine, Legalizer, and Lowering + * Performance improvements from instruction exploitation, especially for vector permute on LE * Scheduling enhancements -* Added MacroFusion for POWER8 -* Added post-ra heuristics for POWER9 + + * Added MacroFusion for POWER8 + * Added post-ra heuristics for POWER9 + * Target dependent passes tuning -* Updated LoopStrengthReduce to use instruction number as first priority -* Enhanced MachineCombiner to expose more ILP + + * Updated LoopStrengthReduce to use instruction number as first priority + * Enhanced MachineCombiner to expose more ILP + * Code quality and maintenance enhancements -* Enabled more machine verification passes -* Added ability to parse and emit additional extended mnemonics -* Numerous bug fixes + + * Enabled more machine verification passes + * Added ability to parse and emit additional extended mnemonics + * Numerous bug fixes AIX Support Improvements: From a511a88e2fc66be413223bfdaea4a8460c0708ff Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Fri, 2 Oct 2020 01:13:02 -0700 Subject: [PATCH 064/234] Have kernel binary scanner load dSYMs as binary+dSYM if best thing found (#1896) lldb's PlatforDarwinKernel scans the local filesystem (well known locations, plus user-specified directories) for kernels and kexts when doing kernel debugging, and loads them automatically. Sometimes kernel developers want to debug with *only* a dSYM, in which case they give lldb the DWARF binary + the dSYM as a binary and symbol file. This patch adds code to lldb to do this automatically if that's the best thing lldb can find. A few other bits of cleanup in PlatformDarwinKernel that I undertook at the same time: 1. Remove the 'platform.plugin.darwin-kernel.search-locally-for-kexts' setting. When I added the local filesystem index at start of kernel debugging, I thought people might object to the cost of the search and want a way to disable it. No one has. 2. Change the behavior of 'plugin.dynamic-loader.darwin-kernel.load-kexts' setting so it does not disable the local filesystem scan, or use of the local filesystem binaries. 3. PlatformDarwinKernel::GetSharedModule into GetSharedModuleKext and GetSharedModuleKernel for easier readability & maintenance. 4. Added accounting of .dSYM.yaa files (an archive format akin to tar) that I come across during the scan. I'm not using these for now; it would be very expensive to expand the archives & see if the UUID matches what I'm searching for. Differential Revision: https://reviews.llvm.org/D88632 (cherry picked from commit a1e97923a025d09934b557ca4343d8e4b5a9973d) --- .../DynamicLoaderDarwinKernel.cpp | 6 +- .../Platform/MacOSX/PlatformDarwinKernel.cpp | 424 ++++++++++++------ .../Platform/MacOSX/PlatformDarwinKernel.h | 32 +- .../MacOSX/PlatformMacOSXProperties.td | 4 - 4 files changed, 318 insertions(+), 148 deletions(-) diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp index 68a0335682d3a..d0d5a99b28edc 100644 --- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp +++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp @@ -517,12 +517,8 @@ DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel(Process *process, Status error; PlatformSP platform_sp( Platform::Create(PlatformDarwinKernel::GetPluginNameStatic(), error)); - // Only select the darwin-kernel Platform if we've been asked to load kexts. - // It can take some time to scan over all of the kext info.plists and that - // shouldn't be done if kext loading is explicitly disabled. - if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts()) { + if (platform_sp.get()) process->GetTarget().SetPlatform(platform_sp); - } } // Destructor diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp index f6c0f262a3798..54f49601e8112 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp @@ -199,13 +199,6 @@ class PlatformDarwinKernelProperties : public Properties { virtual ~PlatformDarwinKernelProperties() {} - bool GetSearchForKexts() const { - const uint32_t idx = ePropertySearchForKexts; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - NULL, idx, - g_platformdarwinkernel_properties[idx].default_uint_value != 0); - } - FileSpecList GetKextDirectories() const { const uint32_t idx = ePropertyKextDirectories; const OptionValueFileSpecList *option_value = @@ -245,14 +238,12 @@ PlatformDarwinKernel::PlatformDarwinKernel( m_name_to_kext_path_map_with_dsyms(), m_name_to_kext_path_map_without_dsyms(), m_search_directories(), m_search_directories_no_recursing(), m_kernel_binaries_with_dsyms(), - m_kernel_binaries_without_dsyms(), - m_ios_debug_session(is_ios_debug_session) + m_kernel_binaries_without_dsyms(), m_kernel_dsyms_no_binaries(), + m_kernel_dsyms_yaas(), m_ios_debug_session(is_ios_debug_session) { - if (GetGlobalProperties()->GetSearchForKexts()) { - CollectKextAndKernelDirectories(); - SearchForKextsAndKernelsRecursively(); - } + CollectKextAndKernelDirectories(); + SearchForKextsAndKernelsRecursively(); } /// Destructor. @@ -293,6 +284,10 @@ void PlatformDarwinKernel::GetStatus(Stream &strm) { (int)m_kernel_binaries_with_dsyms.size()); strm.Printf(" Number of Kernel binaries without dSYMs indexed: %d\n", (int)m_kernel_binaries_without_dsyms.size()); + strm.Printf(" Number of Kernel dSYMs with no binaries indexed: %d\n", + (int)m_kernel_dsyms_no_binaries.size()); + strm.Printf(" Number of Kernel dSYM.yaa's indexed: %d\n", + (int)m_kernel_dsyms_yaas.size()); Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); if (log) { @@ -305,14 +300,22 @@ void PlatformDarwinKernel::GetStatus(Stream &strm) { for (auto pos : m_name_to_kext_path_map_without_dsyms) { LLDB_LOGF(log, "%s", pos.second.GetPath().c_str()); } - LLDB_LOGF(log, "\nkernels with dSYMS"); + LLDB_LOGF(log, "\nkernel binaries with dSYMS"); for (auto fs : m_kernel_binaries_with_dsyms) { LLDB_LOGF(log, "%s", fs.GetPath().c_str()); } - LLDB_LOGF(log, "\nkernels without dSYMS"); + LLDB_LOGF(log, "\nkernel binaries without dSYMS"); for (auto fs : m_kernel_binaries_without_dsyms) { LLDB_LOGF(log, "%s", fs.GetPath().c_str()); } + LLDB_LOGF(log, "\nkernel dSYMS with no binaries"); + for (auto fs : m_kernel_dsyms_no_binaries) { + LLDB_LOGF(log, "%s", fs.GetPath().c_str()); + } + LLDB_LOGF(log, "\nkernels .dSYM.yaa's"); + for (auto fs : m_kernel_dsyms_yaas) { + LLDB_LOGF(log, "%s", fs.GetPath().c_str()); + } LLDB_LOGF(log, "\n"); } } @@ -497,56 +500,79 @@ PlatformDarwinKernel::GetKernelsAndKextsInDirectoryHelper( file_spec.GetPath().c_str()); PlatformDarwinKernel *thisp = (PlatformDarwinKernel *)baton; + + llvm::StringRef filename = file_spec.GetFilename().GetStringRef(); + bool is_kernel_filename = + filename.startswith("kernel") || filename.startswith("mach"); + bool is_dsym_yaa = filename.endswith(".dSYM.yaa"); + if (ft == llvm::sys::fs::file_type::regular_file || ft == llvm::sys::fs::file_type::symlink_file) { - ConstString filename = file_spec.GetFilename(); - if ((strncmp(filename.GetCString(), "kernel", 6) == 0 || - strncmp(filename.GetCString(), "mach", 4) == 0) && - file_spec_extension != g_dsym_suffix) { - if (KernelHasdSYMSibling(file_spec)) - { - LLDB_LOGF(log, - "PlatformDarwinKernel registering kernel binary '%s' with " - "dSYM sibling", - file_spec.GetPath().c_str()); - thisp->m_kernel_binaries_with_dsyms.push_back(file_spec); + if (is_kernel_filename) { + if (file_spec_extension != g_dsym_suffix && !is_dsym_yaa) { + if (KernelHasdSYMSibling(file_spec)) { + LLDB_LOGF(log, + "PlatformDarwinKernel registering kernel binary '%s' with " + "dSYM sibling", + file_spec.GetPath().c_str()); + thisp->m_kernel_binaries_with_dsyms.push_back(file_spec); + } else { + LLDB_LOGF( + log, + "PlatformDarwinKernel registering kernel binary '%s', no dSYM", + file_spec.GetPath().c_str()); + thisp->m_kernel_binaries_without_dsyms.push_back(file_spec); + } } - else - { - LLDB_LOGF( - log, "PlatformDarwinKernel registering kernel binary '%s', no dSYM", - file_spec.GetPath().c_str()); - thisp->m_kernel_binaries_without_dsyms.push_back(file_spec); + if (is_dsym_yaa) { + LLDB_LOGF(log, "PlatformDarwinKernel registering kernel .dSYM.yaa '%s'", + file_spec.GetPath().c_str()); + thisp->m_kernel_dsyms_yaas.push_back(file_spec); } return FileSystem::eEnumerateDirectoryResultNext; } - } else if (ft == llvm::sys::fs::file_type::directory_file && - file_spec_extension == g_kext_suffix) { - AddKextToMap(thisp, file_spec); - // Look to see if there is a PlugIns subdir with more kexts - FileSpec contents_plugins(file_spec.GetPath() + "/Contents/PlugIns"); - std::string search_here_too; - if (FileSystem::Instance().IsDirectory(contents_plugins)) { - search_here_too = contents_plugins.GetPath(); - } else { - FileSpec plugins(file_spec.GetPath() + "/PlugIns"); - if (FileSystem::Instance().IsDirectory(plugins)) { - search_here_too = plugins.GetPath(); - } - } + } else { + if (ft == llvm::sys::fs::file_type::directory_file) { + if (file_spec_extension == g_kext_suffix) { + AddKextToMap(thisp, file_spec); + // Look to see if there is a PlugIns subdir with more kexts + FileSpec contents_plugins(file_spec.GetPath() + "/Contents/PlugIns"); + std::string search_here_too; + if (FileSystem::Instance().IsDirectory(contents_plugins)) { + search_here_too = contents_plugins.GetPath(); + } else { + FileSpec plugins(file_spec.GetPath() + "/PlugIns"); + if (FileSystem::Instance().IsDirectory(plugins)) { + search_here_too = plugins.GetPath(); + } + } - if (!search_here_too.empty()) { - const bool find_directories = true; - const bool find_files = false; - const bool find_other = false; - FileSystem::Instance().EnumerateDirectory( - search_here_too.c_str(), find_directories, find_files, find_other, - recurse ? GetKernelsAndKextsInDirectoryWithRecursion - : GetKernelsAndKextsInDirectoryNoRecursion, - baton); + if (!search_here_too.empty()) { + const bool find_directories = true; + const bool find_files = false; + const bool find_other = false; + FileSystem::Instance().EnumerateDirectory( + search_here_too.c_str(), find_directories, find_files, find_other, + recurse ? GetKernelsAndKextsInDirectoryWithRecursion + : GetKernelsAndKextsInDirectoryNoRecursion, + baton); + } + return FileSystem::eEnumerateDirectoryResultNext; + } + // Do we have a kernel dSYM with no kernel binary? + if (is_kernel_filename && file_spec_extension == g_dsym_suffix) { + if (KerneldSYMHasNoSiblingBinary(file_spec)) { + LLDB_LOGF(log, + "PlatformDarwinKernel registering kernel dSYM '%s' with " + "no binary sibling", + file_spec.GetPath().c_str()); + thisp->m_kernel_dsyms_no_binaries.push_back(file_spec); + return FileSystem::eEnumerateDirectoryResultNext; + } + } } - return FileSystem::eEnumerateDirectoryResultNext; } + // Don't recurse into dSYM/kext/bundle directories if (recurse && file_spec_extension != g_dsym_suffix && file_spec_extension != g_kext_suffix && @@ -642,6 +668,63 @@ bool PlatformDarwinKernel::KernelHasdSYMSibling(const FileSpec &kernel_binary) { return FileSystem::Instance().IsDirectory(kernel_dsym); } +// Given a FileSpec of /dir/dir/mach.development.t7004.dSYM +// Return true if only the dSYM exists, no binary next to it. +// /dir/dir/mach.development.t7004.dSYM +// but no +// /dir/dir/mach.development.t7004 +bool PlatformDarwinKernel::KerneldSYMHasNoSiblingBinary( + const FileSpec &kernel_dsym) { + static ConstString g_dsym_suffix = ConstString(".dSYM"); + std::string possible_path = kernel_dsym.GetPath(); + if (kernel_dsym.GetFileNameExtension() != g_dsym_suffix) + return false; + + FileSpec binary_filespec = kernel_dsym; + // Chop off the '.dSYM' extension on the filename + binary_filespec.GetFilename() = + binary_filespec.GetFileNameStrippingExtension(); + + // Is there a binary next to this this? Then return false. + if (FileSystem::Instance().Exists(binary_filespec)) + return false; + + // If we have at least one binary in the DWARF subdir, then + // this is a properly formed dSYM and it has no binary next + // to it. + if (GetDWARFBinaryInDSYMBundle(kernel_dsym).size() > 0) + return true; + + return false; +} + +// TODO: This method returns a vector of FileSpec's because a +// dSYM bundle may contain multiple DWARF binaries, but it +// only implements returning the base name binary for now; +// it should iterate over every binary in the DWARF subdir +// and return them all. +std::vector +PlatformDarwinKernel::GetDWARFBinaryInDSYMBundle(FileSpec dsym_bundle) { + std::vector results; + static ConstString g_dsym_suffix = ConstString(".dSYM"); + if (dsym_bundle.GetFileNameExtension() != g_dsym_suffix) { + return results; + } + // Drop the '.dSYM' from the filename + std::string filename = + dsym_bundle.GetFileNameStrippingExtension().GetCString(); + std::string dirname = dsym_bundle.GetDirectory().GetCString(); + + std::string binary_filepath = dsym_bundle.GetPath(); + binary_filepath += "/Contents/Resources/DWARF/"; + binary_filepath += filename; + + FileSpec binary_fspec(binary_filepath); + if (FileSystem::Instance().Exists(binary_fspec)) + results.push_back(binary_fspec); + return results; +} + Status PlatformDarwinKernel::GetSharedModule( const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, @@ -653,111 +736,176 @@ Status PlatformDarwinKernel::GetSharedModule( // Treat the file's path as a kext bundle ID (e.g. // "com.apple.driver.AppleIRController") and search our kext index. std::string kext_bundle_id = platform_file.GetPath(); - if (!kext_bundle_id.empty()) { - ConstString kext_bundle_cs(kext_bundle_id.c_str()); - - // First look through the kext bundles that had a dsym next to them - if (m_name_to_kext_path_map_with_dsyms.count(kext_bundle_cs) > 0) { - for (BundleIDToKextIterator it = - m_name_to_kext_path_map_with_dsyms.begin(); - it != m_name_to_kext_path_map_with_dsyms.end(); ++it) { - if (it->first == kext_bundle_cs) { - error = ExamineKextForMatchingUUID(it->second, module_spec.GetUUID(), - module_spec.GetArchitecture(), - module_sp); - if (module_sp.get()) { - return error; - } - } - } - } + if (!kext_bundle_id.empty() && module_spec.GetUUID().IsValid()) { + if (kext_bundle_id == "mach_kernel") { + return GetSharedModuleKernel(module_spec, process, module_sp, + module_search_paths_ptr, old_module_sp_ptr, + did_create_ptr); + } else { + return GetSharedModuleKext(module_spec, process, module_sp, + module_search_paths_ptr, old_module_sp_ptr, + did_create_ptr); + } + } else { // Give the generic methods, including possibly calling into DebugSymbols // framework on macOS systems, a chance. - error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp, + return PlatformDarwin::GetSharedModule(module_spec, process, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); - if (error.Success() && module_sp.get()) { - return error; + } +} + +Status PlatformDarwinKernel::GetSharedModuleKext( + const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, + bool *did_create_ptr) { + Status error; + module_sp.reset(); + const FileSpec &platform_file = module_spec.GetFileSpec(); + + // Treat the file's path as a kext bundle ID (e.g. + // "com.apple.driver.AppleIRController") and search our kext index. + ConstString kext_bundle(platform_file.GetPath().c_str()); + // First look through the kext bundles that had a dsym next to them + if (m_name_to_kext_path_map_with_dsyms.count(kext_bundle) > 0) { + for (BundleIDToKextIterator it = m_name_to_kext_path_map_with_dsyms.begin(); + it != m_name_to_kext_path_map_with_dsyms.end(); ++it) { + if (it->first == kext_bundle) { + error = ExamineKextForMatchingUUID(it->second, module_spec.GetUUID(), + module_spec.GetArchitecture(), + module_sp); + if (module_sp.get()) { + return error; + } + } + } + } + + // Give the generic methods, including possibly calling into DebugSymbols + // framework on macOS systems, a chance. + error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp, + module_search_paths_ptr, + old_module_sp_ptr, did_create_ptr); + if (error.Success() && module_sp.get()) { + return error; + } + + // Lastly, look through the kext binarys without dSYMs + if (m_name_to_kext_path_map_without_dsyms.count(kext_bundle) > 0) { + for (BundleIDToKextIterator it = + m_name_to_kext_path_map_without_dsyms.begin(); + it != m_name_to_kext_path_map_without_dsyms.end(); ++it) { + if (it->first == kext_bundle) { + error = ExamineKextForMatchingUUID(it->second, module_spec.GetUUID(), + module_spec.GetArchitecture(), + module_sp); + if (module_sp.get()) { + return error; + } + } } + } + return error; +} - // Lastly, look through the kext binarys without dSYMs - if (m_name_to_kext_path_map_without_dsyms.count(kext_bundle_cs) > 0) { - for (BundleIDToKextIterator it = - m_name_to_kext_path_map_without_dsyms.begin(); - it != m_name_to_kext_path_map_without_dsyms.end(); ++it) { - if (it->first == kext_bundle_cs) { - error = ExamineKextForMatchingUUID(it->second, module_spec.GetUUID(), - module_spec.GetArchitecture(), - module_sp); - if (module_sp.get()) { +Status PlatformDarwinKernel::GetSharedModuleKernel( + const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, + bool *did_create_ptr) { + Status error; + module_sp.reset(); + + // First try all kernel binaries that have a dSYM next to them + for (auto possible_kernel : m_kernel_binaries_with_dsyms) { + if (FileSystem::Instance().Exists(possible_kernel)) { + ModuleSpec kern_spec(possible_kernel); + kern_spec.GetUUID() = module_spec.GetUUID(); + module_sp.reset(new Module(kern_spec)); + if (module_sp && module_sp->GetObjectFile() && + module_sp->MatchesModuleSpec(kern_spec)) { + // module_sp is an actual kernel binary we want to add. + if (process) { + process->GetTarget().GetImages().AppendIfNeeded(module_sp); + error.Clear(); + return error; + } else { + error = ModuleList::GetSharedModule(kern_spec, module_sp, nullptr, + nullptr, nullptr); + if (module_sp && module_sp->GetObjectFile() && + module_sp->GetObjectFile()->GetType() != + ObjectFile::Type::eTypeCoreFile) { return error; } + module_sp.reset(); } } } } - if (kext_bundle_id == "mach_kernel" && module_spec.GetUUID().IsValid()) { - // First try all kernel binaries that have a dSYM next to them - for (auto possible_kernel : m_kernel_binaries_with_dsyms) { - if (FileSystem::Instance().Exists(possible_kernel)) { - ModuleSpec kern_spec(possible_kernel); - kern_spec.GetUUID() = module_spec.GetUUID(); - ModuleSP module_sp(new Module(kern_spec)); - if (module_sp && module_sp->GetObjectFile() && - module_sp->MatchesModuleSpec(kern_spec)) { - // module_sp is an actual kernel binary we want to add. - if (process) { - process->GetTarget().GetImages().AppendIfNeeded(module_sp); - error.Clear(); + // Next try all dSYMs that have no kernel binary next to them (load + // the kernel DWARF stub as the main binary) + for (auto possible_kernel_dsym : m_kernel_dsyms_no_binaries) { + std::vector objfile_names = + GetDWARFBinaryInDSYMBundle(possible_kernel_dsym); + for (FileSpec objfile : objfile_names) { + ModuleSpec kern_spec(objfile); + kern_spec.GetUUID() = module_spec.GetUUID(); + kern_spec.GetSymbolFileSpec() = possible_kernel_dsym; + + module_sp.reset(new Module(kern_spec)); + if (module_sp && module_sp->GetObjectFile() && + module_sp->MatchesModuleSpec(kern_spec)) { + // module_sp is an actual kernel binary we want to add. + if (process) { + process->GetTarget().GetImages().AppendIfNeeded(module_sp); + error.Clear(); + return error; + } else { + error = ModuleList::GetSharedModule(kern_spec, module_sp, nullptr, + nullptr, nullptr); + if (module_sp && module_sp->GetObjectFile() && + module_sp->GetObjectFile()->GetType() != + ObjectFile::Type::eTypeCoreFile) { return error; - } else { - error = ModuleList::GetSharedModule(kern_spec, module_sp, NULL, - NULL, NULL); - if (module_sp && module_sp->GetObjectFile() && - module_sp->GetObjectFile()->GetType() != - ObjectFile::Type::eTypeCoreFile) { - return error; - } - module_sp.reset(); } + module_sp.reset(); } } } + } - // Give the generic methods, including possibly calling into DebugSymbols - // framework on macOS systems, a chance. - error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp, - module_search_paths_ptr, - old_module_sp_ptr, did_create_ptr); - if (error.Success() && module_sp.get()) { - return error; - } + // Give the generic methods, including possibly calling into DebugSymbols + // framework on macOS systems, a chance. + error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp, + module_search_paths_ptr, + old_module_sp_ptr, did_create_ptr); + if (error.Success() && module_sp.get()) { + return error; + } - // Next try all kernel binaries that don't have a dSYM - for (auto possible_kernel : m_kernel_binaries_without_dsyms) { - if (FileSystem::Instance().Exists(possible_kernel)) { - ModuleSpec kern_spec(possible_kernel); - kern_spec.GetUUID() = module_spec.GetUUID(); - ModuleSP module_sp(new Module(kern_spec)); - if (module_sp && module_sp->GetObjectFile() && - module_sp->MatchesModuleSpec(kern_spec)) { - // module_sp is an actual kernel binary we want to add. - if (process) { - process->GetTarget().GetImages().AppendIfNeeded(module_sp); - error.Clear(); + // Lastly, try all kernel binaries that don't have a dSYM + for (auto possible_kernel : m_kernel_binaries_without_dsyms) { + if (FileSystem::Instance().Exists(possible_kernel)) { + ModuleSpec kern_spec(possible_kernel); + kern_spec.GetUUID() = module_spec.GetUUID(); + module_sp.reset(new Module(kern_spec)); + if (module_sp && module_sp->GetObjectFile() && + module_sp->MatchesModuleSpec(kern_spec)) { + // module_sp is an actual kernel binary we want to add. + if (process) { + process->GetTarget().GetImages().AppendIfNeeded(module_sp); + error.Clear(); + return error; + } else { + error = ModuleList::GetSharedModule(kern_spec, module_sp, nullptr, + nullptr, nullptr); + if (module_sp && module_sp->GetObjectFile() && + module_sp->GetObjectFile()->GetType() != + ObjectFile::Type::eTypeCoreFile) { return error; - } else { - error = ModuleList::GetSharedModule(kern_spec, module_sp, NULL, - NULL, NULL); - if (module_sp && module_sp->GetObjectFile() && - module_sp->GetObjectFile()->GetType() != - ObjectFile::Type::eTypeCoreFile) { - return error; - } - module_sp.reset(); } + module_sp.reset(); } } } diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h index 9cf9e41208eb8..cd9e9d70f8ed8 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h @@ -126,7 +126,30 @@ class PlatformDarwinKernel : public PlatformDarwin { // Returns true if there is a .dSYM bundle next to the kernel static bool - KernelHasdSYMSibling(const lldb_private::FileSpec &kext_bundle_filepath); + KernelHasdSYMSibling(const lldb_private::FileSpec &kernel_filepath); + + // Returns true if there is a .dSYM bundle with NO kernel binary next to it + static bool KerneldSYMHasNoSiblingBinary( + const lldb_private::FileSpec &kernel_dsym_filepath); + + // Given a dsym_bundle argument ('.../foo.dSYM'), return a FileSpec + // with the binary inside it ('.../foo.dSYM/Contents/Resources/DWARF/foo'). + // A dSYM bundle may have multiple DWARF binaries in them, so a vector + // of matches is returned. + static std::vector + GetDWARFBinaryInDSYMBundle(lldb_private::FileSpec dsym_bundle); + + lldb_private::Status + GetSharedModuleKext(const lldb_private::ModuleSpec &module_spec, + lldb_private::Process *process, lldb::ModuleSP &module_sp, + const lldb_private::FileSpecList *module_search_paths_ptr, + lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr); + + lldb_private::Status GetSharedModuleKernel( + const lldb_private::ModuleSpec &module_spec, + lldb_private::Process *process, lldb::ModuleSP &module_sp, + const lldb_private::FileSpecList *module_search_paths_ptr, + lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr); lldb_private::Status ExamineKextForMatchingUUID(const lldb_private::FileSpec &kext_bundle_path, @@ -170,6 +193,13 @@ class PlatformDarwinKernel : public PlatformDarwin { // on local // filesystem, with // dSYMs next to them + KernelBinaryCollection m_kernel_dsyms_no_binaries; // list of kernel + // dsyms with no + // binaries next to + // them + KernelBinaryCollection m_kernel_dsyms_yaas; // list of kernel + // .dSYM.yaa files + lldb_private::LazyBool m_ios_debug_session; PlatformDarwinKernel(const PlatformDarwinKernel &) = delete; diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSXProperties.td b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSXProperties.td index 07e4e3e81d8c5..39e9641daae04 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSXProperties.td +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSXProperties.td @@ -1,10 +1,6 @@ include "../../../../include/lldb/Core/PropertiesBase.td" let Definition = "platformdarwinkernel" in { - def SearchForKexts: Property<"search-locally-for-kexts", "Boolean">, - Global, - DefaultTrue, - Desc<"Automatically search for kexts on the local system when doing kernel debugging.">; def KextDirectories: Property<"kext-directories", "FileSpecList">, DefaultStringValue<"">, Desc<"Directories/KDKs to search for kexts in when starting a kernel debug session.">; From eaf9f9dcaf772fdaf4e5c4acccd269b5114184d2 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Thu, 1 Oct 2020 18:04:11 -0700 Subject: [PATCH 065/234] Thicken generic metatypes in BindGenericTypeParameters(). Generic metatypes should always be thick and TypeRef::subst() performs the exact same transformation. --- .../SwiftLanguageRuntimeDynamicTypeResolution.cpp | 15 +++++++++++++++ .../TestSwiftExpressionsInClassFunctions.py | 9 +++++++++ 2 files changed, 24 insertions(+) diff --git a/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp index 3a39fb6566741..57daab32fdb01 100644 --- a/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -1434,6 +1434,21 @@ SwiftLanguageRuntimeImpl::BindGenericTypeParameters(StackFrame &stack_frame, return type; }); + // Thicken generic metatypes. Once substituted, they should always + // be thick. TypeRef::subst() does the same transformation. + target_swift_type = + target_swift_type.transform([](swift::Type type) -> swift::Type { + using namespace swift; + const auto thin = MetatypeRepresentation::Thin; + const auto thick = MetatypeRepresentation::Thick; + if (auto *metatype = dyn_cast(type.getPointer())) + if (metatype->hasRepresentation() && + metatype->getRepresentation() == thin && + metatype->getInstanceType()->hasTypeParameter()) + return MetatypeType::get(metatype->getInstanceType(), thick); + return type; + }); + while (target_swift_type->hasOpaqueArchetype()) { auto old_type = target_swift_type; target_swift_type = target_swift_type.subst( diff --git a/lldb/test/API/lang/swift/expression/static/TestSwiftExpressionsInClassFunctions.py b/lldb/test/API/lang/swift/expression/static/TestSwiftExpressionsInClassFunctions.py index 2af5dfae8d16c..07378b9d2c869 100644 --- a/lldb/test/API/lang/swift/expression/static/TestSwiftExpressionsInClassFunctions.py +++ b/lldb/test/API/lang/swift/expression/static/TestSwiftExpressionsInClassFunctions.py @@ -76,5 +76,14 @@ def test_expressions_in_class_functions(self): self.check_expression("i", str(i), False) if i == 6: self.check_expression("self", "a.H") + frame = threads[0].GetFrameAtIndex(0) + lldbutil.check_variable(self, frame.FindVariable("self"), + use_dynamic=True, + # FIXME: This should be '@thick a.H.Type' + # but valobj.GetDynamicValue(lldb.eDynamicCanRunTarget) + # doesn't seem to do its job. + # rdar://problem/69889462 + typename='@thin a.H<τ_0_0>.Type') + self.runCmd("continue") From 8863d99f7d5550cafab90e28a9e2cba67940bb9c Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Fri, 2 Oct 2020 12:12:19 -0700 Subject: [PATCH 066/234] Add regression test, and actually fix --- lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp | 8 ++------ lldb/test/API/lang/swift/printdecl/TestSwiftTypeLookup.py | 6 ++++++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index 21f08fcbef743..0f870f20e8fe1 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -7915,8 +7915,7 @@ void SwiftASTContext::DumpTypeDescription(opaque_compiler_type_t type, bool print_help_if_available, bool print_extensions_if_available, lldb::DescriptionLevel level) { - llvm::SmallVector buf; - llvm::raw_svector_ostream llvm_ostrm(buf); + const auto initial_written_bytes = s->GetWrittenBytes(); if (type) { swift::CanType swift_can_type(GetCanonicalSwiftType(type)); @@ -8082,11 +8081,8 @@ void SwiftASTContext::DumpTypeDescription(opaque_compiler_type_t type, } } - if (buf.size() > 0) { - s->Write(buf.data(), buf.size()); - } else { + if (s->GetWrittenBytes() == initial_written_bytes) s->Printf(""); - } } TypeSP SwiftASTContext::GetCachedType(ConstString mangled) { diff --git a/lldb/test/API/lang/swift/printdecl/TestSwiftTypeLookup.py b/lldb/test/API/lang/swift/printdecl/TestSwiftTypeLookup.py index 20fc2139c5f05..b6c33ecfc9d0f 100644 --- a/lldb/test/API/lang/swift/printdecl/TestSwiftTypeLookup.py +++ b/lldb/test/API/lang/swift/printdecl/TestSwiftTypeLookup.py @@ -56,6 +56,12 @@ def test_swift_type_lookup(self): 'func bar()', 'var b']) + # Regression test. Ensure "" is not output. + self.expect( + "type lookup String", + matching=False, + substrs=[""]) + # check that specifiers are honored # self.expect('type lookup class Cla1', substrs=['class Cla1 {']) # self.expect('type lookup struct Cla1', substrs=['class Cla1 {'], matching=False, error=True) From 593758e7ff9ca15da286ef6c3683afa1d8e70904 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 2 Oct 2020 12:11:35 -0700 Subject: [PATCH 067/234] Implement TypeSystemSwiftTypeRef::GetTypeBitAlign() (NFC) This also fixes a pretty serious bit/byte bug in SwiftASTContext::GetTypeBitAlign() that go uncovered by the new validation assertion. --- .../lldb/Target/SwiftLanguageRuntime.h | 3 +- .../TypeSystem/Swift/SwiftASTContext.cpp | 6 +- .../Swift/TypeSystemSwiftTypeRef.cpp | 83 ++++++++++++++----- .../TypeSystem/Swift/TypeSystemSwiftTypeRef.h | 3 + lldb/source/Target/SwiftLanguageRuntime.cpp | 8 +- ...ftLanguageRuntimeDynamicTypeResolution.cpp | 7 +- lldb/source/Target/SwiftLanguageRuntimeImpl.h | 3 +- 7 files changed, 81 insertions(+), 32 deletions(-) diff --git a/lldb/include/lldb/Target/SwiftLanguageRuntime.h b/lldb/include/lldb/Target/SwiftLanguageRuntime.h index f8e1dd1ecc277..b6f9f5b0a6d18 100644 --- a/lldb/include/lldb/Target/SwiftLanguageRuntime.h +++ b/lldb/include/lldb/Target/SwiftLanguageRuntime.h @@ -260,7 +260,8 @@ class SwiftLanguageRuntime : public LanguageRuntime { llvm::Optional GetByteStride(CompilerType type); /// Ask Remote mirrors for the alignment of a Swift type. - llvm::Optional GetBitAlignment(CompilerType type); + llvm::Optional GetBitAlignment(CompilerType type, + ExecutionContextScope *exe_scope); /// Release the RemoteASTContext associated with the given swift::ASTContext. /// Note that a RemoteASTContext must be destroyed before its associated diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index 6debdf242ad2b..dba55ef14401e 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -6054,6 +6054,8 @@ SwiftASTContext::GetTypeBitAlign(opaque_compiler_type_t type, exe_scope->CalculateExecutionContext(exe_ctx); auto swift_scratch_ctx_lock = SwiftASTContextLock(&exe_ctx); CompilerType bound_type = BindGenericTypeParameters({this, type}, exe_scope); + if (bound_type.GetOpaqueQualType() == type) + return {}; // Note thay the bound type may be in a different AST context. return bound_type.GetTypeBitAlign(exe_scope); } @@ -6061,13 +6063,13 @@ SwiftASTContext::GetTypeBitAlign(opaque_compiler_type_t type, const swift::irgen::FixedTypeInfo *fixed_type_info = GetSwiftFixedTypeInfo(type); if (fixed_type_info) - return fixed_type_info->getFixedAlignment().getValue(); + return fixed_type_info->getFixedAlignment().getValue() * 8; // Ask the dynamic type system. if (!exe_scope) return {}; if (auto *runtime = SwiftLanguageRuntime::Get(exe_scope->CalculateProcess())) - return runtime->GetBitAlignment({this, type}); + return runtime->GetBitAlignment({this, type}, exe_scope); return {}; } diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index f29c9130bfc39..2cf9577a982cc 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1033,6 +1033,30 @@ DWARFASTParser *TypeSystemSwiftTypeRef::GetDWARFParser() { return m_swift_ast_context->GetDWARFParser(); } +TypeSP TypeSystemSwiftTypeRef::LookupTypeInModule( + lldb::opaque_compiler_type_t opaque_type) { + auto *M = GetModule(); + if (!M) + return {}; + swift::Demangle::Demangler dem; + auto *node = GetDemangledType(dem, AsMangledName(opaque_type)); + auto module_type = GetNominal(dem, node); + if (!module_type) + return {}; + // DW_AT_linkage_name is not part of the accelerator table, so + // we need to search by module+name. + ConstString module(module_type->first); + ConstString type(module_type->second); + llvm::SmallVector decl_context; + decl_context.push_back({CompilerContextKind::Module, module}); + decl_context.push_back({CompilerContextKind::AnyType, type}); + llvm::DenseSet searched_symbol_files; + TypeMap types; + M->FindTypes(decl_context, TypeSystemSwift::GetSupportedLanguagesForTypes(), + searched_symbol_files, types); + return types.Empty() ? TypeSP() : types.GetTypeAtIndex(0); +} + // Tests #ifndef NDEBUG @@ -1681,27 +1705,8 @@ TypeSystemSwiftTypeRef::GetBitSize(opaque_compiler_type_t type, // If there is no process, we can still try to get the static size // information out of DWARF. Because it is stored in the Type // object we need to look that up by name again. - if (auto *M = GetModule()) { - swift::Demangle::Demangler dem; - auto node = GetDemangledType(dem, AsMangledName(type)); - if (auto module_type = GetNominal(dem, node)) { - // DW_AT_linkage_name is not part of the accelerator table, so - // we need to search by module+name. - ConstString module(module_type->first); - ConstString type(module_type->second); - llvm::SmallVector decl_context; - decl_context.push_back({CompilerContextKind::Module, module}); - decl_context.push_back({CompilerContextKind::AnyType, type}); - llvm::DenseSet searched_symbol_files; - TypeMap types; - M->FindTypes(decl_context, - TypeSystemSwift::GetSupportedLanguagesForTypes(), - searched_symbol_files, types); - if (!types.Empty()) - if (auto type = types.GetTypeAtIndex(0)) - return type->GetByteSize(nullptr); - } - } + if (TypeSP type_sp = LookupTypeInModule(type)) + return type_sp->GetByteSize(exe_scope); LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), "Couldn't compute size of type %s without a process.", AsMangledName(type)); @@ -1956,7 +1961,41 @@ bool TypeSystemSwiftTypeRef::IsPointerOrReferenceType( llvm::Optional TypeSystemSwiftTypeRef::GetTypeBitAlign(opaque_compiler_type_t type, ExecutionContextScope *exe_scope) { - return m_swift_ast_context->GetTypeBitAlign(ReconstructType(type), exe_scope); + auto impl = [&]() -> llvm::Optional { + // Clang types can be resolved even without a process. + if (CompilerType clang_type = GetAsClangTypeOrNull(type)) { + // Swift doesn't know pointers: return the size alignment of the + // object pointer instead of the underlying object. + if (Flags(clang_type.GetTypeInfo()).AllSet(eTypeIsObjC | eTypeIsClass)) + return GetPointerByteSize() * 8; + return clang_type.GetTypeBitAlign(exe_scope); + } + if (!exe_scope) { + LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), + "Couldn't compute alignment of type %s without an execution " + "context.", + AsMangledName(type)); + return {}; + } + if (auto *runtime = + SwiftLanguageRuntime::Get(exe_scope->CalculateProcess())) + return runtime->GetBitAlignment({this, type}, exe_scope); + + // If there is no process, we can still try to get the static + // alignment information out of DWARF. Because it is stored in the + // Type object we need to look that up by name again. + if (TypeSP type_sp = LookupTypeInModule(type)) + return type_sp->GetLayoutCompilerType().GetTypeBitAlign(exe_scope); + LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), + "Couldn't compute alignment of type %s without a process.", + AsMangledName(type)); + return {}; + }; + if (exe_scope && exe_scope->CalculateProcess()) + VALIDATE_AND_RETURN(impl, GetTypeBitAlign, type, + (ReconstructType(type), exe_scope)); + else + return impl(); } bool TypeSystemSwiftTypeRef::IsTypedefType(opaque_compiler_type_t type) { return m_swift_ast_context->IsTypedefType(ReconstructType(type)); diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h index 443ff60000d05..f10f51d8e2d53 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h @@ -278,6 +278,9 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { /// Cast \p opaque_type as a mangled name. const char *AsMangledName(lldb::opaque_compiler_type_t type); + /// Lookup a type in the debug info. + lldb::TypeSP LookupTypeInModule(lldb::opaque_compiler_type_t type); + /// Demangle the mangled name of the canonical type of \p type and /// drill into the Global(TypeMangling(Type())). /// diff --git a/lldb/source/Target/SwiftLanguageRuntime.cpp b/lldb/source/Target/SwiftLanguageRuntime.cpp index e33f2a100d622..eae0cda89c8f7 100644 --- a/lldb/source/Target/SwiftLanguageRuntime.cpp +++ b/lldb/source/Target/SwiftLanguageRuntime.cpp @@ -270,7 +270,8 @@ class SwiftLanguageRuntimeStub { return {}; } - llvm::Optional GetBitAlignment(CompilerType type) { + llvm::Optional GetBitAlignment(CompilerType type, + ExecutionContextScope *exe_scope) { STUB_LOG(); return {}; } @@ -2131,8 +2132,9 @@ SwiftLanguageRuntime::GetByteStride(CompilerType type) { } llvm::Optional -SwiftLanguageRuntime::GetBitAlignment(CompilerType type) { - FORWARD(GetBitAlignment, type); +SwiftLanguageRuntime::GetBitAlignment(CompilerType type, + ExecutionContextScope *exe_scope) { + FORWARD(GetBitAlignment, type, exe_scope); } bool SwiftLanguageRuntime::IsValidErrorValue(ValueObject &in_value) { diff --git a/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp index 57daab32fdb01..28b1a2437e4d4 100644 --- a/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -2181,9 +2181,10 @@ SwiftLanguageRuntimeImpl::GetByteStride(CompilerType type) { } llvm::Optional -SwiftLanguageRuntimeImpl::GetBitAlignment(CompilerType type) { - if (auto *type_info = GetTypeInfo(type, nullptr)) - return type_info->getAlignment(); +SwiftLanguageRuntimeImpl::GetBitAlignment(CompilerType type, + ExecutionContextScope *exe_scope) { + if (auto *type_info = GetTypeInfo(type, exe_scope)) + return type_info->getAlignment() * 8; return {}; } diff --git a/lldb/source/Target/SwiftLanguageRuntimeImpl.h b/lldb/source/Target/SwiftLanguageRuntimeImpl.h index 834eb6f634925..babab68b1891d 100644 --- a/lldb/source/Target/SwiftLanguageRuntimeImpl.h +++ b/lldb/source/Target/SwiftLanguageRuntimeImpl.h @@ -92,7 +92,8 @@ class SwiftLanguageRuntimeImpl { llvm::Optional GetByteStride(CompilerType type); /// Ask Remote mirrors for the alignment of a Swift type. - llvm::Optional GetBitAlignment(CompilerType type); + llvm::Optional GetBitAlignment(CompilerType type, + ExecutionContextScope *exe_scope); SwiftLanguageRuntime::MetadataPromiseSP GetMetadataPromise(lldb::addr_t addr, ValueObject &for_object); From f80e6d63423008ca24aa5d5d9939d0e35a2d7d02 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 5 Oct 2020 13:38:45 +0200 Subject: [PATCH 068/234] ReleaseNotes: mention the machine outliner for ARM As suggested by Yvan. --- llvm/docs/ReleaseNotes.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst index a1f00a1a3b3ad..f5f50cbf01587 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -165,6 +165,9 @@ Changes to the ARM Backend * Added support for Cortex-M55, Cortex-A77, Cortex-A78 and Cortex-X1 cores. +* The Machine Outliner is now supported for ARM and Thumb2, it is not + turned on by default and can be enabled with the ``-moutline`` clang flag. + Changes to the PowerPC Target ----------------------------- From 187a46e14799f0aaa881f8bfd4406a65a822a7ef Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Mon, 5 Oct 2020 13:18:02 -0700 Subject: [PATCH 069/234] [lldb] Hoist --swift-compiler argument out of LLDB_TEST_COMMON_ARGS (NFC) Store the swift compiler for testing in the lit config instead of passing it through the LLDB_TEST_COMMON_ARGS so that we can configure it in lit.site.cfg.py if we so desire. --- lldb/test/API/CMakeLists.txt | 6 ++---- lldb/test/API/lit.cfg.py | 3 +++ lldb/test/API/lit.site.cfg.py.in | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lldb/test/API/CMakeLists.txt b/lldb/test/API/CMakeLists.txt index 0507898944073..724196258a02f 100644 --- a/lldb/test/API/CMakeLists.txt +++ b/lldb/test/API/CMakeLists.txt @@ -32,13 +32,11 @@ option(LLDB_TEST_SWIFT "Use in-tree swift when testing lldb" On) if(LLDB_TEST_SWIFT) set(LLDB_SWIFTC ${SWIFT_BINARY_DIR}/bin/swiftc CACHE STRING "Path to swift compiler") set(LLDB_SWIFT_LIBS ${SWIFT_LIBRARY_DIR}/swift CACHE STRING "Path to swift libraries") + # Prefer the just-built stdlib over the system one. set(SWIFT_TEST_ARGS - --swift-compiler ${LLDB_SWIFTC} - # Prefer the just-built stdlib over the system one. --inferior-env "DYLD_LIBRARY_PATH=\\\"${LLDB_SWIFT_LIBS}/macosx\\\"" --inferior-env "LD_LIBRARY_PATH=\\\"${LLDB_SWIFT_LIBS}/${CMAKE_SYSTEM_PROCESSOR}\\\"" - --inferior-env "SIMCTL_CHILD_DYLD_LIBRARY_PATH=\\\"${LLDB_SWIFT_LIBS}/macosx\\\"" - ) + --inferior-env "SIMCTL_CHILD_DYLD_LIBRARY_PATH=\\\"${LLDB_SWIFT_LIBS}/macosx\\\"") endif() # END - Swift Mods diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py index a4d4d83fd366d..45e3396f07d03 100644 --- a/lldb/test/API/lit.cfg.py +++ b/lldb/test/API/lit.cfg.py @@ -194,6 +194,9 @@ def delete_module_cache(path): if is_configured('test_compiler'): dotest_cmd += ['--compiler', config.test_compiler] +if is_configured('test_swift_compiler'): + dotest_cmd += ['--swift-compiler', config.test_swift_compiler] + if is_configured('dsymutil'): dotest_cmd += ['--dsymutil', config.dsymutil] diff --git a/lldb/test/API/lit.site.cfg.py.in b/lldb/test/API/lit.site.cfg.py.in index ce2ff8e21d0b9..e4a5bdfb17434 100644 --- a/lldb/test/API/lit.site.cfg.py.in +++ b/lldb/test/API/lit.site.cfg.py.in @@ -29,6 +29,7 @@ config.enabled_plugins = [] config.lldb_executable = '@LLDB_TEST_EXECUTABLE@' config.test_arch = '@LLDB_TEST_ARCH@' config.test_compiler = '@LLDB_TEST_COMPILER@' +config.test_swift_compiler = '@LLDB_SWIFTC@' config.dsymutil = '@LLDB_TEST_DSYMUTIL@' config.filecheck = '@LLDB_TEST_FILECHECK@' config.yaml2obj = '@LLDB_TEST_YAML2OBJ@' From 8ecc9e713c55e192a4e72d8334a56e9bfd62ef60 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Mon, 28 Sep 2020 10:28:29 -0700 Subject: [PATCH 070/234] Revert "Revert "Add the ability to write target stop-hooks using the ScriptInterpreter."" This reverts commit f775fe59640a2e837ad059a8f40e26989d4f9831. I fixed a return type error in the original patch that was causing a test failure. Also added a REQUIRES: python to the shell test so we'll skip this for people who build lldb w/o Python. Also added another test for the error printing. (cherry picked from commit 1b1d9815987a753f2f3524cfad050b85972dae5b) --- lldb/bindings/python/python-swigsafecast.swig | 7 + lldb/bindings/python/python-wrapper.swig | 121 +++++++ lldb/docs/use/python-reference.rst | 46 +++ .../lldb/Interpreter/ScriptInterpreter.h | 17 + lldb/include/lldb/Symbol/SymbolContext.h | 2 +- lldb/include/lldb/Target/Target.h | 86 ++++- lldb/source/Commands/CommandObjectTarget.cpp | 113 +++++- lldb/source/Commands/Options.td | 12 +- .../Python/ScriptInterpreterPython.cpp | 64 ++++ .../Python/ScriptInterpreterPythonImpl.h | 8 + lldb/source/Symbol/SymbolContext.cpp | 8 +- lldb/source/Target/Target.cpp | 338 +++++++++++++----- .../target/stop-hooks/TestStopHookScripted.py | 146 ++++++++ .../target/stop-hooks/TestStopHooks.py | 12 +- .../API/commands/target/stop-hooks/main.c | 3 +- .../commands/target/stop-hooks/stop_hook.py | 49 +++ lldb/test/Shell/Commands/Inputs/stop_hook.py | 10 + .../Commands/command-stop-hook-output.test | 19 + .../Python/PythonTestSuite.cpp | 14 + 19 files changed, 943 insertions(+), 132 deletions(-) create mode 100644 lldb/test/API/commands/target/stop-hooks/TestStopHookScripted.py create mode 100644 lldb/test/API/commands/target/stop-hooks/stop_hook.py create mode 100644 lldb/test/Shell/Commands/Inputs/stop_hook.py create mode 100644 lldb/test/Shell/Commands/command-stop-hook-output.test diff --git a/lldb/bindings/python/python-swigsafecast.swig b/lldb/bindings/python/python-swigsafecast.swig index d5cafbfa67cb2..091fc29b1057d 100644 --- a/lldb/bindings/python/python-swigsafecast.swig +++ b/lldb/bindings/python/python-swigsafecast.swig @@ -152,3 +152,10 @@ SBTypeToSWIGWrapper (lldb::SBSymbolContext* sym_ctx_sb) { return SWIG_NewPointerObj((void *) sym_ctx_sb, SWIGTYPE_p_lldb__SBSymbolContext, 0); } + +template <> +PyObject* +SBTypeToSWIGWrapper (lldb::SBStream* stream_sb) +{ + return SWIG_NewPointerObj((void *) stream_sb, SWIGTYPE_p_lldb__SBStream, 0); +} diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig index 516590ed57713..c00deba6073b4 100644 --- a/lldb/bindings/python/python-wrapper.swig +++ b/lldb/bindings/python/python-wrapper.swig @@ -468,6 +468,127 @@ LLDBSwigPythonCallBreakpointResolver return ret_val; } +SWIGEXPORT void * +LLDBSwigPythonCreateScriptedStopHook +( + lldb::TargetSP target_sp, + const char *python_class_name, + const char *session_dictionary_name, + lldb_private::StructuredDataImpl *args_impl, + Status &error +) +{ + if (python_class_name == NULL || python_class_name[0] == '\0') { + error.SetErrorString("Empty class name."); + Py_RETURN_NONE; + } + if (!session_dictionary_name) { + error.SetErrorString("No session dictionary"); + Py_RETURN_NONE; + } + + PyErr_Cleaner py_err_cleaner(true); + + auto dict = + PythonModule::MainModule().ResolveName( + session_dictionary_name); + auto pfunc = + PythonObject::ResolveNameWithDictionary( + python_class_name, dict); + + if (!pfunc.IsAllocated()) { + error.SetErrorStringWithFormat("Could not find class: %s.", + python_class_name); + return nullptr; + } + + lldb::SBTarget *target_val + = new lldb::SBTarget(target_sp); + + PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(target_val)); + + lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl); + PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value)); + + PythonObject result = pfunc(target_arg, args_arg, dict); + + if (result.IsAllocated()) + { + // Check that the handle_stop callback is defined: + auto callback_func = result.ResolveName("handle_stop"); + if (callback_func.IsAllocated()) { + if (auto args_info = callback_func.GetArgInfo()) { + size_t num_args = (*args_info).max_positional_args; + if (num_args != 2) { + error.SetErrorStringWithFormat("Wrong number of args for " + "handle_stop callback, should be 2 (excluding self), got: %d", + num_args); + Py_RETURN_NONE; + } else + return result.release(); + } else { + error.SetErrorString("Couldn't get num arguments for handle_stop " + "callback."); + Py_RETURN_NONE; + } + return result.release(); + } + else { + error.SetErrorStringWithFormat("Class \"%s\" is missing the required " + "handle_stop callback.", + python_class_name); + result.release(); + } + } + Py_RETURN_NONE; +} + +SWIGEXPORT bool +LLDBSwigPythonStopHookCallHandleStop +( + void *implementor, + lldb::ExecutionContextRefSP exc_ctx_sp, + lldb::StreamSP stream +) +{ + // handle_stop will return a bool with the meaning "should_stop"... + // If you return nothing we'll assume we are going to stop. + // Also any errors should return true, since we should stop on error. + + PyErr_Cleaner py_err_cleaner(false); + PythonObject self(PyRefType::Borrowed, static_cast(implementor)); + auto pfunc = self.ResolveName("handle_stop"); + + if (!pfunc.IsAllocated()) + return true; + + PythonObject result; + lldb::SBExecutionContext sb_exc_ctx(exc_ctx_sp); + PythonObject exc_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_exc_ctx)); + lldb::SBStream sb_stream; + PythonObject sb_stream_arg(PyRefType::Owned, + SBTypeToSWIGWrapper(sb_stream)); + result = pfunc(exc_ctx_arg, sb_stream_arg); + + if (PyErr_Occurred()) + { + stream->PutCString("Python error occurred handling stop-hook."); + PyErr_Print(); + PyErr_Clear(); + return true; + } + + // Now add the result to the output stream. SBStream only + // makes an internally help StreamString which I can't interpose, so I + // have to copy it over here. + stream->PutCString(sb_stream.GetData()); + + if (result.get() == Py_False) + return false; + else + return true; +} + // wrapper that calls an optional instance member of an object taking no arguments static PyObject* LLDBSwigPython_CallOptionalMember diff --git a/lldb/docs/use/python-reference.rst b/lldb/docs/use/python-reference.rst index 8c76ef1a08307..60474c94f1850 100644 --- a/lldb/docs/use/python-reference.rst +++ b/lldb/docs/use/python-reference.rst @@ -819,3 +819,49 @@ When the program is stopped at the beginning of the 'read' function in libc, we frame #0: 0x00007fff06013ca0 libsystem_kernel.dylib`read (lldb) frame variable (int) fd = 3 + + Writing Target Stop-Hooks in Python: + ------------------------------------ + + Stop hooks fire whenever the process stops just before control is returned to the + user. Stop hooks can either be a set of lldb command-line commands, or can + be implemented by a suitably defined Python class. The Python based stop-hooks + can also be passed as set of -key -value pairs when they are added, and those + will get packaged up into a SBStructuredData Dictionary and passed to the + constructor of the Python object managing the stop hook. This allows for + parametrization of the stop hooks. + + To add a Python-based stop hook, first define a class with the following methods: + ++--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ +| Name | Arguments | Description | ++--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ +| **__init__** | **target: lldb.SBTarget** | This is the constructor for the new stop-hook. | +| | **extra_args: lldb.SBStructuredData** | | +| | | | +| | | **target** is the SBTarget to which the stop hook is added. | +| | | | +| | | **extra_args** is an SBStructuredData object that the user can pass in when creating instances of this | +| | | breakpoint. It is not required, but allows for reuse of stop-hook classes. | ++--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ +| **handle_stop** | **exe_ctx: lldb.SBExecutionContext** | This is the called when the target stops. | +| | **stream: lldb.SBStream** | | +| | | **exe_ctx** argument will be filled with the current stop point for which the stop hook is | +| | | being evaluated. | +| | | | +| | | **stream** an lldb.SBStream, anything written to this stream will be written to the debugger console. | +| | | | +| | | The return value is a "Should Stop" vote from this thread. If the method returns either True or no return | +| | | this thread votes to stop. If it returns False, then the thread votes to continue after all the stop-hooks | +| | | are evaluated. | +| | | Note, the --auto-continue flag to 'target stop-hook add' overrides a True return value from the method. | ++--------------------+---------------------------------------+------------------------------------------------------------------------------------------------------------------+ + +To use this class in lldb, run the command: + +:: + + (lldb) command script import MyModule.py + (lldb) target stop-hook add -P MyModule.MyStopHook -k first -v 1 -k second -v 2 + +where MyModule.py is the file containing the class definition MyStopHook. diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index 491923e6a6c4f..c38786fd50d42 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -298,6 +298,23 @@ class ScriptInterpreter : public PluginInterface { return lldb::eSearchDepthModule; } + virtual StructuredData::GenericSP + CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name, + StructuredDataImpl *args_data, Status &error) { + error.SetErrorString("Creating scripted stop-hooks with the current " + "script interpreter is not supported."); + return StructuredData::GenericSP(); + } + + // This dispatches to the handle_stop method of the stop-hook class. It + // returns a "should_stop" bool. + virtual bool + ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp, + ExecutionContext &exc_ctx, + lldb::StreamSP stream_sp) { + return true; + } + virtual StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) { return StructuredData::ObjectSP(); diff --git a/lldb/include/lldb/Symbol/SymbolContext.h b/lldb/include/lldb/Symbol/SymbolContext.h index cc49ce51c7139..0f99364596c27 100644 --- a/lldb/include/lldb/Symbol/SymbolContext.h +++ b/lldb/include/lldb/Symbol/SymbolContext.h @@ -340,7 +340,7 @@ class SymbolContextSpecifier { void Clear(); - bool SymbolContextMatches(SymbolContext &sc); + bool SymbolContextMatches(const SymbolContext &sc); bool AddressMatches(lldb::addr_t addr); diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 92904682ffb63..94c6ebeac10da 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -28,6 +28,7 @@ #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/PathMappingList.h" #include "lldb/Target/SectionLoadHistory.h" +#include "lldb/Target/ThreadSpec.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/LLDBAssert.h" @@ -508,6 +509,8 @@ class Target : public std::enable_shared_from_this, static void SetDefaultArchitecture(const ArchSpec &arch); + bool IsDummyTarget() const { return m_is_dummy_target; } + /// Find a binary on the system and return its Module, /// or return an existing Module that is already in the Target. /// @@ -1139,23 +1142,27 @@ class Target : public std::enable_shared_from_this, class StopHook : public UserID { public: StopHook(const StopHook &rhs); + virtual ~StopHook() = default; - ~StopHook(); - - StringList *GetCommandPointer() { return &m_commands; } - - const StringList &GetCommands() { return m_commands; } + enum class StopHookKind : uint32_t { CommandBased = 0, ScriptBased }; lldb::TargetSP &GetTarget() { return m_target_sp; } - void SetCommands(StringList &in_commands) { m_commands = in_commands; } - // Set the specifier. The stop hook will own the specifier, and is // responsible for deleting it when we're done. void SetSpecifier(SymbolContextSpecifier *specifier); SymbolContextSpecifier *GetSpecifier() { return m_specifier_sp.get(); } + bool ExecutionContextPasses(const ExecutionContext &exe_ctx); + + // Called on stop, this gets passed the ExecutionContext for each "stop + // with a reason" thread. It should add to the stream whatever text it + // wants to show the user, and return False to indicate it wants the target + // not to stop. + virtual bool HandleStop(ExecutionContext &exe_ctx, + lldb::StreamSP output) = 0; + // Set the Thread Specifier. The stop hook will own the thread specifier, // and is responsible for deleting it when we're done. void SetThreadSpecifier(ThreadSpec *specifier); @@ -1173,26 +1180,79 @@ class Target : public std::enable_shared_from_this, bool GetAutoContinue() const { return m_auto_continue; } void GetDescription(Stream *s, lldb::DescriptionLevel level) const; + virtual void GetSubclassDescription(Stream *s, + lldb::DescriptionLevel level) const = 0; - private: + protected: lldb::TargetSP m_target_sp; - StringList m_commands; lldb::SymbolContextSpecifierSP m_specifier_sp; std::unique_ptr m_thread_spec_up; bool m_active = true; bool m_auto_continue = false; + StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid); + }; + + class StopHookCommandLine : public StopHook { + public: + virtual ~StopHookCommandLine() = default; + + StringList &GetCommands() { return m_commands; } + void SetActionFromString(const std::string &strings); + void SetActionFromStrings(const std::vector &strings); + + bool HandleStop(ExecutionContext &exc_ctx, + lldb::StreamSP output_sp) override; + void GetSubclassDescription(Stream *s, + lldb::DescriptionLevel level) const override; + + private: + StringList m_commands; // Use CreateStopHook to make a new empty stop hook. The GetCommandPointer // and fill it with commands, and SetSpecifier to set the specifier shared // pointer (can be null, that will match anything.) - StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid); + StopHookCommandLine(lldb::TargetSP target_sp, lldb::user_id_t uid) + : StopHook(target_sp, uid) {} + friend class Target; + }; + + class StopHookScripted : public StopHook { + public: + virtual ~StopHookScripted() = default; + bool HandleStop(ExecutionContext &exc_ctx, lldb::StreamSP output) override; + + Status SetScriptCallback(std::string class_name, + StructuredData::ObjectSP extra_args_sp); + + void GetSubclassDescription(Stream *s, + lldb::DescriptionLevel level) const override; + + private: + std::string m_class_name; + /// This holds the dictionary of keys & values that can be used to + /// parametrize any given callback's behavior. + StructuredDataImpl *m_extra_args; // We own this structured data, + // but the SD itself manages the UP. + /// This holds the python callback object. + StructuredData::GenericSP m_implementation_sp; + + /// Use CreateStopHook to make a new empty stop hook. The GetCommandPointer + /// and fill it with commands, and SetSpecifier to set the specifier shared + /// pointer (can be null, that will match anything.) + StopHookScripted(lldb::TargetSP target_sp, lldb::user_id_t uid) + : StopHook(target_sp, uid) {} friend class Target; }; + typedef std::shared_ptr StopHookSP; - // Add an empty stop hook to the Target's stop hook list, and returns a - // shared pointer to it in new_hook. Returns the id of the new hook. - StopHookSP CreateStopHook(); + /// Add an empty stop hook to the Target's stop hook list, and returns a + /// shared pointer to it in new_hook. Returns the id of the new hook. + StopHookSP CreateStopHook(StopHook::StopHookKind kind); + + /// If you tried to create a stop hook, and that failed, call this to + /// remove the stop hook, as it will also reset the stop hook counter. + void UndoCreateStopHook(lldb::user_id_t uid); void RunStopHooks(); diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index c6a7dd3c77baa..cbfebbfee0fd7 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -24,6 +24,7 @@ #include "lldb/Interpreter/OptionGroupFile.h" #include "lldb/Interpreter/OptionGroupFormat.h" #include "lldb/Interpreter/OptionGroupPlatform.h" +#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h" #include "lldb/Interpreter/OptionGroupString.h" #include "lldb/Interpreter/OptionGroupUInt64.h" #include "lldb/Interpreter/OptionGroupUUID.h" @@ -4414,10 +4415,10 @@ class CommandObjectTargetSymbols : public CommandObjectMultiword { class CommandObjectTargetStopHookAdd : public CommandObjectParsed, public IOHandlerDelegateMultiline { public: - class CommandOptions : public Options { + class CommandOptions : public OptionGroup { public: CommandOptions() - : Options(), m_line_start(0), m_line_end(UINT_MAX), + : OptionGroup(), m_line_start(0), m_line_end(UINT_MAX), m_func_name_type_mask(eFunctionNameTypeAuto), m_sym_ctx_specified(false), m_thread_specified(false), m_use_one_liner(false), m_one_liner() {} @@ -4431,7 +4432,8 @@ class CommandObjectTargetStopHookAdd : public CommandObjectParsed, Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override { Status error; - const int short_option = m_getopt_table[option_idx].val; + const int short_option = + g_target_stop_hook_add_options[option_idx].short_option; switch (short_option) { case 'c': @@ -4561,20 +4563,75 @@ class CommandObjectTargetStopHookAdd : public CommandObjectParsed, // Instance variables to hold the values for one_liner options. bool m_use_one_liner; std::vector m_one_liner; + bool m_auto_continue; }; CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "target stop-hook add", - "Add a hook to be executed when the target stops.", + "Add a hook to be executed when the target stops." + "The hook can either be a list of commands or an " + "appropriately defined Python class. You can also " + "add filters so the hook only runs a certain stop " + "points.", "target stop-hook add"), IOHandlerDelegateMultiline("DONE", IOHandlerDelegate::Completion::LLDBCommand), - m_options() {} + m_options(), m_python_class_options("scripted stop-hook", true, 'P') { + SetHelpLong( + R"( +Command Based stop-hooks: +------------------------- + Stop hooks can run a list of lldb commands by providing one or more + --one-line-command options. The commands will get run in the order they are + added. Or you can provide no commands, in which case you will enter a + command editor where you can enter the commands to be run. + +Python Based Stop Hooks: +------------------------ + Stop hooks can be implemented with a suitably defined Python class, whose name + is passed in the --python-class option. + + When the stop hook is added, the class is initialized by calling: + + def __init__(self, target, extra_args, dict): + + target: The target that the stop hook is being added to. + extra_args: An SBStructuredData Dictionary filled with the -key -value + option pairs passed to the command. + dict: An implementation detail provided by lldb. + + Then when the stop-hook triggers, lldb will run the 'handle_stop' method. + The method has the signature: + + def handle_stop(self, exe_ctx, stream): + + exe_ctx: An SBExecutionContext for the thread that has stopped. + stream: An SBStream, anything written to this stream will be printed in the + the stop message when the process stops. + + Return Value: The method returns "should_stop". If should_stop is false + from all the stop hook executions on threads that stopped + with a reason, then the process will continue. Note that this + will happen only after all the stop hooks are run. + +Filter Options: +--------------- + Stop hooks can be set to always run, or to only run when the stopped thread + matches the filter options passed on the command line. The available filter + options include a shared library or a thread or queue specification, + a line range in a source file, a function name or a class name. + )"); + m_all_options.Append(&m_python_class_options, + LLDB_OPT_SET_1 | LLDB_OPT_SET_2, + LLDB_OPT_SET_FROM_TO(4, 6)); + m_all_options.Append(&m_options); + m_all_options.Finalize(); + } ~CommandObjectTargetStopHookAdd() override = default; - Options *GetOptions() override { return &m_options; } + Options *GetOptions() override { return &m_all_options; } protected: void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { @@ -4598,10 +4655,15 @@ class CommandObjectTargetStopHookAdd : public CommandObjectParsed, error_sp->Flush(); } Target *target = GetDebugger().GetSelectedTarget().get(); - if (target) - target->RemoveStopHookByID(m_stop_hook_sp->GetID()); + if (target) { + target->UndoCreateStopHook(m_stop_hook_sp->GetID()); + } } else { - m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line); + // The IOHandler editor is only for command lines stop hooks: + Target::StopHookCommandLine *hook_ptr = + static_cast(m_stop_hook_sp.get()); + + hook_ptr->SetActionFromString(line); StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); if (output_sp) { output_sp->Printf("Stop hook #%" PRIu64 " added.\n", @@ -4618,7 +4680,10 @@ class CommandObjectTargetStopHookAdd : public CommandObjectParsed, m_stop_hook_sp.reset(); Target &target = GetSelectedOrDummyTarget(); - Target::StopHookSP new_hook_sp = target.CreateStopHook(); + Target::StopHookSP new_hook_sp = + target.CreateStopHook(m_python_class_options.GetName().empty() ? + Target::StopHook::StopHookKind::CommandBased + : Target::StopHook::StopHookKind::ScriptBased); // First step, make the specifier. std::unique_ptr specifier_up; @@ -4687,11 +4752,30 @@ class CommandObjectTargetStopHookAdd : public CommandObjectParsed, new_hook_sp->SetAutoContinue(m_options.m_auto_continue); if (m_options.m_use_one_liner) { - // Use one-liners. - for (auto cmd : m_options.m_one_liner) - new_hook_sp->GetCommandPointer()->AppendString(cmd.c_str()); + // This is a command line stop hook: + Target::StopHookCommandLine *hook_ptr = + static_cast(new_hook_sp.get()); + hook_ptr->SetActionFromStrings(m_options.m_one_liner); result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID()); + } else if (!m_python_class_options.GetName().empty()) { + // This is a scripted stop hook: + Target::StopHookScripted *hook_ptr = + static_cast(new_hook_sp.get()); + Status error = hook_ptr->SetScriptCallback( + m_python_class_options.GetName(), + m_python_class_options.GetStructuredData()); + if (error.Success()) + result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", + new_hook_sp->GetID()); + else { + // FIXME: Set the stop hook ID counter back. + result.AppendErrorWithFormat("Couldn't add stop hook: %s", + error.AsCString()); + result.SetStatus(eReturnStatusFailed); + target.UndoCreateStopHook(new_hook_sp->GetID()); + return false; + } } else { m_stop_hook_sp = new_hook_sp; m_interpreter.GetLLDBCommandsFromIOHandler("> ", // Prompt @@ -4704,6 +4788,9 @@ class CommandObjectTargetStopHookAdd : public CommandObjectParsed, private: CommandOptions m_options; + OptionGroupPythonClassWithDict m_python_class_options; + OptionGroupOptions m_all_options; + Target::StopHookSP m_stop_hook_sp; }; diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 1d604606a7efc..1a23436f9fdf5 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -873,7 +873,7 @@ let Command = "target modules lookup" in { } let Command = "target stop hook add" in { - def target_stop_hook_add_one_liner : Option<"one-liner", "o">, + def target_stop_hook_add_one_liner : Option<"one-liner", "o">, GroupRange<1,3>, Arg<"OneLiner">, Desc<"Add a command for the stop hook. Can be specified " "more than once, and commands will be run in the order they appear.">; def target_stop_hook_add_shlib : Option<"shlib", "s">, Arg<"ShlibName">, @@ -891,19 +891,19 @@ let Command = "target stop hook add" in { def target_stop_hook_add_queue_name : Option<"queue-name", "q">, Arg<"QueueName">, Desc<"The stop hook is run only for threads in the queue " "whose name is given by this argument.">; - def target_stop_hook_add_file : Option<"file", "f">, Group<1>, + def target_stop_hook_add_file : Option<"file", "f">, Groups<[1,4]>, Arg<"Filename">, Desc<"Specify the source file within which the stop-hook " "is to be run.">, Completion<"SourceFile">; - def target_stop_hook_add_start_line : Option<"start-line", "l">, Group<1>, + def target_stop_hook_add_start_line : Option<"start-line", "l">, Groups<[1,4]>, Arg<"LineNum">, Desc<"Set the start of the line range for which the " "stop-hook is to be run.">; - def target_stop_hook_add_end_line : Option<"end-line", "e">, Group<1>, + def target_stop_hook_add_end_line : Option<"end-line", "e">, Groups<[1,4]>, Arg<"LineNum">, Desc<"Set the end of the line range for which the stop-hook" " is to be run.">; - def target_stop_hook_add_classname : Option<"classname", "c">, Group<2>, + def target_stop_hook_add_classname : Option<"classname", "c">, Groups<[2,5]>, Arg<"ClassName">, Desc<"Specify the class within which the stop-hook is to be run.">; - def target_stop_hook_add_name : Option<"name", "n">, Group<3>, + def target_stop_hook_add_name : Option<"name", "n">, Groups<[3,6]>, Arg<"FunctionName">, Desc<"Set the function name within which the stop hook" " will be run.">, Completion<"Symbol">; def target_stop_hook_add_auto_continue : Option<"auto-continue", "G">, diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index 9f56b4fa60a50..f67572c1f0299 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -127,6 +127,16 @@ extern "C" unsigned int LLDBSwigPythonCallBreakpointResolver(void *implementor, const char *method_name, lldb_private::SymbolContext *sym_ctx); +extern "C" void *LLDBSwigPythonCreateScriptedStopHook( + TargetSP target_sp, const char *python_class_name, + const char *session_dictionary_name, lldb_private::StructuredDataImpl *args, + lldb_private::Status &error); + +extern "C" bool +LLDBSwigPythonStopHookCallHandleStop(void *implementor, + lldb::ExecutionContextRefSP exc_ctx, + lldb::StreamSP stream); + extern "C" size_t LLDBSwigPython_CalculateNumChildren(void *implementor, uint32_t max); @@ -1979,6 +1989,60 @@ ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth( return lldb::eSearchDepthModule; } +StructuredData::GenericSP ScriptInterpreterPythonImpl::CreateScriptedStopHook( + TargetSP target_sp, const char *class_name, StructuredDataImpl *args_data, + Status &error) { + + if (!target_sp) { + error.SetErrorString("No target for scripted stop-hook."); + return StructuredData::GenericSP(); + } + + if (class_name == nullptr || class_name[0] == '\0') { + error.SetErrorString("No class name for scripted stop-hook."); + return StructuredData::GenericSP(); + } + + ScriptInterpreter *script_interpreter = m_debugger.GetScriptInterpreter(); + ScriptInterpreterPythonImpl *python_interpreter = + static_cast(script_interpreter); + + if (!script_interpreter) { + error.SetErrorString("No script interpreter for scripted stop-hook."); + return StructuredData::GenericSP(); + } + + void *ret_val; + + { + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + + ret_val = LLDBSwigPythonCreateScriptedStopHook( + target_sp, class_name, python_interpreter->m_dictionary_name.c_str(), + args_data, error); + } + + return StructuredData::GenericSP(new StructuredPythonObject(ret_val)); +} + +bool ScriptInterpreterPythonImpl::ScriptedStopHookHandleStop( + StructuredData::GenericSP implementor_sp, ExecutionContext &exc_ctx, + lldb::StreamSP stream_sp) { + assert(implementor_sp && + "can't call a stop hook with an invalid implementor"); + assert(stream_sp && "can't call a stop hook with an invalid stream"); + + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + + lldb::ExecutionContextRefSP exc_ctx_ref_sp(new ExecutionContextRef(exc_ctx)); + + bool ret_val = LLDBSwigPythonStopHookCallHandleStop( + implementor_sp->GetValue(), exc_ctx_ref_sp, stream_sp); + return ret_val; +} + StructuredData::ObjectSP ScriptInterpreterPythonImpl::LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) { diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h index 22b2c8152eac0..f89c3d461f7fd 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h @@ -105,6 +105,14 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython { lldb::SearchDepth ScriptedBreakpointResolverSearchDepth( StructuredData::GenericSP implementor_sp) override; + StructuredData::GenericSP + CreateScriptedStopHook(lldb::TargetSP target_sp, const char *class_name, + StructuredDataImpl *args_data, Status &error) override; + + bool ScriptedStopHookHandleStop(StructuredData::GenericSP implementor_sp, + ExecutionContext &exc_ctx, + lldb::StreamSP stream_sp) override; + StructuredData::GenericSP CreateFrameRecognizer(const char *class_name) override; diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp index 51f56704cca66..f20dc61996e0b 100644 --- a/lldb/source/Symbol/SymbolContext.cpp +++ b/lldb/source/Symbol/SymbolContext.cpp @@ -1010,11 +1010,15 @@ void SymbolContextSpecifier::Clear() { m_type = eNothingSpecified; } -bool SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) { +bool SymbolContextSpecifier::SymbolContextMatches(const SymbolContext &sc) { if (m_type == eNothingSpecified) return true; - if (m_target_sp.get() != sc.target_sp.get()) + // Only compare targets if this specifier has one and it's not the Dummy + // target. Otherwise if a specifier gets made in the dummy target and + // copied over we'll artificially fail the comparision. + if (m_target_sp && !m_target_sp->IsDummyTarget() && + m_target_sp != sc.target_sp) return false; if (m_type & eModuleSpecified) { diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index a879152393853..293845189d49d 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -2484,13 +2484,28 @@ ClangModulesDeclVendor *Target::GetClangModulesDeclVendor() { return m_clang_modules_decl_vendor_up.get(); } -Target::StopHookSP Target::CreateStopHook() { +Target::StopHookSP Target::CreateStopHook(StopHook::StopHookKind kind) { lldb::user_id_t new_uid = ++m_stop_hook_next_id; - Target::StopHookSP stop_hook_sp(new StopHook(shared_from_this(), new_uid)); + Target::StopHookSP stop_hook_sp; + switch (kind) { + case StopHook::StopHookKind::CommandBased: + stop_hook_sp.reset(new StopHookCommandLine(shared_from_this(), new_uid)); + break; + case StopHook::StopHookKind::ScriptBased: + stop_hook_sp.reset(new StopHookScripted(shared_from_this(), new_uid)); + break; + } m_stop_hooks[new_uid] = stop_hook_sp; return stop_hook_sp; } +void Target::UndoCreateStopHook(lldb::user_id_t user_id) { + if (!RemoveStopHookByID(user_id)) + return; + if (user_id == m_stop_hook_next_id) + m_stop_hook_next_id--; +} + bool Target::RemoveStopHookByID(lldb::user_id_t user_id) { size_t num_removed = m_stop_hooks.erase(user_id); return (num_removed != 0); @@ -2546,25 +2561,18 @@ void Target::RunStopHooks() { if (m_stop_hooks.empty()) return; - StopHookCollection::iterator pos, end = m_stop_hooks.end(); - // If there aren't any active stop hooks, don't bother either. - // Also see if any of the active hooks want to auto-continue. bool any_active_hooks = false; - bool auto_continue = false; for (auto hook : m_stop_hooks) { if (hook.second->IsActive()) { any_active_hooks = true; - auto_continue |= hook.second->GetAutoContinue(); + break; } } if (!any_active_hooks) return; - CommandReturnObject result(m_debugger.GetUseColor()); - std::vector exc_ctx_with_reasons; - std::vector sym_ctx_with_reasons; ThreadList &cur_threadlist = m_process_sp->GetThreadList(); size_t num_threads = cur_threadlist.GetSize(); @@ -2572,10 +2580,8 @@ void Target::RunStopHooks() { lldb::ThreadSP cur_thread_sp = cur_threadlist.GetThreadAtIndex(i); if (cur_thread_sp->ThreadStoppedForAReason()) { lldb::StackFrameSP cur_frame_sp = cur_thread_sp->GetStackFrameAtIndex(0); - exc_ctx_with_reasons.push_back(ExecutionContext( - m_process_sp.get(), cur_thread_sp.get(), cur_frame_sp.get())); - sym_ctx_with_reasons.push_back( - cur_frame_sp->GetSymbolContext(eSymbolContextEverything)); + exc_ctx_with_reasons.emplace_back(m_process_sp.get(), cur_thread_sp.get(), + cur_frame_sp.get()); } } @@ -2584,91 +2590,86 @@ void Target::RunStopHooks() { if (num_exe_ctx == 0) return; - result.SetImmediateOutputStream(m_debugger.GetAsyncOutputStream()); - result.SetImmediateErrorStream(m_debugger.GetAsyncErrorStream()); + StreamSP output_sp = m_debugger.GetAsyncOutputStream(); - bool keep_going = true; + bool auto_continue = false; bool hooks_ran = false; bool print_hook_header = (m_stop_hooks.size() != 1); bool print_thread_header = (num_exe_ctx != 1); - bool did_restart = false; + bool should_stop = false; + bool somebody_restarted = false; - for (pos = m_stop_hooks.begin(); keep_going && pos != end; pos++) { - // result.Clear(); - StopHookSP cur_hook_sp = (*pos).second; + for (auto stop_entry : m_stop_hooks) { + StopHookSP cur_hook_sp = stop_entry.second; if (!cur_hook_sp->IsActive()) continue; bool any_thread_matched = false; - for (size_t i = 0; keep_going && i < num_exe_ctx; i++) { - if ((cur_hook_sp->GetSpecifier() == nullptr || - cur_hook_sp->GetSpecifier()->SymbolContextMatches( - sym_ctx_with_reasons[i])) && - (cur_hook_sp->GetThreadSpecifier() == nullptr || - cur_hook_sp->GetThreadSpecifier()->ThreadPassesBasicTests( - exc_ctx_with_reasons[i].GetThreadRef()))) { - if (!hooks_ran) { - hooks_ran = true; - } - if (print_hook_header && !any_thread_matched) { - const char *cmd = - (cur_hook_sp->GetCommands().GetSize() == 1 - ? cur_hook_sp->GetCommands().GetStringAtIndex(0) - : nullptr); - if (cmd) - result.AppendMessageWithFormat("\n- Hook %" PRIu64 " (%s)\n", - cur_hook_sp->GetID(), cmd); - else - result.AppendMessageWithFormat("\n- Hook %" PRIu64 "\n", - cur_hook_sp->GetID()); - any_thread_matched = true; - } + for (auto exc_ctx : exc_ctx_with_reasons) { + // We detect somebody restarted in the stop-hook loop, and broke out of + // that loop back to here. So break out of here too. + if (somebody_restarted) + break; - if (print_thread_header) - result.AppendMessageWithFormat( - "-- Thread %d\n", - exc_ctx_with_reasons[i].GetThreadPtr()->GetIndexID()); - - CommandInterpreterRunOptions options; - options.SetStopOnContinue(true); - options.SetStopOnError(true); - options.SetEchoCommands(false); - options.SetPrintResults(true); - options.SetPrintErrors(true); - options.SetAddToHistory(false); - - // Force Async: - bool old_async = GetDebugger().GetAsyncExecution(); - GetDebugger().SetAsyncExecution(true); - GetDebugger().GetCommandInterpreter().HandleCommands( - cur_hook_sp->GetCommands(), &exc_ctx_with_reasons[i], options, - result); - GetDebugger().SetAsyncExecution(old_async); - // If the command started the target going again, we should bag out of - // running the stop hooks. - if ((result.GetStatus() == eReturnStatusSuccessContinuingNoResult) || - (result.GetStatus() == eReturnStatusSuccessContinuingResult)) { - // But only complain if there were more stop hooks to do: - StopHookCollection::iterator tmp = pos; - if (++tmp != end) - result.AppendMessageWithFormat( - "\nAborting stop hooks, hook %" PRIu64 - " set the program running.\n" - " Consider using '-G true' to make " - "stop hooks auto-continue.\n", - cur_hook_sp->GetID()); - keep_going = false; - did_restart = true; - } + if (!cur_hook_sp->ExecutionContextPasses(exc_ctx)) + continue; + + // We only consult the auto-continue for a stop hook if it matched the + // specifier. + auto_continue |= cur_hook_sp->GetAutoContinue(); + + if (!hooks_ran) + hooks_ran = true; + + if (print_hook_header && !any_thread_matched) { + StreamString s; + cur_hook_sp->GetDescription(&s, eDescriptionLevelBrief); + if (s.GetSize() != 0) + output_sp->Printf("\n- Hook %" PRIu64 " (%s)\n", cur_hook_sp->GetID(), + s.GetData()); + else + output_sp->Printf("\n- Hook %" PRIu64 "\n", cur_hook_sp->GetID()); + any_thread_matched = true; + } + + if (print_thread_header) + output_sp->Printf("-- Thread %d\n", + exc_ctx.GetThreadPtr()->GetIndexID()); + + bool this_should_stop = cur_hook_sp->HandleStop(exc_ctx, output_sp); + // If this hook is set to auto-continue that should override the + // HandleStop result... + if (cur_hook_sp->GetAutoContinue()) + this_should_stop = false; + + // If anybody wanted to stop, we should all stop. + if (!should_stop) + should_stop = this_should_stop; + + // We don't have a good way to prohibit people from restarting the target + // willy nilly in a stop hook. So see if the private state is running + // here and bag out if it is. + // FIXME: when we are doing non-stop mode for realz we'll have to instead + // track each thread, and only bag out if a thread is set running. + if (m_process_sp->GetPrivateState() != eStateStopped) { + output_sp->Printf("\nAborting stop hooks, hook %" PRIu64 + " set the program running.\n" + " Consider using '-G true' to make " + "stop hooks auto-continue.\n", + cur_hook_sp->GetID()); + somebody_restarted = true; + break; } } } + + output_sp->Flush(); + // Finally, if auto-continue was requested, do it now: - if (!did_restart && auto_continue) + // We only compute should_stop against the hook results if a hook got to run + // which is why we have to do this conjoint test. + if (!somebody_restarted && ((hooks_ran && !should_stop) || auto_continue)) m_process_sp->PrivateResume(); - - result.GetImmediateOutputStream()->Flush(); - result.GetImmediateErrorStream()->Flush(); } const TargetPropertiesSP &Target::GetGlobalProperties() { @@ -3133,20 +3134,17 @@ void Target::FinalizeFileActions(ProcessLaunchInfo &info) { // Target::StopHook Target::StopHook::StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid) - : UserID(uid), m_target_sp(target_sp), m_commands(), m_specifier_sp(), + : UserID(uid), m_target_sp(target_sp), m_specifier_sp(), m_thread_spec_up() {} Target::StopHook::StopHook(const StopHook &rhs) : UserID(rhs.GetID()), m_target_sp(rhs.m_target_sp), - m_commands(rhs.m_commands), m_specifier_sp(rhs.m_specifier_sp), - m_thread_spec_up(), m_active(rhs.m_active), - m_auto_continue(rhs.m_auto_continue) { + m_specifier_sp(rhs.m_specifier_sp), m_thread_spec_up(), + m_active(rhs.m_active), m_auto_continue(rhs.m_auto_continue) { if (rhs.m_thread_spec_up) m_thread_spec_up = std::make_unique(*rhs.m_thread_spec_up); } -Target::StopHook::~StopHook() = default; - void Target::StopHook::SetSpecifier(SymbolContextSpecifier *specifier) { m_specifier_sp.reset(specifier); } @@ -3155,8 +3153,31 @@ void Target::StopHook::SetThreadSpecifier(ThreadSpec *specifier) { m_thread_spec_up.reset(specifier); } +bool Target::StopHook::ExecutionContextPasses(const ExecutionContext &exc_ctx) { + SymbolContextSpecifier *specifier = GetSpecifier(); + if (!specifier) + return true; + + bool will_run = true; + if (exc_ctx.GetFramePtr()) + will_run = GetSpecifier()->SymbolContextMatches( + exc_ctx.GetFramePtr()->GetSymbolContext(eSymbolContextEverything)); + if (will_run && GetThreadSpecifier() != nullptr) + will_run = + GetThreadSpecifier()->ThreadPassesBasicTests(exc_ctx.GetThreadRef()); + + return will_run; +} + void Target::StopHook::GetDescription(Stream *s, lldb::DescriptionLevel level) const { + + // For brief descriptions, only print the subclass description: + if (level == eDescriptionLevelBrief) { + GetSubclassDescription(s, level); + return; + } + unsigned indent_level = s->GetIndentLevel(); s->SetIndentLevel(indent_level + 2); @@ -3187,15 +3208,148 @@ void Target::StopHook::GetDescription(Stream *s, s->PutCString("\n"); s->SetIndentLevel(indent_level + 2); } + GetSubclassDescription(s, level); +} +void Target::StopHookCommandLine::GetSubclassDescription( + Stream *s, lldb::DescriptionLevel level) const { + // The brief description just prints the first command. + if (level == eDescriptionLevelBrief) { + if (m_commands.GetSize() == 1) + s->PutCString(m_commands.GetStringAtIndex(0)); + return; + } s->Indent("Commands: \n"); - s->SetIndentLevel(indent_level + 4); + s->SetIndentLevel(s->GetIndentLevel() + 4); uint32_t num_commands = m_commands.GetSize(); for (uint32_t i = 0; i < num_commands; i++) { s->Indent(m_commands.GetStringAtIndex(i)); s->PutCString("\n"); } - s->SetIndentLevel(indent_level); + s->SetIndentLevel(s->GetIndentLevel() - 4); +} + +// Target::StopHookCommandLine +void Target::StopHookCommandLine::SetActionFromString(const std::string &string) { + GetCommands().SplitIntoLines(string); +} + +void Target::StopHookCommandLine::SetActionFromStrings( + const std::vector &strings) { + for (auto string : strings) + GetCommands().AppendString(string.c_str()); +} + +bool Target::StopHookCommandLine::HandleStop(ExecutionContext &exc_ctx, + StreamSP output_sp) { + assert(exc_ctx.GetTargetPtr() && "Can't call PerformAction on a context " + "with no target"); + + if (!m_commands.GetSize()) + return true; + + CommandReturnObject result(false); + result.SetImmediateOutputStream(output_sp); + Debugger &debugger = exc_ctx.GetTargetPtr()->GetDebugger(); + CommandInterpreterRunOptions options; + options.SetStopOnContinue(true); + options.SetStopOnError(true); + options.SetEchoCommands(false); + options.SetPrintResults(true); + options.SetPrintErrors(true); + options.SetAddToHistory(false); + + // Force Async: + bool old_async = debugger.GetAsyncExecution(); + debugger.SetAsyncExecution(true); + debugger.GetCommandInterpreter().HandleCommands(GetCommands(), &exc_ctx, + options, result); + debugger.SetAsyncExecution(old_async); + + return true; +} + +// Target::StopHookScripted +Status Target::StopHookScripted::SetScriptCallback( + std::string class_name, StructuredData::ObjectSP extra_args_sp) { + Status error; + + ScriptInterpreter *script_interp = + GetTarget()->GetDebugger().GetScriptInterpreter(); + if (!script_interp) { + error.SetErrorString("No script interpreter installed."); + return error; + } + + m_class_name = class_name; + + m_extra_args = new StructuredDataImpl(); + + if (extra_args_sp) + m_extra_args->SetObjectSP(extra_args_sp); + + m_implementation_sp = script_interp->CreateScriptedStopHook( + GetTarget(), m_class_name.c_str(), m_extra_args, error); + + return error; +} + +bool Target::StopHookScripted::HandleStop(ExecutionContext &exc_ctx, + StreamSP output_sp) { + assert(exc_ctx.GetTargetPtr() && "Can't call HandleStop on a context " + "with no target"); + + ScriptInterpreter *script_interp = + GetTarget()->GetDebugger().GetScriptInterpreter(); + if (!script_interp) + return true; + + bool should_stop = script_interp->ScriptedStopHookHandleStop( + m_implementation_sp, exc_ctx, output_sp); + + return should_stop; +} + +void Target::StopHookScripted::GetSubclassDescription( + Stream *s, lldb::DescriptionLevel level) const { + if (level == eDescriptionLevelBrief) { + s->PutCString(m_class_name); + return; + } + s->Indent("Class:"); + s->Printf("%s\n", m_class_name.c_str()); + + // Now print the extra args: + // FIXME: We should use StructuredData.GetDescription on the m_extra_args + // but that seems to rely on some printing plugin that doesn't exist. + if (!m_extra_args->IsValid()) + return; + StructuredData::ObjectSP object_sp = m_extra_args->GetObjectSP(); + if (!object_sp || !object_sp->IsValid()) + return; + + StructuredData::Dictionary *as_dict = object_sp->GetAsDictionary(); + if (!as_dict || !as_dict->IsValid()) + return; + + uint32_t num_keys = as_dict->GetSize(); + if (num_keys == 0) + return; + + s->Indent("Args:\n"); + s->SetIndentLevel(s->GetIndentLevel() + 4); + + auto print_one_element = [&s](ConstString key, + StructuredData::Object *object) { + s->Indent(); + s->Printf("%s : %s\n", key.GetCString(), + object->GetStringValue().str().c_str()); + return true; + }; + + as_dict->ForEach(print_one_element); + + s->SetIndentLevel(s->GetIndentLevel() - 4); } static constexpr OptionEnumValueElement g_dynamic_value_types[] = { diff --git a/lldb/test/API/commands/target/stop-hooks/TestStopHookScripted.py b/lldb/test/API/commands/target/stop-hooks/TestStopHookScripted.py new file mode 100644 index 0000000000000..e650778fe8e3b --- /dev/null +++ b/lldb/test/API/commands/target/stop-hooks/TestStopHookScripted.py @@ -0,0 +1,146 @@ +""" +Test stop hook functionality +""" + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + + +class TestStopHooks(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + # If your test case doesn't stress debug info, the + # set this to true. That way it won't be run once for + # each debug info format. + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + TestBase.setUp(self) + self.build() + self.main_source_file = lldb.SBFileSpec("main.c") + full_path = os.path.join(self.getSourceDir(), "main.c") + self.main_start_line = line_number(full_path, "main()") + + def test_bad_handler(self): + """Test that we give a good error message when the handler is bad""" + self.script_setup() + result = lldb.SBCommandReturnObject() + + # First try the wrong number of args handler: + command = "target stop-hook add -P stop_hook.bad_handle_stop" + self.interp.HandleCommand(command, result) + self.assertFalse(result.Succeeded(), "Set the target stop hook") + self.assertIn("Wrong number of args", result.GetError(), "Got the wrong number of args error") + + # Next the no handler at all handler: + command = "target stop-hook add -P stop_hook.no_handle_stop" + + self.interp.HandleCommand(command, result) + self.assertFalse(result.Succeeded(), "Set the target stop hook") + self.assertIn('Class "stop_hook.no_handle_stop" is missing the required handle_stop callback', result.GetError(), "Got the right error") + + def test_stop_hooks_scripted(self): + """Test that a scripted stop hook works with no specifiers""" + self.stop_hooks_scripted(5) + + def test_stop_hooks_scripted_right_func(self): + """Test that a scripted stop hook fires when there is a function match""" + self.stop_hooks_scripted(5, "-n step_out_of_me") + + def test_stop_hooks_scripted_wrong_func(self): + """Test that a scripted stop hook doesn't fire when the function does not match""" + self.stop_hooks_scripted(0, "-n main") + + def test_stop_hooks_scripted_right_lines(self): + """Test that a scripted stop hook fires when there is a function match""" + self.stop_hooks_scripted(5, "-f main.c -l 1 -e %d"%(self.main_start_line)) + + def test_stop_hooks_scripted_wrong_lines(self): + """Test that a scripted stop hook doesn't fire when the function does not match""" + self.stop_hooks_scripted(0, "-f main.c -l %d -e 100"%(self.main_start_line)) + + def test_stop_hooks_scripted_auto_continue(self): + """Test that the --auto-continue flag works""" + self.do_test_auto_continue(False) + + def test_stop_hooks_scripted_return_false(self): + """Test that the returning False from a stop hook works""" + self.do_test_auto_continue(True) + + def do_test_auto_continue(self, return_true): + """Test that auto-continue works.""" + # We set auto-continue to 1 but the stop hook only applies to step_out_of_me, + # so we should end up stopped in main, having run the expression only once. + self.script_setup() + + result = lldb.SBCommandReturnObject() + + if return_true: + command = "target stop-hook add -P stop_hook.stop_handler -k increment -v 5 -k return_false -v 1 -n step_out_of_me" + else: + command = "target stop-hook add -G 1 -P stop_hook.stop_handler -k increment -v 5 -n step_out_of_me" + + self.interp.HandleCommand(command, result) + self.assertTrue(result.Succeeded, "Set the target stop hook") + + # First run to main. If we go straight to the first stop hook hit, + # run_to_source_breakpoint will fail because we aren't at original breakpoint + + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + "Stop here first", self.main_source_file) + + # Now set the breakpoint on step_out_of_me, and make sure we run the + # expression, then continue back to main. + bkpt = target.BreakpointCreateBySourceRegex("Set a breakpoint here and step out", self.main_source_file) + self.assertTrue(bkpt.GetNumLocations() > 0, "Got breakpoints in step_out_of_me") + process.Continue() + + var = target.FindFirstGlobalVariable("g_var") + self.assertTrue(var.IsValid()) + self.assertEqual(var.GetValueAsUnsigned(), 5, "Updated g_var") + + func_name = process.GetSelectedThread().frames[0].GetFunctionName() + self.assertEqual("main", func_name, "Didn't stop at the expected function.") + + def script_setup(self): + self.interp = self.dbg.GetCommandInterpreter() + result = lldb.SBCommandReturnObject() + + # Bring in our script file: + script_name = os.path.join(self.getSourceDir(), "stop_hook.py") + command = "command script import " + script_name + self.interp.HandleCommand(command, result) + self.assertTrue(result.Succeeded(), "com scr imp failed: %s"%(result.GetError())) + + # set a breakpoint at the end of main to catch our auto-continue tests. + # Do it in the dummy target so it will get copied to our target even when + # we don't have a chance to stop. + dummy_target = self.dbg.GetDummyTarget() + dummy_target.BreakpointCreateBySourceRegex("return result", self.main_source_file) + + + def stop_hooks_scripted(self, g_var_value, specifier = None): + self.script_setup() + + result = lldb.SBCommandReturnObject() + + command = "target stop-hook add -P stop_hook.stop_handler -k increment -v 5 " + if specifier: + command += specifier + + self.interp.HandleCommand(command, result) + self.assertTrue(result.Succeeded, "Set the target stop hook") + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + "Set a breakpoint here", self.main_source_file) + # At this point we've hit our stop hook so we should have run our expression, + # which increments g_var by the amount specified by the increment key's value. + while process.GetState() == lldb.eStateRunning: + continue + + var = target.FindFirstGlobalVariable("g_var") + self.assertTrue(var.IsValid()) + self.assertEqual(var.GetValueAsUnsigned(), g_var_value, "Updated g_var") diff --git a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py index 64686afe627da..43447a845156d 100644 --- a/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py +++ b/lldb/test/API/commands/target/stop-hooks/TestStopHooks.py @@ -1,5 +1,5 @@ """ -Test that stop hooks trigger on "step-out" +Test stop hook functionality """ @@ -18,10 +18,15 @@ class TestStopHooks(TestBase): # each debug info format. NO_DEBUG_INFO_TESTCASE = True - def test_stop_hooks_step_out(self): - """Test that stop hooks fire on step-out.""" + def setUp(self): + TestBase.setUp(self) self.build() self.main_source_file = lldb.SBFileSpec("main.c") + full_path = os.path.join(self.getSourceDir(), "main.c") + self.main_start_line = line_number(full_path, "main()") + + def test_stop_hooks_step_out(self): + """Test that stop hooks fire on step-out.""" self.step_out_test() def step_out_test(self): @@ -37,4 +42,3 @@ def step_out_test(self): self.assertTrue(var.IsValid()) self.assertEqual(var.GetValueAsUnsigned(), 1, "Updated g_var") - diff --git a/lldb/test/API/commands/target/stop-hooks/main.c b/lldb/test/API/commands/target/stop-hooks/main.c index d08ad14776b5a..16bfc0ce5db6b 100644 --- a/lldb/test/API/commands/target/stop-hooks/main.c +++ b/lldb/test/API/commands/target/stop-hooks/main.c @@ -10,5 +10,6 @@ int step_out_of_me() int main() { - return step_out_of_me(); + int result = step_out_of_me(); // Stop here first + return result; } diff --git a/lldb/test/API/commands/target/stop-hooks/stop_hook.py b/lldb/test/API/commands/target/stop-hooks/stop_hook.py new file mode 100644 index 0000000000000..1abc2bdeeb31b --- /dev/null +++ b/lldb/test/API/commands/target/stop-hooks/stop_hook.py @@ -0,0 +1,49 @@ +import lldb + +class stop_handler: + def __init__(self, target, extra_args, dict): + self.extra_args = extra_args + self.target = target + self.counter = 0 + ret_val = self.extra_args.GetValueForKey("return_false") + if ret_val: + self.ret_val = False + else: + self.ret_val = True + + def handle_stop(self, exe_ctx, stream): + self.counter += 1 + stream.Print("I have stopped %d times.\n"%(self.counter)) + increment = 1 + value = self.extra_args.GetValueForKey("increment") + if value: + incr_as_str = value.GetStringValue(100) + increment = int(incr_as_str) + else: + stream.Print("Could not find increment in extra_args\n") + frame = exe_ctx.GetFrame() + expression = "g_var += %d"%(increment) + expr_result = frame.EvaluateExpression(expression) + if not expr_result.GetError().Success(): + stream.Print("Error running expression: %s"%(expr_result.GetError().GetCString())) + value = exe_ctx.target.FindFirstGlobalVariable("g_var") + if not value.IsValid(): + stream.Print("Didn't get a valid value for g_var.") + else: + int_val = value.GetValueAsUnsigned() + stream.Print("Returning value: %d from handle_stop.\n"%(self.ret_val)) + return self.ret_val + +class bad_handle_stop: + def __init__(self, target, extra_args, dict): + print("I am okay") + + def handle_stop(self): + print("I am bad") + +class no_handle_stop: + def __init__(self, target, extra_args, dict): + print("I am okay") + + + diff --git a/lldb/test/Shell/Commands/Inputs/stop_hook.py b/lldb/test/Shell/Commands/Inputs/stop_hook.py new file mode 100644 index 0000000000000..e319ca9ec5bc8 --- /dev/null +++ b/lldb/test/Shell/Commands/Inputs/stop_hook.py @@ -0,0 +1,10 @@ +import lldb + +class stop_handler: + def __init__(self, target, extra_args, dict): + self.extra_args = extra_args + self.target = target + + def handle_stop(self, exe_ctx, stream): + stream.Print("I did indeed run\n") + return True diff --git a/lldb/test/Shell/Commands/command-stop-hook-output.test b/lldb/test/Shell/Commands/command-stop-hook-output.test new file mode 100644 index 0000000000000..7890bb3ca5e75 --- /dev/null +++ b/lldb/test/Shell/Commands/command-stop-hook-output.test @@ -0,0 +1,19 @@ +# REQUIRES: python +# RUN: %clang_host -g %S/Inputs/main.c -o %t +# RUN: %lldb %t -O 'command script import %S/Inputs/stop_hook.py' -s %s -o exit | FileCheck %s + +b main +# CHECK-LABEL: b main +# CHECK: Breakpoint 1: where = {{.*}}`main + +target stop-hook add -P stop_hook.stop_handler +# CHECK-LABEL: target stop-hook add -P stop_hook.stop_handler +# CHECK: Stop hook #1 added. + +run +# CHECK-LABEL: run +# CHECK: I did indeed run +# CHECK: Process {{.*}} stopped +# CHECK: stop reason = breakpoint 1 +# CHECK: frame #0: {{.*}}`main at main.c + diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp index f661835d191b1..58ddf0c40a267 100644 --- a/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp +++ b/lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp @@ -254,3 +254,17 @@ LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting, const lldb::TargetSP &target_sp) { return nullptr; } + +extern "C" void *LLDBSwigPythonCreateScriptedStopHook( + lldb::TargetSP target_sp, const char *python_class_name, + const char *session_dictionary_name, + lldb_private::StructuredDataImpl *args_impl, Status &error) { + return nullptr; +} + +extern "C" bool +LLDBSwigPythonStopHookCallHandleStop(void *implementor, + lldb::ExecutionContextRefSP exc_ctx_sp, + lldb::StreamSP stream) { + return false; +} From d932a0b00031ee5e3b5d6baf2d60257d345bd4e9 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Fri, 2 Oct 2020 12:43:24 -0700 Subject: [PATCH 071/234] Fix raciness in the StopHook check for "has the target run". This was looking at the privateState, but it's possible that the actual process has started up and then stopped again by the time we get to the check, which would lead us to get out of running the stop hooks too early. Instead we need to track the intention of the stop hooks directly. Differential Revision: https://reviews.llvm.org/D88753 (cherry picked from commit be66987e2047636d9ed9d2a4d88b762d59ae88f2) --- lldb/include/lldb/Target/Target.h | 20 ++++-- lldb/source/Target/Process.cpp | 3 +- lldb/source/Target/Target.cpp | 104 ++++++++++++++++++++---------- 3 files changed, 86 insertions(+), 41 deletions(-) diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 94c6ebeac10da..7ee27a9776d5c 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -1145,6 +1145,11 @@ class Target : public std::enable_shared_from_this, virtual ~StopHook() = default; enum class StopHookKind : uint32_t { CommandBased = 0, ScriptBased }; + enum class StopHookResult : uint32_t { + KeepStopped = 0, + RequestContinue, + AlreadyContinued + }; lldb::TargetSP &GetTarget() { return m_target_sp; } @@ -1160,8 +1165,8 @@ class Target : public std::enable_shared_from_this, // with a reason" thread. It should add to the stream whatever text it // wants to show the user, and return False to indicate it wants the target // not to stop. - virtual bool HandleStop(ExecutionContext &exe_ctx, - lldb::StreamSP output) = 0; + virtual StopHookResult HandleStop(ExecutionContext &exe_ctx, + lldb::StreamSP output) = 0; // Set the Thread Specifier. The stop hook will own the thread specifier, // and is responsible for deleting it when we're done. @@ -1201,8 +1206,8 @@ class Target : public std::enable_shared_from_this, void SetActionFromString(const std::string &strings); void SetActionFromStrings(const std::vector &strings); - bool HandleStop(ExecutionContext &exc_ctx, - lldb::StreamSP output_sp) override; + StopHookResult HandleStop(ExecutionContext &exc_ctx, + lldb::StreamSP output_sp) override; void GetSubclassDescription(Stream *s, lldb::DescriptionLevel level) const override; @@ -1219,7 +1224,8 @@ class Target : public std::enable_shared_from_this, class StopHookScripted : public StopHook { public: virtual ~StopHookScripted() = default; - bool HandleStop(ExecutionContext &exc_ctx, lldb::StreamSP output) override; + StopHookResult HandleStop(ExecutionContext &exc_ctx, + lldb::StreamSP output) override; Status SetScriptCallback(std::string class_name, StructuredData::ObjectSP extra_args_sp); @@ -1254,7 +1260,9 @@ class Target : public std::enable_shared_from_this, /// remove the stop hook, as it will also reset the stop hook counter. void UndoCreateStopHook(lldb::user_id_t uid); - void RunStopHooks(); + // Runs the stop hooks that have been registered for this target. + // Returns true if the stop hooks cause the target to resume. + bool RunStopHooks(); size_t GetStopHookSize(); diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index d87f57f8ccacd..55e1d281c799e 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -4175,8 +4175,7 @@ void Process::ProcessEventData::DoOnRemoval(Event *event_ptr) { // public (or SyncResume) broadcasters. StopHooks are just for // real public stops. They might also restart the target, // so watch for that. - process_sp->GetTarget().RunStopHooks(); - if (process_sp->GetPrivateState() == eStateRunning) + if (process_sp->GetTarget().RunStopHooks()) SetRestarted(true); } } diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 293845189d49d..8f22ee2528669 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -2541,25 +2541,26 @@ void Target::SetAllStopHooksActiveState(bool active_state) { } } -void Target::RunStopHooks() { +bool Target::RunStopHooks() { if (m_suppress_stop_hooks) - return; + return false; if (!m_process_sp) - return; + return false; // Somebody might have restarted the process: + // Still return false, the return value is about US restarting the target. if (m_process_sp->GetState() != eStateStopped) - return; + return false; // make sure we check that we are not stopped // because of us running a user expression since in that case we do not want // to run the stop-hooks if (m_process_sp->GetModIDRef().IsLastResumeForUserExpression()) - return; + return false; if (m_stop_hooks.empty()) - return; + return false; // If there aren't any active stop hooks, don't bother either. bool any_active_hooks = false; @@ -2570,7 +2571,7 @@ void Target::RunStopHooks() { } } if (!any_active_hooks) - return; + return false; std::vector exc_ctx_with_reasons; @@ -2588,7 +2589,7 @@ void Target::RunStopHooks() { // If no threads stopped for a reason, don't run the stop-hooks. size_t num_exe_ctx = exc_ctx_with_reasons.size(); if (num_exe_ctx == 0) - return; + return false; StreamSP output_sp = m_debugger.GetAsyncOutputStream(); @@ -2636,22 +2637,27 @@ void Target::RunStopHooks() { output_sp->Printf("-- Thread %d\n", exc_ctx.GetThreadPtr()->GetIndexID()); - bool this_should_stop = cur_hook_sp->HandleStop(exc_ctx, output_sp); - // If this hook is set to auto-continue that should override the - // HandleStop result... - if (cur_hook_sp->GetAutoContinue()) - this_should_stop = false; + StopHook::StopHookResult this_result = + cur_hook_sp->HandleStop(exc_ctx, output_sp); + bool this_should_stop = true; - // If anybody wanted to stop, we should all stop. - if (!should_stop) - should_stop = this_should_stop; + switch (this_result) { + case StopHook::StopHookResult::KeepStopped: + // If this hook is set to auto-continue that should override the + // HandleStop result... + if (cur_hook_sp->GetAutoContinue()) + this_should_stop = false; + else + this_should_stop = true; - // We don't have a good way to prohibit people from restarting the target - // willy nilly in a stop hook. So see if the private state is running - // here and bag out if it is. - // FIXME: when we are doing non-stop mode for realz we'll have to instead - // track each thread, and only bag out if a thread is set running. - if (m_process_sp->GetPrivateState() != eStateStopped) { + break; + case StopHook::StopHookResult::RequestContinue: + this_should_stop = false; + break; + case StopHook::StopHookResult::AlreadyContinued: + // We don't have a good way to prohibit people from restarting the + // target willy nilly in a stop hook. If the hook did so, give a + // gentle suggestion here and bag out if the hook processing. output_sp->Printf("\nAborting stop hooks, hook %" PRIu64 " set the program running.\n" " Consider using '-G true' to make " @@ -2660,16 +2666,42 @@ void Target::RunStopHooks() { somebody_restarted = true; break; } + // If we're already restarted, stop processing stop hooks. + // FIXME: if we are doing non-stop mode for real, we would have to + // check that OUR thread was restarted, otherwise we should keep + // processing stop hooks. + if (somebody_restarted) + break; + + // If anybody wanted to stop, we should all stop. + if (!should_stop) + should_stop = this_should_stop; } } output_sp->Flush(); + // If one of the commands in the stop hook already restarted the target, + // report that fact. + if (somebody_restarted) + return true; + // Finally, if auto-continue was requested, do it now: // We only compute should_stop against the hook results if a hook got to run // which is why we have to do this conjoint test. - if (!somebody_restarted && ((hooks_ran && !should_stop) || auto_continue)) - m_process_sp->PrivateResume(); + if ((hooks_ran && !should_stop) || auto_continue) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + Status error = m_process_sp->PrivateResume(); + if (error.Success()) { + LLDB_LOG(log, "Resuming from RunStopHooks"); + return true; + } else { + LLDB_LOG(log, "Resuming from RunStopHooks failed: {0}", error); + return false; + } + } + + return false; } const TargetPropertiesSP &Target::GetGlobalProperties() { @@ -3240,13 +3272,14 @@ void Target::StopHookCommandLine::SetActionFromStrings( GetCommands().AppendString(string.c_str()); } -bool Target::StopHookCommandLine::HandleStop(ExecutionContext &exc_ctx, - StreamSP output_sp) { +Target::StopHook::StopHookResult +Target::StopHookCommandLine::HandleStop(ExecutionContext &exc_ctx, + StreamSP output_sp) { assert(exc_ctx.GetTargetPtr() && "Can't call PerformAction on a context " "with no target"); if (!m_commands.GetSize()) - return true; + return StopHookResult::KeepStopped; CommandReturnObject result(false); result.SetImmediateOutputStream(output_sp); @@ -3265,8 +3298,11 @@ bool Target::StopHookCommandLine::HandleStop(ExecutionContext &exc_ctx, debugger.GetCommandInterpreter().HandleCommands(GetCommands(), &exc_ctx, options, result); debugger.SetAsyncExecution(old_async); - - return true; + lldb::ReturnStatus status = result.GetStatus(); + if (status == eReturnStatusSuccessContinuingNoResult || + status == eReturnStatusSuccessContinuingResult) + return StopHookResult::AlreadyContinued; + return StopHookResult::KeepStopped; } // Target::StopHookScripted @@ -3294,20 +3330,22 @@ Status Target::StopHookScripted::SetScriptCallback( return error; } -bool Target::StopHookScripted::HandleStop(ExecutionContext &exc_ctx, - StreamSP output_sp) { +Target::StopHook::StopHookResult +Target::StopHookScripted::HandleStop(ExecutionContext &exc_ctx, + StreamSP output_sp) { assert(exc_ctx.GetTargetPtr() && "Can't call HandleStop on a context " "with no target"); ScriptInterpreter *script_interp = GetTarget()->GetDebugger().GetScriptInterpreter(); if (!script_interp) - return true; + return StopHookResult::KeepStopped; bool should_stop = script_interp->ScriptedStopHookHandleStop( m_implementation_sp, exc_ctx, output_sp); - return should_stop; + return should_stop ? StopHookResult::KeepStopped + : StopHookResult::RequestContinue; } void Target::StopHookScripted::GetSubclassDescription( From 779364a40d343b127ef45b3c0b57f62d6742c258 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 1 Oct 2020 13:46:52 +0200 Subject: [PATCH 072/234] [lldb][swift] Only run Swift API tests when Swift support is enabled Disabling Swift support in LLDB doesn't prevent the test suite from running the Swift tests (which then end up failing instead of being marked as unsupported). This adds a lit feature for Swift and adds the REQUIRES to all Swift tests to mark them as unsupported if Swift is disabled. --- lldb/test/CMakeLists.txt | 6 ++++++ lldb/test/Shell/Reproducer/Swift/TestBridging.test | 1 + lldb/test/Shell/Reproducer/Swift/TestModule.test | 1 + lldb/test/Shell/Reproducer/Swift/TestSimple.test | 1 + lldb/test/Shell/Reproducer/Swift/TestSwiftInterface.test | 1 + lldb/test/Shell/Swift/DeserializationFailure.test | 1 + lldb/test/Shell/Swift/DynamicTyperesolutionConflict.test | 1 + lldb/test/Shell/Swift/MissingVFSOverlay.test | 1 + lldb/test/Shell/Swift/No.swiftmodule-ObjC.test | 1 + lldb/test/Shell/Swift/No.swiftmodule.test | 1 + lldb/test/Shell/Swift/RemoteASTImport.test | 1 + lldb/test/Shell/Swift/astcontext_error.test | 1 + lldb/test/Shell/Swift/cond-breakpoint.test | 1 + lldb/test/Shell/Swift/global.test | 2 ++ lldb/test/Shell/Swift/runtime-initialization.test | 1 + lldb/test/Shell/SwiftREPL/Basic.test | 1 + lldb/test/Shell/SwiftREPL/BreakpointSimple.test | 2 +- lldb/test/Shell/SwiftREPL/CFString.test | 1 + lldb/test/Shell/SwiftREPL/Class.test | 1 + lldb/test/Shell/SwiftREPL/ComputedProperties.test | 1 + lldb/test/Shell/SwiftREPL/CrashArgs.test | 1 + lldb/test/Shell/SwiftREPL/Deadlock.test | 6 ++++-- lldb/test/Shell/SwiftREPL/DeferredNSArray.test | 1 + lldb/test/Shell/SwiftREPL/DeploymentTarget.test | 1 + lldb/test/Shell/SwiftREPL/Dict.test | 1 + lldb/test/Shell/SwiftREPL/DictBridging.test | 2 ++ lldb/test/Shell/SwiftREPL/ErrorReturn.test | 1 + lldb/test/Shell/SwiftREPL/ErrorReturnObjC.test | 1 + lldb/test/Shell/SwiftREPL/ExclusivityREPL.test | 1 + lldb/test/Shell/SwiftREPL/FoundationTypes.test | 1 + lldb/test/Shell/SwiftREPL/FrameworkPath.test | 1 + lldb/test/Shell/SwiftREPL/GLKIT.test | 1 + lldb/test/Shell/SwiftREPL/GenericTypealias.test | 2 ++ lldb/test/Shell/SwiftREPL/Generics.test | 1 + lldb/test/Shell/SwiftREPL/ImportCocoa.test | 1 + lldb/test/Shell/SwiftREPL/ImportDispatch.test | 1 + lldb/test/Shell/SwiftREPL/ImportError.test | 1 + lldb/test/Shell/SwiftREPL/ImportFoundation.test | 1 + lldb/test/Shell/SwiftREPL/InitFile.test | 2 ++ lldb/test/Shell/SwiftREPL/LookupAfterImport.test | 1 + lldb/test/Shell/SwiftREPL/MetatypeRepl.test | 2 ++ lldb/test/Shell/SwiftREPL/NSObjectSubclass.test | 1 + lldb/test/Shell/SwiftREPL/NSString.test | 1 + lldb/test/Shell/SwiftREPL/OpenClass.test | 1 + lldb/test/Shell/SwiftREPL/Optional.test | 1 + lldb/test/Shell/SwiftREPL/OptionalUnowned.test | 2 ++ lldb/test/Shell/SwiftREPL/OptionalWithDynamicType.test | 1 + lldb/test/Shell/SwiftREPL/PropertyWrapperPrivate.test | 1 + lldb/test/Shell/SwiftREPL/PropertyWrapperPublic.test | 1 + lldb/test/Shell/SwiftREPL/PropertyWrapperTopLevel.test | 2 ++ lldb/test/Shell/SwiftREPL/RecursiveClass.test | 1 + lldb/test/Shell/SwiftREPL/Redefinition.test | 1 + lldb/test/Shell/SwiftREPL/RedirectInput.test | 1 + lldb/test/Shell/SwiftREPL/RedirectInputNoSuchFile.test | 1 + lldb/test/Shell/SwiftREPL/RedirectInputUnreadable.test | 1 + lldb/test/Shell/SwiftREPL/ResilientArray.test | 2 ++ lldb/test/Shell/SwiftREPL/ResilientDict.test | 6 ++++-- lldb/test/Shell/SwiftREPL/SIMD.test | 1 + lldb/test/Shell/SwiftREPL/SetBridging.test | 2 ++ lldb/test/Shell/SwiftREPL/SimpleExpressions.test | 1 + lldb/test/Shell/SwiftREPL/SleepREPL.test | 1 + lldb/test/Shell/SwiftREPL/String.test | 1 + lldb/test/Shell/SwiftREPL/Struct.test | 1 + lldb/test/Shell/SwiftREPL/Subclassing.test | 1 + lldb/test/Shell/SwiftREPL/SwiftInterface.test | 1 + .../Shell/SwiftREPL/SwiftInterfaceForceModuleLoadMode.test | 1 + lldb/test/Shell/SwiftREPL/SwiftTypeLookup.test | 1 + lldb/test/Shell/SwiftREPL/UninitVariables.test | 1 + lldb/test/Shell/SwiftREPL/ZeroSizeStruct.test | 1 + lldb/test/Shell/SwiftREPL/enum-singlecase.test | 1 + lldb/test/Shell/SwiftREPL/one-char-string.test | 1 + lldb/test/Shell/lit.cfg.py | 3 +++ lldb/test/Shell/lit.site.cfg.py.in | 1 + 73 files changed, 95 insertions(+), 5 deletions(-) diff --git a/lldb/test/CMakeLists.txt b/lldb/test/CMakeLists.txt index 44824d41f37c9..26b96e4a63dd5 100644 --- a/lldb/test/CMakeLists.txt +++ b/lldb/test/CMakeLists.txt @@ -174,6 +174,12 @@ llvm_canonicalize_cmake_booleans( LLVM_ENABLE_SHARED_LIBS LLDB_IS_64_BITS) +# BEGIN SWIFT +llvm_canonicalize_cmake_booleans( + LLDB_ENABLE_SWIFT_SUPPORT +) +# END SWIFT + # Configure the individual test suites. add_subdirectory(API) add_subdirectory(Shell) diff --git a/lldb/test/Shell/Reproducer/Swift/TestBridging.test b/lldb/test/Shell/Reproducer/Swift/TestBridging.test index 6a146ca1e692c..bf4317d38be36 100644 --- a/lldb/test/Shell/Reproducer/Swift/TestBridging.test +++ b/lldb/test/Shell/Reproducer/Swift/TestBridging.test @@ -1,4 +1,5 @@ # UNSUPPORTED: system-windows, system-freebsd, system-linux +# REQUIRES: swift # This tests replaying a Swift reproducer with bridging. diff --git a/lldb/test/Shell/Reproducer/Swift/TestModule.test b/lldb/test/Shell/Reproducer/Swift/TestModule.test index 4e12560102b08..362261fe2b761 100644 --- a/lldb/test/Shell/Reproducer/Swift/TestModule.test +++ b/lldb/test/Shell/Reproducer/Swift/TestModule.test @@ -1,4 +1,5 @@ # UNSUPPORTED: system-windows, system-freebsd +# REQUIRES: swift # This tests replaying a Swift reproducer with bridging. diff --git a/lldb/test/Shell/Reproducer/Swift/TestSimple.test b/lldb/test/Shell/Reproducer/Swift/TestSimple.test index d13327ee77fa9..5d85f50ae6ffa 100644 --- a/lldb/test/Shell/Reproducer/Swift/TestSimple.test +++ b/lldb/test/Shell/Reproducer/Swift/TestSimple.test @@ -1,4 +1,5 @@ # UNSUPPORTED: system-windows, system-freebsd +# REQUIRES: swift # This tests replaying a simple reproducer. diff --git a/lldb/test/Shell/Reproducer/Swift/TestSwiftInterface.test b/lldb/test/Shell/Reproducer/Swift/TestSwiftInterface.test index 8bc950ec529ad..9d166bf32e922 100644 --- a/lldb/test/Shell/Reproducer/Swift/TestSwiftInterface.test +++ b/lldb/test/Shell/Reproducer/Swift/TestSwiftInterface.test @@ -1,6 +1,7 @@ # Test that reproducers can deal with .swiftinterface files. # REQUIRES: system-darwin +# REQUIRES: swift # # rdar://problem/55564275 # XFAIL: * diff --git a/lldb/test/Shell/Swift/DeserializationFailure.test b/lldb/test/Shell/Swift/DeserializationFailure.test index f1054961a7b30..7bcdb51afda85 100644 --- a/lldb/test/Shell/Swift/DeserializationFailure.test +++ b/lldb/test/Shell/Swift/DeserializationFailure.test @@ -1,4 +1,5 @@ # REQUIRES: system-darwin +# REQUIRES: swift # Tests that error messages from deserializing Swift modules are # printed to the error stream. Architecturally it is not possible to # write this as a dotest.py test. diff --git a/lldb/test/Shell/Swift/DynamicTyperesolutionConflict.test b/lldb/test/Shell/Swift/DynamicTyperesolutionConflict.test index 1b22289dbb6a6..b2e5f8b3e53ee 100644 --- a/lldb/test/Shell/Swift/DynamicTyperesolutionConflict.test +++ b/lldb/test/Shell/Swift/DynamicTyperesolutionConflict.test @@ -1,5 +1,6 @@ # REQUIRES: system-darwin # REQUIRES: rdar50667488 +# REQUIRES: swift # This testcase causes the scratch context to get destroyed by a # conflict that is triggered via dynamic type resolution. The conflict diff --git a/lldb/test/Shell/Swift/MissingVFSOverlay.test b/lldb/test/Shell/Swift/MissingVFSOverlay.test index 2c0da83eefcc7..fbd1e2000fce0 100644 --- a/lldb/test/Shell/Swift/MissingVFSOverlay.test +++ b/lldb/test/Shell/Swift/MissingVFSOverlay.test @@ -1,5 +1,6 @@ # Test that error messages from constructing ClangImporter # are surfaced to the user. +# REQUIRES: swift # RUN: rm -rf %t && mkdir %t && cd %t # RUN: cp %p/../../API/lang/swift/deserialization_failure/Inputs/main.swift %t/main.swift diff --git a/lldb/test/Shell/Swift/No.swiftmodule-ObjC.test b/lldb/test/Shell/Swift/No.swiftmodule-ObjC.test index 5bb095f0c7384..eb206d54ed078 100644 --- a/lldb/test/Shell/Swift/No.swiftmodule-ObjC.test +++ b/lldb/test/Shell/Swift/No.swiftmodule-ObjC.test @@ -1,4 +1,5 @@ # REQUIRES: system-darwin +# REQUIRES: swift # This tests debugging without the presence of a .swiftmodule. # RUN: rm -rf %t && mkdir %t && cd %t diff --git a/lldb/test/Shell/Swift/No.swiftmodule.test b/lldb/test/Shell/Swift/No.swiftmodule.test index e5d8120add8ae..ca58778ca05e8 100644 --- a/lldb/test/Shell/Swift/No.swiftmodule.test +++ b/lldb/test/Shell/Swift/No.swiftmodule.test @@ -1,4 +1,5 @@ # This tests debugging without the presence of a .swiftmodule. +# REQUIRES: swift # RUN: rm -rf %t && mkdir %t && cd %t # diff --git a/lldb/test/Shell/Swift/RemoteASTImport.test b/lldb/test/Shell/Swift/RemoteASTImport.test index 12c8db67c4a49..06522707862a4 100644 --- a/lldb/test/Shell/Swift/RemoteASTImport.test +++ b/lldb/test/Shell/Swift/RemoteASTImport.test @@ -1,4 +1,5 @@ # REQUIRES: system-darwin +# REQUIRES: swift # This tests that RemoteAST querying the dynamic type of a variable # doesn't import any modules into a module SwiftASTContext that diff --git a/lldb/test/Shell/Swift/astcontext_error.test b/lldb/test/Shell/Swift/astcontext_error.test index 1840ee7c1bf93..cfe0692724453 100644 --- a/lldb/test/Shell/Swift/astcontext_error.test +++ b/lldb/test/Shell/Swift/astcontext_error.test @@ -1,3 +1,4 @@ +# REQUIRES: swift # RUN: rm -rf %t && mkdir %t && cd %t # RUN: %target-swiftc -g %S/Inputs/ContextError.swift # RUN: %lldb ContextError -s %s | FileCheck %S/Inputs/ContextError.swift diff --git a/lldb/test/Shell/Swift/cond-breakpoint.test b/lldb/test/Shell/Swift/cond-breakpoint.test index 3346e7306ef61..3cf5a6c60ad66 100644 --- a/lldb/test/Shell/Swift/cond-breakpoint.test +++ b/lldb/test/Shell/Swift/cond-breakpoint.test @@ -1,3 +1,4 @@ +# REQUIRES: swift # RUN: rm -rf %t && mkdir %t && cd %t # RUN: %target-swiftc -g %S/Inputs/main.swift -o a.out # RUN: %lldb a.out -b -s %s 2>&1 | FileCheck %s diff --git a/lldb/test/Shell/Swift/global.test b/lldb/test/Shell/Swift/global.test index 76e2ffe5b6969..17a1e1e7e66f8 100644 --- a/lldb/test/Shell/Swift/global.test +++ b/lldb/test/Shell/Swift/global.test @@ -1,3 +1,5 @@ +# REQUIRES: swift + # RUN: rm -rf %t && mkdir %t && cd %t # RUN: %target-swiftc -g \ # RUN: -module-cache-path %t/cache %S/Inputs/Global.swift \ diff --git a/lldb/test/Shell/Swift/runtime-initialization.test b/lldb/test/Shell/Swift/runtime-initialization.test index 5a68d976e4ef3..6589dea965caa 100644 --- a/lldb/test/Shell/Swift/runtime-initialization.test +++ b/lldb/test/Shell/Swift/runtime-initialization.test @@ -1,3 +1,4 @@ +# REQUIRES: swift # RUN: rm -rf %t && mkdir %t # RUN: %target-swiftc -g \ # RUN: -module-cache-path %t/cache %S/Inputs/RuntimeInit.swift \ diff --git a/lldb/test/Shell/SwiftREPL/Basic.test b/lldb/test/Shell/SwiftREPL/Basic.test index dc5b54a7dc06a..d7fba8631dc57 100644 --- a/lldb/test/Shell/SwiftREPL/Basic.test +++ b/lldb/test/Shell/SwiftREPL/Basic.test @@ -1,4 +1,5 @@ // Basic sanity checking of the REPL. +// REQUIRES: swift // RUN: %lldb --repl --repl-language swift | FileCheck %s --check-prefix=SWIFT // SWIFT: Welcome to {{.*}}Swift diff --git a/lldb/test/Shell/SwiftREPL/BreakpointSimple.test b/lldb/test/Shell/SwiftREPL/BreakpointSimple.test index d462bf6c164fd..d43ce111c14c5 100644 --- a/lldb/test/Shell/SwiftREPL/BreakpointSimple.test +++ b/lldb/test/Shell/SwiftREPL/BreakpointSimple.test @@ -1,5 +1,5 @@ // Test that we can set breakpoints in the REPL. - +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s func foo() -> Int { diff --git a/lldb/test/Shell/SwiftREPL/CFString.test b/lldb/test/Shell/SwiftREPL/CFString.test index 721febb3d9517..2d7b9985dc154 100644 --- a/lldb/test/Shell/SwiftREPL/CFString.test +++ b/lldb/test/Shell/SwiftREPL/CFString.test @@ -1,5 +1,6 @@ // Test that CFString works in the REPL. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s // CHECK: Welcome to {{.*}}Swift diff --git a/lldb/test/Shell/SwiftREPL/Class.test b/lldb/test/Shell/SwiftREPL/Class.test index ed051ba0ff0d5..e649f989f13e0 100644 --- a/lldb/test/Shell/SwiftREPL/Class.test +++ b/lldb/test/Shell/SwiftREPL/Class.test @@ -1,4 +1,5 @@ // Test that we can define and use a basic class. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/ComputedProperties.test b/lldb/test/Shell/SwiftREPL/ComputedProperties.test index cb90047417023..6539cf3efbea6 100644 --- a/lldb/test/Shell/SwiftREPL/ComputedProperties.test +++ b/lldb/test/Shell/SwiftREPL/ComputedProperties.test @@ -1,4 +1,5 @@ // Check that we print computed properties correctly. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/CrashArgs.test b/lldb/test/Shell/SwiftREPL/CrashArgs.test index eebd222bb1aea..f503dbfe465ed 100644 --- a/lldb/test/Shell/SwiftREPL/CrashArgs.test +++ b/lldb/test/Shell/SwiftREPL/CrashArgs.test @@ -1,4 +1,5 @@ // Make sure we don't crash if we pass args to the repl. +// REQUIRES: swift // RUN: %lldb --repl="-some-argument" | FileCheck %s --check-prefix=SWIFT // SWIFT: Welcome to {{.*}}Swift diff --git a/lldb/test/Shell/SwiftREPL/Deadlock.test b/lldb/test/Shell/SwiftREPL/Deadlock.test index b203428d39681..fa996871d59ad 100644 --- a/lldb/test/Shell/SwiftREPL/Deadlock.test +++ b/lldb/test/Shell/SwiftREPL/Deadlock.test @@ -1,3 +1,5 @@ +// REQUIRES: swift + // RUN: %lldb --repl < %s | FileCheck %s // From https://bugs.swift.org/browse/SR-7114 @@ -5,11 +7,11 @@ let a = 9007199254740991.0 // CHECK: a: Double = 9007199254740991 -(a * a - a * a).squareRoot() +(a * a - a * a).squareRoot() // CHECK: (Double) = { // CHECK-NEXT: _value = 0 // CHECK-NEXT: } (a * a).addingProduct(-a, a).squareRoot() // CHECK: (Double) = { -// CHECK-NEXT: _value = NaN +// CHECK-NEXT: _value = NaN // CHECK-NEXT: } diff --git a/lldb/test/Shell/SwiftREPL/DeferredNSArray.test b/lldb/test/Shell/SwiftREPL/DeferredNSArray.test index fc994f14622a5..b32633363a583 100644 --- a/lldb/test/Shell/SwiftREPL/DeferredNSArray.test +++ b/lldb/test/Shell/SwiftREPL/DeferredNSArray.test @@ -1,5 +1,6 @@ // Test that NSDeferredArray data formatter works. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/DeploymentTarget.test b/lldb/test/Shell/SwiftREPL/DeploymentTarget.test index 62fed643676f1..ab18d90ba577c 100644 --- a/lldb/test/Shell/SwiftREPL/DeploymentTarget.test +++ b/lldb/test/Shell/SwiftREPL/DeploymentTarget.test @@ -1,5 +1,6 @@ // Test that the REPL can call a *really* new function. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: echo -n "@available(macOS " >%t.swift // RUN: python -c 'from __future__ import print_function; import platform; print(platform.mac_ver()[0],end="")' >>%t.swift diff --git a/lldb/test/Shell/SwiftREPL/Dict.test b/lldb/test/Shell/SwiftREPL/Dict.test index dd6b9ead68a11..3e1ef2b9ac76c 100644 --- a/lldb/test/Shell/SwiftREPL/Dict.test +++ b/lldb/test/Shell/SwiftREPL/Dict.test @@ -1,4 +1,5 @@ // Test that the dictionary data formatter works in the REPL. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s --check-prefix=DICT diff --git a/lldb/test/Shell/SwiftREPL/DictBridging.test b/lldb/test/Shell/SwiftREPL/DictBridging.test index e7bae8548e94c..68ad3f2ea026c 100644 --- a/lldb/test/Shell/SwiftREPL/DictBridging.test +++ b/lldb/test/Shell/SwiftREPL/DictBridging.test @@ -1,6 +1,8 @@ // -*- mode: swift; -*- // Test formatters on bridged dictionaries in the REPL. // REQUIRES: system-darwin +// REQUIRES: swift + // RUN: %lldb --repl < %s | FileCheck %s --check-prefix=DICT import Foundation diff --git a/lldb/test/Shell/SwiftREPL/ErrorReturn.test b/lldb/test/Shell/SwiftREPL/ErrorReturn.test index 025bb92f88d0d..e61733687b4b5 100644 --- a/lldb/test/Shell/SwiftREPL/ErrorReturn.test +++ b/lldb/test/Shell/SwiftREPL/ErrorReturn.test @@ -1,6 +1,7 @@ // XFAIL: powerpc64le // SR-10212 // Test that we can handle errors. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/ErrorReturnObjC.test b/lldb/test/Shell/SwiftREPL/ErrorReturnObjC.test index 304cc136329b5..718958d6490ce 100644 --- a/lldb/test/Shell/SwiftREPL/ErrorReturnObjC.test +++ b/lldb/test/Shell/SwiftREPL/ErrorReturnObjC.test @@ -2,6 +2,7 @@ // types when they're stored in REPL-defined globals. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/ExclusivityREPL.test b/lldb/test/Shell/SwiftREPL/ExclusivityREPL.test index 030187700d52d..e8f1ed47ac7eb 100644 --- a/lldb/test/Shell/SwiftREPL/ExclusivityREPL.test +++ b/lldb/test/Shell/SwiftREPL/ExclusivityREPL.test @@ -1,4 +1,5 @@ // Runtime checks for exclusive access should be enabled in the REPL. +// REQUIRES: swift // RUN: %lldb --repl < %s 2>&1 | FileCheck %s // CHECK: modification requires exclusive access diff --git a/lldb/test/Shell/SwiftREPL/FoundationTypes.test b/lldb/test/Shell/SwiftREPL/FoundationTypes.test index e25acce3fb266..a39d8c95daf47 100644 --- a/lldb/test/Shell/SwiftREPL/FoundationTypes.test +++ b/lldb/test/Shell/SwiftREPL/FoundationTypes.test @@ -2,6 +2,7 @@ // types when they're stored in REPL-defined globals. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/FrameworkPath.test b/lldb/test/Shell/SwiftREPL/FrameworkPath.test index b6e73e11af21f..95d0019ce41e4 100644 --- a/lldb/test/Shell/SwiftREPL/FrameworkPath.test +++ b/lldb/test/Shell/SwiftREPL/FrameworkPath.test @@ -1,5 +1,6 @@ // Test target.swift-framework-search-paths works in the REPL. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: %lldb -O "settings set target.swift-framework-search-paths %S/Inputs/Frameworks" --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/GLKIT.test b/lldb/test/Shell/SwiftREPL/GLKIT.test index 8260006a82654..ddeaa1b5bd92f 100644 --- a/lldb/test/Shell/SwiftREPL/GLKIT.test +++ b/lldb/test/Shell/SwiftREPL/GLKIT.test @@ -1,5 +1,6 @@ // Test formatters for Accelerate/simd. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/GenericTypealias.test b/lldb/test/Shell/SwiftREPL/GenericTypealias.test index bbd0792ff948c..032aacd9f7eb8 100644 --- a/lldb/test/Shell/SwiftREPL/GenericTypealias.test +++ b/lldb/test/Shell/SwiftREPL/GenericTypealias.test @@ -1,4 +1,6 @@ // Test that generic typealiases are reconstructed correctly. +// REQUIRES: swift + // RUN: %lldb --repl < %s | FileCheck %s class Tinky { diff --git a/lldb/test/Shell/SwiftREPL/Generics.test b/lldb/test/Shell/SwiftREPL/Generics.test index 9674453acedfe..eaf8598a1c3b9 100644 --- a/lldb/test/Shell/SwiftREPL/Generics.test +++ b/lldb/test/Shell/SwiftREPL/Generics.test @@ -1,4 +1,5 @@ // Test that generics work in the REPL. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/ImportCocoa.test b/lldb/test/Shell/SwiftREPL/ImportCocoa.test index 3d15ad2874b6f..ce2f4f20aaf84 100644 --- a/lldb/test/Shell/SwiftREPL/ImportCocoa.test +++ b/lldb/test/Shell/SwiftREPL/ImportCocoa.test @@ -1,5 +1,6 @@ // Test that importing Cocoa works. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: %lldb --repl < %s 2>&1 | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/ImportDispatch.test b/lldb/test/Shell/SwiftREPL/ImportDispatch.test index b36eae691b2aa..b1cc611245063 100644 --- a/lldb/test/Shell/SwiftREPL/ImportDispatch.test +++ b/lldb/test/Shell/SwiftREPL/ImportDispatch.test @@ -1,5 +1,6 @@ // Test that importing Dispatch works. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: %lldb --repl < %s 2>&1 | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/ImportError.test b/lldb/test/Shell/SwiftREPL/ImportError.test index 44fe179103c57..435f3554014c0 100644 --- a/lldb/test/Shell/SwiftREPL/ImportError.test +++ b/lldb/test/Shell/SwiftREPL/ImportError.test @@ -1,4 +1,5 @@ // Test that importing non-existing module fails. +// REQUIRES: swift // RUN: %lldb --repl < %s 2>&1 | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/ImportFoundation.test b/lldb/test/Shell/SwiftREPL/ImportFoundation.test index a3b481bdad897..751f83ccbb533 100644 --- a/lldb/test/Shell/SwiftREPL/ImportFoundation.test +++ b/lldb/test/Shell/SwiftREPL/ImportFoundation.test @@ -1,5 +1,6 @@ // Test that type lookup chooses the right language. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/InitFile.test b/lldb/test/Shell/SwiftREPL/InitFile.test index b3363df20d4a8..a3fefab62c919 100644 --- a/lldb/test/Shell/SwiftREPL/InitFile.test +++ b/lldb/test/Shell/SwiftREPL/InitFile.test @@ -1,5 +1,7 @@ // Test that the Swift REPL init file works. // REQUIRES: system-darwin +// REQUIRES: swift + // RUN: export HOME=%t // RUN: mkdir -p %t // RUN: echo 'br set -f main.c -l 123' > ~/.lldbinit diff --git a/lldb/test/Shell/SwiftREPL/LookupAfterImport.test b/lldb/test/Shell/SwiftREPL/LookupAfterImport.test index d067501e5f155..ae763e2bb5895 100644 --- a/lldb/test/Shell/SwiftREPL/LookupAfterImport.test +++ b/lldb/test/Shell/SwiftREPL/LookupAfterImport.test @@ -1,5 +1,6 @@ // Make sure we properly load in new extension members after an import. // rdar://64040436 +// REQUIRES: swift // RUN: rm -rf %t // RUN: mkdir %t diff --git a/lldb/test/Shell/SwiftREPL/MetatypeRepl.test b/lldb/test/Shell/SwiftREPL/MetatypeRepl.test index ad88d7dae1f30..979286e442b37 100644 --- a/lldb/test/Shell/SwiftREPL/MetatypeRepl.test +++ b/lldb/test/Shell/SwiftREPL/MetatypeRepl.test @@ -1,3 +1,5 @@ +// REQUIRES: swift + // RUN: %lldb --repl < %s | FileCheck %s let x = [Double.self] diff --git a/lldb/test/Shell/SwiftREPL/NSObjectSubclass.test b/lldb/test/Shell/SwiftREPL/NSObjectSubclass.test index 0b9784527f96a..fbf8db07d531a 100644 --- a/lldb/test/Shell/SwiftREPL/NSObjectSubclass.test +++ b/lldb/test/Shell/SwiftREPL/NSObjectSubclass.test @@ -1,5 +1,6 @@ // Test that the REPL allows defining subclasses of NSObject. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/NSString.test b/lldb/test/Shell/SwiftREPL/NSString.test index 34fa250947a79..f31a73eb4481d 100644 --- a/lldb/test/Shell/SwiftREPL/NSString.test +++ b/lldb/test/Shell/SwiftREPL/NSString.test @@ -1,5 +1,6 @@ // Test that NSString works in the REPL. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s --check-prefix=NSSTRING diff --git a/lldb/test/Shell/SwiftREPL/OpenClass.test b/lldb/test/Shell/SwiftREPL/OpenClass.test index 4239f8e337b8a..a32b1d6be1cd5 100644 --- a/lldb/test/Shell/SwiftREPL/OpenClass.test +++ b/lldb/test/Shell/SwiftREPL/OpenClass.test @@ -1,4 +1,5 @@ // RUN: %lldb --repl < %s 2>&1 | FileCheck %s +// REQUIRES: swift class Foo { // Don't make any of these 'open'. diff --git a/lldb/test/Shell/SwiftREPL/Optional.test b/lldb/test/Shell/SwiftREPL/Optional.test index b6d3ac77b12c1..47e9749f190e8 100644 --- a/lldb/test/Shell/SwiftREPL/Optional.test +++ b/lldb/test/Shell/SwiftREPL/Optional.test @@ -1,4 +1,5 @@ // RUN: %lldb --repl < %s | FileCheck %s +// REQUIRES: swift enum Patatino { case first diff --git a/lldb/test/Shell/SwiftREPL/OptionalUnowned.test b/lldb/test/Shell/SwiftREPL/OptionalUnowned.test index 4d3e8aa2e9e19..c855e97868e43 100644 --- a/lldb/test/Shell/SwiftREPL/OptionalUnowned.test +++ b/lldb/test/Shell/SwiftREPL/OptionalUnowned.test @@ -1,3 +1,5 @@ +// REQUIRES: swift + // RUN: %lldb --repl < %s | FileCheck %s class C diff --git a/lldb/test/Shell/SwiftREPL/OptionalWithDynamicType.test b/lldb/test/Shell/SwiftREPL/OptionalWithDynamicType.test index 56f8499931864..a52a53766b4ee 100644 --- a/lldb/test/Shell/SwiftREPL/OptionalWithDynamicType.test +++ b/lldb/test/Shell/SwiftREPL/OptionalWithDynamicType.test @@ -2,6 +2,7 @@ // optional. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: %lldb --repl < %s 2>&1 | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/PropertyWrapperPrivate.test b/lldb/test/Shell/SwiftREPL/PropertyWrapperPrivate.test index 4e982cbb97463..af9c34fd4a4a8 100644 --- a/lldb/test/Shell/SwiftREPL/PropertyWrapperPrivate.test +++ b/lldb/test/Shell/SwiftREPL/PropertyWrapperPrivate.test @@ -1,5 +1,6 @@ // Test that we don't crash when SILGen(ing) property wrappers // [private]. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/PropertyWrapperPublic.test b/lldb/test/Shell/SwiftREPL/PropertyWrapperPublic.test index 2da16b84ac186..5d0cade5b25cd 100644 --- a/lldb/test/Shell/SwiftREPL/PropertyWrapperPublic.test +++ b/lldb/test/Shell/SwiftREPL/PropertyWrapperPublic.test @@ -1,5 +1,6 @@ // Test that we don't crash when SILGen(ing) property wrappers // [public]. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/PropertyWrapperTopLevel.test b/lldb/test/Shell/SwiftREPL/PropertyWrapperTopLevel.test index 3ad2007532aed..99dee0ae85957 100644 --- a/lldb/test/Shell/SwiftREPL/PropertyWrapperTopLevel.test +++ b/lldb/test/Shell/SwiftREPL/PropertyWrapperTopLevel.test @@ -1,3 +1,5 @@ +// REQUIRES: swift + // RUN: %lldb --repl < %s 2>&1 | FileCheck %s @propertyWrapper struct A { diff --git a/lldb/test/Shell/SwiftREPL/RecursiveClass.test b/lldb/test/Shell/SwiftREPL/RecursiveClass.test index c002c7580d5d3..f36ed92d6ada9 100644 --- a/lldb/test/Shell/SwiftREPL/RecursiveClass.test +++ b/lldb/test/Shell/SwiftREPL/RecursiveClass.test @@ -1,4 +1,5 @@ // Test that recursive class instances work in the REPL. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/Redefinition.test b/lldb/test/Shell/SwiftREPL/Redefinition.test index 11aebcd36f768..a265e92756b64 100644 --- a/lldb/test/Shell/SwiftREPL/Redefinition.test +++ b/lldb/test/Shell/SwiftREPL/Redefinition.test @@ -1,4 +1,5 @@ // Test that we can set breakpoints in the REPL. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/RedirectInput.test b/lldb/test/Shell/SwiftREPL/RedirectInput.test index be48c037ffcb9..eadb5d7ef3566 100644 --- a/lldb/test/Shell/SwiftREPL/RedirectInput.test +++ b/lldb/test/Shell/SwiftREPL/RedirectInput.test @@ -1,4 +1,5 @@ // Test that input can be redirected from A.swift +// REQUIRES: swift // RUN: mkdir -p %t // RUN: cp %S/Inputs/A.swift %t/A.swift diff --git a/lldb/test/Shell/SwiftREPL/RedirectInputNoSuchFile.test b/lldb/test/Shell/SwiftREPL/RedirectInputNoSuchFile.test index d0b6c847145cd..c76364138ba55 100644 --- a/lldb/test/Shell/SwiftREPL/RedirectInputNoSuchFile.test +++ b/lldb/test/Shell/SwiftREPL/RedirectInputNoSuchFile.test @@ -1,4 +1,5 @@ // Test that input can't be redirected from non-existent file A.swift +// REQUIRES: swift // RUN: mkdir -p %t // RUN: cd %t diff --git a/lldb/test/Shell/SwiftREPL/RedirectInputUnreadable.test b/lldb/test/Shell/SwiftREPL/RedirectInputUnreadable.test index a252673f43a69..8f74532d1bded 100644 --- a/lldb/test/Shell/SwiftREPL/RedirectInputUnreadable.test +++ b/lldb/test/Shell/SwiftREPL/RedirectInputUnreadable.test @@ -1,4 +1,5 @@ // Test that input can't be redirected from unreadable A.swift +// REQUIRES: swift // RUN: mkdir -p %t // RUN: cp %S/Inputs/A.swift %t/A.swift diff --git a/lldb/test/Shell/SwiftREPL/ResilientArray.test b/lldb/test/Shell/SwiftREPL/ResilientArray.test index 38d3fbdebe6c2..dbf9006cd2b2b 100644 --- a/lldb/test/Shell/SwiftREPL/ResilientArray.test +++ b/lldb/test/Shell/SwiftREPL/ResilientArray.test @@ -1,4 +1,6 @@ // REQUIRES: system-darwin +// REQUIRES: swift + // RUN: %lldb --repl < %s | FileCheck %s import Foundation diff --git a/lldb/test/Shell/SwiftREPL/ResilientDict.test b/lldb/test/Shell/SwiftREPL/ResilientDict.test index 0b7eea68d73c0..6be96a29ec12e 100644 --- a/lldb/test/Shell/SwiftREPL/ResilientDict.test +++ b/lldb/test/Shell/SwiftREPL/ResilientDict.test @@ -1,4 +1,6 @@ // REQUIRES: system-darwin +// REQUIRES: swift + // RUN: %lldb --repl < %s | FileCheck %s --check-prefix=DICT // The dictionary order isn't deterministic, so print the dictionary @@ -6,14 +8,14 @@ import Foundation -let x : [URL:Int] = [URL(string: "https://github.com")!: 4, URL(string: "https://apple.com")!: 23] +let x : [URL:Int] = [URL(string: "https://github.com")!: 4, URL(string: "https://apple.com")!: 23] // DICT-LABEL: {{x}}: [URL : Int] = 2 key/value pairs { // DICT: [{{[0-1]}}] = { // DICT: key = "https://apple.com" // DICT-NEXT: value = 23 // DICT-NEXT: } -let y : [URL:Int] = [URL(string: "https://github.com")!: 4, URL(string: "https://apple.com")!: 23] +let y : [URL:Int] = [URL(string: "https://github.com")!: 4, URL(string: "https://apple.com")!: 23] // DICT-LABEL: {{y}}: [URL : Int] = 2 key/value pairs { // DICT: [{{[0-1]}}] = { // DICT: key = "https://github.com" diff --git a/lldb/test/Shell/SwiftREPL/SIMD.test b/lldb/test/Shell/SwiftREPL/SIMD.test index 708b944ef4b45..c4fb14c7ccf71 100644 --- a/lldb/test/Shell/SwiftREPL/SIMD.test +++ b/lldb/test/Shell/SwiftREPL/SIMD.test @@ -1,5 +1,6 @@ // Test formatters for SIMD. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/SetBridging.test b/lldb/test/Shell/SwiftREPL/SetBridging.test index 4c7aca292f144..98d70e13e2853 100644 --- a/lldb/test/Shell/SwiftREPL/SetBridging.test +++ b/lldb/test/Shell/SwiftREPL/SetBridging.test @@ -1,6 +1,8 @@ // -*- mode: swift; -*- // Test formatters on bridged sets in the REPL. // REQUIRES: system-darwin +// REQUIRES: swift + // RUN: %lldb --repl < %s | FileCheck %s --check-prefix=SET import Foundation diff --git a/lldb/test/Shell/SwiftREPL/SimpleExpressions.test b/lldb/test/Shell/SwiftREPL/SimpleExpressions.test index 5b65ddb500dab..8331973801a05 100644 --- a/lldb/test/Shell/SwiftREPL/SimpleExpressions.test +++ b/lldb/test/Shell/SwiftREPL/SimpleExpressions.test @@ -1,5 +1,6 @@ // Test that we can define and use basic functions/expressions in the REPL. // Note: All of this should work on all supported platforms. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/SleepREPL.test b/lldb/test/Shell/SwiftREPL/SleepREPL.test index 13f254520f0ab..0f480afc41862 100644 --- a/lldb/test/Shell/SwiftREPL/SleepREPL.test +++ b/lldb/test/Shell/SwiftREPL/SleepREPL.test @@ -1,5 +1,6 @@ // Test that we can sleep in the repl // REQUIRES: system-darwin +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s --check-prefix=SLEEP diff --git a/lldb/test/Shell/SwiftREPL/String.test b/lldb/test/Shell/SwiftREPL/String.test index 3aaa00ca964b1..2d5e50ccd0057 100644 --- a/lldb/test/Shell/SwiftREPL/String.test +++ b/lldb/test/Shell/SwiftREPL/String.test @@ -1,5 +1,6 @@ // Test that String works in the REPL. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s --check-prefix=STRING diff --git a/lldb/test/Shell/SwiftREPL/Struct.test b/lldb/test/Shell/SwiftREPL/Struct.test index 842125f91d7bc..5f86fa6759bc9 100644 --- a/lldb/test/Shell/SwiftREPL/Struct.test +++ b/lldb/test/Shell/SwiftREPL/Struct.test @@ -1,4 +1,5 @@ // Test that we can define and use structs in the REPL. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/Subclassing.test b/lldb/test/Shell/SwiftREPL/Subclassing.test index fb81821a22df3..c99bdb43d70ac 100644 --- a/lldb/test/Shell/SwiftREPL/Subclassing.test +++ b/lldb/test/Shell/SwiftREPL/Subclassing.test @@ -1,4 +1,5 @@ // Test that subclassing works in the repl. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/SwiftInterface.test b/lldb/test/Shell/SwiftREPL/SwiftInterface.test index 558d3598d5702..37e9bfcddc879 100644 --- a/lldb/test/Shell/SwiftREPL/SwiftInterface.test +++ b/lldb/test/Shell/SwiftREPL/SwiftInterface.test @@ -1,4 +1,5 @@ // Test that .swiftinterface files can be loaded via the repl. +// REQUIRES: swift // RUN: rm -rf %t // RUN: mkdir %t diff --git a/lldb/test/Shell/SwiftREPL/SwiftInterfaceForceModuleLoadMode.test b/lldb/test/Shell/SwiftREPL/SwiftInterfaceForceModuleLoadMode.test index 4bec05e5a6ffc..ac71e2c198458 100644 --- a/lldb/test/Shell/SwiftREPL/SwiftInterfaceForceModuleLoadMode.test +++ b/lldb/test/Shell/SwiftREPL/SwiftInterfaceForceModuleLoadMode.test @@ -3,6 +3,7 @@ // Note: It intentionally does not check the only-interface or prefer-interface // modes as this also causes the Swift stdlib to be loaded via its module // interface file, which slows down this test considerably. +// REQUIRES: swift // RUN: rm -rf %t && mkdir %t diff --git a/lldb/test/Shell/SwiftREPL/SwiftTypeLookup.test b/lldb/test/Shell/SwiftREPL/SwiftTypeLookup.test index 0a5d67c75cd74..d320a4c1a3066 100644 --- a/lldb/test/Shell/SwiftREPL/SwiftTypeLookup.test +++ b/lldb/test/Shell/SwiftREPL/SwiftTypeLookup.test @@ -1,4 +1,5 @@ // Test that we don't crash when looking up types. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s --check-prefix=TYPE diff --git a/lldb/test/Shell/SwiftREPL/UninitVariables.test b/lldb/test/Shell/SwiftREPL/UninitVariables.test index f30dd331da692..e35a1fb9b8abb 100644 --- a/lldb/test/Shell/SwiftREPL/UninitVariables.test +++ b/lldb/test/Shell/SwiftREPL/UninitVariables.test @@ -1,4 +1,5 @@ // Document the way we handle uninitialized variables. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/ZeroSizeStruct.test b/lldb/test/Shell/SwiftREPL/ZeroSizeStruct.test index d30a4cc5b13a7..add267619f50a 100644 --- a/lldb/test/Shell/SwiftREPL/ZeroSizeStruct.test +++ b/lldb/test/Shell/SwiftREPL/ZeroSizeStruct.test @@ -1,4 +1,5 @@ // Test that we can define and use zero-sized struct in the repl. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s diff --git a/lldb/test/Shell/SwiftREPL/enum-singlecase.test b/lldb/test/Shell/SwiftREPL/enum-singlecase.test index ced4eb9c8a957..aec724705f2da 100644 --- a/lldb/test/Shell/SwiftREPL/enum-singlecase.test +++ b/lldb/test/Shell/SwiftREPL/enum-singlecase.test @@ -1,4 +1,5 @@ // RUN: %lldb --repl < %s 2>&1 | FileCheck %s +// REQUIRES: swift enum Foo: String { case patatino diff --git a/lldb/test/Shell/SwiftREPL/one-char-string.test b/lldb/test/Shell/SwiftREPL/one-char-string.test index 9c98f4fafd3c1..2afb920b8f0b9 100644 --- a/lldb/test/Shell/SwiftREPL/one-char-string.test +++ b/lldb/test/Shell/SwiftREPL/one-char-string.test @@ -1,5 +1,6 @@ // rdar://30147367 // Make sure that single character strings are displayed correctly. +// REQUIRES: swift // RUN: %lldb --repl < %s | FileCheck %s --check-prefix=STRING diff --git a/lldb/test/Shell/lit.cfg.py b/lldb/test/Shell/lit.cfg.py index ef4d9f6dc7ec1..f36bbfa6e01f8 100644 --- a/lldb/test/Shell/lit.cfg.py +++ b/lldb/test/Shell/lit.cfg.py @@ -121,6 +121,9 @@ def calculate_arch_features(arch_string): if config.lldb_enable_lua: config.available_features.add('lua') +if config.lldb_enable_swift: + config.available_features.add('swift') + if config.lldb_enable_lzma: config.available_features.add('lzma') diff --git a/lldb/test/Shell/lit.site.cfg.py.in b/lldb/test/Shell/lit.site.cfg.py.in index a89c6c7eab11d..04800cfb0c828 100644 --- a/lldb/test/Shell/lit.site.cfg.py.in +++ b/lldb/test/Shell/lit.site.cfg.py.in @@ -16,6 +16,7 @@ config.lldb_lit_tools_dir = r"@LLDB_LIT_TOOLS_DIR@" config.target_triple = "@TARGET_TRIPLE@" config.python_executable = "@Python3_EXECUTABLE@" config.swiftc = "@LLDB_SWIFTC@" +config.lldb_enable_swift = @LLDB_ENABLE_SWIFT_SUPPORT@ config.have_zlib = @LLVM_ENABLE_ZLIB@ config.lldb_enable_lzma = @LLDB_ENABLE_LZMA@ config.host_triple = "@LLVM_HOST_TRIPLE@" From 2c911bceb06ed376801251bdfd992905a66f276c Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 1 Oct 2020 12:29:00 +0200 Subject: [PATCH 073/234] [lldb][swift] Only run Swift API tests when Swift support is enabled Disabling Swift support in LLDB doesn't prevent the test suite from running the Swift tests (which then end up failing instead of being marked as unsupported). This adds swift to the SBDebugger configuration and then checks that Swift is enabled when running Swift API tests. --- lldb/packages/Python/lldbsuite/test/decorators.py | 3 +++ lldb/source/API/SBDebugger.cpp | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/lldb/packages/Python/lldbsuite/test/decorators.py b/lldb/packages/Python/lldbsuite/test/decorators.py index f627c72355428..f6acdf7bda9b2 100644 --- a/lldb/packages/Python/lldbsuite/test/decorators.py +++ b/lldb/packages/Python/lldbsuite/test/decorators.py @@ -626,6 +626,9 @@ def skipUnlessTargetAndroid(func): def swiftTest(func): """Decorate the item as a Swift test (Darwin/Linux only, no i386).""" def is_not_swift_compatible(self): + swift_enabled_error = _get_bool_config_skip_if_decorator("swift")(func) + if swift_enabled_error: + return swift_enabled_error if self.getDebugInfo() == "gmodules": return "skipping (gmodules only makes sense for clang tests)" diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index e8851333770c8..e1f64be177a4f 100644 --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -702,6 +702,12 @@ SBStructuredData SBDebugger::GetBuildConfiguration() { "A boolean value that indicates if lua support is enabled in LLDB"); AddLLVMTargets(*config_up); +#ifdef LLDB_ENABLE_SWIFT + AddBoolConfigEntry( + *config_up, "swift", true, + "A boolean value that indicates if Swift support is enabled in LLDB"); +#endif // LLDB_ENABLE_SWIFT + SBStructuredData data; data.m_impl_up->SetObjectSP(std::move(config_up)); return LLDB_RECORD_RESULT(data); From 121babae56e9f08acedf3d6d44757e35556d0a37 Mon Sep 17 00:00:00 2001 From: Qiu Chaofan Date: Tue, 6 Oct 2020 00:45:24 +0800 Subject: [PATCH 074/234] [SelectionDAG] Don't remove unused negated constant immediately This reverts partial of a2fb5446 (actually, 2508ef01) about removing negated FP constant immediately if it has no uses. However, as discussed in bug 47517, there're cases when NegX is folded into constant from other places while NegY is removed by that line of code and NegX is equal to NegY. In these cases, NegX is deleted before used and crash happens. So revert the code and add necessary test case. (cherry picked from commit b326d4ff946d2061a566a3fcce9f33b484759fe0) --- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 4 +--- llvm/test/CodeGen/X86/pr47517.ll | 13 +++++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 64af293caf9ea..8b3e6189a07f8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -5751,10 +5751,8 @@ SDValue TargetLowering::getNegatedExpression(SDValue Op, SelectionDAG &DAG, // If we already have the use of the negated floating constant, it is free // to negate it even it has multiple uses. - if (!Op.hasOneUse() && CFP.use_empty()) { - RemoveDeadNode(CFP); + if (!Op.hasOneUse() && CFP.use_empty()) break; - } Cost = NegatibleCost::Neutral; return CFP; } diff --git a/llvm/test/CodeGen/X86/pr47517.ll b/llvm/test/CodeGen/X86/pr47517.ll index 5672fbc69a41d..afc27b49ab2a4 100644 --- a/llvm/test/CodeGen/X86/pr47517.ll +++ b/llvm/test/CodeGen/X86/pr47517.ll @@ -26,3 +26,16 @@ entry: %fmul6 = fmul fast float %fmul3, %fadd4 ret float %fmul6 } + +; To ensure negated result will not be removed when NegX=NegY and +; NegX is needed +define float @test2(float %x, float %y) { + %add = fadd fast float %x, 750.0 + %sub = fsub fast float %x, %add + %mul = fmul fast float %sub, %sub + %mul2 = fmul fast float %mul, %sub + %add2 = fadd fast float %mul2, 1.0 + %add3 = fadd fast float %mul2, %add2 + %mul3 = fmul fast float %y, %add3 + ret float %mul3 +} From 7ad7c1b54c9299a8b4736958a946570e69fd6890 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Mon, 5 Oct 2020 16:35:23 -0700 Subject: [PATCH 075/234] [dotest] Simplify logic to find the Python path Simplify the logic of parsing the lldb -P output to find the python path. This removes the special handling for the LLDB.framework case and instead of pattern matching known errors focus on finding a directory path that contains an __init__.py. Differential revision: https://reviews.llvm.org/D88840 (cherry picked from commit f22496a9f4cabb97e735314b62731fedb2e01e50) --- lldb/packages/Python/lldbsuite/test/dotest.py | 92 ++++++------------- 1 file changed, 30 insertions(+), 62 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py index ffa24ce6bc312..36333e4c5cd3b 100644 --- a/lldb/packages/Python/lldbsuite/test/dotest.py +++ b/lldb/packages/Python/lldbsuite/test/dotest.py @@ -560,68 +560,33 @@ def setupSysPath(): configuration.skip_categories.append("lldb-vscode") lldbPythonDir = None # The directory that contains 'lldb/__init__.py' - if configuration.lldb_framework_path: - lldbtest_config.lldb_framework_path = configuration.lldb_framework_path - candidatePath = os.path.join( - configuration.lldb_framework_path, 'Resources', 'Python') - if os.path.isfile(os.path.join(candidatePath, 'lldb/__init__.py')): - lldbPythonDir = candidatePath - if not lldbPythonDir: - print( - 'Resources/Python/lldb/__init__.py was not found in ' + - configuration.lldb_framework_path) - sys.exit(-1) - else: - # If our lldb supports the -P option, use it to find the python path: - init_in_python_dir = os.path.join('lldb', '__init__.py') - - lldb_dash_p_result = subprocess.check_output( - [lldbtest_config.lldbExec, "-P"], stderr=subprocess.STDOUT, universal_newlines=True) - - if lldb_dash_p_result and not lldb_dash_p_result.startswith( - ("<", "lldb: invalid option:")) and not lldb_dash_p_result.startswith("Traceback"): - lines = lldb_dash_p_result.splitlines() - - # Workaround for readline vs libedit issue on FreeBSD. If stdout - # is not a terminal Python executes - # rl_variable_bind ("enable-meta-key", "off"); - # This produces a warning with FreeBSD's libedit because the - # enable-meta-key variable is unknown. Not an issue on Apple - # because cpython commit f0ab6f9f0603 added a #ifndef __APPLE__ - # around the call. See http://bugs.python.org/issue19884 for more - # information. For now we just discard the warning output. - if len(lines) >= 1 and lines[0].startswith( - "bind: Invalid command"): - lines.pop(0) - - # Taking the last line because lldb outputs - # 'Cannot read termcap database;\nusing dumb terminal settings.\n' - # before the path - if len(lines) >= 1 and os.path.isfile( - os.path.join(lines[-1], init_in_python_dir)): - lldbPythonDir = lines[-1] - if "freebsd" in sys.platform or "linux" in sys.platform: - os.environ['LLDB_LIB_DIR'] = os.path.join( - lldbPythonDir, '..', '..') - - if not lldbPythonDir: - print( - "Unable to load lldb extension module. Possible reasons for this include:") - print(" 1) LLDB was built with LLDB_ENABLE_PYTHON=0") - print( - " 2) PYTHONPATH and PYTHONHOME are not set correctly. PYTHONHOME should refer to") - print( - " the version of Python that LLDB built and linked against, and PYTHONPATH") - print( - " should contain the Lib directory for the same python distro, as well as the") - print(" location of LLDB\'s site-packages folder.") - print( - " 3) A different version of Python than that which was built against is exported in") - print(" the system\'s PATH environment variable, causing conflicts.") - print( - " 4) The executable '%s' could not be found. Please check " % - lldbtest_config.lldbExec) - print(" that it exists and is executable.") + + # If our lldb supports the -P option, use it to find the python path: + lldb_dash_p_result = subprocess.check_output([lldbtest_config.lldbExec, "-P"], universal_newlines=True) + if lldb_dash_p_result: + for line in lldb_dash_p_result.splitlines(): + if os.path.isdir(line) and os.path.exists(os.path.join(line, 'lldb', '__init__.py')): + lldbPythonDir = line + break + + if not lldbPythonDir: + print( + "Unable to load lldb extension module. Possible reasons for this include:") + print(" 1) LLDB was built with LLDB_ENABLE_PYTHON=0") + print( + " 2) PYTHONPATH and PYTHONHOME are not set correctly. PYTHONHOME should refer to") + print( + " the version of Python that LLDB built and linked against, and PYTHONPATH") + print( + " should contain the Lib directory for the same python distro, as well as the") + print(" location of LLDB\'s site-packages folder.") + print( + " 3) A different version of Python than that which was built against is exported in") + print(" the system\'s PATH environment variable, causing conflicts.") + print( + " 4) The executable '%s' could not be found. Please check " % + lldbtest_config.lldbExec) + print(" that it exists and is executable.") if lldbPythonDir: lldbPythonDir = os.path.normpath(lldbPythonDir) @@ -635,6 +600,9 @@ def setupSysPath(): lldbPythonDir = os.path.abspath(lldbPythonDir) + if "freebsd" in sys.platform or "linux" in sys.platform: + os.environ['LLDB_LIB_DIR'] = os.path.join(lldbPythonDir, '..', '..') + # If tests need to find LLDB_FRAMEWORK, now they can do it os.environ["LLDB_FRAMEWORK"] = os.path.dirname( os.path.dirname(lldbPythonDir)) From a88b9a023637a189dc54f9365263f22b6c865187 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 15 Sep 2020 13:37:44 -0700 Subject: [PATCH 076/234] [lldb] Reimplement and implement GetPointerType --- .../TypeSystem/Swift/SwiftASTContext.cpp | 9 +-- .../Swift/TypeSystemSwiftTypeRef.cpp | 62 +++++++++++++++++-- 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index 0141ba6bc7b73..c3806608723ad 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -5886,10 +5886,11 @@ CompilerType SwiftASTContext::GetPointerType(opaque_compiler_type_t type) { VALID_OR_RETURN(CompilerType()); if (type) { - swift::Type swift_type(GetSwiftType({this, type})); - const swift::TypeKind type_kind = swift_type->getKind(); - if (type_kind == swift::TypeKind::BuiltinRawPointer) - return ToCompilerType({swift_type}); + auto swift_type = GetSwiftType({this, type}); + auto pointer_type = + swift_type->wrapInPointer(swift::PointerTypeKind::PTK_UnsafePointer); + if (pointer_type) + return ToCompilerType(pointer_type); } return {}; } diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index 2cf9577a982cc..aa01a026ba4b0 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -90,8 +90,7 @@ GetClangTypeNode(CompilerType clang_type, swift::Demangle::Demangler &dem) { } /// \return the child of the \p Type node. -static swift::Demangle::NodePointer GetType(swift::Demangle::Demangler &dem, - swift::Demangle::NodePointer n) { +static NodePointer GetType(swift::Demangle::NodePointer n) { using namespace swift::Demangle; if (!n || n->getKind() != Node::Kind::Global || !n->hasChildren()) return nullptr; @@ -109,7 +108,7 @@ static swift::Demangle::NodePointer GetType(swift::Demangle::Demangler &dem, static swift::Demangle::NodePointer GetDemangledType(swift::Demangle::Demangler &dem, StringRef name) { NodePointer n = dem.demangleSymbol(name); - return GetType(dem, n); + return GetType(n); } /// Resolve a type alias node and return a demangle tree for the @@ -1291,7 +1290,7 @@ swift::Demangle::NodePointer TypeSystemSwiftTypeRef::DemangleCanonicalType( using namespace swift::Demangle; NodePointer node = GetCanonicalDemangleTree(GetModule(), dem, AsMangledName(opaque_type)); - return GetType(dem, node); + return GetType(node); } bool TypeSystemSwiftTypeRef::IsArrayType(opaque_compiler_type_t type, @@ -1669,9 +1668,62 @@ CompilerType TypeSystemSwiftTypeRef::GetPointeeType(opaque_compiler_type_t type) { return m_swift_ast_context->GetPointeeType(ReconstructType(type)); } + CompilerType TypeSystemSwiftTypeRef::GetPointerType(opaque_compiler_type_t type) { - return m_swift_ast_context->GetPointerType(ReconstructType(type)); + auto impl = [&]() -> CompilerType { + /* + kind=Type + kind=BoundGenericStructure + kind=Type + kind=Structure + kind=Module, text="Swift" + kind=Identifier, text="UnsafePointer" + kind=TypeList + kind=Type + kind=Structure + kind=Module, text="Swift" + kind=Identifier, text="Int" + */ + using namespace swift::Demangle; + Demangler dem; + + auto *pointee_type = GetType(dem.demangleSymbol(AsMangledName(type))); + + auto *pointer_type = dem.createNode(Node::Kind::Type); + auto *BGS = dem.createNode(Node::Kind::BoundGenericStructure); + pointer_type->addChild(BGS, dem); + + NodePointer parent; + NodePointer child; + + // Construct the first (Type) branch of BoundGenericStructure. + parent = BGS; + child = dem.createNode(Node::Kind::Type); + parent->addChild(child, dem); + parent = child; + child = dem.createNode(Node::Kind::Structure); + parent->addChild(child, dem); + parent = child; + parent->addChild( + dem.createNodeWithAllocatedText(Node::Kind::Module, swift::STDLIB_NAME), + dem); + parent->addChild(dem.createNode(Node::Kind::Identifier, "UnsafePointer"), + dem); + + // Construct the second (TypeList) branch of BoundGenericStructure. + parent = BGS; + child = dem.createNode(Node::Kind::TypeList); + parent->addChild(child, dem); + parent = child; + child = dem.createNode(Node::Kind::Type); + parent->addChild(child, dem); + parent = child; + parent->addChild(pointee_type, dem); + + return RemangleAsType(dem, pointer_type); + }; + VALIDATE_AND_RETURN(impl, GetPointerType, type, (ReconstructType(type))); } // Exploring the type From ca973564c1907bcda7ef23d17f804ab25e3022bb Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 6 Oct 2020 11:54:55 -0700 Subject: [PATCH 077/234] Remove development reference comment --- .../TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index aa01a026ba4b0..4134ceedf9fde 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1672,19 +1672,6 @@ TypeSystemSwiftTypeRef::GetPointeeType(opaque_compiler_type_t type) { CompilerType TypeSystemSwiftTypeRef::GetPointerType(opaque_compiler_type_t type) { auto impl = [&]() -> CompilerType { - /* - kind=Type - kind=BoundGenericStructure - kind=Type - kind=Structure - kind=Module, text="Swift" - kind=Identifier, text="UnsafePointer" - kind=TypeList - kind=Type - kind=Structure - kind=Module, text="Swift" - kind=Identifier, text="Int" - */ using namespace swift::Demangle; Demangler dem; From 8f837b62fae0e36937f15cabb09322ba2e5785b8 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 6 Oct 2020 12:03:12 -0700 Subject: [PATCH 078/234] Use GetDemangledType --- lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index 4134ceedf9fde..67873a967dbd9 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1675,7 +1675,7 @@ TypeSystemSwiftTypeRef::GetPointerType(opaque_compiler_type_t type) { using namespace swift::Demangle; Demangler dem; - auto *pointee_type = GetType(dem.demangleSymbol(AsMangledName(type))); + auto *pointee_type = GetDemangledType(dem, AsMangledName(type)); auto *pointer_type = dem.createNode(Node::Kind::Type); auto *BGS = dem.createNode(Node::Kind::BoundGenericStructure); From 6f0433b4450fc0879c770bc222182f46289a9a7b Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Sun, 4 Oct 2020 23:46:26 -0700 Subject: [PATCH 079/234] [llvm] Rename DwarfFile to DWARFFile to fix ODR violation (NFC) Rename the DwarfFile class in DWARFLinker to DWARFFile. This is consistent with the other DWARF classes and avoids a ODR violation with the DwarfFile class in AsmPrinter. (cherry picked from commit a58b20e5a4fb64404cb62d2bb6a5e6dc40d22784) --- llvm/include/llvm/DWARFLinker/DWARFLinker.h | 60 ++++++++++---------- llvm/lib/DWARFLinker/DWARFLinker.cpp | 40 ++++++------- llvm/tools/dsymutil/DwarfLinkerForBinary.cpp | 8 +-- llvm/tools/dsymutil/DwarfLinkerForBinary.h | 4 +- 4 files changed, 56 insertions(+), 56 deletions(-) diff --git a/llvm/include/llvm/DWARFLinker/DWARFLinker.h b/llvm/include/llvm/DWARFLinker/DWARFLinker.h index be3c5ebcadaeb..2fb61b9edf559 100644 --- a/llvm/include/llvm/DWARFLinker/DWARFLinker.h +++ b/llvm/include/llvm/DWARFLinker/DWARFLinker.h @@ -202,9 +202,9 @@ using UnitListTy = std::vector>; /// this class represents DWARF information for source file /// and it`s address map. -class DwarfFile { +class DWARFFile { public: - DwarfFile(StringRef Name, DWARFContext *Dwarf, AddressesMap *Addresses, + DWARFFile(StringRef Name, DWARFContext *Dwarf, AddressesMap *Addresses, const std::vector &Warnings) : FileName(Name), Dwarf(Dwarf), Addresses(Addresses), Warnings(Warnings) { } @@ -222,7 +222,7 @@ class DwarfFile { typedef std::function messageHandler; -typedef std::function(StringRef ContainerName, +typedef std::function(StringRef ContainerName, StringRef Path)> objFileLoader; typedef std::map swiftInterfacesMap; @@ -249,7 +249,7 @@ class DWARFLinker { : TheDwarfEmitter(Emitter), DwarfLinkerClientID(ClientID) {} /// Add object file to be linked. - void addObjectFile(DwarfFile &File); + void addObjectFile(DWARFFile &File); /// Link debug info for added objFiles. Object /// files are linked all together. @@ -376,13 +376,13 @@ class DWARFLinker { /// returns true if we need to translate strings. bool needToTranslateStrings() { return StringsTranslator != nullptr; } - void reportWarning(const Twine &Warning, const DwarfFile &File, + void reportWarning(const Twine &Warning, const DWARFFile &File, const DWARFDie *DIE = nullptr) const { if (Options.WarningHandler != nullptr) Options.WarningHandler(Warning, File.FileName, DIE); } - void reportError(const Twine &Warning, const DwarfFile &File, + void reportError(const Twine &Warning, const DWARFFile &File, const DWARFDie *DIE = nullptr) const { if (Options.ErrorHandler != nullptr) Options.ErrorHandler(Warning, File.FileName, DIE); @@ -398,18 +398,18 @@ class DWARFLinker { void updateAccelKind(DWARFContext &Dwarf); /// Emit warnings as Dwarf compile units to leave a trail after linking. - bool emitPaperTrailWarnings(const DwarfFile &File, + bool emitPaperTrailWarnings(const DWARFFile &File, OffsetsStringPool &StringPool); void copyInvariantDebugSection(DWARFContext &Dwarf); /// Keeps track of data associated with one object during linking. struct LinkContext { - DwarfFile &File; + DWARFFile &File; UnitListTy CompileUnits; bool Skip = false; - LinkContext(DwarfFile &File) : File(File) {} + LinkContext(DWARFFile &File) : File(File) {} /// Clear part of the context that's no longer needed when we're done with /// the debug object. @@ -438,7 +438,7 @@ class DWARFLinker { /// kept. All DIEs referenced though attributes should be kept. void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU, unsigned Flags, const UnitListTy &Units, - const DwarfFile &File, + const DWARFFile &File, SmallVectorImpl &Worklist); /// \defgroup FindRootDIEs Find DIEs corresponding to Address map entries. @@ -450,7 +450,7 @@ class DWARFLinker { /// The return value indicates whether the DIE is incomplete. void lookForDIEsToKeep(AddressesMap &RelocMgr, RangesTy &Ranges, const UnitListTy &Units, const DWARFDie &DIE, - const DwarfFile &File, CompileUnit &CU, + const DWARFFile &File, CompileUnit &CU, unsigned Flags); /// If this compile unit is really a skeleton CU that points to a @@ -460,7 +460,7 @@ class DWARFLinker { /// pointing to the module, and a DW_AT_gnu_dwo_id with the module /// hash. bool registerModuleReference(DWARFDie CUDie, const DWARFUnit &Unit, - const DwarfFile &File, + const DWARFFile &File, OffsetsStringPool &OffsetsStringPool, UniquingStringPool &UniquingStringPoolStringPool, DeclContextTree &ODRContexts, @@ -473,7 +473,7 @@ class DWARFLinker { /// to Units. Error loadClangModule(DWARFDie CUDie, StringRef FilePath, StringRef ModuleName, uint64_t DwoId, - const DwarfFile &File, + const DWARFFile &File, OffsetsStringPool &OffsetsStringPool, UniquingStringPool &UniquingStringPool, DeclContextTree &ODRContexts, uint64_t ModulesEndOffset, @@ -484,11 +484,11 @@ class DWARFLinker { void keepDIEAndDependencies(AddressesMap &RelocMgr, RangesTy &Ranges, const UnitListTy &Units, const DWARFDie &DIE, CompileUnit::DIEInfo &MyInfo, - const DwarfFile &File, CompileUnit &CU, + const DWARFFile &File, CompileUnit &CU, bool UseODR); unsigned shouldKeepDIE(AddressesMap &RelocMgr, RangesTy &Ranges, - const DWARFDie &DIE, const DwarfFile &File, + const DWARFDie &DIE, const DWARFFile &File, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo, unsigned Flags); @@ -499,7 +499,7 @@ class DWARFLinker { CompileUnit::DIEInfo &MyInfo, unsigned Flags); unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr, RangesTy &Ranges, - const DWARFDie &DIE, const DwarfFile &File, + const DWARFDie &DIE, const DWARFFile &File, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo, unsigned Flags); @@ -508,7 +508,7 @@ class DWARFLinker { /// RefValue. The resulting DIE might be in another CompileUnit which is /// stored into \p ReferencedCU. \returns null if resolving fails for any /// reason. - DWARFDie resolveDIEReference(const DwarfFile &File, const UnitListTy &Units, + DWARFDie resolveDIEReference(const DWARFFile &File, const UnitListTy &Units, const DWARFFormValue &RefValue, const DWARFDie &DIE, CompileUnit *&RefCU); @@ -523,7 +523,7 @@ class DWARFLinker { class DIECloner { DWARFLinker &Linker; DwarfEmitter *Emitter; - DwarfFile &ObjFile; + DWARFFile &ObjFile; /// Allocator used for all the DIEValue objects. BumpPtrAllocator &DIEAlloc; @@ -533,7 +533,7 @@ class DWARFLinker { bool Update; public: - DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DwarfFile &ObjFile, + DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DWARFFile &ObjFile, BumpPtrAllocator &DIEAlloc, std::vector> &CompileUnits, bool Update) @@ -551,7 +551,7 @@ class DWARFLinker { /// applied to the entry point of the function to get the linked address. /// \param Die the output DIE to use, pass NULL to create one. /// \returns the root of the cloned tree or null if nothing was selected. - DIE *cloneDIE(const DWARFDie &InputDIE, const DwarfFile &File, + DIE *cloneDIE(const DWARFDie &InputDIE, const DWARFFile &File, CompileUnit &U, OffsetsStringPool &StringPool, int64_t PCOffset, uint32_t OutOffset, unsigned Flags, bool IsLittleEndian, DIE *Die = nullptr); @@ -560,7 +560,7 @@ class DWARFLinker { /// chose to keep above. If there are no valid relocs, then there's /// nothing to clone/emit. uint64_t cloneAllCompileUnits(DWARFContext &DwarfContext, - const DwarfFile &File, + const DWARFFile &File, OffsetsStringPool &StringPool, bool IsLittleEndian); @@ -606,7 +606,7 @@ class DWARFLinker { /// Helper for cloneDIE. unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE, - const DwarfFile &File, CompileUnit &U, + const DWARFFile &File, CompileUnit &U, OffsetsStringPool &StringPool, const DWARFFormValue &Val, const AttributeSpec AttrSpec, unsigned AttrSize, @@ -627,18 +627,18 @@ class DWARFLinker { AttributeSpec AttrSpec, unsigned AttrSize, const DWARFFormValue &Val, - const DwarfFile &File, + const DWARFFile &File, CompileUnit &Unit); /// Clone a DWARF expression that may be referencing another DIE. void cloneExpression(DataExtractor &Data, DWARFExpression Expression, - const DwarfFile &File, CompileUnit &Unit, + const DWARFFile &File, CompileUnit &Unit, SmallVectorImpl &OutputBuffer); /// Clone an attribute referencing another DIE and add /// it to \p Die. /// \returns the size of the new attribute. - unsigned cloneBlockAttribute(DIE &Die, const DwarfFile &File, + unsigned cloneBlockAttribute(DIE &Die, const DWARFFile &File, CompileUnit &Unit, AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize, bool IsLittleEndian); @@ -654,7 +654,7 @@ class DWARFLinker { /// Clone a scalar attribute and add it to \p Die. /// \returns the size of the new attribute. unsigned cloneScalarAttribute(DIE &Die, const DWARFDie &InputDIE, - const DwarfFile &File, CompileUnit &U, + const DWARFFile &File, CompileUnit &U, AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize, AttributesInfo &Info); @@ -670,7 +670,7 @@ class DWARFLinker { void copyAbbrev(const DWARFAbbreviationDeclaration &Abbrev, bool hasODR); uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U, - const DwarfFile &File, + const DWARFFile &File, int RecurseDepth = 0); /// Helper for cloneDIE. @@ -685,7 +685,7 @@ class DWARFLinker { /// Compute and emit debug_ranges section for \p Unit, and /// patch the attributes referencing it. void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf, - const DwarfFile &File) const; + const DWARFFile &File) const; /// Generate and emit the DW_AT_ranges attribute for a compile_unit if it had /// one. @@ -695,7 +695,7 @@ class DWARFLinker { /// parts according to the linked function ranges and emit the result in the /// debug_line section. void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf, - const DwarfFile &File); + const DWARFFile &File); /// Emit the accelerator entries for \p Unit. void emitAcceleratorEntriesForUnit(CompileUnit &Unit); @@ -703,7 +703,7 @@ class DWARFLinker { void emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit); /// Patch the frame info for an object file and emit it. - void patchFrameInfoForObject(const DwarfFile &, RangesTy &Ranges, + void patchFrameInfoForObject(const DWARFFile &, RangesTy &Ranges, DWARFContext &, unsigned AddressSize); /// FoldingSet that uniques the abbreviations. diff --git a/llvm/lib/DWARFLinker/DWARFLinker.cpp b/llvm/lib/DWARFLinker/DWARFLinker.cpp index 12b19e77a4223..2b12274281055 100644 --- a/llvm/lib/DWARFLinker/DWARFLinker.cpp +++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp @@ -63,7 +63,7 @@ static CompileUnit *getUnitForOffset(const UnitListTy &Units, uint64_t Offset) { /// Resolve the DIE attribute reference that has been extracted in \p RefValue. /// The resulting DIE might be in another CompileUnit which is stored into \p /// ReferencedCU. \returns null if resolving fails for any reason. -DWARFDie DWARFLinker::resolveDIEReference(const DwarfFile &File, +DWARFDie DWARFLinker::resolveDIEReference(const DWARFFile &File, const UnitListTy &Units, const DWARFFormValue &RefValue, const DWARFDie &DIE, @@ -420,7 +420,7 @@ unsigned DWARFLinker::shouldKeepVariableDIE(AddressesMap &RelocMgr, /// \returns updated TraversalFlags. unsigned DWARFLinker::shouldKeepSubprogramDIE( AddressesMap &RelocMgr, RangesTy &Ranges, const DWARFDie &DIE, - const DwarfFile &File, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo, + const DWARFFile &File, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo, unsigned Flags) { const auto *Abbrev = DIE.getAbbreviationDeclarationPtr(); @@ -482,7 +482,7 @@ unsigned DWARFLinker::shouldKeepSubprogramDIE( /// Check if a DIE should be kept. /// \returns updated TraversalFlags. unsigned DWARFLinker::shouldKeepDIE(AddressesMap &RelocMgr, RangesTy &Ranges, - const DWARFDie &DIE, const DwarfFile &File, + const DWARFDie &DIE, const DWARFFile &File, CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo, unsigned Flags) { @@ -590,7 +590,7 @@ void DWARFLinker::lookForChildDIEsToKeep( /// kept. All DIEs referenced though attributes should be kept. void DWARFLinker::lookForRefDIEsToKeep( const DWARFDie &Die, CompileUnit &CU, unsigned Flags, - const UnitListTy &Units, const DwarfFile &File, + const UnitListTy &Units, const DWARFFile &File, SmallVectorImpl &Worklist) { bool UseOdr = (Flags & DWARFLinker::TF_DependencyWalk) ? (Flags & DWARFLinker::TF_ODR) @@ -700,7 +700,7 @@ void DWARFLinker::lookForParentDIEsToKeep( /// The return value indicates whether the DIE is incomplete. void DWARFLinker::lookForDIEsToKeep(AddressesMap &AddressesMap, RangesTy &Ranges, const UnitListTy &Units, - const DWARFDie &Die, const DwarfFile &File, + const DWARFDie &Die, const DWARFFile &File, CompileUnit &Cu, unsigned Flags) { // LIFO work list. SmallVector Worklist; @@ -838,7 +838,7 @@ unsigned DWARFLinker::DIECloner::cloneStringAttribute( unsigned DWARFLinker::DIECloner::cloneDieReferenceAttribute( DIE &Die, const DWARFDie &InputDIE, AttributeSpec AttrSpec, - unsigned AttrSize, const DWARFFormValue &Val, const DwarfFile &File, + unsigned AttrSize, const DWARFFormValue &Val, const DWARFFile &File, CompileUnit &Unit) { const DWARFUnit &U = Unit.getOrigUnit(); uint64_t Ref = *Val.getAsReference(); @@ -910,7 +910,7 @@ unsigned DWARFLinker::DIECloner::cloneDieReferenceAttribute( } void DWARFLinker::DIECloner::cloneExpression( - DataExtractor &Data, DWARFExpression Expression, const DwarfFile &File, + DataExtractor &Data, DWARFExpression Expression, const DWARFFile &File, CompileUnit &Unit, SmallVectorImpl &OutputBuffer) { using Encoding = DWARFExpression::Operation::Encoding; @@ -975,7 +975,7 @@ void DWARFLinker::DIECloner::cloneExpression( } unsigned DWARFLinker::DIECloner::cloneBlockAttribute( - DIE &Die, const DwarfFile &File, CompileUnit &Unit, AttributeSpec AttrSpec, + DIE &Die, const DWARFFile &File, CompileUnit &Unit, AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize, bool IsLittleEndian) { DIEValueList *Attr; DIEValue Value; @@ -1087,7 +1087,7 @@ unsigned DWARFLinker::DIECloner::cloneAddressAttribute( } unsigned DWARFLinker::DIECloner::cloneScalarAttribute( - DIE &Die, const DWARFDie &InputDIE, const DwarfFile &File, + DIE &Die, const DWARFDie &InputDIE, const DWARFFile &File, CompileUnit &Unit, AttributeSpec AttrSpec, const DWARFFormValue &Val, unsigned AttrSize, AttributesInfo &Info) { uint64_t Value; @@ -1155,7 +1155,7 @@ unsigned DWARFLinker::DIECloner::cloneScalarAttribute( /// value \p Val, and add it to \p Die. /// \returns the size of the cloned attribute. unsigned DWARFLinker::DIECloner::cloneAttribute( - DIE &Die, const DWARFDie &InputDIE, const DwarfFile &File, + DIE &Die, const DWARFDie &InputDIE, const DWARFFile &File, CompileUnit &Unit, OffsetsStringPool &StringPool, const DWARFFormValue &Val, const AttributeSpec AttrSpec, unsigned AttrSize, AttributesInfo &Info, bool IsLittleEndian) { @@ -1273,7 +1273,7 @@ shouldSkipAttribute(DWARFAbbreviationDeclaration::AttributeSpec AttrSpec, } DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE, - const DwarfFile &File, CompileUnit &Unit, + const DWARFFile &File, CompileUnit &Unit, OffsetsStringPool &StringPool, int64_t PCOffset, uint32_t OutOffset, unsigned Flags, bool IsLittleEndian, @@ -1483,7 +1483,7 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE, /// to point at the new entries. void DWARFLinker::patchRangesForUnit(const CompileUnit &Unit, DWARFContext &OrigDwarf, - const DwarfFile &File) const { + const DWARFFile &File) const { DWARFDebugRangeList RangeList; const auto &FunctionRanges = Unit.getFunctionRanges(); unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); @@ -1590,7 +1590,7 @@ static void patchStmtList(DIE &Die, DIEInteger Offset) { /// are present in the binary. void DWARFLinker::patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf, - const DwarfFile &File) { + const DWARFFile &File) { DWARFDie CUDie = Unit.getOrigUnit().getUnitDIE(); auto StmtList = dwarf::toSectionOffset(CUDie.find(dwarf::DW_AT_stmt_list)); if (!StmtList) @@ -1790,7 +1790,7 @@ void DWARFLinker::emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit) { /// This is actually pretty easy as the data of the CIEs and FDEs can /// be considered as black boxes and moved as is. The only thing to do /// is to patch the addresses in the headers. -void DWARFLinker::patchFrameInfoForObject(const DwarfFile &File, +void DWARFLinker::patchFrameInfoForObject(const DWARFFile &File, RangesTy &Ranges, DWARFContext &OrigDwarf, unsigned AddrSize) { @@ -1887,7 +1887,7 @@ void DWARFLinker::DIECloner::copyAbbrev( uint32_t DWARFLinker::DIECloner::hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U, - const DwarfFile &File, + const DWARFFile &File, int ChildRecurseDepth) { const char *Name = nullptr; DWARFUnit *OrigUnit = &U.getOrigUnit(); @@ -1952,7 +1952,7 @@ static std::string remapPath(StringRef Path, } bool DWARFLinker::registerModuleReference( - DWARFDie CUDie, const DWARFUnit &Unit, const DwarfFile &File, + DWARFDie CUDie, const DWARFUnit &Unit, const DWARFFile &File, OffsetsStringPool &StringPool, UniquingStringPool &UniquingStringPool, DeclContextTree &ODRContexts, uint64_t ModulesEndOffset, unsigned &UnitID, bool IsLittleEndian, unsigned Indent, bool Quiet) { @@ -2011,7 +2011,7 @@ bool DWARFLinker::registerModuleReference( Error DWARFLinker::loadClangModule( DWARFDie CUDie, StringRef Filename, StringRef ModuleName, uint64_t DwoId, - const DwarfFile &File, OffsetsStringPool &StringPool, + const DWARFFile &File, OffsetsStringPool &StringPool, UniquingStringPool &UniquingStringPool, DeclContextTree &ODRContexts, uint64_t ModulesEndOffset, unsigned &UnitID, bool IsLittleEndian, unsigned Indent, bool Quiet) { @@ -2096,7 +2096,7 @@ Error DWARFLinker::loadClangModule( } uint64_t DWARFLinker::DIECloner::cloneAllCompileUnits( - DWARFContext &DwarfContext, const DwarfFile &File, + DWARFContext &DwarfContext, const DWARFFile &File, OffsetsStringPool &StringPool, bool IsLittleEndian) { uint64_t OutputDebugInfoSize = Linker.Options.NoOutput ? 0 : Emitter->getDebugInfoSectionSize(); @@ -2190,7 +2190,7 @@ void DWARFLinker::updateAccelKind(DWARFContext &Dwarf) { } } -bool DWARFLinker::emitPaperTrailWarnings(const DwarfFile &File, +bool DWARFLinker::emitPaperTrailWarnings(const DWARFFile &File, OffsetsStringPool &StringPool) { if (File.Warnings.empty()) @@ -2267,7 +2267,7 @@ void DWARFLinker::copyInvariantDebugSection(DWARFContext &Dwarf) { "debug_aranges"); } -void DWARFLinker::addObjectFile(DwarfFile &File) { +void DWARFLinker::addObjectFile(DWARFFile &File) { ObjectContexts.emplace_back(LinkContext(File)); if (ObjectContexts.back().File.Dwarf) diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp index 07237e220c310..3c71567b54bbf 100644 --- a/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp +++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.cpp @@ -262,7 +262,7 @@ static Error emitRemarks(const LinkOptions &Options, StringRef BinaryPath, return Error::success(); } -ErrorOr +ErrorOr DwarfLinkerForBinary::loadObject(const DebugMapObject &Obj, const DebugMap &DebugMap, remarks::RemarkLinker &RL) { @@ -274,7 +274,7 @@ DwarfLinkerForBinary::loadObject(const DebugMapObject &Obj, AddressMapForLinking.push_back( std::make_unique(*this, *ErrorOrObj, Obj)); - ObjectsForLinking.push_back(std::make_unique( + ObjectsForLinking.push_back(std::make_unique( Obj.getObjectFilename(), ContextForLinking.back().get(), AddressMapForLinking.back().get(), Obj.empty() ? Obj.getWarnings() : EmptyWarnings)); @@ -334,7 +334,7 @@ bool DwarfLinkerForBinary::link(const DebugMap &Map) { }); GeneralLinker.setObjFileLoader( [&DebugMap, &RL, this](StringRef ContainerName, - StringRef Path) -> ErrorOr { + StringRef Path) -> ErrorOr { auto &Obj = DebugMap.addDebugMapObject( Path, sys::TimePoint(), MachO::N_OSO); @@ -429,7 +429,7 @@ bool DwarfLinkerForBinary::link(const DebugMap &Map) { if (auto ErrorOrObj = loadObject(*Obj, Map, RL)) GeneralLinker.addObjectFile(*ErrorOrObj); else { - ObjectsForLinking.push_back(std::make_unique( + ObjectsForLinking.push_back(std::make_unique( Obj->getObjectFilename(), nullptr, nullptr, Obj->empty() ? Obj->getWarnings() : EmptyWarnings)); GeneralLinker.addObjectFile(*ObjectsForLinking.back()); diff --git a/llvm/tools/dsymutil/DwarfLinkerForBinary.h b/llvm/tools/dsymutil/DwarfLinkerForBinary.h index 7cabacbb993b7..842b27c70ab41 100644 --- a/llvm/tools/dsymutil/DwarfLinkerForBinary.h +++ b/llvm/tools/dsymutil/DwarfLinkerForBinary.h @@ -167,7 +167,7 @@ class DwarfLinkerForBinary { /// Attempt to load a debug object from disk. ErrorOr loadObject(const DebugMapObject &Obj, const Triple &triple); - ErrorOr loadObject(const DebugMapObject &Obj, + ErrorOr loadObject(const DebugMapObject &Obj, const DebugMap &DebugMap, remarks::RemarkLinker &RL); @@ -175,7 +175,7 @@ class DwarfLinkerForBinary { BinaryHolder &BinHolder; LinkOptions Options; std::unique_ptr Streamer; - std::vector> ObjectsForLinking; + std::vector> ObjectsForLinking; std::vector> ContextForLinking; std::vector> AddressMapForLinking; std::vector EmptyWarnings; From 80ff18d456b11dbfa852ac6edd424e7313a9133f Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 2 Oct 2020 09:53:30 -0700 Subject: [PATCH 080/234] [lldb] Fix bug in fallback logic for finding the resource directory. Both of the if-clauses modify the raw_path variable and only one of them was resetting the variable for the fallback. Avoid future bugs like that by always resetting the variable. Differential revision: https://reviews.llvm.org/D88704 (cherry picked from commit 07c112574a324318a02ef29901a0d5aa1fd95144) --- lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp index 8abb7e4205757..b76fa6fbf690c 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp @@ -137,14 +137,12 @@ bool lldb_private::ComputeClangResourceDirectory(FileSpec &lldb_shlib_spec, FileSystem::Instance().Resolve(file_spec); return true; } - raw_path = lldb_shlib_spec.GetPath(); } - raw_path.resize(rev_it - r_end); - } else { - raw_path.resize(rev_it - r_end); } // Fall back to the Clang resource directory inside the framework. + raw_path = lldb_shlib_spec.GetPath(); + raw_path.resize(rev_it - r_end); raw_path.append("LLDB.framework/Resources/Clang"); file_spec.GetDirectory().SetString(raw_path.c_str()); FileSystem::Instance().Resolve(file_spec); From 688c2e80381be16aecbb7bae67bef1229610a60a Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 6 Oct 2020 14:22:49 -0700 Subject: [PATCH 081/234] Don't reuse variables; Nest in scopes --- .../Swift/TypeSystemSwiftTypeRef.cpp | 57 +++++++++---------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index 67873a967dbd9..f3b78b65a6541 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1675,38 +1675,35 @@ TypeSystemSwiftTypeRef::GetPointerType(opaque_compiler_type_t type) { using namespace swift::Demangle; Demangler dem; + // The type that will be wrapped in UnsafePointer. auto *pointee_type = GetDemangledType(dem, AsMangledName(type)); - + // The UnsafePointer type. auto *pointer_type = dem.createNode(Node::Kind::Type); - auto *BGS = dem.createNode(Node::Kind::BoundGenericStructure); - pointer_type->addChild(BGS, dem); - - NodePointer parent; - NodePointer child; - - // Construct the first (Type) branch of BoundGenericStructure. - parent = BGS; - child = dem.createNode(Node::Kind::Type); - parent->addChild(child, dem); - parent = child; - child = dem.createNode(Node::Kind::Structure); - parent->addChild(child, dem); - parent = child; - parent->addChild( - dem.createNodeWithAllocatedText(Node::Kind::Module, swift::STDLIB_NAME), - dem); - parent->addChild(dem.createNode(Node::Kind::Identifier, "UnsafePointer"), - dem); - - // Construct the second (TypeList) branch of BoundGenericStructure. - parent = BGS; - child = dem.createNode(Node::Kind::TypeList); - parent->addChild(child, dem); - parent = child; - child = dem.createNode(Node::Kind::Type); - parent->addChild(child, dem); - parent = child; - parent->addChild(pointee_type, dem); + + auto *bgs = dem.createNode(Node::Kind::BoundGenericStructure); + pointer_type->addChild(bgs, dem); + + // Construct the first branch of BoundGenericStructure. + { + auto *type = dem.createNode(Node::Kind::Type); + bgs->addChild(type, dem); + auto *structure = dem.createNode(Node::Kind::Structure); + type->addChild(structure, dem); + structure->addChild(dem.createNodeWithAllocatedText(Node::Kind::Module, + swift::STDLIB_NAME), + dem); + structure->addChild( + dem.createNode(Node::Kind::Identifier, "UnsafePointer"), dem); + } + + // Construct the second branch of BoundGenericStructure. + { + auto *typelist = dem.createNode(Node::Kind::TypeList); + bgs->addChild(typelist, dem); + auto *type = dem.createNode(Node::Kind::Type); + typelist->addChild(type, dem); + type->addChild(pointee_type, dem); + } return RemangleAsType(dem, pointer_type); }; From fa050c6615f966edcb3f3360f8445f0a7c359957 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 6 Oct 2020 15:12:23 -0700 Subject: [PATCH 082/234] [lldb] Change the xcrun (fallback) logic in GetXcodeSDK This changes the logic in GetXcodeSDK to find an SDK with xcrun. The code now executes the following steps: 1. If DEVELOPER_DIR is set in the environment, it invokes xcrun with the given developer dir. If this fails we stop and don't fall back. 2. If the shlib dir is set and exists,it invokes xcrun with the developer dir corresponding to the shlib dir. If this fails we fall back to 3. 3. We run xcrun without a developer dir. The new behavior introduced in this patch is that we fall back to running xcrun without a developer dir if running it based on the shlib dir failed. A situation where this matters is when you're running lldb from an Xcode that has no SDKs and that is not xcode-selected. Based on lldb's shlib dir pointing into this Xcode installation, it will do an xcrun with the developer set to the Xcode without any SDKs which will fail. With this patch, when that happens, we'll fall back to trying the xcode-selected Xcode by running xcrun without a developer dir. Differential revision: https://reviews.llvm.org/D88866 (cherry picked from commit e3b0414b0ea305396a1fcfb2821ad643b0731880) --- .../Host/macosx/objcxx/HostInfoMacOSX.mm | 48 +++++++++++++------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm index b325bd2c5b745..5e06792e0fbf6 100644 --- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm @@ -373,26 +373,19 @@ static void ParseOSVersion(llvm::VersionTuple &version, NSString *Key) { static std::string GetXcodeSDK(XcodeSDK sdk) { XcodeSDK::Info info = sdk.Parse(); std::string sdk_name = XcodeSDK::GetCanonicalName(info); - auto find_sdk = [](std::string sdk_name) -> std::string { - std::string xcrun_cmd; - std::string developer_dir = GetEnvDeveloperDir(); - if (developer_dir.empty()) - if (FileSpec fspec = HostInfo::GetShlibDir()) - if (FileSystem::Instance().Exists(fspec)) { - FileSpec path( - XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath())); - if (path.RemoveLastPathComponent()) - developer_dir = path.GetPath(); - } + + auto xcrun = [](const std::string &sdk, + llvm::StringRef developer_dir = "") -> std::string { + std::string xcrun_cmd = "xcrun --show-sdk-path --sdk " + sdk; if (!developer_dir.empty()) - xcrun_cmd = "/usr/bin/env DEVELOPER_DIR=\"" + developer_dir + "\" "; - xcrun_cmd += "xcrun --show-sdk-path --sdk " + sdk_name; + xcrun_cmd = "/usr/bin/env DEVELOPER_DIR=\"" + developer_dir.str() + + "\" " + xcrun_cmd; int status = 0; int signo = 0; std::string output_str; lldb_private::Status error = - Host::RunShellCommand(xcrun_cmd.c_str(), FileSpec(), &status, &signo, + Host::RunShellCommand(xcrun_cmd, FileSpec(), &status, &signo, &output_str, std::chrono::seconds(15)); // Check that xcrun return something useful. @@ -414,6 +407,33 @@ FileSpec path( return output.str(); }; + auto find_sdk = [&xcrun](const std::string &sdk_name) -> std::string { + // Invoke xcrun with the developer dir specified in the environment. + std::string developer_dir = GetEnvDeveloperDir(); + if (!developer_dir.empty()) { + // Don't fallback if DEVELOPER_DIR was set. + return xcrun(sdk_name, developer_dir); + } + + // Invoke xcrun with the shlib dir. + if (FileSpec fspec = HostInfo::GetShlibDir()) { + if (FileSystem::Instance().Exists(fspec)) { + std::string contents_dir = + XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath()); + llvm::StringRef shlib_developer_dir = + llvm::sys::path::parent_path(contents_dir); + if (!shlib_developer_dir.empty()) { + std::string sdk = xcrun(sdk_name, std::move(shlib_developer_dir)); + if (!sdk.empty()) + return sdk; + } + } + } + + // Invoke xcrun without a developer dir as a last resort. + return xcrun(sdk_name); + }; + std::string path = find_sdk(sdk_name); while (path.empty()) { // Try an alternate spelling of the name ("macosx10.9internal"). From c6c82ad21ddb2064e28b51b71402639a6aa6f90b Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 6 Oct 2020 16:27:26 -0700 Subject: [PATCH 083/234] [llvm] Remove no-children.yaml test This test relies on functionality in obj2yaml that's not present on the stable branch. I made an attempt at backporting all the necessary changes but quickly realized it was too much churn for this change. --- .../tools/llvm-dwarfdump/X86/no-children.yaml | 23 ------------------- 1 file changed, 23 deletions(-) delete mode 100644 llvm/test/tools/llvm-dwarfdump/X86/no-children.yaml diff --git a/llvm/test/tools/llvm-dwarfdump/X86/no-children.yaml b/llvm/test/tools/llvm-dwarfdump/X86/no-children.yaml deleted file mode 100644 index 1417ab2bdc3f0..0000000000000 --- a/llvm/test/tools/llvm-dwarfdump/X86/no-children.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# RUN: yaml2obj %s | llvm-dwarfdump -verify - | FileCheck %s -# CHECK: warning: DW_TAG_compile_unit has DW_CHILDREN_yes but DIE has no children - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_EXEC -DWARF: - debug_abbrev: - - Table: - - Tag: DW_TAG_compile_unit - Children: DW_CHILDREN_yes - Attributes: - - Attribute: DW_AT_low_pc - Form: DW_FORM_data4 - debug_info: - - Version: 4 - Entries: - - AbbrCode: 1 - Values: - - Value: 0x1234 - - AbbrCode: 0 ## Terminator for the current DIE. From 83253b29d64b6b5a95da0c0eea2403d9d53a448a Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 6 Oct 2020 18:13:53 -0700 Subject: [PATCH 084/234] [lldb] Remove unused version defines --- lldb/source/lldb.cpp | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/lldb/source/lldb.cpp b/lldb/source/lldb.cpp index 942fec2350474..90277844eb71d 100644 --- a/lldb/source/lldb.cpp +++ b/lldb/source/lldb.cpp @@ -36,16 +36,6 @@ static const char *GetLLDBRepository() { #endif } -#if LLDB_IS_BUILDBOT_BUILD -static std::string GetBuildDate() { -#if defined(LLDB_BUILD_DATE) - return std::string(LLDB_BUILD_DATE); -#else - return std::string(); -#endif -} -#endif - #define QUOTE(str) #str #define EXPAND_AND_QUOTE(str) QUOTE(str) @@ -71,34 +61,11 @@ const char *lldb_private::GetVersion() { } g_version_str += ")"; } - -#if LLDB_IS_BUILDBOT_BUILD - std::string build_date = GetBuildDate(); - if(!build_date.empty()) - g_version_str += " (buildbot " + build_date + ")"; -#endif #ifdef LLDB_ENABLE_SWIFT auto const swift_version = swift::version::getSwiftFullVersion(); g_version_str += "\n" + swift_version; #endif // LLDB_ENABLE_SWIFT - - // getSwiftFullVersion() also prints clang and llvm versions, no - // need to print them again. We keep this code here to not diverge - // too much from upstream. -#undef LLDB_UPSTREAM -#ifdef LLDB_UPSTREAM - std::string clang_rev(clang::getClangRevision()); - if (clang_rev.length() > 0) { - g_version_str += "\n clang revision "; - g_version_str += clang_rev; - } - std::string llvm_rev(clang::getLLVMRevision()); - if (llvm_rev.length() > 0) { - g_version_str += "\n llvm revision "; - g_version_str += llvm_rev; - } -#endif // LLDB_UPSTREAM } return g_version_str.c_str(); } From 0387ef915497ac552c45aa21f557a5ac27c4ad8f Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 6 Oct 2020 18:31:20 -0700 Subject: [PATCH 085/234] oops, restore upstream block of code --- lldb/source/lldb.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lldb/source/lldb.cpp b/lldb/source/lldb.cpp index 90277844eb71d..2017d7e0c4219 100644 --- a/lldb/source/lldb.cpp +++ b/lldb/source/lldb.cpp @@ -65,6 +65,20 @@ const char *lldb_private::GetVersion() { #ifdef LLDB_ENABLE_SWIFT auto const swift_version = swift::version::getSwiftFullVersion(); g_version_str += "\n" + swift_version; +#else + // getSwiftFullVersion() also prints clang and llvm versions, no + // need to print them again. We keep this code here to not diverge + // too much from upstream. + std::string clang_rev(clang::getClangRevision()); + if (clang_rev.length() > 0) { + g_version_str += "\n clang revision "; + g_version_str += clang_rev; + } + std::string llvm_rev(clang::getLLVMRevision()); + if (llvm_rev.length() > 0) { + g_version_str += "\n llvm revision "; + g_version_str += llvm_rev; + } #endif // LLDB_ENABLE_SWIFT } return g_version_str.c_str(); From 8a33482be9af7561aed05d566f4f28e3f1fbb2d5 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 6 Oct 2020 18:33:25 -0700 Subject: [PATCH 086/234] fix indentation --- lldb/source/lldb.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lldb/source/lldb.cpp b/lldb/source/lldb.cpp index 2017d7e0c4219..cbb2dc1fc4e9f 100644 --- a/lldb/source/lldb.cpp +++ b/lldb/source/lldb.cpp @@ -66,19 +66,19 @@ const char *lldb_private::GetVersion() { auto const swift_version = swift::version::getSwiftFullVersion(); g_version_str += "\n" + swift_version; #else - // getSwiftFullVersion() also prints clang and llvm versions, no - // need to print them again. We keep this code here to not diverge - // too much from upstream. - std::string clang_rev(clang::getClangRevision()); - if (clang_rev.length() > 0) { - g_version_str += "\n clang revision "; - g_version_str += clang_rev; - } - std::string llvm_rev(clang::getLLVMRevision()); - if (llvm_rev.length() > 0) { - g_version_str += "\n llvm revision "; - g_version_str += llvm_rev; - } + // getSwiftFullVersion() also prints clang and llvm versions, no + // need to print them again. We keep this code here to not diverge + // too much from upstream. + std::string clang_rev(clang::getClangRevision()); + if (clang_rev.length() > 0) { + g_version_str += "\n clang revision "; + g_version_str += clang_rev; + } + std::string llvm_rev(clang::getLLVMRevision()); + if (llvm_rev.length() > 0) { + g_version_str += "\n llvm revision "; + g_version_str += llvm_rev; + } #endif // LLDB_ENABLE_SWIFT } return g_version_str.c_str(); From e84852be644d34867a604997fd328bf411b1977d Mon Sep 17 00:00:00 2001 From: Shivanshu Goyal Date: Tue, 6 Oct 2020 16:12:48 +0200 Subject: [PATCH 087/234] Add ability to turn off -fpch-instantiate-templates in clang-cl A lot of our code building with clang-cl.exe using Clang 11 was failing with the following 2 type of errors: 1. explicit specialization of 'foo' after instantiation 2. no matching function for call to 'bar' Note that we also use -fdelayed-template-parsing in our builds. I tried pretty hard to get a small repro for these failures, but couldn't. So there is some subtle edge case in the -fpch-instantiate-templates feature introduced by this change: https://reviews.llvm.org/D69585 When I tried turning this off using -fno-pch-instantiate-templates, builds would silently fail with the same error without any indication that -fno-pch-instantiate-templates was being ignored by the compiler. Then I realized this "no" option wasn't actually working when I ran Clang under a debugger. Differential revision: https://reviews.llvm.org/D88680 (cherry picked from commit 66e4f07198761bbb4dcd55235024c1081ed15c75) --- clang/include/clang/Driver/Options.td | 4 ++-- clang/lib/Driver/ToolChains/Clang.cpp | 6 +++++- clang/test/Driver/pch-instantiate-templates.c | 13 +++++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 clang/test/Driver/pch-instantiate-templates.c diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index f818acb39d510..966cb907b7e20 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1435,11 +1435,11 @@ def fno_pch_validate_input_files_content: Group, Flags<[DriverOption]>; def fpch_instantiate_templates: Flag <["-"], "fpch-instantiate-templates">, - Group, Flags<[CC1Option]>, + Group, Flags<[CC1Option, CoreOption]>, HelpText<"Instantiate templates already while building a PCH">; def fno_pch_instantiate_templates: Flag <["-"], "fno-pch-instantiate-templates">, - Group, Flags<[CC1Option]>; + Group, Flags<[CC1Option, CoreOption]>; defm pch_codegen: OptInFFlag<"pch-codegen", "Generate ", "Do not generate ", "code for uses of this PCH that assumes an explicit object file will be built for the PCH">; defm pch_debuginfo: OptInFFlag<"pch-debuginfo", "Generate ", "Do not generate ", diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index f0a5451322aaa..af4bcf951e6c8 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1197,7 +1197,11 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, if (YcArg && JA.getKind() >= Action::PrecompileJobClass && JA.getKind() <= Action::AssembleJobClass) { CmdArgs.push_back(Args.MakeArgString("-building-pch-with-obj")); - CmdArgs.push_back(Args.MakeArgString("-fpch-instantiate-templates")); + // -fpch-instantiate-templates is the default when creating + // precomp using /Yc + if (Args.hasFlag(options::OPT_fpch_instantiate_templates, + options::OPT_fno_pch_instantiate_templates, true)) + CmdArgs.push_back(Args.MakeArgString("-fpch-instantiate-templates")); } if (YcArg || YuArg) { StringRef ThroughHeader = YcArg ? YcArg->getValue() : YuArg->getValue(); diff --git a/clang/test/Driver/pch-instantiate-templates.c b/clang/test/Driver/pch-instantiate-templates.c new file mode 100644 index 0000000000000..b0f7f34739938 --- /dev/null +++ b/clang/test/Driver/pch-instantiate-templates.c @@ -0,0 +1,13 @@ +// CL driver test cases +// RUN: %clang_cl -### /Yc /Fpfoo.pch /Fofoo.obj -- %s 2>&1 | FileCheck --check-prefix=CLANG_CL_YC %s +// RUN: %clang_cl -### /Yc /Fpfoo.pch /Fofoo.obj -fno-pch-instantiate-templates -- %s 2>&1 | FileCheck --check-prefix=CLANG_CL_YC_DISABLE %s + +// CLANG_CL_YC: "-fpch-instantiate-templates" +// CLANG_CL_YC_DISABLE-NOT: "-fpch-instantiate-templates" + +// GCC driver test cases +// RUN: %clang -### -x c-header %s -o %t/foo.pch 2>&1 | FileCheck -check-prefix=GCC_DEFAULT %s +// RUN: %clang -### -x c-header %s -o %t/foo.pch -fpch-instantiate-templates 2>&1 | FileCheck -check-prefix=GCC_DEFAULT_ENABLE %s + +// GCC_DEFAULT-NOT: "-fpch-instantiate-templates" +// GCC_DEFAULT_ENABLE: "-fpch-instantiate-templates" From 176249bd6732a8044d457092ed932768724a6f06 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 6 Oct 2020 17:54:36 -0700 Subject: [PATCH 088/234] [CodeGen][TailDuplicator] Don't duplicate blocks with INLINEASM_BR Tail duplication of a block with an INLINEASM_BR may result in a PHI node on the indirect branch. This is okay, but it also introduces a copy for that PHI node *after* the INLINEASM_BR, which is not okay. See: https://github.com/ClangBuiltLinux/linux/issues/1125 Differential Revision: https://reviews.llvm.org/D88823 (cherry picked from commit d2c61d2bf9bd1efad49acba2f2751112522686aa) --- llvm/lib/CodeGen/TailDuplicator.cpp | 8 +++ llvm/test/CodeGen/X86/tail-dup-asm-goto.ll | 61 ++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 llvm/test/CodeGen/X86/tail-dup-asm-goto.ll diff --git a/llvm/lib/CodeGen/TailDuplicator.cpp b/llvm/lib/CodeGen/TailDuplicator.cpp index bd554189f12b5..f9773f74a7bdd 100644 --- a/llvm/lib/CodeGen/TailDuplicator.cpp +++ b/llvm/lib/CodeGen/TailDuplicator.cpp @@ -627,6 +627,14 @@ bool TailDuplicator::shouldTailDuplicate(bool IsSimple, if (PreRegAlloc && MI.isCall()) return false; + // TailDuplicator::appendCopies will erroneously place COPYs after + // INLINEASM_BR instructions after 4b0aa5724fea, which demonstrates the same + // bug that was fixed in f7a53d82c090. + // FIXME: Use findPHICopyInsertPoint() to find the correct insertion point + // for the COPY when replacing PHIs. + if (MI.getOpcode() == TargetOpcode::INLINEASM_BR) + return false; + if (MI.isBundle()) InstrCount += MI.getBundleSize(); else if (!MI.isPHI() && !MI.isMetaInstruction()) diff --git a/llvm/test/CodeGen/X86/tail-dup-asm-goto.ll b/llvm/test/CodeGen/X86/tail-dup-asm-goto.ll new file mode 100644 index 0000000000000..77aa3adf0fc69 --- /dev/null +++ b/llvm/test/CodeGen/X86/tail-dup-asm-goto.ll @@ -0,0 +1,61 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -mtriple=x86_64-linux -stop-after=early-tailduplication < %s | FileCheck %s + +; Ensure that we don't duplicate a block with an "INLINEASM_BR" instruction +; during code gen. +declare void @foo() + +define i8* @test1(i8** %arg1, i8* %arg2) { + ; CHECK-LABEL: name: test1 + ; CHECK: bb.0.bb: + ; CHECK: successors: %bb.1(0x50000000), %bb.2(0x30000000) + ; CHECK: liveins: $rdi, $rsi + ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi + ; CHECK: [[COPY1:%[0-9]+]]:gr64 = COPY $rdi + ; CHECK: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm [[COPY1]], 1, $noreg, 0, $noreg :: (load 8 from %ir.arg1) + ; CHECK: [[SUB64rr:%[0-9]+]]:gr64 = SUB64rr [[MOV64rm]], [[COPY]], implicit-def $eflags + ; CHECK: JCC_1 %bb.2, 4, implicit $eflags + ; CHECK: JMP_1 %bb.1 + ; CHECK: bb.1.bb100: + ; CHECK: successors: %bb.3(0x80000000) + ; CHECK: MOV64mi32 [[COPY1]], 1, $noreg, 0, $noreg, 0 :: (store 8 into %ir.arg1) + ; CHECK: JMP_1 %bb.3 + ; CHECK: bb.2.bb106: + ; CHECK: successors: %bb.3(0x80000000) + ; CHECK: ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + ; CHECK: CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp + ; CHECK: ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + ; CHECK: bb.3.bb110: + ; CHECK: successors: %bb.5(0x80000000), %bb.4(0x00000000) + ; CHECK: [[PHI:%[0-9]+]]:gr64 = PHI [[COPY]], %bb.2, [[MOV64rm]], %bb.1 + ; CHECK: INLINEASM_BR &"#$0 $1 $2", 9 /* sideeffect mayload attdialect */, 13 /* imm */, 42, 13 /* imm */, 0, 13 /* imm */, blockaddress(@test1, %ir-block.bb17.i.i.i), 12 /* clobber */, implicit-def early-clobber $df, 12 /* clobber */, implicit-def early-clobber $fpsw, 12 /* clobber */, implicit-def early-clobber $eflags + ; CHECK: JMP_1 %bb.5 + ; CHECK: bb.4.bb17.i.i.i (address-taken): + ; CHECK: successors: %bb.5(0x80000000) + ; CHECK: bb.5.kmem_cache_has_cpu_partial.exit: + ; CHECK: $rax = COPY [[PHI]] + ; CHECK: RET 0, $rax +bb: + %i28.i = load i8*, i8** %arg1, align 8 + %if = icmp ne i8* %i28.i, %arg2 + br i1 %if, label %bb100, label %bb106 + +bb100: ; preds = %bb + store i8* null, i8** %arg1, align 8 + br label %bb110 + +bb106: ; preds = %bb + call void @foo() + br label %bb110 + +bb110: ; preds = %bb106, %bb100 + %i10.1 = phi i8* [ %arg2, %bb106 ], [ %i28.i, %bb100 ] + callbr void asm sideeffect "#$0 $1 $2", "i,i,X,~{dirflag},~{fpsr},~{flags}"(i32 42, i1 false, i8* blockaddress(@test1, %bb17.i.i.i)) + to label %kmem_cache_has_cpu_partial.exit [label %bb17.i.i.i] + +bb17.i.i.i: ; preds = %bb110 + br label %kmem_cache_has_cpu_partial.exit + +kmem_cache_has_cpu_partial.exit: ; preds = %bb110 + ret i8* %i10.1 +} From 5dad915223fe3bcec3a7ac5efe367a645a8d8ff1 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 7 Oct 2020 16:24:18 -0400 Subject: [PATCH 089/234] [Swift] Synthesized type alias should be implicit to avoid upsetting ASTScope --- .../ExpressionParser/Swift/SwiftASTManipulator.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.cpp index 4008a62dce9e4..f6411a641a974 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.cpp @@ -1331,21 +1331,15 @@ swift::ValueDecl *SwiftASTManipulator::MakeGlobalTypealias( if (!IsValid()) return nullptr; - swift::SourceLoc source_loc; - - if (m_extension_decl) - source_loc = m_extension_decl->getEndLoc(); - else - source_loc = m_function_decl->getEndLoc(); - swift::ASTContext &ast_context = m_source_file.getASTContext(); swift::TypeAliasDecl *type_alias_decl = new (ast_context) - swift::TypeAliasDecl(source_loc, swift::SourceLoc(), name, source_loc, - nullptr, &m_source_file); + swift::TypeAliasDecl(swift::SourceLoc(), swift::SourceLoc(), name, + swift::SourceLoc(), nullptr, &m_source_file); swift::Type underlying_type = GetSwiftType(type); type_alias_decl->setUnderlyingType(underlying_type); type_alias_decl->markAsDebuggerAlias(true); + type_alias_decl->setImplicit(true); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); if (log) { From adb227f71c466ed53e9ea5a59e85c4dbb61522d8 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Wed, 7 Oct 2020 14:52:24 -0700 Subject: [PATCH 090/234] [lldb] Regenerate the static bindings --- .../python/static-binding/LLDBWrapPython.cpp | 189 ++++++++++++++++++ lldb/bindings/python/static-binding/lldb.py | 52 ++++- 2 files changed, 240 insertions(+), 1 deletion(-) diff --git a/lldb/bindings/python/static-binding/LLDBWrapPython.cpp b/lldb/bindings/python/static-binding/LLDBWrapPython.cpp index 269e1173311d7..b481edaf48a06 100644 --- a/lldb/bindings/python/static-binding/LLDBWrapPython.cpp +++ b/lldb/bindings/python/static-binding/LLDBWrapPython.cpp @@ -64135,6 +64135,66 @@ SWIGINTERN PyObject *_wrap_SBThreadPlan_IsPlanStale(PyObject *SWIGUNUSEDPARM(sel } +SWIGINTERN PyObject *_wrap_SBThreadPlan_GetStopOthers(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + lldb::SBThreadPlan *arg1 = (lldb::SBThreadPlan *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + bool result; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBThreadPlan, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBThreadPlan_GetStopOthers" "', argument " "1"" of type '" "lldb::SBThreadPlan *""'"); + } + arg1 = reinterpret_cast< lldb::SBThreadPlan * >(argp1); + { + SWIG_PYTHON_THREAD_BEGIN_ALLOW; + result = (bool)(arg1)->GetStopOthers(); + SWIG_PYTHON_THREAD_END_ALLOW; + } + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_SBThreadPlan_SetStopOthers(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + lldb::SBThreadPlan *arg1 = (lldb::SBThreadPlan *) 0 ; + bool arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + bool val2 ; + int ecode2 = 0 ; + PyObject *swig_obj[2] ; + + if (!SWIG_Python_UnpackTuple(args, "SBThreadPlan_SetStopOthers", 2, 2, swig_obj)) SWIG_fail; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_lldb__SBThreadPlan, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SBThreadPlan_SetStopOthers" "', argument " "1"" of type '" "lldb::SBThreadPlan *""'"); + } + arg1 = reinterpret_cast< lldb::SBThreadPlan * >(argp1); + ecode2 = SWIG_AsVal_bool(swig_obj[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SBThreadPlan_SetStopOthers" "', argument " "2"" of type '" "bool""'"); + } + arg2 = static_cast< bool >(val2); + { + SWIG_PYTHON_THREAD_BEGIN_ALLOW; + (arg1)->SetStopOthers(arg2); + SWIG_PYTHON_THREAD_END_ALLOW; + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_SBThreadPlan_QueueThreadPlanForStepOverRange(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; lldb::SBThreadPlan *arg1 = (lldb::SBThreadPlan *) 0 ; @@ -80183,6 +80243,127 @@ LLDBSwigPythonCallBreakpointResolver return ret_val; } +SWIGEXPORT void * +LLDBSwigPythonCreateScriptedStopHook +( + lldb::TargetSP target_sp, + const char *python_class_name, + const char *session_dictionary_name, + lldb_private::StructuredDataImpl *args_impl, + Status &error +) +{ + if (python_class_name == NULL || python_class_name[0] == '\0') { + error.SetErrorString("Empty class name."); + Py_RETURN_NONE; + } + if (!session_dictionary_name) { + error.SetErrorString("No session dictionary"); + Py_RETURN_NONE; + } + + PyErr_Cleaner py_err_cleaner(true); + + auto dict = + PythonModule::MainModule().ResolveName( + session_dictionary_name); + auto pfunc = + PythonObject::ResolveNameWithDictionary( + python_class_name, dict); + + if (!pfunc.IsAllocated()) { + error.SetErrorStringWithFormat("Could not find class: %s.", + python_class_name); + return nullptr; + } + + lldb::SBTarget *target_val + = new lldb::SBTarget(target_sp); + + PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(target_val)); + + lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl); + PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value)); + + PythonObject result = pfunc(target_arg, args_arg, dict); + + if (result.IsAllocated()) + { + // Check that the handle_stop callback is defined: + auto callback_func = result.ResolveName("handle_stop"); + if (callback_func.IsAllocated()) { + if (auto args_info = callback_func.GetArgInfo()) { + size_t num_args = (*args_info).max_positional_args; + if (num_args != 2) { + error.SetErrorStringWithFormat("Wrong number of args for " + "handle_stop callback, should be 2 (excluding self), got: %d", + num_args); + Py_RETURN_NONE; + } else + return result.release(); + } else { + error.SetErrorString("Couldn't get num arguments for handle_stop " + "callback."); + Py_RETURN_NONE; + } + return result.release(); + } + else { + error.SetErrorStringWithFormat("Class \"%s\" is missing the required " + "handle_stop callback.", + python_class_name); + result.release(); + } + } + Py_RETURN_NONE; +} + +SWIGEXPORT bool +LLDBSwigPythonStopHookCallHandleStop +( + void *implementor, + lldb::ExecutionContextRefSP exc_ctx_sp, + lldb::StreamSP stream +) +{ + // handle_stop will return a bool with the meaning "should_stop"... + // If you return nothing we'll assume we are going to stop. + // Also any errors should return true, since we should stop on error. + + PyErr_Cleaner py_err_cleaner(false); + PythonObject self(PyRefType::Borrowed, static_cast(implementor)); + auto pfunc = self.ResolveName("handle_stop"); + + if (!pfunc.IsAllocated()) + return true; + + PythonObject result; + lldb::SBExecutionContext sb_exc_ctx(exc_ctx_sp); + PythonObject exc_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_exc_ctx)); + lldb::SBStream sb_stream; + PythonObject sb_stream_arg(PyRefType::Owned, + SBTypeToSWIGWrapper(sb_stream)); + result = pfunc(exc_ctx_arg, sb_stream_arg); + + if (PyErr_Occurred()) + { + stream->PutCString("Python error occurred handling stop-hook."); + PyErr_Print(); + PyErr_Clear(); + return true; + } + + // Now add the result to the output stream. SBStream only + // makes an internally help StreamString which I can't interpose, so I + // have to copy it over here. + stream->PutCString(sb_stream.GetData()); + + if (result.get() == Py_False) + return false; + else + return true; +} + // wrapper that calls an optional instance member of an object taking no arguments static PyObject* LLDBSwigPython_CallOptionalMember @@ -83893,6 +84074,11 @@ static PyMethodDef SwigMethods[] = { { "SBThreadPlan_SetPlanComplete", _wrap_SBThreadPlan_SetPlanComplete, METH_VARARGS, "SBThreadPlan_SetPlanComplete(SBThreadPlan self, bool success)"}, { "SBThreadPlan_IsPlanComplete", _wrap_SBThreadPlan_IsPlanComplete, METH_O, "SBThreadPlan_IsPlanComplete(SBThreadPlan self) -> bool"}, { "SBThreadPlan_IsPlanStale", _wrap_SBThreadPlan_IsPlanStale, METH_O, "SBThreadPlan_IsPlanStale(SBThreadPlan self) -> bool"}, + { "SBThreadPlan_GetStopOthers", _wrap_SBThreadPlan_GetStopOthers, METH_O, "\n" + "SBThreadPlan_GetStopOthers(SBThreadPlan self) -> bool\n" + "Return whether this plan will ask to stop other threads when it runs.\n" + ""}, + { "SBThreadPlan_SetStopOthers", _wrap_SBThreadPlan_SetStopOthers, METH_VARARGS, "SBThreadPlan_SetStopOthers(SBThreadPlan self, bool stop_others)"}, { "SBThreadPlan_QueueThreadPlanForStepOverRange", _wrap_SBThreadPlan_QueueThreadPlanForStepOverRange, METH_VARARGS, "SBThreadPlan_QueueThreadPlanForStepOverRange(SBThreadPlan self, SBAddress start_address, lldb::addr_t range_size) -> SBThreadPlan"}, { "SBThreadPlan_QueueThreadPlanForStepInRange", _wrap_SBThreadPlan_QueueThreadPlanForStepInRange, METH_VARARGS, "SBThreadPlan_QueueThreadPlanForStepInRange(SBThreadPlan self, SBAddress start_address, lldb::addr_t range_size) -> SBThreadPlan"}, { "SBThreadPlan_QueueThreadPlanForStepOut", _wrap_SBThreadPlan_QueueThreadPlanForStepOut, METH_VARARGS, "SBThreadPlan_QueueThreadPlanForStepOut(SBThreadPlan self, uint32_t frame_idx_to_step_to, bool first_insn=False) -> SBThreadPlan"}, @@ -86308,6 +86494,7 @@ SWIG_init(void) { SWIG_Python_SetConstant(d, "LLDB_INVALID_SIGNAL_NUMBER",SWIG_From_int(static_cast< int >(2147483647))); SWIG_Python_SetConstant(d, "LLDB_INVALID_OFFSET",SWIG_From_unsigned_SS_long_SS_long(static_cast< unsigned long long >(18446744073709551615ULL))); SWIG_Python_SetConstant(d, "LLDB_INVALID_LINE_NUMBER",SWIG_From_unsigned_SS_int(static_cast< unsigned int >(4294967295U))); + SWIG_Python_SetConstant(d, "LLDB_INVALID_COLUMN_NUMBER",SWIG_From_int(static_cast< int >(0))); SWIG_Python_SetConstant(d, "LLDB_INVALID_QUEUE_ID",SWIG_From_int(static_cast< int >(0))); SWIG_Python_SetConstant(d, "LLDB_ARCH_DEFAULT",SWIG_FromCharPtr("systemArch")); SWIG_Python_SetConstant(d, "LLDB_ARCH_DEFAULT_32BIT",SWIG_FromCharPtr("systemArch32")); @@ -86326,6 +86513,7 @@ SWIG_init(void) { SWIG_Python_SetConstant(d, "LLDB_OPT_SET_9",SWIG_From_unsigned_SS_int(static_cast< unsigned int >((1U << 8)))); SWIG_Python_SetConstant(d, "LLDB_OPT_SET_10",SWIG_From_unsigned_SS_int(static_cast< unsigned int >((1U << 9)))); SWIG_Python_SetConstant(d, "LLDB_OPT_SET_11",SWIG_From_unsigned_SS_int(static_cast< unsigned int >((1U << 10)))); + SWIG_Python_SetConstant(d, "LLDB_OPT_SET_12",SWIG_From_unsigned_SS_int(static_cast< unsigned int >((1U << 11)))); SWIG_Python_SetConstant(d, "eStateInvalid",SWIG_From_int(static_cast< int >(lldb::eStateInvalid))); SWIG_Python_SetConstant(d, "eStateUnloaded",SWIG_From_int(static_cast< int >(lldb::eStateUnloaded))); SWIG_Python_SetConstant(d, "eStateConnected",SWIG_From_int(static_cast< int >(lldb::eStateConnected))); @@ -86608,6 +86796,7 @@ SWIG_init(void) { SWIG_Python_SetConstant(d, "eArgTypeExpression",SWIG_From_int(static_cast< int >(lldb::eArgTypeExpression))); SWIG_Python_SetConstant(d, "eArgTypeExpressionPath",SWIG_From_int(static_cast< int >(lldb::eArgTypeExpressionPath))); SWIG_Python_SetConstant(d, "eArgTypeExprFormat",SWIG_From_int(static_cast< int >(lldb::eArgTypeExprFormat))); + SWIG_Python_SetConstant(d, "eArgTypeFileLineColumn",SWIG_From_int(static_cast< int >(lldb::eArgTypeFileLineColumn))); SWIG_Python_SetConstant(d, "eArgTypeFilename",SWIG_From_int(static_cast< int >(lldb::eArgTypeFilename))); SWIG_Python_SetConstant(d, "eArgTypeFormat",SWIG_From_int(static_cast< int >(lldb::eArgTypeFormat))); SWIG_Python_SetConstant(d, "eArgTypeFrameIndex",SWIG_From_int(static_cast< int >(lldb::eArgTypeFrameIndex))); diff --git a/lldb/bindings/python/static-binding/lldb.py b/lldb/bindings/python/static-binding/lldb.py index f5c61fb05da4d..e3c1a5c8a2b91 100644 --- a/lldb/bindings/python/static-binding/lldb.py +++ b/lldb/bindings/python/static-binding/lldb.py @@ -199,6 +199,8 @@ def __init__(self): LLDB_INVALID_LINE_NUMBER = _lldb.LLDB_INVALID_LINE_NUMBER +LLDB_INVALID_COLUMN_NUMBER = _lldb.LLDB_INVALID_COLUMN_NUMBER + LLDB_INVALID_QUEUE_ID = _lldb.LLDB_INVALID_QUEUE_ID LLDB_ARCH_DEFAULT = _lldb.LLDB_ARCH_DEFAULT @@ -235,6 +237,8 @@ def __init__(self): LLDB_OPT_SET_11 = _lldb.LLDB_OPT_SET_11 +LLDB_OPT_SET_12 = _lldb.LLDB_OPT_SET_12 + eStateInvalid = _lldb.eStateInvalid eStateUnloaded = _lldb.eStateUnloaded @@ -799,6 +803,8 @@ def __init__(self): eArgTypeExprFormat = _lldb.eArgTypeExprFormat +eArgTypeFileLineColumn = _lldb.eArgTypeFileLineColumn + eArgTypeFilename = _lldb.eArgTypeFilename eArgTypeFormat = _lldb.eArgTypeFormat @@ -11645,6 +11651,17 @@ def IsPlanStale(self): r"""IsPlanStale(SBThreadPlan self) -> bool""" return _lldb.SBThreadPlan_IsPlanStale(self) + def GetStopOthers(self): + r""" + GetStopOthers(SBThreadPlan self) -> bool + Return whether this plan will ask to stop other threads when it runs. + """ + return _lldb.SBThreadPlan_GetStopOthers(self) + + def SetStopOthers(self, stop_others): + r"""SetStopOthers(SBThreadPlan self, bool stop_others)""" + return _lldb.SBThreadPlan_SetStopOthers(self, stop_others) + def QueueThreadPlanForStepOverRange(self, start_address, range_size): r"""QueueThreadPlanForStepOverRange(SBThreadPlan self, SBAddress start_address, lldb::addr_t range_size) -> SBThreadPlan""" return _lldb.SBThreadPlan_QueueThreadPlanForStepOverRange(self, start_address, range_size) @@ -12653,7 +12670,19 @@ def __str__(self): _lldb.SBTypeEnumMember_swigregister(SBTypeEnumMember) class SBTypeEnumMemberList(object): - r"""Represents a list of SBTypeEnumMembers.""" + r""" + Represents a list of SBTypeEnumMembers. + SBTypeEnumMemberList supports SBTypeEnumMember iteration. + It also supports [] access either by index, or by enum + element name by doing: + + myType = target.FindFirstType('MyEnumWithElementA') + members = myType.GetEnumMembers() + first_elem = members[0] + elem_A = members['A'] + + + """ thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") __repr__ = _swig_repr @@ -12688,6 +12717,27 @@ def GetSize(self): r"""GetSize(SBTypeEnumMemberList self) -> uint32_t""" return _lldb.SBTypeEnumMemberList_GetSize(self) + def __iter__(self): + '''Iterate over all members in a lldb.SBTypeEnumMemberList object.''' + return lldb_iter(self, 'GetSize', 'GetTypeEnumMemberAtIndex') + + def __len__(self): + '''Return the number of members in a lldb.SBTypeEnumMemberList object.''' + return self.GetSize() + + def __getitem__(self, key): + num_elements = self.GetSize() + if type(key) is int: + if key < num_elements: + return self.GetTypeEnumMemberAtIndex(key) + elif type(key) is str: + for idx in range(num_elements): + item = self.GetTypeEnumMemberAtIndex(idx) + if item.name == key: + return item + return None + + # Register SBTypeEnumMemberList in _lldb: _lldb.SBTypeEnumMemberList_swigregister(SBTypeEnumMemberList) From eb20e57d3ce5236a7d10efd51171c02c9bed61a0 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 7 Oct 2020 15:40:13 -0700 Subject: [PATCH 091/234] [lldb] Implement TypeSystemSwiftTypeRef::CreateTupleType --- .../Swift/TypeSystemSwiftTypeRef.cpp | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index 2cf9577a982cc..033f8a2fc7907 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1880,10 +1880,46 @@ TypeSystemSwift::TypeAllocationStrategy TypeSystemSwiftTypeRef::GetAllocationStrategy(opaque_compiler_type_t type) { return m_swift_ast_context->GetAllocationStrategy(ReconstructType(type)); } + CompilerType TypeSystemSwiftTypeRef::CreateTupleType( const std::vector &elements) { - return m_swift_ast_context->CreateTupleType(elements); + auto impl = [&]() -> CompilerType { + using namespace swift::Demangle; + Demangler dem; + auto *tuple = dem.createNode(Node::Kind::Tuple); + for (const auto &element : elements) { + auto *tuple_element = dem.createNode(Node::Kind::TupleElement); + tuple->addChild(tuple_element, dem); + + if (!element.element_name.IsEmpty()) { + auto *name = dem.createNode(Node::Kind::TupleElementName, + element.element_name.GetStringRef()); + tuple_element->addChild(name, dem); + } + + auto *type = dem.createNode(Node::Kind::Type); + tuple_element->addChild(type, dem); + auto *element_type = GetDemangledType( + dem, element.element_type.GetMangledTypeName().GetStringRef()); + type->addChild(element_type, dem); + } + return RemangleAsType(dem, tuple); + }; + { + auto result = impl(); + if (!m_swift_ast_context) + return result; + bool equivalent = + Equivalent(result, m_swift_ast_context->CreateTupleType(elements)); + if (!equivalent) + llvm::dbgs() << "failing tuple type \n"; + assert(equivalent && + "TypeSystemSwiftTypeRef diverges from SwiftASTContext"); + return result; + } +// VALIDATE_AND_RETURN(impl, CreateTupleType, ..); } + void TypeSystemSwiftTypeRef::DumpTypeDescription( opaque_compiler_type_t type, bool print_help_if_available, bool print_extensions_if_available, lldb::DescriptionLevel level) { From ba813dd4b5e4b85b1629bf8405a35027bed4aa93 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 7 Oct 2020 15:49:30 -0700 Subject: [PATCH 092/234] Use NDEBUG for inlined macro --- .../TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index 033f8a2fc7907..af9622c47bbfa 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1905,6 +1905,10 @@ CompilerType TypeSystemSwiftTypeRef::CreateTupleType( } return RemangleAsType(dem, tuple); }; + + // The signature of VALIDATE_AND_RETURN doesn't support this function, below + // is an inlined function-specific variation. +#ifndef NDEBUG { auto result = impl(); if (!m_swift_ast_context) @@ -1912,12 +1916,14 @@ CompilerType TypeSystemSwiftTypeRef::CreateTupleType( bool equivalent = Equivalent(result, m_swift_ast_context->CreateTupleType(elements)); if (!equivalent) - llvm::dbgs() << "failing tuple type \n"; + llvm::dbgs() << "failing tuple type\n"; assert(equivalent && "TypeSystemSwiftTypeRef diverges from SwiftASTContext"); return result; } -// VALIDATE_AND_RETURN(impl, CreateTupleType, ..); +#else + return impl(); +#endif } void TypeSystemSwiftTypeRef::DumpTypeDescription( From 254c6ff7656bb0d17868f3fd17585200c80fc6c1 Mon Sep 17 00:00:00 2001 From: Ben Barham Date: Thu, 8 Oct 2020 08:14:58 +1000 Subject: [PATCH 093/234] [clang][Index] Add guard to IndexUnitReader module name reading Check that ModuleNamesBuffer is valid before attempting to read strings from it to avoid possible segfaults. Wasn't able to come up with a test case, but this does happen based on reported crashes. Also use StringRef.substr, which returns an empty string if the index is out of bounds, for even further safety. Resolves rdar://69809414 --- clang/lib/Index/IndexUnitReader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Index/IndexUnitReader.cpp b/clang/lib/Index/IndexUnitReader.cpp index 30e474d6d6165..a1f8ca7798407 100644 --- a/clang/lib/Index/IndexUnitReader.cpp +++ b/clang/lib/Index/IndexUnitReader.cpp @@ -378,10 +378,10 @@ void IndexUnitReaderImpl::constructFilePath(SmallVectorImpl &PathBuf, } StringRef IndexUnitReaderImpl::getModuleName(int ModuleIndex) { - if (ModuleIndex < 0) + if (ModuleIndex < 0 || ModuleNamesBuffer.empty()) return StringRef(); auto &ModInfo = Modules[ModuleIndex]; - return StringRef(ModuleNamesBuffer.data()+ModInfo.NameOffset, ModInfo.NameSize); + return ModuleNamesBuffer.substr(ModInfo.NameOffset, ModInfo.NameSize); } From bd1dd3654c12e57146d271c2786d7c39ec3e51c6 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 8 Oct 2020 12:23:30 +0200 Subject: [PATCH 094/234] [lldb][swift] Add missing swiftTest decorators The swiftTest decorator should be on all Swift tests to make sure they are only run in configurations where Swift is supported. Otherwise these tests are still run and will fail when the Swift plugin is disabled. --- lldb/packages/Python/lldbsuite/test/lldbplaygroundrepl.py | 1 + lldb/test/API/commands/help/TestHelp.py | 1 + .../functionalities/mtc/swift-property/TestMTCSwiftProperty.py | 1 + lldb/test/API/functionalities/mtc/swift/TestMTCSwift.py | 1 + lldb/test/API/lang/swift/availability/TestAvailability.py | 1 + lldb/test/API/lang/swift/completion/TestSwiftREPLCompletion.py | 2 ++ .../swift/delayed_parsing_crash/TestDelayedParsingCrash.py | 2 +- .../deserialization_failure/TestSwiftDeserializationFailure.py | 2 ++ lldb/test/API/lang/swift/enum_associated/TestEnumAssociated.py | 2 +- .../API/lang/swift/expression/errors/TestExpressionErrors.py | 1 + lldb/test/API/lang/swift/missing_sdk/TestMissingSDK.py | 1 + .../API/lang/swift/objc_runtime_ivars/TestObjCIvarDiscovery.py | 2 ++ .../API/lang/swift/private_import/TestSwiftPrivateImport.py | 1 + .../swift/protocol_extension_two/TestProtocolExtensionTwo.py | 2 +- lldb/test/API/repl/array/TestREPLArray.py | 3 ++- lldb/test/API/repl/cpp_exceptions/TestCPPExceptionsInREPL.py | 2 ++ 16 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/lldbplaygroundrepl.py b/lldb/packages/Python/lldbsuite/test/lldbplaygroundrepl.py index b3238f5025a26..74ed2bd0c8ccb 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbplaygroundrepl.py +++ b/lldb/packages/Python/lldbsuite/test/lldbplaygroundrepl.py @@ -129,6 +129,7 @@ def did_crash(self, result): error = self.get_stream_data(result) print("Crash Error: {}".format(error)) + @swiftTest def test_playgrounds(self): # Build self.build_all() diff --git a/lldb/test/API/commands/help/TestHelp.py b/lldb/test/API/commands/help/TestHelp.py index c9dc39650d881..3147a2a47520b 100644 --- a/lldb/test/API/commands/help/TestHelp.py +++ b/lldb/test/API/commands/help/TestHelp.py @@ -81,6 +81,7 @@ def test_help_arch(self): substrs=['arm', 'i386', 'x86_64']) @no_debug_info_test + @swiftTest # Checks for the Swift version number in the output def test_help_version(self): """Test 'help version' and 'version' commands.""" self.expect("help version", diff --git a/lldb/test/API/functionalities/mtc/swift-property/TestMTCSwiftProperty.py b/lldb/test/API/functionalities/mtc/swift-property/TestMTCSwiftProperty.py index de5ed00f4d28a..b27f8530be4fb 100644 --- a/lldb/test/API/functionalities/mtc/swift-property/TestMTCSwiftProperty.py +++ b/lldb/test/API/functionalities/mtc/swift-property/TestMTCSwiftProperty.py @@ -19,6 +19,7 @@ class MTCSwiftPropertyTestCase(TestBase): @expectedFailureAll(bugnumber="rdar://60396797", setting=('symbols.use-swift-clangimporter', 'false')) @skipUnlessDarwin + @swiftTest def test(self): self.mtc_dylib_path = findMainThreadCheckerDylib() self.assertTrue(self.mtc_dylib_path != "") diff --git a/lldb/test/API/functionalities/mtc/swift/TestMTCSwift.py b/lldb/test/API/functionalities/mtc/swift/TestMTCSwift.py index fbfaeea46e09b..9fc68a2e8feb9 100644 --- a/lldb/test/API/functionalities/mtc/swift/TestMTCSwift.py +++ b/lldb/test/API/functionalities/mtc/swift/TestMTCSwift.py @@ -19,6 +19,7 @@ class MTCSwiftTestCase(TestBase): @expectedFailureAll(bugnumber="rdar://60396797", setting=('symbols.use-swift-clangimporter', 'false')) @skipUnlessDarwin + @swiftTest def test(self): self.mtc_dylib_path = findMainThreadCheckerDylib() self.assertTrue(self.mtc_dylib_path != "") diff --git a/lldb/test/API/lang/swift/availability/TestAvailability.py b/lldb/test/API/lang/swift/availability/TestAvailability.py index 9d9f89da06a7b..e497d6920e347 100644 --- a/lldb/test/API/lang/swift/availability/TestAvailability.py +++ b/lldb/test/API/lang/swift/availability/TestAvailability.py @@ -41,6 +41,7 @@ def setUp(self): # Call super's setUp(). TestBase.setUp(self) + @swiftTest @skipIf(oslist=['linux', 'windows']) def testAvailability(self): platform_name = lldbplatformutil.getPlatform() diff --git a/lldb/test/API/lang/swift/completion/TestSwiftREPLCompletion.py b/lldb/test/API/lang/swift/completion/TestSwiftREPLCompletion.py index e54408916884e..6e665e17e0228 100644 --- a/lldb/test/API/lang/swift/completion/TestSwiftREPLCompletion.py +++ b/lldb/test/API/lang/swift/completion/TestSwiftREPLCompletion.py @@ -12,6 +12,7 @@ class SwiftCompletionTest(PExpectTest): # under ASAN on a loaded machine.. @skipIfAsan @skipUnlessDarwin + @swiftTest def test_basic_completion(self): self.launch(extra_args=["--repl"], executable=None, dimensions=(100,500)) @@ -41,6 +42,7 @@ def test_basic_completion(self): # under ASAN on a loaded machine.. @skipIfAsan @skipIf(oslist=['windows']) + @swiftTest def test_lldb_command_completion(self): self.launch(extra_args=["--repl"], executable=None, dimensions=(100,500)) diff --git a/lldb/test/API/lang/swift/delayed_parsing_crash/TestDelayedParsingCrash.py b/lldb/test/API/lang/swift/delayed_parsing_crash/TestDelayedParsingCrash.py index 3c0912ac0181f..e0768afb05784 100644 --- a/lldb/test/API/lang/swift/delayed_parsing_crash/TestDelayedParsingCrash.py +++ b/lldb/test/API/lang/swift/delayed_parsing_crash/TestDelayedParsingCrash.py @@ -1,4 +1,4 @@ import lldbsuite.test.lldbinline as lldbinline from lldbsuite.test.decorators import * -lldbinline.MakeInlineTest(__file__, globals()) +lldbinline.MakeInlineTest(__file__, globals(), decorators=[swiftTest]) diff --git a/lldb/test/API/lang/swift/deserialization_failure/TestSwiftDeserializationFailure.py b/lldb/test/API/lang/swift/deserialization_failure/TestSwiftDeserializationFailure.py index 5499d5d21dae4..56fe6b2af2186 100644 --- a/lldb/test/API/lang/swift/deserialization_failure/TestSwiftDeserializationFailure.py +++ b/lldb/test/API/lang/swift/deserialization_failure/TestSwiftDeserializationFailure.py @@ -37,6 +37,7 @@ def run_tests(self, target, process): # FIXME: this is formatted incorrectly. self.expect("fr var t", substrs=["(T)"]) #, "world"]) + @swiftTest @skipIf(oslist=['windows']) @skipIf(debug_info=no_match(["dwarf"])) @expectedFailureAll(archs=["arm64", "arm64e", 'arm64_32'], bugnumber="") @@ -47,6 +48,7 @@ def test_missing_module(self): target, process, _, _ = lldbutil.run_to_name_breakpoint(self, 'main') self.run_tests(target, process) + @swiftTest @skipIf(oslist=['windows']) @skipIf(debug_info=no_match(["dwarf"])) @expectedFailureAll(archs=["arm64", "arm64e", 'arm64_32'], bugnumber="") diff --git a/lldb/test/API/lang/swift/enum_associated/TestEnumAssociated.py b/lldb/test/API/lang/swift/enum_associated/TestEnumAssociated.py index 3c0912ac0181f..e0768afb05784 100644 --- a/lldb/test/API/lang/swift/enum_associated/TestEnumAssociated.py +++ b/lldb/test/API/lang/swift/enum_associated/TestEnumAssociated.py @@ -1,4 +1,4 @@ import lldbsuite.test.lldbinline as lldbinline from lldbsuite.test.decorators import * -lldbinline.MakeInlineTest(__file__, globals()) +lldbinline.MakeInlineTest(__file__, globals(), decorators=[swiftTest]) diff --git a/lldb/test/API/lang/swift/expression/errors/TestExpressionErrors.py b/lldb/test/API/lang/swift/expression/errors/TestExpressionErrors.py index e52aa32956af8..74927b5bc0869 100644 --- a/lldb/test/API/lang/swift/expression/errors/TestExpressionErrors.py +++ b/lldb/test/API/lang/swift/expression/errors/TestExpressionErrors.py @@ -24,6 +24,7 @@ class TestExpressionErrors(TestBase): mydir = TestBase.compute_mydir(__file__) + @swiftTest def test_CanThrowError(self): """Tests that swift expressions resolve scoped variables correctly""" self.build() diff --git a/lldb/test/API/lang/swift/missing_sdk/TestMissingSDK.py b/lldb/test/API/lang/swift/missing_sdk/TestMissingSDK.py index ca01eaf57eca5..f6bb817f70661 100644 --- a/lldb/test/API/lang/swift/missing_sdk/TestMissingSDK.py +++ b/lldb/test/API/lang/swift/missing_sdk/TestMissingSDK.py @@ -19,6 +19,7 @@ def setUp(self): # Call super's setUp(). TestBase.setUp(self) + @swiftTest @skipIf(oslist=['windows']) @skipIfDarwinEmbedded # swift crash inspecting swift stdlib with little other swift loaded def testMissingSDK(self): diff --git a/lldb/test/API/lang/swift/objc_runtime_ivars/TestObjCIvarDiscovery.py b/lldb/test/API/lang/swift/objc_runtime_ivars/TestObjCIvarDiscovery.py index b9d7ea746ad57..7a5870fd28c9b 100644 --- a/lldb/test/API/lang/swift/objc_runtime_ivars/TestObjCIvarDiscovery.py +++ b/lldb/test/API/lang/swift/objc_runtime_ivars/TestObjCIvarDiscovery.py @@ -28,6 +28,7 @@ class TestObjCIVarDiscovery(TestBase): @skipUnlessDarwin @skipIf(debug_info=no_match("dsym")) + @swiftTest def test_nodbg(self): self.build() shutil.rmtree(self.getBuildArtifact("aTestFramework.framework/Versions/A/aTestFramework.dSYM")) @@ -35,6 +36,7 @@ def test_nodbg(self): @skipUnlessDarwin @skipIf(debug_info=no_match("dsym")) + @swiftTest def test_dbg(self): self.build() self.do_test(True) diff --git a/lldb/test/API/lang/swift/private_import/TestSwiftPrivateImport.py b/lldb/test/API/lang/swift/private_import/TestSwiftPrivateImport.py index 698b4bc0511fd..da77c07c8dbef 100644 --- a/lldb/test/API/lang/swift/private_import/TestSwiftPrivateImport.py +++ b/lldb/test/API/lang/swift/private_import/TestSwiftPrivateImport.py @@ -11,6 +11,7 @@ def setUp(self): TestBase.setUp(self) @skipUnlessDarwin + @swiftTest def test_private_import(self): """Test a library with a private import for which there is no debug info""" invisible_swift = self.getBuildArtifact("Invisible.swift") diff --git a/lldb/test/API/lang/swift/protocol_extension_two/TestProtocolExtensionTwo.py b/lldb/test/API/lang/swift/protocol_extension_two/TestProtocolExtensionTwo.py index 3c0912ac0181f..e0768afb05784 100644 --- a/lldb/test/API/lang/swift/protocol_extension_two/TestProtocolExtensionTwo.py +++ b/lldb/test/API/lang/swift/protocol_extension_two/TestProtocolExtensionTwo.py @@ -1,4 +1,4 @@ import lldbsuite.test.lldbinline as lldbinline from lldbsuite.test.decorators import * -lldbinline.MakeInlineTest(__file__, globals()) +lldbinline.MakeInlineTest(__file__, globals(), decorators=[swiftTest]) diff --git a/lldb/test/API/repl/array/TestREPLArray.py b/lldb/test/API/repl/array/TestREPLArray.py index caabfff293660..8cbb966ab63ba 100644 --- a/lldb/test/API/repl/array/TestREPLArray.py +++ b/lldb/test/API/repl/array/TestREPLArray.py @@ -1,4 +1,5 @@ import lldbsuite.test.lldbinrepl as lldbinrepl import lldbsuite.test.lldbtest as lldbtest +from lldbsuite.test.decorators import * -lldbinrepl.MakeREPLTest(__file__, globals(), []) +lldbinrepl.MakeREPLTest(__file__, globals(), decorators=[swiftTest]) diff --git a/lldb/test/API/repl/cpp_exceptions/TestCPPExceptionsInREPL.py b/lldb/test/API/repl/cpp_exceptions/TestCPPExceptionsInREPL.py index f305b01bbf8ba..00c1993cecd82 100644 --- a/lldb/test/API/repl/cpp_exceptions/TestCPPExceptionsInREPL.py +++ b/lldb/test/API/repl/cpp_exceptions/TestCPPExceptionsInREPL.py @@ -26,6 +26,7 @@ class TestREPLExceptions(TestBase): NO_DEBUG_INFO_TESTCASE = True @decorators.skipUnlessDarwin + @decorators.swiftTest def test_set_repl_mode_exceptions(self): """ Test that SetREPLMode turns off trapping exceptions.""" self.build() @@ -33,6 +34,7 @@ def test_set_repl_mode_exceptions(self): self.do_repl_mode_test() @decorators.skipUnlessDarwin + @decorators.swiftTest def test_repl_exceptions(self): """ Test the lldb --repl turns off trapping exceptions.""" self.build() From d58b51483a07451abd401c40c943f5e4393b5156 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Thu, 8 Oct 2020 13:26:06 -0700 Subject: [PATCH 095/234] Rename test to give it a unique name --- .../dwarfimporter/from_dylib/TestSwiftDWARFImporterFromDylib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/test/API/lang/swift/dwarfimporter/from_dylib/TestSwiftDWARFImporterFromDylib.py b/lldb/test/API/lang/swift/dwarfimporter/from_dylib/TestSwiftDWARFImporterFromDylib.py index 7369fcd926fb5..876290917fb90 100644 --- a/lldb/test/API/lang/swift/dwarfimporter/from_dylib/TestSwiftDWARFImporterFromDylib.py +++ b/lldb/test/API/lang/swift/dwarfimporter/from_dylib/TestSwiftDWARFImporterFromDylib.py @@ -4,7 +4,7 @@ import lldbsuite.test.lldbutil as lldbutil import os -class TestSwiftDWARFImporterC(lldbtest.TestBase): +class TestSwiftDWARFImporterFromDylib(lldbtest.TestBase): mydir = lldbtest.TestBase.compute_mydir(__file__) From bee62864487d29e80c225dde26ca468de7b18887 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Thu, 8 Oct 2020 13:26:06 -0700 Subject: [PATCH 096/234] Rename test to give it a unique name --- .../dwarfimporter/from_dylib/TestSwiftDWARFImporterFromDylib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/test/API/lang/swift/dwarfimporter/from_dylib/TestSwiftDWARFImporterFromDylib.py b/lldb/test/API/lang/swift/dwarfimporter/from_dylib/TestSwiftDWARFImporterFromDylib.py index 7369fcd926fb5..876290917fb90 100644 --- a/lldb/test/API/lang/swift/dwarfimporter/from_dylib/TestSwiftDWARFImporterFromDylib.py +++ b/lldb/test/API/lang/swift/dwarfimporter/from_dylib/TestSwiftDWARFImporterFromDylib.py @@ -4,7 +4,7 @@ import lldbsuite.test.lldbutil as lldbutil import os -class TestSwiftDWARFImporterC(lldbtest.TestBase): +class TestSwiftDWARFImporterFromDylib(lldbtest.TestBase): mydir = lldbtest.TestBase.compute_mydir(__file__) From 5f90706e5b0ab8fd71882e06e1baeecfa41ad8d7 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Thu, 8 Oct 2020 21:11:06 -0700 Subject: [PATCH 097/234] Add tests; Fix found bug; Add descriptive comment --- .../Swift/TypeSystemSwiftTypeRef.cpp | 8 +++++++- .../Symbol/TestTypeSystemSwiftTypeRef.cpp | 20 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index af9622c47bbfa..1f47599a38cb0 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1886,11 +1886,16 @@ CompilerType TypeSystemSwiftTypeRef::CreateTupleType( auto impl = [&]() -> CompilerType { using namespace swift::Demangle; Demangler dem; + auto *tuple_type = dem.createNode(Node::Kind::Type); auto *tuple = dem.createNode(Node::Kind::Tuple); + tuple_type->addChild(tuple, dem); + for (const auto &element : elements) { auto *tuple_element = dem.createNode(Node::Kind::TupleElement); tuple->addChild(tuple_element, dem); + // Add the element's name, if it has one. + // Ex: `(Int, Int)` vs `(x: Int, y: Int)` if (!element.element_name.IsEmpty()) { auto *name = dem.createNode(Node::Kind::TupleElementName, element.element_name.GetStringRef()); @@ -1903,7 +1908,8 @@ CompilerType TypeSystemSwiftTypeRef::CreateTupleType( dem, element.element_type.GetMangledTypeName().GetStringRef()); type->addChild(element_type, dem); } - return RemangleAsType(dem, tuple); + + return RemangleAsType(dem, tuple_type); }; // The signature of VALIDATE_AND_RETURN doesn't support this function, below diff --git a/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp b/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp index c5f4f3e0ff1fc..add52ffa0801c 100644 --- a/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp +++ b/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp @@ -364,6 +364,26 @@ TEST_F(TestTypeSystemSwiftTypeRef, LanguageVersion) { } } +TEST_F(TestTypeSystemSwiftTypeRef, Tuple) { + using namespace swift::Demangle; + Demangler dem; + NodeBuilder b(dem); + NodePointer int_node = b.GlobalTypeMangling(b.IntType()); + auto int_type = GetCompilerType(b.Mangle(int_node)); + TypeSystemSwift::TupleElement int_element{{}, int_type}; + NodePointer float_node = b.GlobalTypeMangling(b.FloatType()); + auto float_type = GetCompilerType(b.Mangle(float_node)); + TypeSystemSwift::TupleElement float_element{{}, float_type}; + auto int_float_tuple = + m_swift_ts.CreateTupleType({int_element, float_element}); + ASSERT_EQ(int_float_tuple.GetMangledTypeName(), + "$ss0016BuiltinInt_gCJAcV_s0019BuiltinFPIEEE_CJEEdVtD"); + auto float_int_tuple = + m_swift_ts.CreateTupleType({float_element, int_element}); + ASSERT_EQ(float_int_tuple.GetMangledTypeName(), + "$ss0019BuiltinFPIEEE_CJEEdV_s0016BuiltinInt_gCJAcVtD"); +} + TEST_F(TestTypeSystemSwiftTypeRef, TypeClass) { using namespace swift::Demangle; Demangler dem; From 190f7a8fa8903d68e5d0ba4f5bb669f4c1016edc Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Thu, 8 Oct 2020 21:22:52 -0700 Subject: [PATCH 098/234] Test named tuple elements too --- .../Symbol/TestTypeSystemSwiftTypeRef.cpp | 48 +++++++++++++------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp b/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp index add52ffa0801c..19d8b54953fae 100644 --- a/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp +++ b/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp @@ -368,20 +368,40 @@ TEST_F(TestTypeSystemSwiftTypeRef, Tuple) { using namespace swift::Demangle; Demangler dem; NodeBuilder b(dem); - NodePointer int_node = b.GlobalTypeMangling(b.IntType()); - auto int_type = GetCompilerType(b.Mangle(int_node)); - TypeSystemSwift::TupleElement int_element{{}, int_type}; - NodePointer float_node = b.GlobalTypeMangling(b.FloatType()); - auto float_type = GetCompilerType(b.Mangle(float_node)); - TypeSystemSwift::TupleElement float_element{{}, float_type}; - auto int_float_tuple = - m_swift_ts.CreateTupleType({int_element, float_element}); - ASSERT_EQ(int_float_tuple.GetMangledTypeName(), - "$ss0016BuiltinInt_gCJAcV_s0019BuiltinFPIEEE_CJEEdVtD"); - auto float_int_tuple = - m_swift_ts.CreateTupleType({float_element, int_element}); - ASSERT_EQ(float_int_tuple.GetMangledTypeName(), - "$ss0019BuiltinFPIEEE_CJEEdV_s0016BuiltinInt_gCJAcVtD"); + + auto makeElement = [&](NodePointer type, + const char *name = + nullptr) -> TypeSystemSwift::TupleElement { + auto *node = b.GlobalTypeMangling(type); + return {ConstString(name), GetCompilerType(b.Mangle(node))}; + }; + + { + // Test unnamed tuple elements. + auto int_element = makeElement(b.IntType()); + auto float_element = makeElement(b.FloatType()); + auto int_float_tuple = + m_swift_ts.CreateTupleType({int_element, float_element}); + ASSERT_EQ(int_float_tuple.GetMangledTypeName(), + "$ss0016BuiltinInt_gCJAcV_s0019BuiltinFPIEEE_CJEEdVtD"); + auto float_int_tuple = + m_swift_ts.CreateTupleType({float_element, int_element}); + ASSERT_EQ(float_int_tuple.GetMangledTypeName(), + "$ss0019BuiltinFPIEEE_CJEEdV_s0016BuiltinInt_gCJAcVtD"); + } + { + // Test named tuple elements. + auto int_element = makeElement(b.IntType(), "i"); + auto float_element = makeElement(b.FloatType(), "f"); + auto int_float_tuple = + m_swift_ts.CreateTupleType({int_element, float_element}); + ASSERT_EQ(int_float_tuple.GetMangledTypeName(), + "$ss0016BuiltinInt_gCJAcV1i_s0019BuiltinFPIEEE_CJEEdV1ftD"); + auto float_int_tuple = + m_swift_ts.CreateTupleType({float_element, int_element}); + ASSERT_EQ(float_int_tuple.GetMangledTypeName(), + "$ss0019BuiltinFPIEEE_CJEEdV1f_s0016BuiltinInt_gCJAcV1itD"); + } } TEST_F(TestTypeSystemSwiftTypeRef, TypeClass) { From faaf4b95ded45eded62c17c28b7430ca8ad08c7f Mon Sep 17 00:00:00 2001 From: Ben Barham Date: Thu, 8 Oct 2020 19:48:33 -0700 Subject: [PATCH 099/234] [AST] Fix crashes caused by redeclarations in hidden prototypes ObjCContainerDecl.getMethod returns a nullptr by default when the container is a hidden prototype. Callsites where the method is being looked up on the redeclaration's own container should skip this check since they (rightly) expect a valid method to be found. Resolves rdar://69444243 Reviewed By: akyrtzi Differential Revision: https://reviews.llvm.org/D89024 --- clang/lib/AST/DeclObjC.cpp | 11 +++++++---- clang/test/Index/Inputs/hidden-redecls-sub.h | 7 +++++++ clang/test/Index/Inputs/hidden-redecls.h | 3 +++ clang/test/Index/Inputs/module.map | 8 ++++++++ clang/test/Index/hidden-redecls.m | 12 ++++++++++++ 5 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 clang/test/Index/Inputs/hidden-redecls-sub.h create mode 100644 clang/test/Index/Inputs/hidden-redecls.h create mode 100644 clang/test/Index/hidden-redecls.m diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 817b0ba4f062b..16c43aa4d72c5 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -949,7 +949,8 @@ ObjCMethodDecl *ObjCMethodDecl::getNextRedeclarationImpl() { if (!Redecl && isRedeclaration()) { // This is the last redeclaration, go back to the first method. return cast(CtxD)->getMethod(getSelector(), - isInstanceMethod()); + isInstanceMethod(), + /*AllowHidden=*/true); } return Redecl ? Redecl : this; @@ -982,7 +983,8 @@ ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() { if (isRedeclaration()) { // It is possible that we have not done deserializing the ObjCMethod yet. ObjCMethodDecl *MD = - cast(CtxD)->getMethod(Sel, isInstanceMethod()); + cast(CtxD)->getMethod(Sel, isInstanceMethod(), + /*AllowHidden=*/true); return MD ? MD : this; } @@ -1299,8 +1301,9 @@ void ObjCMethodDecl::getOverriddenMethods( const ObjCMethodDecl *Method = this; if (Method->isRedeclaration()) { - Method = cast(Method->getDeclContext())-> - getMethod(Method->getSelector(), Method->isInstanceMethod()); + Method = cast(Method->getDeclContext()) + ->getMethod(Method->getSelector(), Method->isInstanceMethod(), + /*AllowHidden=*/true); } if (Method->isOverriding()) { diff --git a/clang/test/Index/Inputs/hidden-redecls-sub.h b/clang/test/Index/Inputs/hidden-redecls-sub.h new file mode 100644 index 0000000000000..f5a77977cfba9 --- /dev/null +++ b/clang/test/Index/Inputs/hidden-redecls-sub.h @@ -0,0 +1,7 @@ +@protocol P1 +- (void)p1_method; +- (void)p1_method; +@end + +@interface Foo (SubP1) +@end diff --git a/clang/test/Index/Inputs/hidden-redecls.h b/clang/test/Index/Inputs/hidden-redecls.h new file mode 100644 index 0000000000000..c5558cf0ab18e --- /dev/null +++ b/clang/test/Index/Inputs/hidden-redecls.h @@ -0,0 +1,3 @@ +@interface Foo +- (void)parent_method; +@end diff --git a/clang/test/Index/Inputs/module.map b/clang/test/Index/Inputs/module.map index 10712accb1c24..cd5bcb4670322 100644 --- a/clang/test/Index/Inputs/module.map +++ b/clang/test/Index/Inputs/module.map @@ -20,3 +20,11 @@ module PreambleWithImplicitImport { export * } } + +module hidden_redecls { + header "hidden-redecls.h" + + explicit module sub { + header "hidden-redecls-sub.h" + } +} diff --git a/clang/test/Index/hidden-redecls.m b/clang/test/Index/hidden-redecls.m new file mode 100644 index 0000000000000..1735c0b5e184e --- /dev/null +++ b/clang/test/Index/hidden-redecls.m @@ -0,0 +1,12 @@ +@import hidden_redecls; + +@interface Foo (Top) +- (void)top_method; +@end + +// p1_method in protocol P1 is hidden since module_redecls.sub hasn't been +// imported yet. Check it is still indexed. + +// RUN: c-index-test -index-file-full %s -isystem %S/Inputs -fmodules -target x86_64-apple-macosx10.7 | FileCheck %s +// CHECK: [indexDeclaration]: kind: objc-instance-method | name: p1_method | {{.*}} | loc: {{.*}}hidden-redecls-sub.h:2:9 | {{.*}} | isRedecl: 0 +// CHECK: [indexDeclaration]: kind: objc-instance-method | name: p1_method | {{.*}} | loc: {{.*}}hidden-redecls-sub.h:3:9 | {{.*}} | isRedecl: 1 From 12424dd4486e99171d539219cd9172f0f9703d61 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 6 Oct 2020 23:33:04 -0700 Subject: [PATCH 100/234] [lldb] Format unix signal table (NFC) Restore unix signal table to its original glory and mark it as not to be clang-formatted. (cherry picked from commit 0fcacefd160494280dc040f4f055db6df695ac12) --- lldb/source/Target/UnixSignals.cpp | 86 ++++++++++++++---------------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/lldb/source/Target/UnixSignals.cpp b/lldb/source/Target/UnixSignals.cpp index dce32adbf0a36..f6b4e82a88ed9 100644 --- a/lldb/source/Target/UnixSignals.cpp +++ b/lldb/source/Target/UnixSignals.cpp @@ -65,55 +65,49 @@ UnixSignals::UnixSignals(const UnixSignals &rhs) : m_signals(rhs.m_signals) {} UnixSignals::~UnixSignals() = default; void UnixSignals::Reset() { - // This builds one standard set of Unix Signals. If yours aren't quite in + // This builds one standard set of Unix Signals. If yours aren't quite in // this order, you can either subclass this class, and use Add & Remove to - // change them - // or you can subclass and build them afresh in your constructor; + // change them or you can subclass and build them afresh in your constructor. // - // Note: the signals below are the Darwin signals. Do not change these! + // Note: the signals below are the Darwin signals. Do not change these! + m_signals.clear(); - // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION - // ====== ============ ======== ====== ====== - // =================================================== - AddSignal(1, "SIGHUP", false, true, true, "hangup"); - AddSignal(2, "SIGINT", true, true, true, "interrupt"); - AddSignal(3, "SIGQUIT", false, true, true, "quit"); - AddSignal(4, "SIGILL", false, true, true, "illegal instruction"); - AddSignal(5, "SIGTRAP", true, true, true, - "trace trap (not reset when caught)"); - AddSignal(6, "SIGABRT", false, true, true, "abort()"); - AddSignal(7, "SIGEMT", false, true, true, "pollable event"); - AddSignal(8, "SIGFPE", false, true, true, "floating point exception"); - AddSignal(9, "SIGKILL", false, true, true, "kill"); - AddSignal(10, "SIGBUS", false, true, true, "bus error"); - AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation"); - AddSignal(12, "SIGSYS", false, true, true, "bad argument to system call"); - AddSignal(13, "SIGPIPE", false, false, false, - "write on a pipe with no one to read it"); - AddSignal(14, "SIGALRM", false, false, false, "alarm clock"); - AddSignal(15, "SIGTERM", false, true, true, - "software termination signal from kill"); - AddSignal(16, "SIGURG", false, false, false, - "urgent condition on IO channel"); - AddSignal(17, "SIGSTOP", true, true, true, - "sendable stop signal not from tty"); - AddSignal(18, "SIGTSTP", false, true, true, "stop signal from tty"); - AddSignal(19, "SIGCONT", false, true, true, "continue a stopped process"); - AddSignal(20, "SIGCHLD", false, false, false, - "to parent on child stop or exit"); - AddSignal(21, "SIGTTIN", false, true, true, - "to readers process group upon background tty read"); - AddSignal(22, "SIGTTOU", false, true, true, - "to readers process group upon background tty write"); - AddSignal(23, "SIGIO", false, false, false, "input/output possible signal"); - AddSignal(24, "SIGXCPU", false, true, true, "exceeded CPU time limit"); - AddSignal(25, "SIGXFSZ", false, true, true, "exceeded file size limit"); - AddSignal(26, "SIGVTALRM", false, false, false, "virtual time alarm"); - AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm"); - AddSignal(28, "SIGWINCH", false, false, false, "window size changes"); - AddSignal(29, "SIGINFO", false, true, true, "information request"); - AddSignal(30, "SIGUSR1", false, true, true, "user defined signal 1"); - AddSignal(31, "SIGUSR2", false, true, true, "user defined signal 2"); + + // clang-format off + // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION + // ====== ============ ======== ====== ====== =================================================== + AddSignal(1, "SIGHUP", false, true, true, "hangup"); + AddSignal(2, "SIGINT", true, true, true, "interrupt"); + AddSignal(3, "SIGQUIT", false, true, true, "quit"); + AddSignal(4, "SIGILL", false, true, true, "illegal instruction"); + AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)"); + AddSignal(6, "SIGABRT", false, true, true, "abort()"); + AddSignal(7, "SIGEMT", false, true, true, "pollable event"); + AddSignal(8, "SIGFPE", false, true, true, "floating point exception"); + AddSignal(9, "SIGKILL", false, true, true, "kill"); + AddSignal(10, "SIGBUS", false, true, true, "bus error"); + AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation"); + AddSignal(12, "SIGSYS", false, true, true, "bad argument to system call"); + AddSignal(13, "SIGPIPE", false, false, false, "write on a pipe with no one to read it"); + AddSignal(14, "SIGALRM", false, false, false, "alarm clock"); + AddSignal(15, "SIGTERM", false, true, true, "software termination signal from kill"); + AddSignal(16, "SIGURG", false, false, false, "urgent condition on IO channel"); + AddSignal(17, "SIGSTOP", true, true, true, "sendable stop signal not from tty"); + AddSignal(18, "SIGTSTP", false, true, true, "stop signal from tty"); + AddSignal(19, "SIGCONT", false, true, true, "continue a stopped process"); + AddSignal(20, "SIGCHLD", false, false, false, "to parent on child stop or exit"); + AddSignal(21, "SIGTTIN", false, true, true, "to readers process group upon background tty read"); + AddSignal(22, "SIGTTOU", false, true, true, "to readers process group upon background tty write"); + AddSignal(23, "SIGIO", false, false, false, "input/output possible signal"); + AddSignal(24, "SIGXCPU", false, true, true, "exceeded CPU time limit"); + AddSignal(25, "SIGXFSZ", false, true, true, "exceeded file size limit"); + AddSignal(26, "SIGVTALRM", false, false, false, "virtual time alarm"); + AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm"); + AddSignal(28, "SIGWINCH", false, false, false, "window size changes"); + AddSignal(29, "SIGINFO", false, true, true, "information request"); + AddSignal(30, "SIGUSR1", false, true, true, "user defined signal 1"); + AddSignal(31, "SIGUSR2", false, true, true, "user defined signal 2"); + // clang-format on } void UnixSignals::AddSignal(int signo, const char *name, bool default_suppress, From f27bb63a59427ba8daf61491c3f2d163e0ad64d7 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Thu, 8 Oct 2020 15:21:51 -0700 Subject: [PATCH 101/234] Change the default handling of SIGCONT to nosuppress/nostop/notify Except for the few people actually debugging shells, stopping on a SIGCONT doesn't add any value. And for people trying to run tests under the debugger, stopping here is actively inconvenient. So this patch switches the default behavior to not stop. Differential Revision: https://reviews.llvm.org/D89019 (cherry picked from commit a68ffb19d392c6d52f6e42925217a77b4cd71cee) --- lldb/source/Plugins/Process/Utility/LinuxSignals.cpp | 2 +- lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp | 2 +- lldb/source/Target/UnixSignals.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp b/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp index 4dd619e3bade8..568939029aeea 100644 --- a/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp +++ b/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp @@ -37,7 +37,7 @@ void LinuxSignals::Reset() { AddSignal(16, "SIGSTKFLT", false, true, true, "stack fault"); AddSignal(17, "SIGCHLD", false, false, true, "child status has changed", "SIGCLD"); - AddSignal(18, "SIGCONT", false, true, true, "process continue"); + AddSignal(18, "SIGCONT", false, false, true, "process continue"); AddSignal(19, "SIGSTOP", true, true, true, "process stop"); AddSignal(20, "SIGTSTP", false, true, true, "tty stop"); AddSignal(21, "SIGTTIN", false, true, true, "background tty read"); diff --git a/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp index 8f75844277c0e..17c238c044535 100644 --- a/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp +++ b/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp @@ -45,7 +45,7 @@ void MipsLinuxSignals::Reset() { "SIGPOLL"); AddSignal(23, "SIGSTOP", true, true, true, "process stop"); AddSignal(24, "SIGTSTP", false, true, true, "tty stop"); - AddSignal(25, "SIGCONT", false, true, true, "process continue"); + AddSignal(25, "SIGCONT", false, false, true, "process continue"); AddSignal(26, "SIGTTIN", false, true, true, "background tty read"); AddSignal(27, "SIGTTOU", false, true, true, "background tty write"); AddSignal(28, "SIGVTALRM", false, true, true, "virtual time alarm"); diff --git a/lldb/source/Target/UnixSignals.cpp b/lldb/source/Target/UnixSignals.cpp index f6b4e82a88ed9..84a2ef67ac29e 100644 --- a/lldb/source/Target/UnixSignals.cpp +++ b/lldb/source/Target/UnixSignals.cpp @@ -94,7 +94,7 @@ void UnixSignals::Reset() { AddSignal(16, "SIGURG", false, false, false, "urgent condition on IO channel"); AddSignal(17, "SIGSTOP", true, true, true, "sendable stop signal not from tty"); AddSignal(18, "SIGTSTP", false, true, true, "stop signal from tty"); - AddSignal(19, "SIGCONT", false, true, true, "continue a stopped process"); + AddSignal(19, "SIGCONT", false, false, true, "continue a stopped process"); AddSignal(20, "SIGCHLD", false, false, false, "to parent on child stop or exit"); AddSignal(21, "SIGTTIN", false, true, true, "to readers process group upon background tty read"); AddSignal(22, "SIGTTOU", false, true, true, "to readers process group upon background tty write"); From 216e87d0f30b3506c1011a072362f613c9720184 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Thu, 8 Oct 2020 20:01:21 -0700 Subject: [PATCH 102/234] [lldb] Format remaining signal table (NFC) Restore the signal tables to its original glory and mark it as not to be clang-formatted. (cherry picked from commit 9d7b08bd0657688c186b5b3d39512c484e8c37f5) --- .../Plugins/Process/Utility/LinuxSignals.cpp | 143 +++++++++--------- .../Process/Utility/MipsLinuxSignals.cpp | 143 +++++++++--------- lldb/source/Target/UnixSignals.cpp | 66 ++++---- 3 files changed, 169 insertions(+), 183 deletions(-) diff --git a/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp b/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp index 568939029aeea..d4b0f4039da95 100644 --- a/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp +++ b/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp @@ -14,79 +14,72 @@ LinuxSignals::LinuxSignals() : UnixSignals() { Reset(); } void LinuxSignals::Reset() { m_signals.clear(); - // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION ALIAS - // ===== =========== ======== ===== ====== - // ====================================== ====== - AddSignal(1, "SIGHUP", false, true, true, "hangup"); - AddSignal(2, "SIGINT", true, true, true, "interrupt"); - AddSignal(3, "SIGQUIT", false, true, true, "quit"); - AddSignal(4, "SIGILL", false, true, true, "illegal instruction"); - AddSignal(5, "SIGTRAP", true, true, true, - "trace trap (not reset when caught)"); - AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT"); - AddSignal(7, "SIGBUS", false, true, true, "bus error"); - AddSignal(8, "SIGFPE", false, true, true, "floating point exception"); - AddSignal(9, "SIGKILL", false, true, true, "kill"); - AddSignal(10, "SIGUSR1", false, true, true, "user defined signal 1"); - AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation"); - AddSignal(12, "SIGUSR2", false, true, true, "user defined signal 2"); - AddSignal(13, "SIGPIPE", false, true, true, - "write to pipe with reading end closed"); - AddSignal(14, "SIGALRM", false, false, false, "alarm"); - AddSignal(15, "SIGTERM", false, true, true, "termination requested"); - AddSignal(16, "SIGSTKFLT", false, true, true, "stack fault"); - AddSignal(17, "SIGCHLD", false, false, true, "child status has changed", - "SIGCLD"); - AddSignal(18, "SIGCONT", false, false, true, "process continue"); - AddSignal(19, "SIGSTOP", true, true, true, "process stop"); - AddSignal(20, "SIGTSTP", false, true, true, "tty stop"); - AddSignal(21, "SIGTTIN", false, true, true, "background tty read"); - AddSignal(22, "SIGTTOU", false, true, true, "background tty write"); - AddSignal(23, "SIGURG", false, true, true, "urgent data on socket"); - AddSignal(24, "SIGXCPU", false, true, true, "CPU resource exceeded"); - AddSignal(25, "SIGXFSZ", false, true, true, "file size limit exceeded"); - AddSignal(26, "SIGVTALRM", false, true, true, "virtual time alarm"); - AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm"); - AddSignal(28, "SIGWINCH", false, true, true, "window size changes"); - AddSignal(29, "SIGIO", false, true, true, "input/output ready/Pollable event", - "SIGPOLL"); - AddSignal(30, "SIGPWR", false, true, true, "power failure"); - AddSignal(31, "SIGSYS", false, true, true, "invalid system call"); - AddSignal(32, "SIG32", false, false, false, - "threading library internal signal 1"); - AddSignal(33, "SIG33", false, false, false, - "threading library internal signal 2"); - AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0"); - AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1"); - AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2"); - AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3"); - AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4"); - AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5"); - AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6"); - AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7"); - AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8"); - AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9"); - AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10"); - AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11"); - AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12"); - AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13"); - AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14"); - AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15"); - AddSignal(50, "SIGRTMAX-14", false, false, false, - "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill - // -l" output - AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17"); - AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18"); - AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19"); - AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20"); - AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21"); - AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22"); - AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23"); - AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24"); - AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25"); - AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26"); - AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27"); - AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28"); - AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29"); - AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30"); + // clang-format off + // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION + // ====== ============== ======== ====== ====== =================================================== + AddSignal(1, "SIGHUP", false, true, true, "hangup"); + AddSignal(2, "SIGINT", true, true, true, "interrupt"); + AddSignal(3, "SIGQUIT", false, true, true, "quit"); + AddSignal(4, "SIGILL", false, true, true, "illegal instruction"); + AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)"); + AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT"); + AddSignal(7, "SIGBUS", false, true, true, "bus error"); + AddSignal(8, "SIGFPE", false, true, true, "floating point exception"); + AddSignal(9, "SIGKILL", false, true, true, "kill"); + AddSignal(10, "SIGUSR1", false, true, true, "user defined signal 1"); + AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation"); + AddSignal(12, "SIGUSR2", false, true, true, "user defined signal 2"); + AddSignal(13, "SIGPIPE", false, true, true, "write to pipe with reading end closed"); + AddSignal(14, "SIGALRM", false, false, false, "alarm"); + AddSignal(15, "SIGTERM", false, true, true, "termination requested"); + AddSignal(16, "SIGSTKFLT", false, true, true, "stack fault"); + AddSignal(17, "SIGCHLD", false, false, true, "child status has changed", "SIGCLD"); + AddSignal(18, "SIGCONT", false, false, true, "process continue"); + AddSignal(19, "SIGSTOP", true, true, true, "process stop"); + AddSignal(20, "SIGTSTP", false, true, true, "tty stop"); + AddSignal(21, "SIGTTIN", false, true, true, "background tty read"); + AddSignal(22, "SIGTTOU", false, true, true, "background tty write"); + AddSignal(23, "SIGURG", false, true, true, "urgent data on socket"); + AddSignal(24, "SIGXCPU", false, true, true, "CPU resource exceeded"); + AddSignal(25, "SIGXFSZ", false, true, true, "file size limit exceeded"); + AddSignal(26, "SIGVTALRM", false, true, true, "virtual time alarm"); + AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm"); + AddSignal(28, "SIGWINCH", false, true, true, "window size changes"); + AddSignal(29, "SIGIO", false, true, true, "input/output ready/Pollable event", "SIGPOLL"); + AddSignal(30, "SIGPWR", false, true, true, "power failure"); + AddSignal(31, "SIGSYS", false, true, true, "invalid system call"); + AddSignal(32, "SIG32", false, false, false, "threading library internal signal 1"); + AddSignal(33, "SIG33", false, false, false, "threading library internal signal 2"); + AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0"); + AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1"); + AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2"); + AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3"); + AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4"); + AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5"); + AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6"); + AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7"); + AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8"); + AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9"); + AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10"); + AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11"); + AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12"); + AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13"); + AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14"); + AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15"); + AddSignal(50, "SIGRTMAX-14", false, false, false, "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill -l" output + AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17"); + AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18"); + AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19"); + AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20"); + AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21"); + AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22"); + AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23"); + AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24"); + AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25"); + AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26"); + AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27"); + AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28"); + AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29"); + AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30"); + // clang-format on } diff --git a/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp index 17c238c044535..fb51c56953f85 100644 --- a/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp +++ b/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp @@ -14,79 +14,72 @@ MipsLinuxSignals::MipsLinuxSignals() : UnixSignals() { Reset(); } void MipsLinuxSignals::Reset() { m_signals.clear(); - // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION ALIAS - // ===== =========== ======== ===== ====== - // ====================================== ======== - AddSignal(1, "SIGHUP", false, true, true, "hangup"); - AddSignal(2, "SIGINT", true, true, true, "interrupt"); - AddSignal(3, "SIGQUIT", false, true, true, "quit"); - AddSignal(4, "SIGILL", false, true, true, "illegal instruction"); - AddSignal(5, "SIGTRAP", true, true, true, - "trace trap (not reset when caught)"); - AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT"); - AddSignal(7, "SIGEMT", false, true, true, "terminate process with core dump"); - AddSignal(8, "SIGFPE", false, true, true, "floating point exception"); - AddSignal(9, "SIGKILL", false, true, true, "kill"); - AddSignal(10, "SIGBUS", false, true, true, "bus error"); - AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation"); - AddSignal(12, "SIGSYS", false, true, true, "invalid system call"); - AddSignal(13, "SIGPIPE", false, true, true, - "write to pipe with reading end closed"); - AddSignal(14, "SIGALRM", false, false, false, "alarm"); - AddSignal(15, "SIGTERM", false, true, true, "termination requested"); - AddSignal(16, "SIGUSR1", false, true, true, "user defined signal 1"); - AddSignal(17, "SIGUSR2", false, true, true, "user defined signal 2"); - AddSignal(18, "SIGCHLD", false, false, true, "child status has changed", - "SIGCLD"); - AddSignal(19, "SIGPWR", false, true, true, "power failure"); - AddSignal(20, "SIGWINCH", false, true, true, "window size changes"); - AddSignal(21, "SIGURG", false, true, true, "urgent data on socket"); - AddSignal(22, "SIGIO", false, true, true, "input/output ready/Pollable event", - "SIGPOLL"); - AddSignal(23, "SIGSTOP", true, true, true, "process stop"); - AddSignal(24, "SIGTSTP", false, true, true, "tty stop"); - AddSignal(25, "SIGCONT", false, false, true, "process continue"); - AddSignal(26, "SIGTTIN", false, true, true, "background tty read"); - AddSignal(27, "SIGTTOU", false, true, true, "background tty write"); - AddSignal(28, "SIGVTALRM", false, true, true, "virtual time alarm"); - AddSignal(29, "SIGPROF", false, false, false, "profiling time alarm"); - AddSignal(30, "SIGXCPU", false, true, true, "CPU resource exceeded"); - AddSignal(31, "SIGXFSZ", false, true, true, "file size limit exceeded"); - AddSignal(32, "SIG32", false, false, false, - "threading library internal signal 1"); - AddSignal(33, "SIG33", false, false, false, - "threading library internal signal 2"); - AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0"); - AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1"); - AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2"); - AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3"); - AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4"); - AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5"); - AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6"); - AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7"); - AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8"); - AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9"); - AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10"); - AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11"); - AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12"); - AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13"); - AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14"); - AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15"); - AddSignal(50, "SIGRTMAX-14", false, false, false, - "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill - // -l" output - AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17"); - AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18"); - AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19"); - AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20"); - AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21"); - AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22"); - AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23"); - AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24"); - AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25"); - AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26"); - AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27"); - AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28"); - AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29"); - AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30"); + // clang-format off + // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION + // ====== ============== ======== ====== ====== =================================================== + AddSignal(1, "SIGHUP", false, true, true, "hangup"); + AddSignal(2, "SIGINT", true, true, true, "interrupt"); + AddSignal(3, "SIGQUIT", false, true, true, "quit"); + AddSignal(4, "SIGILL", false, true, true, "illegal instruction"); + AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)"); + AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT"); + AddSignal(7, "SIGEMT", false, true, true, "terminate process with core dump"); + AddSignal(8, "SIGFPE", false, true, true, "floating point exception"); + AddSignal(9, "SIGKILL", false, true, true, "kill"); + AddSignal(10, "SIGBUS", false, true, true, "bus error"); + AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation"); + AddSignal(12, "SIGSYS", false, true, true, "invalid system call"); + AddSignal(13, "SIGPIPE", false, true, true, "write to pipe with reading end closed"); + AddSignal(14, "SIGALRM", false, false, false, "alarm"); + AddSignal(15, "SIGTERM", false, true, true, "termination requested"); + AddSignal(16, "SIGUSR1", false, true, true, "user defined signal 1"); + AddSignal(17, "SIGUSR2", false, true, true, "user defined signal 2"); + AddSignal(18, "SIGCHLD", false, false, true, "child status has changed", "SIGCLD"); + AddSignal(19, "SIGPWR", false, true, true, "power failure"); + AddSignal(20, "SIGWINCH", false, true, true, "window size changes"); + AddSignal(21, "SIGURG", false, true, true, "urgent data on socket"); + AddSignal(22, "SIGIO", false, true, true, "input/output ready/Pollable event", "SIGPOLL"); + AddSignal(23, "SIGSTOP", true, true, true, "process stop"); + AddSignal(24, "SIGTSTP", false, true, true, "tty stop"); + AddSignal(25, "SIGCONT", false, false, true, "process continue"); + AddSignal(26, "SIGTTIN", false, true, true, "background tty read"); + AddSignal(27, "SIGTTOU", false, true, true, "background tty write"); + AddSignal(28, "SIGVTALRM", false, true, true, "virtual time alarm"); + AddSignal(29, "SIGPROF", false, false, false, "profiling time alarm"); + AddSignal(30, "SIGXCPU", false, true, true, "CPU resource exceeded"); + AddSignal(31, "SIGXFSZ", false, true, true, "file size limit exceeded"); + AddSignal(32, "SIG32", false, false, false, "threading library internal signal 1"); + AddSignal(33, "SIG33", false, false, false, "threading library internal signal 2"); + AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0"); + AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1"); + AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2"); + AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3"); + AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4"); + AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5"); + AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6"); + AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7"); + AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8"); + AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9"); + AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10"); + AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11"); + AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12"); + AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13"); + AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14"); + AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15"); + AddSignal(50, "SIGRTMAX-14", false, false, false, "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill -l" output + AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17"); + AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18"); + AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19"); + AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20"); + AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21"); + AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22"); + AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23"); + AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24"); + AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25"); + AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26"); + AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27"); + AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28"); + AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29"); + AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30"); + // clang-format on } diff --git a/lldb/source/Target/UnixSignals.cpp b/lldb/source/Target/UnixSignals.cpp index 84a2ef67ac29e..4ec2e25c7e3b0 100644 --- a/lldb/source/Target/UnixSignals.cpp +++ b/lldb/source/Target/UnixSignals.cpp @@ -74,39 +74,39 @@ void UnixSignals::Reset() { m_signals.clear(); // clang-format off - // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION - // ====== ============ ======== ====== ====== =================================================== - AddSignal(1, "SIGHUP", false, true, true, "hangup"); - AddSignal(2, "SIGINT", true, true, true, "interrupt"); - AddSignal(3, "SIGQUIT", false, true, true, "quit"); - AddSignal(4, "SIGILL", false, true, true, "illegal instruction"); - AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)"); - AddSignal(6, "SIGABRT", false, true, true, "abort()"); - AddSignal(7, "SIGEMT", false, true, true, "pollable event"); - AddSignal(8, "SIGFPE", false, true, true, "floating point exception"); - AddSignal(9, "SIGKILL", false, true, true, "kill"); - AddSignal(10, "SIGBUS", false, true, true, "bus error"); - AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation"); - AddSignal(12, "SIGSYS", false, true, true, "bad argument to system call"); - AddSignal(13, "SIGPIPE", false, false, false, "write on a pipe with no one to read it"); - AddSignal(14, "SIGALRM", false, false, false, "alarm clock"); - AddSignal(15, "SIGTERM", false, true, true, "software termination signal from kill"); - AddSignal(16, "SIGURG", false, false, false, "urgent condition on IO channel"); - AddSignal(17, "SIGSTOP", true, true, true, "sendable stop signal not from tty"); - AddSignal(18, "SIGTSTP", false, true, true, "stop signal from tty"); - AddSignal(19, "SIGCONT", false, false, true, "continue a stopped process"); - AddSignal(20, "SIGCHLD", false, false, false, "to parent on child stop or exit"); - AddSignal(21, "SIGTTIN", false, true, true, "to readers process group upon background tty read"); - AddSignal(22, "SIGTTOU", false, true, true, "to readers process group upon background tty write"); - AddSignal(23, "SIGIO", false, false, false, "input/output possible signal"); - AddSignal(24, "SIGXCPU", false, true, true, "exceeded CPU time limit"); - AddSignal(25, "SIGXFSZ", false, true, true, "exceeded file size limit"); - AddSignal(26, "SIGVTALRM", false, false, false, "virtual time alarm"); - AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm"); - AddSignal(28, "SIGWINCH", false, false, false, "window size changes"); - AddSignal(29, "SIGINFO", false, true, true, "information request"); - AddSignal(30, "SIGUSR1", false, true, true, "user defined signal 1"); - AddSignal(31, "SIGUSR2", false, true, true, "user defined signal 2"); + // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION + // ====== ============== ======== ====== ====== =================================================== + AddSignal(1, "SIGHUP", false, true, true, "hangup"); + AddSignal(2, "SIGINT", true, true, true, "interrupt"); + AddSignal(3, "SIGQUIT", false, true, true, "quit"); + AddSignal(4, "SIGILL", false, true, true, "illegal instruction"); + AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)"); + AddSignal(6, "SIGABRT", false, true, true, "abort()"); + AddSignal(7, "SIGEMT", false, true, true, "pollable event"); + AddSignal(8, "SIGFPE", false, true, true, "floating point exception"); + AddSignal(9, "SIGKILL", false, true, true, "kill"); + AddSignal(10, "SIGBUS", false, true, true, "bus error"); + AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation"); + AddSignal(12, "SIGSYS", false, true, true, "bad argument to system call"); + AddSignal(13, "SIGPIPE", false, false, false, "write on a pipe with no one to read it"); + AddSignal(14, "SIGALRM", false, false, false, "alarm clock"); + AddSignal(15, "SIGTERM", false, true, true, "software termination signal from kill"); + AddSignal(16, "SIGURG", false, false, false, "urgent condition on IO channel"); + AddSignal(17, "SIGSTOP", true, true, true, "sendable stop signal not from tty"); + AddSignal(18, "SIGTSTP", false, true, true, "stop signal from tty"); + AddSignal(19, "SIGCONT", false, false, true, "continue a stopped process"); + AddSignal(20, "SIGCHLD", false, false, false, "to parent on child stop or exit"); + AddSignal(21, "SIGTTIN", false, true, true, "to readers process group upon background tty read"); + AddSignal(22, "SIGTTOU", false, true, true, "to readers process group upon background tty write"); + AddSignal(23, "SIGIO", false, false, false, "input/output possible signal"); + AddSignal(24, "SIGXCPU", false, true, true, "exceeded CPU time limit"); + AddSignal(25, "SIGXFSZ", false, true, true, "exceeded file size limit"); + AddSignal(26, "SIGVTALRM", false, false, false, "virtual time alarm"); + AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm"); + AddSignal(28, "SIGWINCH", false, false, false, "window size changes"); + AddSignal(29, "SIGINFO", false, true, true, "information request"); + AddSignal(30, "SIGUSR1", false, true, true, "user defined signal 1"); + AddSignal(31, "SIGUSR2", false, true, true, "user defined signal 2"); // clang-format on } From 347e815c0d30e9ab4c2a490d5360ab4885b84e7b Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Thu, 8 Oct 2020 17:50:28 -0700 Subject: [PATCH 103/234] Add a Transform() utility for rewriting demangle trees. (NFC) Transform() recursively transforms a demangle tree by doing a post-order traversal and replacing each node with fn(node). In most cases this utility will do less work than the ad-hoc implementation it is replacing because we now only recreate nodes that actually changed. --- .../Swift/TypeSystemSwiftTypeRef.cpp | 468 +++++++++--------- .../TypeSystem/Swift/TypeSystemSwiftTypeRef.h | 8 + 2 files changed, 241 insertions(+), 235 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index f3b78b65a6541..d6f678d764de5 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -180,149 +180,165 @@ ResolveTypeAlias(lldb_private::Module *M, swift::Demangle::Demangler &dem, return {n, {}}; } +swift::Demangle::NodePointer TypeSystemSwiftTypeRef::Transform( + swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node, + std::function + fn) { + if (!node) + return node; + using namespace swift::Demangle; + llvm::SmallVector children; + bool changed = false; + for (NodePointer child : *node) { + NodePointer transformed = Transform(dem, child, fn); + changed |= (child != transformed); + assert(transformed && "callback returned a nullptr"); + if (transformed) + children.push_back(transformed); + } + if (changed) { + // Create a new node with the transformed children. + auto kind = node->getKind(); + if (node->hasText()) + node = dem.createNodeWithAllocatedText(kind, node->getText()); + else if (node->hasIndex()) + node = dem.createNode(kind, node->getIndex()); + else + node = dem.createNode(kind); + for (NodePointer transformed_child : children) + node->addChild(transformed_child, dem); + } + return fn(node); +} + /// Iteratively resolve all type aliases in \p node by looking up their /// desugared types in the debug info of module \p M. static swift::Demangle::NodePointer GetCanonicalNode(lldb_private::Module *M, swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node) { - if (!node) - return node; using namespace swift::Demangle; - auto getCanonicalNode = [&](NodePointer node) -> NodePointer { - return GetCanonicalNode(M, dem, node); - }; - - NodePointer canonical = nullptr; - auto kind = node->getKind(); - switch (kind) { - case Node::Kind::SugaredOptional: - // FIXME: Factor these three cases out. - assert(node->getNumChildren() == 1); - if (node->getNumChildren() != 1) - return node; - - canonical = dem.createNode(Node::Kind::BoundGenericEnum); - { - NodePointer type = dem.createNode(Node::Kind::Type); - NodePointer e = dem.createNode(Node::Kind::Enum); - NodePointer module = dem.createNodeWithAllocatedText(Node::Kind::Module, - swift::STDLIB_NAME); - e->addChild(module, dem); - NodePointer optional = - dem.createNodeWithAllocatedText(Node::Kind::Identifier, "Optional"); - e->addChild(optional, dem); - type->addChild(e, dem); - canonical->addChild(type, dem); - } - { - NodePointer typelist = dem.createNode(Node::Kind::TypeList); - NodePointer type = dem.createNode(Node::Kind::Type); - type->addChild(getCanonicalNode(node->getFirstChild()), dem); - typelist->addChild(type, dem); - canonical->addChild(typelist, dem); - } - return canonical; - case Node::Kind::SugaredArray: { - assert(node->getNumChildren() == 1); - if (node->getNumChildren() != 1) - return node; - - canonical = dem.createNode(Node::Kind::BoundGenericStructure); - { - NodePointer type = dem.createNode(Node::Kind::Type); - NodePointer structure = dem.createNode(Node::Kind::Structure); - NodePointer module = dem.createNodeWithAllocatedText(Node::Kind::Module, - swift::STDLIB_NAME); - structure->addChild(module, dem); - NodePointer array = - dem.createNodeWithAllocatedText(Node::Kind::Identifier, "Array"); - structure->addChild(array, dem); - type->addChild(structure, dem); - canonical->addChild(type, dem); - } - { - NodePointer typelist = dem.createNode(Node::Kind::TypeList); - NodePointer type = dem.createNode(Node::Kind::Type); - type->addChild(getCanonicalNode(node->getFirstChild()), dem); - typelist->addChild(type, dem); - canonical->addChild(typelist, dem); - } - return canonical; - } - case Node::Kind::SugaredDictionary: - // FIXME: This isnt covered by any test. - assert(node->getNumChildren() == 2); - if (node->getNumChildren() != 2) - return node; + return TypeSystemSwiftTypeRef::Transform(dem, node, [&](NodePointer node) { + NodePointer canonical = nullptr; + auto kind = node->getKind(); + switch (kind) { + case Node::Kind::SugaredOptional: + // FIXME: Factor these three cases out. + assert(node->getNumChildren() == 1); + if (node->getNumChildren() != 1) + return node; - canonical = dem.createNode(Node::Kind::BoundGenericStructure); - { - NodePointer type = dem.createNode(Node::Kind::Type); - NodePointer structure = dem.createNode(Node::Kind::Structure); - NodePointer module = dem.createNodeWithAllocatedText(Node::Kind::Module, - swift::STDLIB_NAME); - structure->addChild(module, dem); - NodePointer dict = - dem.createNodeWithAllocatedText(Node::Kind::Identifier, "Dictionary"); - structure->addChild(dict, dem); - type->addChild(structure, dem); - canonical->addChild(type, dem); - } - { - NodePointer typelist = dem.createNode(Node::Kind::TypeList); + canonical = dem.createNode(Node::Kind::BoundGenericEnum); { NodePointer type = dem.createNode(Node::Kind::Type); - type->addChild(getCanonicalNode(node->getChild(0)), dem); + NodePointer e = dem.createNode(Node::Kind::Enum); + NodePointer module = dem.createNodeWithAllocatedText( + Node::Kind::Module, swift::STDLIB_NAME); + e->addChild(module, dem); + NodePointer optional = + dem.createNodeWithAllocatedText(Node::Kind::Identifier, "Optional"); + e->addChild(optional, dem); + type->addChild(e, dem); + canonical->addChild(type, dem); + } + { + NodePointer typelist = dem.createNode(Node::Kind::TypeList); + NodePointer type = dem.createNode(Node::Kind::Type); + type->addChild(node->getFirstChild(), dem); typelist->addChild(type, dem); + canonical->addChild(typelist, dem); + } + return canonical; + case Node::Kind::SugaredArray: { + assert(node->getNumChildren() == 1); + if (node->getNumChildren() != 1) + return node; + + canonical = dem.createNode(Node::Kind::BoundGenericStructure); + { + NodePointer type = dem.createNode(Node::Kind::Type); + NodePointer structure = dem.createNode(Node::Kind::Structure); + NodePointer module = dem.createNodeWithAllocatedText( + Node::Kind::Module, swift::STDLIB_NAME); + structure->addChild(module, dem); + NodePointer array = + dem.createNodeWithAllocatedText(Node::Kind::Identifier, "Array"); + structure->addChild(array, dem); + type->addChild(structure, dem); + canonical->addChild(type, dem); } { + NodePointer typelist = dem.createNode(Node::Kind::TypeList); NodePointer type = dem.createNode(Node::Kind::Type); - type->addChild(getCanonicalNode(node->getChild(1)), dem); + type->addChild(node->getFirstChild(), dem); typelist->addChild(type, dem); + canonical->addChild(typelist, dem); } - canonical->addChild(typelist, dem); + return canonical; } - return canonical; - case Node::Kind::SugaredParen: - assert(node->getNumChildren() == 1); - if (node->getNumChildren() != 1) + case Node::Kind::SugaredDictionary: + // FIXME: This isnt covered by any test. + assert(node->getNumChildren() == 2); + if (node->getNumChildren() != 2) + return node; + + canonical = dem.createNode(Node::Kind::BoundGenericStructure); + { + NodePointer type = dem.createNode(Node::Kind::Type); + NodePointer structure = dem.createNode(Node::Kind::Structure); + NodePointer module = dem.createNodeWithAllocatedText( + Node::Kind::Module, swift::STDLIB_NAME); + structure->addChild(module, dem); + NodePointer dict = dem.createNodeWithAllocatedText( + Node::Kind::Identifier, "Dictionary"); + structure->addChild(dict, dem); + type->addChild(structure, dem); + canonical->addChild(type, dem); + } + { + NodePointer typelist = dem.createNode(Node::Kind::TypeList); + { + NodePointer type = dem.createNode(Node::Kind::Type); + type->addChild(node->getChild(0), dem); + typelist->addChild(type, dem); + } + { + NodePointer type = dem.createNode(Node::Kind::Type); + type->addChild(node->getChild(1), dem); + typelist->addChild(type, dem); + } + canonical->addChild(typelist, dem); + } + return canonical; + case Node::Kind::SugaredParen: + assert(node->getNumChildren() == 1); + if (node->getNumChildren() != 1) + return node; + return node->getFirstChild(); + + case Node::Kind::BoundGenericTypeAlias: + case Node::Kind::TypeAlias: { + auto node_clangtype = ResolveTypeAlias(M, dem, node); + if (CompilerType clang_type = node_clangtype.second) + return GetClangTypeNode(clang_type, dem); + if (node_clangtype.first) + return node_clangtype.first; return node; - return getCanonicalNode(node->getFirstChild()); - - case Node::Kind::BoundGenericTypeAlias: - case Node::Kind::TypeAlias: { - auto node_clangtype = ResolveTypeAlias(M, dem, node); - if (CompilerType clang_type = node_clangtype.second) - return getCanonicalNode(GetClangTypeNode(clang_type, dem)); - if (node_clangtype.first) - return getCanonicalNode(node_clangtype.first); + } + case Node::Kind::DynamicSelf: { + // Substitute the static type for dynamic self. + assert(node->getNumChildren() == 1); + if (node->getNumChildren() != 1) + return node; + NodePointer type = node->getChild(0); + if (type->getKind() != Node::Kind::Type || type->getNumChildren() != 1) + return node; + return type->getChild(0); + } + default: + break; + } return node; - } - case Node::Kind::DynamicSelf: { - // Substitute the static type for dynamic self. - assert(node->getNumChildren() == 1); - if (node->getNumChildren() != 1) - return node; - NodePointer type = node->getChild(0); - if (type->getKind() != Node::Kind::Type || type->getNumChildren() != 1) - return node; - return getCanonicalNode(type->getChild(0)); - } - default: - break; - } - - // Recurse through all children. - // FIXME: don't create new nodes if children don't change! - if (node->hasText()) - canonical = dem.createNodeWithAllocatedText(kind, node->getText()); - else if (node->hasIndex()) - canonical = dem.createNode(kind, node->getIndex()); - else - canonical = dem.createNode(kind); - for (unsigned i = 0; i < node->getNumChildren(); ++i) - canonical->addChild(getCanonicalNode(node->getChild(i)), dem); - return canonical; + }); } /// Return the demangle tree representation of this type's canonical @@ -552,128 +568,110 @@ TypeSystemSwiftTypeRef::GetSwiftified(swift::Demangle::Demangler &dem, swift::Demangle::NodePointer TypeSystemSwiftTypeRef::GetNodeForPrintingImpl( swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node, bool resolve_objc_module, bool desugar) { - if (!node) - return node; using namespace swift::Demangle; - auto getNodeForPrinting = [&](NodePointer node) -> NodePointer { - return GetNodeForPrintingImpl(dem, node, resolve_objc_module, desugar); - }; + return Transform(dem, node, [&](NodePointer node) { + NodePointer canonical = node; + auto kind = node->getKind(); + switch (kind) { + case Node::Kind::Class: + case Node::Kind::Structure: + case Node::Kind::TypeAlias: + return GetSwiftified(dem, node, resolve_objc_module); - NodePointer canonical = nullptr; - auto kind = node->getKind(); - switch (kind) { - case Node::Kind::Class: - case Node::Kind::Structure: - case Node::Kind::TypeAlias: - return GetSwiftified(dem, node, resolve_objc_module); + // + // The remaining cases are all about bug-for-bug compatibility + // with the type dumper and we don't need to carry them forward + // necessarily. + // - // - // The remaining cases are all about bug-for-bug compatibility - // with the type dumper and we don't need to carry them forward - // necessarily. - // - - // The type dumper doesn't print these. + // The type dumper doesn't print these. #define REF_STORAGE(Name, ...) \ case Node::Kind::Name: \ - return (node->getNumChildren() == 1) \ - ? getNodeForPrinting(node->getChild(0)) \ - : node; + return (node->getNumChildren() == 1) ? node->getChild(0) : node; #include "swift/AST/ReferenceStorage.def" - case Node::Kind::ImplFunctionType: { - // Rewrite ImplFunctionType nodes as FunctionType nodes. - NodePointer fnty = dem.createNode(Node::Kind::FunctionType); - NodePointer args = dem.createNode(Node::Kind::ArgumentTuple); - NodePointer rett = dem.createNode(Node::Kind::ReturnType); - NodePointer args_ty = dem.createNode(Node::Kind::Type); - NodePointer args_tuple = dem.createNode(Node::Kind::Tuple); - for (NodePointer child : *node) { - if (child->getKind() == Node::Kind::ImplParameter) { - for (NodePointer type : *node) - if (type->getKind() == Node::Kind::Type && - type->getNumChildren() == 1) - rett->addChild(type->getChild(0), dem); - } else if (child->getKind() == Node::Kind::ImplResult) { - for (NodePointer type : *node) - if (type->getKind() == Node::Kind::Type) - rett->addChild(type, dem); + case Node::Kind::ImplFunctionType: { + // Rewrite ImplFunctionType nodes as FunctionType nodes. + NodePointer fnty = dem.createNode(Node::Kind::FunctionType); + NodePointer args = dem.createNode(Node::Kind::ArgumentTuple); + NodePointer rett = dem.createNode(Node::Kind::ReturnType); + NodePointer args_ty = dem.createNode(Node::Kind::Type); + NodePointer args_tuple = dem.createNode(Node::Kind::Tuple); + for (NodePointer child : *node) { + if (child->getKind() == Node::Kind::ImplParameter) { + for (NodePointer type : *node) + if (type->getKind() == Node::Kind::Type && + type->getNumChildren() == 1) + rett->addChild(type->getChild(0), dem); + } else if (child->getKind() == Node::Kind::ImplResult) { + for (NodePointer type : *node) + if (type->getKind() == Node::Kind::Type) + rett->addChild(type, dem); + } } + args_ty->addChild(args_tuple, dem); + args->addChild(args_ty, dem); + fnty->addChild(args, dem); + if (rett->getNumChildren() != 1) + rett->addChild(dem.createNode(Node::Kind::Tuple), dem); + fnty->addChild(rett, dem); + return fnty; } - args_ty->addChild(args_tuple, dem); - args->addChild(args_ty, dem); - fnty->addChild(args, dem); - if (rett->getNumChildren() != 1) - rett->addChild(dem.createNode(Node::Kind::Tuple), dem); - fnty->addChild(rett, dem); - return fnty; - } - case Node::Kind::SugaredOptional: - // This is particularly silly. The outermost sugared Optional is desugared. - // See SwiftASTContext::GetTypeName() and remove it there, too! - if (desugar && node->getNumChildren() == 1) { - desugar = false; - return Desugar(dem, node, Node::Kind::BoundGenericEnum, Node::Kind::Enum, - "Optional"); - } - return node; - case Node::Kind::SugaredArray: - // See comment on SugaredOptional. - if (desugar && node->getNumChildren() == 1) { - desugar = false; - return Desugar(dem, node, Node::Kind::BoundGenericStructure, - Node::Kind::Structure, "Array"); - } - return node; - case Node::Kind::SugaredDictionary: - // See comment on SugaredOptional. - if (desugar && node->getNumChildren() == 1) { - desugar = false; - return Desugar(dem, node, Node::Kind::BoundGenericStructure, - Node::Kind::Structure, "Dictionary"); + case Node::Kind::SugaredOptional: + // This is particularly silly. The outermost sugared Optional is + // desugared. See SwiftASTContext::GetTypeName() and remove it there, too! + if (desugar && node->getNumChildren() == 1) { + desugar = false; + return Desugar(dem, node, Node::Kind::BoundGenericEnum, + Node::Kind::Enum, "Optional"); + } + return node; + case Node::Kind::SugaredArray: + // See comment on SugaredOptional. + if (desugar && node->getNumChildren() == 1) { + desugar = false; + return Desugar(dem, node, Node::Kind::BoundGenericStructure, + Node::Kind::Structure, "Array"); + } + return node; + case Node::Kind::SugaredDictionary: + // See comment on SugaredOptional. + if (desugar && node->getNumChildren() == 1) { + desugar = false; + return Desugar(dem, node, Node::Kind::BoundGenericStructure, + Node::Kind::Structure, "Dictionary"); + } + return node; + case Node::Kind::DependentAssociatedTypeRef: + if (node->getNumChildren() == 2 && + node->getChild(0)->getKind() == Node::Kind::Identifier) + return node->getChild(0); + break; + default: + break; } - return node; - case Node::Kind::DependentAssociatedTypeRef: - if (node->getNumChildren() == 2 && - node->getChild(0)->getKind() == Node::Kind::Identifier) - return node->getChild(0); - break; - default: - break; - } - // Recurse through all children. - // FIXME: don't create new nodes if children don't change! - if (node->hasText()) - canonical = dem.createNodeWithAllocatedText(kind, node->getText()); - else if (node->hasIndex()) - canonical = dem.createNode(kind, node->getIndex()); - else - canonical = dem.createNode(kind); - - // Bug-for-bug compatibility. Remove this loop! - // Strip out LocalDeclNames. - for (unsigned i = 0; i < node->getNumChildren(); ++i) { - NodePointer child = node->getChild(i); - if (child->getKind() == Node::Kind::LocalDeclName) - for (NodePointer identifier : *child) - if (identifier->getKind() == Node::Kind::Identifier) { - NodePointer module = nullptr; - if (node->getChild(0)->getNumChildren() > 1) - module = node->getChild(0)->getChild(0); - if (module->getKind() != Node::Kind::Module) - break; - - canonical->addChild(module, dem); - canonical->addChild(identifier, dem); - return canonical; - } - } - - for (unsigned i = 0; i < node->getNumChildren(); ++i) - canonical->addChild(getNodeForPrinting(node->getChild(i)), dem); - return canonical; + // Bug-for-bug compatibility. Remove this loop! + // Strip out LocalDeclNames. + for (unsigned i = 0; i < node->getNumChildren(); ++i) { + NodePointer child = node->getChild(i); + if (child->getKind() == Node::Kind::LocalDeclName) + for (NodePointer identifier : *child) + if (identifier->getKind() == Node::Kind::Identifier) { + NodePointer module = nullptr; + if (node->getChild(0)->getNumChildren() > 1) + module = node->getChild(0)->getChild(0); + if (module->getKind() != Node::Kind::Module) + break; + + canonical->addChild(module, dem); + canonical->addChild(identifier, dem); + return canonical; + } + } + return canonical; + }); } /// Return the demangle tree representation with all "__C" module diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h index f10f51d8e2d53..a21cc276eb1c8 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h @@ -257,6 +257,14 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { bool print_help_if_available, bool print_extensions_if_available, lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) override; + /// Recursively transform the demangle tree starting a \p node by + /// doing a post-order traversal and replacing each node with + /// fn(node). + static swift::Demangle::NodePointer Transform( + swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node, + std::function + fn); + /// Return the canonicalized Demangle tree for a Swift mangled type name. static swift::Demangle::NodePointer GetCanonicalDemangleTree(lldb_private::Module *Module, From f6c3c453773e69e060e039fe170106ac8b13a261 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 9 Oct 2020 09:48:24 -0700 Subject: [PATCH 104/234] Remove the dynamic self replacement from canonicalization where it doesn't belong and move it directly into BindGenericTypeParameters, where it is the only desirable transformation and full canonicalization is actually counterproductive. A subsequent patch will enable the TypeRef typesystem in the expression evaluator. This is a prerequisite for that to work. --- .../TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp | 10 ---------- .../TypeSystem/Swift/TypeSystemSwiftTypeRef.h | 1 + ...wiftLanguageRuntimeDynamicTypeResolution.cpp | 17 ++++++++++++++--- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index d6f678d764de5..5f32c71f5723a 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -324,16 +324,6 @@ GetCanonicalNode(lldb_private::Module *M, swift::Demangle::Demangler &dem, return node_clangtype.first; return node; } - case Node::Kind::DynamicSelf: { - // Substitute the static type for dynamic self. - assert(node->getNumChildren() == 1); - if (node->getNumChildren() != 1) - return node; - NodePointer type = node->getChild(0); - if (type->getKind() != Node::Kind::Type || type->getNumChildren() != 1) - return node; - return type->getChild(0); - } default: break; } diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h index a21cc276eb1c8..2c96379bdea72 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h @@ -260,6 +260,7 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { /// Recursively transform the demangle tree starting a \p node by /// doing a post-order traversal and replacing each node with /// fn(node). + /// The NodePointer passed to \p fn is guaranteed to be non-null. static swift::Demangle::NodePointer Transform( swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node, std::function diff --git a/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp index 28b1a2437e4d4..27c008c86be7a 100644 --- a/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -1325,9 +1325,20 @@ SwiftLanguageRuntimeImpl::BindGenericTypeParameters(StackFrame &stack_frame, } swift::Demangle::Demangler dem; - swift::Demangle::NodePointer canonical = - TypeSystemSwiftTypeRef::GetCanonicalDemangleTree( - ts.GetModule(), dem, mangled_name.GetStringRef()); + swift::Demangle::NodePointer canonical = TypeSystemSwiftTypeRef::Transform( + dem, dem.demangleSymbol(mangled_name.GetStringRef()), + [](swift::Demangle::NodePointer node) { + if (node->getKind() != Node::Kind::DynamicSelf) + return node; + // Substitute the static type for dynamic self. + assert(node->getNumChildren() == 1); + if (node->getNumChildren() != 1) + return node; + NodePointer type = node->getChild(0); + if (type->getKind() != Node::Kind::Type || type->getNumChildren() != 1) + return node; + return type->getChild(0); + }); // Build the list of type substitutions. swift::reflection::GenericArgumentMap substitutions; From 19e31c53cab1f6b5d297f2ca253d005fc6454731 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Wed, 30 Sep 2020 22:42:17 -0700 Subject: [PATCH 105/234] DirectoryWatcher: add an implementation for Windows This implements the directory watcher on Windows. It does the most naive thing for simplicity. ReadDirectoryChangesW is used to monitor the changes. However, in order to support interruption, we must use overlapped IO, which allows us to use the blocking, synchronous mechanism. We create a thread to post the notification to the consumer to allow the monitoring to continue. The two threads communicate via a locked queue. Differential Revision: https://reviews.llvm.org/D88666 Reviewed By: Adrian McCarthy (cherry picked from commit 5d74c435117526616d2c2665f030263b8f60da1b) --- .../windows/DirectoryWatcher-windows.cpp | 278 ++++++++++++++++-- .../unittests/DirectoryWatcher/CMakeLists.txt | 2 +- 2 files changed, 260 insertions(+), 20 deletions(-) diff --git a/clang/lib/DirectoryWatcher/windows/DirectoryWatcher-windows.cpp b/clang/lib/DirectoryWatcher/windows/DirectoryWatcher-windows.cpp index 25cbcf536388a..8c2e64a87b79d 100644 --- a/clang/lib/DirectoryWatcher/windows/DirectoryWatcher-windows.cpp +++ b/clang/lib/DirectoryWatcher/windows/DirectoryWatcher-windows.cpp @@ -6,19 +6,12 @@ // //===----------------------------------------------------------------------===// -// TODO: This is not yet an implementation, but it will make it so Windows -// builds don't fail. - #include "DirectoryScanner.h" #include "clang/DirectoryWatcher/DirectoryWatcher.h" - #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/ScopeExit.h" -#include "llvm/Support/AlignOf.h" -#include "llvm/Support/Errno.h" -#include "llvm/Support/Mutex.h" +#include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Path.h" -#include +#include "llvm/Support/Windows/WindowsSupport.h" #include #include #include @@ -28,23 +21,270 @@ namespace { +using DirectoryWatcherCallback = + std::function, bool)>; + using namespace llvm; using namespace clang; class DirectoryWatcherWindows : public clang::DirectoryWatcher { + OVERLAPPED Overlapped; + + std::vector Notifications; + + std::thread WatcherThread; + std::thread HandlerThread; + std::function, bool)> Callback; + SmallString Path; + HANDLE Terminate; + + class EventQueue { + std::mutex M; + std::queue Q; + std::condition_variable CV; + + public: + void emplace(DirectoryWatcher::Event::EventKind Kind, StringRef Path) { + { + std::unique_lock L(M); + Q.emplace(Kind, Path); + } + CV.notify_one(); + } + + DirectoryWatcher::Event pop_front() { + std::unique_lock L(M); + while (true) { + if (!Q.empty()) { + DirectoryWatcher::Event E = Q.front(); + Q.pop(); + return E; + } + CV.wait(L, [this]() { return !Q.empty(); }); + } + } + } Q; + public: - ~DirectoryWatcherWindows() override { } - void InitialScan() { } - void EventReceivingLoop() { } - void StopWork() { } + DirectoryWatcherWindows(HANDLE DirectoryHandle, bool WaitForInitialSync, + DirectoryWatcherCallback Receiver); + + ~DirectoryWatcherWindows() override; + + void InitialScan(); + void WatcherThreadProc(HANDLE DirectoryHandle); + void NotifierThreadProc(bool WaitForInitialSync); }; + +DirectoryWatcherWindows::DirectoryWatcherWindows( + HANDLE DirectoryHandle, bool WaitForInitialSync, + DirectoryWatcherCallback Receiver) + : Callback(Receiver), Terminate(INVALID_HANDLE_VALUE) { + // Pre-compute the real location as we will be handing over the directory + // handle to the watcher and performing synchronous operations. + { + DWORD Length = GetFinalPathNameByHandleW(DirectoryHandle, NULL, 0, 0); + + std::vector Buffer; + Buffer.resize(Length); + + Length = GetFinalPathNameByHandleW(DirectoryHandle, Buffer.data(), + Buffer.size(), 0); + Buffer.resize(Length); + + llvm::sys::windows::UTF16ToUTF8(Buffer.data(), Buffer.size(), Path); + } + + Notifications.resize(4 * (sizeof(FILE_NOTIFY_INFORMATION) + + MAX_PATH * sizeof(WCHAR))); + + memset(&Overlapped, 0, sizeof(Overlapped)); + Overlapped.hEvent = + CreateEventW(NULL, /*bManualReset=*/TRUE, /*bInitialState=*/FALSE, NULL); + assert(Overlapped.hEvent && "unable to create event"); + + Terminate = CreateEventW(NULL, /*bManualReset=*/TRUE, + /*bInitialState=*/FALSE, NULL); + + WatcherThread = std::thread([this, DirectoryHandle]() { + this->WatcherThreadProc(DirectoryHandle); + }); + + if (WaitForInitialSync) + InitialScan(); + + HandlerThread = std::thread([this, WaitForInitialSync]() { + this->NotifierThreadProc(WaitForInitialSync); + }); +} + +DirectoryWatcherWindows::~DirectoryWatcherWindows() { + // Signal the Watcher to exit. + SetEvent(Terminate); + HandlerThread.join(); + WatcherThread.join(); + CloseHandle(Terminate); + CloseHandle(Overlapped.hEvent); +} + +void DirectoryWatcherWindows::InitialScan() { + Callback(getAsFileEvents(scanDirectory(Path.data())), /*IsInitial=*/true); +} + +void DirectoryWatcherWindows::WatcherThreadProc(HANDLE DirectoryHandle) { + while (true) { + // We do not guarantee subdirectories, but macOS already provides + // subdirectories, might as well as ... + BOOL WatchSubtree = TRUE; + DWORD NotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME + | FILE_NOTIFY_CHANGE_DIR_NAME + | FILE_NOTIFY_CHANGE_SIZE + | FILE_NOTIFY_CHANGE_LAST_ACCESS + | FILE_NOTIFY_CHANGE_LAST_WRITE + | FILE_NOTIFY_CHANGE_CREATION; + + DWORD BytesTransferred; + if (!ReadDirectoryChangesW(DirectoryHandle, Notifications.data(), + Notifications.size(), WatchSubtree, + NotifyFilter, &BytesTransferred, &Overlapped, + NULL)) { + Q.emplace(DirectoryWatcher::Event::EventKind::WatcherGotInvalidated, + ""); + break; + } + + HANDLE Handles[2] = { Terminate, Overlapped.hEvent }; + switch (WaitForMultipleObjects(2, Handles, FALSE, INFINITE)) { + case WAIT_OBJECT_0: // Terminate Request + case WAIT_FAILED: // Failure + Q.emplace(DirectoryWatcher::Event::EventKind::WatcherGotInvalidated, + ""); + (void)CloseHandle(DirectoryHandle); + return; + case WAIT_TIMEOUT: // Spurious wakeup? + continue; + case WAIT_OBJECT_0 + 1: // Directory change + break; + } + + if (!GetOverlappedResult(DirectoryHandle, &Overlapped, &BytesTransferred, + FALSE)) { + Q.emplace(DirectoryWatcher::Event::EventKind::WatchedDirRemoved, + ""); + Q.emplace(DirectoryWatcher::Event::EventKind::WatcherGotInvalidated, + ""); + break; + } + + // There was a buffer underrun on the kernel side. We may have lost + // events, please re-synchronize. + if (BytesTransferred == 0) { + Q.emplace(DirectoryWatcher::Event::EventKind::WatcherGotInvalidated, + ""); + break; + } + + for (FILE_NOTIFY_INFORMATION *I = + (FILE_NOTIFY_INFORMATION *)Notifications.data(); + I; + I = I->NextEntryOffset + ? (FILE_NOTIFY_INFORMATION *)((CHAR *)I + I->NextEntryOffset) + : NULL) { + DirectoryWatcher::Event::EventKind Kind = + DirectoryWatcher::Event::EventKind::WatcherGotInvalidated; + switch (I->Action) { + case FILE_ACTION_MODIFIED: + Kind = DirectoryWatcher::Event::EventKind::Modified; + break; + case FILE_ACTION_ADDED: + Kind = DirectoryWatcher::Event::EventKind::Modified; + break; + case FILE_ACTION_REMOVED: + Kind = DirectoryWatcher::Event::EventKind::Removed; + break; + case FILE_ACTION_RENAMED_OLD_NAME: + Kind = DirectoryWatcher::Event::EventKind::Removed; + break; + case FILE_ACTION_RENAMED_NEW_NAME: + Kind = DirectoryWatcher::Event::EventKind::Modified; + break; + } + + SmallString filename; + sys::windows::UTF16ToUTF8(I->FileName, I->FileNameLength / 2, + filename); + Q.emplace(Kind, filename); + } + } + + (void)CloseHandle(DirectoryHandle); +} + +void DirectoryWatcherWindows::NotifierThreadProc(bool WaitForInitialSync) { + // If we did not wait for the initial sync, then we should perform the + // scan when we enter the thread. + if (!WaitForInitialSync) + this->InitialScan(); + + while (true) { + DirectoryWatcher::Event E = Q.pop_front(); + Callback(E, /*IsInitial=*/false); + if (E.Kind == DirectoryWatcher::Event::EventKind::WatcherGotInvalidated) + break; + } +} + +auto error(DWORD ErrorCode) { + DWORD Flags = FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS; + + LPSTR Buffer; + if (!FormatMessageA(Flags, NULL, ErrorCode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&Buffer, + 0, NULL)) { + return make_error("error " + utostr(ErrorCode), + inconvertibleErrorCode()); + } + std::string Message{Buffer}; + LocalFree(Buffer); + return make_error(Message, inconvertibleErrorCode()); +} + } // namespace llvm::Expected> -clang::DirectoryWatcher::create( - StringRef Path, - std::function, bool)> Receiver, - bool WaitForInitialSync) { - return llvm::Expected>( - llvm::errorCodeToError(std::make_error_code(std::errc::not_supported))); +clang::DirectoryWatcher::create(StringRef Path, + DirectoryWatcherCallback Receiver, + bool WaitForInitialSync) { + if (Path.empty()) + llvm::report_fatal_error( + "DirectoryWatcher::create can not accept an empty Path."); + + if (!sys::fs::is_directory(Path)) + llvm::report_fatal_error( + "DirectoryWatcher::create can not accept a filepath."); + + SmallVector WidePath; + if (sys::windows::UTF8ToUTF16(Path, WidePath)) + return llvm::make_error( + "unable to convert path to UTF-16", llvm::inconvertibleErrorCode()); + + DWORD DesiredAccess = FILE_LIST_DIRECTORY; + DWORD ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + DWORD CreationDisposition = OPEN_EXISTING; + DWORD FlagsAndAttributes = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED; + + HANDLE DirectoryHandle = + CreateFileW(WidePath.data(), DesiredAccess, ShareMode, + /*lpSecurityAttributes=*/NULL, CreationDisposition, + FlagsAndAttributes, NULL); + if (DirectoryHandle == INVALID_HANDLE_VALUE) + return error(GetLastError()); + + // NOTE: We use the watcher instance as a RAII object to discard the handles + // for the directory and the IOCP in case of an error. Hence, this is early + // allocated, with the state being written directly to the watcher. + return std::make_unique( + DirectoryHandle, WaitForInitialSync, Receiver); } diff --git a/clang/unittests/DirectoryWatcher/CMakeLists.txt b/clang/unittests/DirectoryWatcher/CMakeLists.txt index 0355525a86b0a..84a1a9d40c250 100644 --- a/clang/unittests/DirectoryWatcher/CMakeLists.txt +++ b/clang/unittests/DirectoryWatcher/CMakeLists.txt @@ -1,4 +1,4 @@ -if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Linux") +if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME STREQUAL Windows) set(LLVM_LINK_COMPONENTS Support From dbef9ec2ea9f41bd4455032a4057e2ab61759d26 Mon Sep 17 00:00:00 2001 From: Brent Royal-Gordon Date: Sat, 10 Oct 2020 22:43:05 -0700 Subject: [PATCH 106/234] [lldb] Update to match apple/swift#33935 --- .../Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp | 3 ++- lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp index 96f3832b63849..a9c0538ece804 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp @@ -1189,7 +1189,8 @@ static llvm::Expected ParseAndImport( swift::ImplicitImportInfo importInfo; importInfo.StdlibKind = swift::ImplicitStdlibKind::Stdlib; for (auto *module : additional_imports) - importInfo.AdditionalModules.emplace_back(module, /*exported*/ false); + importInfo.AdditionalImports.emplace_back(swift::ImportedModule(module), + swift::ImportOptions()); auto module_id = ast_context->getIdentifier(expr_name_buf); auto &module = *swift::ModuleDecl::create(module_id, *ast_context, diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index c3806608723ad..f700462ab26c4 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -8314,7 +8314,7 @@ bool SwiftASTContext::CacheUserImports(SwiftASTContext &swift_ast_context, swift::SourceFile &source_file, Status &error) { llvm::SmallString<1> m_description; - llvm::SmallVector parsed_imports; + llvm::SmallVector parsed_imports; swift::ModuleDecl::ImportFilter import_filter { swift::ModuleDecl::ImportFilterKind::Exported, From d85505d791b7e23c1216ef7be9d8e7b5a849ee28 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 3 Sep 2020 09:17:03 +0200 Subject: [PATCH 107/234] [debugserver] Fix that debugserver's stop reply packets always return signal code 0 If our process terminates due to an unhandled signal, we are supposed to get the signal code via WTERMSIG. However, we instead try to get the exit status via WEXITSTATUS which just ends up always calculating signal code 0 (at least on the macOS implementation where it just shifts the signal code bits away and we're left with only 0 bits). The exit status calculation on the LLDB side also seems a bit off as it claims an exit status that is just the signal code (instead of for example 128 + signal code), but that will be another patch. Reviewed By: jasonmolenda Differential Revision: https://reviews.llvm.org/D86336 (cherry picked from commit f0699d9109143754088c26604c58f5ab3e9d4678) --- lldb/test/Shell/Process/Inputs/abort.c | 3 +++ lldb/test/Shell/Process/TestAbortExitCode.test | 6 ++++++ lldb/tools/debugserver/source/RNBRemote.cpp | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 lldb/test/Shell/Process/Inputs/abort.c create mode 100644 lldb/test/Shell/Process/TestAbortExitCode.test diff --git a/lldb/test/Shell/Process/Inputs/abort.c b/lldb/test/Shell/Process/Inputs/abort.c new file mode 100644 index 0000000000000..9edc9336dc3e0 --- /dev/null +++ b/lldb/test/Shell/Process/Inputs/abort.c @@ -0,0 +1,3 @@ +#include + +int main(int argc, char **argv) { abort(); } diff --git a/lldb/test/Shell/Process/TestAbortExitCode.test b/lldb/test/Shell/Process/TestAbortExitCode.test new file mode 100644 index 0000000000000..a61c095051124 --- /dev/null +++ b/lldb/test/Shell/Process/TestAbortExitCode.test @@ -0,0 +1,6 @@ +UNSUPPORTED: system-windows + +RUN: %clang_host %p/Inputs/abort.c -o %t +RUN: %lldb %t -o run -o continue | FileCheck %s + +CHECK: status = 6 (0x00000006) Terminated due to signal 6 diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp index 5e2512731f39c..b66cc8f583e8e 100644 --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -3066,7 +3066,7 @@ rnb_err_t RNBRemote::HandlePacket_last_signal(const char *unused) { WEXITSTATUS(pid_status)); else if (WIFSIGNALED(pid_status)) snprintf(pid_exited_packet, sizeof(pid_exited_packet), "X%02x", - WEXITSTATUS(pid_status)); + WTERMSIG(pid_status)); else if (WIFSTOPPED(pid_status)) snprintf(pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG(pid_status)); From a9014a9950209b8ca1aadb2c091eb2267d8ee199 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 3 Sep 2020 09:54:37 +0200 Subject: [PATCH 108/234] [lldb] Remove debugserver specific string from TestAbortExitCode check The test only checks the exit code that the debug server sends back, but not the following explanation which is different for debugserver and lldb-server. (cherry picked from commit e123959e94716ef6b5942060ac5934f696eaa3d3) --- lldb/test/Shell/Process/TestAbortExitCode.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/test/Shell/Process/TestAbortExitCode.test b/lldb/test/Shell/Process/TestAbortExitCode.test index a61c095051124..5be0a15ab1728 100644 --- a/lldb/test/Shell/Process/TestAbortExitCode.test +++ b/lldb/test/Shell/Process/TestAbortExitCode.test @@ -3,4 +3,4 @@ UNSUPPORTED: system-windows RUN: %clang_host %p/Inputs/abort.c -o %t RUN: %lldb %t -o run -o continue | FileCheck %s -CHECK: status = 6 (0x00000006) Terminated due to signal 6 +CHECK: status = 6 (0x00000006) From c24d7bfb8a119076c00d2ece3136e76d2c29c34c Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Fri, 9 Oct 2020 13:57:51 +0200 Subject: [PATCH 109/234] [lldb] Fix that C++ base name is only calculated when Swift plugin is enabled In 41c6ab25afbb6dda179c8d995f1935aa60b9b64b I put the C++ GetBasename() call in Module::LookupInfo behind the LLDB_ENABLE_SWIFT as it appeard to be introduced by a downstream Swift change. However our downstream change actually changed ``` basename = cpp_method.GetBasename(); ``` into ``` if (swift) /*swift stuff*/ else if (c++) basename = cpp_method.GetBasename(); ``` By putting both if and the else behind LLDB_ENABLE_SWIFT this actually broke LLDB's ability to set C++ breakpoints by function name when LLDB_ENABLE_SWIFT wasn't set (which in turn broke the TestCPPBreakpointLocations test). This patch moves `#ifdef LLDB_ENABLE_SWIFT` only around the Swift-specific part and leaves the basename calculation enabled independently of Swift. I also removed the unnecessary `else` as we can't have a method that has both a language value of Swift and C++, so those branches are anyway mutually exlusive and comparing the `language` enum value is cheap. --- lldb/source/Core/Module.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index e6be40a212fe7..fc8ab253bf98b 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -681,13 +681,11 @@ Module::LookupInfo::LookupInfo(ConstString name, language == eLanguageTypeSwift) && swift_method.IsValid()) basename = swift_method.GetBasename(); - else if ((language == eLanguageTypeUnknown || - Language::LanguageIsCPlusPlus(language) || - Language::LanguageIsC(language) || - language == eLanguageTypeObjC_plus_plus) && - cpp_method.IsValid()) - basename = cpp_method.GetBasename(); #endif // LLDB_ENABLE_SWIFT + if ((language == eLanguageTypeUnknown || + Language::LanguageIsCFamily(language)) && + cpp_method.IsValid()) + basename = cpp_method.GetBasename(); if (basename.empty()) { if (CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context, From fa17d1296f471f742552fce54006c2457a178df4 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Mon, 17 Aug 2020 10:56:02 +0200 Subject: [PATCH 110/234] [lldb] Add SBModule::GarbageCollectAllocatedModules and clear modules after each test run Right now the only places in the SB API where lldb:: ModuleSP instances are destroyed are in SBDebugger::MemoryPressureDetected (where it's just attempted but not guaranteed) and in SBDebugger::DeleteTarget (which will be removed in D83933). Tests that directly create an lldb::ModuleSP and never create a target therefore currently leak lldb::Module instances. This triggers the sanity checks in lldbtest that make sure that the global module list is empty after a test. This patch adds SBModule::GarbageCollectAllocatedModules as an explicit way to clean orphaned lldb::ModuleSP instances. Also we now start calling this method at the end of each test run and move the sanity check behind that call to make this work. This way even tests that don't create targets can pass the sanity check. This fixes TestUnicodeSymbols.py when D83865 is applied (which makes that the sanity checks actually fail the test). Reviewed By: JDevlieghere Differential Revision: https://reviews.llvm.org/D83876 (cherry picked from commit c2f9454a16e45e1df09d8ebed6dadbc0da264442) --- lldb/bindings/interface/SBModule.i | 11 +++++++++++ lldb/include/lldb/API/SBModule.h | 3 +++ lldb/packages/Python/lldbsuite/test/lldbtest.py | 17 ++++++++++++----- lldb/source/API/SBModule.cpp | 7 +++++++ 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/lldb/bindings/interface/SBModule.i b/lldb/bindings/interface/SBModule.i index e902af0c49ce9..d64391a40d7c4 100644 --- a/lldb/bindings/interface/SBModule.i +++ b/lldb/bindings/interface/SBModule.i @@ -353,6 +353,17 @@ public: static uint32_t GetNumberAllocatedModules(); + %feature("docstring", " + Removes all modules which are no longer needed by any part of LLDB from + the module cache. + + This is an implementation detail exposed for testing and should not be + relied upon. Use SBDebugger::MemoryPressureDetected instead to reduce + LLDB's memory consumption during execution. + ") GarbageCollectAllocatedModules; + static void + GarbageCollectAllocatedModules(); + STRING_EXTENSION(SBModule) #ifdef SWIGPYTHON diff --git a/lldb/include/lldb/API/SBModule.h b/lldb/include/lldb/API/SBModule.h index 859eaffe89a02..ec6e7c21b058d 100644 --- a/lldb/include/lldb/API/SBModule.h +++ b/lldb/include/lldb/API/SBModule.h @@ -291,6 +291,9 @@ class LLDB_API SBModule { /// Get the number of global modules. static uint32_t GetNumberAllocatedModules(); + /// Remove any global modules which are no longer needed. + static void GarbageCollectAllocatedModules(); + private: friend class SBAddress; friend class SBFrame; diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py index fb141616ef6e5..2530967f465c0 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -1029,6 +1029,17 @@ def tearDown(self): lldb.SBDebugger.Destroy(self.dbg) del self.dbg + # All modules should be orphaned now so that they can be cleared from + # the shared module cache. + lldb.SBModule.GarbageCollectAllocatedModules() + + # Modules are not orphaned during reproducer replay because they're + # leaked on purpose. + if not configuration.is_reproducer(): + # Assert that the global module cache is empty. + self.assertEqual(lldb.SBModule.GetNumberAllocatedModules(), 0) + + # ========================================================= # Various callbacks to allow introspection of test progress # ========================================================= @@ -1984,13 +1995,9 @@ def tearDown(self): for target in targets: self.dbg.DeleteTarget(target) - # Modules are not orphaned during reproducer replay because they're - # leaked on purpose. if not configuration.is_reproducer(): # Assert that all targets are deleted. - assert self.dbg.GetNumTargets() == 0 - # Assert that the global module cache is empty. - assert lldb.SBModule.GetNumberAllocatedModules() == 0 + self.assertEqual(self.dbg.GetNumTargets(), 0) # Do this last, to make sure it's in reverse order from how we setup. Base.tearDown(self) diff --git a/lldb/source/API/SBModule.cpp b/lldb/source/API/SBModule.cpp index c30529b37eb1e..883319b8078c8 100644 --- a/lldb/source/API/SBModule.cpp +++ b/lldb/source/API/SBModule.cpp @@ -690,6 +690,13 @@ uint32_t SBModule::GetNumberAllocatedModules() { return Module::GetNumberAllocatedModules(); } +void SBModule::GarbageCollectAllocatedModules() { + LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBModule, + GarbageCollectAllocatedModules); + const bool mandatory = false; + ModuleList::RemoveOrphanSharedModules(mandatory); +} + namespace lldb_private { namespace repro { From f02195fd0b8138f6a434f21751a7aa923e64229c Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Mon, 12 Oct 2020 15:22:53 -0700 Subject: [PATCH 111/234] [lldb] Alphabetically sort test categories (NFC) (cherry picked from commit e465ddac880228b879b5a6549adbb9c8a7f335bf) --- .../Python/lldbsuite/test/test_categories.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/test_categories.py b/lldb/packages/Python/lldbsuite/test/test_categories.py index 177c50ee17cfa..dcfef5be04acf 100644 --- a/lldb/packages/Python/lldbsuite/test/test_categories.py +++ b/lldb/packages/Python/lldbsuite/test/test_categories.py @@ -19,26 +19,26 @@ ] all_categories = { + 'basic_process': 'Basic process execution sniff tests.', + 'cmdline': 'Tests related to the LLDB command-line interface', + 'darwin-log': 'Darwin log tests', 'dataformatters': 'Tests related to the type command and the data formatters subsystem', + 'dsym': 'Tests that can be run with DSYM debug information', 'dwarf': 'Tests that can be run with DWARF debug information', 'dwo': 'Tests that can be run with DWO debug information', - 'dsym': 'Tests that can be run with DSYM debug information', - 'gmodules': 'Tests that can be run with -gmodules debug information', + 'dyntype': 'Tests related to dynamic type support', 'expression': 'Tests related to the expression parser', + 'flakey': 'Flakey test cases, i.e. tests that do not reliably pass at each execution', + 'gmodules': 'Tests that can be run with -gmodules debug information', 'libc++': 'Test for libc++ data formatters', 'libstdcxx': 'Test for libstdcxx data formatters', + 'lldb-server': 'Tests related to lldb-server', + 'lldb-vscode': 'Visual Studio Code debug adaptor tests', 'objc': 'Tests related to the Objective-C programming language support', 'pyapi': 'Tests related to the Python API', - 'basic_process': 'Basic process execution sniff tests.', - 'cmdline': 'Tests related to the LLDB command-line interface', - 'dyntype': 'Tests related to dynamic type support', - 'stresstest': 'Tests related to stressing lldb limits', - 'flakey': 'Flakey test cases, i.e. tests that do not reliably pass at each execution', - 'darwin-log': 'Darwin log tests', 'std-module': 'Tests related to importing the std module', + 'stresstest': 'Tests related to stressing lldb limits', 'watchpoint': 'Watchpoint-related tests', - 'lldb-vscode': 'Visual Studio Code debug adaptor tests', - 'lldb-server': 'Tests related to lldb-server', } From 673573516d7243dffcf10a897b89bcff5f37b283 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Mon, 12 Oct 2020 15:27:37 -0700 Subject: [PATCH 112/234] [lldb] Add instrumentation runtime category (cherry picked from commit 360ab009e2b95629388cef132ebe639c120ed35e) --- lldb/packages/Python/lldbsuite/test/test_categories.py | 1 + lldb/test/API/functionalities/asan/.categories | 1 + lldb/test/API/functionalities/mtc/.categories | 1 + lldb/test/API/functionalities/tsan/.categories | 1 + lldb/test/API/functionalities/ubsan/.categories | 1 + 5 files changed, 5 insertions(+) create mode 100644 lldb/test/API/functionalities/asan/.categories create mode 100644 lldb/test/API/functionalities/mtc/.categories create mode 100644 lldb/test/API/functionalities/tsan/.categories create mode 100644 lldb/test/API/functionalities/ubsan/.categories diff --git a/lldb/packages/Python/lldbsuite/test/test_categories.py b/lldb/packages/Python/lldbsuite/test/test_categories.py index dcfef5be04acf..699fcf4cb8870 100644 --- a/lldb/packages/Python/lldbsuite/test/test_categories.py +++ b/lldb/packages/Python/lldbsuite/test/test_categories.py @@ -30,6 +30,7 @@ 'expression': 'Tests related to the expression parser', 'flakey': 'Flakey test cases, i.e. tests that do not reliably pass at each execution', 'gmodules': 'Tests that can be run with -gmodules debug information', + 'instrumentation-runtime': 'Tests for the instrumentation runtime plugins', 'libc++': 'Test for libc++ data formatters', 'libstdcxx': 'Test for libstdcxx data formatters', 'lldb-server': 'Tests related to lldb-server', diff --git a/lldb/test/API/functionalities/asan/.categories b/lldb/test/API/functionalities/asan/.categories new file mode 100644 index 0000000000000..c756cb1241945 --- /dev/null +++ b/lldb/test/API/functionalities/asan/.categories @@ -0,0 +1 @@ +instrumentation-runtime diff --git a/lldb/test/API/functionalities/mtc/.categories b/lldb/test/API/functionalities/mtc/.categories new file mode 100644 index 0000000000000..c756cb1241945 --- /dev/null +++ b/lldb/test/API/functionalities/mtc/.categories @@ -0,0 +1 @@ +instrumentation-runtime diff --git a/lldb/test/API/functionalities/tsan/.categories b/lldb/test/API/functionalities/tsan/.categories new file mode 100644 index 0000000000000..c756cb1241945 --- /dev/null +++ b/lldb/test/API/functionalities/tsan/.categories @@ -0,0 +1 @@ +instrumentation-runtime diff --git a/lldb/test/API/functionalities/ubsan/.categories b/lldb/test/API/functionalities/ubsan/.categories new file mode 100644 index 0000000000000..c756cb1241945 --- /dev/null +++ b/lldb/test/API/functionalities/ubsan/.categories @@ -0,0 +1 @@ +instrumentation-runtime From e5e1ec7ed01b4d6086e9e236ea69d627b08631c4 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Mon, 12 Oct 2020 14:48:52 -0700 Subject: [PATCH 113/234] [lldb] Handle alternative output in TestAbortExitCode This test On macOS, this test can instead return `status = 0 (0x00000000) Terminated due to signal 6`. This updates the `CHECK` accordingly. Differential Revision: https://reviews.llvm.org/D89273 (cherry picked from commit a52cc9b4be362b12ca261000b723374d4b772a45) --- lldb/test/Shell/Process/TestAbortExitCode.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/test/Shell/Process/TestAbortExitCode.test b/lldb/test/Shell/Process/TestAbortExitCode.test index 5be0a15ab1728..746bc915897ec 100644 --- a/lldb/test/Shell/Process/TestAbortExitCode.test +++ b/lldb/test/Shell/Process/TestAbortExitCode.test @@ -3,4 +3,4 @@ UNSUPPORTED: system-windows RUN: %clang_host %p/Inputs/abort.c -o %t RUN: %lldb %t -o run -o continue | FileCheck %s -CHECK: status = 6 (0x00000006) +CHECK: {{status = 6 \(0x00000006\)|status = 0 \(0x00000000\) Terminated due to signal 6}} From 4782156227ab12d1e76db3febce9fec896e9de69 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Mon, 12 Oct 2020 16:48:20 -0700 Subject: [PATCH 114/234] [llvm] Export LLVM_USE_SPLIT_DWARF in LLVMConfig.cmake Export LLVM_USE_SPLIT_DWARF in LLVMConfig.cmake so that it can be used from standalone builds of clang and lldb. Currently, there is no way for standalone builds to know whether this option was set which means that it only applies to LLVM. Differential revision: https://reviews.llvm.org/D89282 (cherry picked from commit 7f8dc347c9552f339b4410b679d91bceb2cc456e) --- llvm/cmake/modules/LLVMConfig.cmake.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/cmake/modules/LLVMConfig.cmake.in b/llvm/cmake/modules/LLVMConfig.cmake.in index 4d8e33711d27b..aab5cf555da1b 100644 --- a/llvm/cmake/modules/LLVMConfig.cmake.in +++ b/llvm/cmake/modules/LLVMConfig.cmake.in @@ -16,6 +16,8 @@ set(LLVM_USE_CRT_MINSIZEREL @LLVM_USE_CRT_MINSIZEREL@) set(LLVM_USE_CRT_RELEASE @LLVM_USE_CRT_RELEASE@) set(LLVM_USE_CRT_RELWITHDEBINFO @LLVM_USE_CRT_RELWITHDEBINFO@) +set(LLVM_USE_SPLIT_DWARF @LLVM_USE_SPLIT_DWARF@) + set(LLVM_COMMON_DEPENDS @LLVM_COMMON_DEPENDS@) set(LLVM_AVAILABLE_LIBS @LLVM_AVAILABLE_LIBS@) From 86d12608bee69c58f2268dbe810f924e0352ef7f Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Tue, 13 Oct 2020 08:55:57 -0700 Subject: [PATCH 115/234] [repl_swift] Delete codesigning override This might be causing codesigning to occur multiple times during a fat package build. rdar://70237254 --- lldb/tools/repl/swift/CMakeLists.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lldb/tools/repl/swift/CMakeLists.txt b/lldb/tools/repl/swift/CMakeLists.txt index 16dd41c928c76..10ac8b686f014 100644 --- a/lldb/tools/repl/swift/CMakeLists.txt +++ b/lldb/tools/repl/swift/CMakeLists.txt @@ -1,10 +1,3 @@ -# Only set LLVM_CODESIGNING_IDENTITY for building on Apple hosts for Apple -# targets -if (CMAKE_HOST_APPLE AND APPLE) - # Override locally, so the repl is ad-hoc signed. - set(LLVM_CODESIGNING_IDENTITY "-") -endif() - # Requires system-provided Swift libs. set(CMAKE_OSX_DEPLOYMENT_TARGET 10.14.4) From 59ea711a607d1893c6f16f8f02b4b851b98f7716 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Tue, 13 Oct 2020 09:29:53 -0700 Subject: [PATCH 116/234] TypeSystem: silence a number of uncovered switch warnings This silences a number of uncovered switch warnings from MSVC when building lldb. --- .../TypeSystem/Swift/SwiftASTContext.cpp | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index f700462ab26c4..0816e12d0ce50 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -4425,6 +4425,9 @@ static SwiftASTContext::TypeOrDecl DeclToTypeOrDecl(swift::ASTContext *ast, case swift::DeclKind::Accessor: case swift::DeclKind::PoundDiagnostic: break; + + default: + break; } } return CompilerType(); @@ -5561,6 +5564,9 @@ SwiftASTContext::GetTypeInfo(opaque_compiler_type_t type, case swift::TypeKind::SILToken: break; + + default: + break; } return swift_flags; } @@ -5658,6 +5664,9 @@ lldb::TypeClass SwiftASTContext::GetTypeClass(opaque_compiler_type_t type) { case swift::TypeKind::SILToken: break; + + default: + break; } return lldb::eTypeClassOther; @@ -6164,6 +6173,9 @@ lldb::Encoding SwiftASTContext::GetEncoding(opaque_compiler_type_t type, case swift::TypeKind::SILToken: break; + + default: + break; } count = 0; return lldb::eEncodingInvalid; @@ -6250,6 +6262,9 @@ lldb::Format SwiftASTContext::GetFormat(opaque_compiler_type_t type) { case swift::TypeKind::SILToken: break; + + default: + break; } // We don't know hot to display this type. return lldb::eFormatBytes; @@ -6362,6 +6377,9 @@ uint32_t SwiftASTContext::GetNumChildren(opaque_compiler_type_t type, case swift::TypeKind::SILToken: break; + + default: + break; } return num_children; @@ -6477,6 +6495,9 @@ uint32_t SwiftASTContext::GetNumFields(opaque_compiler_type_t type) { case swift::TypeKind::SILToken: break; + + default: + break; } return count; @@ -6762,6 +6783,9 @@ CompilerType SwiftASTContext::GetFieldAtIndex(opaque_compiler_type_t type, case swift::TypeKind::SILToken: break; + + default: + break; } return CompilerType(); @@ -6838,6 +6862,9 @@ uint32_t SwiftASTContext::GetNumPointeeChildren(opaque_compiler_type_t type) { case swift::TypeKind::SILToken: break; + + default: + break; } return 0; @@ -7201,6 +7228,9 @@ CompilerType SwiftASTContext::GetChildCompilerTypeAtIndex( case swift::TypeKind::SILToken: break; + + default: + break; } return CompilerType(); } @@ -7417,6 +7447,9 @@ size_t SwiftASTContext::GetIndexOfChildMemberWithName( case swift::TypeKind::SILToken: break; + + default: + break; } } return 0; @@ -7801,6 +7834,9 @@ bool SwiftASTContext::DumpTypeValue( case swift::TypeKind::SILToken: break; + + default: + break; } return 0; From ec01dd968514785735e3de48e5e320eab2853071 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Tue, 13 Oct 2020 12:52:38 -0700 Subject: [PATCH 117/234] [repl_swift] Delete unused Xcode project --- .../repl_swift.xcodeproj/project.pbxproj | 357 ------------------ .../contents.xcworkspacedata | 7 - 2 files changed, 364 deletions(-) delete mode 100644 lldb/tools/repl/swift/repl_swift.xcodeproj/project.pbxproj delete mode 100644 lldb/tools/repl/swift/repl_swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/lldb/tools/repl/swift/repl_swift.xcodeproj/project.pbxproj b/lldb/tools/repl/swift/repl_swift.xcodeproj/project.pbxproj deleted file mode 100644 index 2282c933559bc..0000000000000 --- a/lldb/tools/repl/swift/repl_swift.xcodeproj/project.pbxproj +++ /dev/null @@ -1,357 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 942829751A8975A600521B30 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 942829741A8975A600521B30 /* main.swift */; }; - 9428297D1A8975CC00521B30 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9428297C1A8975CC00521B30 /* Foundation.framework */; }; - 942829871A8975E400521B30 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 942829741A8975A600521B30 /* main.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 942829621A89754E00521B30 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; - }; - 942829781A8975CC00521B30 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 942829641A89754E00521B30 /* repl_swift */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = repl_swift; sourceTree = BUILT_PRODUCTS_DIR; }; - 942829741A8975A600521B30 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = SOURCE_ROOT; }; - 9428297A1A8975CC00521B30 /* repl_swift_ios */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = repl_swift_ios; sourceTree = BUILT_PRODUCTS_DIR; }; - 9428297C1A8975CC00521B30 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 942829611A89754E00521B30 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 942829771A8975CC00521B30 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 9428297D1A8975CC00521B30 /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 9428295B1A89754E00521B30 = { - isa = PBXGroup; - children = ( - 942829661A89754E00521B30 /* repl_swift */, - 9428297B1A8975CC00521B30 /* Frameworks */, - 942829651A89754E00521B30 /* Products */, - ); - sourceTree = ""; - }; - 942829651A89754E00521B30 /* Products */ = { - isa = PBXGroup; - children = ( - 942829641A89754E00521B30 /* repl_swift */, - 9428297A1A8975CC00521B30 /* repl_swift_ios */, - ); - name = Products; - sourceTree = ""; - }; - 942829661A89754E00521B30 /* repl_swift */ = { - isa = PBXGroup; - children = ( - 942829741A8975A600521B30 /* main.swift */, - ); - path = repl_swift; - sourceTree = ""; - }; - 9428297B1A8975CC00521B30 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 9428297C1A8975CC00521B30 /* Foundation.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 942829631A89754E00521B30 /* repl_swift */ = { - isa = PBXNativeTarget; - buildConfigurationList = 9428296B1A89754E00521B30 /* Build configuration list for PBXNativeTarget "repl_swift" */; - buildPhases = ( - 942829601A89754E00521B30 /* Sources */, - 942829611A89754E00521B30 /* Frameworks */, - 942829621A89754E00521B30 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = repl_swift; - productName = repl_swift; - productReference = 942829641A89754E00521B30 /* repl_swift */; - productType = "com.apple.product-type.tool"; - }; - 942829791A8975CC00521B30 /* repl_swift_ios */ = { - isa = PBXNativeTarget; - buildConfigurationList = 942829831A8975CC00521B30 /* Build configuration list for PBXNativeTarget "repl_swift_ios" */; - buildPhases = ( - 942829B81A897ABB00521B30 /* ShellScript */, - 942829761A8975CC00521B30 /* Sources */, - 942829771A8975CC00521B30 /* Frameworks */, - 942829781A8975CC00521B30 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = repl_swift_ios; - productName = repl_swift_ios; - productReference = 9428297A1A8975CC00521B30 /* repl_swift_ios */; - productType = "com.apple.product-type.tool"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 9428295C1A89754E00521B30 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0700; - ORGANIZATIONNAME = lldb; - TargetAttributes = { - 942829631A89754E00521B30 = { - CreatedOnToolsVersion = 7.0; - }; - 942829791A8975CC00521B30 = { - CreatedOnToolsVersion = 7.0; - }; - }; - }; - buildConfigurationList = 9428295F1A89754E00521B30 /* Build configuration list for PBXProject "repl_swift" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 9428295B1A89754E00521B30; - productRefGroup = 942829651A89754E00521B30 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 942829631A89754E00521B30 /* repl_swift */, - 942829791A8975CC00521B30 /* repl_swift_ios */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXShellScriptBuildPhase section */ - 942829B81A897ABB00521B30 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = ""; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 942829601A89754E00521B30 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 942829751A8975A600521B30 /* main.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 942829761A8975CC00521B30 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 942829871A8975E400521B30 /* main.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 942829691A89754E00521B30 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.10; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 9428296A1A89754E00521B30 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.10; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - }; - name = Release; - }; - 9428296C1A89754E00521B30 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - COPY_PHASE_STRIP = YES; - LD_RUNPATH_SEARCH_PATHS = "@executable_path/../../../../../../usr/lib/swift/macosx"; - MACOSX_DEPLOYMENT_TARGET = 10.9; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 9428296D1A89754E00521B30 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - COPY_PHASE_STRIP = YES; - LD_RUNPATH_SEARCH_PATHS = "@executable_path/../../../../../../usr/lib/swift/macosx"; - MACOSX_DEPLOYMENT_TARGET = 10.9; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; - 942829841A8975CC00521B30 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - IPHONEOS_DEPLOYMENT_TARGET = 8.3; - LD_RUNPATH_SEARCH_PATHS = "@executable_path/../../../../../../usr/lib/swift/iphonesimulator"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos.internal; - }; - name = Debug; - }; - 942829851A8975CC00521B30 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - IPHONEOS_DEPLOYMENT_TARGET = 8.3; - LD_RUNPATH_SEARCH_PATHS = "@executable_path/../../../../../../usr/lib/swift/iphonesimulator"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos.internal; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 9428295F1A89754E00521B30 /* Build configuration list for PBXProject "repl_swift" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 942829691A89754E00521B30 /* Debug */, - 9428296A1A89754E00521B30 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 9428296B1A89754E00521B30 /* Build configuration list for PBXNativeTarget "repl_swift" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 9428296C1A89754E00521B30 /* Debug */, - 9428296D1A89754E00521B30 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 942829831A8975CC00521B30 /* Build configuration list for PBXNativeTarget "repl_swift_ios" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 942829841A8975CC00521B30 /* Debug */, - 942829851A8975CC00521B30 /* Release */, - ); - defaultConfigurationIsVisible = 0; - }; -/* End XCConfigurationList section */ - }; - rootObject = 9428295C1A89754E00521B30 /* Project object */; -} diff --git a/lldb/tools/repl/swift/repl_swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/lldb/tools/repl/swift/repl_swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index a03ff818d6f3b..0000000000000 --- a/lldb/tools/repl/swift/repl_swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - From d77607870da177702b37e010d8ff81775e476dc8 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Tue, 13 Oct 2020 13:20:25 -0700 Subject: [PATCH 118/234] Revert "[repl_swift] Delete codesigning override" --- lldb/tools/repl/swift/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lldb/tools/repl/swift/CMakeLists.txt b/lldb/tools/repl/swift/CMakeLists.txt index 10ac8b686f014..16dd41c928c76 100644 --- a/lldb/tools/repl/swift/CMakeLists.txt +++ b/lldb/tools/repl/swift/CMakeLists.txt @@ -1,3 +1,10 @@ +# Only set LLVM_CODESIGNING_IDENTITY for building on Apple hosts for Apple +# targets +if (CMAKE_HOST_APPLE AND APPLE) + # Override locally, so the repl is ad-hoc signed. + set(LLVM_CODESIGNING_IDENTITY "-") +endif() + # Requires system-provided Swift libs. set(CMAKE_OSX_DEPLOYMENT_TARGET 10.14.4) From a1077636c9ecbb83954797853694a9d2718d5a72 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Wed, 26 Aug 2020 14:13:54 +0200 Subject: [PATCH 119/234] [lldb/DWARF] Fix handling of variables with both location and const_value attributes Class-level static constexpr variables can have both DW_AT_const_value (in the "declaration") and a DW_AT_location (in the "definition") attributes. Our code was trying to handle this, but it was brittle and hard to follow (and broken) because it was processing the attributes in the order in which they were found. Refactor the code to make the intent clearer -- DW_AT_location trumps DW_AT_const_value, and fix the bug which meant that we were not displaying these variables properly (the culprit was the delayed parsing of the const_value attribute due to a need to fetch the variable type. Differential Revision: https://reviews.llvm.org/D86615 (cherry picked from commit 9f5927e42bf4a7448dc9dd3a1550d1126c595dad) --- .../Plugins/SymbolFile/DWARF/DWARFFormValue.h | 1 + .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 137 +++++++++-------- .../DWARF/DW_AT_location-DW_AT_const_value.s | 144 ++++++++++++++++++ 3 files changed, 215 insertions(+), 67 deletions(-) create mode 100644 lldb/test/Shell/SymbolFile/DWARF/DW_AT_location-DW_AT_const_value.s diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h index b401352c693dd..fe6a55520978f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h @@ -42,6 +42,7 @@ class DWARFFormValue { DWARFFormValue(const DWARFUnit *unit) : m_unit(unit) {} DWARFFormValue(const DWARFUnit *unit, dw_form_t form) : m_unit(unit), m_form(form) {} + const DWARFUnit *GetUnit() const { return m_unit; } void SetUnit(const DWARFUnit *unit) { m_unit = unit; } dw_form_t Form() const { return m_form; } dw_form_t& FormRef() { return m_form; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 500d7567536ef..271821b245175 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3111,18 +3111,15 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, const char *name = nullptr; const char *mangled = nullptr; Declaration decl; - uint32_t i; DWARFFormValue type_die_form; DWARFExpression location; bool is_external = false; bool is_artificial = false; - bool location_is_const_value_data = false; - bool has_explicit_location = false; - DWARFFormValue const_value; + DWARFFormValue const_value_form, location_form; Variable::RangeList scope_ranges; // AccessType accessibility = eAccessNone; - for (i = 0; i < num_attributes; ++i) { + for (size_t i = 0; i < num_attributes; ++i) { dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; @@ -3152,65 +3149,11 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, is_external = form_value.Boolean(); break; case DW_AT_const_value: - // If we have already found a DW_AT_location attribute, ignore this - // attribute. - if (!has_explicit_location) { - location_is_const_value_data = true; - // The constant value will be either a block, a data value or a - // string. - auto debug_info_data = die.GetData(); - if (DWARFFormValue::IsBlockForm(form_value.Form())) { - // Retrieve the value as a block expression. - uint32_t block_offset = - form_value.BlockData() - debug_info_data.GetDataStart(); - uint32_t block_length = form_value.Unsigned(); - location = DWARFExpression( - module, - DataExtractor(debug_info_data, block_offset, block_length), - die.GetCU()); - } else if (DWARFFormValue::IsDataForm(form_value.Form())) { - // Constant value size does not have to match the size of the - // variable. We will fetch the size of the type after we create - // it. - const_value = form_value; - } else if (const char *str = form_value.AsCString()) { - uint32_t string_length = strlen(str) + 1; - location = DWARFExpression( - module, - DataExtractor(str, string_length, - die.GetCU()->GetByteOrder(), - die.GetCU()->GetAddressByteSize()), - die.GetCU()); - } - } + const_value_form = form_value; + break; + case DW_AT_location: + location_form = form_value; break; - case DW_AT_location: { - location_is_const_value_data = false; - has_explicit_location = true; - if (DWARFFormValue::IsBlockForm(form_value.Form())) { - auto data = die.GetData(); - - uint32_t block_offset = - form_value.BlockData() - data.GetDataStart(); - uint32_t block_length = form_value.Unsigned(); - location = DWARFExpression( - module, DataExtractor(data, block_offset, block_length), - die.GetCU()); - } else { - DataExtractor data = die.GetCU()->GetLocationData(); - dw_offset_t offset = form_value.Unsigned(); - if (form_value.Form() == DW_FORM_loclistx) - offset = die.GetCU()->GetLoclistOffset(offset).getValueOr(-1); - if (data.ValidOffset(offset)) { - data = DataExtractor(data, offset, data.GetByteSize() - offset); - location = DWARFExpression(module, data, die.GetCU()); - assert(func_low_pc != LLDB_INVALID_ADDRESS); - location.SetLocationListAddresses( - attributes.CompileUnitAtIndex(i)->GetBaseAddress(), - func_low_pc); - } - } - } break; case DW_AT_specification: spec_die = form_value.Reference(); break; @@ -3236,6 +3179,66 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, } } + // Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g. + // for static constexpr member variables -- DW_AT_const_value will be + // present in the class declaration and DW_AT_location in the DIE defining + // the member. + bool location_is_const_value_data = false; + bool has_explicit_location = false; + bool use_type_size_for_value = false; + if (location_form.IsValid()) { + has_explicit_location = true; + if (DWARFFormValue::IsBlockForm(location_form.Form())) { + const DWARFDataExtractor &data = die.GetData(); + + uint32_t block_offset = + location_form.BlockData() - data.GetDataStart(); + uint32_t block_length = location_form.Unsigned(); + location = DWARFExpression( + module, DataExtractor(data, block_offset, block_length), + die.GetCU()); + } else { + DataExtractor data = die.GetCU()->GetLocationData(); + dw_offset_t offset = location_form.Unsigned(); + if (location_form.Form() == DW_FORM_loclistx) + offset = die.GetCU()->GetLoclistOffset(offset).getValueOr(-1); + if (data.ValidOffset(offset)) { + data = DataExtractor(data, offset, data.GetByteSize() - offset); + location = DWARFExpression(module, data, die.GetCU()); + assert(func_low_pc != LLDB_INVALID_ADDRESS); + location.SetLocationListAddresses( + location_form.GetUnit()->GetBaseAddress(), func_low_pc); + } + } + } else if (const_value_form.IsValid()) { + location_is_const_value_data = true; + // The constant value will be either a block, a data value or a + // string. + const DWARFDataExtractor &debug_info_data = die.GetData(); + if (DWARFFormValue::IsBlockForm(const_value_form.Form())) { + // Retrieve the value as a block expression. + uint32_t block_offset = + const_value_form.BlockData() - debug_info_data.GetDataStart(); + uint32_t block_length = const_value_form.Unsigned(); + location = DWARFExpression( + module, + DataExtractor(debug_info_data, block_offset, block_length), + die.GetCU()); + } else if (DWARFFormValue::IsDataForm(const_value_form.Form())) { + // Constant value size does not have to match the size of the + // variable. We will fetch the size of the type after we create + // it. + use_type_size_for_value = true; + } else if (const char *str = const_value_form.AsCString()) { + uint32_t string_length = strlen(str) + 1; + location = DWARFExpression( + module, + DataExtractor(str, string_length, die.GetCU()->GetByteOrder(), + die.GetCU()->GetAddressByteSize()), + die.GetCU()); + } + } + const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die); const dw_tag_t parent_tag = die.GetParent().Tag(); bool is_static_member = @@ -3415,12 +3418,12 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, } if (symbol_context_scope) { - SymbolFileTypeSP type_sp( - new SymbolFileType(*this, GetUID(type_die_form.Reference()))); + auto type_sp = std::make_shared( + *this, GetUID(type_die_form.Reference())); - if (const_value.Form() && type_sp && type_sp->GetType()) + if (use_type_size_for_value && type_sp->GetType()) location.UpdateValue( - const_value.Unsigned(), + const_value_form.Unsigned(), type_sp->GetType()->GetByteSize(nullptr).getValueOr(0), die.GetCU()->GetAddressByteSize()); diff --git a/lldb/test/Shell/SymbolFile/DWARF/DW_AT_location-DW_AT_const_value.s b/lldb/test/Shell/SymbolFile/DWARF/DW_AT_location-DW_AT_const_value.s new file mode 100644 index 0000000000000..08ee77175f770 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/DW_AT_location-DW_AT_const_value.s @@ -0,0 +1,144 @@ +## Test that we don't get confused by variables with both location and +## const_value attributes. Such values are produced in C++ for class-level +## static constexpr variables. + +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux %s -o %t +# RUN: %lldb %t -o "target variable A::x A::y" -o exit | FileCheck %s + +# CHECK-LABEL: target variable +# CHECK: (const int) A::x = 142 +# CHECK: (const int) A::y = 242 + + .section .rodata,"a",@progbits + .p2align 2 +_ZN1A1xE: + .long 142 +_ZN1A1yE: + .long 242 + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 8 # DW_FORM_string + .byte 3 # DW_AT_name + .byte 8 # DW_FORM_string + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 8 # DW_FORM_string + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 13 # DW_TAG_member + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 8 # DW_FORM_string + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 28 # DW_AT_const_value + .byte 13 # DW_FORM_sdata + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 38 # DW_TAG_const_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 8 # DW_FORM_string + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 71 # DW_AT_specification + .byte 19 # DW_FORM_ref4 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 8 # DW_FORM_string + .byte 0 # EOM(1) + .byte 0 # EOM(2) +## This deliberately inverts the order of the specification and location +## attributes. + .byte 8 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 71 # DW_AT_specification + .byte 19 # DW_FORM_ref4 + .byte 110 # DW_AT_linkage_name + .byte 8 # DW_FORM_string + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev DW_TAG_compile_unit + .asciz "Hand-written DWARF" # DW_AT_producer + .asciz "a.cc" # DW_AT_name + .byte 7 # Abbrev DW_TAG_variable + .long .LA__x-.Lcu_begin0 # DW_AT_specification + .byte 9 # DW_AT_location + .byte 3 + .quad _ZN1A1xE + .asciz "_ZN1A1xE" # DW_AT_linkage_name + .byte 8 # Abbrev DW_TAG_variable + .byte 9 # DW_AT_location + .byte 3 + .quad _ZN1A1yE + .long .LA__y-.Lcu_begin0 # DW_AT_specification + .asciz "_ZN1A1yE" # DW_AT_linkage_name + .byte 3 # Abbrev DW_TAG_structure_type + .asciz "A" # DW_AT_name + .byte 1 # DW_AT_byte_size +.LA__x: + .byte 4 # Abbrev DW_TAG_member + .asciz "x" # DW_AT_name + .long .Lconst_int-.Lcu_begin0 # DW_AT_type + # DW_AT_declaration + .sleb128 147 # DW_AT_const_value +.LA__y: + .byte 4 # Abbrev DW_TAG_member + .asciz "y" # DW_AT_name + .long .Lconst_int-.Lcu_begin0 # DW_AT_type + # DW_AT_declaration + .sleb128 247 # DW_AT_const_value + .byte 0 # End Of Children Mark +.Lconst_int: + .byte 5 # Abbrev DW_TAG_const_type + .long .Lint-.Lcu_begin0 # DW_AT_type +.Lint: + .byte 6 # Abbrev DW_TAG_base_type + .asciz "int" # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: From da9b7d8e313e904487d2df6bac884993df54c82d Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Wed, 26 Aug 2020 14:13:54 +0200 Subject: [PATCH 120/234] [lldb/DWARF] Fix handling of variables with both location and const_value attributes Class-level static constexpr variables can have both DW_AT_const_value (in the "declaration") and a DW_AT_location (in the "definition") attributes. Our code was trying to handle this, but it was brittle and hard to follow (and broken) because it was processing the attributes in the order in which they were found. Refactor the code to make the intent clearer -- DW_AT_location trumps DW_AT_const_value, and fix the bug which meant that we were not displaying these variables properly (the culprit was the delayed parsing of the const_value attribute due to a need to fetch the variable type. Differential Revision: https://reviews.llvm.org/D86615 (cherry picked from commit 9f5927e42bf4a7448dc9dd3a1550d1126c595dad) --- .../Plugins/SymbolFile/DWARF/DWARFFormValue.h | 1 + .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 137 +++++++++-------- .../DWARF/DW_AT_location-DW_AT_const_value.s | 144 ++++++++++++++++++ 3 files changed, 215 insertions(+), 67 deletions(-) create mode 100644 lldb/test/Shell/SymbolFile/DWARF/DW_AT_location-DW_AT_const_value.s diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h index b401352c693dd..fe6a55520978f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h @@ -42,6 +42,7 @@ class DWARFFormValue { DWARFFormValue(const DWARFUnit *unit) : m_unit(unit) {} DWARFFormValue(const DWARFUnit *unit, dw_form_t form) : m_unit(unit), m_form(form) {} + const DWARFUnit *GetUnit() const { return m_unit; } void SetUnit(const DWARFUnit *unit) { m_unit = unit; } dw_form_t Form() const { return m_form; } dw_form_t& FormRef() { return m_form; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 9e6d9730e5d59..641ce99588aec 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3185,18 +3185,15 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, const char *name = nullptr; const char *mangled = nullptr; Declaration decl; - uint32_t i; DWARFFormValue type_die_form; DWARFExpression location; bool is_external = false; bool is_artificial = false; - bool location_is_const_value_data = false; - bool has_explicit_location = false; - DWARFFormValue const_value; + DWARFFormValue const_value_form, location_form; Variable::RangeList scope_ranges; // AccessType accessibility = eAccessNone; - for (i = 0; i < num_attributes; ++i) { + for (size_t i = 0; i < num_attributes; ++i) { dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; @@ -3226,65 +3223,11 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, is_external = form_value.Boolean(); break; case DW_AT_const_value: - // If we have already found a DW_AT_location attribute, ignore this - // attribute. - if (!has_explicit_location) { - location_is_const_value_data = true; - // The constant value will be either a block, a data value or a - // string. - auto debug_info_data = die.GetData(); - if (DWARFFormValue::IsBlockForm(form_value.Form())) { - // Retrieve the value as a block expression. - uint32_t block_offset = - form_value.BlockData() - debug_info_data.GetDataStart(); - uint32_t block_length = form_value.Unsigned(); - location = DWARFExpression( - module, - DataExtractor(debug_info_data, block_offset, block_length), - die.GetCU()); - } else if (DWARFFormValue::IsDataForm(form_value.Form())) { - // Constant value size does not have to match the size of the - // variable. We will fetch the size of the type after we create - // it. - const_value = form_value; - } else if (const char *str = form_value.AsCString()) { - uint32_t string_length = strlen(str) + 1; - location = DWARFExpression( - module, - DataExtractor(str, string_length, - die.GetCU()->GetByteOrder(), - die.GetCU()->GetAddressByteSize()), - die.GetCU()); - } - } + const_value_form = form_value; + break; + case DW_AT_location: + location_form = form_value; break; - case DW_AT_location: { - location_is_const_value_data = false; - has_explicit_location = true; - if (DWARFFormValue::IsBlockForm(form_value.Form())) { - auto data = die.GetData(); - - uint32_t block_offset = - form_value.BlockData() - data.GetDataStart(); - uint32_t block_length = form_value.Unsigned(); - location = DWARFExpression( - module, DataExtractor(data, block_offset, block_length), - die.GetCU()); - } else { - DataExtractor data = die.GetCU()->GetLocationData(); - dw_offset_t offset = form_value.Unsigned(); - if (form_value.Form() == DW_FORM_loclistx) - offset = die.GetCU()->GetLoclistOffset(offset).getValueOr(-1); - if (data.ValidOffset(offset)) { - data = DataExtractor(data, offset, data.GetByteSize() - offset); - location = DWARFExpression(module, data, die.GetCU()); - assert(func_low_pc != LLDB_INVALID_ADDRESS); - location.SetLocationListAddresses( - attributes.CompileUnitAtIndex(i)->GetBaseAddress(), - func_low_pc); - } - } - } break; case DW_AT_specification: spec_die = form_value.Reference(); break; @@ -3314,6 +3257,66 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, IsSwiftLanguage(sc.comp_unit->GetLanguage())) mangled = NULL; + // Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g. + // for static constexpr member variables -- DW_AT_const_value will be + // present in the class declaration and DW_AT_location in the DIE defining + // the member. + bool location_is_const_value_data = false; + bool has_explicit_location = false; + bool use_type_size_for_value = false; + if (location_form.IsValid()) { + has_explicit_location = true; + if (DWARFFormValue::IsBlockForm(location_form.Form())) { + const DWARFDataExtractor &data = die.GetData(); + + uint32_t block_offset = + location_form.BlockData() - data.GetDataStart(); + uint32_t block_length = location_form.Unsigned(); + location = DWARFExpression( + module, DataExtractor(data, block_offset, block_length), + die.GetCU()); + } else { + DataExtractor data = die.GetCU()->GetLocationData(); + dw_offset_t offset = location_form.Unsigned(); + if (location_form.Form() == DW_FORM_loclistx) + offset = die.GetCU()->GetLoclistOffset(offset).getValueOr(-1); + if (data.ValidOffset(offset)) { + data = DataExtractor(data, offset, data.GetByteSize() - offset); + location = DWARFExpression(module, data, die.GetCU()); + assert(func_low_pc != LLDB_INVALID_ADDRESS); + location.SetLocationListAddresses( + location_form.GetUnit()->GetBaseAddress(), func_low_pc); + } + } + } else if (const_value_form.IsValid()) { + location_is_const_value_data = true; + // The constant value will be either a block, a data value or a + // string. + const DWARFDataExtractor &debug_info_data = die.GetData(); + if (DWARFFormValue::IsBlockForm(const_value_form.Form())) { + // Retrieve the value as a block expression. + uint32_t block_offset = + const_value_form.BlockData() - debug_info_data.GetDataStart(); + uint32_t block_length = const_value_form.Unsigned(); + location = DWARFExpression( + module, + DataExtractor(debug_info_data, block_offset, block_length), + die.GetCU()); + } else if (DWARFFormValue::IsDataForm(const_value_form.Form())) { + // Constant value size does not have to match the size of the + // variable. We will fetch the size of the type after we create + // it. + use_type_size_for_value = true; + } else if (const char *str = const_value_form.AsCString()) { + uint32_t string_length = strlen(str) + 1; + location = DWARFExpression( + module, + DataExtractor(str, string_length, die.GetCU()->GetByteOrder(), + die.GetCU()->GetAddressByteSize()), + die.GetCU()); + } + } + const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die); const dw_tag_t parent_tag = die.GetParent().Tag(); bool is_static_member = @@ -3493,12 +3496,12 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, } if (symbol_context_scope) { - SymbolFileTypeSP type_sp( - new SymbolFileType(*this, GetUID(type_die_form.Reference()))); + auto type_sp = std::make_shared( + *this, GetUID(type_die_form.Reference())); - if (const_value.Form() && type_sp && type_sp->GetType()) + if (use_type_size_for_value && type_sp->GetType()) location.UpdateValue( - const_value.Unsigned(), + const_value_form.Unsigned(), type_sp->GetType()->GetByteSize(nullptr).getValueOr(0), die.GetCU()->GetAddressByteSize()); diff --git a/lldb/test/Shell/SymbolFile/DWARF/DW_AT_location-DW_AT_const_value.s b/lldb/test/Shell/SymbolFile/DWARF/DW_AT_location-DW_AT_const_value.s new file mode 100644 index 0000000000000..08ee77175f770 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/DW_AT_location-DW_AT_const_value.s @@ -0,0 +1,144 @@ +## Test that we don't get confused by variables with both location and +## const_value attributes. Such values are produced in C++ for class-level +## static constexpr variables. + +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux %s -o %t +# RUN: %lldb %t -o "target variable A::x A::y" -o exit | FileCheck %s + +# CHECK-LABEL: target variable +# CHECK: (const int) A::x = 142 +# CHECK: (const int) A::y = 242 + + .section .rodata,"a",@progbits + .p2align 2 +_ZN1A1xE: + .long 142 +_ZN1A1yE: + .long 242 + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 8 # DW_FORM_string + .byte 3 # DW_AT_name + .byte 8 # DW_FORM_string + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 8 # DW_FORM_string + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 13 # DW_TAG_member + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 8 # DW_FORM_string + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 28 # DW_AT_const_value + .byte 13 # DW_FORM_sdata + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 38 # DW_TAG_const_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 8 # DW_FORM_string + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 71 # DW_AT_specification + .byte 19 # DW_FORM_ref4 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 110 # DW_AT_linkage_name + .byte 8 # DW_FORM_string + .byte 0 # EOM(1) + .byte 0 # EOM(2) +## This deliberately inverts the order of the specification and location +## attributes. + .byte 8 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 71 # DW_AT_specification + .byte 19 # DW_FORM_ref4 + .byte 110 # DW_AT_linkage_name + .byte 8 # DW_FORM_string + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev DW_TAG_compile_unit + .asciz "Hand-written DWARF" # DW_AT_producer + .asciz "a.cc" # DW_AT_name + .byte 7 # Abbrev DW_TAG_variable + .long .LA__x-.Lcu_begin0 # DW_AT_specification + .byte 9 # DW_AT_location + .byte 3 + .quad _ZN1A1xE + .asciz "_ZN1A1xE" # DW_AT_linkage_name + .byte 8 # Abbrev DW_TAG_variable + .byte 9 # DW_AT_location + .byte 3 + .quad _ZN1A1yE + .long .LA__y-.Lcu_begin0 # DW_AT_specification + .asciz "_ZN1A1yE" # DW_AT_linkage_name + .byte 3 # Abbrev DW_TAG_structure_type + .asciz "A" # DW_AT_name + .byte 1 # DW_AT_byte_size +.LA__x: + .byte 4 # Abbrev DW_TAG_member + .asciz "x" # DW_AT_name + .long .Lconst_int-.Lcu_begin0 # DW_AT_type + # DW_AT_declaration + .sleb128 147 # DW_AT_const_value +.LA__y: + .byte 4 # Abbrev DW_TAG_member + .asciz "y" # DW_AT_name + .long .Lconst_int-.Lcu_begin0 # DW_AT_type + # DW_AT_declaration + .sleb128 247 # DW_AT_const_value + .byte 0 # End Of Children Mark +.Lconst_int: + .byte 5 # Abbrev DW_TAG_const_type + .long .Lint-.Lcu_begin0 # DW_AT_type +.Lint: + .byte 6 # Abbrev DW_TAG_base_type + .asciz "int" # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: From 31031e6866c85a95d3506fdf58cde72cb83fb84e Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 13 Oct 2020 14:34:55 -0700 Subject: [PATCH 121/234] Remove legacy Swift language constant support --- .../Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 641ce99588aec..bdf05d4273195 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -249,11 +249,6 @@ ParseSupportFilesFromPrologue(const lldb::ModuleSP &module, return support_files; } -static inline bool IsSwiftLanguage(LanguageType language) { - return language == eLanguageTypePLI || language == eLanguageTypeSwift || - ((uint32_t)language == (uint32_t)llvm::dwarf::DW_LANG_Swift); -} - void SymbolFileDWARF::Initialize() { LogChannelDWARF::Initialize(); PluginManager::RegisterPlugin(GetPluginNameStatic(), @@ -974,7 +969,7 @@ bool SymbolFileDWARF::ParseImportedModules( return false; auto lang = sc.comp_unit->GetLanguage(); if (!ClangModulesDeclVendor::LanguageSupportsClangModules(lang) && - !IsSwiftLanguage(lang)) + lang != eLanguageTypeSwift) return false; UpdateExternalModuleListIfNeeded(); @@ -3254,7 +3249,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, } if (tag == DW_TAG_variable && mangled && - IsSwiftLanguage(sc.comp_unit->GetLanguage())) + sc.comp_unit->GetLanguage() == eLanguageTypeSwift) mangled = NULL; // Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g. @@ -3507,7 +3502,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, // Swift let-bindings are marked by a DW_TAG_const_type. bool is_constant = false; - if (IsSwiftLanguage(sc.comp_unit->GetLanguage())) { + if (sc.comp_unit->GetLanguage() == eLanguageTypeSwift) { DWARFDIE type_die = die.GetReferencedDIE(llvm::dwarf::DW_AT_type); if (type_die && type_die.Tag() == llvm::dwarf::DW_TAG_const_type) is_constant = true; From 0bebe9fd3e9b27c1f30d6edc3b49f8fadcb57500 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Tue, 13 Oct 2020 16:20:40 -0700 Subject: [PATCH 122/234] [llvm-cov] Warn when -arch spec is missing/invalid for universal binary (reland) llvm-cov reports a poor error message when the -arch specifier is missing or invalid, and a binary has multiple slices. Make the error message more specific. (This version of the patch avoids using llvm::none_of -- the way I used the utility caused compile errors on many bots, possibly because the wrong overload of `none_of` was selected.) rdar://40312677 (cherry picked from commit 7fafaa07bcaddd6cad8323940b73c0df98a8f02a) --- .../llvm/ProfileData/Coverage/CoverageMapping.h | 3 ++- .../ProfileData/Coverage/CoverageMapping.cpp | 2 ++ .../Coverage/CoverageMappingReader.cpp | 17 +++++++++++++++++ llvm/test/tools/llvm-cov/universal-binary.c | 3 ++- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index bf0dffc9653cf..2f285bf54a6a9 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -55,7 +55,8 @@ enum class coveragemap_error { unsupported_version, truncated, malformed, - decompression_failed + decompression_failed, + invalid_or_missing_arch_specifier }; const std::error_category &coveragemap_category(); diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 70f00d333db17..30cead95cbee6 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -807,6 +807,8 @@ static std::string getCoverageMapErrString(coveragemap_error Err) { return "Malformed coverage data"; case coveragemap_error::decompression_failed: return "Failed to decompress coverage data (zlib)"; + case coveragemap_error::invalid_or_missing_arch_specifier: + return "`-arch` specifier is invalid or missing for universal binary"; } llvm_unreachable("A value of coveragemap_error has no message."); } diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp index b75738bc360ce..4936638c61cc9 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp @@ -950,6 +950,19 @@ loadBinaryFormat(std::unique_ptr Bin, StringRef Arch) { BytesInAddress, Endian); } +/// Determine whether \p Arch is invalid or empty, given \p Bin. +static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch) { + // If we have a universal binary and Arch doesn't identify any of its slices, + // it's user error. + if (auto *Universal = dyn_cast(Bin)) { + for (auto &ObjForArch : Universal->objects()) + if (Arch == ObjForArch.getArchFlagName()) + return false; + return true; + } + return false; +} + Expected>> BinaryCoverageReader::create( MemoryBufferRef ObjectBuffer, StringRef Arch, @@ -970,6 +983,10 @@ BinaryCoverageReader::create( return BinOrErr.takeError(); std::unique_ptr Bin = std::move(BinOrErr.get()); + if (isArchSpecifierInvalidOrMissing(Bin.get(), Arch)) + return make_error( + coveragemap_error::invalid_or_missing_arch_specifier); + // MachO universal binaries which contain archives need to be treated as // archives, not as regular binaries. if (auto *Universal = dyn_cast(Bin.get())) { diff --git a/llvm/test/tools/llvm-cov/universal-binary.c b/llvm/test/tools/llvm-cov/universal-binary.c index 635cd32146eba..f8d5346bc5794 100644 --- a/llvm/test/tools/llvm-cov/universal-binary.c +++ b/llvm/test/tools/llvm-cov/universal-binary.c @@ -10,8 +10,9 @@ int main(int argc, const char *argv[]) {} // COMBINED: showTemplateInstantiations.cpp // COMBINED-NEXT: universal-binary.c +// RUN: not llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -path-equivalence=/tmp,%S %s 2>&1 | FileCheck --check-prefix=WRONG-ARCH %s // RUN: not llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -path-equivalence=/tmp,%S %s -arch i386 2>&1 | FileCheck --check-prefix=WRONG-ARCH %s -// WRONG-ARCH: Failed to load coverage +// WRONG-ARCH: Failed to load coverage: `-arch` specifier is invalid or missing for universal binary // RUN: not llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -path-equivalence=/tmp,%S %s -arch definitly_a_made_up_architecture 2>&1 | FileCheck --check-prefix=MADE-UP-ARCH %s // MADE-UP-ARCH: Unknown architecture: definitly_a_made_up_architecture From ee91d80a5c42af1015a96e3e9da625592140e604 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Tue, 13 Oct 2020 14:22:12 -0700 Subject: [PATCH 123/234] [cmake] Unconditionally set the force flag when codesigning The Darwin linker now defaults to ad hoc signing binaries when targeting Apple Silicon. This creates a problem when configuring targets that must be built with entitlements: we either need to add -Wl,-no_adhoc_codesign when building the target, or sign with the force flag set to allow replacing a pre-existing signature. Unconditionally force-signing is the more convenient solution. This doesn't require a ld64 version check, and it's a much less invasive cmake change. Patch by Fred Riss! rdar://70237254 Differential Revision: https://reviews.llvm.org/D89343 (cherry picked from commit 24c1660ac5d7813072b429eee7a9531338e53aea) --- llvm/cmake/modules/AddLLVM.cmake | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index 333167bfb6b0d..459a73a59bc39 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -2037,9 +2037,10 @@ function(llvm_codesign name) set(ARG_BUNDLE_PATH $) endif() - if(ARG_FORCE) - set(force_flag "-f") - endif() + # ld64 now always codesigns the binaries it creates. Apply the force arg + # unconditionally so that we can - for example - add entitlements to the + # targets that need it. + set(force_flag "-f") add_custom_command( TARGET ${name} POST_BUILD From d9e4ea4c243760647351751c4895bd81150b533f Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Tue, 13 Oct 2020 14:43:31 -0700 Subject: [PATCH 124/234] [repl_swift] Add get-task-allow entitlement This upstreams an Apple-internal change that sets the get-task-allow entitlement on repl_swift. --- lldb/tools/repl/swift/CMakeLists.txt | 7 ++++++- lldb/tools/repl/swift/get-task-allow-entitlements.plist | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 lldb/tools/repl/swift/get-task-allow-entitlements.plist diff --git a/lldb/tools/repl/swift/CMakeLists.txt b/lldb/tools/repl/swift/CMakeLists.txt index 16dd41c928c76..46989e7c25b5a 100644 --- a/lldb/tools/repl/swift/CMakeLists.txt +++ b/lldb/tools/repl/swift/CMakeLists.txt @@ -6,10 +6,15 @@ if (CMAKE_HOST_APPLE AND APPLE) endif() # Requires system-provided Swift libs. -set(CMAKE_OSX_DEPLOYMENT_TARGET 10.14.4) +if(NOT APPLE_EMBEDDED) + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.14.4) +endif() add_lldb_tool(repl_swift ADD_TO_FRAMEWORK main.c + + ENTITLEMENTS + "${CMAKE_CURRENT_SOURCE_DIR}/get-task-allow-entitlements.plist" ) target_link_libraries(repl_swift PRIVATE ${CMAKE_DL_LIBS}) if(CMAKE_SYSTEM_NAME STREQUAL Windows) diff --git a/lldb/tools/repl/swift/get-task-allow-entitlements.plist b/lldb/tools/repl/swift/get-task-allow-entitlements.plist new file mode 100644 index 0000000000000..9acd12816c913 --- /dev/null +++ b/lldb/tools/repl/swift/get-task-allow-entitlements.plist @@ -0,0 +1,8 @@ + + + + + com.apple.security.get-task-allow + + + From 8a348eb706b912a7a14d5a7782c42eb1b06a630a Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 13 Oct 2020 17:00:32 -0700 Subject: [PATCH 125/234] Move initialization of Variable::m_loc_is_const_data into constructor (NFC) This makes it symmetric with all other flags and makes it easier to not forget to initialize it. https://reviews.llvm.org/D89351 (cherry picked from commit 9b1c06c0e84a9cc763e12b289becb5fc3c9d01ea) Conflicts: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp --- lldb/include/lldb/Symbol/Variable.h | 3 ++- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 4 +--- .../Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp | 8 +++----- lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | 4 ++-- lldb/source/Symbol/Variable.cpp | 5 +++-- 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/lldb/include/lldb/Symbol/Variable.h b/lldb/include/lldb/Symbol/Variable.h index 66abdc0b31178..20ade3e0bb5d8 100644 --- a/lldb/include/lldb/Symbol/Variable.h +++ b/lldb/include/lldb/Symbol/Variable.h @@ -33,7 +33,8 @@ class Variable : public UserID, public std::enable_shared_from_this { const lldb::SymbolFileTypeSP &symfile_type_sp, lldb::ValueType scope, SymbolContextScope *owner_scope, const RangeList &scope_range, Declaration *decl, const DWARFExpression &location, bool external, - bool artificial, bool static_member = false); + bool artificial, bool location_is_constant_data, + bool static_member = false); virtual ~Variable(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 271821b245175..be5271e2c3201 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3430,9 +3430,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, var_sp = std::make_shared( die.GetID(), name, mangled, type_sp, scope, symbol_context_scope, scope_ranges, &decl, location, is_external, is_artificial, - is_static_member); - - var_sp->SetLocationIsConstantValueData(location_is_const_value_data); + location_is_const_value_data, is_static_member); } else { // Not ready to parse this variable yet. It might be a global or static // variable that is in a function scope and the function in the symbol diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 9f53e92afa0b1..9f41a9a8127be 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -812,8 +812,7 @@ VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) { VariableSP var_sp = std::make_shared( toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp, scope, comp_unit.get(), ranges, &decl, location, is_external, false, - false); - var_sp->SetLocationIsConstantValueData(false); + false, false); return var_sp; } @@ -840,8 +839,7 @@ SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id, VariableSP var_sp = std::make_shared( toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(), type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location, - false, false, false); - var_sp->SetLocationIsConstantValueData(true); + false, false, true, false); return var_sp; } @@ -1346,7 +1344,7 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id, VariableSP var_sp = std::make_shared( toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope, comp_unit_sp.get(), *var_info.ranges, &decl, *var_info.location, false, - false, false); + false, false, false); if (!is_param) m_ast->GetOrCreateVariableDecl(scope_id, var_id); diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 1001514edede1..a86aebd116177 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1020,8 +1020,8 @@ VariableSP SymbolFilePDB::ParseVariableForPDBData( var_sp = std::make_shared( var_uid, var_name.c_str(), mangled_cstr, type_sp, scope, context_scope, - ranges, &decl, location, is_external, is_artificial, is_static_member); - var_sp->SetLocationIsConstantValueData(is_constant); + ranges, &decl, location, is_external, is_artificial, is_constant, + is_static_member); m_variables.insert(std::make_pair(var_uid, var_sp)); return var_sp; diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp index 6c18ef15e1a2d..62b16011fe66d 100644 --- a/lldb/source/Symbol/Variable.cpp +++ b/lldb/source/Symbol/Variable.cpp @@ -40,12 +40,13 @@ Variable::Variable(lldb::user_id_t uid, const char *name, const char *mangled, ValueType scope, SymbolContextScope *context, const RangeList &scope_range, Declaration *decl_ptr, const DWARFExpression &location, bool external, - bool artificial, bool static_member) + bool artificial, bool location_is_constant_data, + bool static_member) : UserID(uid), m_name(name), m_mangled(ConstString(mangled)), m_symfile_type_sp(symfile_type_sp), m_scope(scope), m_owner_scope(context), m_scope_range(scope_range), m_declaration(decl_ptr), m_location(location), m_external(external), - m_artificial(artificial), m_loc_is_const_data(false), + m_artificial(artificial), m_loc_is_const_data(location_is_constant_data), m_static_member(static_member) {} Variable::~Variable() {} From 988642217f4628b3ebcbacb33890a32c713766b1 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 13 Oct 2020 17:00:32 -0700 Subject: [PATCH 126/234] Move initialization of Variable::m_loc_is_const_data into constructor (NFC) This makes it symmetric with all other flags and makes it easier to not forget to initialize it. https://reviews.llvm.org/D89351 (cherry picked from commit 9b1c06c0e84a9cc763e12b289becb5fc3c9d01ea) Conflicts: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Conflicts: lldb/include/lldb/Symbol/Variable.h lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp lldb/source/Symbol/Variable.cpp --- lldb/include/lldb/Symbol/Variable.h | 3 ++- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 4 +--- .../Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp | 8 +++----- lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | 5 ++--- lldb/source/Symbol/Variable.cpp | 5 +++-- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/lldb/include/lldb/Symbol/Variable.h b/lldb/include/lldb/Symbol/Variable.h index 204cb9e5297a7..44618fe01a23b 100644 --- a/lldb/include/lldb/Symbol/Variable.h +++ b/lldb/include/lldb/Symbol/Variable.h @@ -33,7 +33,8 @@ class Variable : public UserID, public std::enable_shared_from_this { const lldb::SymbolFileTypeSP &symfile_type_sp, lldb::ValueType scope, SymbolContextScope *owner_scope, const RangeList &scope_range, Declaration *decl, const DWARFExpression &location, bool external, - bool artificial, bool static_member, bool constant); + bool artificial, bool location_is_constant_data, bool static_member, + bool constant); virtual ~Variable(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index bdf05d4273195..ae083cad10667 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3511,9 +3511,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, var_sp = std::make_shared( die.GetID(), name, mangled, type_sp, scope, symbol_context_scope, scope_ranges, &decl, location, is_external, is_artificial, - is_static_member, is_constant); - - var_sp->SetLocationIsConstantValueData(location_is_const_value_data); + location_is_const_value_data, is_static_member, is_constant); } else { // Not ready to parse this variable yet. It might be a global or static // variable that is in a function scope and the function in the symbol diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index d4451b3adcdc4..7bf310807400e 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -812,8 +812,7 @@ VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) { VariableSP var_sp = std::make_shared( toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp, scope, comp_unit.get(), ranges, &decl, location, is_external, false, - false, false); - var_sp->SetLocationIsConstantValueData(false); + false, false, false); return var_sp; } @@ -840,8 +839,7 @@ SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id, VariableSP var_sp = std::make_shared( toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(), type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location, - false, false, false, true); - var_sp->SetLocationIsConstantValueData(true); + false, false, true, false, true); return var_sp; } @@ -1346,7 +1344,7 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id, VariableSP var_sp = std::make_shared( toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope, comp_unit_sp.get(), *var_info.ranges, &decl, *var_info.location, false, - false, false, false); + false, false, false, false); if (!is_param) m_ast->GetOrCreateVariableDecl(scope_id, var_id); diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 8e6a4cc455152..8a11502094467 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1020,9 +1020,8 @@ VariableSP SymbolFilePDB::ParseVariableForPDBData( var_sp = std::make_shared( var_uid, var_name.c_str(), mangled_cstr, type_sp, scope, context_scope, - ranges, &decl, location, is_external, is_artificial, is_static_member, - is_constant); - var_sp->SetLocationIsConstantValueData(is_constant); + ranges, &decl, location, is_external, is_artificial, is_constant, + is_static_member, is_constant); m_variables.insert(std::make_pair(var_uid, var_sp)); return var_sp; diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp index a83b8b258b239..bd1d3204a0ee3 100644 --- a/lldb/source/Symbol/Variable.cpp +++ b/lldb/source/Symbol/Variable.cpp @@ -40,12 +40,13 @@ Variable::Variable(lldb::user_id_t uid, const char *name, const char *mangled, ValueType scope, SymbolContextScope *context, const RangeList &scope_range, Declaration *decl_ptr, const DWARFExpression &location, bool external, - bool artificial, bool static_member, bool constant) + bool artificial, bool location_is_constant_data, + bool static_member, bool constant) : UserID(uid), m_name(name), m_mangled(ConstString(mangled)), m_symfile_type_sp(symfile_type_sp), m_scope(scope), m_owner_scope(context), m_scope_range(scope_range), m_declaration(decl_ptr), m_location(location), m_external(external), - m_artificial(artificial), m_loc_is_const_data(false), + m_artificial(artificial), m_loc_is_const_data(location_is_constant_data), m_static_member(static_member), m_constant(constant) {} Variable::~Variable() {} From d449c816a68ebf3107145df17032b5d50f0a7968 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 14 Oct 2020 09:50:59 +0200 Subject: [PATCH 127/234] [lldb] Reject redefinitions of persistent variables Currently one can redefine a persistent variable and LLDB will just silently ignore the second definition: ``` (lldb) expr int $i = 1 (lldb) expr int $i = 2 (lldb) expr $i (int) $i = 1 ``` This patch makes this an error and rejects the expression with the second definition. A nice follow up would be to refactor LLDB's persistent variables to not just be a pair of type and name, but also contain some way to obtain the original declaration and source code that declared the variable. That way we could actually make a full diagnostic as we would get from redefining a variable twice in the same expression. Reviewed By: labath, shafik, JDevlieghere Differential Revision: https://reviews.llvm.org/D89310 (cherry picked from commit cb81e662a58908913f342520e4c010564a68126a) --- .../Clang/ClangExpressionDeclMap.cpp | 18 ++++++++++++++++++ .../Clang/ClangExpressionDeclMap.h | 4 ++++ .../Clang/ClangExpressionParser.cpp | 1 + .../TestPersistentVariables.py | 16 ++++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index 8c49898e1d6ca..7d8cd85500aed 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -19,6 +19,7 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectVariable.h" +#include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/Materializer.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/CompilerDecl.h" @@ -125,6 +126,12 @@ void ClangExpressionDeclMap::InstallCodeGenerator( m_parser_vars->m_code_gen = code_gen; } +void ClangExpressionDeclMap::InstallDiagnosticManager( + DiagnosticManager &diag_manager) { + assert(m_parser_vars); + m_parser_vars->m_diagnostics = &diag_manager; +} + void ClangExpressionDeclMap::DidParse() { if (m_parser_vars && m_parser_vars->m_persistent_vars) { for (size_t entity_index = 0, num_entities = m_found_entities.GetSize(); @@ -196,6 +203,17 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl, if (ast == nullptr) return false; + // Check if we already declared a persistent variable with the same name. + if (lldb::ExpressionVariableSP conflicting_var = + m_parser_vars->m_persistent_vars->GetVariable(name)) { + std::string msg = llvm::formatv("redefinition of persistent variable '{0}'", + name).str(); + m_parser_vars->m_diagnostics->AddDiagnostic( + msg, DiagnosticSeverity::eDiagnosticSeverityError, + DiagnosticOrigin::eDiagnosticOriginLLDB); + return false; + } + if (m_parser_vars->m_materializer && is_result) { Status err; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h index 6974535a89934..0c81d46c6c528 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h @@ -102,6 +102,8 @@ class ClangExpressionDeclMap : public ClangASTSource { void InstallCodeGenerator(clang::ASTConsumer *code_gen); + void InstallDiagnosticManager(DiagnosticManager &diag_manager); + /// Disable the state needed for parsing and IR transformation. void DidParse(); @@ -330,6 +332,8 @@ class ClangExpressionDeclMap : public ClangASTSource { clang::ASTConsumer *m_code_gen = nullptr; ///< If non-NULL, a code generator ///that receives new top-level ///functions. + DiagnosticManager *m_diagnostics = nullptr; + private: ParserVars(const ParserVars &) = delete; const ParserVars &operator=(const ParserVars &) = delete; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index 202eb87cca3d0..68446a3d181c7 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -1074,6 +1074,7 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap(); if (decl_map) { decl_map->InstallCodeGenerator(&m_compiler->getASTConsumer()); + decl_map->InstallDiagnosticManager(diagnostic_manager); clang::ExternalASTSource *ast_source = decl_map->CreateProxy(); diff --git a/lldb/test/API/commands/expression/persistent_variables/TestPersistentVariables.py b/lldb/test/API/commands/expression/persistent_variables/TestPersistentVariables.py index ebe180998c634..bdd1ccc596964 100644 --- a/lldb/test/API/commands/expression/persistent_variables/TestPersistentVariables.py +++ b/lldb/test/API/commands/expression/persistent_variables/TestPersistentVariables.py @@ -41,3 +41,19 @@ def test_persistent_variables(self): # Test that $200 wasn't created by the previous expression. self.expect("expr $200", error=True, substrs=["use of undeclared identifier '$200'"]) + + # Try redeclaring the persistent variable with the same type. + # This should be rejected as we treat them as if they are globals. + self.expect("expr int $i = 123", error=True, + substrs=["error: redefinition of persistent variable '$i'"]) + self.expect_expr("$i", result_type="int", result_value="5") + + # Try redeclaring the persistent variable with another type. Should + # also be rejected. + self.expect("expr long $i = 123", error=True, + substrs=["error: redefinition of persistent variable '$i'"]) + self.expect_expr("$i", result_type="int", result_value="5") + + # Try assigning the persistent variable a new value. + self.expect("expr $i = 55") + self.expect_expr("$i", result_type="int", result_value="55") From cd62e2a7b813c86a40f626cfa509cdacd2600b6d Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 14 Oct 2020 17:15:51 +0200 Subject: [PATCH 128/234] [lldb] Fix Python syntax error in lldbtest.py --- lldb/packages/Python/lldbsuite/test/lldbtest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py index cebb585af8aec..e055336a4177c 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -1038,6 +1038,7 @@ def tearDown(self): if not configuration.is_reproducer(): # Assert that the global module cache is empty. # (rdar://problem/64424164) self.assertEqual(lldb.SBModule.GetNumberAllocatedModules(), 0) + pass # ========================================================= From 40f9432f369012ca6e8eabc7d799418b3f2c7181 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 14 Oct 2020 17:34:28 +0200 Subject: [PATCH 129/234] [lldb] Regenerate the static bindings --- .../python/static-binding/LLDBWrapPython.cpp | 27 +++++++++++++++++ lldb/bindings/python/static-binding/lldb.py | 29 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/lldb/bindings/python/static-binding/LLDBWrapPython.cpp b/lldb/bindings/python/static-binding/LLDBWrapPython.cpp index b481edaf48a06..4dc092548fe7c 100644 --- a/lldb/bindings/python/static-binding/LLDBWrapPython.cpp +++ b/lldb/bindings/python/static-binding/LLDBWrapPython.cpp @@ -40700,6 +40700,22 @@ SWIGINTERN PyObject *_wrap_SBModule_GetNumberAllocatedModules(PyObject *SWIGUNUS } +SWIGINTERN PyObject *_wrap_SBModule_GarbageCollectAllocatedModules(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + + if (!SWIG_Python_UnpackTuple(args, "SBModule_GarbageCollectAllocatedModules", 0, 0, 0)) SWIG_fail; + { + SWIG_PYTHON_THREAD_BEGIN_ALLOW; + lldb::SBModule::GarbageCollectAllocatedModules(); + SWIG_PYTHON_THREAD_END_ALLOW; + } + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_SBModule___str__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; lldb::SBModule *arg1 = (lldb::SBModule *) 0 ; @@ -82548,6 +82564,17 @@ static PyMethodDef SwigMethods[] = { " @return\n" " The number of modules in the module cache.\n" ""}, + { "SBModule_GarbageCollectAllocatedModules", _wrap_SBModule_GarbageCollectAllocatedModules, METH_NOARGS, "\n" + "SBModule_GarbageCollectAllocatedModules()\n" + "\n" + " Removes all modules which are no longer needed by any part of LLDB from\n" + " the module cache.\n" + "\n" + " This is an implementation detail exposed for testing and should not be\n" + " relied upon. Use SBDebugger::MemoryPressureDetected instead to reduce\n" + " LLDB's memory consumption during execution.\n" + "\n" + ""}, { "SBModule___str__", _wrap_SBModule___str__, METH_O, "SBModule___str__(SBModule self) -> std::string"}, { "SBModule_swigregister", SBModule_swigregister, METH_O, NULL}, { "SBModule_swiginit", SBModule_swiginit, METH_VARARGS, NULL}, diff --git a/lldb/bindings/python/static-binding/lldb.py b/lldb/bindings/python/static-binding/lldb.py index e3c1a5c8a2b91..feff0b5d3de29 100644 --- a/lldb/bindings/python/static-binding/lldb.py +++ b/lldb/bindings/python/static-binding/lldb.py @@ -7484,6 +7484,21 @@ def GetNumberAllocatedModules(): """ return _lldb.SBModule_GetNumberAllocatedModules() + @staticmethod + def GarbageCollectAllocatedModules(): + r""" + GarbageCollectAllocatedModules() + + Removes all modules which are no longer needed by any part of LLDB from + the module cache. + + This is an implementation detail exposed for testing and should not be + relied upon. Use SBDebugger::MemoryPressureDetected instead to reduce + LLDB's memory consumption during execution. + + """ + return _lldb.SBModule_GarbageCollectAllocatedModules() + def __str__(self): r"""__str__(SBModule self) -> std::string""" return _lldb.SBModule___str__(self) @@ -7716,6 +7731,20 @@ def SBModule_GetNumberAllocatedModules(): """ return _lldb.SBModule_GetNumberAllocatedModules() +def SBModule_GarbageCollectAllocatedModules(): + r""" + SBModule_GarbageCollectAllocatedModules() + + Removes all modules which are no longer needed by any part of LLDB from + the module cache. + + This is an implementation detail exposed for testing and should not be + relied upon. Use SBDebugger::MemoryPressureDetected instead to reduce + LLDB's memory consumption during execution. + + """ + return _lldb.SBModule_GarbageCollectAllocatedModules() + class SBModuleSpec(object): r"""Proxy of C++ lldb::SBModuleSpec class.""" From 8642e649b0d0029efacf1a3def62f98af06a45d2 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 2 Oct 2020 12:32:01 -0700 Subject: [PATCH 130/234] Add accessors. (NFC) There's a place in swift-lldb where it is useful to create a copy of an lldb_private::Variable. Adding these two accessors makes this possible. (cherry picked from commit ec2c2ad2a2dddf24b052625b5ff434704ea43e24) --- lldb/include/lldb/Symbol/Type.h | 1 + lldb/include/lldb/Symbol/Variable.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h index efd3ede034457..06fc1d5da0aa9 100644 --- a/lldb/include/lldb/Symbol/Type.h +++ b/lldb/include/lldb/Symbol/Type.h @@ -56,6 +56,7 @@ class SymbolFileType : public std::enable_shared_from_this, Type *operator->() { return GetType(); } Type *GetType(); + SymbolFile &GetSymbolFile() const { return m_symbol_file; } protected: SymbolFile &m_symbol_file; diff --git a/lldb/include/lldb/Symbol/Variable.h b/lldb/include/lldb/Symbol/Variable.h index 20ade3e0bb5d8..0dcbbd8e4c8ee 100644 --- a/lldb/include/lldb/Symbol/Variable.h +++ b/lldb/include/lldb/Symbol/Variable.h @@ -65,6 +65,8 @@ class Variable : public UserID, public std::enable_shared_from_this { lldb::ValueType GetScope() const { return m_scope; } + const RangeList &GetScopeRange() const { return m_scope_range; } + bool IsExternal() const { return m_external; } bool IsArtificial() const { return m_artificial; } From 4e85bc43b731d0329643f49e3df05c5cba45bd1e Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 31 Jul 2020 13:12:13 -0700 Subject: [PATCH 131/234] Make sure the Swift REPL is initialized with host OS availablity. This is fixed by unifying the code that updates the ArchSpec after finding a fat binary with how it is done for a lean binary. (cherry picked from commit 9f22fa52c9dfc98c96b6a9fdad0c7b3b7759820e) Conflicts: lldb/source/Target/TargetList.cpp --- lldb/source/Target/TargetList.cpp | 3 ++- lldb/test/Shell/SwiftREPL/Availability.test | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 lldb/test/Shell/SwiftREPL/Availability.test diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp index d4d3740286b7c..e02a638492f94 100644 --- a/lldb/source/Target/TargetList.cpp +++ b/lldb/source/Target/TargetList.cpp @@ -254,7 +254,8 @@ Status TargetList::CreateTargetInternal( // If we have a valid architecture, make sure the current platform is // compatible with that architecture. if (!prefer_platform_arch && arch.IsValid()) { - if (!platform_sp->IsCompatibleArchitecture(arch, false, nullptr)) { + ArchSpec compatible_arch; + if (!platform_sp->IsCompatibleArchitecture(arch, false, &compatible_arch)) { platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); if (!is_dummy_target && platform_sp) debugger.GetPlatformList().SetSelectedPlatform(platform_sp); diff --git a/lldb/test/Shell/SwiftREPL/Availability.test b/lldb/test/Shell/SwiftREPL/Availability.test new file mode 100644 index 0000000000000..97af971ef2af3 --- /dev/null +++ b/lldb/test/Shell/SwiftREPL/Availability.test @@ -0,0 +1,14 @@ +// -*- mode: swift; -*- +// Test that the REPL is launched with the current OS as availability target. +// REQUIRES: system-darwin + +// RUN: mkdir -p %t.dir +// RUN: echo '@available(macOS '>%t.dir/NewModule.swift +// RUN: sw_vers | grep ProductVersion | cut -d : -f 2 >>%t.dir/NewModule.swift +// RUN: echo ', *) public let message = "Hello"' >>%t.dir/NewModule.swift +// RUN: %target-swiftc -module-name NewModule -emit-module -emit-library -o %t.dir/libNewModule%target-shared-library-suffix %t.dir/NewModule.swift + +// RUN: %lldb --repl="-I%t.dir -L%t.dir -lNewModule" --repl-language swift < %s | FileCheck %s +import NewModule +message +// CHECK: $R0{{.*}}Hello From e161d5c2891525d19129a36fb661beac4fcbd669 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 9 Oct 2020 17:19:54 -0700 Subject: [PATCH 132/234] Refactor LookupClangType to take a module holder rather than a module. This allows look up types in an entire expression context in addition to looking types up in just one lldb::Module. --- .../TypeSystem/Swift/SwiftASTContext.h | 2 + .../TypeSystem/Swift/TypeSystemSwift.h | 2 + .../Swift/TypeSystemSwiftTypeRef.cpp | 110 +++++++++++------- .../TypeSystem/Swift/TypeSystemSwiftTypeRef.h | 3 +- ...ftLanguageRuntimeDynamicTypeResolution.cpp | 8 +- lldb/source/Target/SwiftLanguageRuntimeImpl.h | 13 +-- 6 files changed, 81 insertions(+), 57 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h index 3da1fd61ab5a5..7fc0608c0beb6 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h @@ -175,6 +175,8 @@ class SwiftASTContext : public TypeSystemSwift { bool SupportsLanguage(lldb::LanguageType language) override; + SwiftASTContext *GetSwiftASTContext() override { return this; } + Status IsCompatible() override; swift::SourceManager &GetSourceManager(); diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h index 04b8235859c1c..adcba7e4984c7 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h @@ -27,6 +27,7 @@ class Decl; namespace lldb_private { class TypeSystemClang; +class SwiftASTContext; /// The implementation of lldb::Type's m_payload field for TypeSystemSwift. class TypePayloadSwift { @@ -97,6 +98,7 @@ class TypeSystemSwift : public TypeSystem { /// \} static LanguageSet GetSupportedLanguagesForTypes(); + virtual SwiftASTContext *GetSwiftASTContext() = 0; virtual Module *GetModule() const = 0; virtual lldb::TypeSP GetCachedType(ConstString mangled) = 0; virtual void SetCachedType(ConstString mangled, diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index d4ae5ed094eaa..ada639ed5ec89 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h" +#include "Plugins/TypeSystem/Swift/SwiftASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/TypeList.h" @@ -52,23 +53,39 @@ static ConstString GetTypeAlias(swift::Demangle::Demangler &dem, return ConstString(mangleNode(global)); } -/// Find a Clang type by name in module \p M. -static TypeSP LookupClangType(Module &M, StringRef name) { - llvm::SmallVector decl_context; - decl_context.push_back({CompilerContextKind::AnyModule, ConstString()}); - decl_context.push_back({CompilerContextKind::AnyType, ConstString(name)}); - llvm::DenseSet searched_symbol_files; - TypeMap clang_types; - M.FindTypes(decl_context, TypeSystemClang::GetSupportedLanguagesForTypes(), - searched_symbol_files, clang_types); - if (clang_types.Empty()) +/// Find a Clang type by name in the modules in \p module_holder. +static TypeSP LookupClangType(SwiftASTContext *module_holder, StringRef name) { + auto lookup = [](Module &M, StringRef name) -> TypeSP { + llvm::SmallVector decl_context; + decl_context.push_back({CompilerContextKind::AnyModule, ConstString()}); + decl_context.push_back({CompilerContextKind::AnyType, ConstString(name)}); + llvm::DenseSet searched_symbol_files; + TypeMap clang_types; + M.FindTypes(decl_context, TypeSystemClang::GetSupportedLanguagesForTypes(), + searched_symbol_files, clang_types); + if (clang_types.Empty()) + return {}; + return clang_types.GetTypeAtIndex(0); + }; + if (!module_holder) + return {}; + if (auto *M = module_holder->GetModule()) + return lookup(*M, name); + TargetSP target_sp = module_holder->GetTarget().lock(); + if (!target_sp) return {}; - return clang_types.GetTypeAtIndex(0); + TypeSP result; + target_sp->GetImages().ForEach([&](const ModuleSP &module) -> bool { + result = lookup(const_cast(*module), name); + return !result; + }); + return result; } /// Find a Clang type by name in module \p M. -CompilerType LookupClangForwardType(Module &M, StringRef name) { - if (TypeSP type = LookupClangType(M, name)) +static CompilerType LookupClangForwardType(SwiftASTContext *module_holder, + StringRef name) { + if (TypeSP type = LookupClangType(module_holder, name)) return type->GetForwardCompilerType(); return {}; } @@ -119,22 +136,28 @@ GetDemangledType(swift::Demangle::Demangler &dem, StringRef name) { /// __C module are resolved as Clang types. /// static std::pair -ResolveTypeAlias(lldb_private::Module *M, swift::Demangle::Demangler &dem, +ResolveTypeAlias(SwiftASTContext *module_holder, + swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node, bool prefer_clang_types = false) { // Try to look this up as a Swift type alias. For each *Swift* // type alias there is a debug info entry that has the mangled // name as name and the aliased type as a type. ConstString mangled = GetTypeAlias(dem, node); - if (!M) { - LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), - "No module. Couldn't resolve type alias %s", mangled.AsCString()); - return {{}, {}}; - } TypeList types; if (!prefer_clang_types) { - llvm::DenseSet searched_symbol_files; - M->FindTypes({mangled}, false, 1, searched_symbol_files, types); + llvm::DenseSet searched_symbol_files; + if (auto *M = module_holder->GetModule()) + M->FindTypes({mangled}, false, 1, searched_symbol_files, types); + else if (TargetSP target_sp = module_holder->GetTarget().lock()) + target_sp->GetImages().FindTypes(nullptr, {mangled}, + false, 1, searched_symbol_files, types); + else { + LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), + "No module. Couldn't resolve type alias %s", + mangled.AsCString()); + return {{}, {}}; + } } if (prefer_clang_types || types.Empty()) { // No Swift type found -- this could be a Clang typedef. This @@ -146,7 +169,7 @@ ResolveTypeAlias(lldb_private::Module *M, swift::Demangle::Demangler &dem, node->getChild(1)->hasText()) { // Resolve the typedef within the Clang debug info. auto clang_type = - LookupClangForwardType(*M, node->getChild(1)->getText()); + LookupClangForwardType(module_holder, node->getChild(1)->getText()); if (!clang_type) return {{}, {}}; return {{}, clang_type.GetCanonicalType()}; @@ -214,7 +237,8 @@ swift::Demangle::NodePointer TypeSystemSwiftTypeRef::Transform( /// Iteratively resolve all type aliases in \p node by looking up their /// desugared types in the debug info of module \p M. static swift::Demangle::NodePointer -GetCanonicalNode(lldb_private::Module *M, swift::Demangle::Demangler &dem, +GetCanonicalNode(SwiftASTContext *module_holder, + swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node) { using namespace swift::Demangle; return TypeSystemSwiftTypeRef::Transform(dem, node, [&](NodePointer node) { @@ -317,7 +341,7 @@ GetCanonicalNode(lldb_private::Module *M, swift::Demangle::Demangler &dem, case Node::Kind::BoundGenericTypeAlias: case Node::Kind::TypeAlias: { - auto node_clangtype = ResolveTypeAlias(M, dem, node); + auto node_clangtype = ResolveTypeAlias(module_holder, dem, node); if (CompilerType clang_type = node_clangtype.second) return GetClangTypeNode(clang_type, dem); if (node_clangtype.first) @@ -334,10 +358,10 @@ GetCanonicalNode(lldb_private::Module *M, swift::Demangle::Demangler &dem, /// Return the demangle tree representation of this type's canonical /// (type aliases resolved) type. swift::Demangle::NodePointer TypeSystemSwiftTypeRef::GetCanonicalDemangleTree( - lldb_private::Module *Module, swift::Demangle::Demangler &dem, + SwiftASTContext *module_holder, swift::Demangle::Demangler &dem, StringRef mangled_name) { NodePointer node = dem.demangleSymbol(mangled_name); - NodePointer canonical = GetCanonicalNode(Module, dem, node); + NodePointer canonical = GetCanonicalNode(module_holder, dem, node); return canonical; } @@ -504,7 +528,7 @@ TypeSystemSwiftTypeRef::GetSwiftified(swift::Demangle::Demangler &dem, // This is an imported Objective-C type; look it up in the // debug info. - TypeSP clang_type = LookupClangType(*Module, ident); + TypeSP clang_type = LookupClangType(m_swift_ast_context, ident); if (!clang_type) return node; @@ -680,7 +704,8 @@ swift::Demangle::NodePointer TypeSystemSwiftTypeRef::GetDemangleTreeForPrinting( /// determine whether a node is generic or not, it needs to visit all /// nodes. The \p generic_walk argument specifies that the primary /// attributes have been collected and that we only look for generics. -static uint32_t collectTypeInfo(Module *M, swift::Demangle::Demangler &dem, +static uint32_t collectTypeInfo(SwiftASTContext *module_holder, + swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node, bool generic_walk = false) { if (!node) @@ -724,6 +749,7 @@ static uint32_t collectTypeInfo(Module *M, swift::Demangle::Demangler &dem, } else switch (node->getKind()) { + case Node::Kind::SugaredOptional: swift_flags |= eTypeIsGeneric | eTypeIsBound | eTypeHasChildren | eTypeHasValue | eTypeIsEnumeration; @@ -793,7 +819,8 @@ static uint32_t collectTypeInfo(Module *M, swift::Demangle::Demangler &dem, if (node->getNumChildren() != 2) break; // Bug-for-bug compatibility. - if (!(collectTypeInfo(M, dem, node->getChild(1)) & eTypeIsGenericTypeParam)) + if (!(collectTypeInfo(module_holder, dem, node->getChild(1)) & + eTypeIsGenericTypeParam)) swift_flags |= eTypeHasValue | eTypeHasChildren; auto module = node->getChild(0); if (module->hasText() && @@ -827,10 +854,9 @@ static uint32_t collectTypeInfo(Module *M, swift::Demangle::Demangler &dem, if (ident->getKind() != Node::Kind::Identifier || !ident->hasText()) break; - if (!M) - break; // Look up the Clang type in DWARF. - CompilerType clang_type = LookupClangForwardType(*M, ident->getText()); + CompilerType clang_type = + LookupClangForwardType(module_holder, ident->getText()); collect_clang_type(clang_type.GetCanonicalType()); return swift_flags; } @@ -879,12 +905,14 @@ static uint32_t collectTypeInfo(Module *M, swift::Demangle::Demangler &dem, case Node::Kind::TypeAlias: { // Bug-for-bug compatibility. // swift_flags |= eTypeIsTypedef; - auto node_clangtype = ResolveTypeAlias(M, dem, node); + auto node_clangtype = + ResolveTypeAlias(module_holder, dem, node); if (CompilerType clang_type = node_clangtype.second) { collect_clang_type(clang_type); return swift_flags; } - swift_flags |= collectTypeInfo(M, dem, node_clangtype.first, generic_walk); + swift_flags |= collectTypeInfo(module_holder, dem, node_clangtype.first, + generic_walk); return swift_flags; } default: @@ -897,7 +925,7 @@ static uint32_t collectTypeInfo(Module *M, swift::Demangle::Demangler &dem, // Visit the child nodes. for (unsigned i = 0; i < node->getNumChildren(); ++i) - swift_flags |= collectTypeInfo(M, dem, node->getChild(i), generic_walk); + swift_flags |= collectTypeInfo(module_holder, dem, node->getChild(i), generic_walk); return swift_flags; } @@ -1276,8 +1304,8 @@ TypeSystemSwiftTypeRef::RemangleAsType(swift::Demangle::Demangler &dem, swift::Demangle::NodePointer TypeSystemSwiftTypeRef::DemangleCanonicalType( swift::Demangle::Demangler &dem, opaque_compiler_type_t opaque_type) { using namespace swift::Demangle; - NodePointer node = - GetCanonicalDemangleTree(GetModule(), dem, AsMangledName(opaque_type)); + NodePointer node = GetCanonicalDemangleTree(m_swift_ast_context, dem, + AsMangledName(opaque_type)); return GetType(node); } @@ -1538,7 +1566,7 @@ uint32_t TypeSystemSwiftTypeRef::GetTypeInfo( using namespace swift::Demangle; Demangler dem; NodePointer node = dem.demangleSymbol(AsMangledName(type)); - return collectTypeInfo(GetModule(), dem, node); + return collectTypeInfo(m_swift_ast_context, dem, node); }; VALIDATE_AND_RETURN(impl, GetTypeInfo, type, (ReconstructType(type), nullptr)); @@ -1593,7 +1621,7 @@ TypeSystemSwiftTypeRef::GetCanonicalType(opaque_compiler_type_t type) { using namespace swift::Demangle; Demangler dem; NodePointer canonical = - GetCanonicalDemangleTree(GetModule(), dem, AsMangledName(type)); + GetCanonicalDemangleTree(m_swift_ast_context, dem, AsMangledName(type)); ConstString mangled(mangleNode(canonical)); return GetTypeFromMangledTypename(mangled); }; @@ -1831,7 +1859,7 @@ CompilerType TypeSystemSwiftTypeRef::GetAsClangTypeOrNull( node->getNumChildren() == 2 && node->getChild(0)->hasText() && node->getChild(0)->getText() == swift::MANGLING_MODULE_OBJC && node->getChild(1)->hasText()) { - auto node_clangtype = ResolveTypeAlias(GetModule(), dem, node, + auto node_clangtype = ResolveTypeAlias(m_swift_ast_context, dem, node, /*prefer_clang_types*/ true); if (node_clangtype.second) return node_clangtype.second; @@ -1853,7 +1881,7 @@ bool TypeSystemSwiftTypeRef::IsImportedType(opaque_compiler_type_t type, if (ident.empty()) return {}; if (original_type && GetModule()) - if (TypeSP clang_type = LookupClangType(*GetModule(), ident)) + if (TypeSP clang_type = LookupClangType(m_swift_ast_context, ident)) *original_type = clang_type->GetForwardCompilerType(); return true; }; diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h index 2c96379bdea72..aa1fc235b9701 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h @@ -49,6 +49,7 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { /// \} TypeSystemSwiftTypeRef(SwiftASTContext *swift_ast_context); + SwiftASTContext *GetSwiftASTContext() override { return m_swift_ast_context; } Module *GetModule() const override; swift::CanType GetCanonicalSwiftType(CompilerType compiler_type); @@ -268,7 +269,7 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { /// Return the canonicalized Demangle tree for a Swift mangled type name. static swift::Demangle::NodePointer - GetCanonicalDemangleTree(lldb_private::Module *Module, + GetCanonicalDemangleTree(SwiftASTContext *module_holder, swift::Demangle::Demangler &dem, llvm::StringRef mangled_name); diff --git a/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp index 27c008c86be7a..a30099ad4c1f3 100644 --- a/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -2106,7 +2106,8 @@ lldb::addr_t SwiftLanguageRuntime::FixupAddress(lldb::addr_t addr, } const swift::reflection::TypeRef * -SwiftLanguageRuntimeImpl::GetTypeRef(CompilerType type, Module *module) { +SwiftLanguageRuntimeImpl::GetTypeRef(CompilerType type, + SwiftASTContext *module_holder) { // Demangle the mangled name. swift::Demangle::Demangler dem; ConstString mangled_name = type.GetMangledTypeName(); @@ -2115,7 +2116,8 @@ SwiftLanguageRuntimeImpl::GetTypeRef(CompilerType type, Module *module) { return nullptr; swift::Demangle::NodePointer node = TypeSystemSwiftTypeRef::GetCanonicalDemangleTree( - module ? module : ts->GetModule(), dem, mangled_name.GetStringRef()); + module_holder ? module_holder : ts->GetSwiftASTContext(), dem, + mangled_name.GetStringRef()); if (!node) return nullptr; @@ -2158,7 +2160,7 @@ SwiftLanguageRuntimeImpl::GetTypeInfo(CompilerType type, // context, but we need to resolve (any DWARF links in) the typeref // in the original module. const swift::reflection::TypeRef *type_ref = - GetTypeRef(type, ts->GetModule()); + GetTypeRef(type, ts->GetSwiftASTContext()); if (!type_ref) return nullptr; diff --git a/lldb/source/Target/SwiftLanguageRuntimeImpl.h b/lldb/source/Target/SwiftLanguageRuntimeImpl.h index babab68b1891d..bb8f894bbcd6c 100644 --- a/lldb/source/Target/SwiftLanguageRuntimeImpl.h +++ b/lldb/source/Target/SwiftLanguageRuntimeImpl.h @@ -148,19 +148,8 @@ class SwiftLanguageRuntimeImpl { protected: /// Use the reflection context to build a TypeRef object. - /// - /// \param module can be used to specify a module to look up DWARF - /// type references (such as type aliases and Clang types) - /// in. Module only needs to be specified when it is different from - /// \c type.GetTypeSystem().GetModule(). The only situation where it - /// is necessary to specify the module explicitly is if a type has - /// been imported into the scratch context. This is always the - /// module of the outermost type. Even for bound generic types, - /// we're only interested in the module the bound generic type came - /// from, the bound generic parameters can be resolved from their - /// type metadata alone. const swift::reflection::TypeRef *GetTypeRef(CompilerType type, - Module *module = nullptr); + SwiftASTContext *module_holder); /// If \p instance points to a Swift object, retrieve its /// RecordTypeInfo pass it to the callback \p fn. Repeat the process From cc23662f828db68909dde24ec8b486726ff1e512 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 28 Aug 2020 11:41:47 -0700 Subject: [PATCH 133/234] [lldb] Fix typo in disassemble_options_line description (cherry picked from commit cdc18163cd1449c3a1c20e65a4d95a35ba3f6c23) --- lldb/source/Commands/Options.td | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 1a23436f9fdf5..410b852a85a1f 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -202,8 +202,8 @@ let Command = "breakpoint set" in { Desc<"Move breakpoints to nearest code. If not set the " "target.move-to-nearest-codesetting is used.">; def breakpoint_set_file_colon_line : Option<"joint-specifier", "y">, Group<12>, Arg<"FileLineColumn">, - Required, Completion<"SourceFile">, - Desc<"A specifier in the form filename:line[:column] for setting file & line breakpoints.">; + Required, Completion<"SourceFile">, + Desc<"A specifier in the form filename:line[:column] for setting file & line breakpoints.">; /* Don't add this option till it actually does something useful... def breakpoint_set_exception_typename : Option<"exception-typename", "O">, Arg<"TypeName">, Desc<"The breakpoint will only stop if an " @@ -327,7 +327,7 @@ let Command = "disassemble" in { def disassemble_options_pc : Option<"pc", "p">, Group<5>, Desc<"Disassemble around the current pc.">; def disassemble_options_line : Option<"line", "l">, Group<6>, - Desc<"Disassemble the current frame's current source line instructions if" + Desc<"Disassemble the current frame's current source line instructions if " "there is debug line table information, else disassemble around the pc.">; def disassemble_options_address : Option<"address", "a">, Group<7>, Arg<"AddressOrExpression">, @@ -762,7 +762,7 @@ let Command = "source list" in { def source_list_reverse : Option<"reverse", "r">, Group<4>, Desc<"Reverse the" " listing to look backwards from the last displayed block of source.">; def source_list_file_colon_line : Option<"joint-specifier", "y">, Group<5>, - Arg<"FileLineColumn">, Completion<"SourceFile">, + Arg<"FileLineColumn">, Completion<"SourceFile">, Desc<"A specifier in the form filename:line[:column] from which to display" " source.">; } From eaceb46661c6833f11fa98659223652f6d549f4a Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 9 Oct 2020 17:47:43 -0700 Subject: [PATCH 134/234] Use the dynamic type of self in the expression evaluator. This allows LLDB to resolve generic self types even if no type parameters are present (for example, because they were optimized out) because class objects and other entities carry all their dynamic type information in the *object*. rdar://problem/69020595 --- lldb/include/lldb/Symbol/Type.h | 1 + lldb/include/lldb/Symbol/Variable.h | 2 + .../Swift/SwiftASTManipulator.cpp | 6 +- .../Swift/SwiftExpressionParser.cpp | 87 ++++++++++++------- .../Swift/TypeSystemSwiftTypeRef.cpp | 58 ++++++++++++- ...ftLanguageRuntimeDynamicTypeResolution.cpp | 3 + .../API/lang/swift/generic_class/Makefile | 4 + .../generic_class/TestSwiftGenericClass.py | 21 +++++ .../API/lang/swift/generic_class/main.swift | 25 ++++++ 9 files changed, 167 insertions(+), 40 deletions(-) create mode 100644 lldb/test/API/lang/swift/generic_class/Makefile create mode 100644 lldb/test/API/lang/swift/generic_class/TestSwiftGenericClass.py create mode 100644 lldb/test/API/lang/swift/generic_class/main.swift diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h index b9cebaeb51a05..fbe77c28a1433 100644 --- a/lldb/include/lldb/Symbol/Type.h +++ b/lldb/include/lldb/Symbol/Type.h @@ -56,6 +56,7 @@ class SymbolFileType : public std::enable_shared_from_this, Type *operator->() { return GetType(); } Type *GetType(); + SymbolFile &GetSymbolFile() const { return m_symbol_file; } protected: SymbolFile &m_symbol_file; diff --git a/lldb/include/lldb/Symbol/Variable.h b/lldb/include/lldb/Symbol/Variable.h index 44618fe01a23b..f9d6e84cd8704 100644 --- a/lldb/include/lldb/Symbol/Variable.h +++ b/lldb/include/lldb/Symbol/Variable.h @@ -65,6 +65,8 @@ class Variable : public UserID, public std::enable_shared_from_this { lldb::ValueType GetScope() const { return m_scope; } + const RangeList &GetScopeRange() const { return m_scope_range; } + bool IsExternal() const { return m_external; } bool IsArtificial() const { return m_artificial; } diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.cpp index f6411a641a974..7b733d6cfec04 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.cpp @@ -15,6 +15,7 @@ #include "Plugins/TypeSystem/Swift/SwiftASTContext.h" #include "lldb/Expression/ExpressionParser.h" #include "lldb/Expression/ExpressionSourceCode.h" +#include "lldb/Target/SwiftLanguageRuntime.h" #include "lldb/Target/Target.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" @@ -1021,11 +1022,6 @@ GetPatternBindingForVarDecl(swift::VarDecl *var_decl, return pattern_binding; } -static inline swift::Type GetSwiftType(CompilerType type) { - return swift::Type( - reinterpret_cast(type.GetOpaqueQualType())); -} - bool SwiftASTManipulator::AddExternalVariables( llvm::MutableArrayRef variables) { if (!IsValid()) diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp index a9c0538ece804..11a580468d8ab 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp @@ -479,7 +479,7 @@ AddRequiredAliases(Block *block, lldb::StackFrameSP &stack_frame_sp, if (stack_frame_sp) { lldb::ValueObjectSP valobj_sp = stack_frame_sp->GetValueObjectForFrameVariable(self_var_sp, - lldb::eNoDynamicValues); + lldb::eDynamicCanRunTarget); if (valobj_sp) self_type = valobj_sp->GetCompilerType(); @@ -604,7 +604,7 @@ static void AddVariableInfo( if (stack_frame_sp) { lldb::ValueObjectSP valobj_sp = stack_frame_sp->GetValueObjectForFrameVariable(variable_sp, - lldb::eNoDynamicValues); + lldb::eDynamicCanRunTarget); if (!valobj_sp || valobj_sp->GetError().Fail()) { // Ignore the variable if we couldn't find its corresponding @@ -628,12 +628,6 @@ static void AddVariableInfo( if (!target_type.IsValid()) return; - // Resolve all archetypes in the variable type. - if (stack_frame_sp) - if (language_runtime) - target_type = language_runtime->BindGenericTypeParameters(*stack_frame_sp, - target_type); - // If we couldn't fully realize the type, then we aren't going // to get very far making a local out of it, so discard it here. Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TYPES | @@ -642,7 +636,7 @@ static void AddVariableInfo( if (log) log->Printf("Discarding local %s because we couldn't fully realize it, " "our best attempt was: %s.", - name_cstr, target_type.GetTypeName().AsCString("")); + name_cstr, target_type.GetDisplayTypeName().AsCString("")); return; } @@ -656,8 +650,27 @@ static void AddVariableInfo( static_cast(swift_type.getPointer()), static_cast(ast_context.GetASTContext()), s.c_str()); } + // A one-off clone of variable_sp with the type replaced by target_type. + auto patched_variable_sp = std::make_shared( + 0, variable_sp->GetName().GetCString(), "", + std::make_shared( + *variable_sp->GetType()->GetSymbolFile(), + std::make_shared( + 0, variable_sp->GetType()->GetSymbolFile(), + variable_sp->GetType()->GetName(), llvm::None, + variable_sp->GetType()->GetSymbolContextScope(), LLDB_INVALID_UID, + Type::eEncodingIsUID, variable_sp->GetType()->GetDeclaration(), + target_type, lldb_private::Type::ResolveState::Full, + variable_sp->GetType()->GetPayload())), + variable_sp->GetScope(), variable_sp->GetSymbolContextScope(), + variable_sp->GetScopeRange(), + const_cast(&variable_sp->GetDeclaration()), + variable_sp->LocationExpression(), variable_sp->IsExternal(), + variable_sp->IsArtificial(), + variable_sp->GetLocationIsConstantValueData(), + variable_sp->IsStaticMember(), variable_sp->IsConstant()); SwiftASTManipulatorBase::VariableMetadataSP metadata_sp( - new VariableMetadataVariable(variable_sp)); + new VariableMetadataVariable(patched_variable_sp)); SwiftASTManipulator::VariableInfo variable_info( target_type, ast_context.GetASTContext()->getIdentifier(overridden_name), metadata_sp, @@ -917,6 +930,23 @@ CreateMainFile(SwiftASTContextForExpressions &swift_ast_context, return {buffer_id, filename.str()}; } +/// Determine whether this type was defined inside an LLDB expression. +template bool FromLLDBModuleImpl(TypeType *type) { + if (auto *decl = type->getDecl()) + if (auto *module = decl->getModuleContext()) + return module->getName().str().startswith("__lldb_expr_"); + return false; +}; + +/// Determine whether this type was defined inside an LLDB expression. +static bool FromLLDBModule(swift::TypeBase *type) { + if (auto *type_alias = llvm::dyn_cast(type)) + return FromLLDBModuleImpl(type_alias); + if (auto *nominal = llvm::dyn_cast(type)) + return FromLLDBModuleImpl(nominal); + return false; +} + /// Attempt to materialize one variable. static llvm::Optional MaterializeVariable(SwiftASTManipulatorBase::VariableInfo &variable, @@ -954,23 +984,7 @@ MaterializeVariable(SwiftASTManipulatorBase::VariableInfo &variable, } } } else { - CompilerType actual_type(variable.GetType()); - auto orig_swift_type = GetSwiftType(actual_type); - auto *swift_type = orig_swift_type->mapTypeOutOfContext().getPointer(); - actual_type = ToCompilerType(swift_type); - lldb::StackFrameSP stack_frame_sp = stack_frame_wp.lock(); - if (swift_type->hasTypeParameter()) { - if (stack_frame_sp && stack_frame_sp->GetThread() && - stack_frame_sp->GetThread()->GetProcess()) { - auto *swift_runtime = SwiftLanguageRuntime::Get( - stack_frame_sp->GetThread()->GetProcess()); - if (swift_runtime) { - actual_type = swift_runtime->BindGenericTypeParameters( - *stack_frame_sp, actual_type); - } - } - } - + CompilerType actual_type = variable.GetType(); // Desugar '$lldb_context', etc. auto transformed_type = GetSwiftType(actual_type).transform( [](swift::Type t) -> swift::Type { @@ -981,7 +995,21 @@ MaterializeVariable(SwiftASTManipulatorBase::VariableInfo &variable, } return t; }); - actual_type = ToCompilerType(transformed_type.getPointer()); + actual_type = + ToCompilerType(transformed_type->mapTypeOutOfContext().getPointer()); + // CompilerType return_ast_type = + // ToCompilerType(result_type->mapTypeOutOfContext()); + auto *swift_ast_ctx = + llvm::cast(actual_type.GetTypeSystem()); + + // Currently the Swift runtime cannot resolve types that were + // defined in the expression evaluator. That's because we don't + // tell it about type metadata sections that were JIT-compiled + // by the expression evaluator. Until that is implemented, fall + // back to SwiftASTContext. + if (!FromLLDBModule(transformed_type.getPointer())) + actual_type = + swift_ast_ctx->GetTypeRefType(actual_type.GetOpaqueQualType()); if (is_result) offset = materializer.AddResultVariable( @@ -1009,9 +1037,6 @@ MaterializeVariable(SwiftASTManipulatorBase::VariableInfo &variable, VariableMetadataVariable *variable_metadata = static_cast(variable.m_metadata.get()); - // FIXME: It would be nice if we could do something like - // variable_metadata->m_variable_sp->SetType(variable.GetType()) - // here. offset = materializer.AddVariable(variable_metadata->m_variable_sp, error); if (!error.Success()) { diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index ada639ed5ec89..bbb5f33cafccd 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1250,6 +1250,19 @@ bool Equivalent>(llvm::Optional l, return false; } +/// Version taylored to GetTypeBitAlign. +template <> +bool Equivalent>(llvm::Optional l, + llvm::Optional r) { + if (l == r) + return true; + // Assume that any value is "better" than none. + if (l.hasValue() && !r.hasValue()) + return true; + llvm::dbgs() << l << " != " << r << "\n"; + return false; +} + } // namespace #endif @@ -1615,6 +1628,22 @@ TypeSystemSwiftTypeRef::GetArrayElementType(opaque_compiler_type_t type, VALIDATE_AND_RETURN(impl, GetArrayElementType, type, (ReconstructType(type), nullptr, exe_scope)); } + +/// Determine wether this demangle tree contains an unresolved type alias. +static bool ContainsUnresolvedTypeAlias(swift::Demangle::NodePointer node) { + if (!node) + return false; + + if (node->getKind() == swift::Demangle::Node::Kind::TypeAlias) + return true; + + for (swift::Demangle::NodePointer child : *node) + if (ContainsUnresolvedTypeAlias(child)) + return true; + + return false; +} + CompilerType TypeSystemSwiftTypeRef::GetCanonicalType(opaque_compiler_type_t type) { auto impl = [&]() { @@ -1622,6 +1651,12 @@ TypeSystemSwiftTypeRef::GetCanonicalType(opaque_compiler_type_t type) { Demangler dem; NodePointer canonical = GetCanonicalDemangleTree(m_swift_ast_context, dem, AsMangledName(type)); + if (ContainsUnresolvedTypeAlias(canonical)) { + // If this is a typealias defined in the expression evaluator, + // then we don't have debug info to resolve it from. + CompilerType ast_type = ReconstructType({this, type}).GetCanonicalType(); + return GetTypeFromMangledTypename(ast_type.GetMangledTypeName()); + } ConstString mangled(mangleNode(canonical)); return GetTypeFromMangledTypename(mangled); }; @@ -1750,9 +1785,17 @@ TypeSystemSwiftTypeRef::GetBitSize(opaque_compiler_type_t type, AsMangledName(type)); return {}; } + // The hot code path is to ask the Swift runtime for the size. if (auto *runtime = - SwiftLanguageRuntime::Get(exe_scope->CalculateProcess())) - return runtime->GetBitSize({this, type}, exe_scope); + SwiftLanguageRuntime::Get(exe_scope->CalculateProcess())) { + if (auto result = runtime->GetBitSize({this, type}, exe_scope)) + return result; + // If this is an expression context, perhaps the type was + // defined in the expression. In that case we don't have debug + // info for it, so defer to SwiftASTContext. + if (llvm::isa(m_swift_ast_context)) + return ReconstructType({this, type}).GetBitSize(exe_scope); + } // If there is no process, we can still try to get the static size // information out of DWARF. Because it is stored in the Type @@ -2078,8 +2121,15 @@ TypeSystemSwiftTypeRef::GetTypeBitAlign(opaque_compiler_type_t type, return {}; } if (auto *runtime = - SwiftLanguageRuntime::Get(exe_scope->CalculateProcess())) - return runtime->GetBitAlignment({this, type}, exe_scope); + SwiftLanguageRuntime::Get(exe_scope->CalculateProcess())) { + if (auto result = runtime->GetBitAlignment({this, type}, exe_scope)) + return result; + // If this is an expression context, perhaps the type was + // defined in the expression. In that case we don't have debug + // info for it, so defer to SwiftASTContext. + if (llvm::isa(m_swift_ast_context)) + return ReconstructType({this, type}).GetTypeBitAlign(exe_scope); + } // If there is no process, we can still try to get the static // alignment information out of DWARF. Because it is stored in the diff --git a/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp index a30099ad4c1f3..a3445b3aa1836 100644 --- a/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -2141,6 +2141,9 @@ SwiftLanguageRuntimeImpl::GetTypeInfo(CompilerType type, if (!ts) return nullptr; + // Resolve all type aliases. + type = type.GetCanonicalType(); + // Resolve all generic type parameters in the type for the current // frame. Archetype binding has to happen in the scratch context, // so we lock it while we are in this function. diff --git a/lldb/test/API/lang/swift/generic_class/Makefile b/lldb/test/API/lang/swift/generic_class/Makefile new file mode 100644 index 0000000000000..6bae433ab956a --- /dev/null +++ b/lldb/test/API/lang/swift/generic_class/Makefile @@ -0,0 +1,4 @@ +SWIFT_SOURCES := main.swift +SWIFTFLAGS_EXTRAS := -O + +include Makefile.rules diff --git a/lldb/test/API/lang/swift/generic_class/TestSwiftGenericClass.py b/lldb/test/API/lang/swift/generic_class/TestSwiftGenericClass.py new file mode 100644 index 0000000000000..84e837ffb7338 --- /dev/null +++ b/lldb/test/API/lang/swift/generic_class/TestSwiftGenericClass.py @@ -0,0 +1,21 @@ +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil +import unittest2 + + +class SwiftGenericClassTest(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test(self): + """Tests that a generic class type can be resolved from the instance metadata alone""" + self.build() + (target, process, thread, breakpoint) = lldbutil.run_to_source_breakpoint(self, + "break here", lldb.SBFileSpec("main.swift")) + + self.expect("frame variable -d run self", + substrs=["a.F", "23", "42", "128", "256"]) + self.expect("expr -d run -- self", + substrs=["a.F", "23", "42", "128", "256"]) diff --git a/lldb/test/API/lang/swift/generic_class/main.swift b/lldb/test/API/lang/swift/generic_class/main.swift new file mode 100644 index 0000000000000..a50d00f1123a1 --- /dev/null +++ b/lldb/test/API/lang/swift/generic_class/main.swift @@ -0,0 +1,25 @@ +public class F { + let a : A + var b = 42 + var c = 128 + var d = 256 + public init(_ val : A) { a = val } +} + +protocol P { + func method() +} +extension F : P { + @inline(never) func method() { + print("break here \(b)") + } +} + +// Defeat type specialization. +@inline(never) func getF() -> P { + return F(23) +} + +let obj = getF() +obj.method() + From bfe698971c2fc2e04151b3bfa494ccdb1a3ad4af Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 17 Jul 2020 14:46:06 -0700 Subject: [PATCH 135/234] Sort the cases in GetTypeClass (NFC) (cherry picked from commit 63182b1454ea518bf0eab26fbe661d83eded4709) --- .../TypeSystem/Swift/SwiftASTContext.cpp | 52 +++++-------------- 1 file changed, 14 insertions(+), 38 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index 0816e12d0ce50..04ad1474cbe24 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -5580,18 +5580,11 @@ lldb::TypeClass SwiftASTContext::GetTypeClass(opaque_compiler_type_t type) { swift::CanType swift_can_type(GetCanonicalSwiftType(type)); const swift::TypeKind type_kind = swift_can_type->getKind(); switch (type_kind) { - case swift::TypeKind::Error: - return lldb::eTypeClassOther; case swift::TypeKind::BuiltinInteger: - return lldb::eTypeClassBuiltin; case swift::TypeKind::BuiltinFloat: - return lldb::eTypeClassBuiltin; case swift::TypeKind::BuiltinRawPointer: - return lldb::eTypeClassBuiltin; case swift::TypeKind::BuiltinNativeObject: - return lldb::eTypeClassBuiltin; case swift::TypeKind::BuiltinUnsafeValueBuffer: - return lldb::eTypeClassBuiltin; case swift::TypeKind::BuiltinBridgeObject: return lldb::eTypeClassBuiltin; case swift::TypeKind::BuiltinVector: @@ -5603,56 +5596,39 @@ lldb::TypeClass SwiftASTContext::GetTypeClass(opaque_compiler_type_t type) { case swift::TypeKind::WeakStorage: return ToCompilerType(swift_can_type->getReferenceStorageReferent()) .GetTypeClass(); - case swift::TypeKind::GenericTypeParam: - return lldb::eTypeClassOther; - case swift::TypeKind::DependentMember: - return lldb::eTypeClassOther; case swift::TypeKind::Enum: + case swift::TypeKind::BoundGenericEnum: return lldb::eTypeClassUnion; case swift::TypeKind::Struct: + case swift::TypeKind::BoundGenericStruct: return lldb::eTypeClassStruct; case swift::TypeKind::Class: + case swift::TypeKind::BoundGenericClass: return lldb::eTypeClassClass; + case swift::TypeKind::GenericTypeParam: + case swift::TypeKind::DependentMember: case swift::TypeKind::Protocol: - return lldb::eTypeClassOther; + case swift::TypeKind::ProtocolComposition: case swift::TypeKind::Metatype: - return lldb::eTypeClassOther; case swift::TypeKind::Module: - return lldb::eTypeClassOther; case swift::TypeKind::PrimaryArchetype: case swift::TypeKind::OpenedArchetype: case swift::TypeKind::NestedArchetype: - return lldb::eTypeClassOther; - case swift::TypeKind::Function: - return lldb::eTypeClassFunction; - case swift::TypeKind::GenericFunction: - return lldb::eTypeClassFunction; - case swift::TypeKind::ProtocolComposition: - return lldb::eTypeClassOther; - case swift::TypeKind::LValue: - return lldb::eTypeClassReference; case swift::TypeKind::UnboundGeneric: - return lldb::eTypeClassOther; - case swift::TypeKind::BoundGenericClass: - return lldb::eTypeClassClass; - case swift::TypeKind::BoundGenericEnum: - return lldb::eTypeClassUnion; - case swift::TypeKind::BoundGenericStruct: - return lldb::eTypeClassStruct; case swift::TypeKind::TypeVariable: - return lldb::eTypeClassOther; case swift::TypeKind::ExistentialMetatype: - return lldb::eTypeClassOther; - case swift::TypeKind::DynamicSelf: - return lldb::eTypeClassOther; case swift::TypeKind::SILBox: - return lldb::eTypeClassOther; - case swift::TypeKind::SILFunction: - return lldb::eTypeClassFunction; + case swift::TypeKind::DynamicSelf: case swift::TypeKind::SILBlockStorage: - return lldb::eTypeClassOther; case swift::TypeKind::Unresolved: + case swift::TypeKind::Error: return lldb::eTypeClassOther; + case swift::TypeKind::Function: + case swift::TypeKind::GenericFunction: + case swift::TypeKind::SILFunction: + return lldb::eTypeClassFunction; + case swift::TypeKind::LValue: + return lldb::eTypeClassReference; case swift::TypeKind::Optional: case swift::TypeKind::TypeAlias: From 4863244efddfaf49822880371f88e57cf5374a24 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Wed, 14 Oct 2020 14:58:16 -0700 Subject: [PATCH 136/234] Appease older compilers --- .../TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index bbb5f33cafccd..b0845aee8f40d 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1250,19 +1250,6 @@ bool Equivalent>(llvm::Optional l, return false; } -/// Version taylored to GetTypeBitAlign. -template <> -bool Equivalent>(llvm::Optional l, - llvm::Optional r) { - if (l == r) - return true; - // Assume that any value is "better" than none. - if (l.hasValue() && !r.hasValue()) - return true; - llvm::dbgs() << l << " != " << r << "\n"; - return false; -} - } // namespace #endif From 8a243daf2e002223d2882e85f324ca5f0a12a47d Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Wed, 14 Oct 2020 20:10:55 -0700 Subject: [PATCH 137/234] [dsymutil] Fix handling of aliases to private external symbols dsymutil was incorrectly ignoring aliases to private extern symbols in the MachODebugMapParser. This resulted in spurious warnings about not being able to find symbols. rdar://49652389 Differential revision: https://reviews.llvm.org/D89444 (cherry picked from commit f9fb9da36c34d2745b74dc30e6c26f7d3f48466c) --- .../dsymutil/ARM/private-extern-alias.test | 29 ++++++++++++++++++ .../Inputs/private/tmp/private_extern/main.o | Bin 0 -> 1904 bytes .../tmp/private_extern/private_extern.o | Bin 0 -> 2160 bytes .../tmp/private_extern/private_extern.out | Bin 0 -> 33536 bytes llvm/tools/dsymutil/MachODebugMapParser.cpp | 4 ++- 5 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 llvm/test/tools/dsymutil/ARM/private-extern-alias.test create mode 100644 llvm/test/tools/dsymutil/Inputs/private/tmp/private_extern/main.o create mode 100644 llvm/test/tools/dsymutil/Inputs/private/tmp/private_extern/private_extern.o create mode 100755 llvm/test/tools/dsymutil/Inputs/private/tmp/private_extern/private_extern.out diff --git a/llvm/test/tools/dsymutil/ARM/private-extern-alias.test b/llvm/test/tools/dsymutil/ARM/private-extern-alias.test new file mode 100644 index 0000000000000..99301febb15f5 --- /dev/null +++ b/llvm/test/tools/dsymutil/ARM/private-extern-alias.test @@ -0,0 +1,29 @@ +$ cat private_extern.c +__attribute__((visibility("hidden"))) +int* foo() { + int i = 10; + volatile int* j = &i; + return j; +} + +int* bar() { + return foo(); +} + +$ cat main.c +int* bar(); +int main() { + return *bar(); +} + +$ cat alias_list +_foo _baz + +$ xcrun --sdk iphoneos clang -g private_extern.c -c -o private_extern.o -target arm64-apple-ios14.0 +$ xcrun --sdk iphoneos clang -g main.c -c -o main.o -target arm64-apple-ios14.0 +$ xcrun --sdk iphoneos clang private_extern.o main.o -target arm64-apple-ios14.0 -o private_extern.out -Xlinker -alias_list -Xlinker alias_list + +RUN: dsymutil -oso-prepend-path %p/../Inputs %p/../Inputs/private/tmp/private_extern/private_extern.out -o %t.dSYM --verbose 2>&1 | FileCheck %s +CHECK-NOT: could not find object file symbol for symbol _baz +CHECK: { sym: _foo, objAddr: 0x0000000000000000, binAddr: 0x0000000100007F58, size: 0x00000020 } +CHECK: { sym: _baz, objAddr: 0x0000000000000000, binAddr: 0x0000000100007F58, size: 0x00000000 } diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/private_extern/main.o b/llvm/test/tools/dsymutil/Inputs/private/tmp/private_extern/main.o new file mode 100644 index 0000000000000000000000000000000000000000..d9cf74ee64403d5f7049e7b6038f52715d78a55d GIT binary patch literal 1904 zcmb7E%}>-&5Pzk+E3jDkFcCG;J)qGD+gKP*4%f=sd>z$mb?+qZtc9{P+m0QCl$yB1sN?;CO25PVV;g?IS+UFw67;UO*UgFYDuJM#;oX5brK4 zE-+tWc$>hF0qu!bacs9Di1&iwaBk-b**K7&Y*{*$47p4zP#eU1$#AYP+}B~Y*l_`V z9-gTzsCXoZ_l@ECef)JuJeQv(t3kX@_H-Zb6!a}1d-8K0T6?~4mYu%AKt>M4Q_V8) za->D$zGf69=~lk+`89?YW64#(!?ACMA!e-z@bl(R*9?j!!S{W}PWume&iJ+OgVzrj z-Jo8X04r24#(X!_g}~2($2bZ)4T^#_sK^sJGrq7oylg!tAL>iodVP$ny?J-`6;wVU zWOSpxlv{_rwYR+ViR<9b30+}cc(g2hUlH0*oEAE`PI$4VIKjneH!loFFGp{7U4`EU z-$Qs|BpOAgQ=rHm`stEuBiJ+@^dlxgK6}o!Jz!b;2*H3WZ=!9Q1k2aKghNEtWn(T@ zrFKO#jaafjo`@%67v?l)6m))3iNk#l>w2{;qUp12bAhT(95!PqC6!Xr$!sD$Fqke4 zB~t2uno(1O*=(jbkSWSTsiIOEOk^&SvaA_#m54d`_B2&?;87KERyB(>4xf)WW*QDP zoQjyIRjQj7wZ&;&c1osQu87+7ylK#>Lfm4hhEs+7G7;t{n%bZM_uD~%U0(`3BqHaT2j|9@nC}EHxD~kLbx3F-q{iT} bzsDN(aoG^U4?&S_BH;iL9j-Cy+64IrZ{+iW literal 0 HcmV?d00001 diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/private_extern/private_extern.o b/llvm/test/tools/dsymutil/Inputs/private/tmp/private_extern/private_extern.o new file mode 100644 index 0000000000000000000000000000000000000000..b7f1a6a8e8472cb517572cea3a73dd37af650148 GIT binary patch literal 2160 zcmb7F&2Jk;6o2dWI<6fyUr40lz#alBhuThUCvJ2TKIXmO&dhr= z`@^3%{~je$2*g7ce4t`5z@U@hEw=xIew1^0P6WmF2z2HGJ3*!yI+wyokL-(2Z(KaG zW346?#>+sz0T8jcEbYcIEKRfRw01U4tJMmeA=^tYFI;#g35juh>3Kq~FA0d?6Enth zy^csp<9#9{KbGJyb&S5k8*uA}+Pnq-{&%YR)8XZBKR;AyADCAUFMt0T`;-agQGH5N^>^OVf4`!S zKlHFZp-iF>nG&WZbH7|U*_>AObH($;m8qxjlBhMxBo6GSL>zWJMjNA*DWcpAsrr+} zBKA2_7aqEbZ%5n9ixV6rK6%`I`WejhTO`ED4?uFl1`Nf|AWg}<4PDLbkLqlx??)Dm zvz7f27G(_{K@WnJUXEw-oTYJat^ixhY9B!#VF%e=%iA=DPB3tN&zL<^s+20msZBR* zg12^BC3N1oZgj+xt!srHKj;n0?%I~`IWMl4`qFhr)cVruQNU~syBM@zr#K^Vl*3-Xe0(+3@qKDp z0l8jCE^X8D`oc0!DQQalU<9#GAvB1PL|?zQSNveGS8Tvu28*MH+yXO+fX4%O#%yr^sM?{HWvNY2k+u;9;#uN^;T6kX7Xq^+m4k-|6H#Hvq>b5$uHlhTk9Ld@5toPgvT5)&VWeu5}|CwXcNgCPUBsE^zcPbN2n$(_+f K$IObcLi7)Y5)&-| literal 0 HcmV?d00001 diff --git a/llvm/test/tools/dsymutil/Inputs/private/tmp/private_extern/private_extern.out b/llvm/test/tools/dsymutil/Inputs/private/tmp/private_extern/private_extern.out new file mode 100755 index 0000000000000000000000000000000000000000..fff5df162cf752aba4eb9361c0b9d6893e1d40da GIT binary patch literal 33536 zcmeI*O=uKn7zglYvk9~qj0Y(#YFtVTS|n?$pofU@BQ!xtqV*7@@Uoko;L>Cxn~mlJ zaq*LaPy#I?f;Yh&1WUEllP$gU*5*>`&0{=x@KUv~+5Z1C?~vIT(1XYS1JBMp@4R30 z+qu7g{`Y*j)huO*CS)6L(q>mI!#n!~*@tv)=-`*Vr+QBevb8b7!HrFCRGeoC>DINE!pKYrJ$NAB@GQHKF*1`U#qpPE&7g-_n{ zQ;q%~?&)LX5bAbZcU?653)gjQLo&EGW;1dNGPxegcZ&7sl|ka0vFy}jIXhO&XA3i9 z1=Ng9NbckO<*x_7`RTybpP#(=q5IygZ@)lW1{v9Lmi6KK(d*}$K10g}WE|V^{+#DJ zypypL1>3F1C+`v5&psrdMQgO;vq`P&5&QgVX0j5DcOB}&ev5f@M06s#ZeP{x16+6b znvMzyNI(J-kbndvAOQ(TKmrnwfCMBU0SQPz0uqpb1SB8<2}nQ!5|DrdBp?9^NI(J- zkbndvAOQ(TKmrnwfCMBU0SQPz0uqpb1SB8<2}nQ!5|DrdBp?9^NI(J-kbndvAOQ(T zKmrnwfCMBU0SQPz0uqpb1SB8<2}nQ!5|DrdBp?9^NI(J-kbndvAOQ(TKmrnwfCMBU z0SQPz0uqpb1SB8<2}t1m2-FYT;?i!L?@v`vJZrN@OKE%kG~M$W?eo8;-QTsj#|yQz z&Hr1k->A*~c9(7SOSV{>OD)vU=kf1be|d>#IOzOQZSLR#o`vIhX8UHp#pIP|p7X5x zJ-9M|^yjAYo@cDL;#BmF(aGqk3~EF(4nA+Pl(QB~yYbU5m<~p!DuFv4vf{W^js#4jJY+w6_?MI4L`Hy!Y`&UGgfeum8rbT z7fbw@+~~xFWh>)nvS-T0vpIZa!E_}km$KGaca2!wW3Aq+I#2jDIeEARF8-D&!Y=3@ H?$hjlf{gK> literal 0 HcmV?d00001 diff --git a/llvm/tools/dsymutil/MachODebugMapParser.cpp b/llvm/tools/dsymutil/MachODebugMapParser.cpp index 617b708561c42..3323a0514e324 100644 --- a/llvm/tools/dsymutil/MachODebugMapParser.cpp +++ b/llvm/tools/dsymutil/MachODebugMapParser.cpp @@ -562,7 +562,9 @@ void MachODebugMapParser::loadMainBinarySymbols( continue; } Section = *SectionOrErr; - if (Section == MainBinary.section_end() || Section->isText()) + if ((Section == MainBinary.section_end() || Section->isText()) && + !(SymType & + MachO::N_PEXT)) // Alias to non-external (was a private external) continue; uint64_t Addr = cantFail(Sym.getValue()); Expected NameOrErr = Sym.getName(); From 8fd632727edbab1ee4372faaed6bcb821f9c3e06 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 15 Oct 2020 10:10:11 +0200 Subject: [PATCH 138/234] [lldb] Add swiftTest decorator to TestSwiftGenericClass.py Otherwise this test will run in build configurations without the Swift plugin. --- lldb/test/API/lang/swift/generic_class/TestSwiftGenericClass.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/test/API/lang/swift/generic_class/TestSwiftGenericClass.py b/lldb/test/API/lang/swift/generic_class/TestSwiftGenericClass.py index 84e837ffb7338..ba46da2c49cf3 100644 --- a/lldb/test/API/lang/swift/generic_class/TestSwiftGenericClass.py +++ b/lldb/test/API/lang/swift/generic_class/TestSwiftGenericClass.py @@ -9,6 +9,7 @@ class SwiftGenericClassTest(TestBase): mydir = TestBase.compute_mydir(__file__) + @swiftTest def test(self): """Tests that a generic class type can be resolved from the instance metadata alone""" self.build() From 482aea0a9ec09a29886560707ac0c049c32eac5c Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 15 Oct 2020 14:18:53 +0200 Subject: [PATCH 139/234] [lldb] Add REQUIRES swift to Availability.test --- lldb/test/Shell/SwiftREPL/Availability.test | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/test/Shell/SwiftREPL/Availability.test b/lldb/test/Shell/SwiftREPL/Availability.test index 97af971ef2af3..a3e0e6d8be10f 100644 --- a/lldb/test/Shell/SwiftREPL/Availability.test +++ b/lldb/test/Shell/SwiftREPL/Availability.test @@ -1,6 +1,7 @@ // -*- mode: swift; -*- // Test that the REPL is launched with the current OS as availability target. // REQUIRES: system-darwin +// REQUIRES: swift // RUN: mkdir -p %t.dir // RUN: echo '@available(macOS '>%t.dir/NewModule.swift From d636cf18529927db189663ec034f848b1dda07f9 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 15 Oct 2020 16:08:13 +0200 Subject: [PATCH 140/234] [lldb][swift] Remove mydir calculation from lldbplaygroundrepl Calling compute_mydir on a path outside the test/API leads to bogus results and since commit fcb0d8163a4f3 will also trigger a sanity assert. Also this isn't an actual test but only the base test for actual tests, so the mydir value here should be anyway unused. --- lldb/packages/Python/lldbsuite/test/lldbplaygroundrepl.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/lldbplaygroundrepl.py b/lldb/packages/Python/lldbsuite/test/lldbplaygroundrepl.py index 74ed2bd0c8ccb..5f13d6352ef5d 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbplaygroundrepl.py +++ b/lldb/packages/Python/lldbsuite/test/lldbplaygroundrepl.py @@ -24,8 +24,6 @@ class PlaygroundREPLTest(TestBase): - mydir = TestBase.compute_mydir(__file__) - @decorators.skipUnlessDarwin @decorators.swiftTest @decorators.skipIf( From d74692ef08e0b018664ad9c7d30df51f0fe20092 Mon Sep 17 00:00:00 2001 From: shafik Date: Mon, 21 Sep 2020 14:55:33 -0700 Subject: [PATCH 141/234] [ASTImporter] Modifying ImportDeclContext(...) to ensure that we also handle the case when the FieldDecl is an ArrayType whose ElementType is a RecordDecl When we fixed ImportDeclContext(...) in D71378 to make sure we complete each FieldDecl of a RecordDecl when we are importing the definition we missed the case where a FeildDecl was an ArrayType whose ElementType is a record. This fix was motivated by a codegen crash during LLDB expression parsing. Since we were not importing the definition we were crashing during layout which required all the records be defined. Differential Revision: https://reviews.llvm.org/D86660 (cherry picked from commit 6807f244fa67bb75ef09fb3db54743b5b358a7fa) --- clang/lib/AST/ASTImporter.cpp | 26 ++++++++-- .../Makefile | 3 ++ .../TestImportDefinitionArrayType.py | 14 +++++ .../main.cpp | 52 +++++++++++++++++++ 4 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 lldb/test/API/commands/expression/codegen-crash-import-def-arraytype-element/Makefile create mode 100644 lldb/test/API/commands/expression/codegen-crash-import-def-arraytype-element/TestImportDefinitionArrayType.py create mode 100644 lldb/test/API/commands/expression/codegen-crash-import-def-arraytype-element/main.cpp diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index a0159388bbb5c..4a823659c4b55 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -1743,12 +1743,28 @@ ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) { Decl *ImportedDecl = *ImportedOrErr; FieldDecl *FieldTo = dyn_cast_or_null(ImportedDecl); if (FieldFrom && FieldTo) { - const RecordType *RecordFrom = FieldFrom->getType()->getAs(); - const RecordType *RecordTo = FieldTo->getType()->getAs(); - if (RecordFrom && RecordTo) { - RecordDecl *FromRecordDecl = RecordFrom->getDecl(); - RecordDecl *ToRecordDecl = RecordTo->getDecl(); + RecordDecl *FromRecordDecl = nullptr; + RecordDecl *ToRecordDecl = nullptr; + // If we have a field that is an ArrayType we need to check if the array + // element is a RecordDecl and if so we need to import the defintion. + if (FieldFrom->getType()->isArrayType()) { + // getBaseElementTypeUnsafe(...) handles multi-dimensonal arrays for us. + FromRecordDecl = FieldFrom->getType()->getBaseElementTypeUnsafe()->getAsRecordDecl(); + ToRecordDecl = FieldTo->getType()->getBaseElementTypeUnsafe()->getAsRecordDecl(); + } + + if (!FromRecordDecl || !ToRecordDecl) { + const RecordType *RecordFrom = + FieldFrom->getType()->getAs(); + const RecordType *RecordTo = FieldTo->getType()->getAs(); + + if (RecordFrom && RecordTo) { + FromRecordDecl = RecordFrom->getDecl(); + ToRecordDecl = RecordTo->getDecl(); + } + } + if (FromRecordDecl && ToRecordDecl) { if (FromRecordDecl->isCompleteDefinition() && !ToRecordDecl->isCompleteDefinition()) { Error Err = ImportDefinition(FromRecordDecl, ToRecordDecl); diff --git a/lldb/test/API/commands/expression/codegen-crash-import-def-arraytype-element/Makefile b/lldb/test/API/commands/expression/codegen-crash-import-def-arraytype-element/Makefile new file mode 100644 index 0000000000000..99998b20bcb05 --- /dev/null +++ b/lldb/test/API/commands/expression/codegen-crash-import-def-arraytype-element/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/commands/expression/codegen-crash-import-def-arraytype-element/TestImportDefinitionArrayType.py b/lldb/test/API/commands/expression/codegen-crash-import-def-arraytype-element/TestImportDefinitionArrayType.py new file mode 100644 index 0000000000000..a485b94a680dc --- /dev/null +++ b/lldb/test/API/commands/expression/codegen-crash-import-def-arraytype-element/TestImportDefinitionArrayType.py @@ -0,0 +1,14 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestImportDefinitionArrayType(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test(self): + self.build() + lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.cpp")) + + self.expect_expr("__private->o", result_type="char", result_value="'A'") diff --git a/lldb/test/API/commands/expression/codegen-crash-import-def-arraytype-element/main.cpp b/lldb/test/API/commands/expression/codegen-crash-import-def-arraytype-element/main.cpp new file mode 100644 index 0000000000000..99fc7b727cc80 --- /dev/null +++ b/lldb/test/API/commands/expression/codegen-crash-import-def-arraytype-element/main.cpp @@ -0,0 +1,52 @@ +// This is a reproducer for a crash during codegen. The base issue is when we +// Import the DeclContext we force FieldDecl that are RecordType to be defined +// since we need these to be defined in order to layout the class. +// This case involves an array member whose ElementType are records. In this +// case we need to check the ElementType of an ArrayType and if it is a record +// we need to import the definition. +struct A { + int x; +}; + +struct B { + // When we import the all the FieldDecl we need to check if we have an + // ArrayType and then check if the ElementType is a RecordDecl and if so + // import the defintion. Otherwise during codegen we will attempt to layout A + // but won't be able to. + A s1[2]; + A s2[2][2][3]; + char o; +}; + +class FB { +public: + union { + struct { + unsigned char *_s; + } t; + char *tt[1]; + } U; + + FB(B *p) : __private(p) {} + + // We import A but we don't import the definition. + void f(A **bounds) {} + + void init(); + +private: + B *__private; +}; + +void FB::init() { + return; // break here +} + +int main() { + B b; + FB fb(&b); + + b.o = 'A'; + + fb.init(); +} From ea50a44dc238885b9c75872b925268480fe3873a Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 16 Oct 2020 13:12:00 -0700 Subject: [PATCH 142/234] Resolve merge conflict. --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 1450205b17cae..9d0d0e3403449 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3511,11 +3511,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, var_sp = std::make_shared( die.GetID(), name, mangled, type_sp, scope, symbol_context_scope, scope_ranges, &decl, location, is_external, is_artificial, -<<<<<<< HEAD location_is_const_value_data, is_static_member, is_constant); -======= - location_is_const_value_data, is_static_member); ->>>>>>> refs/am/changes/feab006e953aa91c7cbf91b3eadec5acb027efb1_swift/main } else { // Not ready to parse this variable yet. It might be a global or static // variable that is in a function scope and the function in the symbol From d26ebfd0739597da03b2b630b562cfaf634e4937 Mon Sep 17 00:00:00 2001 From: Med Ismail Bennani Date: Wed, 14 Oct 2020 03:25:38 +0200 Subject: [PATCH 143/234] [lldb/Swift] Fix import attributes handing in expression evaluations Previously, when importing a Swift module it the REPL or a Playground, LLDB would only cache the module name and reload the module at every expression evaluation. Doing so means that, when LLDB transfers imports information from the original source file to the new one, it is doing it with low fidelity, because LLDB would not keep track of the import attributes used in the previous expression evaluations. Thanks to apple/swift#33935, we can now cache the whole `swift::AttributedImport>` instead of only storing the module name. This struct contains both the `ImportedModule` with the `ModuleDecl` but also the `ImportOptions` set containing all the possible import attributes (Exported / Testable / PrivateImport ...) of that import statement. Now, before compiling and evaluating a Swift expression, LLDB fetches all the attributed imports cached previously and add them to the `ImplicitImportInfo` object that is used to create the `ModuleDecl` of the evaluated expression. It allows for the `ImportOptions` to be propagated in the compiled expression. This should fix some irregularities between the debugger and the compiler regarding import statements. rdar://65319954 Signed-off-by: Med Ismail Bennani --- .../Swift/SwiftExpressionParser.cpp | 31 ++++++++---- .../Swift/SwiftPersistentExpressionState.h | 16 +++++-- .../Swift/SwiftUserExpression.cpp | 32 ++++++++++++- .../TypeSystem/Swift/SwiftASTContext.cpp | 48 ++++++++++++------- .../TypeSystem/Swift/SwiftASTContext.h | 15 +++--- lldb/source/Target/Target.cpp | 3 +- lldb/test/Shell/SwiftREPL/Inputs/Test.swift | 11 +++++ .../SwiftREPL/LookupWithAttributedImport.test | 24 ++++++++++ 8 files changed, 144 insertions(+), 36 deletions(-) create mode 100644 lldb/test/Shell/SwiftREPL/Inputs/Test.swift create mode 100644 lldb/test/Shell/SwiftREPL/LookupWithAttributedImport.test diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp index a9c0538ece804..22da77b06efda 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp @@ -55,17 +55,18 @@ #include "clang/Rewrite/Core/RewriteBuffer.h" #include "swift/AST/ASTContext.h" -#include "swift/AST/DiagnosticEngine.h" #include "swift/AST/DiagnosticConsumer.h" +#include "swift/AST/DiagnosticEngine.h" #include "swift/AST/IRGenOptions.h" #include "swift/AST/IRGenRequests.h" +#include "swift/AST/Import.h" #include "swift/AST/Module.h" #include "swift/AST/ModuleLoader.h" -#include "swift/Demangling/Demangle.h" +#include "swift/Basic/OptimizationMode.h" #include "swift/Basic/PrimarySpecificPaths.h" #include "swift/Basic/SourceManager.h" -#include "swift/Basic/OptimizationMode.h" #include "swift/ClangImporter/ClangImporter.h" +#include "swift/Demangling/Demangle.h" #include "swift/Frontend/Frontend.h" #include "swift/Parse/LocalContext.h" #include "swift/Parse/PersistentParserState.h" @@ -1137,6 +1138,7 @@ static llvm::Expected ParseAndImport( lldb::StackFrameWP &stack_frame_wp, SymbolContext &sc, ExecutionContextScope &exe_scope, const EvaluateExpressionOptions &options, bool repl, bool playground) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); auto should_disable_objc_runtime = [&]() { lldb::StackFrameSP this_frame_sp(stack_frame_wp.lock()); @@ -1162,7 +1164,20 @@ static llvm::Expected ParseAndImport( if (playground) { auto *persistent_state = sc.target_sp->GetSwiftPersistentExpressionState(exe_scope); - persistent_state->AddHandLoadedModule(ConstString("Swift")); + + Status error; + SourceModule module_info; + module_info.path.emplace_back("Swift"); + swift::ModuleDecl *module = + swift_ast_context->GetModule(module_info, error); + + if (error.Fail() || !module) { + LLDB_LOG(log, "couldn't load Swift Standard Library\n"); + return error.ToError(); + } + + persistent_state->AddHandLoadedModule(ConstString("Swift"), + swift::ImportedModule(module)); } std::string main_filename; @@ -1178,7 +1193,8 @@ static llvm::Expected ParseAndImport( // The Swift stdlib needs to be imported before the SwiftLanguageRuntime can // be used. Status implicit_import_error; - llvm::SmallVector additional_imports; + llvm::SmallVector, 16> + additional_imports; if (!SwiftASTContext::GetImplicitImports(*swift_ast_context, sc, exe_scope, stack_frame_wp, additional_imports, implicit_import_error)) { @@ -1188,9 +1204,8 @@ static llvm::Expected ParseAndImport( swift::ImplicitImportInfo importInfo; importInfo.StdlibKind = swift::ImplicitStdlibKind::Stdlib; - for (auto *module : additional_imports) - importInfo.AdditionalImports.emplace_back(swift::ImportedModule(module), - swift::ImportOptions()); + for (auto &attributed_import : additional_imports) + importInfo.AdditionalImports.emplace_back(attributed_import); auto module_id = ast_context->getIdentifier(expr_name_buf); auto &module = *swift::ModuleDecl::create(module_id, *ast_context, diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftPersistentExpressionState.h b/lldb/source/Plugins/ExpressionParser/Swift/SwiftPersistentExpressionState.h index 50ab4f6cd58a9..0bae676006eea 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftPersistentExpressionState.h +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftPersistentExpressionState.h @@ -15,10 +15,13 @@ #include "SwiftExpressionVariable.h" +#include "swift/AST/Import.h" +#include "swift/AST/Module.h" + #include "lldb/Core/SwiftForward.h" #include "lldb/Expression/ExpressionVariable.h" -#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include @@ -38,7 +41,9 @@ namespace lldb_private { /// 0-based counter for naming result variables. //---------------------------------------------------------------------- class SwiftPersistentExpressionState : public PersistentExpressionState { - typedef std::set HandLoadedModuleSet; + + typedef llvm::StringMap> + HandLoadedModuleSet; public: class SwiftDeclMap { @@ -114,8 +119,11 @@ class SwiftPersistentExpressionState : public PersistentExpressionState { // This just adds this module to the list of hand-loaded modules, it doesn't // actually load it. - void AddHandLoadedModule(ConstString module_name) { - m_hand_loaded_modules.insert(module_name); + void AddHandLoadedModule( + ConstString module_name, + swift::AttributedImport attributed_import) { + m_hand_loaded_modules.insert_or_assign(module_name.GetStringRef(), + attributed_import); } /// This returns the list of hand-loaded modules. diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftUserExpression.cpp index 78ad560531bdd..aa97390f3a4b0 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftUserExpression.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftUserExpression.cpp @@ -285,8 +285,38 @@ bool SwiftUserExpression::Parse(DiagnosticManager &diagnostic_manager, "couldn't start parsing (no target)"); return false; } + + StackFrame *frame = exe_ctx.GetFramePtr(); + if (!frame) { + LLDB_LOG(log, "no stack frame"); + return false; + } + + // Make sure the target's SwiftASTContext has been setup before doing any + // Swift name lookups. + llvm::Optional maybe_swift_ast_ctx = + target->GetScratchSwiftASTContext(err, *frame); + if (!maybe_swift_ast_ctx) { + LLDB_LOG(log, "no Swift AST Context"); + return false; + } + + SwiftASTContext *swift_ast_ctx = maybe_swift_ast_ctx->get(); + if (auto *persistent_state = GetPersistentState(target, exe_ctx)) { - persistent_state->AddHandLoadedModule(ConstString("Swift")); + + Status error; + SourceModule module_info; + module_info.path.emplace_back("Swift"); + swift::ModuleDecl *module = swift_ast_ctx->GetModule(module_info, error); + + if (error.Fail() || !module) { + LLDB_LOG(log, "couldn't load Swift Standard Library\n"); + return false; + } + + persistent_state->AddHandLoadedModule(ConstString("Swift"), + swift::ImportedModule(module)); m_result_delegate.RegisterPersistentState(persistent_state); m_error_delegate.RegisterPersistentState(persistent_state); } else { diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index f700462ab26c4..e07f66a1c8284 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -8284,7 +8284,9 @@ static swift::ModuleDecl *LoadOneModule(const SourceModule &module, bool SwiftASTContext::GetImplicitImports( SwiftASTContext &swift_ast_context, SymbolContext &sc, ExecutionContextScope &exe_scope, lldb::StackFrameWP &stack_frame_wp, - llvm::SmallVectorImpl &modules, Status &error) { + llvm::SmallVectorImpl> + &modules, + Status &error) { if (!GetCompileUnitImports(swift_ast_context, sc, stack_frame_wp, modules, error)) { return false; @@ -8294,15 +8296,28 @@ bool SwiftASTContext::GetImplicitImports( sc.target_sp->GetSwiftPersistentExpressionState(exe_scope); // Get the hand-loaded modules from the SwiftPersistentExpressionState. - for (ConstString name : persistent_expression_state->GetHandLoadedModules()) { + for (auto &module_pair : + persistent_expression_state->GetHandLoadedModules()) { + + auto &attributed_import = module_pair.second; + + // If the ImportedModule in the SwiftPersistentExpressionState has a + // non-null ModuleDecl, add it to the ImplicitImports list. + if (attributed_import.module.importedModule) { + modules.emplace_back(attributed_import); + continue; + } + + // Otherwise, try reloading the ModuleDecl using the module name. SourceModule module_info; - module_info.path.push_back(name); - auto *module = LoadOneModule(module_info, swift_ast_context, stack_frame_wp, - error); + module_info.path.emplace_back(module_pair.first()); + auto *module = + LoadOneModule(module_info, swift_ast_context, stack_frame_wp, error); if (!module) return false; - modules.push_back(module); + attributed_import.module = swift::ImportedModule(module); + modules.emplace_back(attributed_import); } return true; } @@ -8314,7 +8329,6 @@ bool SwiftASTContext::CacheUserImports(SwiftASTContext &swift_ast_context, swift::SourceFile &source_file, Status &error) { llvm::SmallString<1> m_description; - llvm::SmallVector parsed_imports; swift::ModuleDecl::ImportFilter import_filter { swift::ModuleDecl::ImportFilterKind::Exported, @@ -8324,13 +8338,12 @@ bool SwiftASTContext::CacheUserImports(SwiftASTContext &swift_ast_context, swift::ModuleDecl::ImportFilterKind::ShadowedByCrossImportOverlay }; - source_file.getImportedModules(parsed_imports, import_filter); - auto *persistent_expression_state = sc.target_sp->GetSwiftPersistentExpressionState(exe_scope); - for (auto module_pair : parsed_imports) { - swift::ModuleDecl *module = module_pair.importedModule; + for (const auto &attributed_import : source_file.getImports()) { + swift::ModuleDecl *module = attributed_import.module.importedModule; + if (module) { std::string module_name; GetNameFromModule(module, module_name); @@ -8346,7 +8359,8 @@ bool SwiftASTContext::CacheUserImports(SwiftASTContext &swift_ast_context, return false; // How do we tell we are in REPL or playground mode? - persistent_expression_state->AddHandLoadedModule(module_const_str); + persistent_expression_state->AddHandLoadedModule(module_const_str, + attributed_import); } } } @@ -8356,16 +8370,18 @@ bool SwiftASTContext::CacheUserImports(SwiftASTContext &swift_ast_context, bool SwiftASTContext::GetCompileUnitImports( SwiftASTContext &swift_ast_context, SymbolContext &sc, lldb::StackFrameWP &stack_frame_wp, - llvm::SmallVectorImpl &modules, Status &error) { + llvm::SmallVectorImpl> + &modules, + Status &error) { // Import the Swift standard library and its dependencies. SourceModule swift_module; - swift_module.path.push_back(ConstString("Swift")); + swift_module.path.emplace_back("Swift"); auto *stdlib = LoadOneModule(swift_module, swift_ast_context, stack_frame_wp, error); if (!stdlib) return false; - modules.push_back(stdlib); + modules.emplace_back(swift::ImportedModule(stdlib)); CompileUnit *compile_unit = sc.comp_unit; if (!compile_unit || compile_unit->GetLanguage() != lldb::eLanguageTypeSwift) @@ -8386,7 +8402,7 @@ bool SwiftASTContext::GetCompileUnitImports( if (!loaded_module) return false; - modules.push_back(loaded_module); + modules.emplace_back(swift::ImportedModule(loaded_module)); } return true; } diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h index 3da1fd61ab5a5..c0ae47d9ed310 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h @@ -750,7 +750,9 @@ class SwiftASTContext : public TypeSystemSwift { static bool GetImplicitImports( SwiftASTContext &swift_ast_context, SymbolContext &sc, ExecutionContextScope &exe_scope, lldb::StackFrameWP &stack_frame_wp, - llvm::SmallVectorImpl &modules, Status &error); + llvm::SmallVectorImpl> + &modules, + Status &error); /// Cache the user's imports from a SourceFile in a given execution scope such /// that they are carried over into future expression evaluations. @@ -761,11 +763,12 @@ class SwiftASTContext : public TypeSystemSwift { swift::SourceFile &source_file, Status &error); /// Retrieve the modules imported by the compilation unit. - static bool - GetCompileUnitImports(SwiftASTContext &swift_ast_context, SymbolContext &sc, - lldb::StackFrameWP &stack_frame_wp, - llvm::SmallVectorImpl &modules, - Status &error); + static bool GetCompileUnitImports( + SwiftASTContext &swift_ast_context, SymbolContext &sc, + lldb::StackFrameWP &stack_frame_wp, + llvm::SmallVectorImpl> + &modules, + Status &error); protected: /// This map uses the string value of ConstStrings as the key, and the diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 35be3572f0d9a..79cee33a78984 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -2504,7 +2504,8 @@ llvm::Optional Target::GetScratchSwiftASTContext( !swift_ast_ctx->HasFatalErrors()) { StackFrameWP frame_wp(frame_sp); SymbolContext sc = frame_sp->GetSymbolContext(lldb::eSymbolContextEverything); - llvm::SmallVector modules; + llvm::SmallVector, 16> + modules; swift_ast_ctx->GetCompileUnitImports(*swift_ast_ctx, sc, frame_wp, modules, error); } diff --git a/lldb/test/Shell/SwiftREPL/Inputs/Test.swift b/lldb/test/Shell/SwiftREPL/Inputs/Test.swift new file mode 100644 index 0000000000000..25d1dbead4ce2 --- /dev/null +++ b/lldb/test/Shell/SwiftREPL/Inputs/Test.swift @@ -0,0 +1,11 @@ +public struct Bar { + public init(baz: Int) { self.baz = baz } + + var baz : Int +} + +struct Foo { + init(bar: Int) { self.bar = bar } + + var bar : Int +} diff --git a/lldb/test/Shell/SwiftREPL/LookupWithAttributedImport.test b/lldb/test/Shell/SwiftREPL/LookupWithAttributedImport.test new file mode 100644 index 0000000000000..6308ad81454d6 --- /dev/null +++ b/lldb/test/Shell/SwiftREPL/LookupWithAttributedImport.test @@ -0,0 +1,24 @@ +// Make sure import attributes are taken into consideration at every evaluation +// rdar://65319954 +// REQUIRES: swift + +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: %target-swiftc -emit-library %S/Inputs/Test.swift -module-name Test -emit-module-path %t/Test.swiftmodule -o %t/libTest%target-shared-library-suffix -Onone -g -enable-testing + +// RUN: %lldb --repl="-I%t -L%t -lTest" < %s 2>&1 | FileCheck %s + +import Test + +let y = Bar(baz: 123) +// CHECK: y: Test.Bar = { +// CHECK: baz = 123 + +let x = Foo(bar:42) +// CHECK: error: repl.swift:{{.*}}: error: cannot find 'Foo' in scope + +@testable import Test + +let x = Foo(bar:42) +// CHECK: x: Test.Foo = { +// CHECK: bar = 42 From f6b1a6a54bcd70baad35e594fc40fc5b24201359 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 16 Oct 2020 11:42:08 -0700 Subject: [PATCH 144/234] Add support for more OS types to AddClangModuleCompilationOptionsForSDKType() This patch also avoids hardcoding the clang options, which makes it less likely for them to become out-of-date. rdar://problem/63791367+66927829 Differential Revision: https://reviews.llvm.org/D89428 (cherry picked from commit cf245086518efbdf96c2d86697298a8da5c97669) Conflicts: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp --- .../Platform/MacOSX/PlatformDarwin.cpp | 74 ++++++++++++------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index d31559bc90183..d1064a0c8f3e6 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -1477,25 +1477,20 @@ void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType( StreamString minimum_version_option; bool use_current_os_version = false; + // If the SDK type is for the host OS, use its version number. + auto get_host_os = []() { return HostInfo::GetTargetTriple().getOS(); }; switch (sdk_type) { + case XcodeSDK::Type::MacOSX: + use_current_os_version = get_host_os() == llvm::Triple::MacOSX; + break; case XcodeSDK::Type::iPhoneOS: -#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) - use_current_os_version = true; -#else - use_current_os_version = false; -#endif + use_current_os_version = get_host_os() == llvm::Triple::IOS; break; - - case XcodeSDK::Type::iPhoneSimulator: - use_current_os_version = false; + case XcodeSDK::Type::AppleTVOS: + use_current_os_version = get_host_os() == llvm::Triple::TvOS; break; - - case XcodeSDK::Type::MacOSX: -#if defined(__i386__) || defined(__x86_64__) - use_current_os_version = true; -#else - use_current_os_version = false; -#endif + case XcodeSDK::Type::watchOS: + use_current_os_version = get_host_os() == llvm::Triple::WatchOS; break; default: break; @@ -1515,24 +1510,49 @@ void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType( } } // Only add the version-min options if we got a version from somewhere - if (!version.empty()) { + if (!version.empty() && sdk_type != XcodeSDK::Type::Linux) { +#define OPTION(PREFIX, NAME, VAR, ...) \ + const char *opt_##VAR = NAME; \ + (void)opt_##VAR; +#include "clang/Driver/Options.inc" +#undef OPTION + minimum_version_option << '-'; switch (sdk_type) { - case XcodeSDK::Type::iPhoneOS: - minimum_version_option.PutCString("-mios-version-min="); - minimum_version_option.PutCString(version.getAsString()); + case XcodeSDK::Type::MacOSX: + minimum_version_option << opt_mmacosx_version_min_EQ; break; case XcodeSDK::Type::iPhoneSimulator: - minimum_version_option.PutCString("-mios-simulator-version-min="); - minimum_version_option.PutCString(version.getAsString()); + minimum_version_option << opt_mios_simulator_version_min_EQ; break; - case XcodeSDK::Type::MacOSX: - minimum_version_option.PutCString("-mmacosx-version-min="); - minimum_version_option.PutCString(version.getAsString()); + case XcodeSDK::Type::iPhoneOS: + minimum_version_option << opt_mios_version_min_EQ; break; - default: - llvm_unreachable("unsupported sdk"); + case XcodeSDK::Type::AppleTVSimulator: + minimum_version_option << opt_mtvos_simulator_version_min_EQ; + break; + case XcodeSDK::Type::AppleTVOS: + minimum_version_option << opt_mtvos_version_min_EQ; + break; + case XcodeSDK::Type::WatchSimulator: + minimum_version_option << opt_mwatchos_simulator_version_min_EQ; + break; + case XcodeSDK::Type::watchOS: + minimum_version_option << opt_mwatchos_version_min_EQ; + break; + case XcodeSDK::Type::bridgeOS: + case XcodeSDK::Type::Linux: + case XcodeSDK::Type::unknown: + if (lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST)) { + XcodeSDK::Info info; + info.type = sdk_type; + LLDB_LOGF(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST), + "Clang modules on %s are not supported", + XcodeSDK::GetCanonicalName(info).c_str()); + } + return; } - options.push_back(std::string(minimum_version_option.GetString())); + minimum_version_option << version.getAsString(); + options.emplace_back(std::string(minimum_version_option.GetString())); } FileSpec sysroot_spec; From 0e87f350daf6b07d30c10db9b83ab22e4182bc64 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 13 Oct 2020 17:50:02 -0700 Subject: [PATCH 145/234] [cmake] Limit missing external lit warning to be shown once When using a custom `LLVM_EXTERNAL_LIT`, it's possible the file may not exist at the CMake is generating the build. One example is LLDB standalone builds. When the external lit doesn't exist, a warning message is emitted, but the warning is printed once for every single lit target. This produces many redundant warnings. This changes the warning to only be emitted once, controlled by a CACHE variable. Other options are: 1. remove the warning 2. have callers pass an option to silence the warning if desired See https://reviews.llvm.org/D76945 for some context. Differential Revision: https://reviews.llvm.org/D89356 (cherry picked from commit 41f946a6d2a4c1b36ee0a63f615a1aa6edf37cab) --- llvm/cmake/modules/AddLLVM.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index 459a73a59bc39..b2c78d0b88e68 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -1669,8 +1669,9 @@ function(get_llvm_lit_path base_dir file_name) set(${file_name} ${LIT_FILE_NAME} PARENT_SCOPE) set(${base_dir} ${LIT_BASE_DIR} PARENT_SCOPE) return() - else() + elseif (NOT DEFINED CACHE{LLVM_EXTERNAL_LIT_MISSING_WARNED_ONCE}) message(WARNING "LLVM_EXTERNAL_LIT set to ${LLVM_EXTERNAL_LIT}, but the path does not exist.") + set(LLVM_EXTERNAL_LIT_MISSING_WARNED_ONCE YES CACHE INTERNAL "") endif() endif() endif() From 75ccad1d4cada100ad6ab1246988d1c21877abc9 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Thu, 15 Oct 2020 14:28:06 -0700 Subject: [PATCH 146/234] Add an SB API to get the SBTarget from an SBBreakpoint Differential Revision: https://reviews.llvm.org/D89358 (cherry picked from commit 6754caa9bf21a759c4080a797f23e2b7a77a71e1) --- lldb/bindings/interface/SBBreakpoint.i | 3 +++ lldb/include/lldb/API/SBBreakpoint.h | 2 ++ lldb/source/API/SBBreakpoint.cpp | 11 +++++++++++ .../API/python_api/breakpoint/TestBreakpointAPI.py | 3 +++ 4 files changed, 19 insertions(+) diff --git a/lldb/bindings/interface/SBBreakpoint.i b/lldb/bindings/interface/SBBreakpoint.i index e386ace9dee8a..696795241b118 100644 --- a/lldb/bindings/interface/SBBreakpoint.i +++ b/lldb/bindings/interface/SBBreakpoint.i @@ -100,6 +100,9 @@ public: void ClearAllBreakpointSites (); + lldb::SBTarget + GetTarget() const; + lldb::SBBreakpointLocation FindLocationByAddress (lldb::addr_t vm_addr); diff --git a/lldb/include/lldb/API/SBBreakpoint.h b/lldb/include/lldb/API/SBBreakpoint.h index 39a021145fb7b..e13dbc5c35168 100644 --- a/lldb/include/lldb/API/SBBreakpoint.h +++ b/lldb/include/lldb/API/SBBreakpoint.h @@ -42,6 +42,8 @@ class LLDB_API SBBreakpoint { void ClearAllBreakpointSites(); + lldb::SBTarget GetTarget() const; + lldb::SBBreakpointLocation FindLocationByAddress(lldb::addr_t vm_addr); lldb::break_id_t FindLocationIDByAddress(lldb::addr_t vm_addr); diff --git a/lldb/source/API/SBBreakpoint.cpp b/lldb/source/API/SBBreakpoint.cpp index 96b77bd8539e8..96ae305ffce5b 100644 --- a/lldb/source/API/SBBreakpoint.cpp +++ b/lldb/source/API/SBBreakpoint.cpp @@ -81,6 +81,16 @@ bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) { return m_opaque_wp.lock() != rhs.m_opaque_wp.lock(); } +SBTarget SBBreakpoint::GetTarget() const { + LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBTarget, SBBreakpoint, GetTarget); + + BreakpointSP bkpt_sp = GetSP(); + if (bkpt_sp) + return LLDB_RECORD_RESULT(SBTarget(bkpt_sp->GetTargetSP())); + + return LLDB_RECORD_RESULT(SBTarget()); +} + break_id_t SBBreakpoint::GetID() const { LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::break_id_t, SBBreakpoint, GetID); @@ -987,6 +997,7 @@ void RegisterMethods(Registry &R) { SBBreakpoint, operator==,(const lldb::SBBreakpoint &)); LLDB_REGISTER_METHOD(bool, SBBreakpoint, operator!=,(const lldb::SBBreakpoint &)); + LLDB_REGISTER_METHOD_CONST(lldb::SBTarget, SBBreakpoint, GetTarget, ()); LLDB_REGISTER_METHOD_CONST(lldb::break_id_t, SBBreakpoint, GetID, ()); LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsValid, ()); LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, operator bool, ()); diff --git a/lldb/test/API/python_api/breakpoint/TestBreakpointAPI.py b/lldb/test/API/python_api/breakpoint/TestBreakpointAPI.py index 1c0c334fbeebf..80324ee61b70d 100644 --- a/lldb/test/API/python_api/breakpoint/TestBreakpointAPI.py +++ b/lldb/test/API/python_api/breakpoint/TestBreakpointAPI.py @@ -66,6 +66,9 @@ def test_target_delete(self): location = breakpoint.GetLocationAtIndex(0) self.assertTrue(location.IsValid()) + # Make sure the breakpoint's target is right: + self.assertEqual(target, breakpoint.GetTarget(), "Breakpoint reports its target correctly") + self.assertTrue(self.dbg.DeleteTarget(target)) self.assertFalse(breakpoint.IsValid()) self.assertFalse(location.IsValid()) From ef4906d6fda5f14597da3dac08891fe0e73572ee Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 16 Oct 2020 16:55:56 -0700 Subject: [PATCH 147/234] Only print validation warnings when actually triggering an assertion. --- .../TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index b0845aee8f40d..accd5a706648f 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1189,10 +1189,6 @@ template <> bool Equivalent(CompilerType l, CompilerType r) { /// matching that name. template <> bool Equivalent(ConstString l, ConstString r) { if (l != r) { - // Failure. Dump it for easier debugging. - llvm::dbgs() << "TypeSystemSwiftTypeRef diverges from SwiftASTContext: " - << l.GetStringRef() << " != " << r.GetStringRef() << "\n"; - // For some reason the Swift type dumper doesn't attach a module // name to the AnyObject protocol, and only that one. std::string l_prime = std::regex_replace( @@ -1225,7 +1221,11 @@ template <> bool Equivalent(ConstString l, ConstString r) { if (llvm::StringRef(l_prime) == r.GetStringRef()) return true; -#ifndef STRICT_VALIDATION +#ifdef STRICT_VALIDATION + // Failure. Dump it for easier debugging. + llvm::dbgs() << "TypeSystemSwiftTypeRef diverges from SwiftASTContext: " + << l.GetStringRef() << " != " << r.GetStringRef() << "\n"; +#else return true; #endif } From 590ecce905fc15136c3d458793224a1ce44ecc0f Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Fri, 16 Oct 2020 16:58:12 -0700 Subject: [PATCH 148/234] [lldb] Fix few easily correctable warnings --- lldb/source/Expression/REPL.cpp | 2 +- lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp | 8 -------- .../Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp | 6 +++--- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/lldb/source/Expression/REPL.cpp b/lldb/source/Expression/REPL.cpp index 03da3e78524f0..47b07ac02f5c6 100644 --- a/lldb/source/Expression/REPL.cpp +++ b/lldb/source/Expression/REPL.cpp @@ -196,7 +196,7 @@ static bool ReadCode(const std::string &path, std::string &code, const size_t max_size = code.max_size(); if (file_size > max_size) { error_sp->Printf("file at path '%s' too large: " - "file_size = %llu, max_size = %llu\n", + "file_size = %zu, max_size = %zu\n", path.c_str(), file_size, max_size); return false; } diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index 964e678455028..3d3b26a401642 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -8342,14 +8342,6 @@ bool SwiftASTContext::CacheUserImports(SwiftASTContext &swift_ast_context, Status &error) { llvm::SmallString<1> m_description; - swift::ModuleDecl::ImportFilter import_filter { - swift::ModuleDecl::ImportFilterKind::Exported, - swift::ModuleDecl::ImportFilterKind::Default, - swift::ModuleDecl::ImportFilterKind::ImplementationOnly, - swift::ModuleDecl::ImportFilterKind::SPIAccessControl, - swift::ModuleDecl::ImportFilterKind::ShadowedByCrossImportOverlay - }; - auto *persistent_expression_state = sc.target_sp->GetSwiftPersistentExpressionState(exe_scope); diff --git a/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp index a3445b3aa1836..11b819e4ddfdc 100644 --- a/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -965,7 +965,7 @@ llvm::Optional SwiftLanguageRuntimeImpl::GetMemberVariableOffset( } if (offset) { LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), - "[GetMemberVariableOffset] offset of %s is %d", + "[GetMemberVariableOffset] offset of %s is %lld", member_name.str().c_str(), *offset); } else { LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), @@ -2033,7 +2033,7 @@ bool SwiftLanguageRuntime::IsTaggedPointer(lldb::addr_t addr, // Check whether this is a reference to an Objective-C object. if ((addr & 1) == 1) return true; - } + } break; default: break; } @@ -2098,7 +2098,7 @@ lldb::addr_t SwiftLanguageRuntime::FixupAddress(lldb::addr_t addr, if (extra_deref) return refd_addr; } - } + } break; default: break; } From e184b47a679ecccedc4bad7acc42db1c28621765 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Mon, 21 Sep 2020 10:22:51 -0700 Subject: [PATCH 149/234] [cmake] Centralize LLVM_ENABLE_WARNINGS option Configure default value of `LLVM_ENABLE_WARNINGS` in `HandleLLVMOptions.cmake`. `LLVM_ENABLE_WARNINGS` is documented as ON by default, but `HandleLLVMOptions` assumes the default has been set somewhere else. If it has not been explicitly set, then `HandleLLVMOptions` implicitly uses OFF as a default. This removes the various `option()` declarations in favor of a single declaration in `HandleLLVMOptions`. This will prevent the unwanted use of `-w` that is mentioned in a couple of the comments. Reviewed By: DavidTruby, #libunwind, JDevlieghere, compnerd Differential Revision: https://reviews.llvm.org/D87243 (cherry picked from commit b36bdfe5ca0c2b863248f327b03d41516b38dc11) --- clang/CMakeLists.txt | 1 - flang/CMakeLists.txt | 1 - libunwind/CMakeLists.txt | 2 -- llvm/CMakeLists.txt | 1 - llvm/cmake/modules/HandleLLVMOptions.cmake | 2 ++ llvm/cmake/modules/LLVMConfig.cmake.in | 2 ++ llvm/runtimes/CMakeLists.txt | 4 ---- 7 files changed, 4 insertions(+), 9 deletions(-) diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index 2e06c5fd9028b..f54f40d028158 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -105,7 +105,6 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) endif() - option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON) option(LLVM_INSTALL_TOOLCHAIN_ONLY "Only include toolchain files in the 'install' target." OFF) diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt index 13e675f1096e5..e8b81215356c4 100644 --- a/flang/CMakeLists.txt +++ b/flang/CMakeLists.txt @@ -62,7 +62,6 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) if(LLVM_ENABLE_ZLIB) find_package(ZLIB REQUIRED) endif() - option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON) option(LLVM_ENABLE_PEDANTIC "Compile with pedantic enabled." ON) include(CMakeParseArguments) diff --git a/libunwind/CMakeLists.txt b/libunwind/CMakeLists.txt index bd8176c67925f..34277e6bd00a9 100644 --- a/libunwind/CMakeLists.txt +++ b/libunwind/CMakeLists.txt @@ -73,8 +73,6 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR LIBUNWIND_STANDALONE_B endif() if (EXISTS ${LLVM_CMAKE_PATH}) - # Enable warnings, otherwise -w gets added to the cflags by HandleLLVMOptions. - set(LLVM_ENABLE_WARNINGS ON) list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}") include("${LLVM_CMAKE_PATH}/AddLLVM.cmake") include("${LLVM_CMAKE_PATH}/HandleLLVMOptions.cmake") diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index 038139a24090c..0bdabc216f08f 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -402,7 +402,6 @@ set(LLVM_TARGETS_TO_BUILD list(REMOVE_DUPLICATES LLVM_TARGETS_TO_BUILD) option(LLVM_ENABLE_PIC "Build Position-Independent Code" ON) -option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON) option(LLVM_ENABLE_MODULES "Compile with C++ modules enabled." OFF) if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") option(LLVM_ENABLE_MODULE_DEBUGGING "Compile with -gmodules." ON) diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake index acab85a53140c..0b5400757e41c 100644 --- a/llvm/cmake/modules/HandleLLVMOptions.cmake +++ b/llvm/cmake/modules/HandleLLVMOptions.cmake @@ -400,6 +400,8 @@ elseif(MINGW) # FIXME: Also cygwin? endif() endif() +option(LLVM_ENABLE_WARNINGS "Enable compiler warnings." ON) + if( MSVC ) include(ChooseMSVCCRT) diff --git a/llvm/cmake/modules/LLVMConfig.cmake.in b/llvm/cmake/modules/LLVMConfig.cmake.in index aab5cf555da1b..f1f76b63a6936 100644 --- a/llvm/cmake/modules/LLVMConfig.cmake.in +++ b/llvm/cmake/modules/LLVMConfig.cmake.in @@ -38,6 +38,8 @@ set(TARGET_TRIPLE "@TARGET_TRIPLE@") set(LLVM_ABI_BREAKING_CHECKS @LLVM_ABI_BREAKING_CHECKS@) +set(LLVM_ENABLE_WARNINGS @LLVM_ENABLE_WARNINGS@) + set(LLVM_ENABLE_EXPENSIVE_CHECKS @LLVM_ENABLE_EXPENSIVE_CHECKS@) set(LLVM_ENABLE_ASSERTIONS @LLVM_ENABLE_ASSERTIONS@) diff --git a/llvm/runtimes/CMakeLists.txt b/llvm/runtimes/CMakeLists.txt index d56f7af583eda..c58b864376a7d 100644 --- a/llvm/runtimes/CMakeLists.txt +++ b/llvm/runtimes/CMakeLists.txt @@ -105,10 +105,6 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) # Avoid checking whether the compiler is working. set(LLVM_COMPILER_CHECKED ON) - # Enable warnings, otherwise -w gets added to the cflags by HandleLLVMOptions - # resulting in unjustified successes by check_cxx_compiler_flag. - set(LLVM_ENABLE_WARNINGS ON) - # Handle common options used by all runtimes. include(AddLLVM) include(HandleLLVMOptions) From 0180055bdccaf08457f2018acb013d4e3027926c Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Sat, 17 Oct 2020 12:59:52 -0700 Subject: [PATCH 150/234] TypeSystem: silence some errors identified by MSVC Silence a few cases where MSVC complains about not all paths returning a value. Avoid adding a default case to allow for catching covered switches. --- lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index 3d3b26a401642..9ab13d403b881 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -1265,6 +1265,7 @@ static const char *getImportFailureString(swift::serialization::Status status) { return "The module file was built for a target newer than the current " "target."; } + llvm_unreachable("covered switch"); } /// Initialize the compiler invocation with it the search paths from a @@ -2991,6 +2992,7 @@ class SwiftDWARFImporterDelegate : public swift::DWARFImporterDelegate { // described in DWARF. return true; } + llvm_unreachable("covered switch"); } clang::Decl *GetDeclForTypeAndKind(clang::QualType qual_type, From e6aba2ffcc757c682a109bcf1591b8e1a578d08c Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Mon, 19 Oct 2020 10:18:20 -0700 Subject: [PATCH 151/234] [llvm] Make obj2yaml and yaml2obj LLVM utilities instead of tools For testing purposes I need a way to build and install FileCheck and yaml2obj. I had to choose between making FileCheck an LLVM tool and making obj2yaml and yaml2obj utilities. I think the distinction is rather arbitrary but my understanding is that tools are things meant for the toolchain while utilities are more used for things like testing, which is the case here. The functional difference is that these tools now end up in the ${LLVM_UTILS_INSTALL_DIR}, which defaults to the ${LLVM_TOOLS_INSTALL_DIR}. Unless you specified a different value or you added obj2yaml and yaml2obj to ${LLVM_TOOLCHAIN_TOOLS}, this patch shouldn't change anything. Differential revision: https://reviews.llvm.org/D89357 (cherry picked from commit 97b8e2c1f063529125a8d1604d2745878c016061) --- llvm/tools/obj2yaml/CMakeLists.txt | 2 +- llvm/tools/yaml2obj/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/tools/obj2yaml/CMakeLists.txt b/llvm/tools/obj2yaml/CMakeLists.txt index f76983e0e8ece..732cd27cbef04 100644 --- a/llvm/tools/obj2yaml/CMakeLists.txt +++ b/llvm/tools/obj2yaml/CMakeLists.txt @@ -7,7 +7,7 @@ set(LLVM_LINK_COMPONENTS Support ) -add_llvm_tool(obj2yaml +add_llvm_utility(obj2yaml obj2yaml.cpp coff2yaml.cpp dwarf2yaml.cpp diff --git a/llvm/tools/yaml2obj/CMakeLists.txt b/llvm/tools/yaml2obj/CMakeLists.txt index 0cbc8e0d65002..d1dea734a4e9a 100644 --- a/llvm/tools/yaml2obj/CMakeLists.txt +++ b/llvm/tools/yaml2obj/CMakeLists.txt @@ -3,6 +3,6 @@ set(LLVM_LINK_COMPONENTS Support ) -add_llvm_tool(yaml2obj +add_llvm_utility(yaml2obj yaml2obj.cpp ) From 020bdf7bdb017246b5616de7816eab2e8c75d660 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Wed, 19 Aug 2020 07:13:16 -0700 Subject: [PATCH 152/234] Teach the swift calling convention about _Atomic types rdar://67351073 Differential Revision: https://reviews.llvm.org/D86218 --- clang/lib/CodeGen/SwiftCallingConv.cpp | 17 ++++++++++++++-- clang/test/CodeGen/64bit-swiftcall.c | 27 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/SwiftCallingConv.cpp b/clang/lib/CodeGen/SwiftCallingConv.cpp index 3d7421ac2e16c..1423d82896e74 100644 --- a/clang/lib/CodeGen/SwiftCallingConv.cpp +++ b/clang/lib/CodeGen/SwiftCallingConv.cpp @@ -93,11 +93,24 @@ void SwiftAggLowering::addTypedData(QualType type, CharUnits begin) { // Just add it all as opaque. addOpaqueData(begin, begin + CGM.getContext().getTypeSizeInChars(type)); - // Everything else is scalar and should not convert as an LLVM aggregate. + // Atomic types. + } else if (const auto *atomicType = type->getAs()) { + auto valueType = atomicType->getValueType(); + auto atomicSize = CGM.getContext().getTypeSizeInChars(atomicType); + auto valueSize = CGM.getContext().getTypeSizeInChars(valueType); + + addTypedData(atomicType->getValueType(), begin); + + // Add atomic padding. + auto atomicPadding = atomicSize - valueSize; + if (atomicPadding > CharUnits::Zero()) + addOpaqueData(begin + valueSize, begin + atomicSize); + + // Everything else is scalar and should not convert as an LLVM aggregate. } else { // We intentionally convert as !ForMem because we want to preserve // that a type was an i1. - auto llvmType = CGM.getTypes().ConvertType(type); + auto *llvmType = CGM.getTypes().ConvertType(type); addTypedData(llvmType, begin); } } diff --git a/clang/test/CodeGen/64bit-swiftcall.c b/clang/test/CodeGen/64bit-swiftcall.c index 51fb8545551f0..5843b8cde4dce 100644 --- a/clang/test/CodeGen/64bit-swiftcall.c +++ b/clang/test/CodeGen/64bit-swiftcall.c @@ -10,6 +10,9 @@ #define ERROR __attribute__((swift_error_result)) #define CONTEXT __attribute__((swift_context)) +// CHECK-DAG: %struct.atomic_padded = type { { %struct.packed, [7 x i8] } } +// CHECK-DAG: %struct.packed = type <{ i64, i8 }> +// // CHECK: [[STRUCT2_RESULT:@.*]] = private {{.*}} constant [[STRUCT2_TYPE:%.*]] { i32 0, i8 0, i8 undef, i8 0, i32 0, i32 0 } /*****************************************************************************/ @@ -1042,3 +1045,27 @@ void no_lifetime_markers() { // CHECK-NOT: call void @llvm.lifetime. take_int5(return_int5()); } + +typedef struct { + unsigned long long a; + unsigned long long b; +} double_word; + +typedef struct { + _Atomic(double_word) a; +} atomic_double_word; + +// CHECK-LABEL: use_atomic(i64 %0, i64 %1) +SWIFTCALL void use_atomic(atomic_double_word a) {} + +typedef struct { + unsigned long long a; + unsigned char b; +} __attribute__((packed)) packed; + +typedef struct { + _Atomic(packed) a; +} atomic_padded; + +// CHECK-LABEL: use_atomic_padded(i64 %0, i64 %1) +SWIFTCALL void use_atomic_padded(atomic_padded a) {} From 386224aa218ced4bd417a3936cc1033ec59758df Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Mon, 19 Oct 2020 20:17:38 +0200 Subject: [PATCH 153/234] [lldb][swift] Make swiftTest decorator not always skip _get_bool_config_skip_if_decorator returns a decorator, but the is_not_swift_compatible function is supposed to return a bool. The skipTestIfFn is supposed to create the decorator from the function we define. As _get_bool_config_skip_if_decorator's return value is just interpreted as True, this ends up causing that we skip all Swift tests all the time. This just adds a _get_bool_config() function that actually returns a bool. We could probably also solve this by doing a function composition of the returned decorator and the decorator we create from our local function, but just having a bool seems less likely to break. --- lldb/packages/Python/lldbsuite/test/decorators.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/decorators.py b/lldb/packages/Python/lldbsuite/test/decorators.py index f6acdf7bda9b2..35fd2b06d2c54 100644 --- a/lldb/packages/Python/lldbsuite/test/decorators.py +++ b/lldb/packages/Python/lldbsuite/test/decorators.py @@ -626,9 +626,8 @@ def skipUnlessTargetAndroid(func): def swiftTest(func): """Decorate the item as a Swift test (Darwin/Linux only, no i386).""" def is_not_swift_compatible(self): - swift_enabled_error = _get_bool_config_skip_if_decorator("swift")(func) - if swift_enabled_error: - return swift_enabled_error + if not _get_bool_config("swift"): + return "Swift plugin not enabled" if self.getDebugInfo() == "gmodules": return "skipping (gmodules only makes sense for clang tests)" @@ -886,11 +885,14 @@ def skipIfAsan(func): """Skip this test if the environment is set up to run LLDB *itself* under ASAN.""" return skipTestIfFn(is_running_under_asan)(func) -def _get_bool_config_skip_if_decorator(key): +def _get_bool_config(key): config = lldb.SBDebugger.GetBuildConfiguration() value_node = config.GetValueForKey(key) fail_value = True # More likely to notice if something goes wrong - have = value_node.GetValueForKey("value").GetBooleanValue(fail_value) + return value_node.GetValueForKey("value").GetBooleanValue(fail_value) + +def _get_bool_config_skip_if_decorator(key): + have = _get_bool_config(key) return unittest2.skipIf(not have, "requires " + key) def skipIfCursesSupportMissing(func): From 603a9446d9bb41cc1941baa96d6dfae62f1a277d Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Tue, 20 Oct 2020 19:00:47 +0200 Subject: [PATCH 154/234] [lldb][swift] Skip all failing tests Adds skipIf to all the tests that regressed since 2c911bceb06ed376801251bdfd992905a66f276c landed and disabled the Swift tests unintentionally. --- .../headermap_conflict/TestSwiftHeadermapConflict.py | 1 + .../remoteast_import/TestSwiftRemoteASTImport.py | 1 + .../lang/swift/dwarfimporter/C/TestSwiftDWARFImporterC.py | 1 + .../static/TestSwiftExpressionsInClassFunctions.py | 1 + .../swift/generic_existentials/TestGenericExistentials.py | 4 +++- .../lang/swift/opaque_existentials/TestOpaqueExistentials.py | 4 +++- lldb/test/API/lang/swift/optionset/TestSwiftOptionSetType.py | 1 + .../TestProtocolExtensionComputerProperty.py | 1 + .../test/API/lang/swift/unknown_self/TestSwiftUnknownSelf.py | 1 + .../lang/swift/variables/error_type/TestSwiftErrorType.py | 5 ++++- .../lang/swift/variables/protocol/TestSwiftProtocolTypes.py | 1 + 11 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lldb/test/API/lang/swift/clangimporter/headermap_conflict/TestSwiftHeadermapConflict.py b/lldb/test/API/lang/swift/clangimporter/headermap_conflict/TestSwiftHeadermapConflict.py index d861a5530d941..fa7690202fc26 100644 --- a/lldb/test/API/lang/swift/clangimporter/headermap_conflict/TestSwiftHeadermapConflict.py +++ b/lldb/test/API/lang/swift/clangimporter/headermap_conflict/TestSwiftHeadermapConflict.py @@ -25,6 +25,7 @@ class TestSwiftHeadermapConflict(TestBase): def setUp(self): TestBase.setUp(self) + @skipIf #FIXME: This regressed silently due to 2c911bceb06ed376801251bdfd992905a66f276c @skipIf(bugnumber="rdar://60396797", setting=('symbols.use-swift-clangimporter', 'false')) @skipUnlessDarwin diff --git a/lldb/test/API/lang/swift/clangimporter/remoteast_import/TestSwiftRemoteASTImport.py b/lldb/test/API/lang/swift/clangimporter/remoteast_import/TestSwiftRemoteASTImport.py index 2c2fd8df46b40..6bf2b8bb8e7d7 100644 --- a/lldb/test/API/lang/swift/clangimporter/remoteast_import/TestSwiftRemoteASTImport.py +++ b/lldb/test/API/lang/swift/clangimporter/remoteast_import/TestSwiftRemoteASTImport.py @@ -24,6 +24,7 @@ class TestSwiftRemoteASTImport(TestBase): def setUp(self): TestBase.setUp(self) + @expectedFailureAll #FIXME: This regressed silently due to 2c911bceb06ed376801251bdfd992905a66f276c # Don't run ClangImporter tests if Clangimporter is disabled. @skipIf(setting=('symbols.use-swift-clangimporter', 'false')) @skipUnlessDarwin diff --git a/lldb/test/API/lang/swift/dwarfimporter/C/TestSwiftDWARFImporterC.py b/lldb/test/API/lang/swift/dwarfimporter/C/TestSwiftDWARFImporterC.py index dfd8ae0736560..5246a2f849ca5 100644 --- a/lldb/test/API/lang/swift/dwarfimporter/C/TestSwiftDWARFImporterC.py +++ b/lldb/test/API/lang/swift/dwarfimporter/C/TestSwiftDWARFImporterC.py @@ -67,6 +67,7 @@ def test_dwarf_importer(self): target.Clear() lldb.SBDebugger.MemoryPressureDetected() + @expectedFailureAll #FIXME: This regressed silently due to 2c911bceb06ed376801251bdfd992905a66f276c @skipIf(archs=['ppc64le'], bugnumber='SR-10214') @swiftTest # This test needs a working Remote Mirrors implementation. diff --git a/lldb/test/API/lang/swift/expression/static/TestSwiftExpressionsInClassFunctions.py b/lldb/test/API/lang/swift/expression/static/TestSwiftExpressionsInClassFunctions.py index 07378b9d2c869..0226e878e917b 100644 --- a/lldb/test/API/lang/swift/expression/static/TestSwiftExpressionsInClassFunctions.py +++ b/lldb/test/API/lang/swift/expression/static/TestSwiftExpressionsInClassFunctions.py @@ -39,6 +39,7 @@ def check_expression(self, expression, expected_result, use_summary=True): self.assertTrue(answer == expected_result, report_str) + @expectedFailureAll #FIXME: This regressed silently due to 2c911bceb06ed376801251bdfd992905a66f276c @swiftTest def test_expressions_in_class_functions(self): """Test expressions in class func contexts""" diff --git a/lldb/test/API/lang/swift/generic_existentials/TestGenericExistentials.py b/lldb/test/API/lang/swift/generic_existentials/TestGenericExistentials.py index e0768afb05784..932d598b0babf 100644 --- a/lldb/test/API/lang/swift/generic_existentials/TestGenericExistentials.py +++ b/lldb/test/API/lang/swift/generic_existentials/TestGenericExistentials.py @@ -1,4 +1,6 @@ import lldbsuite.test.lldbinline as lldbinline from lldbsuite.test.decorators import * -lldbinline.MakeInlineTest(__file__, globals(), decorators=[swiftTest]) +lldbinline.MakeInlineTest(__file__, globals(), decorators=[swiftTest, + expectedFailureAll #FIXME: This regressed silently due to 2c911bceb06ed376801251bdfd992905a66f276c + ]) diff --git a/lldb/test/API/lang/swift/opaque_existentials/TestOpaqueExistentials.py b/lldb/test/API/lang/swift/opaque_existentials/TestOpaqueExistentials.py index e0768afb05784..932d598b0babf 100644 --- a/lldb/test/API/lang/swift/opaque_existentials/TestOpaqueExistentials.py +++ b/lldb/test/API/lang/swift/opaque_existentials/TestOpaqueExistentials.py @@ -1,4 +1,6 @@ import lldbsuite.test.lldbinline as lldbinline from lldbsuite.test.decorators import * -lldbinline.MakeInlineTest(__file__, globals(), decorators=[swiftTest]) +lldbinline.MakeInlineTest(__file__, globals(), decorators=[swiftTest, + expectedFailureAll #FIXME: This regressed silently due to 2c911bceb06ed376801251bdfd992905a66f276c + ]) diff --git a/lldb/test/API/lang/swift/optionset/TestSwiftOptionSetType.py b/lldb/test/API/lang/swift/optionset/TestSwiftOptionSetType.py index e12d83951c722..d8d389548bf19 100644 --- a/lldb/test/API/lang/swift/optionset/TestSwiftOptionSetType.py +++ b/lldb/test/API/lang/swift/optionset/TestSwiftOptionSetType.py @@ -14,6 +14,7 @@ lldbinline.MakeInlineTest(__file__, globals(), decorators=[swiftTest,skipUnlessDarwin, + expectedFailureAll, #FIXME: This regressed silently due to 2c911bceb06ed376801251bdfd992905a66f276c expectedFailureAll(bugnumber="rdar://60396797", setting=('symbols.use-swift-clangimporter', 'false')) ]) diff --git a/lldb/test/API/lang/swift/protocol_extension_computed_property/TestProtocolExtensionComputerProperty.py b/lldb/test/API/lang/swift/protocol_extension_computed_property/TestProtocolExtensionComputerProperty.py index 37ed3f1358668..3992e6722c65f 100644 --- a/lldb/test/API/lang/swift/protocol_extension_computed_property/TestProtocolExtensionComputerProperty.py +++ b/lldb/test/API/lang/swift/protocol_extension_computed_property/TestProtocolExtensionComputerProperty.py @@ -4,6 +4,7 @@ lldbinline.MakeInlineTest( __file__, globals(), decorators=[ + expectedFailureAll, #FIXME: This regressed silently due to 2c911bceb06ed376801251bdfd992905a66f276c swiftTest,skipUnlessDarwin, skipIf(bugnumber="rdar://60396797", # should work but crashes. setting=('symbols.use-swift-clangimporter', 'false')) diff --git a/lldb/test/API/lang/swift/unknown_self/TestSwiftUnknownSelf.py b/lldb/test/API/lang/swift/unknown_self/TestSwiftUnknownSelf.py index 378dcdc8a0620..9cb54f875ca4a 100644 --- a/lldb/test/API/lang/swift/unknown_self/TestSwiftUnknownSelf.py +++ b/lldb/test/API/lang/swift/unknown_self/TestSwiftUnknownSelf.py @@ -33,6 +33,7 @@ def check_class(self, var_self, broken): self.expect("fr v self", substrs=["hello", "world"]) + @skipIf #FIXME: This regressed silently due to 2c911bceb06ed376801251bdfd992905a66f276c @skipIf(bugnumber="SR-10216", archs=['ppc64le']) @swiftTest def test_unknown_self_objc_ref(self): diff --git a/lldb/test/API/lang/swift/variables/error_type/TestSwiftErrorType.py b/lldb/test/API/lang/swift/variables/error_type/TestSwiftErrorType.py index fece1dd2df708..269dcb7e53910 100644 --- a/lldb/test/API/lang/swift/variables/error_type/TestSwiftErrorType.py +++ b/lldb/test/API/lang/swift/variables/error_type/TestSwiftErrorType.py @@ -12,4 +12,7 @@ import lldbsuite.test.lldbinline as lldbinline from lldbsuite.test.decorators import * -lldbinline.MakeInlineTest(__file__, globals(), decorators=[swiftTest]) +lldbinline.MakeInlineTest(__file__, globals(), decorators=[ +#FIXME: This regressed silently due to 2c911bceb06ed376801251bdfd992905a66f276c + expectedFailureAll, + swiftTest]) diff --git a/lldb/test/API/lang/swift/variables/protocol/TestSwiftProtocolTypes.py b/lldb/test/API/lang/swift/variables/protocol/TestSwiftProtocolTypes.py index ef86ebea19371..4651f6afb2ed9 100644 --- a/lldb/test/API/lang/swift/variables/protocol/TestSwiftProtocolTypes.py +++ b/lldb/test/API/lang/swift/variables/protocol/TestSwiftProtocolTypes.py @@ -23,6 +23,7 @@ class TestSwiftProtocolTypes(TestBase): mydir = TestBase.compute_mydir(__file__) + @expectedFailureAll #FIXME: This regressed silently due to 2c911bceb06ed376801251bdfd992905a66f276c @swiftTest def test_swift_protocol_types(self): """Test support for protocol types""" From caa575bb1aef5b4bbdd7a54c8969032df24bf538 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Mon, 19 Oct 2020 21:54:46 -0700 Subject: [PATCH 155/234] Use LLVM_TOOLCHAIN_UTILITIES to allow utils to be installed in the toolchain Make it possible to specify a list of utilities that should be installed in the toolchain. Differential revision: https://reviews.llvm.org/D89762 (cherry picked from commit 024921a5e165cc2e0fa7c1b3732aff6f3f5df60b) --- llvm/cmake/modules/AddLLVM.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index b2c78d0b88e68..e171698a8d9fb 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -1226,7 +1226,7 @@ macro(add_llvm_utility name) add_llvm_executable(${name} DISABLE_LLVM_LINK_LLVM_DYLIB ${ARGN}) set_target_properties(${name} PROPERTIES FOLDER "Utils") - if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) + if ( ${name} IN_LIST LLVM_TOOLCHAIN_UTILITIES OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY) if (LLVM_INSTALL_UTILS AND LLVM_BUILD_UTILS) set(export_to_llvmexports) if (${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR From acf0294d1892dd26801d942d50ea81457cd59de5 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 20 Oct 2020 13:46:34 -0700 Subject: [PATCH 156/234] [Apple-stage2] Install FileCheck and yaml2obj in the toolchain rdar://70274446 Differential revision: https://reviews.llvm.org/D89763 (cherry picked from commit 27a909a24f99d4de40c4ce6553b9cd420b11c056) --- clang/cmake/caches/Apple-stage2.cmake | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/clang/cmake/caches/Apple-stage2.cmake b/clang/cmake/caches/Apple-stage2.cmake index b24ec558c071d..ff9c612b98082 100644 --- a/clang/cmake/caches/Apple-stage2.cmake +++ b/clang/cmake/caches/Apple-stage2.cmake @@ -58,6 +58,13 @@ set(LLVM_TOOLCHAIN_TOOLS llvm-size CACHE STRING "") +set(LLVM_BUILD_UTILS ON CACHE BOOL "") +set(LLVM_INSTALL_UTILS ON CACHE BOOL "") +set(LLVM_TOOLCHAIN_UTILITIES + FileCheck + yaml2obj + CACHE STRING "") + set(LLVM_DISTRIBUTION_COMPONENTS clang LTO @@ -66,6 +73,7 @@ set(LLVM_DISTRIBUTION_COMPONENTS cxx-headers Remarks ${LLVM_TOOLCHAIN_TOOLS} + ${LLVM_TOOLCHAIN_UTILITIES} CACHE STRING "") # test args From c82e10b65536e9bd8f2438a5f4dcb060f88a08f2 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Tue, 20 Oct 2020 14:20:38 -0700 Subject: [PATCH 157/234] TypeSystem: Avoid the ISO646 spelling of the logical operators Avoid the use of the ISO646 logical operator spelling. This enables the removal of the use of the `ciso646` header which can cause some issues when building Swift. --- lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index 3d3b26a401642..c893920976808 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -401,9 +401,9 @@ template <> struct less { for (; iL >= 0 && iR >= 0; --iL, --iR) { bool bL = lhs[iL]; bool bR = rhs[iR]; - if (bL and not bR) + if (bL && !bR) return false; - if (bR and not bL) + if (bR && !bL) return true; } return false; From 9a8083d9629d9b4e287cf0d218b9a65af235d3ac Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 20 Oct 2020 11:20:22 -0700 Subject: [PATCH 158/234] Remove validation from GetTypeBitAlign. This method doesn't use VALIDATE_AND_RETURN because except for fixed-size types the SwiftASTContext implementation forwards to SwiftLanguageRuntime anyway and for some fixed-size types the fixed layout still returns an incorrect default alignment of 0. --- .../Swift/TypeSystemSwiftTypeRef.cpp | 76 +++++++++---------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index accd5a706648f..5b4a68ed568ad 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -2091,48 +2091,46 @@ bool TypeSystemSwiftTypeRef::IsPointerOrReferenceType( llvm::Optional TypeSystemSwiftTypeRef::GetTypeBitAlign(opaque_compiler_type_t type, ExecutionContextScope *exe_scope) { - auto impl = [&]() -> llvm::Optional { - // Clang types can be resolved even without a process. - if (CompilerType clang_type = GetAsClangTypeOrNull(type)) { - // Swift doesn't know pointers: return the size alignment of the - // object pointer instead of the underlying object. - if (Flags(clang_type.GetTypeInfo()).AllSet(eTypeIsObjC | eTypeIsClass)) - return GetPointerByteSize() * 8; - return clang_type.GetTypeBitAlign(exe_scope); - } - if (!exe_scope) { - LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), - "Couldn't compute alignment of type %s without an execution " - "context.", - AsMangledName(type)); - return {}; - } - if (auto *runtime = - SwiftLanguageRuntime::Get(exe_scope->CalculateProcess())) { - if (auto result = runtime->GetBitAlignment({this, type}, exe_scope)) - return result; - // If this is an expression context, perhaps the type was - // defined in the expression. In that case we don't have debug - // info for it, so defer to SwiftASTContext. - if (llvm::isa(m_swift_ast_context)) - return ReconstructType({this, type}).GetTypeBitAlign(exe_scope); - } - - // If there is no process, we can still try to get the static - // alignment information out of DWARF. Because it is stored in the - // Type object we need to look that up by name again. - if (TypeSP type_sp = LookupTypeInModule(type)) - return type_sp->GetLayoutCompilerType().GetTypeBitAlign(exe_scope); + // This method doesn't use VALIDATE_AND_RETURN because except for + // fixed-size types the SwiftASTContext implementation forwards to + // SwiftLanguageRuntime anyway and for many fixed-size types the + // fixed layout still returns an incorrect default alignment of 0. + // + // Clang types can be resolved even without a process. + if (CompilerType clang_type = GetAsClangTypeOrNull(type)) { + // Swift doesn't know pointers: return the size alignment of the + // object pointer instead of the underlying object. + if (Flags(clang_type.GetTypeInfo()).AllSet(eTypeIsObjC | eTypeIsClass)) + return GetPointerByteSize() * 8; + return clang_type.GetTypeBitAlign(exe_scope); + } + if (!exe_scope) { LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), - "Couldn't compute alignment of type %s without a process.", + "Couldn't compute alignment of type %s without an execution " + "context.", AsMangledName(type)); return {}; - }; - if (exe_scope && exe_scope->CalculateProcess()) - VALIDATE_AND_RETURN(impl, GetTypeBitAlign, type, - (ReconstructType(type), exe_scope)); - else - return impl(); + } + if (auto *runtime = + SwiftLanguageRuntime::Get(exe_scope->CalculateProcess())) { + if (auto result = runtime->GetBitAlignment({this, type}, exe_scope)) + return result; + // If this is an expression context, perhaps the type was + // defined in the expression. In that case we don't have debug + // info for it, so defer to SwiftASTContext. + if (llvm::isa(m_swift_ast_context)) + return ReconstructType({this, type}).GetTypeBitAlign(exe_scope); + } + + // If there is no process, we can still try to get the static + // alignment information out of DWARF. Because it is stored in the + // Type object we need to look that up by name again. + if (TypeSP type_sp = LookupTypeInModule(type)) + return type_sp->GetLayoutCompilerType().GetTypeBitAlign(exe_scope); + LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES), + "Couldn't compute alignment of type %s without a process.", + AsMangledName(type)); + return {}; } bool TypeSystemSwiftTypeRef::IsTypedefType(opaque_compiler_type_t type) { return m_swift_ast_context->IsTypedefType(ReconstructType(type)); From 5c10c169a0d44587361f29e64326bcffc91c19e0 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 20 Oct 2020 13:28:44 -0700 Subject: [PATCH 159/234] Remove obsolete early exit. --- lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index 5b4a68ed568ad..02f6fe7e7cae7 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1910,7 +1910,7 @@ bool TypeSystemSwiftTypeRef::IsImportedType(opaque_compiler_type_t type, StringRef ident = GetObjCTypeName(node); if (ident.empty()) return {}; - if (original_type && GetModule()) + if (original_type) if (TypeSP clang_type = LookupClangType(m_swift_ast_context, ident)) *original_type = clang_type->GetForwardCompilerType(); return true; From 9e8e885bb80d569d7de661a7d6a198f1f3c67f5f Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 20 Oct 2020 14:22:05 -0700 Subject: [PATCH 160/234] delete commented-out code --- .../Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp index 115fcbd696d4d..a2b51aeafa01b 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp @@ -998,8 +998,6 @@ MaterializeVariable(SwiftASTManipulatorBase::VariableInfo &variable, }); actual_type = ToCompilerType(transformed_type->mapTypeOutOfContext().getPointer()); - // CompilerType return_ast_type = - // ToCompilerType(result_type->mapTypeOutOfContext()); auto *swift_ast_ctx = llvm::cast(actual_type.GetTypeSystem()); From 66359bb34b4bf3917650cc425b2473f1ad3607e9 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 20 Oct 2020 14:52:11 -0700 Subject: [PATCH 161/234] unxfail passing tests --- .../API/lang/swift/dwarfimporter/C/TestSwiftDWARFImporterC.py | 1 - lldb/test/API/lang/swift/optionset/TestSwiftOptionSetType.py | 1 - 2 files changed, 2 deletions(-) diff --git a/lldb/test/API/lang/swift/dwarfimporter/C/TestSwiftDWARFImporterC.py b/lldb/test/API/lang/swift/dwarfimporter/C/TestSwiftDWARFImporterC.py index 5246a2f849ca5..dfd8ae0736560 100644 --- a/lldb/test/API/lang/swift/dwarfimporter/C/TestSwiftDWARFImporterC.py +++ b/lldb/test/API/lang/swift/dwarfimporter/C/TestSwiftDWARFImporterC.py @@ -67,7 +67,6 @@ def test_dwarf_importer(self): target.Clear() lldb.SBDebugger.MemoryPressureDetected() - @expectedFailureAll #FIXME: This regressed silently due to 2c911bceb06ed376801251bdfd992905a66f276c @skipIf(archs=['ppc64le'], bugnumber='SR-10214') @swiftTest # This test needs a working Remote Mirrors implementation. diff --git a/lldb/test/API/lang/swift/optionset/TestSwiftOptionSetType.py b/lldb/test/API/lang/swift/optionset/TestSwiftOptionSetType.py index d8d389548bf19..e12d83951c722 100644 --- a/lldb/test/API/lang/swift/optionset/TestSwiftOptionSetType.py +++ b/lldb/test/API/lang/swift/optionset/TestSwiftOptionSetType.py @@ -14,7 +14,6 @@ lldbinline.MakeInlineTest(__file__, globals(), decorators=[swiftTest,skipUnlessDarwin, - expectedFailureAll, #FIXME: This regressed silently due to 2c911bceb06ed376801251bdfd992905a66f276c expectedFailureAll(bugnumber="rdar://60396797", setting=('symbols.use-swift-clangimporter', 'false')) ]) From 33f81b51e06b8527ce68127f24e6197319379ce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= Date: Fri, 14 Aug 2020 17:03:26 +0200 Subject: [PATCH 162/234] [ORC] Add a LLJITWithThinLTOSummaries example in OrcV2Examples The example demonstrates how to use a module summary index file produced for ThinLTO to: * find the module that defines the main entry point * find all extra modules that are required for the build A LIT test runs the example as part of the LLVM test suite [1] and shows how to create a module summary index file. The code also provides two Error types that can be useful when working with ThinLTO summaries. [1] if LLVM_BUILD_EXAMPLES=ON and platform is not Windows Differential Revision: https://reviews.llvm.org/D85974 --- llvm/examples/OrcV2Examples/CMakeLists.txt | 1 + .../LLJITWithThinLTOSummaries/CMakeLists.txt | 12 + .../LLJITWithThinLTOSummaries.cpp | 240 ++++++++++++++++++ .../Examples/OrcV2Examples/Inputs/bar-mod.ll | 7 + .../Examples/OrcV2Examples/Inputs/foo-mod.ll | 7 + .../Examples/OrcV2Examples/Inputs/main-mod.ll | 27 ++ .../lljit-with-thinlto-summaries.test | 12 + llvm/test/Examples/lit.local.cfg | 5 +- 8 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 llvm/examples/OrcV2Examples/LLJITWithThinLTOSummaries/CMakeLists.txt create mode 100644 llvm/examples/OrcV2Examples/LLJITWithThinLTOSummaries/LLJITWithThinLTOSummaries.cpp create mode 100644 llvm/test/Examples/OrcV2Examples/Inputs/bar-mod.ll create mode 100644 llvm/test/Examples/OrcV2Examples/Inputs/foo-mod.ll create mode 100644 llvm/test/Examples/OrcV2Examples/Inputs/main-mod.ll create mode 100644 llvm/test/Examples/OrcV2Examples/lljit-with-thinlto-summaries.test diff --git a/llvm/examples/OrcV2Examples/CMakeLists.txt b/llvm/examples/OrcV2Examples/CMakeLists.txt index 74a90aa07f131..cf19fbc76ff50 100644 --- a/llvm/examples/OrcV2Examples/CMakeLists.txt +++ b/llvm/examples/OrcV2Examples/CMakeLists.txt @@ -7,6 +7,7 @@ add_subdirectory(LLJITWithLazyReexports) add_subdirectory(LLJITWithObjectCache) add_subdirectory(LLJITWithObjectLinkingLayerPlugin) add_subdirectory(LLJITWithTargetProcessControl) +add_subdirectory(LLJITWithThinLTOSummaries) add_subdirectory(OrcV2CBindingsAddObjectFile) add_subdirectory(OrcV2CBindingsBasicUsage) add_subdirectory(OrcV2CBindingsReflectProcessSymbols) diff --git a/llvm/examples/OrcV2Examples/LLJITWithThinLTOSummaries/CMakeLists.txt b/llvm/examples/OrcV2Examples/LLJITWithThinLTOSummaries/CMakeLists.txt new file mode 100644 index 0000000000000..22262e4eb5b97 --- /dev/null +++ b/llvm/examples/OrcV2Examples/LLJITWithThinLTOSummaries/CMakeLists.txt @@ -0,0 +1,12 @@ +set(LLVM_LINK_COMPONENTS + Core + ExecutionEngine + IRReader + OrcJIT + Support + nativecodegen + ) + +add_llvm_example(LLJITWithThinLTOSummaries + LLJITWithThinLTOSummaries.cpp + ) diff --git a/llvm/examples/OrcV2Examples/LLJITWithThinLTOSummaries/LLJITWithThinLTOSummaries.cpp b/llvm/examples/OrcV2Examples/LLJITWithThinLTOSummaries/LLJITWithThinLTOSummaries.cpp new file mode 100644 index 0000000000000..25a899b70c88f --- /dev/null +++ b/llvm/examples/OrcV2Examples/LLJITWithThinLTOSummaries/LLJITWithThinLTOSummaries.cpp @@ -0,0 +1,240 @@ +//===--- LLJITWithThinLTOSummaries.cpp - Module summaries as LLJIT input --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// In this example we will use a module summary index file produced for ThinLTO +// to (A) find the module that defines the main entry point and (B) find all +// extra modules that we need. We will do this in five steps: +// +// (1) Read the index file and parse the module summary index. +// (2) Find the path of the module that defines "main". +// (3) Parse the main module and create a matching LLJIT. +// (4) Add all modules to the LLJIT that are covered by the index. +// (5) Look up and run the JIT'd function. +// +// The index file name must be passed in as command line argument. Please find +// this test for instructions on creating the index file: +// +// llvm/test/Examples/OrcV2Examples/lljit-with-thinlto-summaries.test +// +// If you use "build" as the build directory, you can run the test from the root +// of the monorepo like this: +// +// > build/bin/llvm-lit -a \ +// llvm/test/Examples/OrcV2Examples/lljit-with-thinlto-summaries.test +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Bitcode/BitcodeReader.h" +#include "llvm/ExecutionEngine/Orc/Core.h" +#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" +#include "llvm/ExecutionEngine/Orc/LLJIT.h" +#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/ModuleSummaryIndex.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/InitLLVM.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include +#include + +using namespace llvm; +using namespace llvm::orc; + +// Path of the module summary index file. +cl::opt IndexFile{cl::desc(""), + cl::Positional, cl::init("-")}; + +// Describe a fail state that is caused by the given ModuleSummaryIndex +// providing multiple definitions of the given global value name. It will dump +// name and GUID for the global value and list the paths of the modules covered +// by the index. +class DuplicateDefinitionInSummary + : public ErrorInfo { +public: + static char ID; + + DuplicateDefinitionInSummary(std::string GlobalValueName, ValueInfo VI) + : GlobalValueName(std::move(GlobalValueName)) { + ModulePaths.reserve(VI.getSummaryList().size()); + for (const auto &S : VI.getSummaryList()) + ModulePaths.push_back(S->modulePath().str()); + llvm::sort(ModulePaths); + } + + void log(raw_ostream &OS) const override { + OS << "Duplicate symbol for global value '" << GlobalValueName + << "' (GUID: " << GlobalValue::getGUID(GlobalValueName) << ") in:\n"; + for (const std::string &Path : ModulePaths) { + OS << " " << Path << "\n"; + } + } + + std::error_code convertToErrorCode() const override { + return inconvertibleErrorCode(); + } + +private: + std::string GlobalValueName; + std::vector ModulePaths; +}; + +// Describe a fail state where the given global value name was not found in the +// given ModuleSummaryIndex. It will dump name and GUID for the global value and +// list the paths of the modules covered by the index. +class DefinitionNotFoundInSummary + : public ErrorInfo { +public: + static char ID; + + DefinitionNotFoundInSummary(std::string GlobalValueName, + ModuleSummaryIndex &Index) + : GlobalValueName(std::move(GlobalValueName)) { + ModulePaths.reserve(Index.modulePaths().size()); + for (const auto &Entry : Index.modulePaths()) + ModulePaths.push_back(Entry.first().str()); + llvm::sort(ModulePaths); + } + + void log(raw_ostream &OS) const override { + OS << "No symbol for global value '" << GlobalValueName + << "' (GUID: " << GlobalValue::getGUID(GlobalValueName) << ") in:\n"; + for (const std::string &Path : ModulePaths) { + OS << " " << Path << "\n"; + } + } + + std::error_code convertToErrorCode() const override { + return llvm::inconvertibleErrorCode(); + } + +private: + std::string GlobalValueName; + std::vector ModulePaths; +}; + +char DuplicateDefinitionInSummary::ID = 0; +char DefinitionNotFoundInSummary::ID = 0; + +// Lookup the a function in the ModuleSummaryIndex and return the path of the +// module that defines it. Paths in the ModuleSummaryIndex are relative to the +// build directory of the covered modules. +Expected getMainModulePath(StringRef FunctionName, + ModuleSummaryIndex &Index) { + // Summaries use unmangled names. + GlobalValue::GUID G = GlobalValue::getGUID(FunctionName); + ValueInfo VI = Index.getValueInfo(G); + + // We need a unique definition, otherwise don't try further. + if (!VI || VI.getSummaryList().empty()) + return make_error(FunctionName.str(), Index); + if (VI.getSummaryList().size() > 1) + return make_error(FunctionName.str(), VI); + + GlobalValueSummary *S = VI.getSummaryList().front()->getBaseObject(); + if (!isa(S)) + return createStringError(inconvertibleErrorCode(), + "Entry point is not a function: " + FunctionName); + + // Return a reference. ModuleSummaryIndex owns the module paths. + return S->modulePath(); +} + +// Parse the bitcode module from the given path into a ThreadSafeModule. +Expected loadModule(StringRef Path, + orc::ThreadSafeContext TSCtx) { + outs() << "About to load module: " << Path << "\n"; + + Expected> BitcodeBuffer = + errorOrToExpected(MemoryBuffer::getFile(Path)); + if (!BitcodeBuffer) + return BitcodeBuffer.takeError(); + + MemoryBufferRef BitcodeBufferRef = (**BitcodeBuffer).getMemBufferRef(); + Expected> M = + parseBitcodeFile(BitcodeBufferRef, *TSCtx.getContext()); + if (!M) + return M.takeError(); + + return ThreadSafeModule(std::move(*M), std::move(TSCtx)); +} + +int main(int Argc, char *Argv[]) { + InitLLVM X(Argc, Argv); + + InitializeNativeTarget(); + InitializeNativeTargetAsmPrinter(); + + cl::ParseCommandLineOptions(Argc, Argv, "LLJITWithThinLTOSummaries"); + + ExitOnError ExitOnErr; + ExitOnErr.setBanner(std::string(Argv[0]) + ": "); + + // (1) Read the index file and parse the module summary index. + std::unique_ptr SummaryBuffer = + ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(IndexFile))); + + std::unique_ptr SummaryIndex = + ExitOnErr(getModuleSummaryIndex(SummaryBuffer->getMemBufferRef())); + + // (2) Find the path of the module that defines "main". + std::string MainFunctionName = "main"; + StringRef MainModulePath = + ExitOnErr(getMainModulePath(MainFunctionName, *SummaryIndex)); + + // (3) Parse the main module and create a matching LLJIT. + ThreadSafeContext TSCtx(std::make_unique()); + ThreadSafeModule MainModule = ExitOnErr(loadModule(MainModulePath, TSCtx)); + + auto Builder = LLJITBuilder(); + + MainModule.withModuleDo([&](Module &M) { + if (M.getTargetTriple().empty()) { + Builder.setJITTargetMachineBuilder( + ExitOnErr(JITTargetMachineBuilder::detectHost())); + } else { + Builder.setJITTargetMachineBuilder( + JITTargetMachineBuilder(Triple(M.getTargetTriple()))); + } + if (!M.getDataLayout().getStringRepresentation().empty()) + Builder.setDataLayout(M.getDataLayout()); + }); + + auto J = ExitOnErr(Builder.create()); + + // (4) Add all modules to the LLJIT that are covered by the index. + JITDylib &JD = J->getMainJITDylib(); + + for (const auto &Entry : SummaryIndex->modulePaths()) { + StringRef Path = Entry.first(); + ThreadSafeModule M = (Path == MainModulePath) + ? std::move(MainModule) + : ExitOnErr(loadModule(Path, TSCtx)); + ExitOnErr(J->addIRModule(JD, std::move(M))); + } + + // (5) Look up and run the JIT'd function. + auto MainSym = ExitOnErr(J->lookup(MainFunctionName)); + + using MainFnPtr = int (*)(int, char *[]); + MainFnPtr MainFunction = + jitTargetAddressToFunction(MainSym.getAddress()); + + int Result = runAsMain(MainFunction, {}, MainModulePath); + outs() << "'" << MainFunctionName << "' finished with exit code: " << Result + << "\n"; + + return 0; +} diff --git a/llvm/test/Examples/OrcV2Examples/Inputs/bar-mod.ll b/llvm/test/Examples/OrcV2Examples/Inputs/bar-mod.ll new file mode 100644 index 0000000000000..aad22f8ce783b --- /dev/null +++ b/llvm/test/Examples/OrcV2Examples/Inputs/bar-mod.ll @@ -0,0 +1,7 @@ +define i32 @bar() { + ret i32 0 +} + +^0 = module: (path: "bar-mod.o", hash: (3482110761, 1514484043, 2322286514, 2767576375, 2807967785)) +^1 = gv: (name: "bar", summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0, canAutoHide: 0), insts: 1, funcFlags: (readNone: 0, readOnly: 0, noRecurse: 0, returnDoesNotAlias: 0, noInline: 1, alwaysInline: 0)))) ; guid = 16434608426314478903 +^2 = blockcount: 0 diff --git a/llvm/test/Examples/OrcV2Examples/Inputs/foo-mod.ll b/llvm/test/Examples/OrcV2Examples/Inputs/foo-mod.ll new file mode 100644 index 0000000000000..e08e1ddb897d4 --- /dev/null +++ b/llvm/test/Examples/OrcV2Examples/Inputs/foo-mod.ll @@ -0,0 +1,7 @@ +define i32 @foo() { + ret i32 0 +} + +^0 = module: (path: "foo-mod.o", hash: (3133549885, 2087596051, 4175159200, 756405190, 968713858)) +^1 = gv: (name: "foo", summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0, canAutoHide: 0), insts: 1, funcFlags: (readNone: 0, readOnly: 0, noRecurse: 0, returnDoesNotAlias: 0, noInline: 1, alwaysInline: 0)))) ; guid = 6699318081062747564 +^2 = blockcount: 0 diff --git a/llvm/test/Examples/OrcV2Examples/Inputs/main-mod.ll b/llvm/test/Examples/OrcV2Examples/Inputs/main-mod.ll new file mode 100644 index 0000000000000..d3b39061b56d2 --- /dev/null +++ b/llvm/test/Examples/OrcV2Examples/Inputs/main-mod.ll @@ -0,0 +1,27 @@ +define i32 @main(i32 %argc, i8** %argv) { +entry: + %and = and i32 %argc, 1 + %tobool = icmp eq i32 %and, 0 + br i1 %tobool, label %if.end, label %if.then + +if.then: ; preds = %entry + %call = tail call i32 @foo() #2 + br label %return + +if.end: ; preds = %entry + %call1 = tail call i32 @bar() #2 + br label %return + +return: ; preds = %if.end, %if.then + %retval.0 = phi i32 [ %call, %if.then ], [ %call1, %if.end ] + ret i32 %retval.0 +} + +declare i32 @foo() +declare i32 @bar() + +^0 = module: (path: "main-mod.o", hash: (1466373418, 2110622332, 1230295500, 3229354382, 2004933020)) +^1 = gv: (name: "foo") ; guid = 6699318081062747564 +^2 = gv: (name: "main", summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0, canAutoHide: 0), insts: 22, funcFlags: (readNone: 0, readOnly: 0, noRecurse: 1, returnDoesNotAlias: 0, noInline: 1, alwaysInline: 0), calls: ((callee: ^1), (callee: ^3))))) ; guid = 15822663052811949562 +^3 = gv: (name: "bar") ; guid = 16434608426314478903 +^4 = blockcount: 0 diff --git a/llvm/test/Examples/OrcV2Examples/lljit-with-thinlto-summaries.test b/llvm/test/Examples/OrcV2Examples/lljit-with-thinlto-summaries.test new file mode 100644 index 0000000000000..f82ac41bce38d --- /dev/null +++ b/llvm/test/Examples/OrcV2Examples/lljit-with-thinlto-summaries.test @@ -0,0 +1,12 @@ +# RUN: opt -module-summary %p/Inputs/main-mod.ll -o main-mod.bc +# RUN: opt -module-summary %p/Inputs/foo-mod.ll -o foo-mod.bc +# RUN: opt -module-summary %p/Inputs/bar-mod.ll -o bar-mod.bc + +# RUN: llvm-lto -thinlto -o main-foo-bar main-mod.bc foo-mod.bc bar-mod.bc + +# RUN: LLJITWithThinLTOSummaries main-foo-bar.thinlto.bc 2>&1 | FileCheck %s + +# CHECK: About to load module: main-mod.bc +# CHECK: About to load module: foo-mod.bc +# CHECK: About to load module: bar-mod.bc +# CHECK: 'main' finished with exit code: 0 diff --git a/llvm/test/Examples/lit.local.cfg b/llvm/test/Examples/lit.local.cfg index 72f5c0fff056d..a9f3860333603 100644 --- a/llvm/test/Examples/lit.local.cfg +++ b/llvm/test/Examples/lit.local.cfg @@ -1,2 +1,5 @@ if not config.build_examples or sys.platform in ['win32']: - config.unsupported = True \ No newline at end of file + config.unsupported = True + +# Test discovery should ignore subdirectories that contain test inputs. +config.excludes = ['Inputs'] From 3a625600a5da56e97b8e8fdfda0f39b17acbff9a Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Sun, 23 Aug 2020 20:34:57 -0700 Subject: [PATCH 163/234] [ORC] Fix an endif comment. --- llvm/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h index db9cd1b98cf9c..90097f1131f31 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/TPCIndirectionUtils.h @@ -206,4 +206,4 @@ TPCIndirectionUtils::CreateWithABI(TargetProcessControl &TPC) { } // end namespace orc } // end namespace llvm -#endif // LLVM_EXECUTIONENGINE_ORC_T_H +#endif // LLVM_EXECUTIONENGINE_ORC_TPCINDIRECTIONUTILS_H From d07ed0cf606c618db794a13671ba1766339d563e Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Tue, 25 Aug 2020 11:50:32 -0700 Subject: [PATCH 164/234] [examples] Fix dependencies for OrcV2Examples/LLJITWithThinLTOSummaries. --- .../OrcV2Examples/LLJITWithThinLTOSummaries/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/examples/OrcV2Examples/LLJITWithThinLTOSummaries/CMakeLists.txt b/llvm/examples/OrcV2Examples/LLJITWithThinLTOSummaries/CMakeLists.txt index 22262e4eb5b97..175e655007050 100644 --- a/llvm/examples/OrcV2Examples/LLJITWithThinLTOSummaries/CMakeLists.txt +++ b/llvm/examples/OrcV2Examples/LLJITWithThinLTOSummaries/CMakeLists.txt @@ -1,7 +1,7 @@ set(LLVM_LINK_COMPONENTS + BitReader Core ExecutionEngine - IRReader OrcJIT Support nativecodegen From 35de35dd985e0b4c71e8a10fc859b8b1c6aae859 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Wed, 26 Aug 2020 16:56:33 -0700 Subject: [PATCH 165/234] [ORC][JITLink] Switch to unique ownership for EHFrameRegistrars. This will make stateful registrars (e.g. a future TargetProcessControl based registrar) easier to deal with. --- .../ExecutionEngine/JITLink/EHFrameSupport.h | 25 ++----------------- .../ExecutionEngine/Orc/ObjectLinkingLayer.h | 5 ++-- .../JITLink/EHFrameSupport.cpp | 15 ++++++++--- llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 2 +- .../Orc/ObjectLinkingLayer.cpp | 13 +++++----- llvm/tools/llvm-jitlink/llvm-jitlink.cpp | 2 +- 6 files changed, 24 insertions(+), 38 deletions(-) diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h b/llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h index 72687682f606c..72394d7c99854 100644 --- a/llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/EHFrameSupport.h @@ -42,32 +42,11 @@ class EHFrameRegistrar { /// Registers / Deregisters EH-frames in the current process. class InProcessEHFrameRegistrar final : public EHFrameRegistrar { public: - /// Get a reference to the InProcessEHFrameRegistrar singleton. - static InProcessEHFrameRegistrar &getInstance(); - - InProcessEHFrameRegistrar(const InProcessEHFrameRegistrar &) = delete; - InProcessEHFrameRegistrar & - operator=(const InProcessEHFrameRegistrar &) = delete; - - InProcessEHFrameRegistrar(InProcessEHFrameRegistrar &&) = delete; - InProcessEHFrameRegistrar &operator=(InProcessEHFrameRegistrar &&) = delete; - Error registerEHFrames(JITTargetAddress EHFrameSectionAddr, - size_t EHFrameSectionSize) override { - return registerEHFrameSection( - jitTargetAddressToPointer(EHFrameSectionAddr), - EHFrameSectionSize); - } + size_t EHFrameSectionSize) override; Error deregisterEHFrames(JITTargetAddress EHFrameSectionAddr, - size_t EHFrameSectionSize) override { - return deregisterEHFrameSection( - jitTargetAddressToPointer(EHFrameSectionAddr), - EHFrameSectionSize); - } - -private: - InProcessEHFrameRegistrar(); + size_t EHFrameSectionSize) override; }; using StoreFrameRangeFunction = diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h index fbf9bde8a9d55..cb8ee130ab614 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h @@ -177,7 +177,8 @@ class ObjectLinkingLayer : public ObjectLayer { class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin { public: - EHFrameRegistrationPlugin(jitlink::EHFrameRegistrar &Registrar); + EHFrameRegistrationPlugin( + std::unique_ptr Registrar); Error notifyEmitted(MaterializationResponsibility &MR) override; void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT, jitlink::PassConfiguration &PassConfig) override; @@ -192,7 +193,7 @@ class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin { }; std::mutex EHFramePluginMutex; - jitlink::EHFrameRegistrar &Registrar; + std::unique_ptr Registrar; DenseMap InProcessLinks; DenseMap TrackedEHFrameRanges; std::vector UntrackedEHFrameRanges; diff --git a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp index 54ba9ac39ea6a..9eda6fb9ea77b 100644 --- a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp @@ -763,12 +763,19 @@ Error deregisterEHFrameSection(const void *EHFrameSectionAddr, EHFrameRegistrar::~EHFrameRegistrar() {} -InProcessEHFrameRegistrar &InProcessEHFrameRegistrar::getInstance() { - static InProcessEHFrameRegistrar Instance; - return Instance; +Error InProcessEHFrameRegistrar::registerEHFrames( + JITTargetAddress EHFrameSectionAddr, size_t EHFrameSectionSize) { + return registerEHFrameSection( + jitTargetAddressToPointer(EHFrameSectionAddr), + EHFrameSectionSize); } -InProcessEHFrameRegistrar::InProcessEHFrameRegistrar() {} +Error InProcessEHFrameRegistrar::deregisterEHFrames( + JITTargetAddress EHFrameSectionAddr, size_t EHFrameSectionSize) { + return deregisterEHFrameSection( + jitTargetAddressToPointer(EHFrameSectionAddr), + EHFrameSectionSize); +} LinkGraphPassFunction createEHFrameRecorderPass(const Triple &TT, diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp index 531a71d50b9ec..56dec8688441e 100644 --- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -984,7 +984,7 @@ Error LLJITBuilderState::prepareForConstruction() { ObjLinkingLayer = std::make_unique( ES, std::make_unique()); ObjLinkingLayer->addPlugin(std::make_unique( - jitlink::InProcessEHFrameRegistrar::getInstance())); + std::make_unique())); return std::move(ObjLinkingLayer); }; } diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp index 5b828ed84462a..50fa23d2f80fd 100644 --- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp @@ -536,8 +536,8 @@ Error ObjectLinkingLayer::removeAllModules() { } EHFrameRegistrationPlugin::EHFrameRegistrationPlugin( - EHFrameRegistrar &Registrar) - : Registrar(Registrar) {} + std::unique_ptr Registrar) + : Registrar(std::move(Registrar)) {} void EHFrameRegistrationPlugin::modifyPassConfig( MaterializationResponsibility &MR, const Triple &TT, @@ -572,7 +572,7 @@ Error EHFrameRegistrationPlugin::notifyEmitted( else UntrackedEHFrameRanges.push_back(EHFrameRange); - return Registrar.registerEHFrames(EHFrameRange.Addr, EHFrameRange.Size); + return Registrar->registerEHFrames(EHFrameRange.Addr, EHFrameRange.Size); } Error EHFrameRegistrationPlugin::notifyRemovingModule(VModuleKey K) { @@ -587,7 +587,7 @@ Error EHFrameRegistrationPlugin::notifyRemovingModule(VModuleKey K) { TrackedEHFrameRanges.erase(EHFrameRangeItr); - return Registrar.deregisterEHFrames(EHFrameRange.Addr, EHFrameRange.Size); + return Registrar->deregisterEHFrames(EHFrameRange.Addr, EHFrameRange.Size); } Error EHFrameRegistrationPlugin::notifyRemovingAllModules() { @@ -608,9 +608,8 @@ Error EHFrameRegistrationPlugin::notifyRemovingAllModules() { auto EHFrameRange = EHFrameRanges.back(); assert(EHFrameRange.Addr && "Untracked eh-frame range must not be null"); EHFrameRanges.pop_back(); - Err = joinErrors(std::move(Err), - Registrar.deregisterEHFrames(EHFrameRange.Addr, - EHFrameRange.Size)); + Err = joinErrors(std::move(Err), Registrar->deregisterEHFrames( + EHFrameRange.Addr, EHFrameRange.Size)); } return Err; diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp index ff9579bbf5b82..f1cc1f2550b31 100644 --- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp @@ -618,7 +618,7 @@ Session::Session(Triple TT, uint64_t PageSize, Error &Err) if (!NoExec && !TT.isOSWindows()) ObjLayer.addPlugin(std::make_unique( - InProcessEHFrameRegistrar::getInstance())); + std::make_unique())); ObjLayer.addPlugin(std::make_unique(*this)); From 1171d1eed8b6d9773057a5f76771a1b030ee7d85 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Sat, 29 Aug 2020 14:05:04 -0700 Subject: [PATCH 166/234] [ORC] Add getDFSLinkOrder / getReverseDFSLinkOrder methods to JITDylib. DFS and Reverse-DFS linkage orders are used to order execution of deinitializers and initializers respectively. This patch replaces uses of special purpose DFS order functions in MachOPlatform and LLJIT with uses of the new methods. --- llvm/include/llvm/ExecutionEngine/Orc/Core.h | 20 ++++ .../llvm/ExecutionEngine/Orc/MachOPlatform.h | 2 - llvm/lib/ExecutionEngine/Orc/Core.cpp | 51 +++++++++ llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 93 ++++++--------- .../lib/ExecutionEngine/Orc/MachOPlatform.cpp | 42 ++----- .../ExecutionEngine/Orc/CoreAPIsTest.cpp | 106 ++++++++++++++++++ 6 files changed, 223 insertions(+), 91 deletions(-) diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Core.h b/llvm/include/llvm/ExecutionEngine/Orc/Core.h index 101017f89def1..6951df3f2d3f2 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Core.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Core.h @@ -921,6 +921,26 @@ class JITDylib : public std::enable_shared_from_this { Expected legacyLookup(std::shared_ptr Q, SymbolNameSet Names); + /// Returns the given JITDylibs and all of their transitive dependencies in + /// DFS order (based on linkage relationships). Each JITDylib will appear + /// only once. + static std::vector> + getDFSLinkOrder(ArrayRef> JDs); + + /// Returns the given JITDylibs and all of their transitive dependensies in + /// reverse DFS order (based on linkage relationships). Each JITDylib will + /// appear only once. + static std::vector> + getReverseDFSLinkOrder(ArrayRef> JDs); + + /// Return this JITDylib and its transitive dependencies in DFS order + /// based on linkage relationships. + std::vector> getDFSLinkOrder(); + + /// Rteurn this JITDylib and its transitive dependencies in reverse DFS order + /// based on linkage relationships. + std::vector> getReverseDFSLinkOrder(); + private: using AsynchronousSymbolQueryList = std::vector>; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h b/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h index 15fe079eccafd..15cdc6bee3ce7 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h @@ -136,8 +136,6 @@ class MachOPlatform : public Platform { InitSymbolDepMap InitSymbolDeps; }; - static std::vector getDFSLinkOrder(JITDylib &JD); - void registerInitInfo(JITDylib &JD, JITTargetAddress ObjCImageInfoAddr, MachOJITDylibInitializers::SectionExtent ModInits, MachOJITDylibInitializers::SectionExtent ObjCSelRefs, diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp index bad13cfebbc6b..f623fc59a0a96 100644 --- a/llvm/lib/ExecutionEngine/Orc/Core.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp @@ -1884,6 +1884,57 @@ Expected ExecutionSession::legacyLookup( #endif } +std::vector> +JITDylib::getDFSLinkOrder(ArrayRef> JDs) { + if (JDs.empty()) + return {}; + + auto &ES = JDs.front()->getExecutionSession(); + return ES.runSessionLocked([&]() { + DenseSet Visited; + std::vector> Result; + + for (auto &JD : JDs) { + + if (Visited.count(JD.get())) + continue; + + SmallVector, 64> WorkStack; + WorkStack.push_back(JD); + Visited.insert(JD.get()); + + while (!WorkStack.empty()) { + Result.push_back(std::move(WorkStack.back())); + WorkStack.pop_back(); + + for (auto &KV : llvm::reverse(Result.back()->LinkOrder)) { + auto &JD = *KV.first; + if (Visited.count(&JD)) + continue; + Visited.insert(&JD); + WorkStack.push_back(JD.shared_from_this()); + } + } + } + return Result; + }); +}; + +std::vector> +JITDylib::getReverseDFSLinkOrder(ArrayRef> JDs) { + auto Tmp = getDFSLinkOrder(JDs); + std::reverse(Tmp.begin(), Tmp.end()); + return Tmp; +} + +std::vector> JITDylib::getDFSLinkOrder() { + return getDFSLinkOrder({shared_from_this()}); +} + +std::vector> JITDylib::getReverseDFSLinkOrder() { + return getReverseDFSLinkOrder({shared_from_this()}); +} + void ExecutionSession::lookup( LookupKind K, const JITDylibSearchOrder &SearchOrder, SymbolLookupSet Symbols, SymbolState RequiredState, diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp index 56dec8688441e..373d86d92f8d7 100644 --- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -261,23 +261,23 @@ class GenericLLVMIRPlatformSupport : public LLJIT::PlatformSupport { return std::move(Err); DenseMap LookupSymbols; - std::vector DFSLinkOrder; + std::vector> DFSLinkOrder; getExecutionSession().runSessionLocked([&]() { - DFSLinkOrder = getDFSLinkOrder(JD); - - for (auto *NextJD : DFSLinkOrder) { - auto IFItr = InitFunctions.find(NextJD); - if (IFItr != InitFunctions.end()) { - LookupSymbols[NextJD] = std::move(IFItr->second); - InitFunctions.erase(IFItr); - } + DFSLinkOrder = JD.getDFSLinkOrder(); + + for (auto &NextJD : DFSLinkOrder) { + auto IFItr = InitFunctions.find(NextJD.get()); + if (IFItr != InitFunctions.end()) { + LookupSymbols[NextJD.get()] = std::move(IFItr->second); + InitFunctions.erase(IFItr); } - }); + } + }); LLVM_DEBUG({ dbgs() << "JITDylib init order is [ "; - for (auto *JD : llvm::reverse(DFSLinkOrder)) + for (auto &JD : llvm::reverse(DFSLinkOrder)) dbgs() << "\"" << JD->getName() << "\" "; dbgs() << "]\n"; dbgs() << "Looking up init functions:\n"; @@ -311,26 +311,26 @@ class GenericLLVMIRPlatformSupport : public LLJIT::PlatformSupport { auto LLJITRunAtExits = J.mangleAndIntern("__lljit_run_atexits"); DenseMap LookupSymbols; - std::vector DFSLinkOrder; + std::vector> DFSLinkOrder; ES.runSessionLocked([&]() { - DFSLinkOrder = getDFSLinkOrder(JD); - - for (auto *NextJD : DFSLinkOrder) { - auto &JDLookupSymbols = LookupSymbols[NextJD]; - auto DIFItr = DeInitFunctions.find(NextJD); - if (DIFItr != DeInitFunctions.end()) { - LookupSymbols[NextJD] = std::move(DIFItr->second); - DeInitFunctions.erase(DIFItr); - } - JDLookupSymbols.add(LLJITRunAtExits, + DFSLinkOrder = JD.getDFSLinkOrder(); + + for (auto &NextJD : DFSLinkOrder) { + auto &JDLookupSymbols = LookupSymbols[NextJD.get()]; + auto DIFItr = DeInitFunctions.find(NextJD.get()); + if (DIFItr != DeInitFunctions.end()) { + LookupSymbols[NextJD.get()] = std::move(DIFItr->second); + DeInitFunctions.erase(DIFItr); + } + JDLookupSymbols.add(LLJITRunAtExits, SymbolLookupFlags::WeaklyReferencedSymbol); } }); LLVM_DEBUG({ dbgs() << "JITDylib deinit order is [ "; - for (auto *JD : DFSLinkOrder) + for (auto &JD : DFSLinkOrder) dbgs() << "\"" << JD->getName() << "\" "; dbgs() << "]\n"; dbgs() << "Looking up deinit functions:\n"; @@ -344,8 +344,8 @@ class GenericLLVMIRPlatformSupport : public LLJIT::PlatformSupport { return LookupResult.takeError(); std::vector DeInitializers; - for (auto *NextJD : DFSLinkOrder) { - auto DeInitsItr = LookupResult->find(NextJD); + for (auto &NextJD : DFSLinkOrder) { + auto DeInitsItr = LookupResult->find(NextJD.get()); assert(DeInitsItr != LookupResult->end() && "Every JD should have at least __lljit_run_atexits"); @@ -361,46 +361,23 @@ class GenericLLVMIRPlatformSupport : public LLJIT::PlatformSupport { return DeInitializers; } - // Returns a DFS traversal order of the JITDylibs reachable (via - // links-against edges) from JD, starting with JD itself. - static std::vector getDFSLinkOrder(JITDylib &JD) { - std::vector DFSLinkOrder; - std::vector WorkStack({&JD}); - DenseSet Visited; - - while (!WorkStack.empty()) { - auto &NextJD = *WorkStack.back(); - WorkStack.pop_back(); - if (Visited.count(&NextJD)) - continue; - Visited.insert(&NextJD); - DFSLinkOrder.push_back(&NextJD); - NextJD.withLinkOrderDo([&](const JITDylibSearchOrder &LinkOrder) { - for (auto &KV : LinkOrder) - WorkStack.push_back(KV.first); - }); - } - - return DFSLinkOrder; - } - /// Issue lookups for all init symbols required to initialize JD (and any /// JITDylibs that it depends on). Error issueInitLookups(JITDylib &JD) { DenseMap RequiredInitSymbols; - std::vector DFSLinkOrder; + std::vector> DFSLinkOrder; getExecutionSession().runSessionLocked([&]() { - DFSLinkOrder = getDFSLinkOrder(JD); - - for (auto *NextJD : DFSLinkOrder) { - auto ISItr = InitSymbols.find(NextJD); - if (ISItr != InitSymbols.end()) { - RequiredInitSymbols[NextJD] = std::move(ISItr->second); - InitSymbols.erase(ISItr); - } + DFSLinkOrder = JD.getDFSLinkOrder(); + + for (auto &NextJD : DFSLinkOrder) { + auto ISItr = InitSymbols.find(NextJD.get()); + if (ISItr != InitSymbols.end()) { + RequiredInitSymbols[NextJD.get()] = std::move(ISItr->second); + InitSymbols.erase(ISItr); } - }); + } + }); return Platform::lookupInitSymbols(getExecutionSession(), RequiredInitSymbols) diff --git a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp index 15c3aa79a2a84..2d6435f8dff19 100644 --- a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp +++ b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp @@ -185,19 +185,19 @@ MachOPlatform::getInitializerSequence(JITDylib &JD) { << JD.getName() << "\n"; }); - std::vector DFSLinkOrder; + std::vector> DFSLinkOrder; while (true) { DenseMap NewInitSymbols; ES.runSessionLocked([&]() { - DFSLinkOrder = getDFSLinkOrder(JD); + DFSLinkOrder = JD.getDFSLinkOrder(); - for (auto *InitJD : DFSLinkOrder) { - auto RISItr = RegisteredInitSymbols.find(InitJD); + for (auto &InitJD : DFSLinkOrder) { + auto RISItr = RegisteredInitSymbols.find(InitJD.get()); if (RISItr != RegisteredInitSymbols.end()) { - NewInitSymbols[InitJD] = std::move(RISItr->second); + NewInitSymbols[InitJD.get()] = std::move(RISItr->second); RegisteredInitSymbols.erase(RISItr); } } @@ -229,14 +229,14 @@ MachOPlatform::getInitializerSequence(JITDylib &JD) { InitializerSequence FullInitSeq; { std::lock_guard Lock(InitSeqsMutex); - for (auto *InitJD : reverse(DFSLinkOrder)) { + for (auto &InitJD : reverse(DFSLinkOrder)) { LLVM_DEBUG({ dbgs() << "MachOPlatform: Appending inits for \"" << InitJD->getName() << "\" to sequence\n"; }); - auto ISItr = InitSeqs.find(InitJD); + auto ISItr = InitSeqs.find(InitJD.get()); if (ISItr != InitSeqs.end()) { - FullInitSeq.emplace_back(InitJD, std::move(ISItr->second)); + FullInitSeq.emplace_back(InitJD.get(), std::move(ISItr->second)); InitSeqs.erase(ISItr); } } @@ -247,39 +247,19 @@ MachOPlatform::getInitializerSequence(JITDylib &JD) { Expected MachOPlatform::getDeinitializerSequence(JITDylib &JD) { - std::vector DFSLinkOrder = getDFSLinkOrder(JD); + std::vector> DFSLinkOrder = JD.getDFSLinkOrder(); DeinitializerSequence FullDeinitSeq; { std::lock_guard Lock(InitSeqsMutex); - for (auto *DeinitJD : DFSLinkOrder) { - FullDeinitSeq.emplace_back(DeinitJD, MachOJITDylibDeinitializers()); + for (auto &DeinitJD : DFSLinkOrder) { + FullDeinitSeq.emplace_back(DeinitJD.get(), MachOJITDylibDeinitializers()); } } return FullDeinitSeq; } -std::vector MachOPlatform::getDFSLinkOrder(JITDylib &JD) { - std::vector Result, WorkStack({&JD}); - DenseSet Visited; - - while (!WorkStack.empty()) { - auto *NextJD = WorkStack.back(); - WorkStack.pop_back(); - if (Visited.count(NextJD)) - continue; - Visited.insert(NextJD); - Result.push_back(NextJD); - NextJD->withLinkOrderDo([&](const JITDylibSearchOrder &LO) { - for (auto &KV : LO) - WorkStack.push_back(KV.first); - }); - } - - return Result; -} - void MachOPlatform::registerInitInfo( JITDylib &JD, JITTargetAddress ObjCImageInfoAddr, MachOJITDylibInitializers::SectionExtent ModInits, diff --git a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp index 6f6e1d43af93d..42d76080fdbf9 100644 --- a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp @@ -1325,4 +1325,110 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) { cantFail(FooResponsibility->notifyEmitted()); } +static bool linkOrdersEqual(const std::vector> &LHS, + ArrayRef RHS) { + if (LHS.size() != RHS.size()) + return false; + auto *RHSE = RHS.begin(); + for (auto &LHSE : LHS) + if (LHSE.get() != *RHSE) + return false; + else + ++RHSE; + return true; +}; + +TEST(JITDylibTest, GetDFSLinkOrderTree) { + // Test that DFS ordering behaves as expected when the linkage relationships + // form a tree. + + ExecutionSession ES; + + auto &LibA = ES.createBareJITDylib("A"); + auto &LibB = ES.createBareJITDylib("B"); + auto &LibC = ES.createBareJITDylib("C"); + auto &LibD = ES.createBareJITDylib("D"); + auto &LibE = ES.createBareJITDylib("E"); + auto &LibF = ES.createBareJITDylib("F"); + + // Linkage relationships: + // A --- B -- D + // \ \- E + // \- C -- F + LibA.setLinkOrder(makeJITDylibSearchOrder({&LibB, &LibC})); + LibB.setLinkOrder(makeJITDylibSearchOrder({&LibD, &LibE})); + LibC.setLinkOrder(makeJITDylibSearchOrder({&LibF})); + + auto DFSOrderFromB = JITDylib::getDFSLinkOrder({LibB.shared_from_this()}); + EXPECT_TRUE(linkOrdersEqual(DFSOrderFromB, {&LibB, &LibD, &LibE})) + << "Incorrect DFS link order for LibB"; + + auto DFSOrderFromA = JITDylib::getDFSLinkOrder({LibA.shared_from_this()}); + EXPECT_TRUE(linkOrdersEqual(DFSOrderFromA, + {&LibA, &LibB, &LibD, &LibE, &LibC, &LibF})) + << "Incorrect DFS link order for libA"; + + auto DFSOrderFromAB = JITDylib::getDFSLinkOrder( + {LibA.shared_from_this(), LibB.shared_from_this()}); + EXPECT_TRUE(linkOrdersEqual(DFSOrderFromAB, + {&LibA, &LibB, &LibD, &LibE, &LibC, &LibF})) + << "Incorrect DFS link order for { libA, libB }"; + + auto DFSOrderFromBA = JITDylib::getDFSLinkOrder( + {LibB.shared_from_this(), LibA.shared_from_this()}); + EXPECT_TRUE(linkOrdersEqual(DFSOrderFromBA, + {&LibB, &LibD, &LibE, &LibA, &LibC, &LibF})) + << "Incorrect DFS link order for { libB, libA }"; +} + +TEST(JITDylibTest, GetDFSLinkOrderDiamond) { + // Test that DFS ordering behaves as expected when the linkage relationships + // contain a diamond. + + ExecutionSession ES; + auto &LibA = ES.createBareJITDylib("A"); + auto &LibB = ES.createBareJITDylib("B"); + auto &LibC = ES.createBareJITDylib("C"); + auto &LibD = ES.createBareJITDylib("D"); + + // Linkage relationships: + // A -- B --- D + // \-- C --/ + LibA.setLinkOrder(makeJITDylibSearchOrder({&LibB, &LibC})); + LibB.setLinkOrder(makeJITDylibSearchOrder({&LibD})); + LibC.setLinkOrder(makeJITDylibSearchOrder({&LibD})); + + auto DFSOrderFromA = JITDylib::getDFSLinkOrder({LibA.shared_from_this()}); + EXPECT_TRUE(linkOrdersEqual(DFSOrderFromA, {&LibA, &LibB, &LibD, &LibC})) + << "Incorrect DFS link order for libA"; +} + +TEST(JITDylibTest, GetDFSLinkOrderCycle) { + // Test that DFS ordering behaves as expected when the linkage relationships + // contain a cycle. + + ExecutionSession ES; + auto &LibA = ES.createBareJITDylib("A"); + auto &LibB = ES.createBareJITDylib("B"); + auto &LibC = ES.createBareJITDylib("C"); + + // Linkage relationships: + // A -- B --- C -- A + LibA.setLinkOrder(makeJITDylibSearchOrder({&LibB})); + LibB.setLinkOrder(makeJITDylibSearchOrder({&LibC})); + LibC.setLinkOrder(makeJITDylibSearchOrder({&LibA})); + + auto DFSOrderFromA = JITDylib::getDFSLinkOrder({LibA.shared_from_this()}); + EXPECT_TRUE(linkOrdersEqual(DFSOrderFromA, {&LibA, &LibB, &LibC})) + << "Incorrect DFS link order for libA"; + + auto DFSOrderFromB = JITDylib::getDFSLinkOrder({LibB.shared_from_this()}); + EXPECT_TRUE(linkOrdersEqual(DFSOrderFromB, {&LibB, &LibC, &LibA})) + << "Incorrect DFS link order for libB"; + + auto DFSOrderFromC = JITDylib::getDFSLinkOrder({LibC.shared_from_this()}); + EXPECT_TRUE(linkOrdersEqual(DFSOrderFromC, {&LibC, &LibA, &LibB})) + << "Incorrect DFS link order for libC"; +} + } // namespace From 8ddd01a506878b0397add0f845fd221c1b418b6a Mon Sep 17 00:00:00 2001 From: Sourabh Singh Tomar Date: Mon, 31 Aug 2020 17:46:46 +0530 Subject: [PATCH 167/234] [NFCI] Silent a build warning due to an extra semi-colon --- llvm/lib/ExecutionEngine/Orc/Core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp index f623fc59a0a96..18eced68f07bc 100644 --- a/llvm/lib/ExecutionEngine/Orc/Core.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp @@ -1918,7 +1918,7 @@ JITDylib::getDFSLinkOrder(ArrayRef> JDs) { } return Result; }); -}; +} std::vector> JITDylib::getReverseDFSLinkOrder(ArrayRef> JDs) { From 4f7c68d6ad9ed2bcc4a51f9ba8a371d08113820b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 31 Aug 2020 22:25:25 +0300 Subject: [PATCH 168/234] [ORC] Remove a stray semicolon, silencing warnings. NFC. --- llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp index 42d76080fdbf9..5a83e6a2b04b4 100644 --- a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp @@ -1336,7 +1336,7 @@ static bool linkOrdersEqual(const std::vector> &LHS, else ++RHSE; return true; -}; +} TEST(JITDylibTest, GetDFSLinkOrderTree) { // Test that DFS ordering behaves as expected when the linkage relationships From 100d3f9a4fb34e6c4293ae7d4f0036ee7950eb8e Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Mon, 31 Aug 2020 15:16:03 -0700 Subject: [PATCH 169/234] [ORC] Remove an unused variable. The unused Main variable was accidentally left in an earlier commit. --- llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp index 50fa23d2f80fd..d8283fa7e3461 100644 --- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp @@ -71,9 +71,8 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { } // OnResolve -- De-intern the symbols and pass the result to the linker. - auto OnResolve = [this, LookupContinuation = std::move(LC)]( - Expected Result) mutable { - auto Main = Layer.getExecutionSession().intern("_main"); + auto OnResolve = [LookupContinuation = + std::move(LC)](Expected Result) mutable { if (!Result) LookupContinuation->run(Result.takeError()); else { From c6fc120c90decdedeafde30d1caa541e7ce69600 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Tue, 1 Sep 2020 12:10:23 -0700 Subject: [PATCH 170/234] [ORC] Add unit test for HasMaterializationSideEffectsOnly failure behavior. --- .../ExecutionEngine/Orc/CoreAPIsTest.cpp | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp index 5a83e6a2b04b4..2c008dfdbd33e 100644 --- a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp @@ -110,7 +110,7 @@ TEST_F(CoreAPIsStandardTest, ResolveUnrequestedSymbol) { EXPECT_TRUE(Result.count(Foo)) << "Expected result for \"Foo\""; } -TEST_F(CoreAPIsStandardTest, MaterializationSideEffctsOnlyTest) { +TEST_F(CoreAPIsStandardTest, MaterializationSideEffctsOnlyBasic) { // Test that basic materialization-side-effects-only symbols work as expected: // that they can be emitted without being resolved, that queries for them // don't return until they're emitted, and that they don't appear in query @@ -147,6 +147,24 @@ TEST_F(CoreAPIsStandardTest, MaterializationSideEffctsOnlyTest) { EXPECT_TRUE(Result->empty()) << "Lookup result contained unexpected value"; } +TEST_F(CoreAPIsStandardTest, MaterializationSideEffectsOnlyFailuresPersist) { + // Test that when a MaterializationSideEffectsOnly symbol is failed it + // remains in the failure state rather than vanishing. + + cantFail(JD.define(std::make_unique( + SymbolFlagsMap( + {{Foo, JITSymbolFlags::Exported | + JITSymbolFlags::MaterializationSideEffectsOnly}}), + [&](MaterializationResponsibility R) { R.failMaterialization(); }))); + + EXPECT_THAT_EXPECTED( + ES.lookup(makeJITDylibSearchOrder(&JD), SymbolLookupSet({Foo})), + Failed()); + EXPECT_THAT_EXPECTED( + ES.lookup(makeJITDylibSearchOrder(&JD), SymbolLookupSet({Foo})), + Failed()); +} + TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) { // Test that: // (1) Missing symbols generate a SymbolsNotFound error. From b59c73a1e68b0e00d76055ded9dc1bf8570a178f Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Tue, 1 Sep 2020 19:55:19 -0700 Subject: [PATCH 171/234] [ORC] Fix MachOPlatform's synthetic symbol dependence registration. A think-o in the existing code meant that dependencies were never registered. This failure could lead to crashes rather than orderly error propagation if initialization dependencies failed to materialize. No test case: The bug was discovered in an out-of-tree code and requires pathalogically misconfigured JIT to generate the original error that lead to the crash. --- llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp index 2d6435f8dff19..9ad2577d4174f 100644 --- a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp +++ b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp @@ -305,7 +305,7 @@ void MachOPlatform::InitScraperPlugin::modifyPassConfig( preserveInitSectionIfPresent(InitSectionSymbols, G, "__objc_selrefs"); preserveInitSectionIfPresent(InitSectionSymbols, G, "__objc_classlist"); - if (!InitSymbolDeps.empty()) { + if (!InitSectionSymbols.empty()) { std::lock_guard Lock(InitScraperMutex); InitSymbolDeps[&MR] = std::move(InitSectionSymbols); } From 86642a46fbed37faff317b2942a1207579403c1c Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Tue, 1 Sep 2020 20:00:21 -0700 Subject: [PATCH 172/234] [ORC] Add an early out for MachOPlatform's init-scraper plugin setup. If there's no initializer symbol in the current MaterializationResponsibility then bail out without installing JITLink passes: they're going to be no-ops anyway. --- llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp index 9ad2577d4174f..098e870c71183 100644 --- a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp +++ b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp @@ -299,6 +299,9 @@ void MachOPlatform::InitScraperPlugin::modifyPassConfig( MaterializationResponsibility &MR, const Triple &TT, jitlink::PassConfiguration &Config) { + if (!MR.getInitializerSymbol()) + return; + Config.PrePrunePasses.push_back([this, &MR](jitlink::LinkGraph &G) -> Error { JITLinkSymbolVector InitSectionSymbols; preserveInitSectionIfPresent(InitSectionSymbols, G, "__mod_init_func"); From ffed7085a9410c2cac847bf2a06653afed3ce857 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Tue, 1 Sep 2020 20:53:28 -0700 Subject: [PATCH 173/234] [ORC] Remove stray debugging output. --- llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp index 098e870c71183..6306cc8e1d018 100644 --- a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp +++ b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp @@ -326,10 +326,8 @@ void MachOPlatform::InitScraperPlugin::modifyPassConfig( JITTargetAddress ObjCImageInfoAddr = 0; if (auto *ObjCImageInfoSec = G.findSectionByName("__objc_image_info")) { - if (auto Addr = jitlink::SectionRange(*ObjCImageInfoSec).getStart()) { + if (auto Addr = jitlink::SectionRange(*ObjCImageInfoSec).getStart()) ObjCImageInfoAddr = Addr; - dbgs() << "Recorded __objc_imageinfo @ " << formatv("{0:x16}", Addr); - } } // Record __mod_init_func. From 8e6136f783e17a3f240472952311b41b1e834979 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Fri, 4 Sep 2020 12:27:40 -0700 Subject: [PATCH 174/234] [ORC] Fix some bugs in TPCDynamicLibrarySearchGenerator, use in llvm-jitlink. TPCDynamicLibrarySearchGenerator was generating errors on missing symbols, but that doesn't fit the DefinitionGenerator contract: A symbol that isn't generated by a particular generator should not cause an error. This commit fixes the error by using SymbolLookupFlags::WeaklyReferencedSymbol for all elements of the lookup, and switches llvm-jitlink to use TPCDynamicLibrarySearchGenerator. --- .../Orc/TPCDynamicLibrarySearchGenerator.h | 15 ++++++--- .../Orc/TargetProcessControl.h | 5 ++- .../Orc/TPCDynamicLibrarySearchGenerator.cpp | 32 +++++++++++++++---- .../Orc/TargetProcessControl.cpp | 6 ++-- llvm/tools/llvm-jitlink/llvm-jitlink.cpp | 12 ++----- 5 files changed, 46 insertions(+), 24 deletions(-) diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h b/llvm/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h index d35c8abc84a2e..7c1b72befde76 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h @@ -14,6 +14,7 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H #define LLVM_EXECUTIONENGINE_ORC_TPCDYNAMICLIBRARYSEARCHGENERATOR_H +#include "llvm/ADT/FunctionExtras.h" #include "llvm/ExecutionEngine/Orc/TargetProcessControl.h" namespace llvm { @@ -21,6 +22,8 @@ namespace orc { class TPCDynamicLibrarySearchGenerator : public JITDylib::DefinitionGenerator { public: + using SymbolPredicate = unique_function; + /// Create a DynamicLibrarySearchGenerator that searches for symbols in the /// library with the given handle. /// @@ -28,19 +31,22 @@ class TPCDynamicLibrarySearchGenerator : public JITDylib::DefinitionGenerator { /// will be searched for. If the predicate is not given then all symbols will /// be searched for. TPCDynamicLibrarySearchGenerator(TargetProcessControl &TPC, - TargetProcessControl::DylibHandle H) - : TPC(TPC), H(H) {} + TargetProcessControl::DylibHandle H, + SymbolPredicate Allow = SymbolPredicate()) + : TPC(TPC), H(H), Allow(std::move(Allow)) {} /// Permanently loads the library at the given path and, on success, returns /// a DynamicLibrarySearchGenerator that will search it for symbol definitions /// in the library. On failure returns the reason the library failed to load. static Expected> - Load(TargetProcessControl &TPC, const char *LibraryPath); + Load(TargetProcessControl &TPC, const char *LibraryPath, + SymbolPredicate Allow = SymbolPredicate()); /// Creates a TPCDynamicLibrarySearchGenerator that searches for symbols in /// the target process. static Expected> - GetForTargetProcess(TargetProcessControl &TPC) { + GetForTargetProcess(TargetProcessControl &TPC, + SymbolPredicate Allow = SymbolPredicate()) { return Load(TPC, nullptr); } @@ -51,6 +57,7 @@ class TPCDynamicLibrarySearchGenerator : public JITDylib::DefinitionGenerator { private: TargetProcessControl &TPC; TargetProcessControl::DylibHandle H; + SymbolPredicate Allow; }; } // end namespace orc diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h index 159b6e8d56df3..d3349753284e2 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcessControl.h @@ -149,8 +149,11 @@ class TargetProcessControl { virtual Expected loadDylib(const char *DylibPath) = 0; /// Search for symbols in the target process. + /// /// The result of the lookup is a 2-dimentional array of target addresses - /// that correspond to the lookup order. + /// that correspond to the lookup order. If a required symbol is not + /// found then this method will return an error. If a weakly referenced + /// symbol is not found then it be assigned a '0' value in the result. virtual Expected lookupSymbols(LookupRequest Request) = 0; protected: diff --git a/llvm/lib/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.cpp b/llvm/lib/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.cpp index 18de5b616eec8..d85f3c38feb9d 100644 --- a/llvm/lib/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.cpp +++ b/llvm/lib/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.cpp @@ -13,12 +13,14 @@ namespace orc { Expected> TPCDynamicLibrarySearchGenerator::Load(TargetProcessControl &TPC, - const char *LibraryPath) { + const char *LibraryPath, + SymbolPredicate Allow) { auto Handle = TPC.loadDylib(LibraryPath); if (!Handle) return Handle.takeError(); - return std::make_unique(TPC, *Handle); + return std::make_unique(TPC, *Handle, + std::move(Allow)); } Error TPCDynamicLibrarySearchGenerator::tryToGenerate( @@ -28,22 +30,38 @@ Error TPCDynamicLibrarySearchGenerator::tryToGenerate( if (Symbols.empty()) return Error::success(); + SymbolLookupSet LookupSymbols; + + for (auto &KV : Symbols) { + // Skip symbols that don't match the filter. + if (Allow && !Allow(KV.first)) + continue; + LookupSymbols.add(KV.first, SymbolLookupFlags::WeaklyReferencedSymbol); + } + SymbolMap NewSymbols; - TargetProcessControl::LookupRequestElement Request(H, Symbols); + TargetProcessControl::LookupRequestElement Request(H, LookupSymbols); auto Result = TPC.lookupSymbols(Request); if (!Result) return Result.takeError(); assert(Result->size() == 1 && "Results for more than one library returned"); - assert(Result->front().size() == Symbols.size() && + assert(Result->front().size() == LookupSymbols.size() && "Result has incorrect number of elements"); + SymbolNameVector MissingSymbols; auto ResultI = Result->front().begin(); - for (auto &KV : Symbols) - NewSymbols[KV.first] = - JITEvaluatedSymbol(*ResultI++, JITSymbolFlags::Exported); + for (auto &KV : LookupSymbols) + if (*ResultI) + NewSymbols[KV.first] = + JITEvaluatedSymbol(*ResultI++, JITSymbolFlags::Exported); + + // If there were no resolved symbols bail out. + if (NewSymbols.empty()) + return Error::success(); + // Define resolved symbols. return JD.define(absoluteSymbols(std::move(NewSymbols))); } diff --git a/llvm/lib/ExecutionEngine/Orc/TargetProcessControl.cpp b/llvm/lib/ExecutionEngine/Orc/TargetProcessControl.cpp index 59c9ce2393c92..1e7736d1f40db 100644 --- a/llvm/lib/ExecutionEngine/Orc/TargetProcessControl.cpp +++ b/llvm/lib/ExecutionEngine/Orc/TargetProcessControl.cpp @@ -78,14 +78,14 @@ SelfTargetProcessControl::lookupSymbols(LookupRequest Request) { auto &Sym = KV.first; std::string Tmp((*Sym).data() + !!GlobalManglingPrefix, (*Sym).size() - !!GlobalManglingPrefix); - if (void *Addr = Dylib->getAddressOfSymbol(Tmp.c_str())) - R.back().push_back(pointerToJITTargetAddress(Addr)); - else if (KV.second == SymbolLookupFlags::RequiredSymbol) { + void *Addr = Dylib->getAddressOfSymbol(Tmp.c_str()); + if (!Addr && KV.second == SymbolLookupFlags::RequiredSymbol) { // FIXME: Collect all failing symbols before erroring out. SymbolNameVector MissingSymbols; MissingSymbols.push_back(Sym); return make_error(std::move(MissingSymbols)); } + R.back().push_back(pointerToJITTargetAddress(Addr)); } } diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp index f1cc1f2550b31..a848bf029dbf0 100644 --- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp @@ -17,6 +17,7 @@ #include "llvm/BinaryFormat/Magic.h" #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h" #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" +#include "llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" @@ -30,7 +31,6 @@ #include "llvm/Object/ObjectFile.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Process.h" @@ -802,19 +802,13 @@ Error sanitizeArguments(const Session &S) { } Error loadProcessSymbols(Session &S) { - std::string ErrMsg; - if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr, &ErrMsg)) - return make_error(std::move(ErrMsg), inconvertibleErrorCode()); - - char GlobalPrefix = - S.TPC->getTargetTriple().getObjectFormat() == Triple::MachO ? '_' : '\0'; auto InternedEntryPointName = S.ES.intern(EntryPointName); auto FilterMainEntryPoint = [InternedEntryPointName](SymbolStringPtr Name) { return Name != InternedEntryPointName; }; S.MainJD->addGenerator( - ExitOnErr(orc::DynamicLibrarySearchGenerator::GetForCurrentProcess( - GlobalPrefix, FilterMainEntryPoint))); + ExitOnErr(orc::TPCDynamicLibrarySearchGenerator::GetForTargetProcess( + *S.TPC, std::move(FilterMainEntryPoint)))); return Error::success(); } From 96219e15849a4db00c7a9959e4fc9207cbcad2f7 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Thu, 10 Sep 2020 13:10:27 -0700 Subject: [PATCH 175/234] [ORC] Make MaterializationResponsibility immovable, pass by unique_ptr. Making MaterializationResponsibility instances immovable allows their associated VModuleKeys to be updated by the ExecutionSession while the responsibility is still in-flight. This will be used in the upcoming removable code feature to enable safe merging of resource keys even if there are active compiles using the keys being merged. --- .../SpeculativeJIT/SpeculativeJIT.cpp | 15 +- .../Orc/CompileOnDemandLayer.h | 6 +- llvm/include/llvm/ExecutionEngine/Orc/Core.h | 37 +-- .../llvm/ExecutionEngine/Orc/IRCompileLayer.h | 3 +- .../ExecutionEngine/Orc/IRTransformLayer.h | 3 +- llvm/include/llvm/ExecutionEngine/Orc/Layer.h | 11 +- .../llvm/ExecutionEngine/Orc/LazyReexports.h | 2 +- .../ExecutionEngine/Orc/ObjectLinkingLayer.h | 2 +- .../Orc/ObjectTransformLayer.h | 2 +- .../Orc/RTDyldObjectLinkingLayer.h | 2 +- .../llvm/ExecutionEngine/Orc/Speculation.h | 3 +- .../Orc/CompileOnDemandLayer.cpp | 42 +-- llvm/lib/ExecutionEngine/Orc/Core.cpp | 50 ++-- .../ExecutionEngine/Orc/IRCompileLayer.cpp | 6 +- .../ExecutionEngine/Orc/IRTransformLayer.cpp | 6 +- .../ExecutionEngine/Orc/IndirectionUtils.cpp | 6 +- llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 20 +- llvm/lib/ExecutionEngine/Orc/Layer.cpp | 8 +- .../lib/ExecutionEngine/Orc/LazyReexports.cpp | 16 +- .../Orc/ObjectLinkingLayer.cpp | 59 ++--- .../Orc/ObjectTransformLayer.cpp | 7 +- .../Orc/RTDyldObjectLinkingLayer.cpp | 25 +- llvm/lib/ExecutionEngine/Orc/Speculation.cpp | 4 +- .../ExecutionEngine/Orc/CoreAPIsTest.cpp | 242 ++++++++++-------- .../Orc/LazyCallThroughAndReexportsTest.cpp | 6 +- .../ExecutionEngine/Orc/OrcTestCommon.h | 5 +- 26 files changed, 314 insertions(+), 274 deletions(-) diff --git a/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp b/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp index 4de4897053c1b..24cf0847558f9 100644 --- a/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp +++ b/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp @@ -113,14 +113,13 @@ class SpeculativeJIT { this->CODLayer.setImplMap(&Imps); this->ES->setDispatchMaterialization( [this](std::unique_ptr MU, - MaterializationResponsibility MR) { - // FIXME: Switch to move capture once we have C++14. - auto SharedMU = std::shared_ptr(std::move(MU)); - auto SharedMR = - std::make_shared(std::move(MR)); - CompileThreads.async([SharedMU, SharedMR]() { - SharedMU->materialize(std::move(*SharedMR)); - }); + std::unique_ptr MR) { + CompileThreads.async( + [UnownedMU = MU.release(), UnownedMR = MR.release()]() { + std::unique_ptr MU(UnownedMU); + std::unique_ptr MR(UnownedMR); + MU->materialize(std::move(MR)); + }); }); ExitOnErr(S.addSpeculationRuntime(MainJD, Mangle)); LocalCXXRuntimeOverrides CXXRuntimeoverrides; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 9ecc0464dec1b..3a2f8b54ad22b 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -96,7 +96,8 @@ class CompileOnDemandLayer : public IRLayer { /// Emits the given module. This should not be called by clients: it will be /// called by the JIT when a definition added via the add method is requested. - void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override; + void emit(std::unique_ptr R, + ThreadSafeModule TSM) override; private: struct PerDylibResources { @@ -120,7 +121,8 @@ class CompileOnDemandLayer : public IRLayer { void expandPartition(GlobalValueSet &Partition); - void emitPartition(MaterializationResponsibility R, ThreadSafeModule TSM, + void emitPartition(std::unique_ptr R, + ThreadSafeModule TSM, IRMaterializationUnit::SymbolNameToDefinitionMap Defs); mutable std::mutex CODLayerMutex; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Core.h b/llvm/include/llvm/ExecutionEngine/Orc/Core.h index 6951df3f2d3f2..70bd983c40ce0 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Core.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Core.h @@ -410,7 +410,7 @@ class UnexpectedSymbolDefinitions : public ErrorInfo + delegate(const SymbolNameSet &Symbols, VModuleKey NewKey = VModuleKey()); void addDependencies(const SymbolStringPtr &Name, const SymbolDependenceMap &Dependencies); @@ -577,7 +577,8 @@ class MaterializationUnit { /// Implementations of this method should materialize all symbols /// in the materialzation unit, except for those that have been /// previously discarded. - virtual void materialize(MaterializationResponsibility R) = 0; + virtual void + materialize(std::unique_ptr R) = 0; /// Called by JITDylibs to notify MaterializationUnits that the given symbol /// has been overridden. @@ -594,10 +595,11 @@ class MaterializationUnit { private: virtual void anchor(); - MaterializationResponsibility + std::unique_ptr createMaterializationResponsibility(std::shared_ptr JD) { - return MaterializationResponsibility(std::move(JD), std::move(SymbolFlags), - std::move(InitSymbol), K); + return std::unique_ptr( + new MaterializationResponsibility(std::move(JD), std::move(SymbolFlags), + std::move(InitSymbol), K)); } /// Implementations of this method should discard the given symbol @@ -621,7 +623,7 @@ class AbsoluteSymbolsMaterializationUnit : public MaterializationUnit { StringRef getName() const override; private: - void materialize(MaterializationResponsibility R) override; + void materialize(std::unique_ptr R) override; void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; static SymbolFlagsMap extractFlags(const SymbolMap &Symbols); @@ -663,7 +665,7 @@ class ReExportsMaterializationUnit : public MaterializationUnit { StringRef getName() const override; private: - void materialize(MaterializationResponsibility R) override; + void materialize(std::unique_ptr R) override; void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases); @@ -1116,7 +1118,7 @@ class ExecutionSession { /// For dispatching MaterializationUnit::materialize calls. using DispatchMaterializationFunction = std::function MU, - MaterializationResponsibility MR)>; + std::unique_ptr MR)>; /// Construct an ExecutionSession. /// @@ -1268,10 +1270,11 @@ class ExecutionSession { SymbolState RequiredState = SymbolState::Ready); /// Materialize the given unit. - void dispatchMaterialization(std::unique_ptr MU, - MaterializationResponsibility MR) { + void + dispatchMaterialization(std::unique_ptr MU, + std::unique_ptr MR) { assert(MU && "MU must be non-null"); - DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR.getTargetJITDylib(), *MU)); + DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR->getTargetJITDylib(), *MU)); DispatchMaterialization(std::move(MU), std::move(MR)); } @@ -1283,9 +1286,9 @@ class ExecutionSession { logAllUnhandledErrors(std::move(Err), errs(), "JIT session error: "); } - static void - materializeOnCurrentThread(std::unique_ptr MU, - MaterializationResponsibility MR) { + static void materializeOnCurrentThread( + std::unique_ptr MU, + std::unique_ptr MR) { MU->materialize(std::move(MR)); } @@ -1309,7 +1312,7 @@ class ExecutionSession { // with callbacks from asynchronous queries. mutable std::recursive_mutex OutstandingMUsMutex; std::vector, - MaterializationResponsibility>> + std::unique_ptr>> OutstandingMUs; }; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h index eb74d283f0435..2c53e2f66e851 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h @@ -55,7 +55,8 @@ class IRCompileLayer : public IRLayer { void setNotifyCompiled(NotifyCompiledFunction NotifyCompiled); - void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override; + void emit(std::unique_ptr R, + ThreadSafeModule TSM) override; private: mutable std::mutex IRLayerMutex; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h index 296d74ae6b865..ee4ee3437fa6d 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h @@ -37,7 +37,8 @@ class IRTransformLayer : public IRLayer { this->Transform = std::move(Transform); } - void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override; + void emit(std::unique_ptr R, + ThreadSafeModule TSM) override; static ThreadSafeModule identityTransform(ThreadSafeModule TSM, MaterializationResponsibility &R) { diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Layer.h b/llvm/include/llvm/ExecutionEngine/Orc/Layer.h index e843d0f562455..c8a41199760da 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Layer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Layer.h @@ -100,7 +100,8 @@ class IRLayer { VModuleKey K = VModuleKey()); /// Emit should materialize the given IR. - virtual void emit(MaterializationResponsibility R, ThreadSafeModule TSM) = 0; + virtual void emit(std::unique_ptr R, + ThreadSafeModule TSM) = 0; private: bool CloneToNewContextOnEmit = false; @@ -117,8 +118,7 @@ class BasicIRLayerMaterializationUnit : public IRMaterializationUnit { ThreadSafeModule TSM, VModuleKey K); private: - - void materialize(MaterializationResponsibility R) override; + void materialize(std::unique_ptr R) override; IRLayer &L; VModuleKey K; @@ -139,7 +139,7 @@ class ObjectLayer { VModuleKey K = VModuleKey()); /// Emit should materialize the given IR. - virtual void emit(MaterializationResponsibility R, + virtual void emit(std::unique_ptr R, std::unique_ptr O) = 0; private: @@ -162,8 +162,7 @@ class BasicObjectLayerMaterializationUnit : public MaterializationUnit { StringRef getName() const override; private: - - void materialize(MaterializationResponsibility R) override; + void materialize(std::unique_ptr R) override; void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; ObjectLayer &L; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h b/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h index 9206e40fffb1c..63e3a80d87d86 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h @@ -149,7 +149,7 @@ class LazyReexportsMaterializationUnit : public MaterializationUnit { StringRef getName() const override; private: - void materialize(MaterializationResponsibility R) override; + void materialize(std::unique_ptr R) override; void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases); diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h index cb8ee130ab614..cbcf3928be3df 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h @@ -119,7 +119,7 @@ class ObjectLinkingLayer : public ObjectLayer { } /// Emit the object. - void emit(MaterializationResponsibility R, + void emit(std::unique_ptr R, std::unique_ptr O) override; /// Instructs this ObjectLinkingLayer instance to override the symbol flags diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h index bf989cc8677cf..c77649f19fc74 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h @@ -31,7 +31,7 @@ class ObjectTransformLayer : public ObjectLayer { ObjectTransformLayer(ExecutionSession &ES, ObjectLayer &BaseLayer, TransformFunction Transform = TransformFunction()); - void emit(MaterializationResponsibility R, + void emit(std::unique_ptr R, std::unique_ptr O) override; void setTransform(TransformFunction Transform) { diff --git a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h index 9ada0871cf0cb..9cd3c57a19c6a 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h @@ -58,7 +58,7 @@ class RTDyldObjectLinkingLayer : public ObjectLayer { ~RTDyldObjectLinkingLayer(); /// Emit the object. - void emit(MaterializationResponsibility R, + void emit(std::unique_ptr R, std::unique_ptr O) override; /// Set the NotifyLoaded callback. diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h b/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h index 10f78c8bc6beb..a138f60a77564 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h @@ -181,7 +181,8 @@ class IRSpeculationLayer : public IRLayer { : IRLayer(ES, BaseLayer.getManglingOptions()), NextLayer(BaseLayer), S(Spec), Mangle(Mangle), QueryAnalysis(Interpreter) {} - void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override; + void emit(std::unique_ptr R, + ThreadSafeModule TSM) override; private: TargetAndLikelies diff --git a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp index 9e38dc36faae7..dfb0d06bdba3d 100644 --- a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp @@ -88,7 +88,7 @@ class PartitioningIRMaterializationUnit : public IRMaterializationUnit { Parent(Parent) {} private: - void materialize(MaterializationResponsibility R) override { + void materialize(std::unique_ptr R) override { Parent.emitPartition(std::move(R), std::move(TSM), std::move(SymbolToDefinition)); } @@ -128,15 +128,15 @@ void CompileOnDemandLayer::setPartitionFunction(PartitionFunction Partition) { void CompileOnDemandLayer::setImplMap(ImplSymbolMap *Imp) { this->AliaseeImpls = Imp; } -void CompileOnDemandLayer::emit(MaterializationResponsibility R, - ThreadSafeModule TSM) { +void CompileOnDemandLayer::emit( + std::unique_ptr R, ThreadSafeModule TSM) { assert(TSM && "Null module"); auto &ES = getExecutionSession(); // Sort the callables and non-callables, build re-exports and lodge the // actual module with the implementation dylib. - auto &PDR = getPerDylibResources(R.getTargetJITDylib()); + auto &PDR = getPerDylibResources(R->getTargetJITDylib()); SymbolAliasMap NonCallables; SymbolAliasMap Callables; @@ -145,7 +145,7 @@ void CompileOnDemandLayer::emit(MaterializationResponsibility R, cleanUpModule(M); }); - for (auto &KV : R.getSymbols()) { + for (auto &KV : R->getSymbols()) { auto &Name = KV.first; auto &Flags = KV.second; if (Flags.isCallable()) @@ -158,19 +158,19 @@ void CompileOnDemandLayer::emit(MaterializationResponsibility R, // implementation dylib. if (auto Err = PDR.getImplDylib().define( std::make_unique( - ES, *getManglingOptions(), std::move(TSM), R.getVModuleKey(), + ES, *getManglingOptions(), std::move(TSM), R->getVModuleKey(), *this))) { ES.reportError(std::move(Err)); - R.failMaterialization(); + R->failMaterialization(); return; } if (!NonCallables.empty()) - R.replace(reexports(PDR.getImplDylib(), std::move(NonCallables), - JITDylibLookupFlags::MatchAllSymbols)); + R->replace(reexports(PDR.getImplDylib(), std::move(NonCallables), + JITDylibLookupFlags::MatchAllSymbols)); if (!Callables.empty()) - R.replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(), - std::move(Callables), AliaseeImpls)); + R->replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(), + std::move(Callables), AliaseeImpls)); } CompileOnDemandLayer::PerDylibResources & @@ -247,7 +247,7 @@ void CompileOnDemandLayer::expandPartition(GlobalValueSet &Partition) { } void CompileOnDemandLayer::emitPartition( - MaterializationResponsibility R, ThreadSafeModule TSM, + std::unique_ptr R, ThreadSafeModule TSM, IRMaterializationUnit::SymbolNameToDefinitionMap Defs) { // FIXME: Need a 'notify lazy-extracting/emitting' callback to tie the @@ -257,8 +257,8 @@ void CompileOnDemandLayer::emitPartition( auto &ES = getExecutionSession(); GlobalValueSet RequestedGVs; - for (auto &Name : R.getRequestedSymbols()) { - if (Name == R.getInitializerSymbol()) + for (auto &Name : R->getRequestedSymbols()) { + if (Name == R->getInitializerSymbol()) TSM.withModuleDo([&](Module &M) { for (auto &GV : getStaticInitGVs(M)) RequestedGVs.insert(&GV); @@ -285,9 +285,9 @@ void CompileOnDemandLayer::emitPartition( // If the partition is empty, return the whole module to the symbol table. if (GVsToExtract->empty()) { - R.replace(std::make_unique( - std::move(TSM), R.getVModuleKey(), R.getSymbols(), - R.getInitializerSymbol(), std::move(Defs), *this)); + R->replace(std::make_unique( + std::move(TSM), R->getVModuleKey(), R->getSymbols(), + R->getInitializerSymbol(), std::move(Defs), *this)); return; } @@ -308,7 +308,7 @@ void CompileOnDemandLayer::emitPartition( IRSymbolMapper::add(ES, *getManglingOptions(), PromotedGlobals, SymbolFlags); - if (auto Err = R.defineMaterializing(SymbolFlags)) + if (auto Err = R->defineMaterializing(SymbolFlags)) return std::move(Err); } @@ -348,12 +348,12 @@ void CompileOnDemandLayer::emitPartition( if (!ExtractedTSM) { ES.reportError(ExtractedTSM.takeError()); - R.failMaterialization(); + R->failMaterialization(); return; } - R.replace(std::make_unique( - ES, *getManglingOptions(), std::move(TSM), R.getVModuleKey(), *this)); + R->replace(std::make_unique( + ES, *getManglingOptions(), std::move(TSM), R->getVModuleKey(), *this)); BaseLayer.emit(std::move(R), std::move(*ExtractedTSM)); } diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp index 18eced68f07bc..243bac79c012f 100644 --- a/llvm/lib/ExecutionEngine/Orc/Core.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp @@ -279,7 +279,7 @@ void MaterializationResponsibility::replace( JD->replace(std::move(MU)); } -MaterializationResponsibility +std::unique_ptr MaterializationResponsibility::delegate(const SymbolNameSet &Symbols, VModuleKey NewKey) { @@ -302,9 +302,10 @@ MaterializationResponsibility::delegate(const SymbolNameSet &Symbols, SymbolFlags.erase(I); } - return MaterializationResponsibility(JD, std::move(DelegatedFlags), - std::move(DelegatedInitSymbol), - std::move(NewKey)); + return std::unique_ptr( + new MaterializationResponsibility(JD, std::move(DelegatedFlags), + std::move(DelegatedInitSymbol), + std::move(NewKey))); } void MaterializationResponsibility::addDependencies( @@ -338,10 +339,10 @@ StringRef AbsoluteSymbolsMaterializationUnit::getName() const { } void AbsoluteSymbolsMaterializationUnit::materialize( - MaterializationResponsibility R) { + std::unique_ptr R) { // No dependencies, so these calls can't fail. - cantFail(R.notifyResolved(Symbols)); - cantFail(R.notifyEmitted()); + cantFail(R->notifyResolved(Symbols)); + cantFail(R->notifyEmitted()); } void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD, @@ -370,16 +371,16 @@ StringRef ReExportsMaterializationUnit::getName() const { } void ReExportsMaterializationUnit::materialize( - MaterializationResponsibility R) { + std::unique_ptr R) { - auto &ES = R.getTargetJITDylib().getExecutionSession(); - JITDylib &TgtJD = R.getTargetJITDylib(); + auto &ES = R->getTargetJITDylib().getExecutionSession(); + JITDylib &TgtJD = R->getTargetJITDylib(); JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD; // Find the set of requested aliases and aliasees. Return any unrequested // aliases back to the JITDylib so as to not prematurely materialize any // aliasees. - auto RequestedSymbols = R.getRequestedSymbols(); + auto RequestedSymbols = R->getRequestedSymbols(); SymbolAliasMap RequestedAliases; for (auto &Name : RequestedSymbols) { @@ -399,18 +400,19 @@ void ReExportsMaterializationUnit::materialize( if (!Aliases.empty()) { if (SourceJD) - R.replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags)); + R->replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags)); else - R.replace(symbolAliases(std::move(Aliases))); + R->replace(symbolAliases(std::move(Aliases))); } // The OnResolveInfo struct will hold the aliases and responsibilty for each // query in the list. struct OnResolveInfo { - OnResolveInfo(MaterializationResponsibility R, SymbolAliasMap Aliases) + OnResolveInfo(std::unique_ptr R, + SymbolAliasMap Aliases) : R(std::move(R)), Aliases(std::move(Aliases)) {} - MaterializationResponsibility R; + std::unique_ptr R; SymbolAliasMap Aliases; }; @@ -451,7 +453,7 @@ void ReExportsMaterializationUnit::materialize( assert(!QuerySymbols.empty() && "Alias cycle detected!"); auto QueryInfo = std::make_shared( - R.delegate(ResponsibilitySymbols), std::move(QueryAliases)); + R->delegate(ResponsibilitySymbols), std::move(QueryAliases)); QueryInfos.push_back( make_pair(std::move(QuerySymbols), std::move(QueryInfo))); } @@ -480,12 +482,12 @@ void ReExportsMaterializationUnit::materialize( for (auto &KV : QueryInfo->Aliases) if (SrcJDDeps.count(KV.second.Aliasee)) { PerAliasDeps = {KV.second.Aliasee}; - QueryInfo->R.addDependencies(KV.first, PerAliasDepsMap); + QueryInfo->R->addDependencies(KV.first, PerAliasDepsMap); } }; auto OnComplete = [QueryInfo](Expected Result) { - auto &ES = QueryInfo->R.getTargetJITDylib().getExecutionSession(); + auto &ES = QueryInfo->R->getTargetJITDylib().getExecutionSession(); if (Result) { SymbolMap ResolutionMap; for (auto &KV : QueryInfo->Aliases) { @@ -499,19 +501,19 @@ void ReExportsMaterializationUnit::materialize( ResolutionMap[KV.first] = JITEvaluatedSymbol( (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags); } - if (auto Err = QueryInfo->R.notifyResolved(ResolutionMap)) { + if (auto Err = QueryInfo->R->notifyResolved(ResolutionMap)) { ES.reportError(std::move(Err)); - QueryInfo->R.failMaterialization(); + QueryInfo->R->failMaterialization(); return; } - if (auto Err = QueryInfo->R.notifyEmitted()) { + if (auto Err = QueryInfo->R->notifyEmitted()) { ES.reportError(std::move(Err)); - QueryInfo->R.failMaterialization(); + QueryInfo->R->failMaterialization(); return; } } else { ES.reportError(Result.takeError()); - QueryInfo->R.failMaterialization(); + QueryInfo->R->failMaterialization(); } }; @@ -2131,7 +2133,7 @@ void ExecutionSession::dump(raw_ostream &OS) { void ExecutionSession::runOutstandingMUs() { while (1) { Optional, - MaterializationResponsibility>> + std::unique_ptr>> JMU; { diff --git a/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp b/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp index 023940dc82982..c6f6870279728 100644 --- a/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp @@ -25,7 +25,7 @@ void IRCompileLayer::setNotifyCompiled(NotifyCompiledFunction NotifyCompiled) { this->NotifyCompiled = std::move(NotifyCompiled); } -void IRCompileLayer::emit(MaterializationResponsibility R, +void IRCompileLayer::emit(std::unique_ptr R, ThreadSafeModule TSM) { assert(TSM && "Module must not be null"); @@ -33,13 +33,13 @@ void IRCompileLayer::emit(MaterializationResponsibility R, { std::lock_guard Lock(IRLayerMutex); if (NotifyCompiled) - NotifyCompiled(R.getVModuleKey(), std::move(TSM)); + NotifyCompiled(R->getVModuleKey(), std::move(TSM)); else TSM = ThreadSafeModule(); } BaseLayer.emit(std::move(R), std::move(*Obj)); } else { - R.failMaterialization(); + R->failMaterialization(); getExecutionSession().reportError(Obj.takeError()); } } diff --git a/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp b/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp index 511248f83b259..d5b11349277c1 100644 --- a/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp @@ -17,14 +17,14 @@ IRTransformLayer::IRTransformLayer(ExecutionSession &ES, IRLayer &BaseLayer, : IRLayer(ES, BaseLayer.getManglingOptions()), BaseLayer(BaseLayer), Transform(std::move(Transform)) {} -void IRTransformLayer::emit(MaterializationResponsibility R, +void IRTransformLayer::emit(std::unique_ptr R, ThreadSafeModule TSM) { assert(TSM && "Module must not be null"); - if (auto TransformedTSM = Transform(std::move(TSM), R)) + if (auto TransformedTSM = Transform(std::move(TSM), *R)) BaseLayer.emit(std::move(R), std::move(*TransformedTSM)); else { - R.failMaterialization(); + R->failMaterialization(); getExecutionSession().reportError(TransformedTSM.takeError()); } } diff --git a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp index 4f7f6089e68db..7d57ed5a3a04c 100644 --- a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp +++ b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp @@ -33,12 +33,12 @@ class CompileCallbackMaterializationUnit : public orc::MaterializationUnit { StringRef getName() const override { return ""; } private: - void materialize(MaterializationResponsibility R) override { + void materialize(std::unique_ptr R) override { SymbolMap Result; Result[Name] = JITEvaluatedSymbol(Compile(), JITSymbolFlags::Exported); // No dependencies, so these calls cannot fail. - cantFail(R.notifyResolved(Result)); - cantFail(R.notifyEmitted()); + cantFail(R->notifyResolved(Result)); + cantFail(R->notifyEmitted()); } void discard(const JITDylib &JD, const SymbolStringPtr &Name) override { diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp index 373d86d92f8d7..81f500d66bc29 100644 --- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -1085,15 +1085,17 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err) std::make_unique(hardware_concurrency(S.NumCompileThreads)); ES->setDispatchMaterialization( [this](std::unique_ptr MU, - MaterializationResponsibility MR) { - // FIXME: Switch to move capture once ThreadPool uses unique_function. - auto SharedMU = std::shared_ptr(std::move(MU)); - auto SharedMR = - std::make_shared(std::move(MR)); - auto Work = [SharedMU, SharedMR]() mutable { - SharedMU->materialize(std::move(*SharedMR)); - }; - CompileThreads->async(std::move(Work)); + std::unique_ptr MR) { + // FIXME: We should be able to use move-capture here, but ThreadPool's + // AsyncTaskTys are std::functions rather than unique_functions + // (because MSVC's std::packaged_tasks don't support move-only types). + // Fix this when all the above gets sorted out. + CompileThreads->async( + [UnownedMU = MU.release(), UnownedMR = MR.release()]() mutable { + std::unique_ptr MU(UnownedMU); + std::unique_ptr MR(UnownedMR); + MU->materialize(std::move(MR)); + }); }); } diff --git a/llvm/lib/ExecutionEngine/Orc/Layer.cpp b/llvm/lib/ExecutionEngine/Orc/Layer.cpp index 0a5d5577e99e8..8052e7b08a5a6 100644 --- a/llvm/lib/ExecutionEngine/Orc/Layer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Layer.cpp @@ -133,7 +133,7 @@ BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit( L(L), K(std::move(K)) {} void BasicIRLayerMaterializationUnit::materialize( - MaterializationResponsibility R) { + std::unique_ptr R) { // Throw away the SymbolToDefinition map: it's not usable after we hand // off the module. @@ -144,8 +144,8 @@ void BasicIRLayerMaterializationUnit::materialize( TSM = cloneToNewContext(TSM); #ifndef NDEBUG - auto &ES = R.getTargetJITDylib().getExecutionSession(); - auto &N = R.getTargetJITDylib().getName(); + auto &ES = R->getTargetJITDylib().getExecutionSession(); + auto &N = R->getTargetJITDylib().getName(); #endif // NDEBUG LLVM_DEBUG(ES.runSessionLocked( @@ -200,7 +200,7 @@ StringRef BasicObjectLayerMaterializationUnit::getName() const { } void BasicObjectLayerMaterializationUnit::materialize( - MaterializationResponsibility R) { + std::unique_ptr R) { L.emit(std::move(R), std::move(O)); } diff --git a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp index 5e604130d6eab..695f6cc9c1cb4 100644 --- a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp @@ -154,8 +154,8 @@ StringRef LazyReexportsMaterializationUnit::getName() const { } void LazyReexportsMaterializationUnit::materialize( - MaterializationResponsibility R) { - auto RequestedSymbols = R.getRequestedSymbols(); + std::unique_ptr R) { + auto RequestedSymbols = R->getRequestedSymbols(); SymbolAliasMap RequestedAliases; for (auto &RequestedSymbol : RequestedSymbols) { @@ -166,8 +166,8 @@ void LazyReexportsMaterializationUnit::materialize( } if (!CallableAliases.empty()) - R.replace(lazyReexports(LCTManager, ISManager, SourceJD, - std::move(CallableAliases), AliaseeTable)); + R->replace(lazyReexports(LCTManager, ISManager, SourceJD, + std::move(CallableAliases), AliaseeTable)); IndirectStubsManager::StubInitsMap StubInits; for (auto &Alias : RequestedAliases) { @@ -182,7 +182,7 @@ void LazyReexportsMaterializationUnit::materialize( if (!CallThroughTrampoline) { SourceJD.getExecutionSession().reportError( CallThroughTrampoline.takeError()); - R.failMaterialization(); + R->failMaterialization(); return; } @@ -195,7 +195,7 @@ void LazyReexportsMaterializationUnit::materialize( if (auto Err = ISManager.createStubs(StubInits)) { SourceJD.getExecutionSession().reportError(std::move(Err)); - R.failMaterialization(); + R->failMaterialization(); return; } @@ -204,8 +204,8 @@ void LazyReexportsMaterializationUnit::materialize( Stubs[Alias.first] = ISManager.findStub(*Alias.first, false); // No registered dependencies, so these calls cannot fail. - cantFail(R.notifyResolved(Stubs)); - cantFail(R.notifyEmitted()); + cantFail(R->notifyResolved(Stubs)); + cantFail(R->notifyEmitted()); } void LazyReexportsMaterializationUnit::discard(const JITDylib &JD, diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp index d8283fa7e3461..9e3245d9cc991 100644 --- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp @@ -24,9 +24,10 @@ namespace orc { class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { public: - ObjectLinkingLayerJITLinkContext(ObjectLinkingLayer &Layer, - MaterializationResponsibility MR, - std::unique_ptr ObjBuffer) + ObjectLinkingLayerJITLinkContext( + ObjectLinkingLayer &Layer, + std::unique_ptr MR, + std::unique_ptr ObjBuffer) : Layer(Layer), MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {} ~ObjectLinkingLayerJITLinkContext() { @@ -44,14 +45,14 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { void notifyFailed(Error Err) override { Layer.getExecutionSession().reportError(std::move(Err)); - MR.failMaterialization(); + MR->failMaterialization(); } void lookup(const LookupMap &Symbols, std::unique_ptr LC) override { JITDylibSearchOrder LinkOrder; - MR.getTargetJITDylib().withLinkOrderDo( + MR->getTargetJITDylib().withLinkOrderDo( [&](const JITDylibSearchOrder &LO) { LinkOrder = LO; }); auto &ES = Layer.getExecutionSession(); @@ -85,8 +86,8 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { for (auto &KV : InternalNamedSymbolDeps) { SymbolDependenceMap InternalDeps; - InternalDeps[&MR.getTargetJITDylib()] = std::move(KV.second); - MR.addDependencies(KV.first, InternalDeps); + InternalDeps[&MR->getTargetJITDylib()] = std::move(KV.second); + MR->addDependencies(KV.first, InternalDeps); } ES.lookup(LookupKind::Static, LinkOrder, std::move(LookupSet), @@ -115,7 +116,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { InternedResult[InternedName] = JITEvaluatedSymbol(Sym->getAddress(), Flags); - if (AutoClaim && !MR.getSymbols().count(InternedName)) { + if (AutoClaim && !MR->getSymbols().count(InternedName)) { assert(!ExtraSymbolsToClaim.count(InternedName) && "Duplicate symbol to claim?"); ExtraSymbolsToClaim[InternedName] = Flags; @@ -133,7 +134,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { Flags |= JITSymbolFlags::Weak; InternedResult[InternedName] = JITEvaluatedSymbol(Sym->getAddress(), Flags); - if (AutoClaim && !MR.getSymbols().count(InternedName)) { + if (AutoClaim && !MR->getSymbols().count(InternedName)) { assert(!ExtraSymbolsToClaim.count(InternedName) && "Duplicate symbol to claim?"); ExtraSymbolsToClaim[InternedName] = Flags; @@ -141,19 +142,19 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { } if (!ExtraSymbolsToClaim.empty()) - if (auto Err = MR.defineMaterializing(ExtraSymbolsToClaim)) + if (auto Err = MR->defineMaterializing(ExtraSymbolsToClaim)) return Err; { - // Check that InternedResult matches up with MR.getSymbols(). + // Check that InternedResult matches up with MR->getSymbols(). // This guards against faulty transformations / compilers / object caches. // First check that there aren't any missing symbols. size_t NumMaterializationSideEffectsOnlySymbols = 0; SymbolNameVector ExtraSymbols; SymbolNameVector MissingSymbols; - for (auto &KV : MR.getSymbols()) { + for (auto &KV : MR->getSymbols()) { // If this is a materialization-side-effects only symbol then bump // the counter and make sure it's *not* defined, otherwise make @@ -175,9 +176,9 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { // If there are more definitions than expected, add them to the // ExtraSymbols vector. if (InternedResult.size() > - MR.getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) { + MR->getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) { for (auto &KV : InternedResult) - if (!MR.getSymbols().count(KV.first)) + if (!MR->getSymbols().count(KV.first)) ExtraSymbols.push_back(KV.first); } @@ -187,23 +188,23 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { std::move(ExtraSymbols)); } - if (auto Err = MR.notifyResolved(InternedResult)) + if (auto Err = MR->notifyResolved(InternedResult)) return Err; - Layer.notifyLoaded(MR); + Layer.notifyLoaded(*MR); return Error::success(); } void notifyFinalized( std::unique_ptr A) override { - if (auto Err = Layer.notifyEmitted(MR, std::move(A))) { + if (auto Err = Layer.notifyEmitted(*MR, std::move(A))) { Layer.getExecutionSession().reportError(std::move(Err)); - MR.failMaterialization(); + MR->failMaterialization(); return; } - if (auto Err = MR.notifyEmitted()) { + if (auto Err = MR->notifyEmitted()) { Layer.getExecutionSession().reportError(std::move(Err)); - MR.failMaterialization(); + MR->failMaterialization(); } } @@ -217,7 +218,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { Config.PrePrunePasses.push_back( [this](LinkGraph &G) { return externalizeWeakAndCommonSymbols(G); }); - Layer.modifyPassConfig(MR, TT, Config); + Layer.modifyPassConfig(*MR, TT, Config); Config.PostPrunePasses.push_back( [this](LinkGraph &G) { return computeNamedSymbolDependencies(G); }); @@ -237,13 +238,13 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { auto &ES = Layer.getExecutionSession(); for (auto *Sym : G.defined_symbols()) if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { - if (!MR.getSymbols().count(ES.intern(Sym->getName()))) + if (!MR->getSymbols().count(ES.intern(Sym->getName()))) G.makeExternal(*Sym); } for (auto *Sym : G.absolute_symbols()) if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { - if (!MR.getSymbols().count(ES.intern(Sym->getName()))) + if (!MR->getSymbols().count(ES.intern(Sym->getName()))) G.makeExternal(*Sym); } @@ -253,13 +254,13 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { Error markResponsibilitySymbolsLive(LinkGraph &G) const { auto &ES = Layer.getExecutionSession(); for (auto *Sym : G.defined_symbols()) - if (Sym->hasName() && MR.getSymbols().count(ES.intern(Sym->getName()))) + if (Sym->hasName() && MR->getSymbols().count(ES.intern(Sym->getName()))) Sym->setLive(true); return Error::success(); } Error computeNamedSymbolDependencies(LinkGraph &G) { - auto &ES = MR.getTargetJITDylib().getExecutionSession(); + auto &ES = MR->getTargetJITDylib().getExecutionSession(); auto LocalDeps = computeLocalDeps(G); // Compute dependencies for symbols defined in the JITLink graph. @@ -306,7 +307,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { } for (auto &P : Layer.Plugins) { - auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(MR); + auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(*MR); if (SyntheticLocalDeps.empty()) continue; @@ -426,12 +427,12 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { SymbolDeps.erase(&SourceJD); } - MR.addDependencies(Name, SymbolDeps); + MR->addDependencies(Name, SymbolDeps); } } ObjectLinkingLayer &Layer; - MaterializationResponsibility MR; + std::unique_ptr MR; std::unique_ptr ObjBuffer; DenseMap ExternalNamedSymbolDeps; DenseMap InternalNamedSymbolDeps; @@ -452,7 +453,7 @@ ObjectLinkingLayer::~ObjectLinkingLayer() { getExecutionSession().reportError(std::move(Err)); } -void ObjectLinkingLayer::emit(MaterializationResponsibility R, +void ObjectLinkingLayer::emit(std::unique_ptr R, std::unique_ptr O) { assert(O && "Object must not be null"); jitLink(std::make_unique( diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp index d18eb38a41423..a57662e10a794 100644 --- a/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp @@ -17,8 +17,9 @@ ObjectTransformLayer::ObjectTransformLayer(ExecutionSession &ES, TransformFunction Transform) : ObjectLayer(ES), BaseLayer(BaseLayer), Transform(std::move(Transform)) {} -void ObjectTransformLayer::emit(MaterializationResponsibility R, - std::unique_ptr O) { +void ObjectTransformLayer::emit( + std::unique_ptr R, + std::unique_ptr O) { assert(O && "Module must not be null"); // If there is a transform set then apply it. @@ -26,7 +27,7 @@ void ObjectTransformLayer::emit(MaterializationResponsibility R, if (auto TransformedObj = Transform(std::move(O))) O = std::move(*TransformedObj); else { - R.failMaterialization(); + R->failMaterialization(); getExecutionSession().reportError(TransformedObj.takeError()); return; } diff --git a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp index 7888c2fcbdbd9..1981039eb9f12 100644 --- a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp @@ -89,23 +89,18 @@ RTDyldObjectLinkingLayer::~RTDyldObjectLinkingLayer() { } } -void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, - std::unique_ptr O) { +void RTDyldObjectLinkingLayer::emit( + std::unique_ptr R, + std::unique_ptr O) { assert(O && "Object must not be null"); - // This method launches an asynchronous link step that will fulfill our - // materialization responsibility. We need to switch R to be heap - // allocated before that happens so it can live as long as the asynchronous - // link needs it to (i.e. it must be able to outlive this method). - auto SharedR = std::make_shared(std::move(R)); - auto &ES = getExecutionSession(); auto Obj = object::ObjectFile::createObjectFile(*O); if (!Obj) { getExecutionSession().reportError(Obj.takeError()); - SharedR->failMaterialization(); + R->failMaterialization(); return; } @@ -121,7 +116,7 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, continue; } else { ES.reportError(SymType.takeError()); - R.failMaterialization(); + R->failMaterialization(); return; } @@ -129,7 +124,7 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, if (!SymFlagsOrErr) { // TODO: Test this error. ES.reportError(SymFlagsOrErr.takeError()); - R.failMaterialization(); + R->failMaterialization(); return; } @@ -139,14 +134,14 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, InternalSymbols->insert(*SymName); else { ES.reportError(SymName.takeError()); - R.failMaterialization(); + R->failMaterialization(); return; } } } } - auto K = R.getVModuleKey(); + auto K = R->getVModuleKey(); RuntimeDyld::MemoryManager *MemMgr = nullptr; // Create a record a memory manager for this object. @@ -157,6 +152,10 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, MemMgr = MemMgrs.back().get(); } + // Switch to shared ownership of MR so that it can be captured by both + // lambdas below. + std::shared_ptr SharedR(std::move(R)); + JITDylibSearchOrderResolver Resolver(*SharedR); jitLinkForORC( diff --git a/llvm/lib/ExecutionEngine/Orc/Speculation.cpp b/llvm/lib/ExecutionEngine/Orc/Speculation.cpp index 3dd536d8253e3..0b4755fe23cfc 100644 --- a/llvm/lib/ExecutionEngine/Orc/Speculation.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Speculation.cpp @@ -55,7 +55,7 @@ Error Speculator::addSpeculationRuntime(JITDylib &JD, // If two modules, share the same LLVMContext, different threads must // not access them concurrently without locking the associated LLVMContext // this implementation follows this contract. -void IRSpeculationLayer::emit(MaterializationResponsibility R, +void IRSpeculationLayer::emit(std::unique_ptr R, ThreadSafeModule TSM) { assert(TSM && "Speculation Layer received Null Module ?"); @@ -127,7 +127,7 @@ void IRSpeculationLayer::emit(MaterializationResponsibility R, assert(Mutator.GetInsertBlock()->getParent() == &Fn && "IR builder association mismatch?"); S.registerSymbols(internToJITSymbols(IRNames.getValue()), - &R.getTargetJITDylib()); + &R->getTargetJITDylib()); } } } diff --git a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp index 2c008dfdbd33e..9a1dbbb172517 100644 --- a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp @@ -35,12 +35,12 @@ TEST_F(CoreAPIsStandardTest, BasicSuccessfulLookup) { OnCompletionRun = true; }; - std::shared_ptr FooMR; + std::unique_ptr FooMR; cantFail(JD.define(std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { - FooMR = std::make_shared(std::move(R)); + [&](std::unique_ptr R) { + FooMR = std::move(R); }))); ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD), @@ -99,9 +99,9 @@ TEST_F(CoreAPIsStandardTest, ResolveUnrequestedSymbol) { cantFail(JD.define(std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}), - [this](MaterializationResponsibility R) { - cantFail(R.notifyResolved({{Foo, FooSym}, {Bar, BarSym}})); - cantFail(R.notifyEmitted()); + [this](std::unique_ptr R) { + cantFail(R->notifyResolved({{Foo, FooSym}, {Bar, BarSym}})); + cantFail(R->notifyEmitted()); }))); auto Result = @@ -116,14 +116,16 @@ TEST_F(CoreAPIsStandardTest, MaterializationSideEffctsOnlyBasic) { // don't return until they're emitted, and that they don't appear in query // results. - Optional FooR; + std::unique_ptr FooR; Optional Result; cantFail(JD.define(std::make_unique( SymbolFlagsMap( {{Foo, JITSymbolFlags::Exported | JITSymbolFlags::MaterializationSideEffectsOnly}}), - [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }))); + [&](std::unique_ptr R) { + FooR = std::move(R); + }))); ES.lookup( LookupKind::Static, makeJITDylibSearchOrder(&JD), @@ -155,7 +157,9 @@ TEST_F(CoreAPIsStandardTest, MaterializationSideEffectsOnlyFailuresPersist) { SymbolFlagsMap( {{Foo, JITSymbolFlags::Exported | JITSymbolFlags::MaterializationSideEffectsOnly}}), - [&](MaterializationResponsibility R) { R.failMaterialization(); }))); + [&](std::unique_ptr R) { + R->failMaterialization(); + }))); EXPECT_THAT_EXPECTED( ES.lookup(makeJITDylibSearchOrder(&JD), SymbolLookupSet({Foo})), @@ -182,10 +186,10 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) { bool BarMaterializerDestructed = false; cantFail(JD.define(std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [this](MaterializationResponsibility R) { + [this](std::unique_ptr R) { ADD_FAILURE() << "Unexpected materialization of \"Bar\""; - cantFail(R.notifyResolved({{Bar, BarSym}})); - cantFail(R.notifyEmitted()); + cantFail(R->notifyResolved({{Bar, BarSym}})); + cantFail(R->notifyEmitted()); }, nullptr, [&](const JITDylib &JD, const SymbolStringPtr &Name) { @@ -197,10 +201,12 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) { // Baz will be in the materializing state initially, then // materialized for the final removal attempt. - Optional BazR; + std::unique_ptr BazR; cantFail(JD.define(std::make_unique( SymbolFlagsMap({{Baz, BazSym.getFlags()}}), - [&](MaterializationResponsibility R) { BazR.emplace(std::move(R)); }, + [&](std::unique_ptr R) { + BazR = std::move(R); + }, nullptr, [](const JITDylib &JD, const SymbolStringPtr &Name) { ADD_FAILURE() << "\"Baz\" discarded unexpectedly"; @@ -297,7 +303,7 @@ TEST_F(CoreAPIsStandardTest, LookupFlagsTest) { JITSymbolFlags::Exported | JITSymbolFlags::Weak)); auto MU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [](MaterializationResponsibility R) { + [](std::unique_ptr R) { llvm_unreachable("Symbol materialized on flags lookup"); }); @@ -400,10 +406,10 @@ TEST_F(CoreAPIsStandardTest, TestThatReExportsDontUnnecessarilyMaterialize) { bool BarMaterialized = false; auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { + [&](std::unique_ptr R) { BarMaterialized = true; - cantFail(R.notifyResolved({{Bar, BarSym}})); - cantFail(R.notifyEmitted()); + cantFail(R->notifyResolved({{Bar, BarSym}})); + cantFail(R->notifyEmitted()); }); cantFail(JD.define(BarMU)); @@ -444,10 +450,12 @@ TEST_F(CoreAPIsStandardTest, TestReexportsGenerator) { } TEST_F(CoreAPIsStandardTest, TestTrivialCircularDependency) { - Optional FooR; + std::unique_ptr FooR; auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + FooR = std::move(R); + }); cantFail(JD.define(FooMU)); @@ -476,26 +484,29 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) { // does not prevent any symbol from becoming 'ready' once all symbols are // emitted. - // Create three MaterializationResponsibility objects: one for each of Foo, - // Bar and Baz. These are optional because MaterializationResponsibility - // does not have a default constructor). - Optional FooR; - Optional BarR; - Optional BazR; + std::unique_ptr FooR; + std::unique_ptr BarR; + std::unique_ptr BazR; // Create a MaterializationUnit for each symbol that moves the // MaterializationResponsibility into one of the locals above. auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + FooR = std::move(R); + }); auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + BarR = std::move(R); + }); auto BazMU = std::make_unique( SymbolFlagsMap({{Baz, BazSym.getFlags()}}), - [&](MaterializationResponsibility R) { BazR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + BazR = std::move(R); + }); // Define the symbols. cantFail(JD.define(FooMU)); @@ -622,18 +633,22 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) { } TEST_F(CoreAPIsStandardTest, FailureInDependency) { - Optional FooR; - Optional BarR; + std::unique_ptr FooR; + std::unique_ptr BarR; // Create a MaterializationUnit for each symbol that moves the // MaterializationResponsibility into one of the locals above. auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + FooR = std::move(R); + }); auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + BarR = std::move(R); + }); // Define the symbols. cantFail(JD.define(FooMU)); @@ -687,18 +702,22 @@ TEST_F(CoreAPIsStandardTest, FailureInDependency) { } TEST_F(CoreAPIsStandardTest, FailureInCircularDependency) { - Optional FooR; - Optional BarR; + std::unique_ptr FooR; + std::unique_ptr BarR; // Create a MaterializationUnit for each symbol that moves the // MaterializationResponsibility into one of the locals above. auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + FooR = std::move(R); + }); auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + BarR = std::move(R); + }); // Define the symbols. cantFail(JD.define(FooMU)); @@ -753,18 +772,22 @@ TEST_F(CoreAPIsStandardTest, FailureInCircularDependency) { } TEST_F(CoreAPIsStandardTest, AddDependencyOnFailedSymbol) { - Optional FooR; - Optional BarR; + std::unique_ptr FooR; + std::unique_ptr BarR; // Create a MaterializationUnit for each symbol that moves the // MaterializationResponsibility into one of the locals above. auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + FooR = std::move(R); + }); auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + BarR = std::move(R); + }); // Define the symbols. cantFail(JD.define(FooMU)); @@ -819,18 +842,22 @@ TEST_F(CoreAPIsStandardTest, AddDependencyOnFailedSymbol) { } TEST_F(CoreAPIsStandardTest, FailAfterMaterialization) { - Optional FooR; - Optional BarR; + std::unique_ptr FooR; + std::unique_ptr BarR; // Create a MaterializationUnit for each symbol that moves the // MaterializationResponsibility into one of the locals above. auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + FooR = std::move(R); + }); auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + BarR = std::move(R); + }); // Define the symbols. cantFail(JD.define(FooMU)); @@ -882,9 +909,9 @@ TEST_F(CoreAPIsStandardTest, FailMaterializerWithUnqueriedSymbols) { auto MU = std::make_unique( SymbolFlagsMap( {{Foo, JITSymbolFlags::Exported}, {Bar, JITSymbolFlags::Exported}}), - [&](MaterializationResponsibility R) { + [&](std::unique_ptr R) { MaterializerRun = true; - R.failMaterialization(); + R->failMaterialization(); }); cantFail(JD.define(std::move(MU))); @@ -911,7 +938,7 @@ TEST_F(CoreAPIsStandardTest, DropMaterializerWhenEmpty) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, WeakExported}, {Bar, WeakExported}}), - [](MaterializationResponsibility R) { + [](std::unique_ptr R) { llvm_unreachable("Unexpected call to materialize"); }, nullptr, @@ -943,10 +970,10 @@ TEST_F(CoreAPIsStandardTest, AddAndMaterializeLazySymbol) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}, {Bar, WeakExported}}), - [&](MaterializationResponsibility R) { + [&](std::unique_ptr R) { assert(BarDiscarded && "Bar should have been discarded by this point"); - cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}}))); - cantFail(R.notifyEmitted()); + cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}}))); + cantFail(R->notifyEmitted()); FooMaterialized = true; }, nullptr, @@ -985,18 +1012,18 @@ TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) { bool BarMaterialized = false; auto MU1 = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { - cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); - cantFail(R.notifyEmitted()); + [&](std::unique_ptr R) { + cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); + cantFail(R->notifyEmitted()); BarMaterialized = true; }); bool DuplicateBarDiscarded = false; auto MU2 = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { + [&](std::unique_ptr R) { ADD_FAILURE() << "Attempt to materialize Bar from the wrong unit"; - R.failMaterialization(); + R->failMaterialization(); }, nullptr, [&](const JITDylib &JD, SymbolStringPtr Name) { @@ -1026,20 +1053,21 @@ TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) { TEST_F(CoreAPIsStandardTest, DefineMaterializingSymbol) { bool ExpectNoMoreMaterialization = false; - ES.setDispatchMaterialization([&](std::unique_ptr MU, - MaterializationResponsibility MR) { - if (ExpectNoMoreMaterialization) - ADD_FAILURE() << "Unexpected materialization"; - MU->materialize(std::move(MR)); - }); + ES.setDispatchMaterialization( + [&](std::unique_ptr MU, + std::unique_ptr MR) { + if (ExpectNoMoreMaterialization) + ADD_FAILURE() << "Unexpected materialization"; + MU->materialize(std::move(MR)); + }); auto MU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { + [&](std::unique_ptr R) { cantFail( - R.defineMaterializing(SymbolFlagsMap({{Bar, BarSym.getFlags()}}))); - cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); - cantFail(R.notifyEmitted()); + R->defineMaterializing(SymbolFlagsMap({{Bar, BarSym.getFlags()}}))); + cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); + cantFail(R->notifyEmitted()); }); cantFail(JD.define(MU)); @@ -1093,8 +1121,8 @@ TEST_F(CoreAPIsStandardTest, FailResolution) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, JITSymbolFlags::Exported | JITSymbolFlags::Weak}, {Bar, JITSymbolFlags::Exported | JITSymbolFlags::Weak}}), - [&](MaterializationResponsibility R) { - R.failMaterialization(); + [&](std::unique_ptr R) { + R->failMaterialization(); }); cantFail(JD.define(MU)); @@ -1129,23 +1157,23 @@ TEST_F(CoreAPIsStandardTest, FailEmissionAfterResolution) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { - cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); + [&](std::unique_ptr R) { + cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); ES.lookup( LookupKind::Static, makeJITDylibSearchOrder(&JD), SymbolLookupSet({Baz}), SymbolState::Resolved, - [&R](Expected Result) { + [&](Expected Result) { // Called when "baz" is resolved. We don't actually depend // on or care about baz, but use it to trigger failure of // this materialization before Baz has been finalized in // order to test that error propagation is correct in this // scenario. cantFail(std::move(Result)); - R.failMaterialization(); + R->failMaterialization(); }, [&](const SymbolDependenceMap &Deps) { - R.addDependenciesForAll(Deps); + R->addDependenciesForAll(Deps); }); }); @@ -1165,7 +1193,9 @@ TEST_F(CoreAPIsStandardTest, FailAfterPartialResolution) { // Fail materialization of bar. auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { R.failMaterialization(); }); + [&](std::unique_ptr R) { + R->failMaterialization(); + }); cantFail(JD.define(std::move(BarMU))); @@ -1185,9 +1215,9 @@ TEST_F(CoreAPIsStandardTest, FailAfterPartialResolution) { TEST_F(CoreAPIsStandardTest, TestLookupWithUnthreadedMaterialization) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}), - [&](MaterializationResponsibility R) { - cantFail(R.notifyResolved({{Foo, FooSym}})); - cantFail(R.notifyEmitted()); + [&](std::unique_ptr R) { + cantFail(R->notifyResolved({{Foo, FooSym}})); + cantFail(R->notifyEmitted()); }); cantFail(JD.define(MU)); @@ -1204,15 +1234,14 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) { #if LLVM_ENABLE_THREADS std::thread MaterializationThread; - ES.setDispatchMaterialization([&](std::unique_ptr MU, - MaterializationResponsibility MR) { - auto SharedMR = - std::make_shared(std::move(MR)); - MaterializationThread = - std::thread([MU = std::move(MU), MR = std::move(SharedMR)] { - MU->materialize(std::move(*MR)); - }); - }); + ES.setDispatchMaterialization( + [&](std::unique_ptr MU, + std::unique_ptr MR) { + MaterializationThread = + std::thread([MU = std::move(MU), MR = std::move(MR)]() mutable { + MU->materialize(std::move(MR)); + }); + }); cantFail(JD.define(absoluteSymbols({{Foo, FooSym}}))); @@ -1238,23 +1267,23 @@ TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { - auto Requested = R.getRequestedSymbols(); + [&](std::unique_ptr R) { + auto Requested = R->getRequestedSymbols(); EXPECT_EQ(Requested.size(), 1U) << "Expected one symbol requested"; EXPECT_EQ(*Requested.begin(), Foo) << "Expected \"Foo\" requested"; auto NewMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R2) { - cantFail(R2.notifyResolved(SymbolMap({{Bar, BarSym}}))); - cantFail(R2.notifyEmitted()); + [&](std::unique_ptr R2) { + cantFail(R2->notifyResolved(SymbolMap({{Bar, BarSym}}))); + cantFail(R2->notifyEmitted()); BarMaterialized = true; }); - R.replace(std::move(NewMU)); + R->replace(std::move(NewMU)); - cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}}))); - cantFail(R.notifyEmitted()); + cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}}))); + cantFail(R->notifyEmitted()); FooMaterialized = true; }); @@ -1280,13 +1309,13 @@ TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) { TEST_F(CoreAPIsStandardTest, TestMaterializationResponsibilityDelegation) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { - auto R2 = R.delegate({Bar}); + [&](std::unique_ptr R) { + auto R2 = R->delegate({Bar}); - cantFail(R.notifyResolved({{Foo, FooSym}})); - cantFail(R.notifyEmitted()); - cantFail(R2.notifyResolved({{Bar, BarSym}})); - cantFail(R2.notifyEmitted()); + cantFail(R->notifyResolved({{Foo, FooSym}})); + cantFail(R->notifyEmitted()); + cantFail(R2->notifyResolved({{Bar, BarSym}})); + cantFail(R2->notifyEmitted()); }); cantFail(JD.define(MU)); @@ -1309,12 +1338,11 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) { JITSymbolFlags WeakExported = JITSymbolFlags::Exported; WeakExported &= JITSymbolFlags::Weak; - std::unique_ptr FooResponsibility; + std::unique_ptr FooR; auto MU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { - FooResponsibility = - std::make_unique(std::move(R)); + [&](std::unique_ptr R) { + FooR = std::move(R); }); cantFail(JD.define(MU)); @@ -1328,7 +1356,7 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) { auto MU2 = std::make_unique( SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}), - [](MaterializationResponsibility R) { + [](std::unique_ptr R) { llvm_unreachable("This unit should never be materialized"); }); @@ -1339,8 +1367,8 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) { consumeError(std::move(Err)); // No dependencies registered, can't fail: - cantFail(FooResponsibility->notifyResolved(SymbolMap({{Foo, FooSym}}))); - cantFail(FooResponsibility->notifyEmitted()); + cantFail(FooR->notifyResolved(SymbolMap({{Foo, FooSym}}))); + cantFail(FooR->notifyEmitted()); } static bool linkOrdersEqual(const std::vector> &LHS, diff --git a/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp index 50e7b60a2df4e..81ff3e7a87b30 100644 --- a/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp @@ -39,15 +39,15 @@ TEST_F(LazyReexportsTest, BasicLocalCallThroughManagerOperation) { cantFail(JD.define(std::make_unique( SymbolFlagsMap({{DummyTarget, JITSymbolFlags::Exported}}), - [&](MaterializationResponsibility R) { + [&](std::unique_ptr R) { DummyTargetMaterialized = true; // No dependencies registered, can't fail. - cantFail(R.notifyResolved( + cantFail(R->notifyResolved( {{DummyTarget, JITEvaluatedSymbol(static_cast( reinterpret_cast(&dummyTarget)), JITSymbolFlags::Exported)}})); - cantFail(R.notifyEmitted()); + cantFail(R->notifyEmitted()); }))); unsigned NotifyResolvedCount = 0; diff --git a/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h index b25851d8f796c..afbc4a9ffaa5c 100644 --- a/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h +++ b/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h @@ -86,7 +86,7 @@ class OrcNativeTarget { class SimpleMaterializationUnit : public orc::MaterializationUnit { public: using MaterializeFunction = - std::function; + std::function)>; using DiscardFunction = std::function; using DestructorFunction = std::function; @@ -108,7 +108,8 @@ class SimpleMaterializationUnit : public orc::MaterializationUnit { StringRef getName() const override { return ""; } - void materialize(orc::MaterializationResponsibility R) override { + void + materialize(std::unique_ptr R) override { Materialize(std::move(R)); } From 49993635b2310cafcf4f67fe0a50271e76a52544 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Fri, 11 Sep 2020 09:35:20 +0100 Subject: [PATCH 176/234] Revert "[ORC] Make MaterializationResponsibility immovable, pass by unique_ptr." This reverts commit c74900ca67241bf963b7a4cfa1fae8eadf6bb8cd. This appears to be breaking some builds on macOS and has been causing build failures on Green Dragon (see below). I am reverting this for now, to unblock testing on Green Dragon. http://green.lab.llvm.org/green/job/clang-stage1-cmake-RA-incremental/18144/console [65/187] /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DBUILD_EXAMPLES -DGTEST_HAS_RTTI=0 -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Iexamples/ThinLtoJIT -I/Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/examples/ThinLtoJIT -Iinclude -I/Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -fdiagnostics-color -O3 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -mmacosx-version-min=10.9 -fno-exceptions -fno-rtti -UNDEBUG -std=c++14 -MD -MT examples/ThinLtoJIT/CMakeFiles/ThinLtoJIT.dir/ThinLtoDiscoveryThread.cpp.o -MF examples/ThinLtoJIT/CMakeFiles/ThinLtoJIT.dir/ThinLtoDiscoveryThread.cpp.o.d -o examples/ThinLtoJIT/CMakeFiles/ThinLtoJIT.dir/ThinLtoDiscoveryThread.cpp.o -c /Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/examples/ThinLtoJIT/ThinLtoDiscoveryThread.cpp FAILED: examples/ThinLtoJIT/CMakeFiles/ThinLtoJIT.dir/ThinLtoDiscoveryThread.cpp.o /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -DBUILD_EXAMPLES -DGTEST_HAS_RTTI=0 -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Iexamples/ThinLtoJIT -I/Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/examples/ThinLtoJIT -Iinclude -I/Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -fdiagnostics-color -O3 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -mmacosx-version-min=10.9 -fno-exceptions -fno-rtti -UNDEBUG -std=c++14 -MD -MT examples/ThinLtoJIT/CMakeFiles/ThinLtoJIT.dir/ThinLtoDiscoveryThread.cpp.o -MF examples/ThinLtoJIT/CMakeFiles/ThinLtoJIT.dir/ThinLtoDiscoveryThread.cpp.o.d -o examples/ThinLtoJIT/CMakeFiles/ThinLtoJIT.dir/ThinLtoDiscoveryThread.cpp.o -c /Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/examples/ThinLtoJIT/ThinLtoDiscoveryThread.cpp In file included from /Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/examples/ThinLtoJIT/ThinLtoDiscoveryThread.cpp:7: /Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.h:37:68: error: non-virtual member function marked 'override' hides virtual member function void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override; ^ /Users/buildslave/jenkins/workspace/clang-stage1-cmake-RA-incremental/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Layer.h:103:16: note: hidden overloaded virtual function 'llvm::orc::IRLayer::emit' declared here: type mismatch at 1st parameter ('std::unique_ptr' vs 'llvm::orc::MaterializationResponsibility') virtual void emit(std::unique_ptr R, ^ 1 error generated. --- .../SpeculativeJIT/SpeculativeJIT.cpp | 15 +- .../Orc/CompileOnDemandLayer.h | 6 +- llvm/include/llvm/ExecutionEngine/Orc/Core.h | 37 ++- .../llvm/ExecutionEngine/Orc/IRCompileLayer.h | 3 +- .../ExecutionEngine/Orc/IRTransformLayer.h | 3 +- llvm/include/llvm/ExecutionEngine/Orc/Layer.h | 11 +- .../llvm/ExecutionEngine/Orc/LazyReexports.h | 2 +- .../ExecutionEngine/Orc/ObjectLinkingLayer.h | 2 +- .../Orc/ObjectTransformLayer.h | 2 +- .../Orc/RTDyldObjectLinkingLayer.h | 2 +- .../llvm/ExecutionEngine/Orc/Speculation.h | 3 +- .../Orc/CompileOnDemandLayer.cpp | 42 +-- llvm/lib/ExecutionEngine/Orc/Core.cpp | 50 ++-- .../ExecutionEngine/Orc/IRCompileLayer.cpp | 6 +- .../ExecutionEngine/Orc/IRTransformLayer.cpp | 6 +- .../ExecutionEngine/Orc/IndirectionUtils.cpp | 6 +- llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 20 +- llvm/lib/ExecutionEngine/Orc/Layer.cpp | 8 +- .../lib/ExecutionEngine/Orc/LazyReexports.cpp | 16 +- .../Orc/ObjectLinkingLayer.cpp | 59 +++-- .../Orc/ObjectTransformLayer.cpp | 7 +- .../Orc/RTDyldObjectLinkingLayer.cpp | 25 +- llvm/lib/ExecutionEngine/Orc/Speculation.cpp | 4 +- .../ExecutionEngine/Orc/CoreAPIsTest.cpp | 242 ++++++++---------- .../Orc/LazyCallThroughAndReexportsTest.cpp | 6 +- .../ExecutionEngine/Orc/OrcTestCommon.h | 5 +- 26 files changed, 274 insertions(+), 314 deletions(-) diff --git a/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp b/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp index 24cf0847558f9..4de4897053c1b 100644 --- a/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp +++ b/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp @@ -113,13 +113,14 @@ class SpeculativeJIT { this->CODLayer.setImplMap(&Imps); this->ES->setDispatchMaterialization( [this](std::unique_ptr MU, - std::unique_ptr MR) { - CompileThreads.async( - [UnownedMU = MU.release(), UnownedMR = MR.release()]() { - std::unique_ptr MU(UnownedMU); - std::unique_ptr MR(UnownedMR); - MU->materialize(std::move(MR)); - }); + MaterializationResponsibility MR) { + // FIXME: Switch to move capture once we have C++14. + auto SharedMU = std::shared_ptr(std::move(MU)); + auto SharedMR = + std::make_shared(std::move(MR)); + CompileThreads.async([SharedMU, SharedMR]() { + SharedMU->materialize(std::move(*SharedMR)); + }); }); ExitOnErr(S.addSpeculationRuntime(MainJD, Mangle)); LocalCXXRuntimeOverrides CXXRuntimeoverrides; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 3a2f8b54ad22b..9ecc0464dec1b 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -96,8 +96,7 @@ class CompileOnDemandLayer : public IRLayer { /// Emits the given module. This should not be called by clients: it will be /// called by the JIT when a definition added via the add method is requested. - void emit(std::unique_ptr R, - ThreadSafeModule TSM) override; + void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override; private: struct PerDylibResources { @@ -121,8 +120,7 @@ class CompileOnDemandLayer : public IRLayer { void expandPartition(GlobalValueSet &Partition); - void emitPartition(std::unique_ptr R, - ThreadSafeModule TSM, + void emitPartition(MaterializationResponsibility R, ThreadSafeModule TSM, IRMaterializationUnit::SymbolNameToDefinitionMap Defs); mutable std::mutex CODLayerMutex; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Core.h b/llvm/include/llvm/ExecutionEngine/Orc/Core.h index 70bd983c40ce0..6951df3f2d3f2 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Core.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Core.h @@ -410,7 +410,7 @@ class UnexpectedSymbolDefinitions : public ErrorInfo - delegate(const SymbolNameSet &Symbols, VModuleKey NewKey = VModuleKey()); + MaterializationResponsibility delegate(const SymbolNameSet &Symbols, + VModuleKey NewKey = VModuleKey()); void addDependencies(const SymbolStringPtr &Name, const SymbolDependenceMap &Dependencies); @@ -577,8 +577,7 @@ class MaterializationUnit { /// Implementations of this method should materialize all symbols /// in the materialzation unit, except for those that have been /// previously discarded. - virtual void - materialize(std::unique_ptr R) = 0; + virtual void materialize(MaterializationResponsibility R) = 0; /// Called by JITDylibs to notify MaterializationUnits that the given symbol /// has been overridden. @@ -595,11 +594,10 @@ class MaterializationUnit { private: virtual void anchor(); - std::unique_ptr + MaterializationResponsibility createMaterializationResponsibility(std::shared_ptr JD) { - return std::unique_ptr( - new MaterializationResponsibility(std::move(JD), std::move(SymbolFlags), - std::move(InitSymbol), K)); + return MaterializationResponsibility(std::move(JD), std::move(SymbolFlags), + std::move(InitSymbol), K); } /// Implementations of this method should discard the given symbol @@ -623,7 +621,7 @@ class AbsoluteSymbolsMaterializationUnit : public MaterializationUnit { StringRef getName() const override; private: - void materialize(std::unique_ptr R) override; + void materialize(MaterializationResponsibility R) override; void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; static SymbolFlagsMap extractFlags(const SymbolMap &Symbols); @@ -665,7 +663,7 @@ class ReExportsMaterializationUnit : public MaterializationUnit { StringRef getName() const override; private: - void materialize(std::unique_ptr R) override; + void materialize(MaterializationResponsibility R) override; void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases); @@ -1118,7 +1116,7 @@ class ExecutionSession { /// For dispatching MaterializationUnit::materialize calls. using DispatchMaterializationFunction = std::function MU, - std::unique_ptr MR)>; + MaterializationResponsibility MR)>; /// Construct an ExecutionSession. /// @@ -1270,11 +1268,10 @@ class ExecutionSession { SymbolState RequiredState = SymbolState::Ready); /// Materialize the given unit. - void - dispatchMaterialization(std::unique_ptr MU, - std::unique_ptr MR) { + void dispatchMaterialization(std::unique_ptr MU, + MaterializationResponsibility MR) { assert(MU && "MU must be non-null"); - DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR->getTargetJITDylib(), *MU)); + DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR.getTargetJITDylib(), *MU)); DispatchMaterialization(std::move(MU), std::move(MR)); } @@ -1286,9 +1283,9 @@ class ExecutionSession { logAllUnhandledErrors(std::move(Err), errs(), "JIT session error: "); } - static void materializeOnCurrentThread( - std::unique_ptr MU, - std::unique_ptr MR) { + static void + materializeOnCurrentThread(std::unique_ptr MU, + MaterializationResponsibility MR) { MU->materialize(std::move(MR)); } @@ -1312,7 +1309,7 @@ class ExecutionSession { // with callbacks from asynchronous queries. mutable std::recursive_mutex OutstandingMUsMutex; std::vector, - std::unique_ptr>> + MaterializationResponsibility>> OutstandingMUs; }; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h index 2c53e2f66e851..eb74d283f0435 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h @@ -55,8 +55,7 @@ class IRCompileLayer : public IRLayer { void setNotifyCompiled(NotifyCompiledFunction NotifyCompiled); - void emit(std::unique_ptr R, - ThreadSafeModule TSM) override; + void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override; private: mutable std::mutex IRLayerMutex; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h index ee4ee3437fa6d..296d74ae6b865 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h @@ -37,8 +37,7 @@ class IRTransformLayer : public IRLayer { this->Transform = std::move(Transform); } - void emit(std::unique_ptr R, - ThreadSafeModule TSM) override; + void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override; static ThreadSafeModule identityTransform(ThreadSafeModule TSM, MaterializationResponsibility &R) { diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Layer.h b/llvm/include/llvm/ExecutionEngine/Orc/Layer.h index c8a41199760da..e843d0f562455 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Layer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Layer.h @@ -100,8 +100,7 @@ class IRLayer { VModuleKey K = VModuleKey()); /// Emit should materialize the given IR. - virtual void emit(std::unique_ptr R, - ThreadSafeModule TSM) = 0; + virtual void emit(MaterializationResponsibility R, ThreadSafeModule TSM) = 0; private: bool CloneToNewContextOnEmit = false; @@ -118,7 +117,8 @@ class BasicIRLayerMaterializationUnit : public IRMaterializationUnit { ThreadSafeModule TSM, VModuleKey K); private: - void materialize(std::unique_ptr R) override; + + void materialize(MaterializationResponsibility R) override; IRLayer &L; VModuleKey K; @@ -139,7 +139,7 @@ class ObjectLayer { VModuleKey K = VModuleKey()); /// Emit should materialize the given IR. - virtual void emit(std::unique_ptr R, + virtual void emit(MaterializationResponsibility R, std::unique_ptr O) = 0; private: @@ -162,7 +162,8 @@ class BasicObjectLayerMaterializationUnit : public MaterializationUnit { StringRef getName() const override; private: - void materialize(std::unique_ptr R) override; + + void materialize(MaterializationResponsibility R) override; void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; ObjectLayer &L; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h b/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h index 63e3a80d87d86..9206e40fffb1c 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h @@ -149,7 +149,7 @@ class LazyReexportsMaterializationUnit : public MaterializationUnit { StringRef getName() const override; private: - void materialize(std::unique_ptr R) override; + void materialize(MaterializationResponsibility R) override; void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases); diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h index cbcf3928be3df..cb8ee130ab614 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h @@ -119,7 +119,7 @@ class ObjectLinkingLayer : public ObjectLayer { } /// Emit the object. - void emit(std::unique_ptr R, + void emit(MaterializationResponsibility R, std::unique_ptr O) override; /// Instructs this ObjectLinkingLayer instance to override the symbol flags diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h index c77649f19fc74..bf989cc8677cf 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h @@ -31,7 +31,7 @@ class ObjectTransformLayer : public ObjectLayer { ObjectTransformLayer(ExecutionSession &ES, ObjectLayer &BaseLayer, TransformFunction Transform = TransformFunction()); - void emit(std::unique_ptr R, + void emit(MaterializationResponsibility R, std::unique_ptr O) override; void setTransform(TransformFunction Transform) { diff --git a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h index 9cd3c57a19c6a..9ada0871cf0cb 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h @@ -58,7 +58,7 @@ class RTDyldObjectLinkingLayer : public ObjectLayer { ~RTDyldObjectLinkingLayer(); /// Emit the object. - void emit(std::unique_ptr R, + void emit(MaterializationResponsibility R, std::unique_ptr O) override; /// Set the NotifyLoaded callback. diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h b/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h index a138f60a77564..10f78c8bc6beb 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h @@ -181,8 +181,7 @@ class IRSpeculationLayer : public IRLayer { : IRLayer(ES, BaseLayer.getManglingOptions()), NextLayer(BaseLayer), S(Spec), Mangle(Mangle), QueryAnalysis(Interpreter) {} - void emit(std::unique_ptr R, - ThreadSafeModule TSM) override; + void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override; private: TargetAndLikelies diff --git a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp index dfb0d06bdba3d..9e38dc36faae7 100644 --- a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp @@ -88,7 +88,7 @@ class PartitioningIRMaterializationUnit : public IRMaterializationUnit { Parent(Parent) {} private: - void materialize(std::unique_ptr R) override { + void materialize(MaterializationResponsibility R) override { Parent.emitPartition(std::move(R), std::move(TSM), std::move(SymbolToDefinition)); } @@ -128,15 +128,15 @@ void CompileOnDemandLayer::setPartitionFunction(PartitionFunction Partition) { void CompileOnDemandLayer::setImplMap(ImplSymbolMap *Imp) { this->AliaseeImpls = Imp; } -void CompileOnDemandLayer::emit( - std::unique_ptr R, ThreadSafeModule TSM) { +void CompileOnDemandLayer::emit(MaterializationResponsibility R, + ThreadSafeModule TSM) { assert(TSM && "Null module"); auto &ES = getExecutionSession(); // Sort the callables and non-callables, build re-exports and lodge the // actual module with the implementation dylib. - auto &PDR = getPerDylibResources(R->getTargetJITDylib()); + auto &PDR = getPerDylibResources(R.getTargetJITDylib()); SymbolAliasMap NonCallables; SymbolAliasMap Callables; @@ -145,7 +145,7 @@ void CompileOnDemandLayer::emit( cleanUpModule(M); }); - for (auto &KV : R->getSymbols()) { + for (auto &KV : R.getSymbols()) { auto &Name = KV.first; auto &Flags = KV.second; if (Flags.isCallable()) @@ -158,19 +158,19 @@ void CompileOnDemandLayer::emit( // implementation dylib. if (auto Err = PDR.getImplDylib().define( std::make_unique( - ES, *getManglingOptions(), std::move(TSM), R->getVModuleKey(), + ES, *getManglingOptions(), std::move(TSM), R.getVModuleKey(), *this))) { ES.reportError(std::move(Err)); - R->failMaterialization(); + R.failMaterialization(); return; } if (!NonCallables.empty()) - R->replace(reexports(PDR.getImplDylib(), std::move(NonCallables), - JITDylibLookupFlags::MatchAllSymbols)); + R.replace(reexports(PDR.getImplDylib(), std::move(NonCallables), + JITDylibLookupFlags::MatchAllSymbols)); if (!Callables.empty()) - R->replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(), - std::move(Callables), AliaseeImpls)); + R.replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(), + std::move(Callables), AliaseeImpls)); } CompileOnDemandLayer::PerDylibResources & @@ -247,7 +247,7 @@ void CompileOnDemandLayer::expandPartition(GlobalValueSet &Partition) { } void CompileOnDemandLayer::emitPartition( - std::unique_ptr R, ThreadSafeModule TSM, + MaterializationResponsibility R, ThreadSafeModule TSM, IRMaterializationUnit::SymbolNameToDefinitionMap Defs) { // FIXME: Need a 'notify lazy-extracting/emitting' callback to tie the @@ -257,8 +257,8 @@ void CompileOnDemandLayer::emitPartition( auto &ES = getExecutionSession(); GlobalValueSet RequestedGVs; - for (auto &Name : R->getRequestedSymbols()) { - if (Name == R->getInitializerSymbol()) + for (auto &Name : R.getRequestedSymbols()) { + if (Name == R.getInitializerSymbol()) TSM.withModuleDo([&](Module &M) { for (auto &GV : getStaticInitGVs(M)) RequestedGVs.insert(&GV); @@ -285,9 +285,9 @@ void CompileOnDemandLayer::emitPartition( // If the partition is empty, return the whole module to the symbol table. if (GVsToExtract->empty()) { - R->replace(std::make_unique( - std::move(TSM), R->getVModuleKey(), R->getSymbols(), - R->getInitializerSymbol(), std::move(Defs), *this)); + R.replace(std::make_unique( + std::move(TSM), R.getVModuleKey(), R.getSymbols(), + R.getInitializerSymbol(), std::move(Defs), *this)); return; } @@ -308,7 +308,7 @@ void CompileOnDemandLayer::emitPartition( IRSymbolMapper::add(ES, *getManglingOptions(), PromotedGlobals, SymbolFlags); - if (auto Err = R->defineMaterializing(SymbolFlags)) + if (auto Err = R.defineMaterializing(SymbolFlags)) return std::move(Err); } @@ -348,12 +348,12 @@ void CompileOnDemandLayer::emitPartition( if (!ExtractedTSM) { ES.reportError(ExtractedTSM.takeError()); - R->failMaterialization(); + R.failMaterialization(); return; } - R->replace(std::make_unique( - ES, *getManglingOptions(), std::move(TSM), R->getVModuleKey(), *this)); + R.replace(std::make_unique( + ES, *getManglingOptions(), std::move(TSM), R.getVModuleKey(), *this)); BaseLayer.emit(std::move(R), std::move(*ExtractedTSM)); } diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp index 243bac79c012f..18eced68f07bc 100644 --- a/llvm/lib/ExecutionEngine/Orc/Core.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp @@ -279,7 +279,7 @@ void MaterializationResponsibility::replace( JD->replace(std::move(MU)); } -std::unique_ptr +MaterializationResponsibility MaterializationResponsibility::delegate(const SymbolNameSet &Symbols, VModuleKey NewKey) { @@ -302,10 +302,9 @@ MaterializationResponsibility::delegate(const SymbolNameSet &Symbols, SymbolFlags.erase(I); } - return std::unique_ptr( - new MaterializationResponsibility(JD, std::move(DelegatedFlags), - std::move(DelegatedInitSymbol), - std::move(NewKey))); + return MaterializationResponsibility(JD, std::move(DelegatedFlags), + std::move(DelegatedInitSymbol), + std::move(NewKey)); } void MaterializationResponsibility::addDependencies( @@ -339,10 +338,10 @@ StringRef AbsoluteSymbolsMaterializationUnit::getName() const { } void AbsoluteSymbolsMaterializationUnit::materialize( - std::unique_ptr R) { + MaterializationResponsibility R) { // No dependencies, so these calls can't fail. - cantFail(R->notifyResolved(Symbols)); - cantFail(R->notifyEmitted()); + cantFail(R.notifyResolved(Symbols)); + cantFail(R.notifyEmitted()); } void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD, @@ -371,16 +370,16 @@ StringRef ReExportsMaterializationUnit::getName() const { } void ReExportsMaterializationUnit::materialize( - std::unique_ptr R) { + MaterializationResponsibility R) { - auto &ES = R->getTargetJITDylib().getExecutionSession(); - JITDylib &TgtJD = R->getTargetJITDylib(); + auto &ES = R.getTargetJITDylib().getExecutionSession(); + JITDylib &TgtJD = R.getTargetJITDylib(); JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD; // Find the set of requested aliases and aliasees. Return any unrequested // aliases back to the JITDylib so as to not prematurely materialize any // aliasees. - auto RequestedSymbols = R->getRequestedSymbols(); + auto RequestedSymbols = R.getRequestedSymbols(); SymbolAliasMap RequestedAliases; for (auto &Name : RequestedSymbols) { @@ -400,19 +399,18 @@ void ReExportsMaterializationUnit::materialize( if (!Aliases.empty()) { if (SourceJD) - R->replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags)); + R.replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags)); else - R->replace(symbolAliases(std::move(Aliases))); + R.replace(symbolAliases(std::move(Aliases))); } // The OnResolveInfo struct will hold the aliases and responsibilty for each // query in the list. struct OnResolveInfo { - OnResolveInfo(std::unique_ptr R, - SymbolAliasMap Aliases) + OnResolveInfo(MaterializationResponsibility R, SymbolAliasMap Aliases) : R(std::move(R)), Aliases(std::move(Aliases)) {} - std::unique_ptr R; + MaterializationResponsibility R; SymbolAliasMap Aliases; }; @@ -453,7 +451,7 @@ void ReExportsMaterializationUnit::materialize( assert(!QuerySymbols.empty() && "Alias cycle detected!"); auto QueryInfo = std::make_shared( - R->delegate(ResponsibilitySymbols), std::move(QueryAliases)); + R.delegate(ResponsibilitySymbols), std::move(QueryAliases)); QueryInfos.push_back( make_pair(std::move(QuerySymbols), std::move(QueryInfo))); } @@ -482,12 +480,12 @@ void ReExportsMaterializationUnit::materialize( for (auto &KV : QueryInfo->Aliases) if (SrcJDDeps.count(KV.second.Aliasee)) { PerAliasDeps = {KV.second.Aliasee}; - QueryInfo->R->addDependencies(KV.first, PerAliasDepsMap); + QueryInfo->R.addDependencies(KV.first, PerAliasDepsMap); } }; auto OnComplete = [QueryInfo](Expected Result) { - auto &ES = QueryInfo->R->getTargetJITDylib().getExecutionSession(); + auto &ES = QueryInfo->R.getTargetJITDylib().getExecutionSession(); if (Result) { SymbolMap ResolutionMap; for (auto &KV : QueryInfo->Aliases) { @@ -501,19 +499,19 @@ void ReExportsMaterializationUnit::materialize( ResolutionMap[KV.first] = JITEvaluatedSymbol( (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags); } - if (auto Err = QueryInfo->R->notifyResolved(ResolutionMap)) { + if (auto Err = QueryInfo->R.notifyResolved(ResolutionMap)) { ES.reportError(std::move(Err)); - QueryInfo->R->failMaterialization(); + QueryInfo->R.failMaterialization(); return; } - if (auto Err = QueryInfo->R->notifyEmitted()) { + if (auto Err = QueryInfo->R.notifyEmitted()) { ES.reportError(std::move(Err)); - QueryInfo->R->failMaterialization(); + QueryInfo->R.failMaterialization(); return; } } else { ES.reportError(Result.takeError()); - QueryInfo->R->failMaterialization(); + QueryInfo->R.failMaterialization(); } }; @@ -2133,7 +2131,7 @@ void ExecutionSession::dump(raw_ostream &OS) { void ExecutionSession::runOutstandingMUs() { while (1) { Optional, - std::unique_ptr>> + MaterializationResponsibility>> JMU; { diff --git a/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp b/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp index c6f6870279728..023940dc82982 100644 --- a/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp @@ -25,7 +25,7 @@ void IRCompileLayer::setNotifyCompiled(NotifyCompiledFunction NotifyCompiled) { this->NotifyCompiled = std::move(NotifyCompiled); } -void IRCompileLayer::emit(std::unique_ptr R, +void IRCompileLayer::emit(MaterializationResponsibility R, ThreadSafeModule TSM) { assert(TSM && "Module must not be null"); @@ -33,13 +33,13 @@ void IRCompileLayer::emit(std::unique_ptr R, { std::lock_guard Lock(IRLayerMutex); if (NotifyCompiled) - NotifyCompiled(R->getVModuleKey(), std::move(TSM)); + NotifyCompiled(R.getVModuleKey(), std::move(TSM)); else TSM = ThreadSafeModule(); } BaseLayer.emit(std::move(R), std::move(*Obj)); } else { - R->failMaterialization(); + R.failMaterialization(); getExecutionSession().reportError(Obj.takeError()); } } diff --git a/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp b/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp index d5b11349277c1..511248f83b259 100644 --- a/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp @@ -17,14 +17,14 @@ IRTransformLayer::IRTransformLayer(ExecutionSession &ES, IRLayer &BaseLayer, : IRLayer(ES, BaseLayer.getManglingOptions()), BaseLayer(BaseLayer), Transform(std::move(Transform)) {} -void IRTransformLayer::emit(std::unique_ptr R, +void IRTransformLayer::emit(MaterializationResponsibility R, ThreadSafeModule TSM) { assert(TSM && "Module must not be null"); - if (auto TransformedTSM = Transform(std::move(TSM), *R)) + if (auto TransformedTSM = Transform(std::move(TSM), R)) BaseLayer.emit(std::move(R), std::move(*TransformedTSM)); else { - R->failMaterialization(); + R.failMaterialization(); getExecutionSession().reportError(TransformedTSM.takeError()); } } diff --git a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp index 7d57ed5a3a04c..4f7f6089e68db 100644 --- a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp +++ b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp @@ -33,12 +33,12 @@ class CompileCallbackMaterializationUnit : public orc::MaterializationUnit { StringRef getName() const override { return ""; } private: - void materialize(std::unique_ptr R) override { + void materialize(MaterializationResponsibility R) override { SymbolMap Result; Result[Name] = JITEvaluatedSymbol(Compile(), JITSymbolFlags::Exported); // No dependencies, so these calls cannot fail. - cantFail(R->notifyResolved(Result)); - cantFail(R->notifyEmitted()); + cantFail(R.notifyResolved(Result)); + cantFail(R.notifyEmitted()); } void discard(const JITDylib &JD, const SymbolStringPtr &Name) override { diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp index 81f500d66bc29..373d86d92f8d7 100644 --- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -1085,17 +1085,15 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err) std::make_unique(hardware_concurrency(S.NumCompileThreads)); ES->setDispatchMaterialization( [this](std::unique_ptr MU, - std::unique_ptr MR) { - // FIXME: We should be able to use move-capture here, but ThreadPool's - // AsyncTaskTys are std::functions rather than unique_functions - // (because MSVC's std::packaged_tasks don't support move-only types). - // Fix this when all the above gets sorted out. - CompileThreads->async( - [UnownedMU = MU.release(), UnownedMR = MR.release()]() mutable { - std::unique_ptr MU(UnownedMU); - std::unique_ptr MR(UnownedMR); - MU->materialize(std::move(MR)); - }); + MaterializationResponsibility MR) { + // FIXME: Switch to move capture once ThreadPool uses unique_function. + auto SharedMU = std::shared_ptr(std::move(MU)); + auto SharedMR = + std::make_shared(std::move(MR)); + auto Work = [SharedMU, SharedMR]() mutable { + SharedMU->materialize(std::move(*SharedMR)); + }; + CompileThreads->async(std::move(Work)); }); } diff --git a/llvm/lib/ExecutionEngine/Orc/Layer.cpp b/llvm/lib/ExecutionEngine/Orc/Layer.cpp index 8052e7b08a5a6..0a5d5577e99e8 100644 --- a/llvm/lib/ExecutionEngine/Orc/Layer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Layer.cpp @@ -133,7 +133,7 @@ BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit( L(L), K(std::move(K)) {} void BasicIRLayerMaterializationUnit::materialize( - std::unique_ptr R) { + MaterializationResponsibility R) { // Throw away the SymbolToDefinition map: it's not usable after we hand // off the module. @@ -144,8 +144,8 @@ void BasicIRLayerMaterializationUnit::materialize( TSM = cloneToNewContext(TSM); #ifndef NDEBUG - auto &ES = R->getTargetJITDylib().getExecutionSession(); - auto &N = R->getTargetJITDylib().getName(); + auto &ES = R.getTargetJITDylib().getExecutionSession(); + auto &N = R.getTargetJITDylib().getName(); #endif // NDEBUG LLVM_DEBUG(ES.runSessionLocked( @@ -200,7 +200,7 @@ StringRef BasicObjectLayerMaterializationUnit::getName() const { } void BasicObjectLayerMaterializationUnit::materialize( - std::unique_ptr R) { + MaterializationResponsibility R) { L.emit(std::move(R), std::move(O)); } diff --git a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp index 695f6cc9c1cb4..5e604130d6eab 100644 --- a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp @@ -154,8 +154,8 @@ StringRef LazyReexportsMaterializationUnit::getName() const { } void LazyReexportsMaterializationUnit::materialize( - std::unique_ptr R) { - auto RequestedSymbols = R->getRequestedSymbols(); + MaterializationResponsibility R) { + auto RequestedSymbols = R.getRequestedSymbols(); SymbolAliasMap RequestedAliases; for (auto &RequestedSymbol : RequestedSymbols) { @@ -166,8 +166,8 @@ void LazyReexportsMaterializationUnit::materialize( } if (!CallableAliases.empty()) - R->replace(lazyReexports(LCTManager, ISManager, SourceJD, - std::move(CallableAliases), AliaseeTable)); + R.replace(lazyReexports(LCTManager, ISManager, SourceJD, + std::move(CallableAliases), AliaseeTable)); IndirectStubsManager::StubInitsMap StubInits; for (auto &Alias : RequestedAliases) { @@ -182,7 +182,7 @@ void LazyReexportsMaterializationUnit::materialize( if (!CallThroughTrampoline) { SourceJD.getExecutionSession().reportError( CallThroughTrampoline.takeError()); - R->failMaterialization(); + R.failMaterialization(); return; } @@ -195,7 +195,7 @@ void LazyReexportsMaterializationUnit::materialize( if (auto Err = ISManager.createStubs(StubInits)) { SourceJD.getExecutionSession().reportError(std::move(Err)); - R->failMaterialization(); + R.failMaterialization(); return; } @@ -204,8 +204,8 @@ void LazyReexportsMaterializationUnit::materialize( Stubs[Alias.first] = ISManager.findStub(*Alias.first, false); // No registered dependencies, so these calls cannot fail. - cantFail(R->notifyResolved(Stubs)); - cantFail(R->notifyEmitted()); + cantFail(R.notifyResolved(Stubs)); + cantFail(R.notifyEmitted()); } void LazyReexportsMaterializationUnit::discard(const JITDylib &JD, diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp index 9e3245d9cc991..d8283fa7e3461 100644 --- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp @@ -24,10 +24,9 @@ namespace orc { class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { public: - ObjectLinkingLayerJITLinkContext( - ObjectLinkingLayer &Layer, - std::unique_ptr MR, - std::unique_ptr ObjBuffer) + ObjectLinkingLayerJITLinkContext(ObjectLinkingLayer &Layer, + MaterializationResponsibility MR, + std::unique_ptr ObjBuffer) : Layer(Layer), MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {} ~ObjectLinkingLayerJITLinkContext() { @@ -45,14 +44,14 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { void notifyFailed(Error Err) override { Layer.getExecutionSession().reportError(std::move(Err)); - MR->failMaterialization(); + MR.failMaterialization(); } void lookup(const LookupMap &Symbols, std::unique_ptr LC) override { JITDylibSearchOrder LinkOrder; - MR->getTargetJITDylib().withLinkOrderDo( + MR.getTargetJITDylib().withLinkOrderDo( [&](const JITDylibSearchOrder &LO) { LinkOrder = LO; }); auto &ES = Layer.getExecutionSession(); @@ -86,8 +85,8 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { for (auto &KV : InternalNamedSymbolDeps) { SymbolDependenceMap InternalDeps; - InternalDeps[&MR->getTargetJITDylib()] = std::move(KV.second); - MR->addDependencies(KV.first, InternalDeps); + InternalDeps[&MR.getTargetJITDylib()] = std::move(KV.second); + MR.addDependencies(KV.first, InternalDeps); } ES.lookup(LookupKind::Static, LinkOrder, std::move(LookupSet), @@ -116,7 +115,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { InternedResult[InternedName] = JITEvaluatedSymbol(Sym->getAddress(), Flags); - if (AutoClaim && !MR->getSymbols().count(InternedName)) { + if (AutoClaim && !MR.getSymbols().count(InternedName)) { assert(!ExtraSymbolsToClaim.count(InternedName) && "Duplicate symbol to claim?"); ExtraSymbolsToClaim[InternedName] = Flags; @@ -134,7 +133,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { Flags |= JITSymbolFlags::Weak; InternedResult[InternedName] = JITEvaluatedSymbol(Sym->getAddress(), Flags); - if (AutoClaim && !MR->getSymbols().count(InternedName)) { + if (AutoClaim && !MR.getSymbols().count(InternedName)) { assert(!ExtraSymbolsToClaim.count(InternedName) && "Duplicate symbol to claim?"); ExtraSymbolsToClaim[InternedName] = Flags; @@ -142,19 +141,19 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { } if (!ExtraSymbolsToClaim.empty()) - if (auto Err = MR->defineMaterializing(ExtraSymbolsToClaim)) + if (auto Err = MR.defineMaterializing(ExtraSymbolsToClaim)) return Err; { - // Check that InternedResult matches up with MR->getSymbols(). + // Check that InternedResult matches up with MR.getSymbols(). // This guards against faulty transformations / compilers / object caches. // First check that there aren't any missing symbols. size_t NumMaterializationSideEffectsOnlySymbols = 0; SymbolNameVector ExtraSymbols; SymbolNameVector MissingSymbols; - for (auto &KV : MR->getSymbols()) { + for (auto &KV : MR.getSymbols()) { // If this is a materialization-side-effects only symbol then bump // the counter and make sure it's *not* defined, otherwise make @@ -176,9 +175,9 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { // If there are more definitions than expected, add them to the // ExtraSymbols vector. if (InternedResult.size() > - MR->getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) { + MR.getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) { for (auto &KV : InternedResult) - if (!MR->getSymbols().count(KV.first)) + if (!MR.getSymbols().count(KV.first)) ExtraSymbols.push_back(KV.first); } @@ -188,23 +187,23 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { std::move(ExtraSymbols)); } - if (auto Err = MR->notifyResolved(InternedResult)) + if (auto Err = MR.notifyResolved(InternedResult)) return Err; - Layer.notifyLoaded(*MR); + Layer.notifyLoaded(MR); return Error::success(); } void notifyFinalized( std::unique_ptr A) override { - if (auto Err = Layer.notifyEmitted(*MR, std::move(A))) { + if (auto Err = Layer.notifyEmitted(MR, std::move(A))) { Layer.getExecutionSession().reportError(std::move(Err)); - MR->failMaterialization(); + MR.failMaterialization(); return; } - if (auto Err = MR->notifyEmitted()) { + if (auto Err = MR.notifyEmitted()) { Layer.getExecutionSession().reportError(std::move(Err)); - MR->failMaterialization(); + MR.failMaterialization(); } } @@ -218,7 +217,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { Config.PrePrunePasses.push_back( [this](LinkGraph &G) { return externalizeWeakAndCommonSymbols(G); }); - Layer.modifyPassConfig(*MR, TT, Config); + Layer.modifyPassConfig(MR, TT, Config); Config.PostPrunePasses.push_back( [this](LinkGraph &G) { return computeNamedSymbolDependencies(G); }); @@ -238,13 +237,13 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { auto &ES = Layer.getExecutionSession(); for (auto *Sym : G.defined_symbols()) if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { - if (!MR->getSymbols().count(ES.intern(Sym->getName()))) + if (!MR.getSymbols().count(ES.intern(Sym->getName()))) G.makeExternal(*Sym); } for (auto *Sym : G.absolute_symbols()) if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { - if (!MR->getSymbols().count(ES.intern(Sym->getName()))) + if (!MR.getSymbols().count(ES.intern(Sym->getName()))) G.makeExternal(*Sym); } @@ -254,13 +253,13 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { Error markResponsibilitySymbolsLive(LinkGraph &G) const { auto &ES = Layer.getExecutionSession(); for (auto *Sym : G.defined_symbols()) - if (Sym->hasName() && MR->getSymbols().count(ES.intern(Sym->getName()))) + if (Sym->hasName() && MR.getSymbols().count(ES.intern(Sym->getName()))) Sym->setLive(true); return Error::success(); } Error computeNamedSymbolDependencies(LinkGraph &G) { - auto &ES = MR->getTargetJITDylib().getExecutionSession(); + auto &ES = MR.getTargetJITDylib().getExecutionSession(); auto LocalDeps = computeLocalDeps(G); // Compute dependencies for symbols defined in the JITLink graph. @@ -307,7 +306,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { } for (auto &P : Layer.Plugins) { - auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(*MR); + auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(MR); if (SyntheticLocalDeps.empty()) continue; @@ -427,12 +426,12 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { SymbolDeps.erase(&SourceJD); } - MR->addDependencies(Name, SymbolDeps); + MR.addDependencies(Name, SymbolDeps); } } ObjectLinkingLayer &Layer; - std::unique_ptr MR; + MaterializationResponsibility MR; std::unique_ptr ObjBuffer; DenseMap ExternalNamedSymbolDeps; DenseMap InternalNamedSymbolDeps; @@ -453,7 +452,7 @@ ObjectLinkingLayer::~ObjectLinkingLayer() { getExecutionSession().reportError(std::move(Err)); } -void ObjectLinkingLayer::emit(std::unique_ptr R, +void ObjectLinkingLayer::emit(MaterializationResponsibility R, std::unique_ptr O) { assert(O && "Object must not be null"); jitLink(std::make_unique( diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp index a57662e10a794..d18eb38a41423 100644 --- a/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp @@ -17,9 +17,8 @@ ObjectTransformLayer::ObjectTransformLayer(ExecutionSession &ES, TransformFunction Transform) : ObjectLayer(ES), BaseLayer(BaseLayer), Transform(std::move(Transform)) {} -void ObjectTransformLayer::emit( - std::unique_ptr R, - std::unique_ptr O) { +void ObjectTransformLayer::emit(MaterializationResponsibility R, + std::unique_ptr O) { assert(O && "Module must not be null"); // If there is a transform set then apply it. @@ -27,7 +26,7 @@ void ObjectTransformLayer::emit( if (auto TransformedObj = Transform(std::move(O))) O = std::move(*TransformedObj); else { - R->failMaterialization(); + R.failMaterialization(); getExecutionSession().reportError(TransformedObj.takeError()); return; } diff --git a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp index 1981039eb9f12..7888c2fcbdbd9 100644 --- a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp @@ -89,18 +89,23 @@ RTDyldObjectLinkingLayer::~RTDyldObjectLinkingLayer() { } } -void RTDyldObjectLinkingLayer::emit( - std::unique_ptr R, - std::unique_ptr O) { +void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, + std::unique_ptr O) { assert(O && "Object must not be null"); + // This method launches an asynchronous link step that will fulfill our + // materialization responsibility. We need to switch R to be heap + // allocated before that happens so it can live as long as the asynchronous + // link needs it to (i.e. it must be able to outlive this method). + auto SharedR = std::make_shared(std::move(R)); + auto &ES = getExecutionSession(); auto Obj = object::ObjectFile::createObjectFile(*O); if (!Obj) { getExecutionSession().reportError(Obj.takeError()); - R->failMaterialization(); + SharedR->failMaterialization(); return; } @@ -116,7 +121,7 @@ void RTDyldObjectLinkingLayer::emit( continue; } else { ES.reportError(SymType.takeError()); - R->failMaterialization(); + R.failMaterialization(); return; } @@ -124,7 +129,7 @@ void RTDyldObjectLinkingLayer::emit( if (!SymFlagsOrErr) { // TODO: Test this error. ES.reportError(SymFlagsOrErr.takeError()); - R->failMaterialization(); + R.failMaterialization(); return; } @@ -134,14 +139,14 @@ void RTDyldObjectLinkingLayer::emit( InternalSymbols->insert(*SymName); else { ES.reportError(SymName.takeError()); - R->failMaterialization(); + R.failMaterialization(); return; } } } } - auto K = R->getVModuleKey(); + auto K = R.getVModuleKey(); RuntimeDyld::MemoryManager *MemMgr = nullptr; // Create a record a memory manager for this object. @@ -152,10 +157,6 @@ void RTDyldObjectLinkingLayer::emit( MemMgr = MemMgrs.back().get(); } - // Switch to shared ownership of MR so that it can be captured by both - // lambdas below. - std::shared_ptr SharedR(std::move(R)); - JITDylibSearchOrderResolver Resolver(*SharedR); jitLinkForORC( diff --git a/llvm/lib/ExecutionEngine/Orc/Speculation.cpp b/llvm/lib/ExecutionEngine/Orc/Speculation.cpp index 0b4755fe23cfc..3dd536d8253e3 100644 --- a/llvm/lib/ExecutionEngine/Orc/Speculation.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Speculation.cpp @@ -55,7 +55,7 @@ Error Speculator::addSpeculationRuntime(JITDylib &JD, // If two modules, share the same LLVMContext, different threads must // not access them concurrently without locking the associated LLVMContext // this implementation follows this contract. -void IRSpeculationLayer::emit(std::unique_ptr R, +void IRSpeculationLayer::emit(MaterializationResponsibility R, ThreadSafeModule TSM) { assert(TSM && "Speculation Layer received Null Module ?"); @@ -127,7 +127,7 @@ void IRSpeculationLayer::emit(std::unique_ptr R, assert(Mutator.GetInsertBlock()->getParent() == &Fn && "IR builder association mismatch?"); S.registerSymbols(internToJITSymbols(IRNames.getValue()), - &R->getTargetJITDylib()); + &R.getTargetJITDylib()); } } } diff --git a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp index 9a1dbbb172517..2c008dfdbd33e 100644 --- a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp @@ -35,12 +35,12 @@ TEST_F(CoreAPIsStandardTest, BasicSuccessfulLookup) { OnCompletionRun = true; }; - std::unique_ptr FooMR; + std::shared_ptr FooMR; cantFail(JD.define(std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](std::unique_ptr R) { - FooMR = std::move(R); + [&](MaterializationResponsibility R) { + FooMR = std::make_shared(std::move(R)); }))); ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD), @@ -99,9 +99,9 @@ TEST_F(CoreAPIsStandardTest, ResolveUnrequestedSymbol) { cantFail(JD.define(std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}), - [this](std::unique_ptr R) { - cantFail(R->notifyResolved({{Foo, FooSym}, {Bar, BarSym}})); - cantFail(R->notifyEmitted()); + [this](MaterializationResponsibility R) { + cantFail(R.notifyResolved({{Foo, FooSym}, {Bar, BarSym}})); + cantFail(R.notifyEmitted()); }))); auto Result = @@ -116,16 +116,14 @@ TEST_F(CoreAPIsStandardTest, MaterializationSideEffctsOnlyBasic) { // don't return until they're emitted, and that they don't appear in query // results. - std::unique_ptr FooR; + Optional FooR; Optional Result; cantFail(JD.define(std::make_unique( SymbolFlagsMap( {{Foo, JITSymbolFlags::Exported | JITSymbolFlags::MaterializationSideEffectsOnly}}), - [&](std::unique_ptr R) { - FooR = std::move(R); - }))); + [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }))); ES.lookup( LookupKind::Static, makeJITDylibSearchOrder(&JD), @@ -157,9 +155,7 @@ TEST_F(CoreAPIsStandardTest, MaterializationSideEffectsOnlyFailuresPersist) { SymbolFlagsMap( {{Foo, JITSymbolFlags::Exported | JITSymbolFlags::MaterializationSideEffectsOnly}}), - [&](std::unique_ptr R) { - R->failMaterialization(); - }))); + [&](MaterializationResponsibility R) { R.failMaterialization(); }))); EXPECT_THAT_EXPECTED( ES.lookup(makeJITDylibSearchOrder(&JD), SymbolLookupSet({Foo})), @@ -186,10 +182,10 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) { bool BarMaterializerDestructed = false; cantFail(JD.define(std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [this](std::unique_ptr R) { + [this](MaterializationResponsibility R) { ADD_FAILURE() << "Unexpected materialization of \"Bar\""; - cantFail(R->notifyResolved({{Bar, BarSym}})); - cantFail(R->notifyEmitted()); + cantFail(R.notifyResolved({{Bar, BarSym}})); + cantFail(R.notifyEmitted()); }, nullptr, [&](const JITDylib &JD, const SymbolStringPtr &Name) { @@ -201,12 +197,10 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) { // Baz will be in the materializing state initially, then // materialized for the final removal attempt. - std::unique_ptr BazR; + Optional BazR; cantFail(JD.define(std::make_unique( SymbolFlagsMap({{Baz, BazSym.getFlags()}}), - [&](std::unique_ptr R) { - BazR = std::move(R); - }, + [&](MaterializationResponsibility R) { BazR.emplace(std::move(R)); }, nullptr, [](const JITDylib &JD, const SymbolStringPtr &Name) { ADD_FAILURE() << "\"Baz\" discarded unexpectedly"; @@ -303,7 +297,7 @@ TEST_F(CoreAPIsStandardTest, LookupFlagsTest) { JITSymbolFlags::Exported | JITSymbolFlags::Weak)); auto MU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [](std::unique_ptr R) { + [](MaterializationResponsibility R) { llvm_unreachable("Symbol materialized on flags lookup"); }); @@ -406,10 +400,10 @@ TEST_F(CoreAPIsStandardTest, TestThatReExportsDontUnnecessarilyMaterialize) { bool BarMaterialized = false; auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](std::unique_ptr R) { + [&](MaterializationResponsibility R) { BarMaterialized = true; - cantFail(R->notifyResolved({{Bar, BarSym}})); - cantFail(R->notifyEmitted()); + cantFail(R.notifyResolved({{Bar, BarSym}})); + cantFail(R.notifyEmitted()); }); cantFail(JD.define(BarMU)); @@ -450,12 +444,10 @@ TEST_F(CoreAPIsStandardTest, TestReexportsGenerator) { } TEST_F(CoreAPIsStandardTest, TestTrivialCircularDependency) { - std::unique_ptr FooR; + Optional FooR; auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](std::unique_ptr R) { - FooR = std::move(R); - }); + [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); cantFail(JD.define(FooMU)); @@ -484,29 +476,26 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) { // does not prevent any symbol from becoming 'ready' once all symbols are // emitted. - std::unique_ptr FooR; - std::unique_ptr BarR; - std::unique_ptr BazR; + // Create three MaterializationResponsibility objects: one for each of Foo, + // Bar and Baz. These are optional because MaterializationResponsibility + // does not have a default constructor). + Optional FooR; + Optional BarR; + Optional BazR; // Create a MaterializationUnit for each symbol that moves the // MaterializationResponsibility into one of the locals above. auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](std::unique_ptr R) { - FooR = std::move(R); - }); + [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](std::unique_ptr R) { - BarR = std::move(R); - }); + [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); }); auto BazMU = std::make_unique( SymbolFlagsMap({{Baz, BazSym.getFlags()}}), - [&](std::unique_ptr R) { - BazR = std::move(R); - }); + [&](MaterializationResponsibility R) { BazR.emplace(std::move(R)); }); // Define the symbols. cantFail(JD.define(FooMU)); @@ -633,22 +622,18 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) { } TEST_F(CoreAPIsStandardTest, FailureInDependency) { - std::unique_ptr FooR; - std::unique_ptr BarR; + Optional FooR; + Optional BarR; // Create a MaterializationUnit for each symbol that moves the // MaterializationResponsibility into one of the locals above. auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](std::unique_ptr R) { - FooR = std::move(R); - }); + [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](std::unique_ptr R) { - BarR = std::move(R); - }); + [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); }); // Define the symbols. cantFail(JD.define(FooMU)); @@ -702,22 +687,18 @@ TEST_F(CoreAPIsStandardTest, FailureInDependency) { } TEST_F(CoreAPIsStandardTest, FailureInCircularDependency) { - std::unique_ptr FooR; - std::unique_ptr BarR; + Optional FooR; + Optional BarR; // Create a MaterializationUnit for each symbol that moves the // MaterializationResponsibility into one of the locals above. auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](std::unique_ptr R) { - FooR = std::move(R); - }); + [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](std::unique_ptr R) { - BarR = std::move(R); - }); + [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); }); // Define the symbols. cantFail(JD.define(FooMU)); @@ -772,22 +753,18 @@ TEST_F(CoreAPIsStandardTest, FailureInCircularDependency) { } TEST_F(CoreAPIsStandardTest, AddDependencyOnFailedSymbol) { - std::unique_ptr FooR; - std::unique_ptr BarR; + Optional FooR; + Optional BarR; // Create a MaterializationUnit for each symbol that moves the // MaterializationResponsibility into one of the locals above. auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](std::unique_ptr R) { - FooR = std::move(R); - }); + [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](std::unique_ptr R) { - BarR = std::move(R); - }); + [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); }); // Define the symbols. cantFail(JD.define(FooMU)); @@ -842,22 +819,18 @@ TEST_F(CoreAPIsStandardTest, AddDependencyOnFailedSymbol) { } TEST_F(CoreAPIsStandardTest, FailAfterMaterialization) { - std::unique_ptr FooR; - std::unique_ptr BarR; + Optional FooR; + Optional BarR; // Create a MaterializationUnit for each symbol that moves the // MaterializationResponsibility into one of the locals above. auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](std::unique_ptr R) { - FooR = std::move(R); - }); + [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](std::unique_ptr R) { - BarR = std::move(R); - }); + [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); }); // Define the symbols. cantFail(JD.define(FooMU)); @@ -909,9 +882,9 @@ TEST_F(CoreAPIsStandardTest, FailMaterializerWithUnqueriedSymbols) { auto MU = std::make_unique( SymbolFlagsMap( {{Foo, JITSymbolFlags::Exported}, {Bar, JITSymbolFlags::Exported}}), - [&](std::unique_ptr R) { + [&](MaterializationResponsibility R) { MaterializerRun = true; - R->failMaterialization(); + R.failMaterialization(); }); cantFail(JD.define(std::move(MU))); @@ -938,7 +911,7 @@ TEST_F(CoreAPIsStandardTest, DropMaterializerWhenEmpty) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, WeakExported}, {Bar, WeakExported}}), - [](std::unique_ptr R) { + [](MaterializationResponsibility R) { llvm_unreachable("Unexpected call to materialize"); }, nullptr, @@ -970,10 +943,10 @@ TEST_F(CoreAPIsStandardTest, AddAndMaterializeLazySymbol) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}, {Bar, WeakExported}}), - [&](std::unique_ptr R) { + [&](MaterializationResponsibility R) { assert(BarDiscarded && "Bar should have been discarded by this point"); - cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}}))); - cantFail(R->notifyEmitted()); + cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}}))); + cantFail(R.notifyEmitted()); FooMaterialized = true; }, nullptr, @@ -1012,18 +985,18 @@ TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) { bool BarMaterialized = false; auto MU1 = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}), - [&](std::unique_ptr R) { - cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); - cantFail(R->notifyEmitted()); + [&](MaterializationResponsibility R) { + cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); + cantFail(R.notifyEmitted()); BarMaterialized = true; }); bool DuplicateBarDiscarded = false; auto MU2 = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](std::unique_ptr R) { + [&](MaterializationResponsibility R) { ADD_FAILURE() << "Attempt to materialize Bar from the wrong unit"; - R->failMaterialization(); + R.failMaterialization(); }, nullptr, [&](const JITDylib &JD, SymbolStringPtr Name) { @@ -1053,21 +1026,20 @@ TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) { TEST_F(CoreAPIsStandardTest, DefineMaterializingSymbol) { bool ExpectNoMoreMaterialization = false; - ES.setDispatchMaterialization( - [&](std::unique_ptr MU, - std::unique_ptr MR) { - if (ExpectNoMoreMaterialization) - ADD_FAILURE() << "Unexpected materialization"; - MU->materialize(std::move(MR)); - }); + ES.setDispatchMaterialization([&](std::unique_ptr MU, + MaterializationResponsibility MR) { + if (ExpectNoMoreMaterialization) + ADD_FAILURE() << "Unexpected materialization"; + MU->materialize(std::move(MR)); + }); auto MU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](std::unique_ptr R) { + [&](MaterializationResponsibility R) { cantFail( - R->defineMaterializing(SymbolFlagsMap({{Bar, BarSym.getFlags()}}))); - cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); - cantFail(R->notifyEmitted()); + R.defineMaterializing(SymbolFlagsMap({{Bar, BarSym.getFlags()}}))); + cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); + cantFail(R.notifyEmitted()); }); cantFail(JD.define(MU)); @@ -1121,8 +1093,8 @@ TEST_F(CoreAPIsStandardTest, FailResolution) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, JITSymbolFlags::Exported | JITSymbolFlags::Weak}, {Bar, JITSymbolFlags::Exported | JITSymbolFlags::Weak}}), - [&](std::unique_ptr R) { - R->failMaterialization(); + [&](MaterializationResponsibility R) { + R.failMaterialization(); }); cantFail(JD.define(MU)); @@ -1157,23 +1129,23 @@ TEST_F(CoreAPIsStandardTest, FailEmissionAfterResolution) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}), - [&](std::unique_ptr R) { - cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); + [&](MaterializationResponsibility R) { + cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); ES.lookup( LookupKind::Static, makeJITDylibSearchOrder(&JD), SymbolLookupSet({Baz}), SymbolState::Resolved, - [&](Expected Result) { + [&R](Expected Result) { // Called when "baz" is resolved. We don't actually depend // on or care about baz, but use it to trigger failure of // this materialization before Baz has been finalized in // order to test that error propagation is correct in this // scenario. cantFail(std::move(Result)); - R->failMaterialization(); + R.failMaterialization(); }, [&](const SymbolDependenceMap &Deps) { - R->addDependenciesForAll(Deps); + R.addDependenciesForAll(Deps); }); }); @@ -1193,9 +1165,7 @@ TEST_F(CoreAPIsStandardTest, FailAfterPartialResolution) { // Fail materialization of bar. auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](std::unique_ptr R) { - R->failMaterialization(); - }); + [&](MaterializationResponsibility R) { R.failMaterialization(); }); cantFail(JD.define(std::move(BarMU))); @@ -1215,9 +1185,9 @@ TEST_F(CoreAPIsStandardTest, FailAfterPartialResolution) { TEST_F(CoreAPIsStandardTest, TestLookupWithUnthreadedMaterialization) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}), - [&](std::unique_ptr R) { - cantFail(R->notifyResolved({{Foo, FooSym}})); - cantFail(R->notifyEmitted()); + [&](MaterializationResponsibility R) { + cantFail(R.notifyResolved({{Foo, FooSym}})); + cantFail(R.notifyEmitted()); }); cantFail(JD.define(MU)); @@ -1234,14 +1204,15 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) { #if LLVM_ENABLE_THREADS std::thread MaterializationThread; - ES.setDispatchMaterialization( - [&](std::unique_ptr MU, - std::unique_ptr MR) { - MaterializationThread = - std::thread([MU = std::move(MU), MR = std::move(MR)]() mutable { - MU->materialize(std::move(MR)); - }); - }); + ES.setDispatchMaterialization([&](std::unique_ptr MU, + MaterializationResponsibility MR) { + auto SharedMR = + std::make_shared(std::move(MR)); + MaterializationThread = + std::thread([MU = std::move(MU), MR = std::move(SharedMR)] { + MU->materialize(std::move(*MR)); + }); + }); cantFail(JD.define(absoluteSymbols({{Foo, FooSym}}))); @@ -1267,23 +1238,23 @@ TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}), - [&](std::unique_ptr R) { - auto Requested = R->getRequestedSymbols(); + [&](MaterializationResponsibility R) { + auto Requested = R.getRequestedSymbols(); EXPECT_EQ(Requested.size(), 1U) << "Expected one symbol requested"; EXPECT_EQ(*Requested.begin(), Foo) << "Expected \"Foo\" requested"; auto NewMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](std::unique_ptr R2) { - cantFail(R2->notifyResolved(SymbolMap({{Bar, BarSym}}))); - cantFail(R2->notifyEmitted()); + [&](MaterializationResponsibility R2) { + cantFail(R2.notifyResolved(SymbolMap({{Bar, BarSym}}))); + cantFail(R2.notifyEmitted()); BarMaterialized = true; }); - R->replace(std::move(NewMU)); + R.replace(std::move(NewMU)); - cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}}))); - cantFail(R->notifyEmitted()); + cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}}))); + cantFail(R.notifyEmitted()); FooMaterialized = true; }); @@ -1309,13 +1280,13 @@ TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) { TEST_F(CoreAPIsStandardTest, TestMaterializationResponsibilityDelegation) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}), - [&](std::unique_ptr R) { - auto R2 = R->delegate({Bar}); + [&](MaterializationResponsibility R) { + auto R2 = R.delegate({Bar}); - cantFail(R->notifyResolved({{Foo, FooSym}})); - cantFail(R->notifyEmitted()); - cantFail(R2->notifyResolved({{Bar, BarSym}})); - cantFail(R2->notifyEmitted()); + cantFail(R.notifyResolved({{Foo, FooSym}})); + cantFail(R.notifyEmitted()); + cantFail(R2.notifyResolved({{Bar, BarSym}})); + cantFail(R2.notifyEmitted()); }); cantFail(JD.define(MU)); @@ -1338,11 +1309,12 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) { JITSymbolFlags WeakExported = JITSymbolFlags::Exported; WeakExported &= JITSymbolFlags::Weak; - std::unique_ptr FooR; + std::unique_ptr FooResponsibility; auto MU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](std::unique_ptr R) { - FooR = std::move(R); + [&](MaterializationResponsibility R) { + FooResponsibility = + std::make_unique(std::move(R)); }); cantFail(JD.define(MU)); @@ -1356,7 +1328,7 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) { auto MU2 = std::make_unique( SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}), - [](std::unique_ptr R) { + [](MaterializationResponsibility R) { llvm_unreachable("This unit should never be materialized"); }); @@ -1367,8 +1339,8 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) { consumeError(std::move(Err)); // No dependencies registered, can't fail: - cantFail(FooR->notifyResolved(SymbolMap({{Foo, FooSym}}))); - cantFail(FooR->notifyEmitted()); + cantFail(FooResponsibility->notifyResolved(SymbolMap({{Foo, FooSym}}))); + cantFail(FooResponsibility->notifyEmitted()); } static bool linkOrdersEqual(const std::vector> &LHS, diff --git a/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp index 81ff3e7a87b30..50e7b60a2df4e 100644 --- a/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp @@ -39,15 +39,15 @@ TEST_F(LazyReexportsTest, BasicLocalCallThroughManagerOperation) { cantFail(JD.define(std::make_unique( SymbolFlagsMap({{DummyTarget, JITSymbolFlags::Exported}}), - [&](std::unique_ptr R) { + [&](MaterializationResponsibility R) { DummyTargetMaterialized = true; // No dependencies registered, can't fail. - cantFail(R->notifyResolved( + cantFail(R.notifyResolved( {{DummyTarget, JITEvaluatedSymbol(static_cast( reinterpret_cast(&dummyTarget)), JITSymbolFlags::Exported)}})); - cantFail(R->notifyEmitted()); + cantFail(R.notifyEmitted()); }))); unsigned NotifyResolvedCount = 0; diff --git a/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h index afbc4a9ffaa5c..b25851d8f796c 100644 --- a/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h +++ b/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h @@ -86,7 +86,7 @@ class OrcNativeTarget { class SimpleMaterializationUnit : public orc::MaterializationUnit { public: using MaterializeFunction = - std::function)>; + std::function; using DiscardFunction = std::function; using DestructorFunction = std::function; @@ -108,8 +108,7 @@ class SimpleMaterializationUnit : public orc::MaterializationUnit { StringRef getName() const override { return ""; } - void - materialize(std::unique_ptr R) override { + void materialize(orc::MaterializationResponsibility R) override { Materialize(std::move(R)); } From b7ca38aac39c9ffb087b489eb70faf4117b70dc3 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Fri, 11 Sep 2020 09:23:14 -0700 Subject: [PATCH 177/234] Re-apply "[ORC] Make MaterializationResponsibility immovable..." with fixes. Re-applies c74900ca672 with fixes for the ThinLtoJIT example. --- .../SpeculativeJIT/SpeculativeJIT.cpp | 15 +- .../ThinLtoInstrumentationLayer.cpp | 4 +- .../ThinLtoJIT/ThinLtoInstrumentationLayer.h | 3 +- llvm/examples/ThinLtoJIT/ThinLtoJIT.cpp | 11 +- .../Orc/CompileOnDemandLayer.h | 6 +- llvm/include/llvm/ExecutionEngine/Orc/Core.h | 37 +-- .../llvm/ExecutionEngine/Orc/IRCompileLayer.h | 3 +- .../ExecutionEngine/Orc/IRTransformLayer.h | 3 +- llvm/include/llvm/ExecutionEngine/Orc/Layer.h | 11 +- .../llvm/ExecutionEngine/Orc/LazyReexports.h | 2 +- .../ExecutionEngine/Orc/ObjectLinkingLayer.h | 2 +- .../Orc/ObjectTransformLayer.h | 2 +- .../Orc/RTDyldObjectLinkingLayer.h | 2 +- .../llvm/ExecutionEngine/Orc/Speculation.h | 3 +- .../Orc/CompileOnDemandLayer.cpp | 42 +-- llvm/lib/ExecutionEngine/Orc/Core.cpp | 50 ++-- .../ExecutionEngine/Orc/IRCompileLayer.cpp | 6 +- .../ExecutionEngine/Orc/IRTransformLayer.cpp | 6 +- .../ExecutionEngine/Orc/IndirectionUtils.cpp | 6 +- llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 20 +- llvm/lib/ExecutionEngine/Orc/Layer.cpp | 8 +- .../lib/ExecutionEngine/Orc/LazyReexports.cpp | 16 +- .../Orc/ObjectLinkingLayer.cpp | 59 ++--- .../Orc/ObjectTransformLayer.cpp | 7 +- .../Orc/RTDyldObjectLinkingLayer.cpp | 25 +- llvm/lib/ExecutionEngine/Orc/Speculation.cpp | 4 +- .../ExecutionEngine/Orc/CoreAPIsTest.cpp | 242 ++++++++++-------- .../Orc/LazyCallThroughAndReexportsTest.cpp | 6 +- .../ExecutionEngine/Orc/OrcTestCommon.h | 5 +- 29 files changed, 323 insertions(+), 283 deletions(-) diff --git a/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp b/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp index 4de4897053c1b..24cf0847558f9 100644 --- a/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp +++ b/llvm/examples/SpeculativeJIT/SpeculativeJIT.cpp @@ -113,14 +113,13 @@ class SpeculativeJIT { this->CODLayer.setImplMap(&Imps); this->ES->setDispatchMaterialization( [this](std::unique_ptr MU, - MaterializationResponsibility MR) { - // FIXME: Switch to move capture once we have C++14. - auto SharedMU = std::shared_ptr(std::move(MU)); - auto SharedMR = - std::make_shared(std::move(MR)); - CompileThreads.async([SharedMU, SharedMR]() { - SharedMU->materialize(std::move(*SharedMR)); - }); + std::unique_ptr MR) { + CompileThreads.async( + [UnownedMU = MU.release(), UnownedMR = MR.release()]() { + std::unique_ptr MU(UnownedMU); + std::unique_ptr MR(UnownedMR); + MU->materialize(std::move(MR)); + }); }); ExitOnErr(S.addSpeculationRuntime(MainJD, Mangle)); LocalCXXRuntimeOverrides CXXRuntimeoverrides; diff --git a/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.cpp b/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.cpp index 345bfd8dd8705..df844bf19b9cc 100644 --- a/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.cpp +++ b/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.cpp @@ -120,8 +120,8 @@ void ThinLtoInstrumentationLayer::nudgeIntoDiscovery( LLVM_DEBUG(dbgs() << "Nudged " << Count << " new functions into discovery\n"); } -void ThinLtoInstrumentationLayer::emit(MaterializationResponsibility R, - ThreadSafeModule TSM) { +void ThinLtoInstrumentationLayer::emit( + std::unique_ptr R, ThreadSafeModule TSM) { TSM.withModuleDo([this](Module &M) { std::vector FunctionsToInstrument; diff --git a/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.h b/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.h index cd87207894745..25006b40607fe 100644 --- a/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.h +++ b/llvm/examples/ThinLtoJIT/ThinLtoInstrumentationLayer.h @@ -34,7 +34,8 @@ class ThinLtoInstrumentationLayer : public IRLayer { ~ThinLtoInstrumentationLayer() override; - void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override; + void emit(std::unique_ptr R, + ThreadSafeModule TSM) override; unsigned reserveDiscoveryFlags(unsigned Count); void registerDiscoveryFlagOwners(std::vector Guids, diff --git a/llvm/examples/ThinLtoJIT/ThinLtoJIT.cpp b/llvm/examples/ThinLtoJIT/ThinLtoJIT.cpp index f5c2b0696f55c..e668be7d11b7e 100644 --- a/llvm/examples/ThinLtoJIT/ThinLtoJIT.cpp +++ b/llvm/examples/ThinLtoJIT/ThinLtoJIT.cpp @@ -267,19 +267,18 @@ void ThinLtoJIT::setupLayers(JITTargetMachineBuilder JTMB, llvm::hardware_concurrency(NumCompileThreads)); ES.setDispatchMaterialization( [this](std::unique_ptr MU, - MaterializationResponsibility MR) { + std::unique_ptr MR) { if (IsTrivialModule(MU.get())) { // This should be quick and we may save a few session locks. MU->materialize(std::move(MR)); } else { // FIXME: Drop the std::shared_ptr workaround once ThreadPool::async() // accepts llvm::unique_function to define jobs. - auto SharedMU = std::shared_ptr(std::move(MU)); - auto SharedMR = - std::make_shared(std::move(MR)); CompileThreads->async( - [MU = std::move(SharedMU), MR = std::move(SharedMR)]() { - MU->materialize(std::move(*MR)); + [UnownedMU = MU.release(), UnownedMR = MR.release()]() { + std::unique_ptr MU(UnownedMU); + std::unique_ptr MR(UnownedMR); + MU->materialize(std::move(MR)); }); } }); diff --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 9ecc0464dec1b..3a2f8b54ad22b 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -96,7 +96,8 @@ class CompileOnDemandLayer : public IRLayer { /// Emits the given module. This should not be called by clients: it will be /// called by the JIT when a definition added via the add method is requested. - void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override; + void emit(std::unique_ptr R, + ThreadSafeModule TSM) override; private: struct PerDylibResources { @@ -120,7 +121,8 @@ class CompileOnDemandLayer : public IRLayer { void expandPartition(GlobalValueSet &Partition); - void emitPartition(MaterializationResponsibility R, ThreadSafeModule TSM, + void emitPartition(std::unique_ptr R, + ThreadSafeModule TSM, IRMaterializationUnit::SymbolNameToDefinitionMap Defs); mutable std::mutex CODLayerMutex; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Core.h b/llvm/include/llvm/ExecutionEngine/Orc/Core.h index 6951df3f2d3f2..70bd983c40ce0 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Core.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Core.h @@ -410,7 +410,7 @@ class UnexpectedSymbolDefinitions : public ErrorInfo + delegate(const SymbolNameSet &Symbols, VModuleKey NewKey = VModuleKey()); void addDependencies(const SymbolStringPtr &Name, const SymbolDependenceMap &Dependencies); @@ -577,7 +577,8 @@ class MaterializationUnit { /// Implementations of this method should materialize all symbols /// in the materialzation unit, except for those that have been /// previously discarded. - virtual void materialize(MaterializationResponsibility R) = 0; + virtual void + materialize(std::unique_ptr R) = 0; /// Called by JITDylibs to notify MaterializationUnits that the given symbol /// has been overridden. @@ -594,10 +595,11 @@ class MaterializationUnit { private: virtual void anchor(); - MaterializationResponsibility + std::unique_ptr createMaterializationResponsibility(std::shared_ptr JD) { - return MaterializationResponsibility(std::move(JD), std::move(SymbolFlags), - std::move(InitSymbol), K); + return std::unique_ptr( + new MaterializationResponsibility(std::move(JD), std::move(SymbolFlags), + std::move(InitSymbol), K)); } /// Implementations of this method should discard the given symbol @@ -621,7 +623,7 @@ class AbsoluteSymbolsMaterializationUnit : public MaterializationUnit { StringRef getName() const override; private: - void materialize(MaterializationResponsibility R) override; + void materialize(std::unique_ptr R) override; void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; static SymbolFlagsMap extractFlags(const SymbolMap &Symbols); @@ -663,7 +665,7 @@ class ReExportsMaterializationUnit : public MaterializationUnit { StringRef getName() const override; private: - void materialize(MaterializationResponsibility R) override; + void materialize(std::unique_ptr R) override; void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases); @@ -1116,7 +1118,7 @@ class ExecutionSession { /// For dispatching MaterializationUnit::materialize calls. using DispatchMaterializationFunction = std::function MU, - MaterializationResponsibility MR)>; + std::unique_ptr MR)>; /// Construct an ExecutionSession. /// @@ -1268,10 +1270,11 @@ class ExecutionSession { SymbolState RequiredState = SymbolState::Ready); /// Materialize the given unit. - void dispatchMaterialization(std::unique_ptr MU, - MaterializationResponsibility MR) { + void + dispatchMaterialization(std::unique_ptr MU, + std::unique_ptr MR) { assert(MU && "MU must be non-null"); - DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR.getTargetJITDylib(), *MU)); + DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR->getTargetJITDylib(), *MU)); DispatchMaterialization(std::move(MU), std::move(MR)); } @@ -1283,9 +1286,9 @@ class ExecutionSession { logAllUnhandledErrors(std::move(Err), errs(), "JIT session error: "); } - static void - materializeOnCurrentThread(std::unique_ptr MU, - MaterializationResponsibility MR) { + static void materializeOnCurrentThread( + std::unique_ptr MU, + std::unique_ptr MR) { MU->materialize(std::move(MR)); } @@ -1309,7 +1312,7 @@ class ExecutionSession { // with callbacks from asynchronous queries. mutable std::recursive_mutex OutstandingMUsMutex; std::vector, - MaterializationResponsibility>> + std::unique_ptr>> OutstandingMUs; }; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h index eb74d283f0435..2c53e2f66e851 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h @@ -55,7 +55,8 @@ class IRCompileLayer : public IRLayer { void setNotifyCompiled(NotifyCompiledFunction NotifyCompiled); - void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override; + void emit(std::unique_ptr R, + ThreadSafeModule TSM) override; private: mutable std::mutex IRLayerMutex; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h index 296d74ae6b865..ee4ee3437fa6d 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h @@ -37,7 +37,8 @@ class IRTransformLayer : public IRLayer { this->Transform = std::move(Transform); } - void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override; + void emit(std::unique_ptr R, + ThreadSafeModule TSM) override; static ThreadSafeModule identityTransform(ThreadSafeModule TSM, MaterializationResponsibility &R) { diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Layer.h b/llvm/include/llvm/ExecutionEngine/Orc/Layer.h index e843d0f562455..c8a41199760da 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Layer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Layer.h @@ -100,7 +100,8 @@ class IRLayer { VModuleKey K = VModuleKey()); /// Emit should materialize the given IR. - virtual void emit(MaterializationResponsibility R, ThreadSafeModule TSM) = 0; + virtual void emit(std::unique_ptr R, + ThreadSafeModule TSM) = 0; private: bool CloneToNewContextOnEmit = false; @@ -117,8 +118,7 @@ class BasicIRLayerMaterializationUnit : public IRMaterializationUnit { ThreadSafeModule TSM, VModuleKey K); private: - - void materialize(MaterializationResponsibility R) override; + void materialize(std::unique_ptr R) override; IRLayer &L; VModuleKey K; @@ -139,7 +139,7 @@ class ObjectLayer { VModuleKey K = VModuleKey()); /// Emit should materialize the given IR. - virtual void emit(MaterializationResponsibility R, + virtual void emit(std::unique_ptr R, std::unique_ptr O) = 0; private: @@ -162,8 +162,7 @@ class BasicObjectLayerMaterializationUnit : public MaterializationUnit { StringRef getName() const override; private: - - void materialize(MaterializationResponsibility R) override; + void materialize(std::unique_ptr R) override; void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; ObjectLayer &L; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h b/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h index 9206e40fffb1c..63e3a80d87d86 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h @@ -149,7 +149,7 @@ class LazyReexportsMaterializationUnit : public MaterializationUnit { StringRef getName() const override; private: - void materialize(MaterializationResponsibility R) override; + void materialize(std::unique_ptr R) override; void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; static SymbolFlagsMap extractFlags(const SymbolAliasMap &Aliases); diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h index cb8ee130ab614..cbcf3928be3df 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h @@ -119,7 +119,7 @@ class ObjectLinkingLayer : public ObjectLayer { } /// Emit the object. - void emit(MaterializationResponsibility R, + void emit(std::unique_ptr R, std::unique_ptr O) override; /// Instructs this ObjectLinkingLayer instance to override the symbol flags diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h index bf989cc8677cf..c77649f19fc74 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h @@ -31,7 +31,7 @@ class ObjectTransformLayer : public ObjectLayer { ObjectTransformLayer(ExecutionSession &ES, ObjectLayer &BaseLayer, TransformFunction Transform = TransformFunction()); - void emit(MaterializationResponsibility R, + void emit(std::unique_ptr R, std::unique_ptr O) override; void setTransform(TransformFunction Transform) { diff --git a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h index 9ada0871cf0cb..9cd3c57a19c6a 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h @@ -58,7 +58,7 @@ class RTDyldObjectLinkingLayer : public ObjectLayer { ~RTDyldObjectLinkingLayer(); /// Emit the object. - void emit(MaterializationResponsibility R, + void emit(std::unique_ptr R, std::unique_ptr O) override; /// Set the NotifyLoaded callback. diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h b/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h index 10f78c8bc6beb..a138f60a77564 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h @@ -181,7 +181,8 @@ class IRSpeculationLayer : public IRLayer { : IRLayer(ES, BaseLayer.getManglingOptions()), NextLayer(BaseLayer), S(Spec), Mangle(Mangle), QueryAnalysis(Interpreter) {} - void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override; + void emit(std::unique_ptr R, + ThreadSafeModule TSM) override; private: TargetAndLikelies diff --git a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp index 9e38dc36faae7..dfb0d06bdba3d 100644 --- a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp @@ -88,7 +88,7 @@ class PartitioningIRMaterializationUnit : public IRMaterializationUnit { Parent(Parent) {} private: - void materialize(MaterializationResponsibility R) override { + void materialize(std::unique_ptr R) override { Parent.emitPartition(std::move(R), std::move(TSM), std::move(SymbolToDefinition)); } @@ -128,15 +128,15 @@ void CompileOnDemandLayer::setPartitionFunction(PartitionFunction Partition) { void CompileOnDemandLayer::setImplMap(ImplSymbolMap *Imp) { this->AliaseeImpls = Imp; } -void CompileOnDemandLayer::emit(MaterializationResponsibility R, - ThreadSafeModule TSM) { +void CompileOnDemandLayer::emit( + std::unique_ptr R, ThreadSafeModule TSM) { assert(TSM && "Null module"); auto &ES = getExecutionSession(); // Sort the callables and non-callables, build re-exports and lodge the // actual module with the implementation dylib. - auto &PDR = getPerDylibResources(R.getTargetJITDylib()); + auto &PDR = getPerDylibResources(R->getTargetJITDylib()); SymbolAliasMap NonCallables; SymbolAliasMap Callables; @@ -145,7 +145,7 @@ void CompileOnDemandLayer::emit(MaterializationResponsibility R, cleanUpModule(M); }); - for (auto &KV : R.getSymbols()) { + for (auto &KV : R->getSymbols()) { auto &Name = KV.first; auto &Flags = KV.second; if (Flags.isCallable()) @@ -158,19 +158,19 @@ void CompileOnDemandLayer::emit(MaterializationResponsibility R, // implementation dylib. if (auto Err = PDR.getImplDylib().define( std::make_unique( - ES, *getManglingOptions(), std::move(TSM), R.getVModuleKey(), + ES, *getManglingOptions(), std::move(TSM), R->getVModuleKey(), *this))) { ES.reportError(std::move(Err)); - R.failMaterialization(); + R->failMaterialization(); return; } if (!NonCallables.empty()) - R.replace(reexports(PDR.getImplDylib(), std::move(NonCallables), - JITDylibLookupFlags::MatchAllSymbols)); + R->replace(reexports(PDR.getImplDylib(), std::move(NonCallables), + JITDylibLookupFlags::MatchAllSymbols)); if (!Callables.empty()) - R.replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(), - std::move(Callables), AliaseeImpls)); + R->replace(lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(), + std::move(Callables), AliaseeImpls)); } CompileOnDemandLayer::PerDylibResources & @@ -247,7 +247,7 @@ void CompileOnDemandLayer::expandPartition(GlobalValueSet &Partition) { } void CompileOnDemandLayer::emitPartition( - MaterializationResponsibility R, ThreadSafeModule TSM, + std::unique_ptr R, ThreadSafeModule TSM, IRMaterializationUnit::SymbolNameToDefinitionMap Defs) { // FIXME: Need a 'notify lazy-extracting/emitting' callback to tie the @@ -257,8 +257,8 @@ void CompileOnDemandLayer::emitPartition( auto &ES = getExecutionSession(); GlobalValueSet RequestedGVs; - for (auto &Name : R.getRequestedSymbols()) { - if (Name == R.getInitializerSymbol()) + for (auto &Name : R->getRequestedSymbols()) { + if (Name == R->getInitializerSymbol()) TSM.withModuleDo([&](Module &M) { for (auto &GV : getStaticInitGVs(M)) RequestedGVs.insert(&GV); @@ -285,9 +285,9 @@ void CompileOnDemandLayer::emitPartition( // If the partition is empty, return the whole module to the symbol table. if (GVsToExtract->empty()) { - R.replace(std::make_unique( - std::move(TSM), R.getVModuleKey(), R.getSymbols(), - R.getInitializerSymbol(), std::move(Defs), *this)); + R->replace(std::make_unique( + std::move(TSM), R->getVModuleKey(), R->getSymbols(), + R->getInitializerSymbol(), std::move(Defs), *this)); return; } @@ -308,7 +308,7 @@ void CompileOnDemandLayer::emitPartition( IRSymbolMapper::add(ES, *getManglingOptions(), PromotedGlobals, SymbolFlags); - if (auto Err = R.defineMaterializing(SymbolFlags)) + if (auto Err = R->defineMaterializing(SymbolFlags)) return std::move(Err); } @@ -348,12 +348,12 @@ void CompileOnDemandLayer::emitPartition( if (!ExtractedTSM) { ES.reportError(ExtractedTSM.takeError()); - R.failMaterialization(); + R->failMaterialization(); return; } - R.replace(std::make_unique( - ES, *getManglingOptions(), std::move(TSM), R.getVModuleKey(), *this)); + R->replace(std::make_unique( + ES, *getManglingOptions(), std::move(TSM), R->getVModuleKey(), *this)); BaseLayer.emit(std::move(R), std::move(*ExtractedTSM)); } diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp index 18eced68f07bc..243bac79c012f 100644 --- a/llvm/lib/ExecutionEngine/Orc/Core.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp @@ -279,7 +279,7 @@ void MaterializationResponsibility::replace( JD->replace(std::move(MU)); } -MaterializationResponsibility +std::unique_ptr MaterializationResponsibility::delegate(const SymbolNameSet &Symbols, VModuleKey NewKey) { @@ -302,9 +302,10 @@ MaterializationResponsibility::delegate(const SymbolNameSet &Symbols, SymbolFlags.erase(I); } - return MaterializationResponsibility(JD, std::move(DelegatedFlags), - std::move(DelegatedInitSymbol), - std::move(NewKey)); + return std::unique_ptr( + new MaterializationResponsibility(JD, std::move(DelegatedFlags), + std::move(DelegatedInitSymbol), + std::move(NewKey))); } void MaterializationResponsibility::addDependencies( @@ -338,10 +339,10 @@ StringRef AbsoluteSymbolsMaterializationUnit::getName() const { } void AbsoluteSymbolsMaterializationUnit::materialize( - MaterializationResponsibility R) { + std::unique_ptr R) { // No dependencies, so these calls can't fail. - cantFail(R.notifyResolved(Symbols)); - cantFail(R.notifyEmitted()); + cantFail(R->notifyResolved(Symbols)); + cantFail(R->notifyEmitted()); } void AbsoluteSymbolsMaterializationUnit::discard(const JITDylib &JD, @@ -370,16 +371,16 @@ StringRef ReExportsMaterializationUnit::getName() const { } void ReExportsMaterializationUnit::materialize( - MaterializationResponsibility R) { + std::unique_ptr R) { - auto &ES = R.getTargetJITDylib().getExecutionSession(); - JITDylib &TgtJD = R.getTargetJITDylib(); + auto &ES = R->getTargetJITDylib().getExecutionSession(); + JITDylib &TgtJD = R->getTargetJITDylib(); JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD; // Find the set of requested aliases and aliasees. Return any unrequested // aliases back to the JITDylib so as to not prematurely materialize any // aliasees. - auto RequestedSymbols = R.getRequestedSymbols(); + auto RequestedSymbols = R->getRequestedSymbols(); SymbolAliasMap RequestedAliases; for (auto &Name : RequestedSymbols) { @@ -399,18 +400,19 @@ void ReExportsMaterializationUnit::materialize( if (!Aliases.empty()) { if (SourceJD) - R.replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags)); + R->replace(reexports(*SourceJD, std::move(Aliases), SourceJDLookupFlags)); else - R.replace(symbolAliases(std::move(Aliases))); + R->replace(symbolAliases(std::move(Aliases))); } // The OnResolveInfo struct will hold the aliases and responsibilty for each // query in the list. struct OnResolveInfo { - OnResolveInfo(MaterializationResponsibility R, SymbolAliasMap Aliases) + OnResolveInfo(std::unique_ptr R, + SymbolAliasMap Aliases) : R(std::move(R)), Aliases(std::move(Aliases)) {} - MaterializationResponsibility R; + std::unique_ptr R; SymbolAliasMap Aliases; }; @@ -451,7 +453,7 @@ void ReExportsMaterializationUnit::materialize( assert(!QuerySymbols.empty() && "Alias cycle detected!"); auto QueryInfo = std::make_shared( - R.delegate(ResponsibilitySymbols), std::move(QueryAliases)); + R->delegate(ResponsibilitySymbols), std::move(QueryAliases)); QueryInfos.push_back( make_pair(std::move(QuerySymbols), std::move(QueryInfo))); } @@ -480,12 +482,12 @@ void ReExportsMaterializationUnit::materialize( for (auto &KV : QueryInfo->Aliases) if (SrcJDDeps.count(KV.second.Aliasee)) { PerAliasDeps = {KV.second.Aliasee}; - QueryInfo->R.addDependencies(KV.first, PerAliasDepsMap); + QueryInfo->R->addDependencies(KV.first, PerAliasDepsMap); } }; auto OnComplete = [QueryInfo](Expected Result) { - auto &ES = QueryInfo->R.getTargetJITDylib().getExecutionSession(); + auto &ES = QueryInfo->R->getTargetJITDylib().getExecutionSession(); if (Result) { SymbolMap ResolutionMap; for (auto &KV : QueryInfo->Aliases) { @@ -499,19 +501,19 @@ void ReExportsMaterializationUnit::materialize( ResolutionMap[KV.first] = JITEvaluatedSymbol( (*Result)[KV.second.Aliasee].getAddress(), KV.second.AliasFlags); } - if (auto Err = QueryInfo->R.notifyResolved(ResolutionMap)) { + if (auto Err = QueryInfo->R->notifyResolved(ResolutionMap)) { ES.reportError(std::move(Err)); - QueryInfo->R.failMaterialization(); + QueryInfo->R->failMaterialization(); return; } - if (auto Err = QueryInfo->R.notifyEmitted()) { + if (auto Err = QueryInfo->R->notifyEmitted()) { ES.reportError(std::move(Err)); - QueryInfo->R.failMaterialization(); + QueryInfo->R->failMaterialization(); return; } } else { ES.reportError(Result.takeError()); - QueryInfo->R.failMaterialization(); + QueryInfo->R->failMaterialization(); } }; @@ -2131,7 +2133,7 @@ void ExecutionSession::dump(raw_ostream &OS) { void ExecutionSession::runOutstandingMUs() { while (1) { Optional, - MaterializationResponsibility>> + std::unique_ptr>> JMU; { diff --git a/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp b/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp index 023940dc82982..c6f6870279728 100644 --- a/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/IRCompileLayer.cpp @@ -25,7 +25,7 @@ void IRCompileLayer::setNotifyCompiled(NotifyCompiledFunction NotifyCompiled) { this->NotifyCompiled = std::move(NotifyCompiled); } -void IRCompileLayer::emit(MaterializationResponsibility R, +void IRCompileLayer::emit(std::unique_ptr R, ThreadSafeModule TSM) { assert(TSM && "Module must not be null"); @@ -33,13 +33,13 @@ void IRCompileLayer::emit(MaterializationResponsibility R, { std::lock_guard Lock(IRLayerMutex); if (NotifyCompiled) - NotifyCompiled(R.getVModuleKey(), std::move(TSM)); + NotifyCompiled(R->getVModuleKey(), std::move(TSM)); else TSM = ThreadSafeModule(); } BaseLayer.emit(std::move(R), std::move(*Obj)); } else { - R.failMaterialization(); + R->failMaterialization(); getExecutionSession().reportError(Obj.takeError()); } } diff --git a/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp b/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp index 511248f83b259..d5b11349277c1 100644 --- a/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/IRTransformLayer.cpp @@ -17,14 +17,14 @@ IRTransformLayer::IRTransformLayer(ExecutionSession &ES, IRLayer &BaseLayer, : IRLayer(ES, BaseLayer.getManglingOptions()), BaseLayer(BaseLayer), Transform(std::move(Transform)) {} -void IRTransformLayer::emit(MaterializationResponsibility R, +void IRTransformLayer::emit(std::unique_ptr R, ThreadSafeModule TSM) { assert(TSM && "Module must not be null"); - if (auto TransformedTSM = Transform(std::move(TSM), R)) + if (auto TransformedTSM = Transform(std::move(TSM), *R)) BaseLayer.emit(std::move(R), std::move(*TransformedTSM)); else { - R.failMaterialization(); + R->failMaterialization(); getExecutionSession().reportError(TransformedTSM.takeError()); } } diff --git a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp index 4f7f6089e68db..7d57ed5a3a04c 100644 --- a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp +++ b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp @@ -33,12 +33,12 @@ class CompileCallbackMaterializationUnit : public orc::MaterializationUnit { StringRef getName() const override { return ""; } private: - void materialize(MaterializationResponsibility R) override { + void materialize(std::unique_ptr R) override { SymbolMap Result; Result[Name] = JITEvaluatedSymbol(Compile(), JITSymbolFlags::Exported); // No dependencies, so these calls cannot fail. - cantFail(R.notifyResolved(Result)); - cantFail(R.notifyEmitted()); + cantFail(R->notifyResolved(Result)); + cantFail(R->notifyEmitted()); } void discard(const JITDylib &JD, const SymbolStringPtr &Name) override { diff --git a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp index 373d86d92f8d7..81f500d66bc29 100644 --- a/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LLJIT.cpp @@ -1085,15 +1085,17 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err) std::make_unique(hardware_concurrency(S.NumCompileThreads)); ES->setDispatchMaterialization( [this](std::unique_ptr MU, - MaterializationResponsibility MR) { - // FIXME: Switch to move capture once ThreadPool uses unique_function. - auto SharedMU = std::shared_ptr(std::move(MU)); - auto SharedMR = - std::make_shared(std::move(MR)); - auto Work = [SharedMU, SharedMR]() mutable { - SharedMU->materialize(std::move(*SharedMR)); - }; - CompileThreads->async(std::move(Work)); + std::unique_ptr MR) { + // FIXME: We should be able to use move-capture here, but ThreadPool's + // AsyncTaskTys are std::functions rather than unique_functions + // (because MSVC's std::packaged_tasks don't support move-only types). + // Fix this when all the above gets sorted out. + CompileThreads->async( + [UnownedMU = MU.release(), UnownedMR = MR.release()]() mutable { + std::unique_ptr MU(UnownedMU); + std::unique_ptr MR(UnownedMR); + MU->materialize(std::move(MR)); + }); }); } diff --git a/llvm/lib/ExecutionEngine/Orc/Layer.cpp b/llvm/lib/ExecutionEngine/Orc/Layer.cpp index 0a5d5577e99e8..8052e7b08a5a6 100644 --- a/llvm/lib/ExecutionEngine/Orc/Layer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Layer.cpp @@ -133,7 +133,7 @@ BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit( L(L), K(std::move(K)) {} void BasicIRLayerMaterializationUnit::materialize( - MaterializationResponsibility R) { + std::unique_ptr R) { // Throw away the SymbolToDefinition map: it's not usable after we hand // off the module. @@ -144,8 +144,8 @@ void BasicIRLayerMaterializationUnit::materialize( TSM = cloneToNewContext(TSM); #ifndef NDEBUG - auto &ES = R.getTargetJITDylib().getExecutionSession(); - auto &N = R.getTargetJITDylib().getName(); + auto &ES = R->getTargetJITDylib().getExecutionSession(); + auto &N = R->getTargetJITDylib().getName(); #endif // NDEBUG LLVM_DEBUG(ES.runSessionLocked( @@ -200,7 +200,7 @@ StringRef BasicObjectLayerMaterializationUnit::getName() const { } void BasicObjectLayerMaterializationUnit::materialize( - MaterializationResponsibility R) { + std::unique_ptr R) { L.emit(std::move(R), std::move(O)); } diff --git a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp index 5e604130d6eab..695f6cc9c1cb4 100644 --- a/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp +++ b/llvm/lib/ExecutionEngine/Orc/LazyReexports.cpp @@ -154,8 +154,8 @@ StringRef LazyReexportsMaterializationUnit::getName() const { } void LazyReexportsMaterializationUnit::materialize( - MaterializationResponsibility R) { - auto RequestedSymbols = R.getRequestedSymbols(); + std::unique_ptr R) { + auto RequestedSymbols = R->getRequestedSymbols(); SymbolAliasMap RequestedAliases; for (auto &RequestedSymbol : RequestedSymbols) { @@ -166,8 +166,8 @@ void LazyReexportsMaterializationUnit::materialize( } if (!CallableAliases.empty()) - R.replace(lazyReexports(LCTManager, ISManager, SourceJD, - std::move(CallableAliases), AliaseeTable)); + R->replace(lazyReexports(LCTManager, ISManager, SourceJD, + std::move(CallableAliases), AliaseeTable)); IndirectStubsManager::StubInitsMap StubInits; for (auto &Alias : RequestedAliases) { @@ -182,7 +182,7 @@ void LazyReexportsMaterializationUnit::materialize( if (!CallThroughTrampoline) { SourceJD.getExecutionSession().reportError( CallThroughTrampoline.takeError()); - R.failMaterialization(); + R->failMaterialization(); return; } @@ -195,7 +195,7 @@ void LazyReexportsMaterializationUnit::materialize( if (auto Err = ISManager.createStubs(StubInits)) { SourceJD.getExecutionSession().reportError(std::move(Err)); - R.failMaterialization(); + R->failMaterialization(); return; } @@ -204,8 +204,8 @@ void LazyReexportsMaterializationUnit::materialize( Stubs[Alias.first] = ISManager.findStub(*Alias.first, false); // No registered dependencies, so these calls cannot fail. - cantFail(R.notifyResolved(Stubs)); - cantFail(R.notifyEmitted()); + cantFail(R->notifyResolved(Stubs)); + cantFail(R->notifyEmitted()); } void LazyReexportsMaterializationUnit::discard(const JITDylib &JD, diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp index d8283fa7e3461..9e3245d9cc991 100644 --- a/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp @@ -24,9 +24,10 @@ namespace orc { class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { public: - ObjectLinkingLayerJITLinkContext(ObjectLinkingLayer &Layer, - MaterializationResponsibility MR, - std::unique_ptr ObjBuffer) + ObjectLinkingLayerJITLinkContext( + ObjectLinkingLayer &Layer, + std::unique_ptr MR, + std::unique_ptr ObjBuffer) : Layer(Layer), MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {} ~ObjectLinkingLayerJITLinkContext() { @@ -44,14 +45,14 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { void notifyFailed(Error Err) override { Layer.getExecutionSession().reportError(std::move(Err)); - MR.failMaterialization(); + MR->failMaterialization(); } void lookup(const LookupMap &Symbols, std::unique_ptr LC) override { JITDylibSearchOrder LinkOrder; - MR.getTargetJITDylib().withLinkOrderDo( + MR->getTargetJITDylib().withLinkOrderDo( [&](const JITDylibSearchOrder &LO) { LinkOrder = LO; }); auto &ES = Layer.getExecutionSession(); @@ -85,8 +86,8 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { for (auto &KV : InternalNamedSymbolDeps) { SymbolDependenceMap InternalDeps; - InternalDeps[&MR.getTargetJITDylib()] = std::move(KV.second); - MR.addDependencies(KV.first, InternalDeps); + InternalDeps[&MR->getTargetJITDylib()] = std::move(KV.second); + MR->addDependencies(KV.first, InternalDeps); } ES.lookup(LookupKind::Static, LinkOrder, std::move(LookupSet), @@ -115,7 +116,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { InternedResult[InternedName] = JITEvaluatedSymbol(Sym->getAddress(), Flags); - if (AutoClaim && !MR.getSymbols().count(InternedName)) { + if (AutoClaim && !MR->getSymbols().count(InternedName)) { assert(!ExtraSymbolsToClaim.count(InternedName) && "Duplicate symbol to claim?"); ExtraSymbolsToClaim[InternedName] = Flags; @@ -133,7 +134,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { Flags |= JITSymbolFlags::Weak; InternedResult[InternedName] = JITEvaluatedSymbol(Sym->getAddress(), Flags); - if (AutoClaim && !MR.getSymbols().count(InternedName)) { + if (AutoClaim && !MR->getSymbols().count(InternedName)) { assert(!ExtraSymbolsToClaim.count(InternedName) && "Duplicate symbol to claim?"); ExtraSymbolsToClaim[InternedName] = Flags; @@ -141,19 +142,19 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { } if (!ExtraSymbolsToClaim.empty()) - if (auto Err = MR.defineMaterializing(ExtraSymbolsToClaim)) + if (auto Err = MR->defineMaterializing(ExtraSymbolsToClaim)) return Err; { - // Check that InternedResult matches up with MR.getSymbols(). + // Check that InternedResult matches up with MR->getSymbols(). // This guards against faulty transformations / compilers / object caches. // First check that there aren't any missing symbols. size_t NumMaterializationSideEffectsOnlySymbols = 0; SymbolNameVector ExtraSymbols; SymbolNameVector MissingSymbols; - for (auto &KV : MR.getSymbols()) { + for (auto &KV : MR->getSymbols()) { // If this is a materialization-side-effects only symbol then bump // the counter and make sure it's *not* defined, otherwise make @@ -175,9 +176,9 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { // If there are more definitions than expected, add them to the // ExtraSymbols vector. if (InternedResult.size() > - MR.getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) { + MR->getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) { for (auto &KV : InternedResult) - if (!MR.getSymbols().count(KV.first)) + if (!MR->getSymbols().count(KV.first)) ExtraSymbols.push_back(KV.first); } @@ -187,23 +188,23 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { std::move(ExtraSymbols)); } - if (auto Err = MR.notifyResolved(InternedResult)) + if (auto Err = MR->notifyResolved(InternedResult)) return Err; - Layer.notifyLoaded(MR); + Layer.notifyLoaded(*MR); return Error::success(); } void notifyFinalized( std::unique_ptr A) override { - if (auto Err = Layer.notifyEmitted(MR, std::move(A))) { + if (auto Err = Layer.notifyEmitted(*MR, std::move(A))) { Layer.getExecutionSession().reportError(std::move(Err)); - MR.failMaterialization(); + MR->failMaterialization(); return; } - if (auto Err = MR.notifyEmitted()) { + if (auto Err = MR->notifyEmitted()) { Layer.getExecutionSession().reportError(std::move(Err)); - MR.failMaterialization(); + MR->failMaterialization(); } } @@ -217,7 +218,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { Config.PrePrunePasses.push_back( [this](LinkGraph &G) { return externalizeWeakAndCommonSymbols(G); }); - Layer.modifyPassConfig(MR, TT, Config); + Layer.modifyPassConfig(*MR, TT, Config); Config.PostPrunePasses.push_back( [this](LinkGraph &G) { return computeNamedSymbolDependencies(G); }); @@ -237,13 +238,13 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { auto &ES = Layer.getExecutionSession(); for (auto *Sym : G.defined_symbols()) if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { - if (!MR.getSymbols().count(ES.intern(Sym->getName()))) + if (!MR->getSymbols().count(ES.intern(Sym->getName()))) G.makeExternal(*Sym); } for (auto *Sym : G.absolute_symbols()) if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) { - if (!MR.getSymbols().count(ES.intern(Sym->getName()))) + if (!MR->getSymbols().count(ES.intern(Sym->getName()))) G.makeExternal(*Sym); } @@ -253,13 +254,13 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { Error markResponsibilitySymbolsLive(LinkGraph &G) const { auto &ES = Layer.getExecutionSession(); for (auto *Sym : G.defined_symbols()) - if (Sym->hasName() && MR.getSymbols().count(ES.intern(Sym->getName()))) + if (Sym->hasName() && MR->getSymbols().count(ES.intern(Sym->getName()))) Sym->setLive(true); return Error::success(); } Error computeNamedSymbolDependencies(LinkGraph &G) { - auto &ES = MR.getTargetJITDylib().getExecutionSession(); + auto &ES = MR->getTargetJITDylib().getExecutionSession(); auto LocalDeps = computeLocalDeps(G); // Compute dependencies for symbols defined in the JITLink graph. @@ -306,7 +307,7 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { } for (auto &P : Layer.Plugins) { - auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(MR); + auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(*MR); if (SyntheticLocalDeps.empty()) continue; @@ -426,12 +427,12 @@ class ObjectLinkingLayerJITLinkContext final : public JITLinkContext { SymbolDeps.erase(&SourceJD); } - MR.addDependencies(Name, SymbolDeps); + MR->addDependencies(Name, SymbolDeps); } } ObjectLinkingLayer &Layer; - MaterializationResponsibility MR; + std::unique_ptr MR; std::unique_ptr ObjBuffer; DenseMap ExternalNamedSymbolDeps; DenseMap InternalNamedSymbolDeps; @@ -452,7 +453,7 @@ ObjectLinkingLayer::~ObjectLinkingLayer() { getExecutionSession().reportError(std::move(Err)); } -void ObjectLinkingLayer::emit(MaterializationResponsibility R, +void ObjectLinkingLayer::emit(std::unique_ptr R, std::unique_ptr O) { assert(O && "Object must not be null"); jitLink(std::make_unique( diff --git a/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp b/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp index d18eb38a41423..a57662e10a794 100644 --- a/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/ObjectTransformLayer.cpp @@ -17,8 +17,9 @@ ObjectTransformLayer::ObjectTransformLayer(ExecutionSession &ES, TransformFunction Transform) : ObjectLayer(ES), BaseLayer(BaseLayer), Transform(std::move(Transform)) {} -void ObjectTransformLayer::emit(MaterializationResponsibility R, - std::unique_ptr O) { +void ObjectTransformLayer::emit( + std::unique_ptr R, + std::unique_ptr O) { assert(O && "Module must not be null"); // If there is a transform set then apply it. @@ -26,7 +27,7 @@ void ObjectTransformLayer::emit(MaterializationResponsibility R, if (auto TransformedObj = Transform(std::move(O))) O = std::move(*TransformedObj); else { - R.failMaterialization(); + R->failMaterialization(); getExecutionSession().reportError(TransformedObj.takeError()); return; } diff --git a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp index 7888c2fcbdbd9..1981039eb9f12 100644 --- a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp @@ -89,23 +89,18 @@ RTDyldObjectLinkingLayer::~RTDyldObjectLinkingLayer() { } } -void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, - std::unique_ptr O) { +void RTDyldObjectLinkingLayer::emit( + std::unique_ptr R, + std::unique_ptr O) { assert(O && "Object must not be null"); - // This method launches an asynchronous link step that will fulfill our - // materialization responsibility. We need to switch R to be heap - // allocated before that happens so it can live as long as the asynchronous - // link needs it to (i.e. it must be able to outlive this method). - auto SharedR = std::make_shared(std::move(R)); - auto &ES = getExecutionSession(); auto Obj = object::ObjectFile::createObjectFile(*O); if (!Obj) { getExecutionSession().reportError(Obj.takeError()); - SharedR->failMaterialization(); + R->failMaterialization(); return; } @@ -121,7 +116,7 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, continue; } else { ES.reportError(SymType.takeError()); - R.failMaterialization(); + R->failMaterialization(); return; } @@ -129,7 +124,7 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, if (!SymFlagsOrErr) { // TODO: Test this error. ES.reportError(SymFlagsOrErr.takeError()); - R.failMaterialization(); + R->failMaterialization(); return; } @@ -139,14 +134,14 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, InternalSymbols->insert(*SymName); else { ES.reportError(SymName.takeError()); - R.failMaterialization(); + R->failMaterialization(); return; } } } } - auto K = R.getVModuleKey(); + auto K = R->getVModuleKey(); RuntimeDyld::MemoryManager *MemMgr = nullptr; // Create a record a memory manager for this object. @@ -157,6 +152,10 @@ void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R, MemMgr = MemMgrs.back().get(); } + // Switch to shared ownership of MR so that it can be captured by both + // lambdas below. + std::shared_ptr SharedR(std::move(R)); + JITDylibSearchOrderResolver Resolver(*SharedR); jitLinkForORC( diff --git a/llvm/lib/ExecutionEngine/Orc/Speculation.cpp b/llvm/lib/ExecutionEngine/Orc/Speculation.cpp index 3dd536d8253e3..0b4755fe23cfc 100644 --- a/llvm/lib/ExecutionEngine/Orc/Speculation.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Speculation.cpp @@ -55,7 +55,7 @@ Error Speculator::addSpeculationRuntime(JITDylib &JD, // If two modules, share the same LLVMContext, different threads must // not access them concurrently without locking the associated LLVMContext // this implementation follows this contract. -void IRSpeculationLayer::emit(MaterializationResponsibility R, +void IRSpeculationLayer::emit(std::unique_ptr R, ThreadSafeModule TSM) { assert(TSM && "Speculation Layer received Null Module ?"); @@ -127,7 +127,7 @@ void IRSpeculationLayer::emit(MaterializationResponsibility R, assert(Mutator.GetInsertBlock()->getParent() == &Fn && "IR builder association mismatch?"); S.registerSymbols(internToJITSymbols(IRNames.getValue()), - &R.getTargetJITDylib()); + &R->getTargetJITDylib()); } } } diff --git a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp index 2c008dfdbd33e..9a1dbbb172517 100644 --- a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp @@ -35,12 +35,12 @@ TEST_F(CoreAPIsStandardTest, BasicSuccessfulLookup) { OnCompletionRun = true; }; - std::shared_ptr FooMR; + std::unique_ptr FooMR; cantFail(JD.define(std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { - FooMR = std::make_shared(std::move(R)); + [&](std::unique_ptr R) { + FooMR = std::move(R); }))); ES.lookup(LookupKind::Static, makeJITDylibSearchOrder(&JD), @@ -99,9 +99,9 @@ TEST_F(CoreAPIsStandardTest, ResolveUnrequestedSymbol) { cantFail(JD.define(std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}), - [this](MaterializationResponsibility R) { - cantFail(R.notifyResolved({{Foo, FooSym}, {Bar, BarSym}})); - cantFail(R.notifyEmitted()); + [this](std::unique_ptr R) { + cantFail(R->notifyResolved({{Foo, FooSym}, {Bar, BarSym}})); + cantFail(R->notifyEmitted()); }))); auto Result = @@ -116,14 +116,16 @@ TEST_F(CoreAPIsStandardTest, MaterializationSideEffctsOnlyBasic) { // don't return until they're emitted, and that they don't appear in query // results. - Optional FooR; + std::unique_ptr FooR; Optional Result; cantFail(JD.define(std::make_unique( SymbolFlagsMap( {{Foo, JITSymbolFlags::Exported | JITSymbolFlags::MaterializationSideEffectsOnly}}), - [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }))); + [&](std::unique_ptr R) { + FooR = std::move(R); + }))); ES.lookup( LookupKind::Static, makeJITDylibSearchOrder(&JD), @@ -155,7 +157,9 @@ TEST_F(CoreAPIsStandardTest, MaterializationSideEffectsOnlyFailuresPersist) { SymbolFlagsMap( {{Foo, JITSymbolFlags::Exported | JITSymbolFlags::MaterializationSideEffectsOnly}}), - [&](MaterializationResponsibility R) { R.failMaterialization(); }))); + [&](std::unique_ptr R) { + R->failMaterialization(); + }))); EXPECT_THAT_EXPECTED( ES.lookup(makeJITDylibSearchOrder(&JD), SymbolLookupSet({Foo})), @@ -182,10 +186,10 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) { bool BarMaterializerDestructed = false; cantFail(JD.define(std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [this](MaterializationResponsibility R) { + [this](std::unique_ptr R) { ADD_FAILURE() << "Unexpected materialization of \"Bar\""; - cantFail(R.notifyResolved({{Bar, BarSym}})); - cantFail(R.notifyEmitted()); + cantFail(R->notifyResolved({{Bar, BarSym}})); + cantFail(R->notifyEmitted()); }, nullptr, [&](const JITDylib &JD, const SymbolStringPtr &Name) { @@ -197,10 +201,12 @@ TEST_F(CoreAPIsStandardTest, RemoveSymbolsTest) { // Baz will be in the materializing state initially, then // materialized for the final removal attempt. - Optional BazR; + std::unique_ptr BazR; cantFail(JD.define(std::make_unique( SymbolFlagsMap({{Baz, BazSym.getFlags()}}), - [&](MaterializationResponsibility R) { BazR.emplace(std::move(R)); }, + [&](std::unique_ptr R) { + BazR = std::move(R); + }, nullptr, [](const JITDylib &JD, const SymbolStringPtr &Name) { ADD_FAILURE() << "\"Baz\" discarded unexpectedly"; @@ -297,7 +303,7 @@ TEST_F(CoreAPIsStandardTest, LookupFlagsTest) { JITSymbolFlags::Exported | JITSymbolFlags::Weak)); auto MU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [](MaterializationResponsibility R) { + [](std::unique_ptr R) { llvm_unreachable("Symbol materialized on flags lookup"); }); @@ -400,10 +406,10 @@ TEST_F(CoreAPIsStandardTest, TestThatReExportsDontUnnecessarilyMaterialize) { bool BarMaterialized = false; auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { + [&](std::unique_ptr R) { BarMaterialized = true; - cantFail(R.notifyResolved({{Bar, BarSym}})); - cantFail(R.notifyEmitted()); + cantFail(R->notifyResolved({{Bar, BarSym}})); + cantFail(R->notifyEmitted()); }); cantFail(JD.define(BarMU)); @@ -444,10 +450,12 @@ TEST_F(CoreAPIsStandardTest, TestReexportsGenerator) { } TEST_F(CoreAPIsStandardTest, TestTrivialCircularDependency) { - Optional FooR; + std::unique_ptr FooR; auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + FooR = std::move(R); + }); cantFail(JD.define(FooMU)); @@ -476,26 +484,29 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) { // does not prevent any symbol from becoming 'ready' once all symbols are // emitted. - // Create three MaterializationResponsibility objects: one for each of Foo, - // Bar and Baz. These are optional because MaterializationResponsibility - // does not have a default constructor). - Optional FooR; - Optional BarR; - Optional BazR; + std::unique_ptr FooR; + std::unique_ptr BarR; + std::unique_ptr BazR; // Create a MaterializationUnit for each symbol that moves the // MaterializationResponsibility into one of the locals above. auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + FooR = std::move(R); + }); auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + BarR = std::move(R); + }); auto BazMU = std::make_unique( SymbolFlagsMap({{Baz, BazSym.getFlags()}}), - [&](MaterializationResponsibility R) { BazR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + BazR = std::move(R); + }); // Define the symbols. cantFail(JD.define(FooMU)); @@ -622,18 +633,22 @@ TEST_F(CoreAPIsStandardTest, TestCircularDependenceInOneJITDylib) { } TEST_F(CoreAPIsStandardTest, FailureInDependency) { - Optional FooR; - Optional BarR; + std::unique_ptr FooR; + std::unique_ptr BarR; // Create a MaterializationUnit for each symbol that moves the // MaterializationResponsibility into one of the locals above. auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + FooR = std::move(R); + }); auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + BarR = std::move(R); + }); // Define the symbols. cantFail(JD.define(FooMU)); @@ -687,18 +702,22 @@ TEST_F(CoreAPIsStandardTest, FailureInDependency) { } TEST_F(CoreAPIsStandardTest, FailureInCircularDependency) { - Optional FooR; - Optional BarR; + std::unique_ptr FooR; + std::unique_ptr BarR; // Create a MaterializationUnit for each symbol that moves the // MaterializationResponsibility into one of the locals above. auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + FooR = std::move(R); + }); auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + BarR = std::move(R); + }); // Define the symbols. cantFail(JD.define(FooMU)); @@ -753,18 +772,22 @@ TEST_F(CoreAPIsStandardTest, FailureInCircularDependency) { } TEST_F(CoreAPIsStandardTest, AddDependencyOnFailedSymbol) { - Optional FooR; - Optional BarR; + std::unique_ptr FooR; + std::unique_ptr BarR; // Create a MaterializationUnit for each symbol that moves the // MaterializationResponsibility into one of the locals above. auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + FooR = std::move(R); + }); auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + BarR = std::move(R); + }); // Define the symbols. cantFail(JD.define(FooMU)); @@ -819,18 +842,22 @@ TEST_F(CoreAPIsStandardTest, AddDependencyOnFailedSymbol) { } TEST_F(CoreAPIsStandardTest, FailAfterMaterialization) { - Optional FooR; - Optional BarR; + std::unique_ptr FooR; + std::unique_ptr BarR; // Create a MaterializationUnit for each symbol that moves the // MaterializationResponsibility into one of the locals above. auto FooMU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { FooR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + FooR = std::move(R); + }); auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { BarR.emplace(std::move(R)); }); + [&](std::unique_ptr R) { + BarR = std::move(R); + }); // Define the symbols. cantFail(JD.define(FooMU)); @@ -882,9 +909,9 @@ TEST_F(CoreAPIsStandardTest, FailMaterializerWithUnqueriedSymbols) { auto MU = std::make_unique( SymbolFlagsMap( {{Foo, JITSymbolFlags::Exported}, {Bar, JITSymbolFlags::Exported}}), - [&](MaterializationResponsibility R) { + [&](std::unique_ptr R) { MaterializerRun = true; - R.failMaterialization(); + R->failMaterialization(); }); cantFail(JD.define(std::move(MU))); @@ -911,7 +938,7 @@ TEST_F(CoreAPIsStandardTest, DropMaterializerWhenEmpty) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, WeakExported}, {Bar, WeakExported}}), - [](MaterializationResponsibility R) { + [](std::unique_ptr R) { llvm_unreachable("Unexpected call to materialize"); }, nullptr, @@ -943,10 +970,10 @@ TEST_F(CoreAPIsStandardTest, AddAndMaterializeLazySymbol) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}, {Bar, WeakExported}}), - [&](MaterializationResponsibility R) { + [&](std::unique_ptr R) { assert(BarDiscarded && "Bar should have been discarded by this point"); - cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}}))); - cantFail(R.notifyEmitted()); + cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}}))); + cantFail(R->notifyEmitted()); FooMaterialized = true; }, nullptr, @@ -985,18 +1012,18 @@ TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) { bool BarMaterialized = false; auto MU1 = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { - cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); - cantFail(R.notifyEmitted()); + [&](std::unique_ptr R) { + cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); + cantFail(R->notifyEmitted()); BarMaterialized = true; }); bool DuplicateBarDiscarded = false; auto MU2 = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { + [&](std::unique_ptr R) { ADD_FAILURE() << "Attempt to materialize Bar from the wrong unit"; - R.failMaterialization(); + R->failMaterialization(); }, nullptr, [&](const JITDylib &JD, SymbolStringPtr Name) { @@ -1026,20 +1053,21 @@ TEST_F(CoreAPIsStandardTest, TestBasicWeakSymbolMaterialization) { TEST_F(CoreAPIsStandardTest, DefineMaterializingSymbol) { bool ExpectNoMoreMaterialization = false; - ES.setDispatchMaterialization([&](std::unique_ptr MU, - MaterializationResponsibility MR) { - if (ExpectNoMoreMaterialization) - ADD_FAILURE() << "Unexpected materialization"; - MU->materialize(std::move(MR)); - }); + ES.setDispatchMaterialization( + [&](std::unique_ptr MU, + std::unique_ptr MR) { + if (ExpectNoMoreMaterialization) + ADD_FAILURE() << "Unexpected materialization"; + MU->materialize(std::move(MR)); + }); auto MU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { + [&](std::unique_ptr R) { cantFail( - R.defineMaterializing(SymbolFlagsMap({{Bar, BarSym.getFlags()}}))); - cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); - cantFail(R.notifyEmitted()); + R->defineMaterializing(SymbolFlagsMap({{Bar, BarSym.getFlags()}}))); + cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); + cantFail(R->notifyEmitted()); }); cantFail(JD.define(MU)); @@ -1093,8 +1121,8 @@ TEST_F(CoreAPIsStandardTest, FailResolution) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, JITSymbolFlags::Exported | JITSymbolFlags::Weak}, {Bar, JITSymbolFlags::Exported | JITSymbolFlags::Weak}}), - [&](MaterializationResponsibility R) { - R.failMaterialization(); + [&](std::unique_ptr R) { + R->failMaterialization(); }); cantFail(JD.define(MU)); @@ -1129,23 +1157,23 @@ TEST_F(CoreAPIsStandardTest, FailEmissionAfterResolution) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { - cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); + [&](std::unique_ptr R) { + cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}, {Bar, BarSym}}))); ES.lookup( LookupKind::Static, makeJITDylibSearchOrder(&JD), SymbolLookupSet({Baz}), SymbolState::Resolved, - [&R](Expected Result) { + [&](Expected Result) { // Called when "baz" is resolved. We don't actually depend // on or care about baz, but use it to trigger failure of // this materialization before Baz has been finalized in // order to test that error propagation is correct in this // scenario. cantFail(std::move(Result)); - R.failMaterialization(); + R->failMaterialization(); }, [&](const SymbolDependenceMap &Deps) { - R.addDependenciesForAll(Deps); + R->addDependenciesForAll(Deps); }); }); @@ -1165,7 +1193,9 @@ TEST_F(CoreAPIsStandardTest, FailAfterPartialResolution) { // Fail materialization of bar. auto BarMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { R.failMaterialization(); }); + [&](std::unique_ptr R) { + R->failMaterialization(); + }); cantFail(JD.define(std::move(BarMU))); @@ -1185,9 +1215,9 @@ TEST_F(CoreAPIsStandardTest, FailAfterPartialResolution) { TEST_F(CoreAPIsStandardTest, TestLookupWithUnthreadedMaterialization) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}), - [&](MaterializationResponsibility R) { - cantFail(R.notifyResolved({{Foo, FooSym}})); - cantFail(R.notifyEmitted()); + [&](std::unique_ptr R) { + cantFail(R->notifyResolved({{Foo, FooSym}})); + cantFail(R->notifyEmitted()); }); cantFail(JD.define(MU)); @@ -1204,15 +1234,14 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) { #if LLVM_ENABLE_THREADS std::thread MaterializationThread; - ES.setDispatchMaterialization([&](std::unique_ptr MU, - MaterializationResponsibility MR) { - auto SharedMR = - std::make_shared(std::move(MR)); - MaterializationThread = - std::thread([MU = std::move(MU), MR = std::move(SharedMR)] { - MU->materialize(std::move(*MR)); - }); - }); + ES.setDispatchMaterialization( + [&](std::unique_ptr MU, + std::unique_ptr MR) { + MaterializationThread = + std::thread([MU = std::move(MU), MR = std::move(MR)]() mutable { + MU->materialize(std::move(MR)); + }); + }); cantFail(JD.define(absoluteSymbols({{Foo, FooSym}}))); @@ -1238,23 +1267,23 @@ TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { - auto Requested = R.getRequestedSymbols(); + [&](std::unique_ptr R) { + auto Requested = R->getRequestedSymbols(); EXPECT_EQ(Requested.size(), 1U) << "Expected one symbol requested"; EXPECT_EQ(*Requested.begin(), Foo) << "Expected \"Foo\" requested"; auto NewMU = std::make_unique( SymbolFlagsMap({{Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R2) { - cantFail(R2.notifyResolved(SymbolMap({{Bar, BarSym}}))); - cantFail(R2.notifyEmitted()); + [&](std::unique_ptr R2) { + cantFail(R2->notifyResolved(SymbolMap({{Bar, BarSym}}))); + cantFail(R2->notifyEmitted()); BarMaterialized = true; }); - R.replace(std::move(NewMU)); + R->replace(std::move(NewMU)); - cantFail(R.notifyResolved(SymbolMap({{Foo, FooSym}}))); - cantFail(R.notifyEmitted()); + cantFail(R->notifyResolved(SymbolMap({{Foo, FooSym}}))); + cantFail(R->notifyEmitted()); FooMaterialized = true; }); @@ -1280,13 +1309,13 @@ TEST_F(CoreAPIsStandardTest, TestGetRequestedSymbolsAndReplace) { TEST_F(CoreAPIsStandardTest, TestMaterializationResponsibilityDelegation) { auto MU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}, {Bar, BarSym.getFlags()}}), - [&](MaterializationResponsibility R) { - auto R2 = R.delegate({Bar}); + [&](std::unique_ptr R) { + auto R2 = R->delegate({Bar}); - cantFail(R.notifyResolved({{Foo, FooSym}})); - cantFail(R.notifyEmitted()); - cantFail(R2.notifyResolved({{Bar, BarSym}})); - cantFail(R2.notifyEmitted()); + cantFail(R->notifyResolved({{Foo, FooSym}})); + cantFail(R->notifyEmitted()); + cantFail(R2->notifyResolved({{Bar, BarSym}})); + cantFail(R2->notifyEmitted()); }); cantFail(JD.define(MU)); @@ -1309,12 +1338,11 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) { JITSymbolFlags WeakExported = JITSymbolFlags::Exported; WeakExported &= JITSymbolFlags::Weak; - std::unique_ptr FooResponsibility; + std::unique_ptr FooR; auto MU = std::make_unique( SymbolFlagsMap({{Foo, FooSym.getFlags()}}), - [&](MaterializationResponsibility R) { - FooResponsibility = - std::make_unique(std::move(R)); + [&](std::unique_ptr R) { + FooR = std::move(R); }); cantFail(JD.define(MU)); @@ -1328,7 +1356,7 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) { auto MU2 = std::make_unique( SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}), - [](MaterializationResponsibility R) { + [](std::unique_ptr R) { llvm_unreachable("This unit should never be materialized"); }); @@ -1339,8 +1367,8 @@ TEST_F(CoreAPIsStandardTest, TestMaterializeWeakSymbol) { consumeError(std::move(Err)); // No dependencies registered, can't fail: - cantFail(FooResponsibility->notifyResolved(SymbolMap({{Foo, FooSym}}))); - cantFail(FooResponsibility->notifyEmitted()); + cantFail(FooR->notifyResolved(SymbolMap({{Foo, FooSym}}))); + cantFail(FooR->notifyEmitted()); } static bool linkOrdersEqual(const std::vector> &LHS, diff --git a/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp index 50e7b60a2df4e..81ff3e7a87b30 100644 --- a/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp +++ b/llvm/unittests/ExecutionEngine/Orc/LazyCallThroughAndReexportsTest.cpp @@ -39,15 +39,15 @@ TEST_F(LazyReexportsTest, BasicLocalCallThroughManagerOperation) { cantFail(JD.define(std::make_unique( SymbolFlagsMap({{DummyTarget, JITSymbolFlags::Exported}}), - [&](MaterializationResponsibility R) { + [&](std::unique_ptr R) { DummyTargetMaterialized = true; // No dependencies registered, can't fail. - cantFail(R.notifyResolved( + cantFail(R->notifyResolved( {{DummyTarget, JITEvaluatedSymbol(static_cast( reinterpret_cast(&dummyTarget)), JITSymbolFlags::Exported)}})); - cantFail(R.notifyEmitted()); + cantFail(R->notifyEmitted()); }))); unsigned NotifyResolvedCount = 0; diff --git a/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h b/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h index b25851d8f796c..afbc4a9ffaa5c 100644 --- a/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h +++ b/llvm/unittests/ExecutionEngine/Orc/OrcTestCommon.h @@ -86,7 +86,7 @@ class OrcNativeTarget { class SimpleMaterializationUnit : public orc::MaterializationUnit { public: using MaterializeFunction = - std::function; + std::function)>; using DiscardFunction = std::function; using DestructorFunction = std::function; @@ -108,7 +108,8 @@ class SimpleMaterializationUnit : public orc::MaterializationUnit { StringRef getName() const override { return ""; } - void materialize(orc::MaterializationResponsibility R) override { + void + materialize(std::unique_ptr R) override { Materialize(std::move(R)); } From a426c6911e45f043629de315b90152adf735ca83 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Sun, 13 Sep 2020 14:22:20 -0700 Subject: [PATCH 178/234] [JITLink] Improve formatting for Edge, Block and Symbol debugging output. --- llvm/lib/ExecutionEngine/JITLink/JITLink.cpp | 34 +++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp index 5105ec4951484..71ec88639a5b7 100644 --- a/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/JITLink.cpp @@ -93,6 +93,7 @@ const char *getScopeName(Scope S) { raw_ostream &operator<<(raw_ostream &OS, const Block &B) { return OS << formatv("{0:x16}", B.getAddress()) << " -- " << formatv("{0:x16}", B.getAddress() + B.getSize()) << ": " + << "size = " << formatv("{0:x}", B.getSize()) << ", " << (B.isZeroFill() ? "zero-fill" : "content") << ", align = " << B.getAlignment() << ", align-ofs = " << B.getAlignmentOffset() @@ -126,10 +127,10 @@ raw_ostream &operator<<(raw_ostream &OS, const Symbol &Sym) { break; } OS << (Sym.isLive() ? '+' : '-') - << ", size = " << formatv("{0:x8}", Sym.getSize()) + << ", size = " << formatv("{0:x}", Sym.getSize()) << ", addr = " << formatv("{0:x16}", Sym.getAddress()) << " (" << formatv("{0:x16}", Sym.getAddressable().getAddress()) << " + " - << formatv("{0:x8}", Sym.getOffset()); + << formatv("{0:x}", Sym.getOffset()); if (Sym.isDefined()) OS << " " << Sym.getBlock().getSection().getName(); OS << ")>"; @@ -139,8 +140,33 @@ raw_ostream &operator<<(raw_ostream &OS, const Symbol &Sym) { void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName) { OS << "edge@" << formatv("{0:x16}", B.getAddress() + E.getOffset()) << ": " - << formatv("{0:x16}", B.getAddress()) << " + " << E.getOffset() << " -- " - << EdgeKindName << " -> " << E.getTarget() << " + " << E.getAddend(); + << formatv("{0:x16}", B.getAddress()) << " + " + << formatv("{0:x}", E.getOffset()) << " -- " << EdgeKindName << " -> "; + + auto &TargetSym = E.getTarget(); + if (TargetSym.hasName()) + OS << TargetSym.getName(); + else { + auto &TargetBlock = TargetSym.getBlock(); + auto &TargetSec = TargetBlock.getSection(); + JITTargetAddress SecAddress = ~JITTargetAddress(0); + for (auto *B : TargetSec.blocks()) + if (B->getAddress() < SecAddress) + SecAddress = B->getAddress(); + + JITTargetAddress SecDelta = TargetSym.getAddress() - SecAddress; + OS << formatv("{0:x16}", TargetSym.getAddress()) << " (section " + << TargetSec.getName(); + if (SecDelta) + OS << " + " << formatv("{0:x}", SecDelta); + OS << " / block " << formatv("{0:x16}", TargetBlock.getAddress()); + if (TargetSym.getOffset()) + OS << " + " << formatv("{0:x}", TargetSym.getOffset()); + OS << ")"; + } + + if (E.getAddend() != 0) + OS << " + " << E.getAddend(); } Section::~Section() { From d578186f6acdebe3068b47f1c6e1ac6a6bff63a6 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Wed, 16 Sep 2020 13:46:55 -0700 Subject: [PATCH 179/234] [ORC] Add operations to create and lookup JITDylibs to OrcV2 C bindings. --- llvm/include/llvm-c/Orc.h | 36 +++++++++++++++++++ .../ExecutionEngine/Orc/OrcV2CBindings.cpp | 23 ++++++++++++ 2 files changed, 59 insertions(+) diff --git a/llvm/include/llvm-c/Orc.h b/llvm/include/llvm-c/Orc.h index 09a058846108a..6271ab689c8b1 100644 --- a/llvm/include/llvm-c/Orc.h +++ b/llvm/include/llvm-c/Orc.h @@ -112,6 +112,42 @@ LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name); */ void LLVMOrcReleaseSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S); +/** + * Create a "bare" JITDylib. + * + * The client is responsible for ensuring that the JITDylib's name is unique, + * e.g. by calling LLVMOrcExecutionSessionGetJTIDylibByName first. + * + * This call does not install any library code or symbols into the newly + * created JITDylib. The client is responsible for all configuration. + */ +LLVMOrcJITDylibRef +LLVMOrcExecutionSessionCreateBareJITDylib(LLVMOrcExecutionSessionRef ES, + const char *Name); + +/** + * Create a JITDylib. + * + * The client is responsible for ensuring that the JITDylib's name is unique, + * e.g. by calling LLVMOrcExecutionSessionGetJTIDylibByName first. + * + * If a Platform is attached to the ExecutionSession then + * Platform::setupJITDylib will be called to install standard platform symbols + * (e.g. standard library interposes). If no Platform is installed then this + * call is equivalent to LLVMExecutionSessionRefCreateBareJITDylib and will + * always return success. + */ +LLVMErrorRef +LLVMOrcExecutionSessionCreateJITDylib(LLVMOrcExecutionSessionRef ES, + LLVMOrcJITDylibRef *Result, + const char *Name); + +/** + * Returns the JITDylib with the given name, or NULL if no such JITDylib + * exists. + */ +LLVMOrcJITDylibRef LLVMOrcExecutionSessionGetJITDylibByName(const char *Name); + /** * Dispose of a JITDylib::DefinitionGenerator. This should only be called if * ownership has not been passed to a JITDylib (e.g. because some error diff --git a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp index 5933c2e666d1c..f6dd235b6edea 100644 --- a/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp +++ b/llvm/lib/ExecutionEngine/Orc/OrcV2CBindings.cpp @@ -68,6 +68,29 @@ void LLVMOrcReleaseSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S) { OrcV2CAPIHelper::releasePoolEntry(unwrap(S)); } +LLVMOrcJITDylibRef +LLVMOrcExecutionSessionCreateBareJITDylib(LLVMOrcExecutionSessionRef ES, + const char *Name) { + return wrap(&unwrap(ES)->createBareJITDylib(Name)); +} + +LLVMErrorRef +LLVMOrcExecutionSessionCreateJITDylib(LLVMOrcExecutionSessionRef ES, + LLVMOrcJITDylibRef *Result, + const char *Name) { + auto JD = unwrap(ES)->createJITDylib(Name); + if (!JD) + return wrap(JD.takeError()); + *Result = wrap(&*JD); + return LLVMErrorSuccess; +} + +LLVMOrcJITDylibRef +LLVMOrcExecutionSessionGetJITDylibByName(LLVMOrcExecutionSessionRef ES, + const char *Name) { + return wrap(unwrap(ES)->getJITDylibByName(Name)); +} + void LLVMOrcDisposeJITDylibDefinitionGenerator( LLVMOrcJITDylibDefinitionGeneratorRef DG) { delete unwrap(DG); From e1e7f1df20adbcb961415ab5ea1f0856690484b2 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Thu, 17 Sep 2020 13:28:14 +0100 Subject: [PATCH 180/234] Remove unnecessary forward declarations. NFCI. All of these forward declarations are fully defined in headers that are directly included. --- llvm/include/llvm/DebugInfo/PDB/PDBSymbol.h | 1 - llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h | 2 -- llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h | 1 - llvm/include/llvm/IR/LegacyPassManagers.h | 1 - llvm/include/llvm/MC/MCELFObjectWriter.h | 1 - llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h | 1 - llvm/include/llvm/ProfileData/SampleProf.h | 2 -- llvm/include/llvm/Transforms/Utils/LoopUtils.h | 1 - llvm/include/llvm/Transforms/Utils/LoopVersioning.h | 1 - 9 files changed, 11 deletions(-) diff --git a/llvm/include/llvm/DebugInfo/PDB/PDBSymbol.h b/llvm/include/llvm/DebugInfo/PDB/PDBSymbol.h index 2982146f960c9..88849d024c233 100644 --- a/llvm/include/llvm/DebugInfo/PDB/PDBSymbol.h +++ b/llvm/include/llvm/DebugInfo/PDB/PDBSymbol.h @@ -42,7 +42,6 @@ class StringRef; class raw_ostream; namespace pdb { -class IPDBRawSymbol; class IPDBSession; #define DECLARE_PDB_SYMBOL_CONCRETE_TYPE(TagValue) \ diff --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h index 8376d163d57a5..c7ba57228ab71 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h @@ -28,8 +28,6 @@ class TargetMachine; namespace orc { -class JITTargetMachineBuilder; - IRSymbolMapper::ManglingOptions irManglingOptionsFromTargetOptions(const TargetOptions &Opts); diff --git a/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h index a4e43d4e1c9c2..943404262bd04 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h @@ -22,7 +22,6 @@ namespace llvm { class Module; -class JITSymbolResolver; namespace orc { diff --git a/llvm/include/llvm/IR/LegacyPassManagers.h b/llvm/include/llvm/IR/LegacyPassManagers.h index 6b1ddd4d79f8f..498e736a0100c 100644 --- a/llvm/include/llvm/IR/LegacyPassManagers.h +++ b/llvm/include/llvm/IR/LegacyPassManagers.h @@ -88,7 +88,6 @@ namespace llvm { template class ArrayRef; class Module; -class Pass; class StringRef; class Value; class Timer; diff --git a/llvm/include/llvm/MC/MCELFObjectWriter.h b/llvm/include/llvm/MC/MCELFObjectWriter.h index 8f78b99d37949..5d99c494b11eb 100644 --- a/llvm/include/llvm/MC/MCELFObjectWriter.h +++ b/llvm/include/llvm/MC/MCELFObjectWriter.h @@ -23,7 +23,6 @@ namespace llvm { class MCAssembler; class MCContext; class MCFixup; -class MCObjectWriter; class MCSymbol; class MCSymbolELF; class MCValue; diff --git a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h index 1d10c66b4201f..774569a090fd7 100644 --- a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h +++ b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h @@ -24,7 +24,6 @@ namespace llvm { class MCInst; -class MCParsedAsmOperand; class MCStreamer; class MCSubtargetInfo; template class SmallVectorImpl; diff --git a/llvm/include/llvm/ProfileData/SampleProf.h b/llvm/include/llvm/ProfileData/SampleProf.h index 562468333ef47..5e212092cb411 100644 --- a/llvm/include/llvm/ProfileData/SampleProf.h +++ b/llvm/include/llvm/ProfileData/SampleProf.h @@ -37,8 +37,6 @@ namespace llvm { -class raw_ostream; - const std::error_category &sampleprof_category(); enum class sampleprof_error { diff --git a/llvm/include/llvm/Transforms/Utils/LoopUtils.h b/llvm/include/llvm/Transforms/Utils/LoopUtils.h index 60446bca53174..8e653b26e2997 100644 --- a/llvm/include/llvm/Transforms/Utils/LoopUtils.h +++ b/llvm/include/llvm/Transforms/Utils/LoopUtils.h @@ -38,7 +38,6 @@ class ScalarEvolution; class SCEV; class SCEVExpander; class TargetLibraryInfo; -class TargetTransformInfo; class LPPassManager; class Instruction; struct RuntimeCheckingPtrGroup; diff --git a/llvm/include/llvm/Transforms/Utils/LoopVersioning.h b/llvm/include/llvm/Transforms/Utils/LoopVersioning.h index 1efdcc65b39a8..4c0998e463d42 100644 --- a/llvm/include/llvm/Transforms/Utils/LoopVersioning.h +++ b/llvm/include/llvm/Transforms/Utils/LoopVersioning.h @@ -24,7 +24,6 @@ namespace llvm { class Loop; class LoopAccessInfo; class LoopInfo; -class ScalarEvolution; struct RuntimeCheckingPtrGroup; typedef std::pair From b2331f025ad61ded2be95da5ccd06018c15ddc29 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Sat, 19 Sep 2020 18:56:49 -0700 Subject: [PATCH 181/234] [ORC][examples] Add an OrcV2 example for IR optimization via IRTransformLayer. Shows how to write a custom IR transform to apply a legacy::PassManager pipeline. --- llvm/examples/OrcV2Examples/CMakeLists.txt | 1 + .../CMakeLists.txt | 12 ++ .../LLJITWithOptimizingIRTransform.cpp | 122 ++++++++++++++++++ .../ExecutionEngine/Orc/IRTransformLayer.h | 3 +- 4 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 llvm/examples/OrcV2Examples/LLJITWithOptimizingIRTransform/CMakeLists.txt create mode 100644 llvm/examples/OrcV2Examples/LLJITWithOptimizingIRTransform/LLJITWithOptimizingIRTransform.cpp diff --git a/llvm/examples/OrcV2Examples/CMakeLists.txt b/llvm/examples/OrcV2Examples/CMakeLists.txt index cf19fbc76ff50..2af3fd90d7176 100644 --- a/llvm/examples/OrcV2Examples/CMakeLists.txt +++ b/llvm/examples/OrcV2Examples/CMakeLists.txt @@ -6,6 +6,7 @@ add_subdirectory(LLJITWithInitializers) add_subdirectory(LLJITWithLazyReexports) add_subdirectory(LLJITWithObjectCache) add_subdirectory(LLJITWithObjectLinkingLayerPlugin) +add_subdirectory(LLJITWithOptimizingIRTransform) add_subdirectory(LLJITWithTargetProcessControl) add_subdirectory(LLJITWithThinLTOSummaries) add_subdirectory(OrcV2CBindingsAddObjectFile) diff --git a/llvm/examples/OrcV2Examples/LLJITWithOptimizingIRTransform/CMakeLists.txt b/llvm/examples/OrcV2Examples/LLJITWithOptimizingIRTransform/CMakeLists.txt new file mode 100644 index 0000000000000..63be55cfa3794 --- /dev/null +++ b/llvm/examples/OrcV2Examples/LLJITWithOptimizingIRTransform/CMakeLists.txt @@ -0,0 +1,12 @@ +set(LLVM_LINK_COMPONENTS + Core + ExecutionEngine + IRReader + OrcJIT + Support + nativecodegen + ) + +add_llvm_example(LLJITWithOptimizingIRTransform + LLJITWithOptimizingIRTransform.cpp + ) diff --git a/llvm/examples/OrcV2Examples/LLJITWithOptimizingIRTransform/LLJITWithOptimizingIRTransform.cpp b/llvm/examples/OrcV2Examples/LLJITWithOptimizingIRTransform/LLJITWithOptimizingIRTransform.cpp new file mode 100644 index 0000000000000..7ebf3e8e9a077 --- /dev/null +++ b/llvm/examples/OrcV2Examples/LLJITWithOptimizingIRTransform/LLJITWithOptimizingIRTransform.cpp @@ -0,0 +1,122 @@ +//===-- LLJITWithOptimizingIRTransform.cpp -- LLJIT with IR optimization --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// In this example we will use an IR transform to optimize a module as it +// passes through LLJIT's IRTransformLayer. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ExecutionEngine/Orc/LLJIT.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/Support/InitLLVM.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/Scalar.h" + +#include "../ExampleModules.h" + +using namespace llvm; +using namespace llvm::orc; + +ExitOnError ExitOnErr; + +// Example IR module. +// +// This IR contains a recursive definition of the factorial function: +// +// fac(n) | n == 0 = 1 +// | otherwise = n * fac(n - 1) +// +// It also contains an entry function which calls the factorial function with +// an input value of 5. +// +// We expect the IR optimization transform that we build below to transform +// this into a non-recursive factorial function and an entry function that +// returns a constant value of 5!, or 120. + +const llvm::StringRef MainMod = + R"( + + define i32 @fac(i32 %n) { + entry: + %tobool = icmp eq i32 %n, 0 + br i1 %tobool, label %return, label %if.then + + if.then: ; preds = %entry + %arg = add nsw i32 %n, -1 + %call_result = call i32 @fac(i32 %arg) + %result = mul nsw i32 %n, %call_result + br label %return + + return: ; preds = %entry, %if.then + %final_result = phi i32 [ %result, %if.then ], [ 1, %entry ] + ret i32 %final_result + } + + define i32 @entry() { + entry: + %result = call i32 @fac(i32 5) + ret i32 %result + } + +)"; + +// A function object that creates a simple pass pipeline to apply to each +// module as it passes through the IRTransformLayer. +class MyOptimizationTransform { +public: + MyOptimizationTransform() : PM(std::make_unique()) { + PM->add(createTailCallEliminationPass()); + PM->add(createFunctionInliningPass()); + PM->add(createIndVarSimplifyPass()); + PM->add(createCFGSimplificationPass()); + } + + Expected operator()(ThreadSafeModule TSM, + MaterializationResponsibility &R) { + TSM.withModuleDo([this](Module &M) { + dbgs() << "--- BEFORE OPTIMIZATION ---\n" << M << "\n"; + PM->run(M); + dbgs() << "--- AFTER OPTIMIZATION ---\n" << M << "\n"; + }); + return std::move(TSM); + } + +private: + std::unique_ptr PM; +}; + +int main(int argc, char *argv[]) { + // Initialize LLVM. + InitLLVM X(argc, argv); + + InitializeNativeTarget(); + InitializeNativeTargetAsmPrinter(); + + ExitOnErr.setBanner(std::string(argv[0]) + ": "); + + // (1) Create LLJIT instance. + auto J = ExitOnErr(LLJITBuilder().create()); + + // (2) Install transform to optimize modules when they're materialized. + J->getIRTransformLayer().setTransform(MyOptimizationTransform()); + + // (3) Add modules. + ExitOnErr(J->addIRModule(ExitOnErr(parseExampleModule(MainMod, "MainMod")))); + + // (4) Look up the JIT'd function and call it. + auto EntrySym = ExitOnErr(J->lookup("entry")); + auto *Entry = (int (*)())EntrySym.getAddress(); + + int Result = Entry(); + outs() << "--- Result ---\n" + << "entry() = " << Result << "\n"; + + return 0; +} diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h index ee4ee3437fa6d..475d3f259aefe 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h @@ -13,6 +13,7 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H #define LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H +#include "llvm/ADT/FunctionExtras.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/Layer.h" #include @@ -27,7 +28,7 @@ namespace orc { /// before operating on the module. class IRTransformLayer : public IRLayer { public: - using TransformFunction = std::function( + using TransformFunction = unique_function( ThreadSafeModule, MaterializationResponsibility &R)>; IRTransformLayer(ExecutionSession &ES, IRLayer &BaseLayer, From 9489860fafcfac83fdc55df9c48d31b4b816405b Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Tue, 22 Sep 2020 16:04:37 -0700 Subject: [PATCH 182/234] [ORC][examples] Add missing library dependencies. --- .../OrcV2Examples/LLJITWithOptimizingIRTransform/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/examples/OrcV2Examples/LLJITWithOptimizingIRTransform/CMakeLists.txt b/llvm/examples/OrcV2Examples/LLJITWithOptimizingIRTransform/CMakeLists.txt index 63be55cfa3794..a9cd91ad596ad 100644 --- a/llvm/examples/OrcV2Examples/LLJITWithOptimizingIRTransform/CMakeLists.txt +++ b/llvm/examples/OrcV2Examples/LLJITWithOptimizingIRTransform/CMakeLists.txt @@ -1,8 +1,10 @@ set(LLVM_LINK_COMPONENTS Core ExecutionEngine + IPO IRReader OrcJIT + ScalarOpts Support nativecodegen ) From dfeb5c7c64b758822026c20af1048f28f87b4016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= Date: Thu, 1 Oct 2020 10:25:06 +0200 Subject: [PATCH 183/234] [ORC][examples] Temporarily remove LLJITWithChildProcess until ORC TPC lands This solves a phase ordering problem: OrcV2 remote process support depends on OrcV2 removable code, OrcV2 removable code depends on OrcV1 removal, OrcV1 removal depends on LLJITWithChildProcess migration, and LLJITWithChildProcess migration depends on OrcV2 TargetProcessControl support. --- llvm/examples/OrcV2Examples/CMakeLists.txt | 1 - .../LLJITWithChildProcess/CMakeLists.txt | 12 -- .../LLJITWithChildProcess.cpp | 128 ------------------ .../LLJITWithChildProcess/RemoteJITUtils.h | 121 ----------------- 4 files changed, 262 deletions(-) delete mode 100644 llvm/examples/OrcV2Examples/LLJITWithChildProcess/CMakeLists.txt delete mode 100644 llvm/examples/OrcV2Examples/LLJITWithChildProcess/LLJITWithChildProcess.cpp delete mode 100644 llvm/examples/OrcV2Examples/LLJITWithChildProcess/RemoteJITUtils.h diff --git a/llvm/examples/OrcV2Examples/CMakeLists.txt b/llvm/examples/OrcV2Examples/CMakeLists.txt index 2af3fd90d7176..2b7f9c501beff 100644 --- a/llvm/examples/OrcV2Examples/CMakeLists.txt +++ b/llvm/examples/OrcV2Examples/CMakeLists.txt @@ -1,5 +1,4 @@ add_subdirectory(LLJITDumpObjects) -add_subdirectory(LLJITWithChildProcess) add_subdirectory(LLJITWithCustomObjectLinkingLayer) add_subdirectory(LLJITWithGDBRegistrationListener) add_subdirectory(LLJITWithInitializers) diff --git a/llvm/examples/OrcV2Examples/LLJITWithChildProcess/CMakeLists.txt b/llvm/examples/OrcV2Examples/LLJITWithChildProcess/CMakeLists.txt deleted file mode 100644 index d96bfc0163088..0000000000000 --- a/llvm/examples/OrcV2Examples/LLJITWithChildProcess/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -set(LLVM_LINK_COMPONENTS - Core - ExecutionEngine - IRReader - OrcJIT - Support - nativecodegen - ) - -add_llvm_example(LLJITInChildProcess - LLJITWithChildProcess.cpp - ) diff --git a/llvm/examples/OrcV2Examples/LLJITWithChildProcess/LLJITWithChildProcess.cpp b/llvm/examples/OrcV2Examples/LLJITWithChildProcess/LLJITWithChildProcess.cpp deleted file mode 100644 index 11e125c9cf755..0000000000000 --- a/llvm/examples/OrcV2Examples/LLJITWithChildProcess/LLJITWithChildProcess.cpp +++ /dev/null @@ -1,128 +0,0 @@ -//===--- LLJITWithLazyReexports.cpp - LLJIT example with custom laziness --===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// In this example we will execute JITed code in a child process: -// -// 1. Launch a remote process. -// 2. Create a JITLink-compatible remote memory manager. -// 3. Use LLJITBuilder to create a (greedy) LLJIT instance. -// 4. Add the Add1Example module and execute add1(). -// 5. Terminate the remote target session. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h" -#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h" -#include "llvm/ExecutionEngine/Orc/LLJIT.h" -#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" -#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/InitLLVM.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Support/raw_ostream.h" - -#include "../ExampleModules.h" -#include "RemoteJITUtils.h" - -#include -#include - -#define DEBUG_TYPE "orc" - -using namespace llvm; -using namespace llvm::orc; - -// Executable running in the child process for remote execution. It communicates -// via stdin/stdout pipes. -cl::opt - ChildExecPath("remote-process", cl::Required, - cl::desc("Specify the filename of the process to launch for " - "remote JITing."), - cl::value_desc("filename")); - -int main(int argc, char *argv[]) { - InitLLVM X(argc, argv); - - InitializeNativeTarget(); - InitializeNativeTargetAsmPrinter(); - - cl::ParseCommandLineOptions(argc, argv, "LLJITWithChildProcess"); - - ExitOnError ExitOnErr; - ExitOnErr.setBanner(std::string(argv[0]) + ": "); - - if (!sys::fs::can_execute(ChildExecPath)) { - WithColor::error(errs(), argv[0]) - << "Child executable invalid: '" << ChildExecPath << "'\n"; - return -1; - } - - ExecutionSession ES; - ES.setErrorReporter([&](Error Err) { ExitOnErr(std::move(Err)); }); - - // Launch the remote process and get a channel to it. - pid_t ChildPID; - std::unique_ptr Ch = launchRemote(ChildExecPath, ChildPID); - if (!Ch) { - WithColor::error(errs(), argv[0]) << "Failed to launch remote JIT.\n"; - exit(1); - } - - LLVM_DEBUG({ - dbgs() - << "Launched executable in subprocess " << ChildPID << ":\n" - << ChildExecPath << "\n\n" - << "You may want to attach a debugger now. Press enter to continue.\n"; - fflush(stdin); - getchar(); - }); - - std::unique_ptr Client = - ExitOnErr(remote::OrcRemoteTargetClient::Create(*Ch, ES)); - - // Create a JITLink-compatible remote memory manager. - using MemManager = remote::OrcRemoteTargetClient::RemoteJITLinkMemoryManager; - std::unique_ptr RemoteMM = - ExitOnErr(Client->createRemoteJITLinkMemoryManager()); - - // Our remote target is running on the host system. - auto JTMB = ExitOnErr(JITTargetMachineBuilder::detectHost()); - JTMB.setCodeModel(CodeModel::Small); - - // Create an LLJIT instance with a JITLink ObjectLinkingLayer. - auto J = ExitOnErr( - LLJITBuilder() - .setJITTargetMachineBuilder(std::move(JTMB)) - .setObjectLinkingLayerCreator( - [&](ExecutionSession &ES, - const Triple &TT) -> std::unique_ptr { - return std::make_unique(ES, *RemoteMM); - }) - .create()); - - auto M = ExitOnErr(parseExampleModule(Add1Example, "add1")); - - ExitOnErr(J->addIRModule(std::move(M))); - - // Look up the JIT'd function. - auto Add1Sym = ExitOnErr(J->lookup("add1")); - - // Run in child target. - Expected Result = Client->callIntInt(Add1Sym.getAddress(), 42); - if (Result) - outs() << "add1(42) = " << *Result << "\n"; - else - ES.reportError(Result.takeError()); - - // Signal the remote target that we're done JITing. - ExitOnErr(Client->terminateSession()); - LLVM_DEBUG(dbgs() << "Subprocess terminated\n"); - - return 0; -} diff --git a/llvm/examples/OrcV2Examples/LLJITWithChildProcess/RemoteJITUtils.h b/llvm/examples/OrcV2Examples/LLJITWithChildProcess/RemoteJITUtils.h deleted file mode 100644 index 9e3f1d417b816..0000000000000 --- a/llvm/examples/OrcV2Examples/LLJITWithChildProcess/RemoteJITUtils.h +++ /dev/null @@ -1,121 +0,0 @@ -//===-- RemoteJITUtils.h - Utilities for remote-JITing ----------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Utilities for remote-JITing -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_EXAMPLES_ORCV2EXAMPLES_LLJITWITHCHILDPROCESS_REMOTEJITUTILS_H -#define LLVM_EXAMPLES_ORCV2EXAMPLES_LLJITWITHCHILDPROCESS_REMOTEJITUTILS_H - -#include "llvm/ExecutionEngine/Orc/RPC/RawByteChannel.h" -#include - -#if !defined(_MSC_VER) && !defined(__MINGW32__) -#include -#else -#include -#endif - -/// RPC channel that reads from and writes from file descriptors. -class FDRawChannel final : public llvm::orc::rpc::RawByteChannel { -public: - FDRawChannel(int InFD, int OutFD) : InFD(InFD), OutFD(OutFD) {} - - llvm::Error readBytes(char *Dst, unsigned Size) override { - assert(Dst && "Attempt to read into null."); - ssize_t Completed = 0; - while (Completed < static_cast(Size)) { - ssize_t Read = ::read(InFD, Dst + Completed, Size - Completed); - if (Read <= 0) { - auto ErrNo = errno; - if (ErrNo == EAGAIN || ErrNo == EINTR) - continue; - else - return llvm::errorCodeToError( - std::error_code(errno, std::generic_category())); - } - Completed += Read; - } - return llvm::Error::success(); - } - - llvm::Error appendBytes(const char *Src, unsigned Size) override { - assert(Src && "Attempt to append from null."); - ssize_t Completed = 0; - while (Completed < static_cast(Size)) { - ssize_t Written = ::write(OutFD, Src + Completed, Size - Completed); - if (Written < 0) { - auto ErrNo = errno; - if (ErrNo == EAGAIN || ErrNo == EINTR) - continue; - else - return llvm::errorCodeToError( - std::error_code(errno, std::generic_category())); - } - Completed += Written; - } - return llvm::Error::success(); - } - - llvm::Error send() override { return llvm::Error::success(); } - -private: - int InFD, OutFD; -}; - -// Launch child process and return a channel to it. -std::unique_ptr launchRemote(std::string ExecPath, - pid_t &ChildPID) { - // Create two pipes. - int PipeFD[2][2]; - if (pipe(PipeFD[0]) != 0 || pipe(PipeFD[1]) != 0) - perror("Error creating pipe: "); - - ChildPID = fork(); - - if (ChildPID == 0) { - // In the child... - - // Close the parent ends of the pipes - close(PipeFD[0][1]); - close(PipeFD[1][0]); - - // Execute the child process. - std::unique_ptr ChildPath, ChildIn, ChildOut; - { - ChildPath.reset(new char[ExecPath.size() + 1]); - std::copy(ExecPath.begin(), ExecPath.end(), &ChildPath[0]); - ChildPath[ExecPath.size()] = '\0'; - std::string ChildInStr = llvm::utostr(PipeFD[0][0]); - ChildIn.reset(new char[ChildInStr.size() + 1]); - std::copy(ChildInStr.begin(), ChildInStr.end(), &ChildIn[0]); - ChildIn[ChildInStr.size()] = '\0'; - std::string ChildOutStr = llvm::utostr(PipeFD[1][1]); - ChildOut.reset(new char[ChildOutStr.size() + 1]); - std::copy(ChildOutStr.begin(), ChildOutStr.end(), &ChildOut[0]); - ChildOut[ChildOutStr.size()] = '\0'; - } - - char *const args[] = {&ChildPath[0], &ChildIn[0], &ChildOut[0], nullptr}; - int rc = execv(ExecPath.c_str(), args); - if (rc != 0) - perror("Error executing child process: "); - llvm_unreachable("Error executing child process"); - } - // else we're the parent... - - // Close the child ends of the pipes - close(PipeFD[0][0]); - close(PipeFD[1][1]); - - // Return an RPC channel connected to our end of the pipes. - return std::make_unique(PipeFD[1][0], PipeFD[0][1]); -} - -#endif From 1ff9f719d8cc9680db82bad2929e9ae41ace98a5 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Mon, 5 Oct 2020 21:28:07 -0700 Subject: [PATCH 184/234] [JITLink][ELF] Handle BSS sections, improve some error messages. This patch enables basic BSS section handling, and improves a couple of error messages in the ELF section parsing code. Patch by Christian Schafmeister. Thanks Christian! Differential Revision: https://reviews.llvm.org/D88867 --- llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp | 9 +++++++-- .../JITLink/X86/ELF_x86-64_relocations.s | 11 +++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp index 48bca4502920b..130d7e494c719 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp @@ -355,6 +355,9 @@ class ELFLinkGraphBuilder_x86_64 { if (SecRef.sh_type == ELF::SHT_SYMTAB) // TODO: Dynamic? SymTab = SecRef; + } else { + auto &Section = G->createSection(*Name, Prot); + G->createZeroFillBlock(Section, Size, Address, Alignment, 0); } } @@ -478,7 +481,8 @@ class ELFLinkGraphBuilder_x86_64 { return Name.takeError(); auto Section = G->findSectionByName(*Name); if (!Section) - return make_error("Could not find a section", + return make_error("Could not find a section " + + *Name, llvm::inconvertibleErrorCode()); // we only have one for now auto blocks = Section->blocks(); @@ -525,7 +529,8 @@ class ELFLinkGraphBuilder_x86_64 { auto JitSection = G->findSectionByName(*sectName); if (!JitSection) return make_error( - "Could not find a section", llvm::inconvertibleErrorCode()); + "Could not find the JitSection " + *sectName, + llvm::inconvertibleErrorCode()); auto bs = JitSection->blocks(); if (bs.empty()) return make_error( diff --git a/llvm/test/ExecutionEngine/JITLink/X86/ELF_x86-64_relocations.s b/llvm/test/ExecutionEngine/JITLink/X86/ELF_x86-64_relocations.s index 0eee9a449cea9..efd438f3d2a89 100644 --- a/llvm/test/ExecutionEngine/JITLink/X86/ELF_x86-64_relocations.s +++ b/llvm/test/ExecutionEngine/JITLink/X86/ELF_x86-64_relocations.s @@ -34,6 +34,17 @@ named_data: .long 42 .size named_data, 4 +# Test BSS / zero-fill section handling. +# llvm-jitlink: *{4}bss_variable = 0 + + .type bss_variable,@object + .bss + .globl bss_variable + .p2align 2 +bss_variable: + .long 0 + .size bss_variable, 4 + .ident "clang version 10.0.0-4ubuntu1 " .section ".note.GNU-stack","",@progbits .addrsig From c963a10db7d1375ca72656817fd6be174c0af95a Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Tue, 6 Oct 2020 15:03:13 -0700 Subject: [PATCH 185/234] [RuntimeDyld][COFF] Report fatal error on error, rather than emiting diagnostic. Report a fatal error if an IMAGE_REL_AMD64_ADDR32NB cannot be applied due to an out-of-range target. Previously we emitted a diagnostic to llvm::errs and continued. Patch by Dale Martin. Thanks Dale! --- .../RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h index ebe3ca33d3089..9df3e2e3c3bf1 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h @@ -113,11 +113,10 @@ class RuntimeDyldCOFFX86_64 : public RuntimeDyldCOFF { // The MemoryManager can make sure this is always true by forcing the // memory layout to be: CodeSection < ReadOnlySection < ReadWriteSection. const uint64_t ImageBase = getImageBase(); - if (Value < ImageBase || ((Value - ImageBase) > UINT32_MAX)) { - llvm::errs() << "IMAGE_REL_AMD64_ADDR32NB relocation requires an" - << "ordered section layout.\n"; - write32BitOffset(Target, 0, 0); - } else { + if (Value < ImageBase || ((Value - ImageBase) > UINT32_MAX)) + report_fatal_error("IMAGE_REL_AMD64_ADDR32NB relocation requires an " + "ordered section layout"); + else { write32BitOffset(Target, RE.Addend, Value - ImageBase); } break; From 5458c7c9eaba0dbeec653f8f15564538993f737e Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Mon, 7 Sep 2020 21:21:28 -0700 Subject: [PATCH 186/234] [ORC] Remove OrcV1 APIs. This removes all legacy layers, legacy utilities, the old Orc C bindings, OrcMCJITReplacement, and OrcMCJITReplacement regression tests. ExecutionEngine and MCJIT are not affected by this change. --- llvm/include/llvm-c/OrcBindings.h | 169 ----- .../llvm/ExecutionEngine/ExecutionEngine.h | 21 - .../Orc/CompileOnDemandLayer.h | 631 ------------------ llvm/include/llvm/ExecutionEngine/Orc/Core.h | 29 - .../llvm/ExecutionEngine/Orc/ExecutionUtils.h | 89 --- .../ExecutionEngine/Orc/GlobalMappingLayer.h | 110 --- .../llvm/ExecutionEngine/Orc/IRCompileLayer.h | 93 --- .../ExecutionEngine/Orc/IRTransformLayer.h | 74 -- .../llvm/ExecutionEngine/Orc/LambdaResolver.h | 84 --- .../ExecutionEngine/Orc/LazyEmittingLayer.h | 267 -------- .../include/llvm/ExecutionEngine/Orc/Legacy.h | 211 ------ .../llvm/ExecutionEngine/Orc/NullResolver.h | 43 -- .../Orc/ObjectTransformLayer.h | 82 --- .../Orc/RTDyldObjectLinkingLayer.h | 351 ---------- .../ExecutionEngine/Orc/RemoteObjectLayer.h | 564 ---------------- llvm/lib/ExecutionEngine/ExecutionEngine.cpp | 15 +- llvm/lib/ExecutionEngine/Orc/CMakeLists.txt | 4 - llvm/lib/ExecutionEngine/Orc/Core.cpp | 210 ------ llvm/lib/ExecutionEngine/Orc/Legacy.cpp | 68 -- llvm/lib/ExecutionEngine/Orc/NullResolver.cpp | 37 - llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp | 158 ----- .../ExecutionEngine/Orc/OrcCBindingsStack.h | 534 --------------- .../Orc/OrcMCJITReplacement.cpp | 138 ---- .../ExecutionEngine/Orc/OrcMCJITReplacement.h | 502 -------------- .../Orc/RTDyldObjectLinkingLayer.cpp | 9 - .../OrcMCJIT/2002-12-16-ArgTest.ll | 37 - .../OrcMCJIT/2003-01-04-ArgumentBug.ll | 13 - .../OrcMCJIT/2003-01-04-LoopTest.ll | 20 - .../OrcMCJIT/2003-01-04-PhiTest.ll | 12 - .../OrcMCJIT/2003-01-09-SARTest.ll | 11 - .../OrcMCJIT/2003-01-10-FUCOM.ll | 10 - .../OrcMCJIT/2003-01-15-AlignmentTest.ll | 17 - .../OrcMCJIT/2003-05-06-LivenessClobber.ll | 19 - .../OrcMCJIT/2003-05-07-ArgumentTest.ll | 11 - .../OrcMCJIT/2003-05-11-PHIRegAllocBug.ll | 13 - .../OrcMCJIT/2003-06-04-bzip2-bug.ll | 17 - .../OrcMCJIT/2003-06-05-PHIBug.ll | 15 - .../OrcMCJIT/2003-08-15-AllocaAssertion.ll | 11 - .../OrcMCJIT/2003-08-21-EnvironmentTest.ll | 21 - .../2003-08-23-RegisterAllocatePhysReg.ll | 34 - ...8-PHINode-ConstantExpr-CondCode-Failure.ll | 23 - .../OrcMCJIT/2005-12-02-TailCallBug.ll | 22 - .../OrcMCJIT/2007-12-10-APIntLoadStore.ll | 19 - .../OrcMCJIT/2008-06-05-APInt-OverAShr.ll | 60 -- .../OrcMCJIT/2013-04-04-RelocAddend.ll | 25 - .../OrcMCJIT/Inputs/cross-module-b.ll | 7 - .../OrcMCJIT/Inputs/multi-module-b.ll | 7 - .../OrcMCJIT/Inputs/multi-module-c.ll | 4 - .../OrcMCJIT/Inputs/multi-module-eh-b.ll | 30 - .../OrcMCJIT/Inputs/weak-function-2.ll | 9 - .../OrcMCJIT/cross-module-a.ll | 13 - .../OrcMCJIT/cross-module-sm-pic-a.ll | 14 - .../ExecutionEngine/OrcMCJIT/eh-lg-pic.ll | 39 -- llvm/test/ExecutionEngine/OrcMCJIT/eh.ll | 33 - .../ExecutionEngine/OrcMCJIT/fpbitcast.ll | 21 - llvm/test/ExecutionEngine/OrcMCJIT/hello.ll | 11 - llvm/test/ExecutionEngine/OrcMCJIT/hello2.ll | 17 - .../ExecutionEngine/OrcMCJIT/lit.local.cfg | 27 - .../ExecutionEngine/OrcMCJIT/load-object-a.ll | 24 - .../OrcMCJIT/multi-module-a.ll | 9 - .../OrcMCJIT/multi-module-eh-a.ll | 36 - .../OrcMCJIT/multi-module-sm-pic-a.ll | 10 - .../OrcMCJIT/non-extern-addend.ll | 21 - llvm/test/ExecutionEngine/OrcMCJIT/pr13727.ll | 88 --- llvm/test/ExecutionEngine/OrcMCJIT/pr32650.ll | 28 - .../OrcMCJIT/remote/Inputs/cross-module-b.ll | 7 - .../OrcMCJIT/remote/Inputs/multi-module-b.ll | 7 - .../OrcMCJIT/remote/Inputs/multi-module-c.ll | 4 - .../OrcMCJIT/remote/cross-module-a.ll | 15 - .../ExecutionEngine/OrcMCJIT/remote/eh.ll | 35 - .../OrcMCJIT/remote/lit.local.cfg | 8 - .../OrcMCJIT/remote/multi-module-a.ll | 12 - .../OrcMCJIT/remote/simpletest-remote.ll | 13 - .../OrcMCJIT/remote/stubs-remote.ll | 38 -- .../OrcMCJIT/remote/stubs-sm-pic.ll | 37 - .../remote/test-common-symbols-remote.ll | 91 --- .../OrcMCJIT/remote/test-data-align-remote.ll | 18 - .../test-fp-no-external-funcs-remote.ll | 23 - .../remote/test-global-init-nonzero-remote.ll | 37 - .../remote/test-global-init-nonzero-sm-pic.ll | 38 -- .../OrcMCJIT/remote/test-ptr-reloc-remote.ll | 18 - .../OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll | 20 - .../ExecutionEngine/OrcMCJIT/simplesttest.ll | 6 - .../ExecutionEngine/OrcMCJIT/simpletest.ll | 11 - .../ExecutionEngine/OrcMCJIT/stubs-sm-pic.ll | 36 - llvm/test/ExecutionEngine/OrcMCJIT/stubs.ll | 35 - .../ExecutionEngine/OrcMCJIT/test-arith.ll | 34 - .../ExecutionEngine/OrcMCJIT/test-branch.ll | 12 - .../OrcMCJIT/test-call-no-external-funcs.ll | 14 - .../ExecutionEngine/OrcMCJIT/test-call.ll | 21 - .../ExecutionEngine/OrcMCJIT/test-cast.ll | 109 --- .../OrcMCJIT/test-common-symbols-alignment.ll | 32 - .../OrcMCJIT/test-common-symbols.ll | 88 --- .../OrcMCJIT/test-constantexpr.ll | 12 - .../OrcMCJIT/test-data-align.ll | 15 - .../OrcMCJIT/test-fp-no-external-funcs.ll | 21 - llvm/test/ExecutionEngine/OrcMCJIT/test-fp.ll | 23 - .../OrcMCJIT/test-global-ctors.ll | 22 - .../test-global-init-nonzero-sm-pic.ll | 35 - .../OrcMCJIT/test-global-init-nonzero.ll | 34 - .../ExecutionEngine/OrcMCJIT/test-global.ll | 34 - .../OrcMCJIT/test-loadstore.ll | 31 - .../ExecutionEngine/OrcMCJIT/test-local.ll | 34 - .../ExecutionEngine/OrcMCJIT/test-logical.ll | 18 - .../ExecutionEngine/OrcMCJIT/test-loop.ll | 14 - .../test/ExecutionEngine/OrcMCJIT/test-phi.ll | 34 - .../OrcMCJIT/test-ptr-reloc-sm-pic.ll | 17 - .../OrcMCJIT/test-ptr-reloc.ll | 16 - .../test/ExecutionEngine/OrcMCJIT/test-ret.ll | 46 -- .../ExecutionEngine/OrcMCJIT/test-return.ll | 8 - .../OrcMCJIT/test-setcond-fp.ll | 24 - .../OrcMCJIT/test-setcond-int.ll | 69 -- .../ExecutionEngine/OrcMCJIT/test-shift.ll | 32 - .../ExecutionEngine/OrcMCJIT/weak-function.ll | 29 - llvm/tools/lli/RemoteJITUtils.h | 21 + llvm/tools/lli/lli.cpp | 17 +- llvm/tools/llvm-c-test/include-all.c | 2 +- .../ExecutionEngine/Orc/CMakeLists.txt | 8 - .../ExecutionEngine/Orc/CoreAPIsTest.cpp | 38 -- .../Orc/GlobalMappingLayerTest.cpp | 62 -- .../Orc/LazyEmittingLayerTest.cpp | 31 - .../Orc/LegacyAPIInteropTest.cpp | 126 ---- .../Orc/LegacyCompileOnDemandLayerTest.cpp | 86 --- .../LegacyRTDyldObjectLinkingLayerTest.cpp | 295 -------- .../Orc/ObjectTransformLayerTest.cpp | 321 --------- .../ExecutionEngine/Orc/OrcCAPITest.cpp | 219 ------ .../Orc/RTDyldObjectLinkingLayerTest.cpp | 3 - .../Orc/RemoteObjectLayerTest.cpp | 609 ----------------- 128 files changed, 26 insertions(+), 8550 deletions(-) delete mode 100644 llvm/include/llvm-c/OrcBindings.h delete mode 100644 llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h delete mode 100644 llvm/include/llvm/ExecutionEngine/Orc/LambdaResolver.h delete mode 100644 llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h delete mode 100644 llvm/include/llvm/ExecutionEngine/Orc/Legacy.h delete mode 100644 llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h delete mode 100644 llvm/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h delete mode 100644 llvm/lib/ExecutionEngine/Orc/Legacy.cpp delete mode 100644 llvm/lib/ExecutionEngine/Orc/NullResolver.cpp delete mode 100644 llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp delete mode 100644 llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h delete mode 100644 llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp delete mode 100644 llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2002-12-16-ArgTest.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2003-01-04-ArgumentBug.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2003-01-04-LoopTest.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2003-01-04-PhiTest.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2003-01-09-SARTest.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2003-01-10-FUCOM.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2003-01-15-AlignmentTest.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2003-05-06-LivenessClobber.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2003-05-07-ArgumentTest.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2003-05-11-PHIRegAllocBug.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2003-06-04-bzip2-bug.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2003-06-05-PHIBug.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2003-08-15-AllocaAssertion.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2003-08-21-EnvironmentTest.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2003-08-23-RegisterAllocatePhysReg.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2003-10-18-PHINode-ConstantExpr-CondCode-Failure.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2005-12-02-TailCallBug.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2007-12-10-APIntLoadStore.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2008-06-05-APInt-OverAShr.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/2013-04-04-RelocAddend.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/Inputs/cross-module-b.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/Inputs/multi-module-b.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/Inputs/multi-module-c.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/Inputs/multi-module-eh-b.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/Inputs/weak-function-2.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/cross-module-a.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/cross-module-sm-pic-a.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/eh-lg-pic.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/eh.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/fpbitcast.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/hello.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/hello2.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/lit.local.cfg delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/load-object-a.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/multi-module-a.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/multi-module-eh-a.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/multi-module-sm-pic-a.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/non-extern-addend.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/pr13727.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/pr32650.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/Inputs/cross-module-b.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/Inputs/multi-module-b.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/Inputs/multi-module-c.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/cross-module-a.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/eh.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/lit.local.cfg delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/multi-module-a.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/simpletest-remote.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/stubs-remote.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/stubs-sm-pic.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/test-common-symbols-remote.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/test-data-align-remote.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/test-fp-no-external-funcs-remote.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/test-global-init-nonzero-remote.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/test-global-init-nonzero-sm-pic.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/test-ptr-reloc-remote.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/simplesttest.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/simpletest.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/stubs-sm-pic.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/stubs.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-arith.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-branch.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-call-no-external-funcs.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-call.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-cast.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-common-symbols-alignment.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-common-symbols.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-constantexpr.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-data-align.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-fp-no-external-funcs.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-fp.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-global-ctors.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-global-init-nonzero-sm-pic.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-global-init-nonzero.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-global.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-loadstore.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-local.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-logical.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-loop.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-phi.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-ptr-reloc-sm-pic.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-ptr-reloc.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-ret.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-return.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-setcond-fp.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-setcond-int.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/test-shift.ll delete mode 100644 llvm/test/ExecutionEngine/OrcMCJIT/weak-function.ll delete mode 100644 llvm/unittests/ExecutionEngine/Orc/GlobalMappingLayerTest.cpp delete mode 100644 llvm/unittests/ExecutionEngine/Orc/LazyEmittingLayerTest.cpp delete mode 100644 llvm/unittests/ExecutionEngine/Orc/LegacyAPIInteropTest.cpp delete mode 100644 llvm/unittests/ExecutionEngine/Orc/LegacyCompileOnDemandLayerTest.cpp delete mode 100644 llvm/unittests/ExecutionEngine/Orc/LegacyRTDyldObjectLinkingLayerTest.cpp delete mode 100644 llvm/unittests/ExecutionEngine/Orc/ObjectTransformLayerTest.cpp delete mode 100644 llvm/unittests/ExecutionEngine/Orc/OrcCAPITest.cpp delete mode 100644 llvm/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp diff --git a/llvm/include/llvm-c/OrcBindings.h b/llvm/include/llvm-c/OrcBindings.h deleted file mode 100644 index 11cdade7c26fc..0000000000000 --- a/llvm/include/llvm-c/OrcBindings.h +++ /dev/null @@ -1,169 +0,0 @@ -/*===----------- llvm-c/OrcBindings.h - Orc Lib C Iface ---------*- C++ -*-===*\ -|* *| -|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| -|* Exceptions. *| -|* See https://llvm.org/LICENSE.txt for license information. *| -|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| -|* *| -|*===----------------------------------------------------------------------===*| -|* *| -|* This header declares the C interface to libLLVMOrcJIT.a, which implements *| -|* JIT compilation of LLVM IR. *| -|* *| -|* Many exotic languages can interoperate with C code but have a harder time *| -|* with C++ due to name mangling. So in addition to C, this interface enables *| -|* tools written in such languages. *| -|* *| -|* Note: This interface is experimental. It is *NOT* stable, and may be *| -|* changed without warning. *| -|* *| -\*===----------------------------------------------------------------------===*/ - -#ifndef LLVM_C_ORCBINDINGS_H -#define LLVM_C_ORCBINDINGS_H - -#include "llvm-c/Error.h" -#include "llvm-c/ExternC.h" -#include "llvm-c/Object.h" -#include "llvm-c/TargetMachine.h" - -LLVM_C_EXTERN_C_BEGIN - -typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef; -typedef uint64_t LLVMOrcModuleHandle; -typedef uint64_t LLVMOrcTargetAddress; -typedef uint64_t (*LLVMOrcSymbolResolverFn)(const char *Name, void *LookupCtx); -typedef uint64_t (*LLVMOrcLazyCompileCallbackFn)(LLVMOrcJITStackRef JITStack, - void *CallbackCtx); - -/** - * Create an ORC JIT stack. - * - * The client owns the resulting stack, and must call OrcDisposeInstance(...) - * to destroy it and free its memory. The JIT stack will take ownership of the - * TargetMachine, which will be destroyed when the stack is destroyed. The - * client should not attempt to dispose of the Target Machine, or it will result - * in a double-free. - */ -LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM); - -/** - * Get the error message for the most recent error (if any). - * - * This message is owned by the ORC JIT Stack and will be freed when the stack - * is disposed of by LLVMOrcDisposeInstance. - */ -const char *LLVMOrcGetErrorMsg(LLVMOrcJITStackRef JITStack); - -/** - * Mangle the given symbol. - * Memory will be allocated for MangledSymbol to hold the result. The client - */ -void LLVMOrcGetMangledSymbol(LLVMOrcJITStackRef JITStack, char **MangledSymbol, - const char *Symbol); - -/** - * Dispose of a mangled symbol. - */ -void LLVMOrcDisposeMangledSymbol(char *MangledSymbol); - -/** - * Create a lazy compile callback. - */ -LLVMErrorRef LLVMOrcCreateLazyCompileCallback( - LLVMOrcJITStackRef JITStack, LLVMOrcTargetAddress *RetAddr, - LLVMOrcLazyCompileCallbackFn Callback, void *CallbackCtx); - -/** - * Create a named indirect call stub. - */ -LLVMErrorRef LLVMOrcCreateIndirectStub(LLVMOrcJITStackRef JITStack, - const char *StubName, - LLVMOrcTargetAddress InitAddr); - -/** - * Set the pointer for the given indirect stub. - */ -LLVMErrorRef LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack, - const char *StubName, - LLVMOrcTargetAddress NewAddr); - -/** - * Add module to be eagerly compiled. - */ -LLVMErrorRef LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle *RetHandle, - LLVMModuleRef Mod, - LLVMOrcSymbolResolverFn SymbolResolver, - void *SymbolResolverCtx); - -/** - * Add module to be lazily compiled one function at a time. - */ -LLVMErrorRef LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle *RetHandle, - LLVMModuleRef Mod, - LLVMOrcSymbolResolverFn SymbolResolver, - void *SymbolResolverCtx); - -/** - * Add an object file. - * - * This method takes ownership of the given memory buffer and attempts to add - * it to the JIT as an object file. - * Clients should *not* dispose of the 'Obj' argument: the JIT will manage it - * from this call onwards. - */ -LLVMErrorRef LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle *RetHandle, - LLVMMemoryBufferRef Obj, - LLVMOrcSymbolResolverFn SymbolResolver, - void *SymbolResolverCtx); - -/** - * Remove a module set from the JIT. - * - * This works for all modules that can be added via OrcAdd*, including object - * files. - */ -LLVMErrorRef LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle H); - -/** - * Get symbol address from JIT instance. - */ -LLVMErrorRef LLVMOrcGetSymbolAddress(LLVMOrcJITStackRef JITStack, - LLVMOrcTargetAddress *RetAddr, - const char *SymbolName); - -/** - * Get symbol address from JIT instance, searching only the specified - * handle. - */ -LLVMErrorRef LLVMOrcGetSymbolAddressIn(LLVMOrcJITStackRef JITStack, - LLVMOrcTargetAddress *RetAddr, - LLVMOrcModuleHandle H, - const char *SymbolName); - -/** - * Dispose of an ORC JIT stack. - */ -LLVMErrorRef LLVMOrcDisposeInstance(LLVMOrcJITStackRef JITStack); - -/** - * Register a JIT Event Listener. - * - * A NULL listener is ignored. - */ -void LLVMOrcRegisterJITEventListener(LLVMOrcJITStackRef JITStack, LLVMJITEventListenerRef L); - -/** - * Unegister a JIT Event Listener. - * - * A NULL listener is ignored. - */ -void LLVMOrcUnregisterJITEventListener(LLVMOrcJITStackRef JITStack, LLVMJITEventListenerRef L); - -LLVM_C_EXTERN_C_END - -#endif /* LLVM_C_ORCBINDINGS_H */ diff --git a/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h b/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h index 2562da7cf60b4..2e386518f0bfa 100644 --- a/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -142,11 +142,6 @@ class ExecutionEngine { std::shared_ptr SR, std::unique_ptr TM); - static ExecutionEngine *(*OrcMCJITReplacementCtor)( - std::string *ErrorStr, std::shared_ptr MM, - std::shared_ptr SR, - std::unique_ptr TM); - static ExecutionEngine *(*InterpCtor)(std::unique_ptr M, std::string *ErrorStr); @@ -552,7 +547,6 @@ class EngineBuilder { std::string MCPU; SmallVector MAttrs; bool VerifyModules; - bool UseOrcMCJITReplacement; bool EmulatedTLS = true; public: @@ -648,17 +642,6 @@ class EngineBuilder { return *this; } - // Use OrcMCJITReplacement instead of MCJIT. Off by default. - LLVM_ATTRIBUTE_DEPRECATED( - inline void setUseOrcMCJITReplacement(bool UseOrcMCJITReplacement), - "ORCv1 utilities (including OrcMCJITReplacement) are deprecated. Please " - "use ORCv2/LLJIT instead (see docs/ORCv2.rst)"); - - void setUseOrcMCJITReplacement(ORCv1DeprecationAcknowledgement, - bool UseOrcMCJITReplacement) { - this->UseOrcMCJITReplacement = UseOrcMCJITReplacement; - } - void setEmulatedTLS(bool EmulatedTLS) { this->EmulatedTLS = EmulatedTLS; } @@ -679,10 +662,6 @@ class EngineBuilder { ExecutionEngine *create(TargetMachine *TM); }; -void EngineBuilder::setUseOrcMCJITReplacement(bool UseOrcMCJITReplacement) { - this->UseOrcMCJITReplacement = UseOrcMCJITReplacement; -} - // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionEngine, LLVMExecutionEngineRef) diff --git a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 3a2f8b54ad22b..67aa09b2f1a74 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -20,10 +20,8 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h" -#include "llvm/ExecutionEngine/Orc/LambdaResolver.h" #include "llvm/ExecutionEngine/Orc/Layer.h" #include "llvm/ExecutionEngine/Orc/LazyReexports.h" -#include "llvm/ExecutionEngine/Orc/Legacy.h" #include "llvm/ExecutionEngine/Orc/OrcError.h" #include "llvm/ExecutionEngine/Orc/Speculation.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" @@ -136,635 +134,6 @@ class CompileOnDemandLayer : public IRLayer { ImplSymbolMap *AliaseeImpls = nullptr; }; -/// Compile-on-demand layer. -/// -/// When a module is added to this layer a stub is created for each of its -/// function definitions. The stubs and other global values are immediately -/// added to the layer below. When a stub is called it triggers the extraction -/// of the function body from the original module. The extracted body is then -/// compiled and executed. -template -class LegacyCompileOnDemandLayer { -private: - template - class LambdaMaterializer final : public ValueMaterializer { - public: - LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {} - - Value *materialize(Value *V) final { return M(V); } - - private: - MaterializerFtor M; - }; - - template - LambdaMaterializer - createLambdaMaterializer(MaterializerFtor M) { - return LambdaMaterializer(std::move(M)); - } - - // Provide type-erasure for the Modules and MemoryManagers. - template - class ResourceOwner { - public: - ResourceOwner() = default; - ResourceOwner(const ResourceOwner &) = delete; - ResourceOwner &operator=(const ResourceOwner &) = delete; - virtual ~ResourceOwner() = default; - - virtual ResourceT& getResource() const = 0; - }; - - template - class ResourceOwnerImpl : public ResourceOwner { - public: - ResourceOwnerImpl(ResourcePtrT ResourcePtr) - : ResourcePtr(std::move(ResourcePtr)) {} - - ResourceT& getResource() const override { return *ResourcePtr; } - - private: - ResourcePtrT ResourcePtr; - }; - - template - std::unique_ptr> - wrapOwnership(ResourcePtrT ResourcePtr) { - using RO = ResourceOwnerImpl; - return std::make_unique(std::move(ResourcePtr)); - } - - struct LogicalDylib { - struct SourceModuleEntry { - std::unique_ptr SourceMod; - std::set StubsToClone; - }; - - using SourceModulesList = std::vector; - using SourceModuleHandle = typename SourceModulesList::size_type; - - LogicalDylib() = default; - - LogicalDylib(VModuleKey K, std::shared_ptr BackingResolver, - std::unique_ptr StubsMgr) - : K(std::move(K)), BackingResolver(std::move(BackingResolver)), - StubsMgr(std::move(StubsMgr)) {} - - SourceModuleHandle addSourceModule(std::unique_ptr M) { - SourceModuleHandle H = SourceModules.size(); - SourceModules.push_back(SourceModuleEntry()); - SourceModules.back().SourceMod = std::move(M); - return H; - } - - Module& getSourceModule(SourceModuleHandle H) { - return *SourceModules[H].SourceMod; - } - - std::set& getStubsToClone(SourceModuleHandle H) { - return SourceModules[H].StubsToClone; - } - - JITSymbol findSymbol(BaseLayerT &BaseLayer, const std::string &Name, - bool ExportedSymbolsOnly) { - if (auto Sym = StubsMgr->findStub(Name, ExportedSymbolsOnly)) - return Sym; - for (auto BLK : BaseLayerVModuleKeys) - if (auto Sym = BaseLayer.findSymbolIn(BLK, Name, ExportedSymbolsOnly)) - return Sym; - else if (auto Err = Sym.takeError()) - return std::move(Err); - return nullptr; - } - - Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) { - for (auto &BLK : BaseLayerVModuleKeys) - if (auto Err = BaseLayer.removeModule(BLK)) - return Err; - return Error::success(); - } - - VModuleKey K; - std::shared_ptr BackingResolver; - std::unique_ptr StubsMgr; - SymbolLinkagePromoter PromoteSymbols; - SourceModulesList SourceModules; - std::vector BaseLayerVModuleKeys; - }; - -public: - - /// Module partitioning functor. - using PartitioningFtor = std::function(Function&)>; - - /// Builder for IndirectStubsManagers. - using IndirectStubsManagerBuilderT = - std::function()>; - - using SymbolResolverGetter = - std::function(VModuleKey K)>; - - using SymbolResolverSetter = - std::function R)>; - - /// Construct a compile-on-demand layer instance. - LLVM_ATTRIBUTE_DEPRECATED( - LegacyCompileOnDemandLayer( - ExecutionSession &ES, BaseLayerT &BaseLayer, - SymbolResolverGetter GetSymbolResolver, - SymbolResolverSetter SetSymbolResolver, PartitioningFtor Partition, - CompileCallbackMgrT &CallbackMgr, - IndirectStubsManagerBuilderT CreateIndirectStubsManager, - bool CloneStubsIntoPartitions = true), - "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please " - "use " - "the ORCv2 LegacyCompileOnDemandLayer instead"); - - /// Legacy layer constructor with deprecation acknowledgement. - LegacyCompileOnDemandLayer( - ORCv1DeprecationAcknowledgement, ExecutionSession &ES, - BaseLayerT &BaseLayer, SymbolResolverGetter GetSymbolResolver, - SymbolResolverSetter SetSymbolResolver, PartitioningFtor Partition, - CompileCallbackMgrT &CallbackMgr, - IndirectStubsManagerBuilderT CreateIndirectStubsManager, - bool CloneStubsIntoPartitions = true) - : ES(ES), BaseLayer(BaseLayer), - GetSymbolResolver(std::move(GetSymbolResolver)), - SetSymbolResolver(std::move(SetSymbolResolver)), - Partition(std::move(Partition)), CompileCallbackMgr(CallbackMgr), - CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)), - CloneStubsIntoPartitions(CloneStubsIntoPartitions) {} - - ~LegacyCompileOnDemandLayer() { - // FIXME: Report error on log. - while (!LogicalDylibs.empty()) - consumeError(removeModule(LogicalDylibs.begin()->first)); - } - - /// Add a module to the compile-on-demand layer. - Error addModule(VModuleKey K, std::unique_ptr M) { - - assert(!LogicalDylibs.count(K) && "VModuleKey K already in use"); - auto I = LogicalDylibs.insert( - LogicalDylibs.end(), - std::make_pair(K, LogicalDylib(K, GetSymbolResolver(K), - CreateIndirectStubsManager()))); - - return addLogicalModule(I->second, std::move(M)); - } - - /// Add extra modules to an existing logical module. - Error addExtraModule(VModuleKey K, std::unique_ptr M) { - return addLogicalModule(LogicalDylibs[K], std::move(M)); - } - - /// Remove the module represented by the given key. - /// - /// This will remove all modules in the layers below that were derived from - /// the module represented by K. - Error removeModule(VModuleKey K) { - auto I = LogicalDylibs.find(K); - assert(I != LogicalDylibs.end() && "VModuleKey K not valid here"); - auto Err = I->second.removeModulesFromBaseLayer(BaseLayer); - LogicalDylibs.erase(I); - return Err; - } - - /// Search for the given named symbol. - /// @param Name The name of the symbol to search for. - /// @param ExportedSymbolsOnly If true, search only for exported symbols. - /// @return A handle for the given named symbol, if it exists. - JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) { - for (auto &KV : LogicalDylibs) { - if (auto Sym = KV.second.StubsMgr->findStub(Name, ExportedSymbolsOnly)) - return Sym; - if (auto Sym = - findSymbolIn(KV.first, std::string(Name), ExportedSymbolsOnly)) - return Sym; - else if (auto Err = Sym.takeError()) - return std::move(Err); - } - return BaseLayer.findSymbol(std::string(Name), ExportedSymbolsOnly); - } - - /// Get the address of a symbol provided by this layer, or some layer - /// below this one. - JITSymbol findSymbolIn(VModuleKey K, const std::string &Name, - bool ExportedSymbolsOnly) { - assert(LogicalDylibs.count(K) && "VModuleKey K is not valid here"); - return LogicalDylibs[K].findSymbol(BaseLayer, Name, ExportedSymbolsOnly); - } - - /// Update the stub for the given function to point at FnBodyAddr. - /// This can be used to support re-optimization. - /// @return true if the function exists and the stub is updated, false - /// otherwise. - // - // FIXME: We should track and free associated resources (unused compile - // callbacks, uncompiled IR, and no-longer-needed/reachable function - // implementations). - Error updatePointer(std::string FuncName, JITTargetAddress FnBodyAddr) { - //Find out which logical dylib contains our symbol - auto LDI = LogicalDylibs.begin(); - for (auto LDE = LogicalDylibs.end(); LDI != LDE; ++LDI) { - if (auto LMResources = - LDI->getLogicalModuleResourcesForSymbol(FuncName, false)) { - Module &SrcM = LMResources->SourceModule->getResource(); - std::string CalledFnName = mangle(FuncName, SrcM.getDataLayout()); - if (auto Err = LMResources->StubsMgr->updatePointer(CalledFnName, - FnBodyAddr)) - return Err; - return Error::success(); - } - } - return make_error(FuncName); - } - -private: - Error addLogicalModule(LogicalDylib &LD, std::unique_ptr SrcMPtr) { - - // Rename anonymous globals and promote linkage to ensure that everything - // will resolve properly after we partition SrcM. - LD.PromoteSymbols(*SrcMPtr); - - // Create a logical module handle for SrcM within the logical dylib. - Module &SrcM = *SrcMPtr; - auto LMId = LD.addSourceModule(std::move(SrcMPtr)); - - // Create stub functions. - const DataLayout &DL = SrcM.getDataLayout(); - - typename IndirectStubsMgrT::StubInitsMap StubInits; - for (auto &F : SrcM) { - // Skip declarations. - if (F.isDeclaration()) - continue; - - // Skip weak functions for which we already have definitions. - auto MangledName = mangle(F.getName(), DL); - if (F.hasWeakLinkage() || F.hasLinkOnceLinkage()) { - if (auto Sym = LD.findSymbol(BaseLayer, MangledName, false)) - continue; - else if (auto Err = Sym.takeError()) - return Err; - } - - // Record all functions defined by this module. - if (CloneStubsIntoPartitions) - LD.getStubsToClone(LMId).insert(&F); - - // Create a callback, associate it with the stub for the function, - // and set the compile action to compile the partition containing the - // function. - auto CompileAction = [this, &LD, LMId, &F]() -> JITTargetAddress { - if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F)) - return *FnImplAddrOrErr; - else { - // FIXME: Report error, return to 'abort' or something similar. - consumeError(FnImplAddrOrErr.takeError()); - return 0; - } - }; - if (auto CCAddr = - CompileCallbackMgr.getCompileCallback(std::move(CompileAction))) - StubInits[MangledName] = - std::make_pair(*CCAddr, JITSymbolFlags::fromGlobalValue(F)); - else - return CCAddr.takeError(); - } - - if (auto Err = LD.StubsMgr->createStubs(StubInits)) - return Err; - - // If this module doesn't contain any globals, aliases, or module flags then - // we can bail out early and avoid the overhead of creating and managing an - // empty globals module. - if (SrcM.global_empty() && SrcM.alias_empty() && - !SrcM.getModuleFlagsMetadata()) - return Error::success(); - - // Create the GlobalValues module. - auto GVsM = std::make_unique((SrcM.getName() + ".globals").str(), - SrcM.getContext()); - GVsM->setDataLayout(DL); - - ValueToValueMapTy VMap; - - // Clone global variable decls. - for (auto &GV : SrcM.globals()) - if (!GV.isDeclaration() && !VMap.count(&GV)) - cloneGlobalVariableDecl(*GVsM, GV, &VMap); - - // And the aliases. - for (auto &A : SrcM.aliases()) - if (!VMap.count(&A)) - cloneGlobalAliasDecl(*GVsM, A, VMap); - - // Clone the module flags. - cloneModuleFlagsMetadata(*GVsM, SrcM, VMap); - - // Now we need to clone the GV and alias initializers. - - // Initializers may refer to functions declared (but not defined) in this - // module. Build a materializer to clone decls on demand. - auto Materializer = createLambdaMaterializer( - [&LD, &GVsM](Value *V) -> Value* { - if (auto *F = dyn_cast(V)) { - // Decls in the original module just get cloned. - if (F->isDeclaration()) - return cloneFunctionDecl(*GVsM, *F); - - // Definitions in the original module (which we have emitted stubs - // for at this point) get turned into a constant alias to the stub - // instead. - const DataLayout &DL = GVsM->getDataLayout(); - std::string FName = mangle(F->getName(), DL); - unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType()); - JITTargetAddress StubAddr = - LD.StubsMgr->findStub(FName, false).getAddress(); - - ConstantInt *StubAddrCI = - ConstantInt::get(GVsM->getContext(), APInt(PtrBitWidth, StubAddr)); - Constant *Init = ConstantExpr::getCast(Instruction::IntToPtr, - StubAddrCI, F->getType()); - return GlobalAlias::create(F->getFunctionType(), - F->getType()->getAddressSpace(), - F->getLinkage(), F->getName(), - Init, GVsM.get()); - } - // else.... - return nullptr; - }); - - // Clone the global variable initializers. - for (auto &GV : SrcM.globals()) - if (!GV.isDeclaration()) - moveGlobalVariableInitializer(GV, VMap, &Materializer); - - // Clone the global alias initializers. - for (auto &A : SrcM.aliases()) { - auto *NewA = cast(VMap[&A]); - assert(NewA && "Alias not cloned?"); - Value *Init = MapValue(A.getAliasee(), VMap, RF_None, nullptr, - &Materializer); - NewA->setAliasee(cast(Init)); - } - - // Build a resolver for the globals module and add it to the base layer. - auto LegacyLookup = [this, &LD](StringRef Name) -> JITSymbol { - if (auto Sym = LD.StubsMgr->findStub(Name, false)) - return Sym; - - if (auto Sym = LD.findSymbol(BaseLayer, std::string(Name), false)) - return Sym; - else if (auto Err = Sym.takeError()) - return std::move(Err); - - return nullptr; - }; - - auto GVsResolver = createSymbolResolver( - [&LD, LegacyLookup](const SymbolNameSet &Symbols) { - auto RS = getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup); - - if (!RS) { - logAllUnhandledErrors( - RS.takeError(), errs(), - "CODLayer/GVsResolver responsibility set lookup failed: "); - return SymbolNameSet(); - } - - if (RS->size() == Symbols.size()) - return *RS; - - SymbolNameSet NotFoundViaLegacyLookup; - for (auto &S : Symbols) - if (!RS->count(S)) - NotFoundViaLegacyLookup.insert(S); - auto RS2 = - LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup); - - for (auto &S : RS2) - (*RS).insert(S); - - return *RS; - }, - [this, &LD, - LegacyLookup](std::shared_ptr Query, - SymbolNameSet Symbols) { - auto NotFoundViaLegacyLookup = - lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup); - return LD.BackingResolver->lookup(Query, NotFoundViaLegacyLookup); - }); - - SetSymbolResolver(LD.K, std::move(GVsResolver)); - - if (auto Err = BaseLayer.addModule(LD.K, std::move(GVsM))) - return Err; - - LD.BaseLayerVModuleKeys.push_back(LD.K); - - return Error::success(); - } - - static std::string mangle(StringRef Name, const DataLayout &DL) { - std::string MangledName; - { - raw_string_ostream MangledNameStream(MangledName); - Mangler::getNameWithPrefix(MangledNameStream, Name, DL); - } - return MangledName; - } - - Expected - extractAndCompile(LogicalDylib &LD, - typename LogicalDylib::SourceModuleHandle LMId, - Function &F) { - Module &SrcM = LD.getSourceModule(LMId); - - // If F is a declaration we must already have compiled it. - if (F.isDeclaration()) - return 0; - - // Grab the name of the function being called here. - std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout()); - - JITTargetAddress CalledAddr = 0; - auto Part = Partition(F); - if (auto PartKeyOrErr = emitPartition(LD, LMId, Part)) { - auto &PartKey = *PartKeyOrErr; - for (auto *SubF : Part) { - std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout()); - if (auto FnBodySym = BaseLayer.findSymbolIn(PartKey, FnName, false)) { - if (auto FnBodyAddrOrErr = FnBodySym.getAddress()) { - JITTargetAddress FnBodyAddr = *FnBodyAddrOrErr; - - // If this is the function we're calling record the address so we can - // return it from this function. - if (SubF == &F) - CalledAddr = FnBodyAddr; - - // Update the function body pointer for the stub. - if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr)) - return 0; - - } else - return FnBodyAddrOrErr.takeError(); - } else if (auto Err = FnBodySym.takeError()) - return std::move(Err); - else - llvm_unreachable("Function not emitted for partition"); - } - - LD.BaseLayerVModuleKeys.push_back(PartKey); - } else - return PartKeyOrErr.takeError(); - - return CalledAddr; - } - - template - Expected - emitPartition(LogicalDylib &LD, - typename LogicalDylib::SourceModuleHandle LMId, - const PartitionT &Part) { - Module &SrcM = LD.getSourceModule(LMId); - - // Create the module. - std::string NewName(SrcM.getName()); - for (auto *F : Part) { - NewName += "."; - NewName += F->getName(); - } - - auto M = std::make_unique(NewName, SrcM.getContext()); - M->setDataLayout(SrcM.getDataLayout()); - ValueToValueMapTy VMap; - - auto Materializer = createLambdaMaterializer([&LD, &LMId, - &M](Value *V) -> Value * { - if (auto *GV = dyn_cast(V)) - return cloneGlobalVariableDecl(*M, *GV); - - if (auto *F = dyn_cast(V)) { - // Check whether we want to clone an available_externally definition. - if (!LD.getStubsToClone(LMId).count(F)) - return cloneFunctionDecl(*M, *F); - - // Ok - we want an inlinable stub. For that to work we need a decl - // for the stub pointer. - auto *StubPtr = createImplPointer(*F->getType(), *M, - F->getName() + "$stub_ptr", nullptr); - auto *ClonedF = cloneFunctionDecl(*M, *F); - makeStub(*ClonedF, *StubPtr); - ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage); - ClonedF->addFnAttr(Attribute::AlwaysInline); - return ClonedF; - } - - if (auto *A = dyn_cast(V)) { - auto *Ty = A->getValueType(); - if (Ty->isFunctionTy()) - return Function::Create(cast(Ty), - GlobalValue::ExternalLinkage, A->getName(), - M.get()); - - return new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, - nullptr, A->getName(), nullptr, - GlobalValue::NotThreadLocal, - A->getType()->getAddressSpace()); - } - - return nullptr; - }); - - // Create decls in the new module. - for (auto *F : Part) - cloneFunctionDecl(*M, *F, &VMap); - - // Move the function bodies. - for (auto *F : Part) - moveFunctionBody(*F, VMap, &Materializer); - - auto K = ES.allocateVModule(); - - auto LegacyLookup = [this, &LD](StringRef Name) -> JITSymbol { - return LD.findSymbol(BaseLayer, std::string(Name), false); - }; - - // Create memory manager and symbol resolver. - auto Resolver = createSymbolResolver( - [&LD, LegacyLookup](const SymbolNameSet &Symbols) { - auto RS = getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup); - if (!RS) { - logAllUnhandledErrors( - RS.takeError(), errs(), - "CODLayer/SubResolver responsibility set lookup failed: "); - return SymbolNameSet(); - } - - if (RS->size() == Symbols.size()) - return *RS; - - SymbolNameSet NotFoundViaLegacyLookup; - for (auto &S : Symbols) - if (!RS->count(S)) - NotFoundViaLegacyLookup.insert(S); - - auto RS2 = - LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup); - - for (auto &S : RS2) - (*RS).insert(S); - - return *RS; - }, - [this, &LD, LegacyLookup](std::shared_ptr Q, - SymbolNameSet Symbols) { - auto NotFoundViaLegacyLookup = - lookupWithLegacyFn(ES, *Q, Symbols, LegacyLookup); - return LD.BackingResolver->lookup(Q, - std::move(NotFoundViaLegacyLookup)); - }); - SetSymbolResolver(K, std::move(Resolver)); - - if (auto Err = BaseLayer.addModule(std::move(K), std::move(M))) - return std::move(Err); - - return K; - } - - ExecutionSession &ES; - BaseLayerT &BaseLayer; - SymbolResolverGetter GetSymbolResolver; - SymbolResolverSetter SetSymbolResolver; - PartitioningFtor Partition; - CompileCallbackMgrT &CompileCallbackMgr; - IndirectStubsManagerBuilderT CreateIndirectStubsManager; - - std::map LogicalDylibs; - bool CloneStubsIntoPartitions; -}; - -template -LegacyCompileOnDemandLayer:: - LegacyCompileOnDemandLayer( - ExecutionSession &ES, BaseLayerT &BaseLayer, - SymbolResolverGetter GetSymbolResolver, - SymbolResolverSetter SetSymbolResolver, PartitioningFtor Partition, - CompileCallbackMgrT &CallbackMgr, - IndirectStubsManagerBuilderT CreateIndirectStubsManager, - bool CloneStubsIntoPartitions) - : ES(ES), BaseLayer(BaseLayer), - GetSymbolResolver(std::move(GetSymbolResolver)), - SetSymbolResolver(std::move(SetSymbolResolver)), - Partition(std::move(Partition)), CompileCallbackMgr(CallbackMgr), - CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)), - CloneStubsIntoPartitions(CloneStubsIntoPartitions) {} - } // end namespace orc } // end namespace llvm diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Core.h b/llvm/include/llvm/ExecutionEngine/Orc/Core.h index 70bd983c40ce0..9bb3678b72126 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Core.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Core.h @@ -759,8 +759,6 @@ class AsynchronousSymbolQuery { void dropSymbol(const SymbolStringPtr &Name); - bool canStillFail(); - void handleFailed(Error Err); void detach(); @@ -912,17 +910,6 @@ class JITDylib : public std::enable_shared_from_this { /// Dump current JITDylib state to OS. void dump(raw_ostream &OS); - /// FIXME: Remove this when we remove the old ORC layers. - /// Search the given JITDylibs in order for the symbols in Symbols. Results - /// (once they become available) will be returned via the given Query. - /// - /// If any symbol is not found then the unresolved symbols will be returned, - /// and the query will not be applied. The Query is not failed and can be - /// re-used in a subsequent lookup once the symbols have been added, or - /// manually failed. - Expected - legacyLookup(std::shared_ptr Q, SymbolNameSet Names); - /// Returns the given JITDylibs and all of their transitive dependencies in /// DFS order (based on linkage relationships). Each JITDylib will appear /// only once. @@ -1039,10 +1026,6 @@ class JITDylib : public std::enable_shared_from_this { LookupKind K, JITDylibLookupFlags JDLookupFlags, SymbolLookupSet &Unresolved); - bool lookupImpl(std::shared_ptr &Q, - std::vector> &MUs, - SymbolLookupSet &Unresolved); - void detachQueryHelper(AsynchronousSymbolQuery &Q, const SymbolNameSet &QuerySymbols); @@ -1198,18 +1181,6 @@ class ExecutionSession { return *this; } - void legacyFailQuery(AsynchronousSymbolQuery &Q, Error Err); - - using LegacyAsyncLookupFunction = std::function Q, SymbolNameSet Names)>; - - /// A legacy lookup function for JITSymbolResolverAdapter. - /// Do not use -- this will be removed soon. - Expected - legacyLookup(LegacyAsyncLookupFunction AsyncLookup, SymbolNameSet Names, - SymbolState RequiredState, - RegisterDependenciesFunction RegisterDependencies); - /// Search the given JITDylib list for the given symbols. /// /// SearchOrder lists the JITDylibs to search. For each dylib, the associated diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h index 3b824b83b0522..3dd114c0af784 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h @@ -152,56 +152,6 @@ inline iterator_range getStaticInitGVs(Module &M) { return make_range(StaticInitGVIterator(M), StaticInitGVIterator()); } -/// Convenience class for recording constructor/destructor names for -/// later execution. -template -class LegacyCtorDtorRunner { -public: - /// Construct a CtorDtorRunner for the given range using the given - /// name mangling function. - LLVM_ATTRIBUTE_DEPRECATED( - LegacyCtorDtorRunner(std::vector CtorDtorNames, - VModuleKey K), - "ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. " - "Please use the ORCv2 CtorDtorRunner utility instead"); - - LegacyCtorDtorRunner(ORCv1DeprecationAcknowledgement, - std::vector CtorDtorNames, VModuleKey K) - : CtorDtorNames(std::move(CtorDtorNames)), K(K) {} - - /// Run the recorded constructors/destructors through the given JIT - /// layer. - Error runViaLayer(JITLayerT &JITLayer) const { - using CtorDtorTy = void (*)(); - - for (const auto &CtorDtorName : CtorDtorNames) { - if (auto CtorDtorSym = JITLayer.findSymbolIn(K, CtorDtorName, false)) { - if (auto AddrOrErr = CtorDtorSym.getAddress()) { - CtorDtorTy CtorDtor = - reinterpret_cast(static_cast(*AddrOrErr)); - CtorDtor(); - } else - return AddrOrErr.takeError(); - } else { - if (auto Err = CtorDtorSym.takeError()) - return Err; - else - return make_error(CtorDtorName); - } - } - return Error::success(); - } - -private: - std::vector CtorDtorNames; - orc::VModuleKey K; -}; - -template -LegacyCtorDtorRunner::LegacyCtorDtorRunner( - std::vector CtorDtorNames, VModuleKey K) - : CtorDtorNames(std::move(CtorDtorNames)), K(K) {} - class CtorDtorRunner { public: CtorDtorRunner(JITDylib &JD) : JD(JD) {} @@ -250,45 +200,6 @@ class LocalCXXRuntimeOverridesBase { void *DSOHandle); }; -class LegacyLocalCXXRuntimeOverrides : public LocalCXXRuntimeOverridesBase { -public: - /// Create a runtime-overrides class. - template - LLVM_ATTRIBUTE_DEPRECATED( - LegacyLocalCXXRuntimeOverrides(const MangleFtorT &Mangle), - "ORCv1 utilities (utilities with the 'Legacy' prefix) are deprecated. " - "Please use the ORCv2 LocalCXXRuntimeOverrides utility instead"); - - template - LegacyLocalCXXRuntimeOverrides(ORCv1DeprecationAcknowledgement, - const MangleFtorT &Mangle) { - addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride)); - addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride)); - } - - /// Search overrided symbols. - JITEvaluatedSymbol searchOverrides(const std::string &Name) { - auto I = CXXRuntimeOverrides.find(Name); - if (I != CXXRuntimeOverrides.end()) - return JITEvaluatedSymbol(I->second, JITSymbolFlags::Exported); - return nullptr; - } - -private: - void addOverride(const std::string &Name, JITTargetAddress Addr) { - CXXRuntimeOverrides.insert(std::make_pair(Name, Addr)); - } - - StringMap CXXRuntimeOverrides; -}; - -template -LegacyLocalCXXRuntimeOverrides::LegacyLocalCXXRuntimeOverrides( - const MangleFtorT &Mangle) { - addOverride(Mangle("__dso_handle"), toTargetAddress(&DSOHandleOverride)); - addOverride(Mangle("__cxa_atexit"), toTargetAddress(&CXAAtExitOverride)); -} - class LocalCXXRuntimeOverrides : public LocalCXXRuntimeOverridesBase { public: Error enable(JITDylib &JD, MangleAndInterner &Mangler); diff --git a/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h deleted file mode 100644 index 943404262bd04..0000000000000 --- a/llvm/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h +++ /dev/null @@ -1,110 +0,0 @@ -//===- GlobalMappingLayer.h - Run all IR through a functor ------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Convenience layer for injecting symbols that will appear in calls to -// findSymbol. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_EXECUTIONENGINE_ORC_GLOBALMAPPINGLAYER_H -#define LLVM_EXECUTIONENGINE_ORC_GLOBALMAPPINGLAYER_H - -#include "llvm/ExecutionEngine/JITSymbol.h" -#include -#include -#include - -namespace llvm { - -class Module; - -namespace orc { - -/// Global mapping layer. -/// -/// This layer overrides the findSymbol method to first search a local symbol -/// table that the client can define. It can be used to inject new symbol -/// mappings into the JIT. Beware, however: symbols within a single IR module or -/// object file will still resolve locally (via RuntimeDyld's symbol table) - -/// such internal references cannot be overriden via this layer. -template -class GlobalMappingLayer { -public: - - /// Handle to an added module. - using ModuleHandleT = typename BaseLayerT::ModuleHandleT; - - /// Construct an GlobalMappingLayer with the given BaseLayer - GlobalMappingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {} - - /// Add the given module to the JIT. - /// @return A handle for the added modules. - Expected - addModule(std::shared_ptr M, - std::shared_ptr Resolver) { - return BaseLayer.addModule(std::move(M), std::move(Resolver)); - } - - /// Remove the module set associated with the handle H. - Error removeModule(ModuleHandleT H) { return BaseLayer.removeModule(H); } - - /// Manually set the address to return for the given symbol. - void setGlobalMapping(const std::string &Name, JITTargetAddress Addr) { - SymbolTable[Name] = Addr; - } - - /// Remove the given symbol from the global mapping. - void eraseGlobalMapping(const std::string &Name) { - SymbolTable.erase(Name); - } - - /// Search for the given named symbol. - /// - /// This method will first search the local symbol table, returning - /// any symbol found there. If the symbol is not found in the local - /// table then this call will be passed through to the base layer. - /// - /// @param Name The name of the symbol to search for. - /// @param ExportedSymbolsOnly If true, search only for exported symbols. - /// @return A handle for the given named symbol, if it exists. - JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { - auto I = SymbolTable.find(Name); - if (I != SymbolTable.end()) - return JITSymbol(I->second, JITSymbolFlags::Exported); - return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); - } - - /// Get the address of the given symbol in the context of the of the - /// module represented by the handle H. This call is forwarded to the - /// base layer's implementation. - /// @param H The handle for the module to search in. - /// @param Name The name of the symbol to search for. - /// @param ExportedSymbolsOnly If true, search only for exported symbols. - /// @return A handle for the given named symbol, if it is found in the - /// given module. - JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name, - bool ExportedSymbolsOnly) { - return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly); - } - - /// Immediately emit and finalize the module set represented by the - /// given handle. - /// @param H Handle for module set to emit/finalize. - Error emitAndFinalize(ModuleHandleT H) { - return BaseLayer.emitAndFinalize(H); - } - -private: - BaseLayerT &BaseLayer; - std::map SymbolTable; -}; - -} // end namespace orc -} // end namespace llvm - -#endif // LLVM_EXECUTIONENGINE_ORC_GLOBALMAPPINGLAYER_H diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h index 2c53e2f66e851..81c39eab87798 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h @@ -66,99 +66,6 @@ class IRCompileLayer : public IRLayer { NotifyCompiledFunction NotifyCompiled = NotifyCompiledFunction(); }; -/// Eager IR compiling layer. -/// -/// This layer immediately compiles each IR module added via addModule to an -/// object file and adds this module file to the layer below, which must -/// implement the object layer concept. -template -class LegacyIRCompileLayer { -public: - /// Callback type for notifications when modules are compiled. - using NotifyCompiledCallback = - std::function)>; - - /// Construct an LegacyIRCompileLayer with the given BaseLayer, which must - /// implement the ObjectLayer concept. - LLVM_ATTRIBUTE_DEPRECATED( - LegacyIRCompileLayer( - BaseLayerT &BaseLayer, CompileFtor Compile, - NotifyCompiledCallback NotifyCompiled = NotifyCompiledCallback()), - "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please " - "use " - "the ORCv2 IRCompileLayer instead"); - - /// Legacy layer constructor with deprecation acknowledgement. - LegacyIRCompileLayer( - ORCv1DeprecationAcknowledgement, BaseLayerT &BaseLayer, - CompileFtor Compile, - NotifyCompiledCallback NotifyCompiled = NotifyCompiledCallback()) - : BaseLayer(BaseLayer), Compile(std::move(Compile)), - NotifyCompiled(std::move(NotifyCompiled)) {} - - /// Get a reference to the compiler functor. - CompileFtor& getCompiler() { return Compile; } - - /// (Re)set the NotifyCompiled callback. - void setNotifyCompiled(NotifyCompiledCallback NotifyCompiled) { - this->NotifyCompiled = std::move(NotifyCompiled); - } - - /// Compile the module, and add the resulting object to the base layer - /// along with the given memory manager and symbol resolver. - Error addModule(VModuleKey K, std::unique_ptr M) { - auto Obj = Compile(*M); - if (!Obj) - return Obj.takeError(); - if (auto Err = BaseLayer.addObject(std::move(K), std::move(*Obj))) - return Err; - if (NotifyCompiled) - NotifyCompiled(std::move(K), std::move(M)); - return Error::success(); - } - - /// Remove the module associated with the VModuleKey K. - Error removeModule(VModuleKey K) { return BaseLayer.removeObject(K); } - - /// Search for the given named symbol. - /// @param Name The name of the symbol to search for. - /// @param ExportedSymbolsOnly If true, search only for exported symbols. - /// @return A handle for the given named symbol, if it exists. - JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { - return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); - } - - /// Get the address of the given symbol in compiled module represented - /// by the handle H. This call is forwarded to the base layer's - /// implementation. - /// @param K The VModuleKey for the module to search in. - /// @param Name The name of the symbol to search for. - /// @param ExportedSymbolsOnly If true, search only for exported symbols. - /// @return A handle for the given named symbol, if it is found in the - /// given module. - JITSymbol findSymbolIn(VModuleKey K, const std::string &Name, - bool ExportedSymbolsOnly) { - return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly); - } - - /// Immediately emit and finalize the module represented by the given - /// handle. - /// @param K The VModuleKey for the module to emit/finalize. - Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); } - -private: - BaseLayerT &BaseLayer; - CompileFtor Compile; - NotifyCompiledCallback NotifyCompiled; -}; - -template -LegacyIRCompileLayer::LegacyIRCompileLayer( - BaseLayerT &BaseLayer, CompileFtor Compile, - NotifyCompiledCallback NotifyCompiled) - : BaseLayer(BaseLayer), Compile(std::move(Compile)), - NotifyCompiled(std::move(NotifyCompiled)) {} - } // end namespace orc } // end namespace llvm diff --git a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h index 475d3f259aefe..66966a0f87626 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h @@ -51,80 +51,6 @@ class IRTransformLayer : public IRLayer { TransformFunction Transform; }; -/// IR mutating layer. -/// -/// This layer applies a user supplied transform to each module that is added, -/// then adds the transformed module to the layer below. -template -class LegacyIRTransformLayer { -public: - - /// Construct an LegacyIRTransformLayer with the given BaseLayer - LLVM_ATTRIBUTE_DEPRECATED( - LegacyIRTransformLayer(BaseLayerT &BaseLayer, - TransformFtor Transform = TransformFtor()), - "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please " - "use " - "the ORCv2 IRTransformLayer instead"); - - /// Legacy layer constructor with deprecation acknowledgement. - LegacyIRTransformLayer(ORCv1DeprecationAcknowledgement, BaseLayerT &BaseLayer, - TransformFtor Transform = TransformFtor()) - : BaseLayer(BaseLayer), Transform(std::move(Transform)) {} - - /// Apply the transform functor to the module, then add the module to - /// the layer below, along with the memory manager and symbol resolver. - /// - /// @return A handle for the added modules. - Error addModule(VModuleKey K, std::unique_ptr M) { - return BaseLayer.addModule(std::move(K), Transform(std::move(M))); - } - - /// Remove the module associated with the VModuleKey K. - Error removeModule(VModuleKey K) { return BaseLayer.removeModule(K); } - - /// Search for the given named symbol. - /// @param Name The name of the symbol to search for. - /// @param ExportedSymbolsOnly If true, search only for exported symbols. - /// @return A handle for the given named symbol, if it exists. - JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { - return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); - } - - /// Get the address of the given symbol in the context of the module - /// represented by the VModuleKey K. This call is forwarded to the base - /// layer's implementation. - /// @param K The VModuleKey for the module to search in. - /// @param Name The name of the symbol to search for. - /// @param ExportedSymbolsOnly If true, search only for exported symbols. - /// @return A handle for the given named symbol, if it is found in the - /// given module. - JITSymbol findSymbolIn(VModuleKey K, const std::string &Name, - bool ExportedSymbolsOnly) { - return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly); - } - - /// Immediately emit and finalize the module represented by the given - /// VModuleKey. - /// @param K The VModuleKey for the module to emit/finalize. - Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); } - - /// Access the transform functor directly. - TransformFtor& getTransform() { return Transform; } - - /// Access the mumate functor directly. - const TransformFtor& getTransform() const { return Transform; } - -private: - BaseLayerT &BaseLayer; - TransformFtor Transform; -}; - -template -LegacyIRTransformLayer::LegacyIRTransformLayer( - BaseLayerT &BaseLayer, TransformFtor Transform) - : BaseLayer(BaseLayer), Transform(std::move(Transform)) {} - } // end namespace orc } // end namespace llvm diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LambdaResolver.h b/llvm/include/llvm/ExecutionEngine/Orc/LambdaResolver.h deleted file mode 100644 index b31914f12a0d3..0000000000000 --- a/llvm/include/llvm/ExecutionEngine/Orc/LambdaResolver.h +++ /dev/null @@ -1,84 +0,0 @@ -//===- LambdaResolverMM - Redirect symbol lookup via a functor --*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Defines a RuntimeDyld::SymbolResolver subclass that uses a user-supplied -// functor for symbol resolution. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H -#define LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H - -#include "llvm/ADT/STLExtras.h" -#include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/ExecutionEngine/OrcV1Deprecation.h" -#include - -namespace llvm { -namespace orc { - -template -class LambdaResolver : public LegacyJITSymbolResolver { -public: - LLVM_ATTRIBUTE_DEPRECATED( - LambdaResolver(DylibLookupFtorT DylibLookupFtor, - ExternalLookupFtorT ExternalLookupFtor), - "ORCv1 utilities (including resolvers) are deprecated and will be " - "removed " - "in the next release. Please use ORCv2 (see docs/ORCv2.rst)"); - - LambdaResolver(ORCv1DeprecationAcknowledgement, - DylibLookupFtorT DylibLookupFtor, - ExternalLookupFtorT ExternalLookupFtor) - : DylibLookupFtor(DylibLookupFtor), - ExternalLookupFtor(ExternalLookupFtor) {} - - JITSymbol findSymbolInLogicalDylib(const std::string &Name) final { - return DylibLookupFtor(Name); - } - - JITSymbol findSymbol(const std::string &Name) final { - return ExternalLookupFtor(Name); - } - -private: - DylibLookupFtorT DylibLookupFtor; - ExternalLookupFtorT ExternalLookupFtor; -}; - -template -LambdaResolver::LambdaResolver( - DylibLookupFtorT DylibLookupFtor, ExternalLookupFtorT ExternalLookupFtor) - : DylibLookupFtor(DylibLookupFtor), ExternalLookupFtor(ExternalLookupFtor) { -} - -template -std::shared_ptr> -createLambdaResolver(DylibLookupFtorT DylibLookupFtor, - ExternalLookupFtorT ExternalLookupFtor) { - using LR = LambdaResolver; - return std::make_unique(std::move(DylibLookupFtor), - std::move(ExternalLookupFtor)); -} - -template -std::shared_ptr> -createLambdaResolver(ORCv1DeprecationAcknowledgement, - DylibLookupFtorT DylibLookupFtor, - ExternalLookupFtorT ExternalLookupFtor) { - using LR = LambdaResolver; - return std::make_unique(AcknowledgeORCv1Deprecation, - std::move(DylibLookupFtor), - std::move(ExternalLookupFtor)); -} - -} // end namespace orc -} // end namespace llvm - -#endif // LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h deleted file mode 100644 index 84f5e0350c2ec..0000000000000 --- a/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h +++ /dev/null @@ -1,267 +0,0 @@ -//===- LazyEmittingLayer.h - Lazily emit IR to lower JIT layers -*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Contains the definition for a lazy-emitting layer for the JIT. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H -#define LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H - -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/ExecutionEngine/Orc/Core.h" -#include "llvm/IR/GlobalValue.h" -#include "llvm/IR/Mangler.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include -#include -#include -#include -#include - -namespace llvm { -namespace orc { - -/// Lazy-emitting IR layer. -/// -/// This layer accepts LLVM IR Modules (via addModule) but does not -/// immediately emit them the layer below. Instead, emission to the base layer -/// is deferred until the first time the client requests the address (via -/// JITSymbol::getAddress) for a symbol contained in this layer. -template class LazyEmittingLayer { -private: - class EmissionDeferredModule { - public: - EmissionDeferredModule(VModuleKey K, std::unique_ptr M) - : K(std::move(K)), M(std::move(M)) {} - - JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) { - switch (EmitState) { - case NotEmitted: - if (auto GV = searchGVs(Name, ExportedSymbolsOnly)) { - JITSymbolFlags Flags = JITSymbolFlags::fromGlobalValue(*GV); - auto GetAddress = [this, ExportedSymbolsOnly, Name = Name.str(), - &B]() -> Expected { - if (this->EmitState == Emitting) - return 0; - else if (this->EmitState == NotEmitted) { - this->EmitState = Emitting; - if (auto Err = this->emitToBaseLayer(B)) - return std::move(Err); - this->EmitState = Emitted; - } - if (auto Sym = B.findSymbolIn(K, Name, ExportedSymbolsOnly)) - return Sym.getAddress(); - else if (auto Err = Sym.takeError()) - return std::move(Err); - else - llvm_unreachable("Successful symbol lookup should return " - "definition address here"); - }; - return JITSymbol(std::move(GetAddress), Flags); - } else - return nullptr; - case Emitting: - // Calling "emit" can trigger a recursive call to 'find' (e.g. to check - // for pre-existing definitions of common-symbol), but any symbol in - // this module would already have been found internally (in the - // RuntimeDyld that did the lookup), so just return a nullptr here. - return nullptr; - case Emitted: - return B.findSymbolIn(K, std::string(Name), ExportedSymbolsOnly); - } - llvm_unreachable("Invalid emit-state."); - } - - Error removeModuleFromBaseLayer(BaseLayerT& BaseLayer) { - return EmitState != NotEmitted ? BaseLayer.removeModule(K) - : Error::success(); - } - - void emitAndFinalize(BaseLayerT &BaseLayer) { - assert(EmitState != Emitting && - "Cannot emitAndFinalize while already emitting"); - if (EmitState == NotEmitted) { - EmitState = Emitting; - emitToBaseLayer(BaseLayer); - EmitState = Emitted; - } - BaseLayer.emitAndFinalize(K); - } - - private: - - const GlobalValue* searchGVs(StringRef Name, - bool ExportedSymbolsOnly) const { - // FIXME: We could clean all this up if we had a way to reliably demangle - // names: We could just demangle name and search, rather than - // mangling everything else. - - // If we have already built the mangled name set then just search it. - if (MangledSymbols) { - auto VI = MangledSymbols->find(Name); - if (VI == MangledSymbols->end()) - return nullptr; - auto GV = VI->second; - if (!ExportedSymbolsOnly || GV->hasDefaultVisibility()) - return GV; - return nullptr; - } - - // If we haven't built the mangled name set yet, try to build it. As an - // optimization this will leave MangledNames set to nullptr if we find - // Name in the process of building the set. - return buildMangledSymbols(Name, ExportedSymbolsOnly); - } - - Error emitToBaseLayer(BaseLayerT &BaseLayer) { - // We don't need the mangled names set any more: Once we've emitted this - // to the base layer we'll just look for symbols there. - MangledSymbols.reset(); - return BaseLayer.addModule(std::move(K), std::move(M)); - } - - // If the mangled name of the given GlobalValue matches the given search - // name (and its visibility conforms to the ExportedSymbolsOnly flag) then - // return the symbol. Otherwise, add the mangled name to the Names map and - // return nullptr. - const GlobalValue* addGlobalValue(StringMap &Names, - const GlobalValue &GV, - const Mangler &Mang, StringRef SearchName, - bool ExportedSymbolsOnly) const { - // Modules don't "provide" decls or common symbols. - if (GV.isDeclaration() || GV.hasCommonLinkage()) - return nullptr; - - // Mangle the GV name. - std::string MangledName; - { - raw_string_ostream MangledNameStream(MangledName); - Mang.getNameWithPrefix(MangledNameStream, &GV, false); - } - - // Check whether this is the name we were searching for, and if it is then - // bail out early. - if (MangledName == SearchName) - if (!ExportedSymbolsOnly || GV.hasDefaultVisibility()) - return &GV; - - // Otherwise add this to the map for later. - Names[MangledName] = &GV; - return nullptr; - } - - // Build the MangledSymbols map. Bails out early (with MangledSymbols left set - // to nullptr) if the given SearchName is found while building the map. - const GlobalValue* buildMangledSymbols(StringRef SearchName, - bool ExportedSymbolsOnly) const { - assert(!MangledSymbols && "Mangled symbols map already exists?"); - - auto Symbols = std::make_unique>(); - - Mangler Mang; - - for (const auto &GO : M->global_objects()) - if (auto GV = addGlobalValue(*Symbols, GO, Mang, SearchName, - ExportedSymbolsOnly)) - return GV; - - MangledSymbols = std::move(Symbols); - return nullptr; - } - - enum { NotEmitted, Emitting, Emitted } EmitState = NotEmitted; - VModuleKey K; - std::unique_ptr M; - mutable std::unique_ptr> MangledSymbols; - }; - - BaseLayerT &BaseLayer; - std::map> ModuleMap; - -public: - - /// Construct a lazy emitting layer. - LLVM_ATTRIBUTE_DEPRECATED( - LazyEmittingLayer(BaseLayerT &BaseLayer), - "ORCv1 layers (including LazyEmittingLayer) are deprecated. Please use " - "ORCv2, where lazy emission is the default"); - - /// Construct a lazy emitting layer. - LazyEmittingLayer(ORCv1DeprecationAcknowledgement, BaseLayerT &BaseLayer) - : BaseLayer(BaseLayer) {} - - /// Add the given module to the lazy emitting layer. - Error addModule(VModuleKey K, std::unique_ptr M) { - assert(!ModuleMap.count(K) && "VModuleKey K already in use"); - ModuleMap[K] = - std::make_unique(std::move(K), std::move(M)); - return Error::success(); - } - - /// Remove the module represented by the given handle. - /// - /// This method will free the memory associated with the given module, both - /// in this layer, and the base layer. - Error removeModule(VModuleKey K) { - auto I = ModuleMap.find(K); - assert(I != ModuleMap.end() && "VModuleKey K not valid here"); - auto EDM = std::move(I.second); - ModuleMap.erase(I); - return EDM->removeModuleFromBaseLayer(BaseLayer); - } - - /// Search for the given named symbol. - /// @param Name The name of the symbol to search for. - /// @param ExportedSymbolsOnly If true, search only for exported symbols. - /// @return A handle for the given named symbol, if it exists. - JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { - // Look for the symbol among existing definitions. - if (auto Symbol = BaseLayer.findSymbol(Name, ExportedSymbolsOnly)) - return Symbol; - - // If not found then search the deferred modules. If any of these contain a - // definition of 'Name' then they will return a JITSymbol that will emit - // the corresponding module when the symbol address is requested. - for (auto &KV : ModuleMap) - if (auto Symbol = KV.second->find(Name, ExportedSymbolsOnly, BaseLayer)) - return Symbol; - - // If no definition found anywhere return a null symbol. - return nullptr; - } - - /// Get the address of the given symbol in the context of the of - /// compiled modules represented by the key K. - JITSymbol findSymbolIn(VModuleKey K, const std::string &Name, - bool ExportedSymbolsOnly) { - assert(ModuleMap.count(K) && "VModuleKey K not valid here"); - return ModuleMap[K]->find(Name, ExportedSymbolsOnly, BaseLayer); - } - - /// Immediately emit and finalize the module represented by the given - /// key. - Error emitAndFinalize(VModuleKey K) { - assert(ModuleMap.count(K) && "VModuleKey K not valid here"); - return ModuleMap[K]->emitAndFinalize(BaseLayer); - } -}; - -template -LazyEmittingLayer::LazyEmittingLayer(BaseLayerT &BaseLayer) - : BaseLayer(BaseLayer) {} - -} // end namespace orc -} // end namespace llvm - -#endif // LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h b/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h deleted file mode 100644 index b20202a49ef65..0000000000000 --- a/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h +++ /dev/null @@ -1,211 +0,0 @@ -//===--- Legacy.h -- Adapters for ExecutionEngine API interop ---*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Contains core ORC APIs. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_EXECUTIONENGINE_ORC_LEGACY_H -#define LLVM_EXECUTIONENGINE_ORC_LEGACY_H - -#include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/ExecutionEngine/Orc/Core.h" - -namespace llvm { -namespace orc { - -/// SymbolResolver is a composable interface for looking up symbol flags -/// and addresses using the AsynchronousSymbolQuery type. It will -/// eventually replace the LegacyJITSymbolResolver interface as the -/// stardard ORC symbol resolver type. -/// -/// FIXME: SymbolResolvers should go away and be replaced with VSOs with -/// defenition generators. -class SymbolResolver { -public: - virtual ~SymbolResolver() = default; - - /// Returns the subset of the given symbols that the caller is responsible for - /// materializing. - virtual SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) = 0; - - /// For each symbol in Symbols that can be found, assigns that symbols - /// value in Query. Returns the set of symbols that could not be found. - virtual SymbolNameSet lookup(std::shared_ptr Query, - SymbolNameSet Symbols) = 0; - -private: - virtual void anchor(); -}; - -/// Implements SymbolResolver with a pair of supplied function objects -/// for convenience. See createSymbolResolver. -template -class LambdaSymbolResolver final : public SymbolResolver { -public: - template - LambdaSymbolResolver(GetResponsibilitySetFnRef &&GetResponsibilitySet, - LookupFnRef &&Lookup) - : GetResponsibilitySet( - std::forward(GetResponsibilitySet)), - Lookup(std::forward(Lookup)) {} - - SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) final { - return GetResponsibilitySet(Symbols); - } - - SymbolNameSet lookup(std::shared_ptr Query, - SymbolNameSet Symbols) final { - return Lookup(std::move(Query), std::move(Symbols)); - } - -private: - GetResponsibilitySetFn GetResponsibilitySet; - LookupFn Lookup; -}; - -/// Creates a SymbolResolver implementation from the pair of supplied -/// function objects. -template -std::unique_ptr>, - std::remove_cv_t>>> -createSymbolResolver(GetResponsibilitySetFn &&GetResponsibilitySet, - LookupFn &&Lookup) { - using LambdaSymbolResolverImpl = LambdaSymbolResolver< - std::remove_cv_t>, - std::remove_cv_t>>; - return std::make_unique( - std::forward(GetResponsibilitySet), - std::forward(Lookup)); -} - -/// Legacy adapter. Remove once we kill off the old ORC layers. -class JITSymbolResolverAdapter : public JITSymbolResolver { -public: - JITSymbolResolverAdapter(ExecutionSession &ES, SymbolResolver &R, - MaterializationResponsibility *MR); - Expected getResponsibilitySet(const LookupSet &Symbols) override; - void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) override; - -private: - ExecutionSession &ES; - std::set ResolvedStrings; - SymbolResolver &R; - MaterializationResponsibility *MR; -}; - -/// Use the given legacy-style FindSymbol function (i.e. a function that takes -/// a const std::string& or StringRef and returns a JITSymbol) to get the -/// subset of symbols that the caller is responsible for materializing. If any -/// JITSymbol returned by FindSymbol is in an error state the function returns -/// immediately with that error. -/// -/// Useful for implementing getResponsibilitySet bodies that query legacy -/// resolvers. -template -Expected -getResponsibilitySetWithLegacyFn(const SymbolNameSet &Symbols, - FindSymbolFn FindSymbol) { - SymbolNameSet Result; - - for (auto &S : Symbols) { - if (JITSymbol Sym = FindSymbol(*S)) { - if (!Sym.getFlags().isStrong()) - Result.insert(S); - } else if (auto Err = Sym.takeError()) - return std::move(Err); - } - - return Result; -} - -/// Use the given legacy-style FindSymbol function (i.e. a function that -/// takes a const std::string& or StringRef and returns a JITSymbol) to -/// find the address and flags for each symbol in Symbols and store the -/// result in Query. If any JITSymbol returned by FindSymbol is in an -/// error then Query.notifyFailed(...) is called with that error and the -/// function returns immediately. On success, returns the set of symbols -/// not found. -/// -/// Useful for implementing lookup bodies that query legacy resolvers. -template -SymbolNameSet -lookupWithLegacyFn(ExecutionSession &ES, AsynchronousSymbolQuery &Query, - const SymbolNameSet &Symbols, FindSymbolFn FindSymbol) { - SymbolNameSet SymbolsNotFound; - bool NewSymbolsResolved = false; - - for (auto &S : Symbols) { - if (JITSymbol Sym = FindSymbol(*S)) { - if (auto Addr = Sym.getAddress()) { - Query.notifySymbolMetRequiredState( - S, JITEvaluatedSymbol(*Addr, Sym.getFlags())); - NewSymbolsResolved = true; - } else { - ES.legacyFailQuery(Query, Addr.takeError()); - return SymbolNameSet(); - } - } else if (auto Err = Sym.takeError()) { - ES.legacyFailQuery(Query, std::move(Err)); - return SymbolNameSet(); - } else - SymbolsNotFound.insert(S); - } - - if (NewSymbolsResolved && Query.isComplete()) - Query.handleComplete(); - - return SymbolsNotFound; -} - -/// An ORC SymbolResolver implementation that uses a legacy -/// findSymbol-like function to perform lookup; -template -class LegacyLookupFnResolver final : public SymbolResolver { -public: - using ErrorReporter = std::function; - - LegacyLookupFnResolver(ExecutionSession &ES, LegacyLookupFn LegacyLookup, - ErrorReporter ReportError) - : ES(ES), LegacyLookup(std::move(LegacyLookup)), - ReportError(std::move(ReportError)) {} - - SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) final { - if (auto ResponsibilitySet = - getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup)) - return std::move(*ResponsibilitySet); - else { - ReportError(ResponsibilitySet.takeError()); - return SymbolNameSet(); - } - } - - SymbolNameSet lookup(std::shared_ptr Query, - SymbolNameSet Symbols) final { - return lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup); - } - -private: - ExecutionSession &ES; - LegacyLookupFn LegacyLookup; - ErrorReporter ReportError; -}; - -template -std::shared_ptr> -createLegacyLookupResolver(ExecutionSession &ES, LegacyLookupFn LegacyLookup, - std::function ErrorReporter) { - return std::make_shared>( - ES, std::move(LegacyLookup), std::move(ErrorReporter)); -} - -} // End namespace orc -} // End namespace llvm - -#endif // LLVM_EXECUTIONENGINE_ORC_LEGACY_H diff --git a/llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h b/llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h deleted file mode 100644 index ffa37a13d0649..0000000000000 --- a/llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h +++ /dev/null @@ -1,43 +0,0 @@ -//===------ NullResolver.h - Reject symbol lookup requests ------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Defines a RuntimeDyld::SymbolResolver subclass that rejects all symbol -// resolution requests, for clients that have no cross-object fixups. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H -#define LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H - -#include "llvm/ExecutionEngine/Orc/Legacy.h" -#include "llvm/ExecutionEngine/RuntimeDyld.h" - -namespace llvm { -namespace orc { - -class NullResolver : public SymbolResolver { -public: - SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) final; - - SymbolNameSet lookup(std::shared_ptr Query, - SymbolNameSet Symbols) final; -}; - -/// SymbolResolver impliementation that rejects all resolution requests. -/// Useful for clients that have no cross-object fixups. -class NullLegacyResolver : public LegacyJITSymbolResolver { -public: - JITSymbol findSymbol(const std::string &Name) final; - - JITSymbol findSymbolInLogicalDylib(const std::string &Name) final; -}; - -} // End namespace orc. -} // End namespace llvm. - -#endif // LLVM_EXECUTIONENGINE_ORC_NULLRESOLVER_H diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h index c77649f19fc74..d8395ab34e470 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h @@ -43,88 +43,6 @@ class ObjectTransformLayer : public ObjectLayer { TransformFunction Transform; }; -/// Object mutating layer. -/// -/// This layer accepts sets of ObjectFiles (via addObject). It -/// immediately applies the user supplied functor to each object, then adds -/// the set of transformed objects to the layer below. -template -class LegacyObjectTransformLayer { -public: - /// Construct an ObjectTransformLayer with the given BaseLayer - LLVM_ATTRIBUTE_DEPRECATED( - LegacyObjectTransformLayer(BaseLayerT &BaseLayer, - TransformFtor Transform = TransformFtor()), - "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please " - "use " - "the ORCv2 ObjectTransformLayer instead"); - - /// Legacy layer constructor with deprecation acknowledgement. - LegacyObjectTransformLayer(ORCv1DeprecationAcknowledgement, - BaseLayerT &BaseLayer, - TransformFtor Transform = TransformFtor()) - : BaseLayer(BaseLayer), Transform(std::move(Transform)) {} - - /// Apply the transform functor to each object in the object set, then - /// add the resulting set of objects to the base layer, along with the - /// memory manager and symbol resolver. - /// - /// @return A handle for the added objects. - template Error addObject(VModuleKey K, ObjectPtr Obj) { - return BaseLayer.addObject(std::move(K), Transform(std::move(Obj))); - } - - /// Remove the object set associated with the VModuleKey K. - Error removeObject(VModuleKey K) { return BaseLayer.removeObject(K); } - - /// Search for the given named symbol. - /// @param Name The name of the symbol to search for. - /// @param ExportedSymbolsOnly If true, search only for exported symbols. - /// @return A handle for the given named symbol, if it exists. - JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { - return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); - } - - /// Get the address of the given symbol in the context of the set of - /// objects represented by the VModuleKey K. This call is forwarded to - /// the base layer's implementation. - /// @param K The VModuleKey associated with the object set to search in. - /// @param Name The name of the symbol to search for. - /// @param ExportedSymbolsOnly If true, search only for exported symbols. - /// @return A handle for the given named symbol, if it is found in the - /// given object set. - JITSymbol findSymbolIn(VModuleKey K, const std::string &Name, - bool ExportedSymbolsOnly) { - return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly); - } - - /// Immediately emit and finalize the object set represented by the - /// given VModuleKey K. - Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); } - - /// Map section addresses for the objects associated with the - /// VModuleKey K. - void mapSectionAddress(VModuleKey K, const void *LocalAddress, - JITTargetAddress TargetAddr) { - BaseLayer.mapSectionAddress(K, LocalAddress, TargetAddr); - } - - /// Access the transform functor directly. - TransformFtor &getTransform() { return Transform; } - - /// Access the mumate functor directly. - const TransformFtor &getTransform() const { return Transform; } - -private: - BaseLayerT &BaseLayer; - TransformFtor Transform; -}; - -template -LegacyObjectTransformLayer:: - LegacyObjectTransformLayer(BaseLayerT &BaseLayer, TransformFtor Transform) - : BaseLayer(BaseLayer), Transform(std::move(Transform)) {} - } // end namespace orc } // end namespace llvm diff --git a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h index 9cd3c57a19c6a..eeec131503a1b 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h @@ -20,7 +20,6 @@ #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/Core.h" #include "llvm/ExecutionEngine/Orc/Layer.h" -#include "llvm/ExecutionEngine/Orc/Legacy.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Error.h" @@ -148,356 +147,6 @@ class RTDyldObjectLinkingLayer : public ObjectLayer { LoadedObjInfos; }; -class LegacyRTDyldObjectLinkingLayerBase { -public: - using ObjectPtr = std::unique_ptr; - -protected: - - /// Holds an object to be allocated/linked as a unit in the JIT. - /// - /// An instance of this class will be created for each object added - /// via JITObjectLayer::addObject. Deleting the instance (via - /// removeObject) frees its memory, removing all symbol definitions that - /// had been provided by this instance. Higher level layers are responsible - /// for taking any action required to handle the missing symbols. - class LinkedObject { - public: - LinkedObject() = default; - LinkedObject(const LinkedObject&) = delete; - void operator=(const LinkedObject&) = delete; - virtual ~LinkedObject() = default; - - virtual Error finalize() = 0; - - virtual JITSymbol::GetAddressFtor - getSymbolMaterializer(std::string Name) = 0; - - virtual void mapSectionAddress(const void *LocalAddress, - JITTargetAddress TargetAddr) const = 0; - - JITSymbol getSymbol(StringRef Name, bool ExportedSymbolsOnly) { - auto SymEntry = SymbolTable.find(Name); - if (SymEntry == SymbolTable.end()) - return nullptr; - if (!SymEntry->second.getFlags().isExported() && ExportedSymbolsOnly) - return nullptr; - if (!Finalized) - return JITSymbol(getSymbolMaterializer(std::string(Name)), - SymEntry->second.getFlags()); - return JITSymbol(SymEntry->second); - } - - protected: - StringMap SymbolTable; - bool Finalized = false; - }; -}; - -/// Bare bones object linking layer. -/// -/// This class is intended to be used as the base layer for a JIT. It allows -/// object files to be loaded into memory, linked, and the addresses of their -/// symbols queried. All objects added to this layer can see each other's -/// symbols. -class LegacyRTDyldObjectLinkingLayer : public LegacyRTDyldObjectLinkingLayerBase { -public: - - using LegacyRTDyldObjectLinkingLayerBase::ObjectPtr; - - /// Functor for receiving object-loaded notifications. - using NotifyLoadedFtor = - std::function; - - /// Functor for receiving finalization notifications. - using NotifyFinalizedFtor = - std::function; - - /// Functor for receiving deallocation notifications. - using NotifyFreedFtor = std::function; - -private: - using OwnedObject = object::OwningBinary; - - template - class ConcreteLinkedObject : public LinkedObject { - public: - ConcreteLinkedObject(LegacyRTDyldObjectLinkingLayer &Parent, VModuleKey K, - OwnedObject Obj, MemoryManagerPtrT MemMgr, - std::shared_ptr Resolver, - bool ProcessAllSections) - : K(std::move(K)), - Parent(Parent), - MemMgr(std::move(MemMgr)), - PFC(std::make_unique( - std::move(Obj), std::move(Resolver), - ProcessAllSections)) { - buildInitialSymbolTable(PFC->Obj); - } - - ~ConcreteLinkedObject() override { - if (this->Parent.NotifyFreed && ObjForNotify.getBinary()) - this->Parent.NotifyFreed(K, *ObjForNotify.getBinary()); - - MemMgr->deregisterEHFrames(); - } - - Error finalize() override { - assert(PFC && "mapSectionAddress called on finalized LinkedObject"); - - JITSymbolResolverAdapter ResolverAdapter(Parent.ES, *PFC->Resolver, - nullptr); - PFC->RTDyld = std::make_unique(*MemMgr, ResolverAdapter); - PFC->RTDyld->setProcessAllSections(PFC->ProcessAllSections); - - Finalized = true; - - std::unique_ptr Info = - PFC->RTDyld->loadObject(*PFC->Obj.getBinary()); - - // Copy the symbol table out of the RuntimeDyld instance. - { - auto SymTab = PFC->RTDyld->getSymbolTable(); - for (auto &KV : SymTab) - SymbolTable[KV.first] = KV.second; - } - - if (Parent.NotifyLoaded) - Parent.NotifyLoaded(K, *PFC->Obj.getBinary(), *Info); - - PFC->RTDyld->finalizeWithMemoryManagerLocking(); - - if (PFC->RTDyld->hasError()) - return make_error(PFC->RTDyld->getErrorString(), - inconvertibleErrorCode()); - - if (Parent.NotifyFinalized) - Parent.NotifyFinalized(K, *PFC->Obj.getBinary(), *Info); - - // Release resources. - if (this->Parent.NotifyFreed) - ObjForNotify = std::move(PFC->Obj); // needed for callback - PFC = nullptr; - return Error::success(); - } - - JITSymbol::GetAddressFtor getSymbolMaterializer(std::string Name) override { - return [this, Name]() -> Expected { - // The symbol may be materialized between the creation of this lambda - // and its execution, so we need to double check. - if (!this->Finalized) - if (auto Err = this->finalize()) - return std::move(Err); - return this->getSymbol(Name, false).getAddress(); - }; - } - - void mapSectionAddress(const void *LocalAddress, - JITTargetAddress TargetAddr) const override { - assert(PFC && "mapSectionAddress called on finalized LinkedObject"); - assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObject"); - PFC->RTDyld->mapSectionAddress(LocalAddress, TargetAddr); - } - - private: - void buildInitialSymbolTable(const OwnedObject &Obj) { - for (auto &Symbol : Obj.getBinary()->symbols()) { - if (Expected SymbolFlagsOrErr = Symbol.getFlags()) { - if (*SymbolFlagsOrErr & object::SymbolRef::SF_Undefined) - continue; - } else { - // FIXME: Raise an error for bad symbols. - consumeError(SymbolFlagsOrErr.takeError()); - continue; - } - - Expected SymbolName = Symbol.getName(); - // FIXME: Raise an error for bad symbols. - if (!SymbolName) { - consumeError(SymbolName.takeError()); - continue; - } - // FIXME: Raise an error for bad symbols. - auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol); - if (!Flags) { - consumeError(Flags.takeError()); - continue; - } - SymbolTable.insert( - std::make_pair(*SymbolName, JITEvaluatedSymbol(0, *Flags))); - } - } - - // Contains the information needed prior to finalization: the object files, - // memory manager, resolver, and flags needed for RuntimeDyld. - struct PreFinalizeContents { - PreFinalizeContents(OwnedObject Obj, - std::shared_ptr Resolver, - bool ProcessAllSections) - : Obj(std::move(Obj)), - Resolver(std::move(Resolver)), - ProcessAllSections(ProcessAllSections) {} - - OwnedObject Obj; - std::shared_ptr Resolver; - bool ProcessAllSections; - std::unique_ptr RTDyld; - }; - - VModuleKey K; - LegacyRTDyldObjectLinkingLayer &Parent; - MemoryManagerPtrT MemMgr; - OwnedObject ObjForNotify; - std::unique_ptr PFC; - }; - - template - std::unique_ptr> - createLinkedObject(LegacyRTDyldObjectLinkingLayer &Parent, VModuleKey K, - OwnedObject Obj, MemoryManagerPtrT MemMgr, - std::shared_ptr Resolver, - bool ProcessAllSections) { - using LOS = ConcreteLinkedObject; - return std::make_unique(Parent, std::move(K), std::move(Obj), - std::move(MemMgr), std::move(Resolver), - ProcessAllSections); - } - -public: - struct Resources { - std::shared_ptr MemMgr; - std::shared_ptr Resolver; - }; - - using ResourcesGetter = std::function; - - /// Construct an ObjectLinkingLayer with the given NotifyLoaded, - /// and NotifyFinalized functors. - LLVM_ATTRIBUTE_DEPRECATED( - LegacyRTDyldObjectLinkingLayer( - ExecutionSession &ES, ResourcesGetter GetResources, - NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(), - NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor(), - NotifyFreedFtor NotifyFreed = NotifyFreedFtor()), - "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please " - "use " - "ORCv2 (see docs/ORCv2.rst)"); - - // Legacy layer constructor with deprecation acknowledgement. - LegacyRTDyldObjectLinkingLayer( - ORCv1DeprecationAcknowledgement, ExecutionSession &ES, - ResourcesGetter GetResources, - NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(), - NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor(), - NotifyFreedFtor NotifyFreed = NotifyFreedFtor()) - : ES(ES), GetResources(std::move(GetResources)), - NotifyLoaded(std::move(NotifyLoaded)), - NotifyFinalized(std::move(NotifyFinalized)), - NotifyFreed(std::move(NotifyFreed)), ProcessAllSections(false) {} - - /// Set the 'ProcessAllSections' flag. - /// - /// If set to true, all sections in each object file will be allocated using - /// the memory manager, rather than just the sections required for execution. - /// - /// This is kludgy, and may be removed in the future. - void setProcessAllSections(bool ProcessAllSections) { - this->ProcessAllSections = ProcessAllSections; - } - - /// Add an object to the JIT. - Error addObject(VModuleKey K, ObjectPtr ObjBuffer) { - - auto Obj = - object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); - if (!Obj) - return Obj.takeError(); - - assert(!LinkedObjects.count(K) && "VModuleKey already in use"); - - auto R = GetResources(K); - - LinkedObjects[K] = createLinkedObject( - *this, K, OwnedObject(std::move(*Obj), std::move(ObjBuffer)), - std::move(R.MemMgr), std::move(R.Resolver), ProcessAllSections); - - return Error::success(); - } - - /// Remove the object associated with VModuleKey K. - /// - /// All memory allocated for the object will be freed, and the sections and - /// symbols it provided will no longer be available. No attempt is made to - /// re-emit the missing symbols, and any use of these symbols (directly or - /// indirectly) will result in undefined behavior. If dependence tracking is - /// required to detect or resolve such issues it should be added at a higher - /// layer. - Error removeObject(VModuleKey K) { - assert(LinkedObjects.count(K) && "VModuleKey not associated with object"); - // How do we invalidate the symbols in H? - LinkedObjects.erase(K); - return Error::success(); - } - - /// Search for the given named symbol. - /// @param Name The name of the symbol to search for. - /// @param ExportedSymbolsOnly If true, search only for exported symbols. - /// @return A handle for the given named symbol, if it exists. - JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) { - for (auto &KV : LinkedObjects) - if (auto Sym = KV.second->getSymbol(Name, ExportedSymbolsOnly)) - return Sym; - else if (auto Err = Sym.takeError()) - return std::move(Err); - - return nullptr; - } - - /// Search for the given named symbol in the context of the loaded - /// object represented by the VModuleKey K. - /// @param K The VModuleKey for the object to search in. - /// @param Name The name of the symbol to search for. - /// @param ExportedSymbolsOnly If true, search only for exported symbols. - /// @return A handle for the given named symbol, if it is found in the - /// given object. - JITSymbol findSymbolIn(VModuleKey K, StringRef Name, - bool ExportedSymbolsOnly) { - assert(LinkedObjects.count(K) && "VModuleKey not associated with object"); - return LinkedObjects[K]->getSymbol(Name, ExportedSymbolsOnly); - } - - /// Map section addresses for the object associated with the - /// VModuleKey K. - void mapSectionAddress(VModuleKey K, const void *LocalAddress, - JITTargetAddress TargetAddr) { - assert(LinkedObjects.count(K) && "VModuleKey not associated with object"); - LinkedObjects[K]->mapSectionAddress(LocalAddress, TargetAddr); - } - - /// Immediately emit and finalize the object represented by the given - /// VModuleKey. - /// @param K VModuleKey for object to emit/finalize. - Error emitAndFinalize(VModuleKey K) { - assert(LinkedObjects.count(K) && "VModuleKey not associated with object"); - return LinkedObjects[K]->finalize(); - } - -private: - ExecutionSession &ES; - - ResourcesGetter GetResources; - NotifyLoadedFtor NotifyLoaded; - NotifyFinalizedFtor NotifyFinalized; - NotifyFreedFtor NotifyFreed; - - // NB! `LinkedObjects` needs to be destroyed before `NotifyFreed` because - // `~ConcreteLinkedObject` calls `NotifyFreed` - std::map> LinkedObjects; - bool ProcessAllSections = false; -}; - } // end namespace orc } // end namespace llvm diff --git a/llvm/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h b/llvm/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h deleted file mode 100644 index d7304cfcf9316..0000000000000 --- a/llvm/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h +++ /dev/null @@ -1,564 +0,0 @@ -//===------ RemoteObjectLayer.h - Forwards objs to a remote -----*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Forwards objects to a remote object layer via RPC. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H -#define LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H - -#include "llvm/ExecutionEngine/Orc/Core.h" -#include "llvm/ExecutionEngine/Orc/LambdaResolver.h" -#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h" -#include "llvm/Object/ObjectFile.h" -#include - -namespace llvm { -namespace orc { - -/// RPC API needed by RemoteObjectClientLayer and RemoteObjectServerLayer. -class RemoteObjectLayerAPI { -public: - - using ObjHandleT = remote::ResourceIdMgr::ResourceId; - -protected: - - using RemoteSymbolId = remote::ResourceIdMgr::ResourceId; - using RemoteSymbol = std::pair; - -public: - - using BadSymbolHandleError = remote::ResourceNotFound; - using BadObjectHandleError = remote::ResourceNotFound; - -protected: - - static const ObjHandleT InvalidObjectHandleId = 0; - static const RemoteSymbolId NullSymbolId = 0; - - class AddObject - : public rpc::Function(std::string)> { - public: - static const char *getName() { return "AddObject"; } - }; - - class RemoveObject - : public rpc::Function { - public: - static const char *getName() { return "RemoveObject"; } - }; - - class FindSymbol - : public rpc::Function(std::string, - bool)> { - public: - static const char *getName() { return "FindSymbol"; } - }; - - class FindSymbolIn - : public rpc::Function(ObjHandleT, std::string, - bool)> { - public: - static const char *getName() { return "FindSymbolIn"; } - }; - - class EmitAndFinalize - : public rpc::Function { - public: - static const char *getName() { return "EmitAndFinalize"; } - }; - - class Lookup - : public rpc::Function(ObjHandleT, std::string)> { - public: - static const char *getName() { return "Lookup"; } - }; - - class LookupInLogicalDylib - : public rpc::Function(ObjHandleT, std::string)> { - public: - static const char *getName() { return "LookupInLogicalDylib"; } - }; - - class ReleaseRemoteSymbol - : public rpc::Function { - public: - static const char *getName() { return "ReleaseRemoteSymbol"; } - }; - - class MaterializeRemoteSymbol - : public rpc::Function(RemoteSymbolId)> { - public: - static const char *getName() { return "MaterializeRemoteSymbol"; } - }; -}; - -/// Base class containing common utilities for RemoteObjectClientLayer and -/// RemoteObjectServerLayer. -template -class RemoteObjectLayer : public RemoteObjectLayerAPI { -public: - - RemoteObjectLayer(RPCEndpoint &Remote, - std::function ReportError) - : Remote(Remote), ReportError(std::move(ReportError)), - SymbolIdMgr(NullSymbolId + 1) { - using ThisT = RemoteObjectLayer; - Remote.template addHandler( - *this, &ThisT::handleReleaseRemoteSymbol); - Remote.template addHandler( - *this, &ThisT::handleMaterializeRemoteSymbol); - } - -protected: - - /// This class is used as the symbol materializer for JITSymbols returned by - /// RemoteObjectLayerClient/RemoteObjectLayerServer -- the materializer knows - /// how to call back to the other RPC endpoint to get the address when - /// requested. - class RemoteSymbolMaterializer { - public: - - /// Construct a RemoteSymbolMaterializer for the given RemoteObjectLayer - /// with the given Id. - RemoteSymbolMaterializer(RemoteObjectLayer &C, - RemoteSymbolId Id) - : C(C), Id(Id) {} - - RemoteSymbolMaterializer(RemoteSymbolMaterializer &&Other) - : C(Other.C), Id(Other.Id) { - Other.Id = 0; - } - - RemoteSymbolMaterializer &operator=(RemoteSymbolMaterializer &&) = delete; - - /// Release the remote symbol. - ~RemoteSymbolMaterializer() { - if (Id) - C.releaseRemoteSymbol(Id); - } - - /// Materialize the symbol on the remote and get its address. - Expected materialize() { - auto Addr = C.materializeRemoteSymbol(Id); - Id = 0; - return Addr; - } - - private: - RemoteObjectLayer &C; - RemoteSymbolId Id; - }; - - /// Convenience function for getting a null remote symbol value. - RemoteSymbol nullRemoteSymbol() { - return RemoteSymbol(0, JITSymbolFlags()); - } - - /// Creates a StringError that contains a copy of Err's log message, then - /// sends that StringError to ReportError. - /// - /// This allows us to locally log error messages for errors that will actually - /// be delivered to the remote. - Error teeLog(Error Err) { - return handleErrors(std::move(Err), - [this](std::unique_ptr EIB) { - ReportError(make_error( - EIB->message(), - EIB->convertToErrorCode())); - return Error(std::move(EIB)); - }); - } - - Error badRemoteSymbolIdError(RemoteSymbolId Id) { - return make_error(Id, "Remote JIT Symbol"); - } - - Error badObjectHandleError(ObjHandleT H) { - return make_error( - H, "Bad object handle"); - } - - /// Create a RemoteSymbol wrapping the given JITSymbol. - Expected jitSymbolToRemote(JITSymbol Sym) { - if (Sym) { - auto Id = SymbolIdMgr.getNext(); - auto Flags = Sym.getFlags(); - assert(!InUseSymbols.count(Id) && "Symbol id already in use"); - InUseSymbols.insert(std::make_pair(Id, std::move(Sym))); - return RemoteSymbol(Id, Flags); - } else if (auto Err = Sym.takeError()) - return teeLog(std::move(Err)); - // else... - return nullRemoteSymbol(); - } - - /// Convert an Expected to a JITSymbol. - JITSymbol remoteToJITSymbol(Expected RemoteSymOrErr) { - if (RemoteSymOrErr) { - auto &RemoteSym = *RemoteSymOrErr; - if (RemoteSym == nullRemoteSymbol()) - return nullptr; - // else... - RemoteSymbolMaterializer RSM(*this, RemoteSym.first); - auto Sym = JITSymbol( - [RSM = std::move(RSM)]() mutable { return RSM.materialize(); }, - RemoteSym.second); - return Sym; - } else - return RemoteSymOrErr.takeError(); - } - - RPCEndpoint &Remote; - std::function ReportError; - -private: - - /// Notify the remote to release the given JITSymbol. - void releaseRemoteSymbol(RemoteSymbolId Id) { - if (auto Err = Remote.template callB(Id)) - ReportError(std::move(Err)); - } - - /// Notify the remote to materialize the JITSymbol with the given Id and - /// return its address. - Expected materializeRemoteSymbol(RemoteSymbolId Id) { - return Remote.template callB(Id); - } - - /// Release the JITSymbol with the given Id. - Error handleReleaseRemoteSymbol(RemoteSymbolId Id) { - auto SI = InUseSymbols.find(Id); - if (SI != InUseSymbols.end()) { - InUseSymbols.erase(SI); - return Error::success(); - } else - return teeLog(badRemoteSymbolIdError(Id)); - } - - /// Run the materializer for the JITSymbol with the given Id and return its - /// address. - Expected handleMaterializeRemoteSymbol(RemoteSymbolId Id) { - auto SI = InUseSymbols.find(Id); - if (SI != InUseSymbols.end()) { - auto AddrOrErr = SI->second.getAddress(); - InUseSymbols.erase(SI); - SymbolIdMgr.release(Id); - if (AddrOrErr) - return *AddrOrErr; - else - return teeLog(AddrOrErr.takeError()); - } else { - return teeLog(badRemoteSymbolIdError(Id)); - } - } - - remote::ResourceIdMgr SymbolIdMgr; - std::map InUseSymbols; -}; - -/// RemoteObjectClientLayer forwards the ORC Object Layer API over an RPC -/// connection. -/// -/// This class can be used as the base layer of a JIT stack on the client and -/// will forward operations to a corresponding RemoteObjectServerLayer on the -/// server (which can be composed on top of a "real" object layer like -/// RTDyldObjectLinkingLayer to actually carry out the operations). -/// -/// Sending relocatable objects to the server (rather than fully relocated -/// bits) allows JIT'd code to be cached on the server side and re-used in -/// subsequent JIT sessions. -template -class RemoteObjectClientLayer : public RemoteObjectLayer { -private: - - using AddObject = RemoteObjectLayerAPI::AddObject; - using RemoveObject = RemoteObjectLayerAPI::RemoveObject; - using FindSymbol = RemoteObjectLayerAPI::FindSymbol; - using FindSymbolIn = RemoteObjectLayerAPI::FindSymbolIn; - using EmitAndFinalize = RemoteObjectLayerAPI::EmitAndFinalize; - using Lookup = RemoteObjectLayerAPI::Lookup; - using LookupInLogicalDylib = RemoteObjectLayerAPI::LookupInLogicalDylib; - - using RemoteObjectLayer::teeLog; - using RemoteObjectLayer::badObjectHandleError; - using RemoteObjectLayer::remoteToJITSymbol; - -public: - - using ObjHandleT = RemoteObjectLayerAPI::ObjHandleT; - using RemoteSymbol = RemoteObjectLayerAPI::RemoteSymbol; - - using ObjectPtr = std::unique_ptr; - - /// Create a RemoteObjectClientLayer that communicates with a - /// RemoteObjectServerLayer instance via the given RPCEndpoint. - /// - /// The ReportError functor can be used locally log errors that are intended - /// to be sent sent - LLVM_ATTRIBUTE_DEPRECATED( - RemoteObjectClientLayer(RPCEndpoint &Remote, - std::function ReportError), - "ORCv1 layers (including RemoteObjectClientLayer) are deprecated. Please " - "use " - "ORCv2 (see docs/ORCv2.rst)"); - - RemoteObjectClientLayer(ORCv1DeprecationAcknowledgement, RPCEndpoint &Remote, - std::function ReportError) - : RemoteObjectLayer(Remote, std::move(ReportError)) { - using ThisT = RemoteObjectClientLayer; - Remote.template addHandler(*this, &ThisT::lookup); - Remote.template addHandler( - *this, &ThisT::lookupInLogicalDylib); - } - - /// Add an object to the JIT. - /// - /// @return A handle that can be used to refer to the loaded object (for - /// symbol searching, finalization, freeing memory, etc.). - Expected - addObject(ObjectPtr ObjBuffer, - std::shared_ptr Resolver) { - if (auto HandleOrErr = - this->Remote.template callB(ObjBuffer->getBuffer())) { - auto &Handle = *HandleOrErr; - // FIXME: Return an error for this: - assert(!Resolvers.count(Handle) && "Handle already in use?"); - Resolvers[Handle] = std::move(Resolver); - return Handle; - } else - return HandleOrErr.takeError(); - } - - /// Remove the given object from the JIT. - Error removeObject(ObjHandleT H) { - return this->Remote.template callB(H); - } - - /// Search for the given named symbol. - JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) { - return remoteToJITSymbol( - this->Remote.template callB(Name, - ExportedSymbolsOnly)); - } - - /// Search for the given named symbol within the given context. - JITSymbol findSymbolIn(ObjHandleT H, StringRef Name, bool ExportedSymbolsOnly) { - return remoteToJITSymbol( - this->Remote.template callB(H, Name, - ExportedSymbolsOnly)); - } - - /// Immediately emit and finalize the object with the given handle. - Error emitAndFinalize(ObjHandleT H) { - return this->Remote.template callB(H); - } - -private: - - Expected lookup(ObjHandleT H, const std::string &Name) { - auto RI = Resolvers.find(H); - if (RI != Resolvers.end()) { - return this->jitSymbolToRemote(RI->second->findSymbol(Name)); - } else - return teeLog(badObjectHandleError(H)); - } - - Expected lookupInLogicalDylib(ObjHandleT H, - const std::string &Name) { - auto RI = Resolvers.find(H); - if (RI != Resolvers.end()) - return this->jitSymbolToRemote( - RI->second->findSymbolInLogicalDylib(Name)); - else - return teeLog(badObjectHandleError(H)); - } - - std::map> - Resolvers; -}; - -/// RemoteObjectServerLayer acts as a server and handling RPC calls for the -/// object layer API from the given RPC connection. -/// -/// This class can be composed on top of a 'real' object layer (e.g. -/// RTDyldObjectLinkingLayer) to do the actual work of relocating objects -/// and making them executable. -template -class RemoteObjectServerLayer : public RemoteObjectLayer { -private: - - using ObjHandleT = RemoteObjectLayerAPI::ObjHandleT; - using RemoteSymbol = RemoteObjectLayerAPI::RemoteSymbol; - - using AddObject = RemoteObjectLayerAPI::AddObject; - using RemoveObject = RemoteObjectLayerAPI::RemoveObject; - using FindSymbol = RemoteObjectLayerAPI::FindSymbol; - using FindSymbolIn = RemoteObjectLayerAPI::FindSymbolIn; - using EmitAndFinalize = RemoteObjectLayerAPI::EmitAndFinalize; - using Lookup = RemoteObjectLayerAPI::Lookup; - using LookupInLogicalDylib = RemoteObjectLayerAPI::LookupInLogicalDylib; - - using RemoteObjectLayer::teeLog; - using RemoteObjectLayer::badObjectHandleError; - using RemoteObjectLayer::remoteToJITSymbol; - -public: - - /// Create a RemoteObjectServerLayer with the given base layer (which must be - /// an object layer), RPC endpoint, and error reporter function. - LLVM_ATTRIBUTE_DEPRECATED( - RemoteObjectServerLayer(BaseLayerT &BaseLayer, RPCEndpoint &Remote, - std::function ReportError), - "ORCv1 layers (including RemoteObjectServerLayer) are deprecated. Please " - "use " - "ORCv2 (see docs/ORCv2.rst)"); - - RemoteObjectServerLayer(ORCv1DeprecationAcknowledgement, - BaseLayerT &BaseLayer, RPCEndpoint &Remote, - std::function ReportError) - : RemoteObjectLayer(Remote, std::move(ReportError)), - BaseLayer(BaseLayer), HandleIdMgr(1) { - using ThisT = RemoteObjectServerLayer; - - Remote.template addHandler(*this, &ThisT::addObject); - Remote.template addHandler(*this, &ThisT::removeObject); - Remote.template addHandler(*this, &ThisT::findSymbol); - Remote.template addHandler(*this, &ThisT::findSymbolIn); - Remote.template addHandler(*this, &ThisT::emitAndFinalize); - } - -private: - - class StringMemoryBuffer : public MemoryBuffer { - public: - StringMemoryBuffer(std::string Buffer) - : Buffer(std::move(Buffer)) { - init(this->Buffer.data(), this->Buffer.data() + this->Buffer.size(), - false); - } - - BufferKind getBufferKind() const override { return MemoryBuffer_Malloc; } - private: - std::string Buffer; - }; - - JITSymbol lookup(ObjHandleT Id, const std::string &Name) { - return remoteToJITSymbol( - this->Remote.template callB(Id, Name)); - } - - JITSymbol lookupInLogicalDylib(ObjHandleT Id, const std::string &Name) { - return remoteToJITSymbol( - this->Remote.template callB(Id, Name)); - } - - Expected addObject(std::string ObjBuffer) { - auto Buffer = std::make_unique(std::move(ObjBuffer)); - auto Id = HandleIdMgr.getNext(); - assert(!BaseLayerHandles.count(Id) && "Id already in use?"); - - auto Resolver = createLambdaResolver( - AcknowledgeORCv1Deprecation, - [this, Id](const std::string &Name) { return lookup(Id, Name); }, - [this, Id](const std::string &Name) { - return lookupInLogicalDylib(Id, Name); - }); - - if (auto HandleOrErr = - BaseLayer.addObject(std::move(Buffer), std::move(Resolver))) { - BaseLayerHandles[Id] = std::move(*HandleOrErr); - return Id; - } else - return teeLog(HandleOrErr.takeError()); - } - - Error removeObject(ObjHandleT H) { - auto HI = BaseLayerHandles.find(H); - if (HI != BaseLayerHandles.end()) { - if (auto Err = BaseLayer.removeObject(HI->second)) - return teeLog(std::move(Err)); - return Error::success(); - } else - return teeLog(badObjectHandleError(H)); - } - - Expected findSymbol(const std::string &Name, - bool ExportedSymbolsOnly) { - if (auto Sym = BaseLayer.findSymbol(Name, ExportedSymbolsOnly)) - return this->jitSymbolToRemote(std::move(Sym)); - else if (auto Err = Sym.takeError()) - return teeLog(std::move(Err)); - return this->nullRemoteSymbol(); - } - - Expected findSymbolIn(ObjHandleT H, const std::string &Name, - bool ExportedSymbolsOnly) { - auto HI = BaseLayerHandles.find(H); - if (HI != BaseLayerHandles.end()) { - if (auto Sym = BaseLayer.findSymbolIn(HI->second, Name, ExportedSymbolsOnly)) - return this->jitSymbolToRemote(std::move(Sym)); - else if (auto Err = Sym.takeError()) - return teeLog(std::move(Err)); - return this->nullRemoteSymbol(); - } else - return teeLog(badObjectHandleError(H)); - } - - Error emitAndFinalize(ObjHandleT H) { - auto HI = BaseLayerHandles.find(H); - if (HI != BaseLayerHandles.end()) { - if (auto Err = BaseLayer.emitAndFinalize(HI->second)) - return teeLog(std::move(Err)); - return Error::success(); - } else - return teeLog(badObjectHandleError(H)); - } - - BaseLayerT &BaseLayer; - remote::ResourceIdMgr HandleIdMgr; - std::map BaseLayerHandles; -}; - -template -RemoteObjectClientLayer::RemoteObjectClientLayer( - RPCEndpoint &Remote, std::function ReportError) - : RemoteObjectLayer(Remote, std::move(ReportError)) { - using ThisT = RemoteObjectClientLayer; - Remote.template addHandler(*this, &ThisT::lookup); - Remote.template addHandler( - *this, &ThisT::lookupInLogicalDylib); -} - -template -RemoteObjectServerLayer::RemoteObjectServerLayer( - BaseLayerT &BaseLayer, RPCEndpoint &Remote, - std::function ReportError) - : RemoteObjectLayer(Remote, std::move(ReportError)), - BaseLayer(BaseLayer), HandleIdMgr(1) { - using ThisT = RemoteObjectServerLayer; - - Remote.template addHandler(*this, &ThisT::addObject); - Remote.template addHandler(*this, &ThisT::removeObject); - Remote.template addHandler(*this, &ThisT::findSymbol); - Remote.template addHandler(*this, &ThisT::findSymbolIn); - Remote.template addHandler(*this, &ThisT::emitAndFinalize); -} - -} // end namespace orc -} // end namespace llvm - -#endif // LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H diff --git a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp index d8bd671c66619..c8bbf0bcdfda7 100644 --- a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp @@ -53,11 +53,6 @@ ExecutionEngine *(*ExecutionEngine::MCJITCtor)( std::shared_ptr Resolver, std::unique_ptr TM) = nullptr; -ExecutionEngine *(*ExecutionEngine::OrcMCJITReplacementCtor)( - std::string *ErrorStr, std::shared_ptr MemMgr, - std::shared_ptr Resolver, - std::unique_ptr TM) = nullptr; - ExecutionEngine *(*ExecutionEngine::InterpCtor)(std::unique_ptr M, std::string *ErrorStr) =nullptr; @@ -476,8 +471,7 @@ EngineBuilder::EngineBuilder() : EngineBuilder(nullptr) {} EngineBuilder::EngineBuilder(std::unique_ptr M) : M(std::move(M)), WhichEngine(EngineKind::Either), ErrorStr(nullptr), - OptLevel(CodeGenOpt::Default), MemMgr(nullptr), Resolver(nullptr), - UseOrcMCJITReplacement(false) { + OptLevel(CodeGenOpt::Default), MemMgr(nullptr), Resolver(nullptr) { // IR module verification is enabled by default in debug builds, and disabled // by default in release builds. #ifndef NDEBUG @@ -540,12 +534,7 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) { } ExecutionEngine *EE = nullptr; - if (ExecutionEngine::OrcMCJITReplacementCtor && UseOrcMCJITReplacement) { - EE = ExecutionEngine::OrcMCJITReplacementCtor(ErrorStr, std::move(MemMgr), - std::move(Resolver), - std::move(TheTM)); - EE->addModule(std::move(M)); - } else if (ExecutionEngine::MCJITCtor) + if (ExecutionEngine::MCJITCtor) EE = ExecutionEngine::MCJITCtor(std::move(M), ErrorStr, std::move(MemMgr), std::move(Resolver), std::move(TheTM)); diff --git a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt index 1876c3512d11a..6396fb5d11876 100644 --- a/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt +++ b/llvm/lib/ExecutionEngine/Orc/CMakeLists.txt @@ -9,18 +9,14 @@ add_llvm_component_library(LLVMOrcJIT IRTransformLayer.cpp JITTargetMachineBuilder.cpp LazyReexports.cpp - Legacy.cpp Layer.cpp LLJIT.cpp MachOPlatform.cpp Mangling.cpp - NullResolver.cpp ObjectLinkingLayer.cpp ObjectTransformLayer.cpp OrcABISupport.cpp - OrcCBindings.cpp OrcV2CBindings.cpp - OrcMCJITReplacement.cpp RTDyldObjectLinkingLayer.cpp Speculation.cpp SpeculateAnalyses.cpp diff --git a/llvm/lib/ExecutionEngine/Orc/Core.cpp b/llvm/lib/ExecutionEngine/Orc/Core.cpp index 243bac79c012f..9227f3f044ac3 100644 --- a/llvm/lib/ExecutionEngine/Orc/Core.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Core.cpp @@ -137,8 +137,6 @@ void AsynchronousSymbolQuery::handleComplete() { TmpNotifyComplete(std::move(ResolvedSymbols)); } -bool AsynchronousSymbolQuery::canStillFail() { return !!NotifyComplete; } - void AsynchronousSymbolQuery::handleFailed(Error Err) { assert(QueryRegistrations.empty() && ResolvedSymbols.empty() && OutstandingSymbolsCount == 0 && @@ -1406,132 +1404,6 @@ Error JITDylib::lodgeQueryImpl(MaterializationUnitList &MUs, }); } -Expected -JITDylib::legacyLookup(std::shared_ptr Q, - SymbolNameSet Names) { - assert(Q && "Query can not be null"); - - ES.runOutstandingMUs(); - - bool QueryComplete = false; - std::vector> MUs; - - SymbolLookupSet Unresolved(Names); - auto Err = ES.runSessionLocked([&, this]() -> Error { - QueryComplete = lookupImpl(Q, MUs, Unresolved); - - // Run any definition generators. - for (auto &DG : DefGenerators) { - - // Bail out early if we have resolved everything. - if (Unresolved.empty()) - break; - - assert(!QueryComplete && "query complete but unresolved symbols remain?"); - if (auto Err = DG->tryToGenerate(LookupKind::Static, *this, - JITDylibLookupFlags::MatchAllSymbols, - Unresolved)) - return Err; - - if (!Unresolved.empty()) - QueryComplete = lookupImpl(Q, MUs, Unresolved); - } - return Error::success(); - }); - - if (Err) - return std::move(Err); - - assert((MUs.empty() || !QueryComplete) && - "If action flags are set, there should be no work to do (so no MUs)"); - - if (QueryComplete) - Q->handleComplete(); - - // FIXME: Swap back to the old code below once RuntimeDyld works with - // callbacks from asynchronous queries. - // Add MUs to the OutstandingMUs list. - { - std::lock_guard Lock(ES.OutstandingMUsMutex); - auto ThisJD = shared_from_this(); - for (auto &MU : MUs) { - auto MR = MU->createMaterializationResponsibility(ThisJD); - ES.OutstandingMUs.push_back(make_pair(std::move(MU), std::move(MR))); - } - } - ES.runOutstandingMUs(); - - // Dispatch any required MaterializationUnits for materialization. - // for (auto &MU : MUs) - // ES.dispatchMaterialization(*this, std::move(MU)); - - SymbolNameSet RemainingSymbols; - for (auto &KV : Unresolved) - RemainingSymbols.insert(KV.first); - - return RemainingSymbols; -} - -bool JITDylib::lookupImpl( - std::shared_ptr &Q, - std::vector> &MUs, - SymbolLookupSet &Unresolved) { - bool QueryComplete = false; - - std::vector ToRemove; - Unresolved.forEachWithRemoval( - [&](const SymbolStringPtr &Name, SymbolLookupFlags Flags) -> bool { - // Search for the name in Symbols. Skip without removing if not found. - auto SymI = Symbols.find(Name); - if (SymI == Symbols.end()) - return false; - - // If the symbol is already in the required state then notify the query - // and remove. - if (SymI->second.getState() >= Q->getRequiredState()) { - Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol()); - if (Q->isComplete()) - QueryComplete = true; - return true; - } - - // If the symbol is lazy, get the MaterialiaztionUnit for it. - if (SymI->second.hasMaterializerAttached()) { - assert(SymI->second.getAddress() == 0 && - "Lazy symbol should not have a resolved address"); - auto UMII = UnmaterializedInfos.find(Name); - assert(UMII != UnmaterializedInfos.end() && - "Lazy symbol should have UnmaterializedInfo"); - auto MU = std::move(UMII->second->MU); - assert(MU != nullptr && "Materializer should not be null"); - - // Kick all symbols associated with this MaterializationUnit into - // materializing state. - for (auto &KV : MU->getSymbols()) { - auto SymK = Symbols.find(KV.first); - assert(SymK != Symbols.end() && "Missing symbol table entry"); - SymK->second.setState(SymbolState::Materializing); - SymK->second.setMaterializerAttached(false); - UnmaterializedInfos.erase(KV.first); - } - - // Add MU to the list of MaterializationUnits to be materialized. - MUs.push_back(std::move(MU)); - } - - // Add the query to the PendingQueries list. - assert(SymI->second.getState() != SymbolState::NeverSearched && - SymI->second.getState() != SymbolState::Ready && - "By this line the symbol should be materializing"); - auto &MI = MaterializingInfos[Name]; - MI.addQuery(Q); - Q->addQueryDependence(*this, Name); - return true; - }); - - return QueryComplete; -} - void JITDylib::dump(raw_ostream &OS) { ES.runSessionLocked([&, this]() { OS << "JITDylib \"" << JITDylibName << "\" (ES: " @@ -1804,88 +1676,6 @@ Expected ExecutionSession::createJITDylib(std::string Name) { return JD; } -void ExecutionSession::legacyFailQuery(AsynchronousSymbolQuery &Q, Error Err) { - assert(!!Err && "Error should be in failure state"); - - bool SendErrorToQuery; - runSessionLocked([&]() { - Q.detach(); - SendErrorToQuery = Q.canStillFail(); - }); - - if (SendErrorToQuery) - Q.handleFailed(std::move(Err)); - else - reportError(std::move(Err)); -} - -Expected ExecutionSession::legacyLookup( - LegacyAsyncLookupFunction AsyncLookup, SymbolNameSet Names, - SymbolState RequiredState, - RegisterDependenciesFunction RegisterDependencies) { -#if LLVM_ENABLE_THREADS - // In the threaded case we use promises to return the results. - std::promise PromisedResult; - Error ResolutionError = Error::success(); - auto NotifyComplete = [&](Expected R) { - if (R) - PromisedResult.set_value(std::move(*R)); - else { - ErrorAsOutParameter _(&ResolutionError); - ResolutionError = R.takeError(); - PromisedResult.set_value(SymbolMap()); - } - }; -#else - SymbolMap Result; - Error ResolutionError = Error::success(); - - auto NotifyComplete = [&](Expected R) { - ErrorAsOutParameter _(&ResolutionError); - if (R) - Result = std::move(*R); - else - ResolutionError = R.takeError(); - }; -#endif - - auto Query = std::make_shared( - SymbolLookupSet(Names), RequiredState, std::move(NotifyComplete)); - // FIXME: This should be run session locked along with the registration code - // and error reporting below. - SymbolNameSet UnresolvedSymbols = AsyncLookup(Query, std::move(Names)); - - // If the query was lodged successfully then register the dependencies, - // otherwise fail it with an error. - if (UnresolvedSymbols.empty()) - RegisterDependencies(Query->QueryRegistrations); - else { - bool DeliverError = runSessionLocked([&]() { - Query->detach(); - return Query->canStillFail(); - }); - auto Err = make_error(std::move(UnresolvedSymbols)); - if (DeliverError) - Query->handleFailed(std::move(Err)); - else - reportError(std::move(Err)); - } - -#if LLVM_ENABLE_THREADS - auto ResultFuture = PromisedResult.get_future(); - auto Result = ResultFuture.get(); - if (ResolutionError) - return std::move(ResolutionError); - return std::move(Result); - -#else - if (ResolutionError) - return std::move(ResolutionError); - - return Result; -#endif -} - std::vector> JITDylib::getDFSLinkOrder(ArrayRef> JDs) { if (JDs.empty()) diff --git a/llvm/lib/ExecutionEngine/Orc/Legacy.cpp b/llvm/lib/ExecutionEngine/Orc/Legacy.cpp deleted file mode 100644 index 67b804c37287d..0000000000000 --- a/llvm/lib/ExecutionEngine/Orc/Legacy.cpp +++ /dev/null @@ -1,68 +0,0 @@ -//===------- Legacy.cpp - Adapters for ExecutionEngine API interop --------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/Legacy.h" - -namespace llvm { -namespace orc { - -void SymbolResolver::anchor() {} - -JITSymbolResolverAdapter::JITSymbolResolverAdapter( - ExecutionSession &ES, SymbolResolver &R, MaterializationResponsibility *MR) - : ES(ES), R(R), MR(MR) {} - -void JITSymbolResolverAdapter::lookup(const LookupSet &Symbols, - OnResolvedFunction OnResolved) { - SymbolNameSet InternedSymbols; - for (auto &S : Symbols) - InternedSymbols.insert(ES.intern(S)); - - auto OnResolvedWithUnwrap = [OnResolved = std::move(OnResolved)]( - Expected InternedResult) mutable { - if (!InternedResult) { - OnResolved(InternedResult.takeError()); - return; - } - - LookupResult Result; - for (auto &KV : *InternedResult) - Result[*KV.first] = std::move(KV.second); - OnResolved(Result); - }; - - auto Q = std::make_shared( - SymbolLookupSet(InternedSymbols), SymbolState::Resolved, - std::move(OnResolvedWithUnwrap)); - - auto Unresolved = R.lookup(Q, InternedSymbols); - if (Unresolved.empty()) { - if (MR) - MR->addDependenciesForAll(Q->QueryRegistrations); - } else - ES.legacyFailQuery(*Q, make_error(std::move(Unresolved))); -} - -Expected -JITSymbolResolverAdapter::getResponsibilitySet(const LookupSet &Symbols) { - SymbolNameSet InternedSymbols; - for (auto &S : Symbols) - InternedSymbols.insert(ES.intern(S)); - - auto InternedResult = R.getResponsibilitySet(InternedSymbols); - LookupSet Result; - for (auto &S : InternedResult) { - ResolvedStrings.insert(S); - Result.insert(*S); - } - - return Result; -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/llvm/lib/ExecutionEngine/Orc/NullResolver.cpp b/llvm/lib/ExecutionEngine/Orc/NullResolver.cpp deleted file mode 100644 index 5b4345b870bb8..0000000000000 --- a/llvm/lib/ExecutionEngine/Orc/NullResolver.cpp +++ /dev/null @@ -1,37 +0,0 @@ -//===---------- NullResolver.cpp - Reject symbol lookup requests ----------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/NullResolver.h" - -#include "llvm/Support/ErrorHandling.h" - -namespace llvm { -namespace orc { - -SymbolNameSet NullResolver::getResponsibilitySet(const SymbolNameSet &Symbols) { - return Symbols; -} - -SymbolNameSet -NullResolver::lookup(std::shared_ptr Query, - SymbolNameSet Symbols) { - assert(Symbols.empty() && "Null resolver: Symbols must be empty"); - return Symbols; -} - -JITSymbol NullLegacyResolver::findSymbol(const std::string &Name) { - llvm_unreachable("Unexpected cross-object symbol reference"); -} - -JITSymbol -NullLegacyResolver::findSymbolInLogicalDylib(const std::string &Name) { - llvm_unreachable("Unexpected cross-object symbol reference"); -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp b/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp deleted file mode 100644 index 28c8479abba44..0000000000000 --- a/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp +++ /dev/null @@ -1,158 +0,0 @@ -//===----------- OrcCBindings.cpp - C bindings for the Orc APIs -----------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "OrcCBindingsStack.h" -#include "llvm-c/OrcBindings.h" -#include "llvm/ExecutionEngine/JITEventListener.h" - -using namespace llvm; - -LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM) { - TargetMachine *TM2(unwrap(TM)); - - Triple T(TM2->getTargetTriple()); - - auto IndirectStubsMgrBuilder = - orc::createLocalIndirectStubsManagerBuilder(T); - - OrcCBindingsStack *JITStack = - new OrcCBindingsStack(*TM2, std::move(IndirectStubsMgrBuilder)); - - return wrap(JITStack); -} - -const char *LLVMOrcGetErrorMsg(LLVMOrcJITStackRef JITStack) { - OrcCBindingsStack &J = *unwrap(JITStack); - return J.getErrorMessage().c_str(); -} - -void LLVMOrcGetMangledSymbol(LLVMOrcJITStackRef JITStack, char **MangledName, - const char *SymbolName) { - OrcCBindingsStack &J = *unwrap(JITStack); - std::string Mangled = J.mangle(SymbolName); - *MangledName = new char[Mangled.size() + 1]; - strcpy(*MangledName, Mangled.c_str()); -} - -void LLVMOrcDisposeMangledSymbol(char *MangledName) { delete[] MangledName; } - -LLVMErrorRef LLVMOrcCreateLazyCompileCallback( - LLVMOrcJITStackRef JITStack, LLVMOrcTargetAddress *RetAddr, - LLVMOrcLazyCompileCallbackFn Callback, void *CallbackCtx) { - OrcCBindingsStack &J = *unwrap(JITStack); - if (auto Addr = J.createLazyCompileCallback(Callback, CallbackCtx)) { - *RetAddr = *Addr; - return LLVMErrorSuccess; - } else - return wrap(Addr.takeError()); -} - -LLVMErrorRef LLVMOrcCreateIndirectStub(LLVMOrcJITStackRef JITStack, - const char *StubName, - LLVMOrcTargetAddress InitAddr) { - OrcCBindingsStack &J = *unwrap(JITStack); - return wrap(J.createIndirectStub(StubName, InitAddr)); -} - -LLVMErrorRef LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack, - const char *StubName, - LLVMOrcTargetAddress NewAddr) { - OrcCBindingsStack &J = *unwrap(JITStack); - return wrap(J.setIndirectStubPointer(StubName, NewAddr)); -} - -LLVMErrorRef LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle *RetHandle, - LLVMModuleRef Mod, - LLVMOrcSymbolResolverFn SymbolResolver, - void *SymbolResolverCtx) { - OrcCBindingsStack &J = *unwrap(JITStack); - std::unique_ptr M(unwrap(Mod)); - if (auto Handle = - J.addIRModuleEager(std::move(M), SymbolResolver, SymbolResolverCtx)) { - *RetHandle = *Handle; - return LLVMErrorSuccess; - } else - return wrap(Handle.takeError()); -} - -LLVMErrorRef LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle *RetHandle, - LLVMModuleRef Mod, - LLVMOrcSymbolResolverFn SymbolResolver, - void *SymbolResolverCtx) { - OrcCBindingsStack &J = *unwrap(JITStack); - std::unique_ptr M(unwrap(Mod)); - if (auto Handle = - J.addIRModuleLazy(std::move(M), SymbolResolver, SymbolResolverCtx)) { - *RetHandle = *Handle; - return LLVMErrorSuccess; - } else - return wrap(Handle.takeError()); -} - -LLVMErrorRef LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle *RetHandle, - LLVMMemoryBufferRef Obj, - LLVMOrcSymbolResolverFn SymbolResolver, - void *SymbolResolverCtx) { - OrcCBindingsStack &J = *unwrap(JITStack); - std::unique_ptr O(unwrap(Obj)); - if (auto Handle = - J.addObject(std::move(O), SymbolResolver, SymbolResolverCtx)) { - *RetHandle = *Handle; - return LLVMErrorSuccess; - } else - return wrap(Handle.takeError()); -} - -LLVMErrorRef LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack, - LLVMOrcModuleHandle H) { - OrcCBindingsStack &J = *unwrap(JITStack); - return wrap(J.removeModule(H)); -} - -LLVMErrorRef LLVMOrcGetSymbolAddress(LLVMOrcJITStackRef JITStack, - LLVMOrcTargetAddress *RetAddr, - const char *SymbolName) { - OrcCBindingsStack &J = *unwrap(JITStack); - if (auto Addr = J.findSymbolAddress(SymbolName, true)) { - *RetAddr = *Addr; - return LLVMErrorSuccess; - } else - return wrap(Addr.takeError()); -} - -LLVMErrorRef LLVMOrcGetSymbolAddressIn(LLVMOrcJITStackRef JITStack, - LLVMOrcTargetAddress *RetAddr, - LLVMOrcModuleHandle H, - const char *SymbolName) { - OrcCBindingsStack &J = *unwrap(JITStack); - if (auto Addr = J.findSymbolAddressIn(H, SymbolName, true)) { - *RetAddr = *Addr; - return LLVMErrorSuccess; - } else - return wrap(Addr.takeError()); -} - -LLVMErrorRef LLVMOrcDisposeInstance(LLVMOrcJITStackRef JITStack) { - auto *J = unwrap(JITStack); - auto Err = J->shutdown(); - delete J; - return wrap(std::move(Err)); -} - -void LLVMOrcRegisterJITEventListener(LLVMOrcJITStackRef JITStack, LLVMJITEventListenerRef L) -{ - unwrap(JITStack)->RegisterJITEventListener(unwrap(L)); -} - -void LLVMOrcUnregisterJITEventListener(LLVMOrcJITStackRef JITStack, LLVMJITEventListenerRef L) -{ - unwrap(JITStack)->UnregisterJITEventListener(unwrap(L)); -} diff --git a/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h b/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h deleted file mode 100644 index 87bb4398765de..0000000000000 --- a/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h +++ /dev/null @@ -1,534 +0,0 @@ -//===- OrcCBindingsStack.h - Orc JIT stack for C bindings -----*- C++ -*---===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H -#define LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H - -#include "llvm-c/OrcBindings.h" -#include "llvm-c/TargetMachine.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/ExecutionEngine/JITEventListener.h" -#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" -#include "llvm/ExecutionEngine/Orc/CompileUtils.h" -#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" -#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" -#include "llvm/ExecutionEngine/Orc/LambdaResolver.h" -#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" -#include "llvm/ExecutionEngine/RuntimeDyld.h" -#include "llvm/ExecutionEngine/SectionMemoryManager.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/Mangler.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/CBindingWrapping.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetMachine.h" -#include -#include -#include -#include -#include -#include -#include -#include - -namespace llvm { - -class OrcCBindingsStack; - -DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef) -DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) - -namespace detail { - -// FIXME: Kill this off once the Layer concept becomes an interface. -class GenericLayer { -public: - virtual ~GenericLayer() = default; - - virtual JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name, - bool ExportedSymbolsOnly) = 0; - virtual Error removeModule(orc::VModuleKey K) = 0; - }; - - template class GenericLayerImpl : public GenericLayer { - public: - GenericLayerImpl(LayerT &Layer) : Layer(Layer) {} - - JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name, - bool ExportedSymbolsOnly) override { - return Layer.findSymbolIn(K, Name, ExportedSymbolsOnly); - } - - Error removeModule(orc::VModuleKey K) override { - return Layer.removeModule(K); - } - - private: - LayerT &Layer; - }; - - template <> - class GenericLayerImpl : public GenericLayer { - private: - using LayerT = orc::LegacyRTDyldObjectLinkingLayer; - public: - GenericLayerImpl(LayerT &Layer) : Layer(Layer) {} - - JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name, - bool ExportedSymbolsOnly) override { - return Layer.findSymbolIn(K, Name, ExportedSymbolsOnly); - } - - Error removeModule(orc::VModuleKey K) override { - return Layer.removeObject(K); - } - - private: - LayerT &Layer; - }; - - template - std::unique_ptr> createGenericLayer(LayerT &Layer) { - return std::make_unique>(Layer); - } - -} // end namespace detail - -class OrcCBindingsStack { -public: - - using CompileCallbackMgr = orc::JITCompileCallbackManager; - using ObjLayerT = orc::LegacyRTDyldObjectLinkingLayer; - using CompileLayerT = orc::LegacyIRCompileLayer; - using CODLayerT = - orc::LegacyCompileOnDemandLayer; - - using CallbackManagerBuilder = - std::function()>; - - using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT; - -private: - - using OwningObject = object::OwningBinary; - - class CBindingsResolver : public orc::SymbolResolver { - public: - CBindingsResolver(OrcCBindingsStack &Stack, - LLVMOrcSymbolResolverFn ExternalResolver, - void *ExternalResolverCtx) - : Stack(Stack), ExternalResolver(std::move(ExternalResolver)), - ExternalResolverCtx(std::move(ExternalResolverCtx)) {} - - orc::SymbolNameSet - getResponsibilitySet(const orc::SymbolNameSet &Symbols) override { - orc::SymbolNameSet Result; - - for (auto &S : Symbols) { - if (auto Sym = findSymbol(std::string(*S))) { - if (!Sym.getFlags().isStrong()) - Result.insert(S); - } else if (auto Err = Sym.takeError()) { - Stack.reportError(std::move(Err)); - return orc::SymbolNameSet(); - } - } - - return Result; - } - - orc::SymbolNameSet - lookup(std::shared_ptr Query, - orc::SymbolNameSet Symbols) override { - orc::SymbolNameSet UnresolvedSymbols; - - for (auto &S : Symbols) { - if (auto Sym = findSymbol(std::string(*S))) { - if (auto Addr = Sym.getAddress()) { - Query->notifySymbolMetRequiredState( - S, JITEvaluatedSymbol(*Addr, Sym.getFlags())); - } else { - Stack.ES.legacyFailQuery(*Query, Addr.takeError()); - return orc::SymbolNameSet(); - } - } else if (auto Err = Sym.takeError()) { - Stack.ES.legacyFailQuery(*Query, std::move(Err)); - return orc::SymbolNameSet(); - } else - UnresolvedSymbols.insert(S); - } - - if (Query->isComplete()) - Query->handleComplete(); - - return UnresolvedSymbols; - } - - private: - JITSymbol findSymbol(const std::string &Name) { - // Search order: - // 1. JIT'd symbols. - // 2. Runtime overrides. - // 3. External resolver (if present). - - if (Stack.CODLayer) { - if (auto Sym = Stack.CODLayer->findSymbol(Name, true)) - return Sym; - else if (auto Err = Sym.takeError()) - return Sym.takeError(); - } else { - if (auto Sym = Stack.CompileLayer.findSymbol(Name, true)) - return Sym; - else if (auto Err = Sym.takeError()) - return Sym.takeError(); - } - - if (auto Sym = Stack.CXXRuntimeOverrides.searchOverrides(Name)) - return Sym; - - if (ExternalResolver) - return JITSymbol(ExternalResolver(Name.c_str(), ExternalResolverCtx), - JITSymbolFlags::Exported); - - return JITSymbol(nullptr); - } - - OrcCBindingsStack &Stack; - LLVMOrcSymbolResolverFn ExternalResolver; - void *ExternalResolverCtx = nullptr; - }; - -public: - OrcCBindingsStack(TargetMachine &TM, - IndirectStubsManagerBuilder IndirectStubsMgrBuilder) - : CCMgr(createCompileCallbackManager(TM, ES)), DL(TM.createDataLayout()), - IndirectStubsMgr(IndirectStubsMgrBuilder()), - ObjectLayer( - AcknowledgeORCv1Deprecation, ES, - [this](orc::VModuleKey K) { - auto ResolverI = Resolvers.find(K); - assert(ResolverI != Resolvers.end() && - "No resolver for module K"); - auto Resolver = std::move(ResolverI->second); - Resolvers.erase(ResolverI); - return ObjLayerT::Resources{ - std::make_shared(), Resolver}; - }, - nullptr, - [this](orc::VModuleKey K, const object::ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &LoadedObjInfo) { - this->notifyFinalized(K, Obj, LoadedObjInfo); - }, - [this](orc::VModuleKey K, const object::ObjectFile &Obj) { - this->notifyFreed(K, Obj); - }), - CompileLayer(AcknowledgeORCv1Deprecation, ObjectLayer, - orc::SimpleCompiler(TM)), - CODLayer(createCODLayer(ES, CompileLayer, CCMgr.get(), - std::move(IndirectStubsMgrBuilder), Resolvers)), - CXXRuntimeOverrides( - AcknowledgeORCv1Deprecation, - [this](const std::string &S) { return mangle(S); }) {} - - Error shutdown() { - // Run any destructors registered with __cxa_atexit. - CXXRuntimeOverrides.runDestructors(); - // Run any IR destructors. - for (auto &DtorRunner : IRStaticDestructorRunners) - if (auto Err = DtorRunner.runViaLayer(*this)) - return Err; - return Error::success(); - } - - std::string mangle(StringRef Name) { - std::string MangledName; - { - raw_string_ostream MangledNameStream(MangledName); - Mangler::getNameWithPrefix(MangledNameStream, Name, DL); - } - return MangledName; - } - - template - static PtrTy fromTargetAddress(JITTargetAddress Addr) { - return reinterpret_cast(static_cast(Addr)); - } - - Expected - createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback, - void *CallbackCtx) { - auto WrappedCallback = [=]() -> JITTargetAddress { - return Callback(wrap(this), CallbackCtx); - }; - - return CCMgr->getCompileCallback(std::move(WrappedCallback)); - } - - Error createIndirectStub(StringRef StubName, JITTargetAddress Addr) { - return IndirectStubsMgr->createStub(StubName, Addr, - JITSymbolFlags::Exported); - } - - Error setIndirectStubPointer(StringRef Name, JITTargetAddress Addr) { - return IndirectStubsMgr->updatePointer(Name, Addr); - } - - template - Expected - addIRModule(LayerT &Layer, std::unique_ptr M, - std::unique_ptr MemMgr, - LLVMOrcSymbolResolverFn ExternalResolver, - void *ExternalResolverCtx) { - - // Attach a data-layout if one isn't already present. - if (M->getDataLayout().isDefault()) - M->setDataLayout(DL); - - // Record the static constructors and destructors. We have to do this before - // we hand over ownership of the module to the JIT. - std::vector CtorNames, DtorNames; - for (auto Ctor : orc::getConstructors(*M)) - CtorNames.push_back(mangle(Ctor.Func->getName())); - for (auto Dtor : orc::getDestructors(*M)) - DtorNames.push_back(mangle(Dtor.Func->getName())); - - // Add the module to the JIT. - auto K = ES.allocateVModule(); - Resolvers[K] = std::make_shared(*this, ExternalResolver, - ExternalResolverCtx); - if (auto Err = Layer.addModule(K, std::move(M))) - return std::move(Err); - - KeyLayers[K] = detail::createGenericLayer(Layer); - - // Run the static constructors, and save the static destructor runner for - // execution when the JIT is torn down. - orc::LegacyCtorDtorRunner CtorRunner( - AcknowledgeORCv1Deprecation, std::move(CtorNames), K); - if (auto Err = CtorRunner.runViaLayer(*this)) - return std::move(Err); - - IRStaticDestructorRunners.emplace_back(AcknowledgeORCv1Deprecation, - std::move(DtorNames), K); - - return K; - } - - Expected - addIRModuleEager(std::unique_ptr M, - LLVMOrcSymbolResolverFn ExternalResolver, - void *ExternalResolverCtx) { - return addIRModule(CompileLayer, std::move(M), - std::make_unique(), - std::move(ExternalResolver), ExternalResolverCtx); - } - - Expected - addIRModuleLazy(std::unique_ptr M, - LLVMOrcSymbolResolverFn ExternalResolver, - void *ExternalResolverCtx) { - if (!CODLayer) - return make_error("Can not add lazy module: No compile " - "callback manager available", - inconvertibleErrorCode()); - - return addIRModule(*CODLayer, std::move(M), - std::make_unique(), - std::move(ExternalResolver), ExternalResolverCtx); - } - - Error removeModule(orc::VModuleKey K) { - // FIXME: Should error release the module key? - if (auto Err = KeyLayers[K]->removeModule(K)) - return Err; - ES.releaseVModule(K); - KeyLayers.erase(K); - return Error::success(); - } - - Expected addObject(std::unique_ptr ObjBuffer, - LLVMOrcSymbolResolverFn ExternalResolver, - void *ExternalResolverCtx) { - if (auto Obj = object::ObjectFile::createObjectFile( - ObjBuffer->getMemBufferRef())) { - - auto K = ES.allocateVModule(); - Resolvers[K] = std::make_shared( - *this, ExternalResolver, ExternalResolverCtx); - - if (auto Err = ObjectLayer.addObject(K, std::move(ObjBuffer))) - return std::move(Err); - - KeyLayers[K] = detail::createGenericLayer(ObjectLayer); - - return K; - } else - return Obj.takeError(); - } - - JITSymbol findSymbol(const std::string &Name, - bool ExportedSymbolsOnly) { - if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly)) - return Sym; - if (CODLayer) - return CODLayer->findSymbol(mangle(Name), ExportedSymbolsOnly); - return CompileLayer.findSymbol(mangle(Name), ExportedSymbolsOnly); - } - - JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name, - bool ExportedSymbolsOnly) { - assert(KeyLayers.count(K) && "looking up symbol in unknown module"); - return KeyLayers[K]->findSymbolIn(K, mangle(Name), ExportedSymbolsOnly); - } - - Expected findSymbolAddress(const std::string &Name, - bool ExportedSymbolsOnly) { - if (auto Sym = findSymbol(Name, ExportedSymbolsOnly)) { - // Successful lookup, non-null symbol: - if (auto AddrOrErr = Sym.getAddress()) - return *AddrOrErr; - else - return AddrOrErr.takeError(); - } else if (auto Err = Sym.takeError()) { - // Lookup failure - report error. - return std::move(Err); - } - - // No symbol not found. Return 0. - return 0; - } - - Expected findSymbolAddressIn(orc::VModuleKey K, - const std::string &Name, - bool ExportedSymbolsOnly) { - if (auto Sym = findSymbolIn(K, Name, ExportedSymbolsOnly)) { - // Successful lookup, non-null symbol: - if (auto AddrOrErr = Sym.getAddress()) - return *AddrOrErr; - else - return AddrOrErr.takeError(); - } else if (auto Err = Sym.takeError()) { - // Lookup failure - report error. - return std::move(Err); - } - - // Symbol not found. Return 0. - return 0; - } - - const std::string &getErrorMessage() const { return ErrMsg; } - - void RegisterJITEventListener(JITEventListener *L) { - if (!L) - return; - EventListeners.push_back(L); - } - - void UnregisterJITEventListener(JITEventListener *L) { - if (!L) - return; - - auto I = find(reverse(EventListeners), L); - if (I != EventListeners.rend()) { - std::swap(*I, EventListeners.back()); - EventListeners.pop_back(); - } - } - -private: - using ResolverMap = - std::map>; - - static std::unique_ptr - createCompileCallbackManager(TargetMachine &TM, orc::ExecutionSession &ES) { - auto CCMgr = createLocalCompileCallbackManager(TM.getTargetTriple(), ES, 0); - if (!CCMgr) { - // FIXME: It would be good if we could report this somewhere, but we do - // have an instance yet. - logAllUnhandledErrors(CCMgr.takeError(), errs(), "ORC error: "); - return nullptr; - } - return std::move(*CCMgr); - } - - static std::unique_ptr - createCODLayer(orc::ExecutionSession &ES, CompileLayerT &CompileLayer, - CompileCallbackMgr *CCMgr, - IndirectStubsManagerBuilder IndirectStubsMgrBuilder, - ResolverMap &Resolvers) { - // If there is no compile callback manager available we can not create a - // compile on demand layer. - if (!CCMgr) - return nullptr; - - return std::make_unique( - AcknowledgeORCv1Deprecation, ES, CompileLayer, - [&Resolvers](orc::VModuleKey K) { - auto ResolverI = Resolvers.find(K); - assert(ResolverI != Resolvers.end() && "No resolver for module K"); - return ResolverI->second; - }, - [&Resolvers](orc::VModuleKey K, - std::shared_ptr Resolver) { - assert(!Resolvers.count(K) && "Resolver already present"); - Resolvers[K] = std::move(Resolver); - }, - [](Function &F) { return std::set({&F}); }, *CCMgr, - std::move(IndirectStubsMgrBuilder), false); - } - - void reportError(Error Err) { - // FIXME: Report errors on the execution session. - logAllUnhandledErrors(std::move(Err), errs(), "ORC error: "); - }; - - void notifyFinalized(orc::VModuleKey K, - const object::ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &LoadedObjInfo) { - uint64_t Key = static_cast( - reinterpret_cast(Obj.getData().data())); - for (auto &Listener : EventListeners) - Listener->notifyObjectLoaded(Key, Obj, LoadedObjInfo); - } - - void notifyFreed(orc::VModuleKey K, const object::ObjectFile &Obj) { - uint64_t Key = static_cast( - reinterpret_cast(Obj.getData().data())); - for (auto &Listener : EventListeners) - Listener->notifyFreeingObject(Key); - } - - orc::ExecutionSession ES; - std::unique_ptr CCMgr; - - std::vector EventListeners; - - DataLayout DL; - SectionMemoryManager CCMgrMemMgr; - - std::unique_ptr IndirectStubsMgr; - - ObjLayerT ObjectLayer; - CompileLayerT CompileLayer; - std::unique_ptr CODLayer; - - std::map> KeyLayers; - - orc::LegacyLocalCXXRuntimeOverrides CXXRuntimeOverrides; - std::vector> IRStaticDestructorRunners; - std::string ErrMsg; - - ResolverMap Resolvers; -}; - -} // end namespace llvm - -#endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H diff --git a/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp b/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp deleted file mode 100644 index 772a9c2c4ab2f..0000000000000 --- a/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp +++ /dev/null @@ -1,138 +0,0 @@ -//===-------- OrcMCJITReplacement.cpp - Orc-based MCJIT replacement -------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "OrcMCJITReplacement.h" -#include "llvm/ExecutionEngine/GenericValue.h" - -namespace { - -static struct RegisterJIT { - RegisterJIT() { llvm::orc::OrcMCJITReplacement::Register(); } -} JITRegistrator; - -} - -extern "C" void LLVMLinkInOrcMCJITReplacement() {} - -namespace llvm { -namespace orc { - -GenericValue -OrcMCJITReplacement::runFunction(Function *F, - ArrayRef ArgValues) { - assert(F && "Function *F was null at entry to run()"); - - void *FPtr = getPointerToFunction(F); - assert(FPtr && "Pointer to fn's code was null after getPointerToFunction"); - FunctionType *FTy = F->getFunctionType(); - Type *RetTy = FTy->getReturnType(); - - assert((FTy->getNumParams() == ArgValues.size() || - (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && - "Wrong number of arguments passed into function!"); - assert(FTy->getNumParams() == ArgValues.size() && - "This doesn't support passing arguments through varargs (yet)!"); - - // Handle some common cases first. These cases correspond to common `main' - // prototypes. - if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) { - switch (ArgValues.size()) { - case 3: - if (FTy->getParamType(0)->isIntegerTy(32) && - FTy->getParamType(1)->isPointerTy() && - FTy->getParamType(2)->isPointerTy()) { - int (*PF)(int, char **, const char **) = - (int (*)(int, char **, const char **))(intptr_t)FPtr; - - // Call the function. - GenericValue rv; - rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), - (char **)GVTOP(ArgValues[1]), - (const char **)GVTOP(ArgValues[2]))); - return rv; - } - break; - case 2: - if (FTy->getParamType(0)->isIntegerTy(32) && - FTy->getParamType(1)->isPointerTy()) { - int (*PF)(int, char **) = (int (*)(int, char **))(intptr_t)FPtr; - - // Call the function. - GenericValue rv; - rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), - (char **)GVTOP(ArgValues[1]))); - return rv; - } - break; - case 1: - if (FTy->getNumParams() == 1 && FTy->getParamType(0)->isIntegerTy(32)) { - GenericValue rv; - int (*PF)(int) = (int (*)(int))(intptr_t)FPtr; - rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue())); - return rv; - } - break; - } - } - - // Handle cases where no arguments are passed first. - if (ArgValues.empty()) { - GenericValue rv; - switch (RetTy->getTypeID()) { - default: - llvm_unreachable("Unknown return type for function call!"); - case Type::IntegerTyID: { - unsigned BitWidth = cast(RetTy)->getBitWidth(); - if (BitWidth == 1) - rv.IntVal = APInt(BitWidth, ((bool (*)())(intptr_t)FPtr)()); - else if (BitWidth <= 8) - rv.IntVal = APInt(BitWidth, ((char (*)())(intptr_t)FPtr)()); - else if (BitWidth <= 16) - rv.IntVal = APInt(BitWidth, ((short (*)())(intptr_t)FPtr)()); - else if (BitWidth <= 32) - rv.IntVal = APInt(BitWidth, ((int (*)())(intptr_t)FPtr)()); - else if (BitWidth <= 64) - rv.IntVal = APInt(BitWidth, ((int64_t (*)())(intptr_t)FPtr)()); - else - llvm_unreachable("Integer types > 64 bits not supported"); - return rv; - } - case Type::VoidTyID: - rv.IntVal = APInt(32, ((int (*)())(intptr_t)FPtr)()); - return rv; - case Type::FloatTyID: - rv.FloatVal = ((float (*)())(intptr_t)FPtr)(); - return rv; - case Type::DoubleTyID: - rv.DoubleVal = ((double (*)())(intptr_t)FPtr)(); - return rv; - case Type::X86_FP80TyID: - case Type::FP128TyID: - case Type::PPC_FP128TyID: - llvm_unreachable("long double not supported yet"); - case Type::PointerTyID: - return PTOGV(((void *(*)())(intptr_t)FPtr)()); - } - } - - llvm_unreachable("Full-featured argument passing not supported yet!"); -} - -void OrcMCJITReplacement::runStaticConstructorsDestructors(bool isDtors) { - auto &CtorDtorsMap = isDtors ? UnexecutedDestructors : UnexecutedConstructors; - - for (auto &KV : CtorDtorsMap) - cantFail(LegacyCtorDtorRunner( - AcknowledgeORCv1Deprecation, std::move(KV.second), KV.first) - .runViaLayer(LazyEmitLayer)); - - CtorDtorsMap.clear(); -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h b/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h deleted file mode 100644 index 139572bd69779..0000000000000 --- a/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h +++ /dev/null @@ -1,502 +0,0 @@ -//===- OrcMCJITReplacement.h - Orc based MCJIT replacement ------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Orc based MCJIT replacement. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H -#define LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" -#include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/ExecutionEngine/Orc/CompileUtils.h" -#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" -#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" -#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h" -#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" -#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" -#include "llvm/ExecutionEngine/RuntimeDyld.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/Mangler.h" -#include "llvm/IR/Module.h" -#include "llvm/Object/Archive.h" -#include "llvm/Object/Binary.h" -#include "llvm/Object/ObjectFile.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetMachine.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace llvm { - -class ObjectCache; - -namespace orc { - -class OrcMCJITReplacement : public ExecutionEngine { - - // OrcMCJITReplacement needs to do a little extra book-keeping to ensure that - // Orc's automatic finalization doesn't kick in earlier than MCJIT clients are - // expecting - see finalizeMemory. - class MCJITReplacementMemMgr : public MCJITMemoryManager { - public: - MCJITReplacementMemMgr(OrcMCJITReplacement &M, - std::shared_ptr ClientMM) - : M(M), ClientMM(std::move(ClientMM)) {} - - uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, - StringRef SectionName) override { - uint8_t *Addr = - ClientMM->allocateCodeSection(Size, Alignment, SectionID, - SectionName); - M.SectionsAllocatedSinceLastLoad.insert(Addr); - return Addr; - } - - uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, StringRef SectionName, - bool IsReadOnly) override { - uint8_t *Addr = ClientMM->allocateDataSection(Size, Alignment, SectionID, - SectionName, IsReadOnly); - M.SectionsAllocatedSinceLastLoad.insert(Addr); - return Addr; - } - - void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign, - uintptr_t RODataSize, uint32_t RODataAlign, - uintptr_t RWDataSize, - uint32_t RWDataAlign) override { - return ClientMM->reserveAllocationSpace(CodeSize, CodeAlign, - RODataSize, RODataAlign, - RWDataSize, RWDataAlign); - } - - bool needsToReserveAllocationSpace() override { - return ClientMM->needsToReserveAllocationSpace(); - } - - void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, - size_t Size) override { - return ClientMM->registerEHFrames(Addr, LoadAddr, Size); - } - - void deregisterEHFrames() override { - return ClientMM->deregisterEHFrames(); - } - - void notifyObjectLoaded(RuntimeDyld &RTDyld, - const object::ObjectFile &O) override { - return ClientMM->notifyObjectLoaded(RTDyld, O); - } - - void notifyObjectLoaded(ExecutionEngine *EE, - const object::ObjectFile &O) override { - return ClientMM->notifyObjectLoaded(EE, O); - } - - bool finalizeMemory(std::string *ErrMsg = nullptr) override { - // Each set of objects loaded will be finalized exactly once, but since - // symbol lookup during relocation may recursively trigger the - // loading/relocation of other modules, and since we're forwarding all - // finalizeMemory calls to a single underlying memory manager, we need to - // defer forwarding the call on until all necessary objects have been - // loaded. Otherwise, during the relocation of a leaf object, we will end - // up finalizing memory, causing a crash further up the stack when we - // attempt to apply relocations to finalized memory. - // To avoid finalizing too early, look at how many objects have been - // loaded but not yet finalized. This is a bit of a hack that relies on - // the fact that we're lazily emitting object files: The only way you can - // get more than one set of objects loaded but not yet finalized is if - // they were loaded during relocation of another set. - if (M.UnfinalizedSections.size() == 1) - return ClientMM->finalizeMemory(ErrMsg); - return false; - } - - private: - OrcMCJITReplacement &M; - std::shared_ptr ClientMM; - }; - - class LinkingORCResolver : public orc::SymbolResolver { - public: - LinkingORCResolver(OrcMCJITReplacement &M) : M(M) {} - - SymbolNameSet getResponsibilitySet(const SymbolNameSet &Symbols) override { - SymbolNameSet Result; - - for (auto &S : Symbols) { - if (auto Sym = M.findMangledSymbol(*S)) { - if (!Sym.getFlags().isStrong()) - Result.insert(S); - } else if (auto Err = Sym.takeError()) { - M.reportError(std::move(Err)); - return SymbolNameSet(); - } else { - if (auto Sym2 = - M.ClientResolver->findSymbolInLogicalDylib(std::string(*S))) { - if (!Sym2.getFlags().isStrong()) - Result.insert(S); - } else if (auto Err = Sym2.takeError()) { - M.reportError(std::move(Err)); - return SymbolNameSet(); - } else - Result.insert(S); - } - } - - return Result; - } - - SymbolNameSet lookup(std::shared_ptr Query, - SymbolNameSet Symbols) override { - SymbolNameSet UnresolvedSymbols; - bool NewSymbolsResolved = false; - - for (auto &S : Symbols) { - if (auto Sym = M.findMangledSymbol(*S)) { - if (auto Addr = Sym.getAddress()) { - Query->notifySymbolMetRequiredState( - S, JITEvaluatedSymbol(*Addr, Sym.getFlags())); - NewSymbolsResolved = true; - } else { - M.ES.legacyFailQuery(*Query, Addr.takeError()); - return SymbolNameSet(); - } - } else if (auto Err = Sym.takeError()) { - M.ES.legacyFailQuery(*Query, std::move(Err)); - return SymbolNameSet(); - } else { - if (auto Sym2 = M.ClientResolver->findSymbol(std::string(*S))) { - if (auto Addr = Sym2.getAddress()) { - Query->notifySymbolMetRequiredState( - S, JITEvaluatedSymbol(*Addr, Sym2.getFlags())); - NewSymbolsResolved = true; - } else { - M.ES.legacyFailQuery(*Query, Addr.takeError()); - return SymbolNameSet(); - } - } else if (auto Err = Sym2.takeError()) { - M.ES.legacyFailQuery(*Query, std::move(Err)); - return SymbolNameSet(); - } else - UnresolvedSymbols.insert(S); - } - } - - if (NewSymbolsResolved && Query->isComplete()) - Query->handleComplete(); - - return UnresolvedSymbols; - } - - private: - OrcMCJITReplacement &M; - }; - -private: - static ExecutionEngine * - createOrcMCJITReplacement(std::string *ErrorMsg, - std::shared_ptr MemMgr, - std::shared_ptr Resolver, - std::unique_ptr TM) { - return new OrcMCJITReplacement(std::move(MemMgr), std::move(Resolver), - std::move(TM)); - } - - void reportError(Error Err) { - logAllUnhandledErrors(std::move(Err), errs(), "MCJIT error: "); - } - -public: - OrcMCJITReplacement(std::shared_ptr MemMgr, - std::shared_ptr ClientResolver, - std::unique_ptr TM) - : ExecutionEngine(TM->createDataLayout()), TM(std::move(TM)), - MemMgr( - std::make_shared(*this, std::move(MemMgr))), - Resolver(std::make_shared(*this)), - ClientResolver(std::move(ClientResolver)), NotifyObjectLoaded(*this), - NotifyFinalized(*this), - ObjectLayer( - AcknowledgeORCv1Deprecation, ES, - [this](VModuleKey K) { - return ObjectLayerT::Resources{this->MemMgr, this->Resolver}; - }, - NotifyObjectLoaded, NotifyFinalized), - CompileLayer(AcknowledgeORCv1Deprecation, ObjectLayer, - SimpleCompiler(*this->TM), - [this](VModuleKey K, std::unique_ptr M) { - Modules.push_back(std::move(M)); - }), - LazyEmitLayer(AcknowledgeORCv1Deprecation, CompileLayer) {} - - static void Register() { - OrcMCJITReplacementCtor = createOrcMCJITReplacement; - } - - void addModule(std::unique_ptr M) override { - // If this module doesn't have a DataLayout attached then attach the - // default. - if (M->getDataLayout().isDefault()) { - M->setDataLayout(getDataLayout()); - } else { - assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch"); - } - - // Rename, bump linkage and record static constructors and destructors. - // We have to do this before we hand over ownership of the module to the - // JIT. - std::vector CtorNames, DtorNames; - { - unsigned CtorId = 0, DtorId = 0; - for (auto Ctor : orc::getConstructors(*M)) { - std::string NewCtorName = ("__ORCstatic_ctor." + Twine(CtorId++)).str(); - Ctor.Func->setName(NewCtorName); - Ctor.Func->setLinkage(GlobalValue::ExternalLinkage); - Ctor.Func->setVisibility(GlobalValue::HiddenVisibility); - CtorNames.push_back(mangle(NewCtorName)); - } - for (auto Dtor : orc::getDestructors(*M)) { - std::string NewDtorName = ("__ORCstatic_dtor." + Twine(DtorId++)).str(); - dbgs() << "Found dtor: " << NewDtorName << "\n"; - Dtor.Func->setName(NewDtorName); - Dtor.Func->setLinkage(GlobalValue::ExternalLinkage); - Dtor.Func->setVisibility(GlobalValue::HiddenVisibility); - DtorNames.push_back(mangle(NewDtorName)); - } - } - - auto K = ES.allocateVModule(); - - UnexecutedConstructors[K] = std::move(CtorNames); - UnexecutedDestructors[K] = std::move(DtorNames); - - cantFail(LazyEmitLayer.addModule(K, std::move(M))); - } - - void addObjectFile(std::unique_ptr O) override { - cantFail(ObjectLayer.addObject( - ES.allocateVModule(), MemoryBuffer::getMemBufferCopy(O->getData()))); - } - - void addObjectFile(object::OwningBinary O) override { - std::unique_ptr Obj; - std::unique_ptr ObjBuffer; - std::tie(Obj, ObjBuffer) = O.takeBinary(); - cantFail(ObjectLayer.addObject(ES.allocateVModule(), std::move(ObjBuffer))); - } - - void addArchive(object::OwningBinary A) override { - Archives.push_back(std::move(A)); - } - - bool removeModule(Module *M) override { - auto I = Modules.begin(); - for (auto E = Modules.end(); I != E; ++I) - if (I->get() == M) - break; - if (I == Modules.end()) - return false; - Modules.erase(I); - return true; - } - - uint64_t getSymbolAddress(StringRef Name) { - return cantFail(findSymbol(Name).getAddress()); - } - - JITSymbol findSymbol(StringRef Name) { - return findMangledSymbol(mangle(Name)); - } - - void finalizeObject() override { - // This is deprecated - Aim to remove in ExecutionEngine. - // REMOVE IF POSSIBLE - Doesn't make sense for New JIT. - } - - void mapSectionAddress(const void *LocalAddress, - uint64_t TargetAddress) override { - for (auto &P : UnfinalizedSections) - if (P.second.count(LocalAddress)) - ObjectLayer.mapSectionAddress(P.first, LocalAddress, TargetAddress); - } - - uint64_t getGlobalValueAddress(const std::string &Name) override { - return getSymbolAddress(Name); - } - - uint64_t getFunctionAddress(const std::string &Name) override { - return getSymbolAddress(Name); - } - - void *getPointerToFunction(Function *F) override { - uint64_t FAddr = getSymbolAddress(F->getName()); - return reinterpret_cast(static_cast(FAddr)); - } - - void *getPointerToNamedFunction(StringRef Name, - bool AbortOnFailure = true) override { - uint64_t Addr = getSymbolAddress(Name); - if (!Addr && AbortOnFailure) - llvm_unreachable("Missing symbol!"); - return reinterpret_cast(static_cast(Addr)); - } - - GenericValue runFunction(Function *F, - ArrayRef ArgValues) override; - - void setObjectCache(ObjectCache *NewCache) override { - CompileLayer.getCompiler().setObjectCache(NewCache); - } - - void setProcessAllSections(bool ProcessAllSections) override { - ObjectLayer.setProcessAllSections(ProcessAllSections); - } - - void runStaticConstructorsDestructors(bool isDtors) override; - -private: - JITSymbol findMangledSymbol(StringRef Name) { - if (auto Sym = LazyEmitLayer.findSymbol(std::string(Name), false)) - return Sym; - if (auto Sym = ClientResolver->findSymbol(std::string(Name))) - return Sym; - if (auto Sym = scanArchives(Name)) - return Sym; - - return nullptr; - } - - JITSymbol scanArchives(StringRef Name) { - for (object::OwningBinary &OB : Archives) { - object::Archive *A = OB.getBinary(); - // Look for our symbols in each Archive - auto OptionalChildOrErr = A->findSym(Name); - if (!OptionalChildOrErr) - report_fatal_error(OptionalChildOrErr.takeError()); - auto &OptionalChild = *OptionalChildOrErr; - if (OptionalChild) { - // FIXME: Support nested archives? - Expected> ChildBinOrErr = - OptionalChild->getAsBinary(); - if (!ChildBinOrErr) { - // TODO: Actually report errors helpfully. - consumeError(ChildBinOrErr.takeError()); - continue; - } - std::unique_ptr &ChildBin = ChildBinOrErr.get(); - if (ChildBin->isObject()) { - cantFail(ObjectLayer.addObject( - ES.allocateVModule(), - MemoryBuffer::getMemBufferCopy(ChildBin->getData()))); - if (auto Sym = ObjectLayer.findSymbol(Name, true)) - return Sym; - } - } - } - return nullptr; - } - - class NotifyObjectLoadedT { - public: - using LoadedObjInfoListT = - std::vector>; - - NotifyObjectLoadedT(OrcMCJITReplacement &M) : M(M) {} - - void operator()(VModuleKey K, const object::ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &Info) const { - M.UnfinalizedSections[K] = std::move(M.SectionsAllocatedSinceLastLoad); - M.SectionsAllocatedSinceLastLoad = SectionAddrSet(); - M.MemMgr->notifyObjectLoaded(&M, Obj); - } - private: - OrcMCJITReplacement &M; - }; - - class NotifyFinalizedT { - public: - NotifyFinalizedT(OrcMCJITReplacement &M) : M(M) {} - - void operator()(VModuleKey K, const object::ObjectFile &Obj, - const RuntimeDyld::LoadedObjectInfo &Info) { - M.UnfinalizedSections.erase(K); - } - - private: - OrcMCJITReplacement &M; - }; - - std::string mangle(StringRef Name) { - std::string MangledName; - { - raw_string_ostream MangledNameStream(MangledName); - Mang.getNameWithPrefix(MangledNameStream, Name, getDataLayout()); - } - return MangledName; - } - - using ObjectLayerT = LegacyRTDyldObjectLinkingLayer; - using CompileLayerT = LegacyIRCompileLayer; - using LazyEmitLayerT = LazyEmittingLayer; - - ExecutionSession ES; - - std::unique_ptr TM; - std::shared_ptr MemMgr; - std::shared_ptr Resolver; - std::shared_ptr ClientResolver; - Mangler Mang; - - // IMPORTANT: ShouldDelete *must* come before LocalModules: The shared_ptr - // delete blocks in LocalModules refer to the ShouldDelete map, so - // LocalModules needs to be destructed before ShouldDelete. - std::map ShouldDelete; - - NotifyObjectLoadedT NotifyObjectLoaded; - NotifyFinalizedT NotifyFinalized; - - ObjectLayerT ObjectLayer; - CompileLayerT CompileLayer; - LazyEmitLayerT LazyEmitLayer; - - std::map> UnexecutedConstructors; - std::map> UnexecutedDestructors; - - // We need to store ObjLayerT::ObjSetHandles for each of the object sets - // that have been emitted but not yet finalized so that we can forward the - // mapSectionAddress calls appropriately. - using SectionAddrSet = std::set; - SectionAddrSet SectionsAllocatedSinceLastLoad; - std::map UnfinalizedSections; - - std::vector> Archives; -}; - -} // end namespace orc - -} // end namespace llvm - -#endif // LLVM_LIB_EXECUTIONENGINE_ORC_MCJITREPLACEMENT_H diff --git a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp index 1981039eb9f12..b71e9d4f5f91d 100644 --- a/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.cpp @@ -318,14 +318,5 @@ void RTDyldObjectLinkingLayer::onObjEmit( NotifyEmitted(K, std::move(ObjBuffer)); } -LegacyRTDyldObjectLinkingLayer::LegacyRTDyldObjectLinkingLayer( - ExecutionSession &ES, ResourcesGetter GetResources, - NotifyLoadedFtor NotifyLoaded, NotifyFinalizedFtor NotifyFinalized, - NotifyFreedFtor NotifyFreed) - : ES(ES), GetResources(std::move(GetResources)), - NotifyLoaded(std::move(NotifyLoaded)), - NotifyFinalized(std::move(NotifyFinalized)), - NotifyFreed(std::move(NotifyFreed)), ProcessAllSections(false) {} - } // End namespace orc. } // End namespace llvm. diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/2002-12-16-ArgTest.ll b/llvm/test/ExecutionEngine/OrcMCJIT/2002-12-16-ArgTest.ll deleted file mode 100644 index 825892e9fbdd0..0000000000000 --- a/llvm/test/ExecutionEngine/OrcMCJIT/2002-12-16-ArgTest.ll +++ /dev/null @@ -1,37 +0,0 @@ -; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null - -@.LC0 = internal global [10 x i8] c"argc: %d\0A\00" ; <[10 x i8]*> [#uses=1] - -declare i32 @puts(i8*) - -define void @getoptions(i32* %argc) { -bb0: - ret void -} - -declare i32 @printf(i8*, ...) - -define i32 @main(i32 %argc, i8** %argv) { -bb0: - call i32 (i8*, ...) @printf( i8* getelementptr ([10 x i8], [10 x i8]* @.LC0, i64 0, i64 0), i32 %argc ) ; :0 [#uses=0] - %cast224 = bitcast i8** %argv to i8* ; [#uses=1] - %local = alloca i8* ; [#uses=3] - store i8* %cast224, i8** %local - %cond226 = icmp sle i32 %argc, 0 ; [#uses=1] - br i1 %cond226, label %bb3, label %bb2 -bb2: ; preds = %bb2, %bb0 - %cann-indvar = phi i32 [ 0, %bb0 ], [ %add1-indvar, %bb2 ] ; [#uses=2] - %add1-indvar = add i32 %cann-indvar, 1 ; [#uses=2] - %cann-indvar-idxcast = sext i32 %cann-indvar to i64 ; [#uses=1] - %CT = bitcast i8** %local to i8*** ; [#uses=1] - %reg115 = load i8**, i8*** %CT ; [#uses=1] - %cast235 = getelementptr i8*, i8** %reg115, i64 %cann-indvar-idxcast ; [#uses=1] - %reg117 = load i8*, i8** %cast235 ; [#uses=1] - %reg236 = call i32 @puts( i8* %reg117 ) ; [#uses=0] - %cond239 = icmp slt i32 %add1-indvar, %argc ; [#uses=1] - br i1 %cond239, label %bb2, label %bb3 -bb3: ; preds = %bb2, %bb0 - %cast243 = bitcast i8** %local to i32* ; [#uses=1] - call void @getoptions( i32* %cast243 ) - ret i32 0 -} diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/2003-01-04-ArgumentBug.ll b/llvm/test/ExecutionEngine/OrcMCJIT/2003-01-04-ArgumentBug.ll deleted file mode 100644 index 2061329f25211..0000000000000 --- a/llvm/test/ExecutionEngine/OrcMCJIT/2003-01-04-ArgumentBug.ll +++ /dev/null @@ -1,13 +0,0 @@ -; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null - -define i32 @foo(i32 %X, i32 %Y, double %A) { - %cond212 = fcmp une double %A, 1.000000e+00 ; [#uses=1] - %cast110 = zext i1 %cond212 to i32 ; [#uses=1] - ret i32 %cast110 -} - -define i32 @main() { - %reg212 = call i32 @foo( i32 0, i32 1, double 1.000000e+00 ) ; [#uses=1] - ret i32 %reg212 -} - diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/2003-01-04-LoopTest.ll b/llvm/test/ExecutionEngine/OrcMCJIT/2003-01-04-LoopTest.ll deleted file mode 100644 index a298172e6780a..0000000000000 --- a/llvm/test/ExecutionEngine/OrcMCJIT/2003-01-04-LoopTest.ll +++ /dev/null @@ -1,20 +0,0 @@ -; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null - -define i32 @main() { - call i32 @mylog( i32 4 ) ; :1 [#uses=0] - ret i32 0 -} - -define internal i32 @mylog(i32 %num) { -bb0: - br label %bb2 -bb2: ; preds = %bb2, %bb0 - %reg112 = phi i32 [ 10, %bb2 ], [ 1, %bb0 ] ; [#uses=1] - %cann-indvar = phi i32 [ %cann-indvar, %bb2 ], [ 0, %bb0 ] ; [#uses=1] - %reg114 = add i32 %reg112, 1 ; [#uses=2] - %cond222 = icmp slt i32 %reg114, %num ; [#uses=1] - br i1 %cond222, label %bb2, label %bb3 -bb3: ; preds = %bb2 - ret i32 %reg114 -} - diff --git a/llvm/test/ExecutionEngine/OrcMCJIT/2003-01-04-PhiTest.ll b/llvm/test/ExecutionEngine/OrcMCJIT/2003-01-04-PhiTest.ll deleted file mode 100644 index a24e188438fb5..0000000000000 --- a/llvm/test/ExecutionEngine/OrcMCJIT/2003-01-04-PhiTest.ll +++ /dev/null @@ -1,12 +0,0 @@ -; RUN: %lli -jit-kind=orc-mcjit %s > /dev/null - -define i32 @main() { -;