From 8d992c3d82d340f1dc42fdc5d0d8bc09a9d2fd24 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Tue, 24 Jul 2018 21:09:17 +0000 Subject: [PATCH 0001/1112] Remove unused History class Summary: This class doesn't seem to be used anywhere, so we might as well remove the code. Reviewers: labath Reviewed By: labath Subscribers: labath, mgorny, lldb-commits Differential Revision: https://reviews.llvm.org/D49755 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@337855 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Utility/History.h | 136 --------------------------------- lldb.xcodeproj/project.pbxproj | 2 - source/Utility/CMakeLists.txt | 1 - source/Utility/History.cpp | 24 ------ 4 files changed, 163 deletions(-) delete mode 100644 include/lldb/Utility/History.h delete mode 100644 source/Utility/History.cpp diff --git a/include/lldb/Utility/History.h b/include/lldb/Utility/History.h deleted file mode 100644 index bf8a63315151..000000000000 --- a/include/lldb/Utility/History.h +++ /dev/null @@ -1,136 +0,0 @@ -//===-- History.h -----------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef lldb_History_h_ -#define lldb_History_h_ - -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN - -// C++ Includes -#include -#include -#include - -#include // for size_t -#include - -namespace lldb_private { -class Stream; -} - -namespace lldb_private { - -//---------------------------------------------------------------------- -/// @class HistorySource History.h "lldb/Core/History.h" -/// A class that defines history events. -//---------------------------------------------------------------------- - -class HistorySource { -public: - typedef const void *HistoryEvent; - - HistorySource() : m_mutex(), m_events() {} - - virtual ~HistorySource() {} - - // Create a new history event. Subclasses should use any data or members in - // the subclass of this class to produce a history event and push it onto the - // end of the history stack. - - virtual HistoryEvent CreateHistoryEvent() = 0; - - virtual void DeleteHistoryEvent(HistoryEvent event) = 0; - - virtual void DumpHistoryEvent(Stream &strm, HistoryEvent event) = 0; - - virtual size_t GetHistoryEventCount() = 0; - - virtual HistoryEvent GetHistoryEventAtIndex(uint32_t idx) = 0; - - virtual HistoryEvent GetCurrentHistoryEvent() = 0; - - // Return 0 when lhs == rhs, 1 if lhs > rhs, or -1 if lhs < rhs. - virtual int CompareHistoryEvents(const HistoryEvent lhs, - const HistoryEvent rhs) = 0; - - virtual bool IsCurrentHistoryEvent(const HistoryEvent event) = 0; - -private: - typedef std::stack collection; - - std::recursive_mutex m_mutex; - collection m_events; - - DISALLOW_COPY_AND_ASSIGN(HistorySource); -}; - -//---------------------------------------------------------------------- -/// @class HistorySourceUInt History.h "lldb/Core/History.h" -/// A class that defines history events that are represented by -/// unsigned integers. -/// -/// Any history event that is defined by a unique monotonically increasing -/// unsigned integer -//---------------------------------------------------------------------- - -class HistorySourceUInt : public HistorySource { - HistorySourceUInt(const char *id_name, uintptr_t start_value = 0u) - : HistorySource(), m_name(id_name), m_curr_id(start_value) {} - - ~HistorySourceUInt() override {} - - // Create a new history event. Subclasses should use any data or members in - // the subclass of this class to produce a history event and push it onto the - // end of the history stack. - - HistoryEvent CreateHistoryEvent() override { - ++m_curr_id; - return (HistoryEvent)m_curr_id; - } - - void DeleteHistoryEvent(HistoryEvent event) override { - // Nothing to delete, the event contains the integer - } - - void DumpHistoryEvent(Stream &strm, HistoryEvent event) override; - - size_t GetHistoryEventCount() override { return m_curr_id; } - - HistoryEvent GetHistoryEventAtIndex(uint32_t idx) override { - return (HistoryEvent)((uintptr_t)idx); - } - - HistoryEvent GetCurrentHistoryEvent() override { - return (HistoryEvent)m_curr_id; - } - - // Return 0 when lhs == rhs, 1 if lhs > rhs, or -1 if lhs < rhs. - int CompareHistoryEvents(const HistoryEvent lhs, - const HistoryEvent rhs) override { - uintptr_t lhs_uint = (uintptr_t)lhs; - uintptr_t rhs_uint = (uintptr_t)rhs; - if (lhs_uint < rhs_uint) - return -1; - if (lhs_uint > rhs_uint) - return +1; - return 0; - } - - bool IsCurrentHistoryEvent(const HistoryEvent event) override { - return (uintptr_t)event == m_curr_id; - } - -protected: - std::string m_name; // The name of the history unsigned integer - uintptr_t m_curr_id; // The current value of the history unsigned unteger -}; - -} // namespace lldb_private - -#endif // lldb_History_h_ diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index a63567d0eec4..a7ee7529733e 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -1880,8 +1880,6 @@ 26A0DA4D140F721D006DA411 /* HashedNameToDIE.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HashedNameToDIE.h; sourceTree = ""; }; 2666ADC31B3CB675001FAFD3 /* HexagonDYLDRendezvous.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HexagonDYLDRendezvous.cpp; sourceTree = ""; }; 2666ADC41B3CB675001FAFD3 /* HexagonDYLDRendezvous.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HexagonDYLDRendezvous.h; sourceTree = ""; }; - AFC2DCF21E6E30CF00283714 /* History.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = History.cpp; path = source/Utility/History.cpp; sourceTree = ""; }; - AFC2DCF41E6E30D800283714 /* History.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = History.h; path = include/lldb/Utility/History.h; sourceTree = ""; }; AF1729D4182C907200E0AB97 /* HistoryThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HistoryThread.cpp; path = Utility/HistoryThread.cpp; sourceTree = ""; }; AF061F89182C980000B6A19C /* HistoryThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HistoryThread.h; path = Utility/HistoryThread.h; sourceTree = ""; }; AF1729D5182C907200E0AB97 /* HistoryUnwind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HistoryUnwind.cpp; path = Utility/HistoryUnwind.cpp; sourceTree = ""; }; diff --git a/source/Utility/CMakeLists.txt b/source/Utility/CMakeLists.txt index 0cd8220523c9..91f3c8773731 100644 --- a/source/Utility/CMakeLists.txt +++ b/source/Utility/CMakeLists.txt @@ -53,7 +53,6 @@ add_lldb_library(lldbUtility Environment.cpp FastDemangle.cpp FileSpec.cpp - History.cpp IOObject.cpp JSON.cpp LLDBAssert.cpp diff --git a/source/Utility/History.cpp b/source/Utility/History.cpp deleted file mode 100644 index 10344b67c635..000000000000 --- a/source/Utility/History.cpp +++ /dev/null @@ -1,24 +0,0 @@ -//===-- History.cpp ---------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Utility/History.h" - -// C Includes -#include -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Utility/Stream.h" - -using namespace lldb; -using namespace lldb_private; - -void HistorySourceUInt::DumpHistoryEvent(Stream &strm, HistoryEvent event) { - strm.Printf("%s %" PRIu64, m_name.c_str(), (uint64_t)((uintptr_t)event)); -} From 02e485e743dbec4839c28c4d82aa66fc9f2be3cd Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Tue, 24 Jul 2018 23:19:56 +0000 Subject: [PATCH 0002/1112] Add DumpRegisterValue.cpp. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@337865 91177308-0d34-0410-b5e6-96231b3b80d8 --- lldb.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index a7ee7529733e..6ba0f7a4e8df 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -264,6 +264,7 @@ 2579065F1BD0488D00178368 /* DomainSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2579065E1BD0488D00178368 /* DomainSocket.cpp */; }; 26F5C27710F3D9E4009D5894 /* Driver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26F5C27310F3D9E4009D5894 /* Driver.cpp */; }; 4C4EB7811E6A4DCC002035C0 /* DumpDataExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C4EB77F1E6A4DB8002035C0 /* DumpDataExtractor.cpp */; }; + AFA585D02107EB7400D7689A /* DumpRegisterValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFA585CF2107EB7300D7689A /* DumpRegisterValue.cpp */; }; 9447DE431BD5963300E67212 /* DumpValueObjectOptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9447DE421BD5963300E67212 /* DumpValueObjectOptions.cpp */; }; 268900EA13353E6F00698AC0 /* DynamicLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E7710F1B85900F91463 /* DynamicLoader.cpp */; }; AF27AD551D3603EA00CF2833 /* DynamicLoaderDarwin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF27AD531D3603EA00CF2833 /* DynamicLoaderDarwin.cpp */; }; @@ -335,7 +336,6 @@ AE44FB301BB07EB20033EB62 /* GoUserExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE44FB2C1BB07DD80033EB62 /* GoUserExpression.cpp */; }; 6D95DC011B9DC057000E318A /* HashedNameToDIE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D95DBFE1B9DC057000E318A /* HashedNameToDIE.cpp */; }; 2666ADC81B3CB675001FAFD3 /* HexagonDYLDRendezvous.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2666ADC31B3CB675001FAFD3 /* HexagonDYLDRendezvous.cpp */; }; - AFC2DCF31E6E30CF00283714 /* History.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFC2DCF21E6E30CF00283714 /* History.cpp */; }; AF1729D6182C907200E0AB97 /* HistoryThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF1729D4182C907200E0AB97 /* HistoryThread.cpp */; }; AF1729D7182C907200E0AB97 /* HistoryUnwind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF1729D5182C907200E0AB97 /* HistoryUnwind.cpp */; }; 2689007113353E1A00698AC0 /* Host.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 69A01E1C1236C5D400C660B5 /* Host.cpp */; }; @@ -1735,6 +1735,7 @@ 26F5C27410F3D9E4009D5894 /* Driver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Driver.h; path = tools/driver/Driver.h; sourceTree = ""; }; 4C4EB77F1E6A4DB8002035C0 /* DumpDataExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DumpDataExtractor.cpp; path = source/Core/DumpDataExtractor.cpp; sourceTree = ""; }; 4C4EB7821E6A4DE7002035C0 /* DumpDataExtractor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DumpDataExtractor.h; path = include/lldb/Core/DumpDataExtractor.h; sourceTree = ""; }; + AFA585CF2107EB7300D7689A /* DumpRegisterValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DumpRegisterValue.cpp; path = source/Core/DumpRegisterValue.cpp; sourceTree = ""; }; 9447DE421BD5963300E67212 /* DumpValueObjectOptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DumpValueObjectOptions.cpp; path = source/DataFormatters/DumpValueObjectOptions.cpp; sourceTree = ""; }; 9447DE411BD5962900E67212 /* DumpValueObjectOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DumpValueObjectOptions.h; path = include/lldb/DataFormatters/DumpValueObjectOptions.h; sourceTree = ""; }; 26BC7E7710F1B85900F91463 /* DynamicLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DynamicLoader.cpp; path = source/Core/DynamicLoader.cpp; sourceTree = ""; }; @@ -4484,8 +4485,6 @@ AFC2DCE61E6E2ED000283714 /* FastDemangle.cpp */, AFC2DCED1E6E2F9800283714 /* FastDemangle.h */, 4CBFF0471F579A36004AFA92 /* Flags.h */, - AFC2DCF21E6E30CF00283714 /* History.cpp */, - AFC2DCF41E6E30D800283714 /* History.h */, 236124A61986B50E004EFC37 /* IOObject.h */, 236124A21986B4E2004EFC37 /* IOObject.cpp */, 4C73152119B7D71700F865A4 /* Iterable.h */, @@ -4979,6 +4978,7 @@ 26BC7E7610F1B85900F91463 /* Disassembler.cpp */, 4C4EB7821E6A4DE7002035C0 /* DumpDataExtractor.h */, 4C4EB77F1E6A4DB8002035C0 /* DumpDataExtractor.cpp */, + AFA585CF2107EB7300D7689A /* DumpRegisterValue.cpp */, 26BC7D5F10F1B77400F91463 /* dwarf.h */, 26D9FDC612F784E60003F2EE /* EmulateInstruction.h */, 26D9FDC812F784FD0003F2EE /* EmulateInstruction.cpp */, @@ -7891,7 +7891,6 @@ 26C7C4831BFFEA7E009BD01F /* WindowsMiniDump.cpp in Sources */, 49CA96FD1E6AACC900C03FEE /* DataBufferLLVM.cpp in Sources */, 268900D813353E6F00698AC0 /* Function.cpp in Sources */, - AFC2DCF31E6E30CF00283714 /* History.cpp in Sources */, 268900D913353E6F00698AC0 /* FuncUnwinders.cpp in Sources */, 268900DA13353E6F00698AC0 /* LineEntry.cpp in Sources */, 268900DB13353E6F00698AC0 /* LineTable.cpp in Sources */, @@ -8033,6 +8032,7 @@ 4CC7C6501D5298F30076FF94 /* OCamlLanguage.cpp in Sources */, 2692BA15136610C100F9E14D /* UnwindAssemblyInstEmulation.cpp in Sources */, 263E949F13661AEA00E7D1CE /* UnwindAssembly-x86.cpp in Sources */, + AFA585D02107EB7400D7689A /* DumpRegisterValue.cpp in Sources */, 3FDFDDBD199C3A06009756A7 /* FileAction.cpp in Sources */, 264D8D5013661BD7003A368F /* UnwindAssembly.cpp in Sources */, AF23B4DB19009C66003E2A58 /* FreeBSDSignals.cpp in Sources */, From d290170ef5948508949aa562d32b3ac06c295741 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Tue, 24 Jul 2018 23:52:39 +0000 Subject: [PATCH 0003/1112] Add unit tests for VMRange Subscribers: clayborg, labath, mgorny, lldb-commits Differential Revision: https://reviews.llvm.org/D49415 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@337873 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/Utility/CMakeLists.txt | 1 + unittests/Utility/VMRangeTest.cpp | 152 ++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 unittests/Utility/VMRangeTest.cpp diff --git a/unittests/Utility/CMakeLists.txt b/unittests/Utility/CMakeLists.txt index 5a690184e805..6d9d7a4d0069 100644 --- a/unittests/Utility/CMakeLists.txt +++ b/unittests/Utility/CMakeLists.txt @@ -22,6 +22,7 @@ add_lldb_unittest(UtilityTests UriParserTest.cpp UUIDTest.cpp VASprintfTest.cpp + VMRangeTest.cpp LINK_LIBS lldbUtility diff --git a/unittests/Utility/VMRangeTest.cpp b/unittests/Utility/VMRangeTest.cpp new file mode 100644 index 000000000000..db35c73c7499 --- /dev/null +++ b/unittests/Utility/VMRangeTest.cpp @@ -0,0 +1,152 @@ +//===-- VMRangeTest.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" + +#include + +#include "lldb/Utility/VMRange.h" + +using namespace lldb_private; + +namespace lldb_private { +void PrintTo(const VMRange &v, std::ostream *os) { + (*os) << "VMRange(" << v.GetBaseAddress() << ", " << v.GetEndAddress() << ")"; +} +} // namespace lldb_private + +TEST(VMRange, IsValid) { + VMRange range; + EXPECT_FALSE(range.IsValid()); + + range.Reset(0x1, 0x100); + EXPECT_TRUE(range.IsValid()); + + range.Reset(0x1, 0x1); + EXPECT_FALSE(range.IsValid()); +} + +TEST(VMRange, Clear) { + VMRange range(0x100, 0x200); + EXPECT_NE(VMRange(), range); + range.Clear(); + EXPECT_EQ(VMRange(), range); +} + +TEST(VMRange, Comparison) { + VMRange range1(0x100, 0x200); + VMRange range2(0x100, 0x200); + EXPECT_EQ(range1, range2); + + EXPECT_NE(VMRange(0x100, 0x1ff), range1); + EXPECT_NE(VMRange(0x100, 0x201), range1); + EXPECT_NE(VMRange(0x0ff, 0x200), range1); + EXPECT_NE(VMRange(0x101, 0x200), range1); + + range2.Clear(); + EXPECT_NE(range1, range2); +} + +TEST(VMRange, Reset) { + VMRange range(0x100, 0x200); + EXPECT_FALSE(VMRange(0x200, 0x200) == range); + range.Reset(0x200, 0x200); + EXPECT_TRUE(VMRange(0x200, 0x200) == range); +} + +TEST(VMRange, SetEndAddress) { + VMRange range(0x100, 0x200); + + range.SetEndAddress(0xFF); + EXPECT_EQ(0U, range.GetByteSize()); + EXPECT_FALSE(range.IsValid()); + + range.SetEndAddress(0x101); + EXPECT_EQ(1U, range.GetByteSize()); + EXPECT_TRUE(range.IsValid()); +} + +TEST(VMRange, ContainsAddr) { + VMRange range(0x100, 0x200); + + EXPECT_FALSE(range.Contains(0x00)); + EXPECT_FALSE(range.Contains(0xFF)); + EXPECT_TRUE(range.Contains(0x100)); + EXPECT_TRUE(range.Contains(0x101)); + EXPECT_TRUE(range.Contains(0x1FF)); + EXPECT_FALSE(range.Contains(0x200)); + EXPECT_FALSE(range.Contains(0x201)); + EXPECT_FALSE(range.Contains(0xFFF)); + EXPECT_FALSE(range.Contains(std::numeric_limits::max())); +} + +TEST(VMRange, ContainsRange) { + VMRange range(0x100, 0x200); + + EXPECT_FALSE(range.Contains(VMRange(0x0, 0x0))); + + EXPECT_FALSE(range.Contains(VMRange(0x0, 0x100))); + EXPECT_FALSE(range.Contains(VMRange(0x0, 0x101))); + EXPECT_TRUE(range.Contains(VMRange(0x100, 0x105))); + EXPECT_TRUE(range.Contains(VMRange(0x101, 0x105))); + EXPECT_TRUE(range.Contains(VMRange(0x100, 0x1FF))); + EXPECT_TRUE(range.Contains(VMRange(0x105, 0x200))); + EXPECT_FALSE(range.Contains(VMRange(0x105, 0x201))); + EXPECT_FALSE(range.Contains(VMRange(0x200, 0x201))); + EXPECT_TRUE(range.Contains(VMRange(0x100, 0x200))); + EXPECT_FALSE( + range.Contains(VMRange(0x105, std::numeric_limits::max()))); + + // Empty range. + EXPECT_TRUE(range.Contains(VMRange(0x100, 0x100))); + + range.Clear(); + EXPECT_FALSE(range.Contains(VMRange(0x0, 0x0))); +} + +TEST(VMRange, Ordering) { + VMRange range1(0x44, 0x200); + VMRange range2(0x100, 0x1FF); + VMRange range3(0x100, 0x200); + + EXPECT_LE(range1, range1); + EXPECT_GE(range1, range1); + + EXPECT_LT(range1, range2); + EXPECT_LT(range2, range3); + + EXPECT_GT(range2, range1); + EXPECT_GT(range3, range2); + + // Ensure that < and > are always false when comparing ranges with themselves. + EXPECT_FALSE(range1 < range1); + EXPECT_FALSE(range2 < range2); + EXPECT_FALSE(range3 < range3); + + EXPECT_FALSE(range1 > range1); + EXPECT_FALSE(range2 > range2); + EXPECT_FALSE(range3 > range3); +} + +TEST(VMRange, CollectionContains) { + VMRange::collection collection = {VMRange(0x100, 0x105), + VMRange(0x108, 0x110)}; + + EXPECT_FALSE(VMRange::ContainsValue(collection, 0xFF)); + EXPECT_TRUE(VMRange::ContainsValue(collection, 0x100)); + EXPECT_FALSE(VMRange::ContainsValue(collection, 0x105)); + EXPECT_TRUE(VMRange::ContainsValue(collection, 0x109)); + + EXPECT_TRUE(VMRange::ContainsRange(collection, VMRange(0x100, 0x104))); + EXPECT_TRUE(VMRange::ContainsRange(collection, VMRange(0x108, 0x100))); + EXPECT_FALSE(VMRange::ContainsRange(collection, VMRange(0xFF, 0x100))); + + // TODO: Implement and test ContainsRange with values that span multiple + // ranges in the collection. +} From b032b915ad7eea93e06d571f1a3ca712cd203b9e Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Wed, 25 Jul 2018 11:35:28 +0000 Subject: [PATCH 0004/1112] Fix PythonString::GetString for >=python-3.7 The return value of PyUnicode_AsUTF8AndSize is now "const char *". Thanks to Brett Neumeier for testing the patch out on python 3.7. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@337908 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../ScriptInterpreter/Python/PythonDataObjects.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp index 6a9d57d5a303..90d8ab97fb73 100644 --- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -399,14 +399,16 @@ llvm::StringRef PythonString::GetString() const { return llvm::StringRef(); Py_ssize_t size; - char *c; + const char *data; #if PY_MAJOR_VERSION >= 3 - c = PyUnicode_AsUTF8AndSize(m_py_obj, &size); + data = PyUnicode_AsUTF8AndSize(m_py_obj, &size); #else + char *c; PyString_AsStringAndSize(m_py_obj, &c, &size); + data = c; #endif - return llvm::StringRef(c, size); + return llvm::StringRef(data, size); } size_t PythonString::GetSize() const { From 35f72c923adc554ea7c07130bf911801a2e90cbc Mon Sep 17 00:00:00 2001 From: Stefan Granitz Date: Wed, 25 Jul 2018 15:19:04 +0000 Subject: [PATCH 0005/1112] Use LLVM's new ItaniumPartialDemangler in LLDB Summary: Replace the existing combination of FastDemangle and the fallback to llvm::itaniumDemangle() with LLVM's new ItaniumPartialDemangler. It slightly reduces complexity and slightly improves performance, but doesn't introduce conceptual changes. This patch is preparing for more fundamental improvements on LLDB's demangling approach. Reviewers: friss, jingham, erik.pilkington, labath, clayborg, mgorny, davide, JDevlieghere Reviewed By: JDevlieghere Subscribers: teemperor, JDevlieghere, labath, clayborg, davide, lldb-commits, mgorny, erik.pilkington Differential Revision: https://reviews.llvm.org/D49612 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@337931 91177308-0d34-0410-b5e6-96231b3b80d8 --- cmake/modules/LLDBConfig.cmake | 9 ------- lldb.xcodeproj/project.pbxproj | 12 +++------ source/Core/Mangled.cpp | 45 ++++++++++++---------------------- unittests/Core/CMakeLists.txt | 1 + unittests/Core/MangledTest.cpp | 38 ++++++++++++++++++++++++++++ 5 files changed, 59 insertions(+), 46 deletions(-) create mode 100644 unittests/Core/MangledTest.cpp diff --git a/cmake/modules/LLDBConfig.cmake b/cmake/modules/LLDBConfig.cmake index 32effe7737fa..dae6e365da38 100644 --- a/cmake/modules/LLDBConfig.cmake +++ b/cmake/modules/LLDBConfig.cmake @@ -411,15 +411,6 @@ if(LLDB_USING_LIBSTDCXX) endif() endif() -if(MSVC) - set(LLDB_USE_BUILTIN_DEMANGLER ON) -else() - option(LLDB_USE_BUILTIN_DEMANGLER "Use lldb's builtin demangler instead of the system one" ON) -endif() -if(LLDB_USE_BUILTIN_DEMANGLER) - add_definitions(-DLLDB_USE_BUILTIN_DEMANGLER) -endif() - if ((CMAKE_SYSTEM_NAME MATCHES "Android") AND LLVM_BUILD_STATIC AND ((ANDROID_ABI MATCHES "armeabi") OR (ANDROID_ABI MATCHES "mips"))) add_definitions(-DANDROID_USE_ACCEPT_WORKAROUND) diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index 6ba0f7a4e8df..d8a714415320 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -483,6 +483,7 @@ 9A20573A1F3B8E7E00F6C293 /* MainLoopTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A2057301F3B8E7600F6C293 /* MainLoopTest.cpp */; }; 8C3BD9961EF45DA50016C343 /* MainThreadCheckerRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C3BD9951EF45D9B0016C343 /* MainThreadCheckerRuntime.cpp */; }; 2689004313353E0400698AC0 /* Mangled.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E8010F1B85900F91463 /* Mangled.cpp */; }; + 4F29D3CF21010FA3003B549A /* MangledTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F29D3CD21010F84003B549A /* MangledTest.cpp */; }; 4CD44CFC20B37C440003557C /* ManualDWARFIndex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CD44CF920B37C440003557C /* ManualDWARFIndex.cpp */; }; 49DCF702170E70120092F75E /* Materializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DCF700170E70120092F75E /* Materializer.cpp */; }; 2690B3711381D5C300ECFBAE /* Memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2690B3701381D5C300ECFBAE /* Memory.cpp */; }; @@ -2185,6 +2186,7 @@ 2669415F1A6DC2AB0063BE93 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = "tools/lldb-mi/Makefile"; sourceTree = SOURCE_ROOT; }; 26BC7E8010F1B85900F91463 /* Mangled.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Mangled.cpp; path = source/Core/Mangled.cpp; sourceTree = ""; }; 26BC7D6910F1B77400F91463 /* Mangled.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Mangled.h; path = include/lldb/Core/Mangled.h; sourceTree = ""; }; + 4F29D3CD21010F84003B549A /* MangledTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MangledTest.cpp; sourceTree = ""; }; 4CD44CF920B37C440003557C /* ManualDWARFIndex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ManualDWARFIndex.cpp; sourceTree = ""; }; 4CD44D0020B37C580003557C /* ManualDWARFIndex.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ManualDWARFIndex.h; sourceTree = ""; }; 2682100C143A59AE004BCF2D /* MappedHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MappedHash.h; path = include/lldb/Core/MappedHash.h; sourceTree = ""; }; @@ -3657,6 +3659,7 @@ 23CB14E51D66CBEB00EDDDE1 /* Core */ = { isa = PBXGroup; children = ( + 4F29D3CD21010F84003B549A /* MangledTest.cpp */, 9A3D43E31F3237D500EB767C /* ListenerTest.cpp */, 9A3D43E21F3237D500EB767C /* StateTest.cpp */, 9A3D43E11F3237D500EB767C /* StreamCallbackTest.cpp */, @@ -7443,6 +7446,7 @@ 9A3D43D71F3151C400EB767C /* LogTest.cpp in Sources */, 9A2057181F3B861400F6C293 /* TestType.cpp in Sources */, 9A2057171F3B861400F6C293 /* TestDWARFCallFrameInfo.cpp in Sources */, + 4F29D3CF21010FA3003B549A /* MangledTest.cpp in Sources */, 9A3D43EC1F3237F900EB767C /* ListenerTest.cpp in Sources */, 9A3D43DC1F3151C400EB767C /* TimeoutTest.cpp in Sources */, 9A3D43D61F3151C400EB767C /* ConstStringTest.cpp in Sources */, @@ -9326,14 +9330,12 @@ "-fno-rtti", "-Wglobal-constructors", "$(OTHER_CFLAGS)", - "-DLLDB_USE_BUILTIN_DEMANGLER", "-DLIBXML2_DEFINED", ); "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*]" = ( "-fno-rtti", "-Wglobal-constructors", "$(OTHER_CFLAGS)", - "-DLLDB_USE_BUILTIN_DEMANGLER", "-DLIBXML2_DEFINED", ); OTHER_LDFLAGS = ""; @@ -9385,14 +9387,12 @@ "-fno-rtti", "-Wglobal-constructors", "$(OTHER_CFLAGS)", - "-DLLDB_USE_BUILTIN_DEMANGLER", "-DLIBXML2_DEFINED", ); "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*]" = ( "-fno-rtti", "-Wglobal-constructors", "$(OTHER_CFLAGS)", - "-DLLDB_USE_BUILTIN_DEMANGLER", "-DLIBXML2_DEFINED", ); OTHER_LDFLAGS = ""; @@ -9444,14 +9444,12 @@ "-fno-rtti", "-Wglobal-constructors", "$(OTHER_CFLAGS)", - "-DLLDB_USE_BUILTIN_DEMANGLER", "-DLIBXML2_DEFINED", ); "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*]" = ( "-fno-rtti", "-Wglobal-constructors", "$(OTHER_CFLAGS)", - "-DLLDB_USE_BUILTIN_DEMANGLER", "-DLIBXML2_DEFINED", ); OTHER_LDFLAGS = ""; @@ -10453,14 +10451,12 @@ "-fno-rtti", "-Wglobal-constructors", "$(OTHER_CFLAGS)", - "-DLLDB_USE_BUILTIN_DEMANGLER", "-DLIBXML2_DEFINED", ); "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*]" = ( "-fno-rtti", "-Wglobal-constructors", "$(OTHER_CFLAGS)", - "-DLLDB_USE_BUILTIN_DEMANGLER", "-DLIBXML2_DEFINED", ); OTHER_LDFLAGS = ""; diff --git a/source/Core/Mangled.cpp b/source/Core/Mangled.cpp index 3f64a3d630b7..545ac51c870f 100644 --- a/source/Core/Mangled.cpp +++ b/source/Core/Mangled.cpp @@ -16,34 +16,24 @@ #pragma comment(lib, "dbghelp.lib") #endif -#ifdef LLDB_USE_BUILTIN_DEMANGLER -// Provide a fast-path demangler implemented in FastDemangle.cpp until it can -// replace the existing C++ demangler with a complete implementation -#include "lldb/Utility/FastDemangle.h" -#include "llvm/Demangle/Demangle.h" -#else -// FreeBSD9-STABLE requires this to know about size_t in cxxabi. -#include -#include -#endif - #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/Timer.h" -#include "lldb/lldb-enumerations.h" // for LanguageType +#include "lldb/lldb-enumerations.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" -#include "llvm/ADT/StringRef.h" // for StringRef -#include "llvm/Support/Compiler.h" // for LLVM_PRETT... +#include "llvm/ADT/StringRef.h" +#include "llvm/Demangle/Demangle.h" +#include "llvm/Support/Compiler.h" -#include // for mutex, loc... -#include // for string -#include // for pair +#include +#include +#include #include #include @@ -295,18 +285,15 @@ Mangled::GetDemangledName(lldb::LanguageType language) const { break; } case eManglingSchemeItanium: { -#ifdef LLDB_USE_BUILTIN_DEMANGLER - if (log) - log->Printf("demangle itanium: %s", mangled_name); - // Try to use the fast-path demangler first for the performance win, - // falling back to the full demangler only when necessary - demangled_name = FastDemangle(mangled_name, m_mangled.GetLength()); - if (!demangled_name) - demangled_name = - llvm::itaniumDemangle(mangled_name, NULL, NULL, NULL); -#else - demangled_name = abi::__cxa_demangle(mangled_name, NULL, NULL, NULL); -#endif + llvm::ItaniumPartialDemangler IPD; + bool demangle_err = IPD.partialDemangle(mangled_name); + if (!demangle_err) { + // Default buffer and size (realloc is used in case it's too small). + size_t demangled_size = 80; + demangled_name = static_cast(::malloc(demangled_size)); + demangled_name = IPD.finishDemangle(demangled_name, &demangled_size); + } + if (log) { if (demangled_name) log->Printf("demangled itanium: %s -> \"%s\"", mangled_name, diff --git a/unittests/Core/CMakeLists.txt b/unittests/Core/CMakeLists.txt index f427845c20c6..4affb8cabca9 100644 --- a/unittests/Core/CMakeLists.txt +++ b/unittests/Core/CMakeLists.txt @@ -3,6 +3,7 @@ add_lldb_unittest(LLDBCoreTests DataExtractorTest.cpp EventTest.cpp ListenerTest.cpp + MangledTest.cpp ScalarTest.cpp StateTest.cpp StreamCallbackTest.cpp diff --git a/unittests/Core/MangledTest.cpp b/unittests/Core/MangledTest.cpp new file mode 100644 index 000000000000..7deb901f5601 --- /dev/null +++ b/unittests/Core/MangledTest.cpp @@ -0,0 +1,38 @@ +//===-- MangledTest.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" + +#include "lldb/Core/Mangled.h" + +using namespace lldb; +using namespace lldb_private; + +TEST(MangledTest, ResultForValidName) { + ConstString MangledName("_ZN1a1b1cIiiiEEvm"); + bool IsMangled = true; + + Mangled TheMangled(MangledName, IsMangled); + const ConstString &TheDemangled = + TheMangled.GetDemangledName(eLanguageTypeC_plus_plus); + + ConstString ExpectedResult("void a::b::c(unsigned long)"); + EXPECT_STREQ(ExpectedResult.GetCString(), TheDemangled.GetCString()); +} + +TEST(MangledTest, EmptyForInvalidName) { + ConstString MangledName("_ZN1a1b1cmxktpEEvm"); + bool IsMangled = true; + + Mangled TheMangled(MangledName, IsMangled); + const ConstString &TheDemangled = + TheMangled.GetDemangledName(eLanguageTypeC_plus_plus); + + EXPECT_STREQ("", TheDemangled.GetCString()); +} From 2c9709d155b9d56b9854b3de1e1875d409ef3e37 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Wed, 25 Jul 2018 15:20:15 +0000 Subject: [PATCH 0006/1112] [ProcessGDBRemote] handle result from ConnectToDebugserver We ignored the result from ConnectToDebugserver, causing certain errors (like a failed handshake) not to surface. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@337932 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 547dd0d4108d..b3d33b19bd66 100644 --- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -3484,7 +3484,7 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver( if (m_gdb_comm.IsConnected()) { // Finish the connection process by doing the handshake without // connecting (send NULL URL) - ConnectToDebugserver(""); + error = ConnectToDebugserver(""); } else { error.SetErrorString("connection failed"); } From e183ec776d098c9a89a01518d37fa323eb7c911d Mon Sep 17 00:00:00 2001 From: Davide Italiano Date: Wed, 25 Jul 2018 20:46:29 +0000 Subject: [PATCH 0007/1112] [DataFormatters] Add formatter for C++17 std::optional. Patch by Shafik Yaghmour. Differential Revision: https://reviews.llvm.org/D49271 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@337959 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../libcxx/optional/Makefile | 7 ++ .../TestDataFormatterLibcxxOptional.py | 59 +++++++++++++ .../libcxx/optional/main.cpp | 27 ++++++ .../Language/CPlusPlus/LibCxxOptional.cpp | 85 +++++++++++++++++++ 4 files changed, 178 insertions(+) create mode 100644 packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile create mode 100644 packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py create mode 100644 packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp create mode 100644 source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile new file mode 100644 index 000000000000..a6ea665ef63c --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../../../../make + +CXX_SOURCES := main.cpp + +USE_LIBCPP := 1 +include $(LEVEL)/Makefile.rules +CXXFLAGS += -std=c++17 diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py new file mode 100644 index 000000000000..630b49693f4b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py @@ -0,0 +1,59 @@ +""" +Test lldb data formatter subsystem. +""" + +from __future__ import print_function + + +import os +import time +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class LibcxxOptionalDataFormatterTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @add_test_categories(["libc++"]) + + def test_with_run_command(self): + """Test that that file and class static variables display correctly.""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + bkpt = self.target().FindBreakpointByID( + lldbutil.run_break_set_by_source_regexp( + self, "break here")) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + self.expect("frame variable number_not_engaged", + substrs=['Has Value=false']) + + self.expect("frame variable number_engaged", + substrs=['Has Value=true', + 'Value = 42', + '}']) + + self.expect("frame var numbers", + substrs=['(optional_int_vect) numbers = Has Value=true {', + 'Value = size=4 {', + '[0] = 1', + '[1] = 2', + '[2] = 3', + '[3] = 4', + '}', + '}']) + + self.expect("frame var ostring", + substrs=['(optional_string) ostring = Has Value=true {', + 'Value = "hello"', + '}']) diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp new file mode 100644 index 000000000000..8ff54d1f1190 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp @@ -0,0 +1,27 @@ +#include +#include +#include +#include + +using int_vect = std::vector ; +using optional_int = std::optional ; +using optional_int_vect = std::optional ; +using optional_string = std::optional ; + +int main() +{ + optional_int number_not_engaged ; + optional_int number_engaged = 42 ; + + printf( "%d\n", *number_engaged) ; + + optional_int_vect numbers{{1,2,3,4}} ; + + printf( "%d %d\n", numbers.value()[0], numbers.value()[1] ) ; + + optional_string ostring = "hello" ; + + printf( "%s\n", ostring->c_str() ) ; + + return 0; // break here +} diff --git a/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp new file mode 100644 index 000000000000..762b824f262a --- /dev/null +++ b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp @@ -0,0 +1,85 @@ +//===-- LibCxxOptional.cpp --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LibCxx.h" +#include "lldb/DataFormatters/FormattersHelpers.h" + +using namespace lldb; +using namespace lldb_private; + +namespace { + +class OptionalFrontEnd : public SyntheticChildrenFrontEnd { +public: + OptionalFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) { + Update(); + } + + size_t GetIndexOfChildWithName(const ConstString &name) override { + return formatters::ExtractIndexFromString(name.GetCString()); + } + + bool MightHaveChildren() override { return true; } + bool Update() override; + size_t CalculateNumChildren() override { return m_size; } + ValueObjectSP GetChildAtIndex(size_t idx) override; + +private: + size_t m_size = 0; + ValueObjectSP m_base_sp; +}; +} // namespace + +bool OptionalFrontEnd::Update() { + ValueObjectSP engaged_sp( + m_backend.GetChildMemberWithName(ConstString("__engaged_"), true)); + + if (!engaged_sp) + return false; + + // __engaged_ is a bool flag and is true if the optional contains a value. + // Converting it to unsigned gives us a size of 1 if it contains a value + // and 0 if not. + m_size = engaged_sp->GetValueAsUnsigned(0); + + return false; +} + +ValueObjectSP OptionalFrontEnd::GetChildAtIndex(size_t idx) { + if (idx >= m_size) + return ValueObjectSP(); + + // __val_ contains the underlying value of an optional if it has one. + // Currently because it is part of an anonymous union GetChildMemberWithName() + // does not peer through and find it unless we are at the parent itself. + // We can obtain the parent through __engaged_. + ValueObjectSP val_sp( + m_backend.GetChildMemberWithName(ConstString("__engaged_"), true) + ->GetParent() + ->GetChildAtIndex(0, true) + ->GetChildMemberWithName(ConstString("__val_"), true)); + + if (!val_sp) + return ValueObjectSP(); + + CompilerType holder_type = val_sp->GetCompilerType(); + + if (!holder_type) + return ValueObjectSP(); + + return val_sp->Clone(ConstString(llvm::formatv("Value").str())); +} + +SyntheticChildrenFrontEnd * +formatters::LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *, + lldb::ValueObjectSP valobj_sp) { + if (valobj_sp) + return new OptionalFrontEnd(*valobj_sp); + return nullptr; +} From f8a71facf7fd7c48cb400dea2ead48396f2e1745 Mon Sep 17 00:00:00 2001 From: Davide Italiano Date: Wed, 25 Jul 2018 21:18:20 +0000 Subject: [PATCH 0008/1112] Revert "[DataFormatters] Add formatter for C++17 std::optional." I forgot to git add some files. I'm going to recommit the correct version at once soon. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@337963 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../libcxx/optional/Makefile | 7 -- .../TestDataFormatterLibcxxOptional.py | 59 ------------- .../libcxx/optional/main.cpp | 27 ------ .../Language/CPlusPlus/LibCxxOptional.cpp | 85 ------------------- 4 files changed, 178 deletions(-) delete mode 100644 packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile delete mode 100644 packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py delete mode 100644 packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp delete mode 100644 source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile deleted file mode 100644 index a6ea665ef63c..000000000000 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -LEVEL = ../../../../../make - -CXX_SOURCES := main.cpp - -USE_LIBCPP := 1 -include $(LEVEL)/Makefile.rules -CXXFLAGS += -std=c++17 diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py deleted file mode 100644 index 630b49693f4b..000000000000 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -Test lldb data formatter subsystem. -""" - -from __future__ import print_function - - -import os -import time -import lldb -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil - - -class LibcxxOptionalDataFormatterTestCase(TestBase): - - mydir = TestBase.compute_mydir(__file__) - - @add_test_categories(["libc++"]) - - def test_with_run_command(self): - """Test that that file and class static variables display correctly.""" - self.build() - self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) - - bkpt = self.target().FindBreakpointByID( - lldbutil.run_break_set_by_source_regexp( - self, "break here")) - - self.runCmd("run", RUN_SUCCEEDED) - - # The stop reason of the thread should be breakpoint. - self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, - substrs=['stopped', - 'stop reason = breakpoint']) - - self.expect("frame variable number_not_engaged", - substrs=['Has Value=false']) - - self.expect("frame variable number_engaged", - substrs=['Has Value=true', - 'Value = 42', - '}']) - - self.expect("frame var numbers", - substrs=['(optional_int_vect) numbers = Has Value=true {', - 'Value = size=4 {', - '[0] = 1', - '[1] = 2', - '[2] = 3', - '[3] = 4', - '}', - '}']) - - self.expect("frame var ostring", - substrs=['(optional_string) ostring = Has Value=true {', - 'Value = "hello"', - '}']) diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp deleted file mode 100644 index 8ff54d1f1190..000000000000 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include - -using int_vect = std::vector ; -using optional_int = std::optional ; -using optional_int_vect = std::optional ; -using optional_string = std::optional ; - -int main() -{ - optional_int number_not_engaged ; - optional_int number_engaged = 42 ; - - printf( "%d\n", *number_engaged) ; - - optional_int_vect numbers{{1,2,3,4}} ; - - printf( "%d %d\n", numbers.value()[0], numbers.value()[1] ) ; - - optional_string ostring = "hello" ; - - printf( "%s\n", ostring->c_str() ) ; - - return 0; // break here -} diff --git a/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp deleted file mode 100644 index 762b824f262a..000000000000 --- a/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp +++ /dev/null @@ -1,85 +0,0 @@ -//===-- LibCxxOptional.cpp --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "LibCxx.h" -#include "lldb/DataFormatters/FormattersHelpers.h" - -using namespace lldb; -using namespace lldb_private; - -namespace { - -class OptionalFrontEnd : public SyntheticChildrenFrontEnd { -public: - OptionalFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) { - Update(); - } - - size_t GetIndexOfChildWithName(const ConstString &name) override { - return formatters::ExtractIndexFromString(name.GetCString()); - } - - bool MightHaveChildren() override { return true; } - bool Update() override; - size_t CalculateNumChildren() override { return m_size; } - ValueObjectSP GetChildAtIndex(size_t idx) override; - -private: - size_t m_size = 0; - ValueObjectSP m_base_sp; -}; -} // namespace - -bool OptionalFrontEnd::Update() { - ValueObjectSP engaged_sp( - m_backend.GetChildMemberWithName(ConstString("__engaged_"), true)); - - if (!engaged_sp) - return false; - - // __engaged_ is a bool flag and is true if the optional contains a value. - // Converting it to unsigned gives us a size of 1 if it contains a value - // and 0 if not. - m_size = engaged_sp->GetValueAsUnsigned(0); - - return false; -} - -ValueObjectSP OptionalFrontEnd::GetChildAtIndex(size_t idx) { - if (idx >= m_size) - return ValueObjectSP(); - - // __val_ contains the underlying value of an optional if it has one. - // Currently because it is part of an anonymous union GetChildMemberWithName() - // does not peer through and find it unless we are at the parent itself. - // We can obtain the parent through __engaged_. - ValueObjectSP val_sp( - m_backend.GetChildMemberWithName(ConstString("__engaged_"), true) - ->GetParent() - ->GetChildAtIndex(0, true) - ->GetChildMemberWithName(ConstString("__val_"), true)); - - if (!val_sp) - return ValueObjectSP(); - - CompilerType holder_type = val_sp->GetCompilerType(); - - if (!holder_type) - return ValueObjectSP(); - - return val_sp->Clone(ConstString(llvm::formatv("Value").str())); -} - -SyntheticChildrenFrontEnd * -formatters::LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *, - lldb::ValueObjectSP valobj_sp) { - if (valobj_sp) - return new OptionalFrontEnd(*valobj_sp); - return nullptr; -} From bda26fe08a1425936fbb7294816ed7bda5c6f1d1 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 26 Jul 2018 16:32:05 +0000 Subject: [PATCH 0009/1112] Don't print two errors for unknown commands. Summary: We always print two error messages when we hit an unknown command. As the function `CommandInterpreter::HandleCommand` that prints the second error message unconditionally called the `CommandInterpreter::ResolveCommandImpl` before (which prints the first error message), we can just remove that second error message. Fixes https://bugs.llvm.org/show_bug.cgi?id=38312 Reviewers: labath Reviewed By: labath Subscribers: labath, lldb-commits Differential Revision: https://reviews.llvm.org/D49831 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338040 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../wrong_commands/.categories | 1 + .../wrong_commands/TestWrongCommands.py | 39 +++++++++++++++++++ source/Interpreter/CommandInterpreter.cpp | 27 ------------- 3 files changed, 40 insertions(+), 27 deletions(-) create mode 100644 packages/Python/lldbsuite/test/functionalities/wrong_commands/.categories create mode 100644 packages/Python/lldbsuite/test/functionalities/wrong_commands/TestWrongCommands.py diff --git a/packages/Python/lldbsuite/test/functionalities/wrong_commands/.categories b/packages/Python/lldbsuite/test/functionalities/wrong_commands/.categories new file mode 100644 index 000000000000..3a3f4df6416b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/wrong_commands/.categories @@ -0,0 +1 @@ +cmdline diff --git a/packages/Python/lldbsuite/test/functionalities/wrong_commands/TestWrongCommands.py b/packages/Python/lldbsuite/test/functionalities/wrong_commands/TestWrongCommands.py new file mode 100644 index 000000000000..dcfb434f1e5c --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/wrong_commands/TestWrongCommands.py @@ -0,0 +1,39 @@ +""" +Test how lldb reacts to wrong commands +""" + +from __future__ import print_function + +import os +import time +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class UnknownCommandTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @no_debug_info_test + def test_ambiguous_command(self): + command_interpreter = self.dbg.GetCommandInterpreter() + self.assertTrue(command_interpreter, VALID_COMMAND_INTERPRETER) + result = lldb.SBCommandReturnObject() + + command_interpreter.HandleCommand("g", result) + self.assertFalse(result.Succeeded()) + self.assertRegexpMatches(result.GetError(), "Ambiguous command 'g'. Possible matches:") + self.assertRegexpMatches(result.GetError(), "gui") + self.assertRegexpMatches(result.GetError(), "gdb-remote") + # FIXME: Somehow we get 'gui' and 'gdb-remote' twice in the output. + + @no_debug_info_test + def test_unknown_command(self): + command_interpreter = self.dbg.GetCommandInterpreter() + self.assertTrue(command_interpreter, VALID_COMMAND_INTERPRETER) + result = lldb.SBCommandReturnObject() + + command_interpreter.HandleCommand("qbert", result) + self.assertFalse(result.Succeeded()) + self.assertEquals(result.GetError(), "error: 'qbert' is not a valid command.\n") diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp index df27eb24b529..977c9babedea 100644 --- a/source/Interpreter/CommandInterpreter.cpp +++ b/source/Interpreter/CommandInterpreter.cpp @@ -1693,33 +1693,6 @@ bool CommandInterpreter::HandleCommand(const char *command_line, remainder.c_str()); cmd_obj->Execute(remainder.c_str(), result); - } else { - // We didn't find the first command object, so complete the first argument. - Args command_args(command_string); - StringList matches; - unsigned cursor_char_position = strlen(command_args.GetArgumentAtIndex(0)); - CompletionRequest request(command_line, cursor_char_position, 0, -1, - matches); - int num_matches = HandleCompletionMatches(request); - - if (num_matches > 0) { - std::string error_msg; - error_msg.assign("ambiguous command '"); - error_msg.append(command_args.GetArgumentAtIndex(0)); - error_msg.append("'."); - - error_msg.append(" Possible completions:"); - for (int i = 0; i < num_matches; i++) { - error_msg.append("\n\t"); - error_msg.append(matches.GetStringAtIndex(i)); - } - error_msg.append("\n"); - result.AppendRawError(error_msg.c_str()); - } else - result.AppendErrorWithFormat("Unrecognized command '%s'.\n", - command_args.GetArgumentAtIndex(0)); - - result.SetStatus(eReturnStatusFailed); } if (log) From 6aae82f4eb42d3abf26c087787ecaceb95112a4b Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 26 Jul 2018 17:14:18 +0000 Subject: [PATCH 0010/1112] Fix duplicate suggestions after an ambiguous command Summary: So far lldb is printing this when it finds an ambiguous command: ``` (lldb) g Ambiguous command 'g'. Possible matches: gdb-remote gui gdb-remote gui ``` The duplicates come from the fact that we call the same query twice with the same parameters and add it to the same list. This patch just removes the second query call to `GetCommandObject`. As `GetCommandObject` is const and the name parameter is also not modified, this shouldn't break anything else. I didn't merge the remaining if statement into the else as I think otherwise the `if obj==nullptr do X else Y` pattern in there becomes hard to recognize. Reviewers: davide Reviewed By: davide Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D49866 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338043 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../test/functionalities/wrong_commands/TestWrongCommands.py | 2 +- source/Interpreter/CommandInterpreter.cpp | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/Python/lldbsuite/test/functionalities/wrong_commands/TestWrongCommands.py b/packages/Python/lldbsuite/test/functionalities/wrong_commands/TestWrongCommands.py index dcfb434f1e5c..c25f9afbfa4e 100644 --- a/packages/Python/lldbsuite/test/functionalities/wrong_commands/TestWrongCommands.py +++ b/packages/Python/lldbsuite/test/functionalities/wrong_commands/TestWrongCommands.py @@ -26,7 +26,7 @@ def test_ambiguous_command(self): self.assertRegexpMatches(result.GetError(), "Ambiguous command 'g'. Possible matches:") self.assertRegexpMatches(result.GetError(), "gui") self.assertRegexpMatches(result.GetError(), "gdb-remote") - # FIXME: Somehow we get 'gui' and 'gdb-remote' twice in the output. + self.assertEquals(1, result.GetError().count("gdb-remote")) @no_debug_info_test def test_unknown_command(self): diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp index 977c9babedea..4c8b65441366 100644 --- a/source/Interpreter/CommandInterpreter.cpp +++ b/source/Interpreter/CommandInterpreter.cpp @@ -2932,8 +2932,6 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, actual_cmd_name_len = cmd_obj->GetCommandName().size(); } } else { - if (!cmd_obj) - cmd_obj = GetCommandObject(next_word, &matches); if (cmd_obj) { llvm::StringRef cmd_name = cmd_obj->GetCommandName(); actual_cmd_name_len += cmd_name.size(); From 7a2e008011e152769cfa2fb7eac5c8b999b28401 Mon Sep 17 00:00:00 2001 From: Alex Langford Date: Thu, 26 Jul 2018 19:04:46 +0000 Subject: [PATCH 0011/1112] Make framework-header-fix process copied headers Summary: Previously the framework-header-fix script would change the sources before they were copied, leading to unnecessary rebuilds on repeat `ninja lldb` invocations. This runs the script on the headers after they're copied into the produced LLDB.framework, meaning it doesn't affect any files being built. Patch by Keith Smiley ! Differential Revision: https://reviews.llvm.org/D49779 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338058 91177308-0d34-0410-b5e6-96231b3b80d8 --- cmake/modules/LLDBFramework.cmake | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/cmake/modules/LLDBFramework.cmake b/cmake/modules/LLDBFramework.cmake index a17f07dad998..4ef0d3a2fc1d 100644 --- a/cmake/modules/LLDBFramework.cmake +++ b/cmake/modules/LLDBFramework.cmake @@ -12,24 +12,21 @@ foreach(header COMMAND ${CMAKE_COMMAND} -E copy ${header} ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders/${basename}) list(APPEND framework_headers ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders/${basename}) endforeach() -add_custom_target(lldb-framework-headers - DEPENDS ${framework_headers} - COMMAND ${LLDB_SOURCE_DIR}/scripts/framework-header-fix.sh ${CMAKE_CURRENT_BINARY_DIR} ${LLDB_VERSION}) + +add_custom_command(TARGET lldb-framework POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders $/Headers + COMMAND ${LLDB_SOURCE_DIR}/scripts/framework-header-fix.sh $/Headers ${LLDB_VERSION} +) if (NOT IOS) if (NOT LLDB_BUILT_STANDALONE) add_dependencies(lldb-framework clang-headers) endif() add_custom_command(TARGET lldb-framework POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders $/Headers COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Headers ${LLDB_FRAMEWORK_DIR}/LLDB.framework/Headers COMMAND ${CMAKE_COMMAND} -E create_symlink ${LLDB_FRAMEWORK_VERSION} ${LLDB_FRAMEWORK_DIR}/LLDB.framework/Versions/Current COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/clang/${LLDB_VERSION} $/Resources/Clang ) -else() - add_custom_command(TARGET lldb-framework POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders $/Headers - ) endif() set_target_properties(liblldb PROPERTIES @@ -41,5 +38,4 @@ set_target_properties(liblldb PROPERTIES PUBLIC_HEADER "${framework_headers}") add_dependencies(lldb-framework - lldb-framework-headers lldb-suite) From 7ec21c24c7d9a10bf5836561d5fee47f2883ebd3 Mon Sep 17 00:00:00 2001 From: Alex Langford Date: Thu, 26 Jul 2018 21:55:14 +0000 Subject: [PATCH 0012/1112] Add back lldb-framework-headers target In r338058 we removed the target `lldb-framework-headers`, which mean lldb-framework no longer depended on `framework_headers`, so they never actually got generated. This is a partial revert of r338058: I added back the lldb-framework-headers target, but the framework-header-fix.sh script still runs on the copied headers. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338074 91177308-0d34-0410-b5e6-96231b3b80d8 --- cmake/modules/LLDBFramework.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/modules/LLDBFramework.cmake b/cmake/modules/LLDBFramework.cmake index 4ef0d3a2fc1d..abacee89d9ac 100644 --- a/cmake/modules/LLDBFramework.cmake +++ b/cmake/modules/LLDBFramework.cmake @@ -13,6 +13,8 @@ foreach(header list(APPEND framework_headers ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders/${basename}) endforeach() +add_custom_target(lldb-framework-headers DEPENDS ${framework_headers}) + add_custom_command(TARGET lldb-framework POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders $/Headers COMMAND ${LLDB_SOURCE_DIR}/scripts/framework-header-fix.sh $/Headers ${LLDB_VERSION} @@ -38,4 +40,5 @@ set_target_properties(liblldb PROPERTIES PUBLIC_HEADER "${framework_headers}") add_dependencies(lldb-framework + lldb-framework-headers lldb-suite) From f4a9eebc5e4185bf64e665e24f4e35131f6d51db Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Fri, 27 Jul 2018 18:42:46 +0000 Subject: [PATCH 0013/1112] Narrow the CompletionRequest API to being append-only. Summary: We currently allow any completion handler to read and manipulate the list of matches we calculated so far. This leads to a few problems: Firstly, a completion handler's logic can now depend on previously calculated results by another handlers. No completion handler should have such an implicit dependency, but the current API makes it likely that this could happen (or already happens). Especially the fact that some completion handler deleted all previously calculated results can mess things up right now. Secondly, all completion handlers have knowledge about our internal data structures with this API. This makes refactoring this internal data structure much harder than it should be. Especially planned changes like the support of descriptions for completions are currently giant patches because we have to refactor every single completion handler. This patch narrows the contract the CompletionRequest has with the different handlers to: 1. A handler can suggest a completion. 2. A handler can ask how many suggestions we already have. Point 2 obviously means we still have a dependency left between the different handlers, but getting rid of this is too large to just append it to this patch. Otherwise this patch just completely hides the internal StringList to the different handlers. The CompletionRequest API now also ensures that the list of completions is unique and we don't suggest the same value multiple times to the user. This property has been so far only been ensured by the `Option` handler, but is now applied globally. This is part of this patch as the OptionHandler is no longer able to implement this functionality itself. Reviewers: jingham, davide, labath Reviewed By: davide Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D49322 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338151 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Utility/CompletionRequest.h | 35 +++++++++- source/Commands/CommandCompletions.cpp | 60 ++++++++++------- source/Commands/CommandObjectCommands.cpp | 4 +- source/Commands/CommandObjectFrame.cpp | 2 +- source/Commands/CommandObjectMultiword.cpp | 26 +++---- source/Commands/CommandObjectPlatform.cpp | 6 +- source/Commands/CommandObjectPlugin.cpp | 2 +- source/Commands/CommandObjectProcess.cpp | 6 +- source/Commands/CommandObjectSettings.cpp | 18 ++--- source/Commands/CommandObjectTarget.cpp | 10 +-- source/Core/FormatEntity.cpp | 23 ++++--- source/Core/IOHandler.cpp | 4 +- source/Interpreter/CommandInterpreter.cpp | 22 +++--- source/Interpreter/CommandObject.cpp | 3 +- .../Interpreter/CommandObjectRegexCommand.cpp | 3 +- source/Interpreter/OptionValue.cpp | 3 +- source/Interpreter/OptionValueArch.cpp | 3 +- source/Interpreter/OptionValueBoolean.cpp | 5 +- source/Interpreter/OptionValueEnumeration.cpp | 8 +-- source/Interpreter/OptionValueFileSpec.cpp | 3 +- source/Interpreter/OptionValueUUID.cpp | 5 +- source/Interpreter/Options.cpp | 22 ++---- source/Symbol/Variable.cpp | 6 +- source/Utility/ArchSpec.cpp | 8 ++- source/Utility/CompletionRequest.cpp | 1 + unittests/Utility/CompletionRequestTest.cpp | 67 ++++++++++++++++++- 26 files changed, 225 insertions(+), 130 deletions(-) diff --git a/include/lldb/Utility/CompletionRequest.h b/include/lldb/Utility/CompletionRequest.h index cfae16f00b37..ef75474813e0 100644 --- a/include/lldb/Utility/CompletionRequest.h +++ b/include/lldb/Utility/CompletionRequest.h @@ -13,6 +13,7 @@ #include "lldb/Utility/Args.h" #include "lldb/Utility/StringList.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSet.h" namespace lldb_private { @@ -77,8 +78,29 @@ class CompletionRequest { void SetWordComplete(bool v) { m_word_complete = v; } - /// The array of matches returned. - StringList &GetMatches() { return *m_matches; } + /// Adds a possible completion string. If the completion was already + /// suggested before, it will not be added to the list of results. A copy of + /// the suggested completion is stored, so the given string can be free'd + /// afterwards. + /// + /// @param match The suggested completion. + void AddCompletion(llvm::StringRef completion) { + // Add the completion if we haven't seen the same value before. + if (m_match_set.insert(completion).second) + m_matches->AppendString(completion); + } + + /// Adds multiple possible completion strings. + /// + /// \param completions The list of completions. + /// + /// @see AddCompletion + void AddCompletions(const StringList &completions) { + for (std::size_t i = 0; i < completions.GetSize(); ++i) + AddCompletion(completions.GetStringAtIndex(i)); + } + + std::size_t GetNumberOfMatches() const { return m_matches->GetSize(); } llvm::StringRef GetCursorArgument() const { return GetParsedLine().GetArgumentAtIndex(GetCursorIndex()); @@ -111,8 +133,15 @@ class CompletionRequest { /// \btrue if this is a complete option value (a space will be inserted /// after the completion.) \bfalse otherwise. bool m_word_complete = false; - // We don't own the list. + + // Note: This list is kept private. This is by design to prevent that any + // completion depends on any already computed completion from another backend. + // Note: We don't own the list. It's owned by the creator of the + // CompletionRequest object. StringList *m_matches; + + /// List of added completions so far. Used to filter out duplicates. + llvm::StringSet<> m_match_set; }; } // namespace lldb_private diff --git a/source/Commands/CommandCompletions.cpp b/source/Commands/CommandCompletions.cpp index bdfdbb83219b..7b351c50dc69 100644 --- a/source/Commands/CommandCompletions.cpp +++ b/source/Commands/CommandCompletions.cpp @@ -90,7 +90,7 @@ int CommandCompletions::SourceFiles(CommandInterpreter &interpreter, } else { completer.DoCompletion(searcher); } - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } static int DiskFilesOrDirectories(const llvm::Twine &partial_name, @@ -103,7 +103,7 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, partial_name.toVector(CompletionBuffer); if (CompletionBuffer.size() >= PATH_MAX) - return 0; + return matches.GetSize(); namespace fs = llvm::sys::fs; namespace path = llvm::sys::path; @@ -145,7 +145,7 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, // Make sure it ends with a separator. path::append(CompletionBuffer, path::get_separator()); matches.AppendString(CompletionBuffer); - return 1; + return matches.GetSize(); } // We want to keep the form the user typed, so we special case this to @@ -224,13 +224,21 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, return matches.GetSize(); } +static int DiskFilesOrDirectories(CompletionRequest &request, + bool only_directories) { + request.SetWordComplete(false); + StandardTildeExpressionResolver resolver; + StringList matches; + DiskFilesOrDirectories(request.GetCursorArgumentPrefix(), only_directories, + matches, resolver); + request.AddCompletions(matches); + return request.GetNumberOfMatches(); +} + int CommandCompletions::DiskFiles(CommandInterpreter &interpreter, CompletionRequest &request, SearchFilter *searcher) { - request.SetWordComplete(false); - StandardTildeExpressionResolver Resolver; - return DiskFiles(request.GetCursorArgumentPrefix(), request.GetMatches(), - Resolver); + return DiskFilesOrDirectories(request, /*only_dirs*/ false); } int CommandCompletions::DiskFiles(const llvm::Twine &partial_file_name, @@ -242,10 +250,7 @@ int CommandCompletions::DiskFiles(const llvm::Twine &partial_file_name, int CommandCompletions::DiskDirectories(CommandInterpreter &interpreter, CompletionRequest &request, SearchFilter *searcher) { - request.SetWordComplete(false); - StandardTildeExpressionResolver Resolver; - return DiskDirectories(request.GetCursorArgumentPrefix(), - request.GetMatches(), Resolver); + return DiskFilesOrDirectories(request, /*only_dirs*/ true); } int CommandCompletions::DiskDirectories(const llvm::Twine &partial_file_name, @@ -267,7 +272,7 @@ int CommandCompletions::Modules(CommandInterpreter &interpreter, } else { completer.DoCompletion(searcher); } - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } int CommandCompletions::Symbols(CommandInterpreter &interpreter, @@ -283,7 +288,7 @@ int CommandCompletions::Symbols(CommandInterpreter &interpreter, } else { completer.DoCompletion(searcher); } - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } int CommandCompletions::SettingsNames(CommandInterpreter &interpreter, @@ -304,20 +309,23 @@ int CommandCompletions::SettingsNames(CommandInterpreter &interpreter, } size_t exact_matches_idx = SIZE_MAX; - const size_t num_matches = - g_property_names.AutoComplete(request.GetCursorArgumentPrefix(), - request.GetMatches(), exact_matches_idx); + StringList matches; + g_property_names.AutoComplete(request.GetCursorArgumentPrefix(), matches, + exact_matches_idx); request.SetWordComplete(exact_matches_idx != SIZE_MAX); - return num_matches; + request.AddCompletions(matches); + return request.GetNumberOfMatches(); } int CommandCompletions::PlatformPluginNames(CommandInterpreter &interpreter, CompletionRequest &request, SearchFilter *searcher) { - const uint32_t num_matches = PluginManager::AutoCompletePlatformName( - request.GetCursorArgumentPrefix(), request.GetMatches()); + StringList new_matches; + std::size_t num_matches = PluginManager::AutoCompletePlatformName( + request.GetCursorArgumentPrefix(), new_matches); request.SetWordComplete(num_matches == 1); - return num_matches; + request.AddCompletions(new_matches); + return request.GetNumberOfMatches(); } int CommandCompletions::ArchitectureNames(CommandInterpreter &interpreter, @@ -409,10 +417,10 @@ CommandCompletions::SourceFileCompleter::DoCompletion(SearchFilter *filter) { filter->Search(*this); // Now convert the filelist to completions: for (size_t i = 0; i < m_matching_files.GetSize(); i++) { - m_request.GetMatches().AppendString( + m_request.AddCompletion( m_matching_files.GetFileSpecAtIndex(i).GetFilename().GetCString()); } - return m_request.GetMatches().GetSize(); + return m_request.GetNumberOfMatches(); } //---------------------------------------------------------------------- @@ -478,9 +486,9 @@ size_t CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) { filter->Search(*this); collection::iterator pos = m_match_set.begin(), end = m_match_set.end(); for (pos = m_match_set.begin(); pos != end; pos++) - m_request.GetMatches().AppendString((*pos).GetCString()); + m_request.AddCompletion((*pos).GetCString()); - return m_request.GetMatches().GetSize(); + return m_request.GetNumberOfMatches(); } //---------------------------------------------------------------------- @@ -517,7 +525,7 @@ Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback( match = false; if (match) { - m_request.GetMatches().AppendString(cur_file_name); + m_request.AddCompletion(cur_file_name); } } return Searcher::eCallbackReturnContinue; @@ -525,5 +533,5 @@ Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback( size_t CommandCompletions::ModuleCompleter::DoCompletion(SearchFilter *filter) { filter->Search(*this); - return m_request.GetMatches().GetSize(); + return m_request.GetNumberOfMatches(); } diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp index 3012ee4a188d..333f72056cbc 100644 --- a/source/Commands/CommandObjectCommands.cpp +++ b/source/Commands/CommandObjectCommands.cpp @@ -241,7 +241,7 @@ class CommandObjectCommandsSource : public CommandObjectParsed { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } Options *GetOptions() override { return &m_options; } @@ -1429,7 +1429,7 @@ class CommandObjectCommandsScriptImport : public CommandObjectParsed { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } Options *GetOptions() override { return &m_options; } diff --git a/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp index 0183c43f85b5..64de14f2edbf 100644 --- a/source/Commands/CommandObjectFrame.cpp +++ b/source/Commands/CommandObjectFrame.cpp @@ -470,7 +470,7 @@ class CommandObjectFrameVariable : public CommandObjectParsed { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } protected: diff --git a/source/Commands/CommandObjectMultiword.cpp b/source/Commands/CommandObjectMultiword.cpp index ade1a2d01f38..19fcf60e557c 100644 --- a/source/Commands/CommandObjectMultiword.cpp +++ b/source/Commands/CommandObjectMultiword.cpp @@ -143,7 +143,7 @@ bool CommandObjectMultiword::Execute(const char *args_string, if (num_subcmd_matches > 0) { error_msg.append(" Possible completions:"); - for (size_t i = 0; i < num_subcmd_matches; i++) { + for (size_t i = 0; i < matches.GetSize(); i++) { error_msg.append("\n\t"); error_msg.append(matches.GetStringAtIndex(i)); } @@ -190,21 +190,22 @@ int CommandObjectMultiword::HandleCompletion(CompletionRequest &request) { // Any of the command matches will provide a complete word, otherwise the // individual completers will override this. request.SetWordComplete(true); - auto &matches = request.GetMatches(); auto arg0 = request.GetParsedLine()[0].ref; if (request.GetCursorIndex() == 0) { - AddNamesMatchingPartialString(m_subcommand_dict, arg0, matches); + StringList new_matches; + AddNamesMatchingPartialString(m_subcommand_dict, arg0, new_matches); + request.AddCompletions(new_matches); - if (matches.GetSize() == 1 && matches.GetStringAtIndex(0) != nullptr && - (arg0 == matches.GetStringAtIndex(0))) { + if (new_matches.GetSize() == 1 && + new_matches.GetStringAtIndex(0) != nullptr && + (arg0 == new_matches.GetStringAtIndex(0))) { StringList temp_matches; CommandObject *cmd_obj = GetSubcommandObject(arg0, &temp_matches); if (cmd_obj != nullptr) { if (request.GetParsedLine().GetArgumentCount() == 1) { request.SetWordComplete(true); } else { - matches.DeleteStringAtIndex(0); request.GetParsedLine().Shift(); request.SetCursorCharPosition(0); request.GetParsedLine().AppendArgument(llvm::StringRef()); @@ -212,14 +213,17 @@ int CommandObjectMultiword::HandleCompletion(CompletionRequest &request) { } } } - return matches.GetSize(); + return new_matches.GetSize(); } else { - CommandObject *sub_command_object = GetSubcommandObject(arg0, &matches); + StringList new_matches; + CommandObject *sub_command_object = GetSubcommandObject(arg0, &new_matches); if (sub_command_object == nullptr) { - return matches.GetSize(); + request.AddCompletions(new_matches); + return request.GetNumberOfMatches(); } else { // Remove the one match that we got from calling GetSubcommandObject. - matches.DeleteStringAtIndex(0); + new_matches.DeleteStringAtIndex(0); + request.AddCompletions(new_matches); request.GetParsedLine().Shift(); request.SetCursorIndex(request.GetCursorIndex() - 1); return sub_command_object->HandleCompletion(request); @@ -366,7 +370,6 @@ int CommandObjectProxy::HandleCompletion(CompletionRequest &request) { CommandObject *proxy_command = GetProxyCommandObject(); if (proxy_command) return proxy_command->HandleCompletion(request); - request.GetMatches().Clear(); return 0; } @@ -375,7 +378,6 @@ int CommandObjectProxy::HandleArgumentCompletion( CommandObject *proxy_command = GetProxyCommandObject(); if (proxy_command) return proxy_command->HandleArgumentCompletion(request, opt_element_vector); - request.GetMatches().Clear(); return 0; } diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp index f822a8b54cb0..22a9a169c7c8 100644 --- a/source/Commands/CommandObjectPlatform.cpp +++ b/source/Commands/CommandObjectPlatform.cpp @@ -181,7 +181,7 @@ class CommandObjectPlatformSelect : public CommandObjectParsed { int HandleCompletion(CompletionRequest &request) override { CommandCompletions::PlatformPluginNames(GetCommandInterpreter(), request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } Options *GetOptions() override { return &m_option_group; } @@ -1583,9 +1583,9 @@ class CommandObjectPlatformProcessAttach : public CommandObjectParsed { const uint32_t num_matches = process_infos.GetSize(); if (num_matches > 0) { for (uint32_t i = 0; i < num_matches; ++i) { - request.GetMatches().AppendString( + request.AddCompletion(llvm::StringRef( process_infos.GetProcessNameAtIndex(i), - process_infos.GetProcessNameLengthAtIndex(i)); + process_infos.GetProcessNameLengthAtIndex(i))); } } } diff --git a/source/Commands/CommandObjectPlugin.cpp b/source/Commands/CommandObjectPlugin.cpp index 1f379a2660ed..13ef6b227c5b 100644 --- a/source/Commands/CommandObjectPlugin.cpp +++ b/source/Commands/CommandObjectPlugin.cpp @@ -48,7 +48,7 @@ class CommandObjectPluginLoad : public CommandObjectParsed { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } protected: diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp index 3ac27918df4c..eb5a19aa4d39 100644 --- a/source/Commands/CommandObjectProcess.cpp +++ b/source/Commands/CommandObjectProcess.cpp @@ -141,7 +141,7 @@ class CommandObjectProcessLaunch : public CommandObjectProcessLaunchOrAttach { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } Options *GetOptions() override { return &m_options; } @@ -410,9 +410,9 @@ class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach { const size_t num_matches = process_infos.GetSize(); if (num_matches > 0) { for (size_t i = 0; i < num_matches; ++i) { - request.GetMatches().AppendString( + request.AddCompletion(llvm::StringRef( process_infos.GetProcessNameAtIndex(i), - process_infos.GetProcessNameLengthAtIndex(i)); + process_infos.GetProcessNameLengthAtIndex(i))); } } } diff --git a/source/Commands/CommandObjectSettings.cpp b/source/Commands/CommandObjectSettings.cpp index f259f2fe200d..3db1e35cd702 100644 --- a/source/Commands/CommandObjectSettings.cpp +++ b/source/Commands/CommandObjectSettings.cpp @@ -172,7 +172,7 @@ insert-before or insert-after."); } } } - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } protected: @@ -272,7 +272,7 @@ class CommandObjectSettingsShow : public CommandObjectParsed { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } protected: @@ -338,7 +338,7 @@ class CommandObjectSettingsList : public CommandObjectParsed { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } protected: @@ -427,7 +427,7 @@ class CommandObjectSettingsRemove : public CommandObjectRaw { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } protected: @@ -544,7 +544,7 @@ class CommandObjectSettingsReplace : public CommandObjectRaw { GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } protected: @@ -644,7 +644,7 @@ class CommandObjectSettingsInsertBefore : public CommandObjectRaw { GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } protected: @@ -749,7 +749,7 @@ class CommandObjectSettingsInsertAfter : public CommandObjectRaw { GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } protected: @@ -843,7 +843,7 @@ class CommandObjectSettingsAppend : public CommandObjectRaw { GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } protected: @@ -924,7 +924,7 @@ class CommandObjectSettingsClear : public CommandObjectParsed { GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } protected: diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp index a9062c14b367..8be43cbf9bb0 100644 --- a/source/Commands/CommandObjectTarget.cpp +++ b/source/Commands/CommandObjectTarget.cpp @@ -201,7 +201,7 @@ class CommandObjectTargetCreate : public CommandObjectParsed { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } protected: @@ -1810,7 +1810,7 @@ class CommandObjectTargetModulesModuleAutoComplete CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } }; @@ -1851,7 +1851,7 @@ class CommandObjectTargetModulesSourceFileAutoComplete CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } }; @@ -2393,7 +2393,7 @@ class CommandObjectTargetModulesAdd : public CommandObjectParsed { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } protected: @@ -3987,7 +3987,7 @@ class CommandObjectTargetSymbolsAdd : public CommandObjectParsed { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } Options *GetOptions() override { return &m_option_group; } diff --git a/source/Core/FormatEntity.cpp b/source/Core/FormatEntity.cpp index 2257b7e273e8..743c7c404994 100644 --- a/source/Core/FormatEntity.cpp +++ b/source/Core/FormatEntity.cpp @@ -2350,7 +2350,6 @@ size_t FormatEntity::AutoComplete(CompletionRequest &request) { request.SetWordComplete(false); str = str.drop_front(request.GetMatchStartPoint()); - request.GetMatches().Clear(); const size_t dollar_pos = str.rfind('$'); if (dollar_pos == llvm::StringRef::npos) @@ -2360,7 +2359,7 @@ size_t FormatEntity::AutoComplete(CompletionRequest &request) { if (dollar_pos == str.size() - 1) { std::string match = str.str(); match.append("{"); - request.GetMatches().AppendString(match); + request.AddCompletion(match); return 1; } @@ -2378,8 +2377,10 @@ size_t FormatEntity::AutoComplete(CompletionRequest &request) { llvm::StringRef partial_variable(str.substr(dollar_pos + 2)); if (partial_variable.empty()) { // Suggest all top level entites as we are just past "${" - AddMatches(&g_root, str, llvm::StringRef(), request.GetMatches()); - return request.GetMatches().GetSize(); + StringList new_matches; + AddMatches(&g_root, str, llvm::StringRef(), new_matches); + request.AddCompletions(new_matches); + return request.GetNumberOfMatches(); } // We have a partially specified variable, find it @@ -2395,19 +2396,23 @@ size_t FormatEntity::AutoComplete(CompletionRequest &request) { // Exact match if (n > 0) { // "${thread.info" - request.GetMatches().AppendString(MakeMatch(str, ".")); + request.AddCompletion(MakeMatch(str, ".")); } else { // "${thread.id" - request.GetMatches().AppendString(MakeMatch(str, "}")); + request.AddCompletion(MakeMatch(str, "}")); request.SetWordComplete(true); } } else if (remainder.equals(".")) { // "${thread." - AddMatches(entry_def, str, llvm::StringRef(), request.GetMatches()); + StringList new_matches; + AddMatches(entry_def, str, llvm::StringRef(), new_matches); + request.AddCompletions(new_matches); } else { // We have a partial match // "${thre" - AddMatches(entry_def, str, remainder, request.GetMatches()); + StringList new_matches; + AddMatches(entry_def, str, remainder, new_matches); + request.AddCompletions(new_matches); } - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } diff --git a/source/Core/IOHandler.cpp b/source/Core/IOHandler.cpp index 8474e4b8c564..e7ebeea1b88d 100644 --- a/source/Core/IOHandler.cpp +++ b/source/Core/IOHandler.cpp @@ -245,10 +245,10 @@ int IOHandlerDelegate::IOHandlerComplete(IOHandler &io_handler, io_handler.GetDebugger().GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion, request, nullptr); - size_t num_matches = request.GetMatches().GetSize(); + size_t num_matches = request.GetNumberOfMatches(); if (num_matches > 0) { std::string common_prefix; - request.GetMatches().LongestCommonPrefix(common_prefix); + matches.LongestCommonPrefix(common_prefix); const size_t partial_name_len = request.GetCursorArgumentPrefix().size(); // If we matched a unique single command, add a space... Only do this if diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp index 4c8b65441366..76cb5f2896e4 100644 --- a/source/Interpreter/CommandInterpreter.cpp +++ b/source/Interpreter/CommandInterpreter.cpp @@ -1703,7 +1703,6 @@ bool CommandInterpreter::HandleCommand(const char *command_line, } int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) { - auto &matches = request.GetMatches(); int num_command_matches = 0; bool look_for_subcommand = false; @@ -1713,30 +1712,34 @@ int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) { if (request.GetCursorIndex() == -1) { // We got nothing on the command line, so return the list of commands bool include_aliases = true; + StringList new_matches; num_command_matches = - GetCommandNamesMatchingPartialString("", include_aliases, matches); + GetCommandNamesMatchingPartialString("", include_aliases, new_matches); + request.AddCompletions(new_matches); } else if (request.GetCursorIndex() == 0) { // The cursor is in the first argument, so just do a lookup in the // dictionary. + StringList new_matches; CommandObject *cmd_obj = GetCommandObject( - request.GetParsedLine().GetArgumentAtIndex(0), &matches); - num_command_matches = matches.GetSize(); + request.GetParsedLine().GetArgumentAtIndex(0), &new_matches); if (num_command_matches == 1 && cmd_obj && cmd_obj->IsMultiwordObject() && - matches.GetStringAtIndex(0) != nullptr && + new_matches.GetStringAtIndex(0) != nullptr && strcmp(request.GetParsedLine().GetArgumentAtIndex(0), - matches.GetStringAtIndex(0)) == 0) { + new_matches.GetStringAtIndex(0)) == 0) { if (request.GetParsedLine().GetArgumentCount() == 1) { request.SetWordComplete(true); } else { look_for_subcommand = true; num_command_matches = 0; - matches.DeleteStringAtIndex(0); + new_matches.DeleteStringAtIndex(0); request.GetParsedLine().AppendArgument(llvm::StringRef()); request.SetCursorIndex(request.GetCursorIndex() + 1); request.SetCursorCharPosition(0); } } + request.AddCompletions(new_matches); + num_command_matches = request.GetNumberOfMatches(); } if (request.GetCursorIndex() > 0 || look_for_subcommand) { @@ -1773,8 +1776,7 @@ int CommandInterpreter::HandleCompletion( return 0; else if (first_arg[0] == CommandHistory::g_repeat_char) { if (auto hist_str = m_command_history.FindString(first_arg)) { - request.GetMatches().Clear(); - request.GetMatches().InsertStringAtIndex(0, *hist_str); + matches.InsertStringAtIndex(0, *hist_str); return -2; } else return 0; @@ -1812,7 +1814,7 @@ int CommandInterpreter::HandleCompletion( common_prefix.push_back(quote_char); common_prefix.push_back(' '); } - request.GetMatches().InsertStringAtIndex(0, common_prefix.c_str()); + matches.InsertStringAtIndex(0, common_prefix.c_str()); } return num_command_matches; } diff --git a/source/Interpreter/CommandObject.cpp b/source/Interpreter/CommandObject.cpp index 07be9139f219..324b0b511220 100644 --- a/source/Interpreter/CommandObject.cpp +++ b/source/Interpreter/CommandObject.cpp @@ -267,7 +267,6 @@ int CommandObject::HandleCompletion(CompletionRequest &request) { if (WantsRawCommandString() && !WantsCompletion()) { // FIXME: Abstract telling the completion to insert the completion // character. - request.GetMatches().Clear(); return -1; } else { // Can we do anything generic with the options? @@ -282,7 +281,7 @@ int CommandObject::HandleCompletion(CompletionRequest &request) { bool handled_by_options = cur_options->HandleOptionCompletion( request, opt_element_vector, GetCommandInterpreter()); if (handled_by_options) - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } // If we got here, the last word is not an option or an option argument. diff --git a/source/Interpreter/CommandObjectRegexCommand.cpp b/source/Interpreter/CommandObjectRegexCommand.cpp index f975c0eea2ee..ec89ad8fb162 100644 --- a/source/Interpreter/CommandObjectRegexCommand.cpp +++ b/source/Interpreter/CommandObjectRegexCommand.cpp @@ -97,9 +97,8 @@ int CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) { if (m_completion_type_mask) { CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), m_completion_type_mask, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } else { - request.GetMatches().Clear(); request.SetWordComplete(false); } return 0; diff --git a/source/Interpreter/OptionValue.cpp b/source/Interpreter/OptionValue.cpp index 2d7c69eaa432..c3f363b05988 100644 --- a/source/Interpreter/OptionValue.cpp +++ b/source/Interpreter/OptionValue.cpp @@ -575,8 +575,7 @@ bool OptionValue::DumpQualifiedName(Stream &strm) const { size_t OptionValue::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { request.SetWordComplete(false); - request.GetMatches().Clear(); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } Status OptionValue::SetValueFromString(llvm::StringRef value, diff --git a/source/Interpreter/OptionValueArch.cpp b/source/Interpreter/OptionValueArch.cpp index 3d08780ae6f6..d4f1fcb8a70a 100644 --- a/source/Interpreter/OptionValueArch.cpp +++ b/source/Interpreter/OptionValueArch.cpp @@ -76,9 +76,8 @@ lldb::OptionValueSP OptionValueArch::DeepCopy() const { size_t OptionValueArch::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { request.SetWordComplete(false); - request.GetMatches().Clear(); CommandCompletions::InvokeCommonCompletionCallbacks( interpreter, CommandCompletions::eArchitectureCompletion, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } diff --git a/source/Interpreter/OptionValueBoolean.cpp b/source/Interpreter/OptionValueBoolean.cpp index 8a340792d78f..94c774d69111 100644 --- a/source/Interpreter/OptionValueBoolean.cpp +++ b/source/Interpreter/OptionValueBoolean.cpp @@ -79,7 +79,6 @@ lldb::OptionValueSP OptionValueBoolean::DeepCopy() const { size_t OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { request.SetWordComplete(false); - request.GetMatches().Clear(); static const llvm::StringRef g_autocomplete_entries[] = { "true", "false", "on", "off", "yes", "no", "1", "0"}; @@ -91,7 +90,7 @@ size_t OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter, for (auto entry : entries) { if (entry.startswith_lower(request.GetCursorArgumentPrefix())) - request.GetMatches().AppendString(entry); + request.AddCompletion(entry); } - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } diff --git a/source/Interpreter/OptionValueEnumeration.cpp b/source/Interpreter/OptionValueEnumeration.cpp index e78618ee3c6b..c7cbcab7fcc8 100644 --- a/source/Interpreter/OptionValueEnumeration.cpp +++ b/source/Interpreter/OptionValueEnumeration.cpp @@ -112,20 +112,18 @@ lldb::OptionValueSP OptionValueEnumeration::DeepCopy() const { size_t OptionValueEnumeration::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { request.SetWordComplete(false); - request.GetMatches().Clear(); const uint32_t num_enumerators = m_enumerations.GetSize(); if (!request.GetCursorArgumentPrefix().empty()) { for (size_t i = 0; i < num_enumerators; ++i) { llvm::StringRef name = m_enumerations.GetCStringAtIndex(i).GetStringRef(); if (name.startswith(request.GetCursorArgumentPrefix())) - request.GetMatches().AppendString(name); + request.AddCompletion(name); } } else { // only suggest "true" or "false" by default for (size_t i = 0; i < num_enumerators; ++i) - request.GetMatches().AppendString( - m_enumerations.GetCStringAtIndex(i).GetStringRef()); + request.AddCompletion(m_enumerations.GetCStringAtIndex(i).GetStringRef()); } - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } diff --git a/source/Interpreter/OptionValueFileSpec.cpp b/source/Interpreter/OptionValueFileSpec.cpp index 18bfcd693949..2b93628679ce 100644 --- a/source/Interpreter/OptionValueFileSpec.cpp +++ b/source/Interpreter/OptionValueFileSpec.cpp @@ -102,10 +102,9 @@ lldb::OptionValueSP OptionValueFileSpec::DeepCopy() const { size_t OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { request.SetWordComplete(false); - request.GetMatches().Clear(); CommandCompletions::InvokeCommonCompletionCallbacks( interpreter, m_completion_mask, request, nullptr); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } const lldb::DataBufferSP &OptionValueFileSpec::GetFileContents() { diff --git a/source/Interpreter/OptionValueUUID.cpp b/source/Interpreter/OptionValueUUID.cpp index 7fa155277cec..355e07bb2b5f 100644 --- a/source/Interpreter/OptionValueUUID.cpp +++ b/source/Interpreter/OptionValueUUID.cpp @@ -70,7 +70,6 @@ lldb::OptionValueSP OptionValueUUID::DeepCopy() const { size_t OptionValueUUID::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { request.SetWordComplete(false); - request.GetMatches().Clear(); ExecutionContext exe_ctx(interpreter.GetExecutionContext()); Target *target = exe_ctx.GetTargetPtr(); if (target) { @@ -86,12 +85,12 @@ size_t OptionValueUUID::AutoComplete(CommandInterpreter &interpreter, llvm::ArrayRef module_bytes = module_uuid.GetBytes(); if (module_bytes.size() >= uuid_bytes.size() && module_bytes.take_front(uuid_bytes.size()).equals(uuid_bytes)) { - request.GetMatches().AppendString(module_uuid.GetAsString()); + request.AddCompletion(module_uuid.GetAsString()); } } } } } } - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } diff --git a/source/Interpreter/Options.cpp b/source/Interpreter/Options.cpp index f4758978e2a6..c9567e91f6b8 100644 --- a/source/Interpreter/Options.cpp +++ b/source/Interpreter/Options.cpp @@ -680,7 +680,7 @@ bool Options::HandleOptionCompletion(CompletionRequest &request, if (!def.short_option) continue; opt_str[1] = def.short_option; - request.GetMatches().AppendString(opt_str); + request.AddCompletion(opt_str); } return true; @@ -692,7 +692,7 @@ bool Options::HandleOptionCompletion(CompletionRequest &request, full_name.erase(full_name.begin() + 2, full_name.end()); full_name.append(def.long_option); - request.GetMatches().AppendString(full_name.c_str()); + request.AddCompletion(full_name.c_str()); } return true; } else if (opt_defs_index != OptionArgElement::eUnrecognizedArg) { @@ -705,10 +705,10 @@ bool Options::HandleOptionCompletion(CompletionRequest &request, strcmp(opt_defs[opt_defs_index].long_option, cur_opt_str) != 0) { std::string full_name("--"); full_name.append(opt_defs[opt_defs_index].long_option); - request.GetMatches().AppendString(full_name.c_str()); + request.AddCompletion(full_name.c_str()); return true; } else { - request.GetMatches().AppendString(request.GetCursorArgument()); + request.AddCompletion(request.GetCursorArgument()); return true; } } else { @@ -728,17 +728,7 @@ bool Options::HandleOptionCompletion(CompletionRequest &request, if (strstr(def.long_option, cur_opt_str + 2) == def.long_option) { std::string full_name("--"); full_name.append(def.long_option); - // The options definitions table has duplicates because of the - // way the grouping information is stored, so only add once. - bool duplicate = false; - for (size_t k = 0; k < request.GetMatches().GetSize(); k++) { - if (request.GetMatches().GetStringAtIndex(k) == full_name) { - duplicate = true; - break; - } - } - if (!duplicate) - request.GetMatches().AppendString(full_name.c_str()); + request.AddCompletion(full_name.c_str()); } } } @@ -790,7 +780,7 @@ bool Options::HandleOptionArgumentCompletion( for (int i = 0; enum_values[i].string_value != nullptr; i++) { if (strstr(enum_values[i].string_value, match_string.c_str()) == enum_values[i].string_value) { - request.GetMatches().AppendString(enum_values[i].string_value); + request.AddCompletion(enum_values[i].string_value); return_value = true; } } diff --git a/source/Symbol/Variable.cpp b/source/Symbol/Variable.cpp index 7eafef1e8955..8e9cadc0a5d7 100644 --- a/source/Symbol/Variable.cpp +++ b/source/Symbol/Variable.cpp @@ -760,9 +760,11 @@ size_t Variable::AutoComplete(const ExecutionContext &exe_ctx, CompilerType compiler_type; bool word_complete = false; + StringList matches; PrivateAutoComplete(exe_ctx.GetFramePtr(), request.GetCursorArgumentPrefix(), - "", compiler_type, request.GetMatches(), word_complete); + "", compiler_type, matches, word_complete); request.SetWordComplete(word_complete); + request.AddCompletions(matches); - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } diff --git a/source/Utility/ArchSpec.cpp b/source/Utility/ArchSpec.cpp index 320f2d9d1144..1c50c313e0d1 100644 --- a/source/Utility/ArchSpec.cpp +++ b/source/Utility/ArchSpec.cpp @@ -255,12 +255,14 @@ size_t ArchSpec::AutoComplete(CompletionRequest &request) { for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) { if (NameMatches(g_core_definitions[i].name, NameMatch::StartsWith, request.GetCursorArgumentPrefix())) - request.GetMatches().AppendString(g_core_definitions[i].name); + request.AddCompletion(g_core_definitions[i].name); } } else { - ListSupportedArchNames(request.GetMatches()); + StringList matches; + ListSupportedArchNames(matches); + request.AddCompletions(matches); } - return request.GetMatches().GetSize(); + return request.GetNumberOfMatches(); } #define CPU_ANY (UINT32_MAX) diff --git a/source/Utility/CompletionRequest.cpp b/source/Utility/CompletionRequest.cpp index 1b7697a35860..c88747e2abe3 100644 --- a/source/Utility/CompletionRequest.cpp +++ b/source/Utility/CompletionRequest.cpp @@ -20,6 +20,7 @@ CompletionRequest::CompletionRequest(llvm::StringRef command_line, : m_command(command_line), m_raw_cursor_pos(raw_cursor_pos), m_match_start_point(match_start_point), m_max_return_elements(max_return_elements), m_matches(&matches) { + matches.Clear(); // We parse the argument up to the cursor, so the last argument in // parsed_line is the one containing the cursor, and the cursor is after the diff --git a/unittests/Utility/CompletionRequestTest.cpp b/unittests/Utility/CompletionRequestTest.cpp index 134bf517f854..58dfab0da508 100644 --- a/unittests/Utility/CompletionRequestTest.cpp +++ b/unittests/Utility/CompletionRequestTest.cpp @@ -34,7 +34,70 @@ TEST(CompletionRequest, Constructor) { EXPECT_EQ(request.GetPartialParsedLine().GetArgumentCount(), 2u); EXPECT_STREQ(request.GetPartialParsedLine().GetArgumentAtIndex(1), "b"); +} + +TEST(CompletionRequest, DuplicateFiltering) { + std::string command = "a bad c"; + const unsigned cursor_pos = 3; + StringList matches; + + CompletionRequest request(command, cursor_pos, 0, 0, matches); + + EXPECT_EQ(0U, request.GetNumberOfMatches()); + + // Add foo twice + request.AddCompletion("foo"); + EXPECT_EQ(1U, request.GetNumberOfMatches()); + EXPECT_EQ(1U, matches.GetSize()); + EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); + + request.AddCompletion("foo"); + EXPECT_EQ(1U, request.GetNumberOfMatches()); + EXPECT_EQ(1U, matches.GetSize()); + EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); + + // Add bar twice + request.AddCompletion("bar"); + EXPECT_EQ(2U, request.GetNumberOfMatches()); + EXPECT_EQ(2U, matches.GetSize()); + EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); + EXPECT_STREQ("bar", matches.GetStringAtIndex(1)); + + request.AddCompletion("bar"); + EXPECT_EQ(2U, request.GetNumberOfMatches()); + EXPECT_EQ(2U, matches.GetSize()); + EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); + EXPECT_STREQ("bar", matches.GetStringAtIndex(1)); + + // Add foo again. + request.AddCompletion("foo"); + EXPECT_EQ(2U, request.GetNumberOfMatches()); + EXPECT_EQ(2U, matches.GetSize()); + EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); + EXPECT_STREQ("bar", matches.GetStringAtIndex(1)); + + // Add something with an existing prefix + request.AddCompletion("foobar"); + EXPECT_EQ(3U, request.GetNumberOfMatches()); + EXPECT_EQ(3U, matches.GetSize()); + EXPECT_STREQ("foo", matches.GetStringAtIndex(0)); + EXPECT_STREQ("bar", matches.GetStringAtIndex(1)); + EXPECT_STREQ("foobar", matches.GetStringAtIndex(2)); +} + +TEST(CompletionRequest, TestCompletionOwnership) { + std::string command = "a bad c"; + const unsigned cursor_pos = 3; + StringList matches; + + CompletionRequest request(command, cursor_pos, 0, 0, matches); + + std::string Temporary = "bar"; + request.AddCompletion(Temporary); + // Manipulate our completion. The request should have taken a copy, so that + // shouldn't influence anything. + Temporary[0] = 'f'; - // This is the generated matches should be equal to our passed string list. - EXPECT_EQ(&request.GetMatches(), &matches); + EXPECT_EQ(1U, request.GetNumberOfMatches()); + EXPECT_STREQ("bar", matches.GetStringAtIndex(0)); } From 954bb03f9ec9af331b2f2290c81e41eeceeb333a Mon Sep 17 00:00:00 2001 From: Alex Langford Date: Fri, 27 Jul 2018 19:41:17 +0000 Subject: [PATCH 0014/1112] Stop building liblldb with CMake's framework functionality Summary: CMake has a bug in its ninja generator that prevents you from installing targets that are built with framework support. Therefore, I want to not rely on CMake's framework support. See https://gitlab.kitware.com/cmake/cmake/issues/18216 Differential Revision: https://reviews.llvm.org/D49888 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338154 91177308-0d34-0410-b5e6-96231b3b80d8 --- CMakeLists.txt | 16 +++++-------- cmake/modules/AddLLDB.cmake | 6 ++--- cmake/modules/LLDBConfig.cmake | 4 +++- cmake/modules/LLDBFramework.cmake | 38 +++++++++++++++++++++---------- scripts/CMakeLists.txt | 6 ++--- source/API/CMakeLists.txt | 23 +++++++++++-------- 6 files changed, 55 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 00ddcdc1488f..96868154908d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,15 +51,16 @@ if(LLDB_BUILD_FRAMEWORK) message(FATAL_ERROR "LLDB.framework can only be generated when targeting Apple platforms") endif() + add_custom_target(lldb-framework) + set(LLDB_SUITE_TARGET lldb-framework) + set(LLDB_FRAMEWORK_DIR + ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${LLDB_FRAMEWORK_INSTALL_DIR}/LLDB.framework) # These are used to fill out LLDB-Info.plist. These are relevant when building # the framework, and must be defined before building liblldb. set(PRODUCT_NAME "LLDB") set(EXECUTABLE_NAME "LLDB") set(CURRENT_PROJECT_VERSION "360.99.0") - set(LLDB_SUITE_TARGET lldb-framework) - - set(LLDB_FRAMEWORK_DIR - ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${LLDB_FRAMEWORK_INSTALL_DIR}) + include(LLDBFramework) endif() add_subdirectory(docs) @@ -71,7 +72,7 @@ if (NOT LLDB_DISABLE_PYTHON) set(LLDB_PYTHON_TARGET_DIR ${LLDB_BINARY_DIR}/scripts) set(LLDB_WRAP_PYTHON ${LLDB_BINARY_DIR}/scripts/LLDBWrapPython.cpp) if(LLDB_BUILD_FRAMEWORK) - set(LLDB_PYTHON_TARGET_DIR ${LLDB_FRAMEWORK_DIR}) + set(LLDB_PYTHON_TARGET_DIR "${LLDB_FRAMEWORK_DIR}/..") set(LLDB_WRAP_PYTHON ${LLDB_PYTHON_TARGET_DIR}/LLDBWrapPython.cpp) else() # Don't set -m when building the framework. @@ -162,11 +163,6 @@ if(LLDB_INCLUDE_TESTS) add_subdirectory(utils/lldb-dotest) endif() -if (LLDB_BUILD_FRAMEWORK) - add_custom_target(lldb-framework) - include(LLDBFramework) -endif() - if (NOT LLDB_DISABLE_PYTHON) # Add a Post-Build Event to copy over Python files and create the symlink # to liblldb.so for the Python API(hardlink on Windows) diff --git a/cmake/modules/AddLLDB.cmake b/cmake/modules/AddLLDB.cmake index 129a5ef7500d..eb2dcbfa9448 100644 --- a/cmake/modules/AddLLDB.cmake +++ b/cmake/modules/AddLLDB.cmake @@ -52,7 +52,7 @@ function(add_lldb_library name) if (PARAM_SHARED) set(out_dir lib${LLVM_LIBDIR_SUFFIX}) if(${name} STREQUAL "liblldb" AND LLDB_BUILD_FRAMEWORK) - set(out_dir ${LLDB_FRAMEWORK_INSTALL_DIR}) + set(out_dir ${LLDB_FRAMEWORK_INSTALL_DIR}/LLDB.framework/Versions/${LLDB_FRAMEWORK_VERSION}) endif() install(TARGETS ${name} COMPONENT ${name} @@ -108,7 +108,7 @@ function(add_lldb_executable name) endif() string(REGEX REPLACE "[^/]+" ".." _dots ${LLDB_FRAMEWORK_INSTALL_DIR}) set_target_properties(${name} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY $${resource_dir} + RUNTIME_OUTPUT_DIRECTORY ${LLDB_FRAMEWORK_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR} BUILD_WITH_INSTALL_RPATH On INSTALL_RPATH "@loader_path/../../../${resource_dots}${_dots}/${LLDB_FRAMEWORK_INSTALL_DIR}") endif() @@ -123,7 +123,7 @@ function(add_lldb_executable name) if(ARG_GENERATE_INSTALL) set(out_dir "bin") if (LLDB_BUILD_FRAMEWORK AND ARG_INCLUDE_IN_SUITE) - set(out_dir ${LLDB_FRAMEWORK_INSTALL_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}) + set(out_dir ${LLDB_FRAMEWORK_INSTALL_DIR}/LLDB.framework/${LLDB_FRAMEWORK_RESOURCE_DIR}) endif() install(TARGETS ${name} COMPONENT ${name} diff --git a/cmake/modules/LLDBConfig.cmake b/cmake/modules/LLDBConfig.cmake index dae6e365da38..b454b3361fb3 100644 --- a/cmake/modules/LLDBConfig.cmake +++ b/cmake/modules/LLDBConfig.cmake @@ -326,7 +326,9 @@ if (APPLE) set(LLDB_FRAMEWORK_INSTALL_DIR Library/Frameworks CACHE STRING "Output directory for LLDB.framework") set(LLDB_FRAMEWORK_VERSION A CACHE STRING "LLDB.framework version (default is A)") set(LLDB_FRAMEWORK_RESOURCE_DIR - LLDB.framework/Versions/${LLDB_FRAMEWORK_VERSION}/Resources) + Versions/${LLDB_FRAMEWORK_VERSION}/Resources) + set(LLDB_FRAMEWORK_HEADER_DIR + Versions/${LLDB_FRAMEWORK_VERSION}/Headers) add_definitions( -DLIBXML2_DEFINED ) list(APPEND system_libs xml2 diff --git a/cmake/modules/LLDBFramework.cmake b/cmake/modules/LLDBFramework.cmake index abacee89d9ac..4bf85813c924 100644 --- a/cmake/modules/LLDBFramework.cmake +++ b/cmake/modules/LLDBFramework.cmake @@ -1,3 +1,16 @@ +# We intentionally do not use CMake's framework support because of a bug in +# CMake. See: https://gitlab.kitware.com/cmake/cmake/issues/18216 + +# We set up part of the framework structure first, as some scripts and build +# rules assume they exist already. +file(MAKE_DIRECTORY ${LLDB_FRAMEWORK_DIR} ${LLDB_FRAMEWORK_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}) +execute_process( + COMMAND + ${CMAKE_COMMAND} -E create_symlink ${LLDB_FRAMEWORK_VERSION} ${LLDB_FRAMEWORK_DIR}/Versions/Current + COMMAND + ${CMAKE_COMMAND} -E create_symlink Versions/Current/Resources ${LLDB_FRAMEWORK_DIR}/Resources +) + file(GLOB public_headers ${LLDB_SOURCE_DIR}/include/lldb/API/*.h) file(GLOB root_public_headers ${LLDB_SOURCE_DIR}/include/lldb/lldb-*.h) file(GLOB root_private_headers ${LLDB_SOURCE_DIR}/include/lldb/lldb-private*.h) @@ -16,8 +29,8 @@ endforeach() add_custom_target(lldb-framework-headers DEPENDS ${framework_headers}) add_custom_command(TARGET lldb-framework POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders $/Headers - COMMAND ${LLDB_SOURCE_DIR}/scripts/framework-header-fix.sh $/Headers ${LLDB_VERSION} + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders ${LLDB_FRAMEWORK_DIR}/${LLDB_FRAMEWORK_HEADER_DIR} + COMMAND ${LLDB_SOURCE_DIR}/scripts/framework-header-fix.sh ${LLDB_FRAMEWORK_DIR}/${LLDB_FRAMEWORK_HEADER_DIR} ${LLDB_VERSION} ) if (NOT IOS) @@ -25,19 +38,20 @@ if (NOT IOS) add_dependencies(lldb-framework clang-headers) endif() add_custom_command(TARGET lldb-framework POST_BUILD - COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Headers ${LLDB_FRAMEWORK_DIR}/LLDB.framework/Headers - COMMAND ${CMAKE_COMMAND} -E create_symlink ${LLDB_FRAMEWORK_VERSION} ${LLDB_FRAMEWORK_DIR}/LLDB.framework/Versions/Current - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/clang/${LLDB_VERSION} $/Resources/Clang + COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Headers ${LLDB_FRAMEWORK_DIR}/Headers + COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/LLDB ${LLDB_FRAMEWORK_DIR}/LLDB + COMMAND ${CMAKE_COMMAND} -E create_symlink ${LLDB_FRAMEWORK_VERSION} ${LLDB_FRAMEWORK_DIR}/Versions/Current + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/clang/${LLDB_VERSION} ${LLDB_FRAMEWORK_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}/Clang ) endif() -set_target_properties(liblldb PROPERTIES - OUTPUT_NAME LLDB - FRAMEWORK On - FRAMEWORK_VERSION ${LLDB_FRAMEWORK_VERSION} - MACOSX_FRAMEWORK_INFO_PLIST ${LLDB_SOURCE_DIR}/resources/LLDB-Info.plist - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LLDB_FRAMEWORK_INSTALL_DIR} - PUBLIC_HEADER "${framework_headers}") +# These are used to fill out LLDB-Info.plist. These are relevant when building +# the framework, and must be defined before configuring Info.plist. +set(PRODUCT_NAME "LLDB") +set(EXECUTABLE_NAME "LLDB") +set(CURRENT_PROJECT_VERSION "360.99.0") +configure_file(${LLDB_SOURCE_DIR}/resources/LLDB-Info.plist + ${LLDB_FRAMEWORK_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}/Info.plist) add_dependencies(lldb-framework lldb-framework-headers diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index be5c3db53556..c8e0c981281d 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -25,9 +25,9 @@ set(SWIG_INSTALL_DIR lib${LLVM_LIBDIR_SUFFIX}) if(LLDB_BUILD_FRAMEWORK) set(framework_arg --framework --target-platform Darwin) set(SWIG_PYTHON_DIR - ${LLDB_PYTHON_TARGET_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}/Python) + ${LLDB_FRAMEWORK_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}/Python) set(SWIG_INSTALL_DIR - ${LLDB_FRAMEWORK_INSTALL_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}) + ${LLDB_FRAMEWORK_INSTALL_DIR}/LLDB.framework/${LLDB_FRAMEWORK_RESOURCE_DIR}) endif() get_filename_component(CFGBLDDIR ${LLDB_WRAP_PYTHON} DIRECTORY) @@ -52,7 +52,7 @@ add_custom_command( COMMENT "Python script building LLDB Python wrapper") add_custom_target(swig_wrapper ALL DEPENDS ${LLDB_WRAP_PYTHON}) -set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/lldb.py PROPERTIES GENERATED 1) +set_source_files_properties(${LLDB_PYTHON_TARGET_DIR}/lldb.py PROPERTIES GENERATED 1) # Install the LLDB python module diff --git a/source/API/CMakeLists.txt b/source/API/CMakeLists.txt index be9d4115cecc..4032332ad08c 100644 --- a/source/API/CMakeLists.txt +++ b/source/API/CMakeLists.txt @@ -110,10 +110,20 @@ if (LLVM_COMPILER_IS_GCC_COMPATIBLE AND PROPERTY COMPILE_FLAGS " -Wno-sequence-point -Wno-cast-qual") endif () -set_target_properties(liblldb - PROPERTIES - VERSION ${LLDB_VERSION} -) +if (LLDB_BUILD_FRAMEWORK) + set_target_properties(liblldb + PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${LLDB_FRAMEWORK_DIR}/Versions/${LLDB_FRAMEWORK_VERSION} + PREFIX "" + SUFFIX "" + INSTALL_NAME_DIR "@rpath/LLDB.framework" + OUTPUT_NAME LLDB) +else() + set_target_properties(liblldb + PROPERTIES + VERSION ${LLDB_VERSION} + OUTPUT_NAME lldb) +endif() if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows") if (NOT LLDB_EXPORT_ALL_SYMBOLS) @@ -136,11 +146,6 @@ if ( CMAKE_SYSTEM_NAME MATCHES "Windows" ) if (MSVC AND NOT LLDB_DISABLE_PYTHON) target_link_libraries(liblldb PRIVATE ${PYTHON_LIBRARY}) endif() -else() - set_target_properties(liblldb - PROPERTIES - OUTPUT_NAME lldb - ) endif() if (LLDB_WRAP_PYTHON) From d9d64f66391f09c2d06dddde79d4566c6bdbc0a6 Mon Sep 17 00:00:00 2001 From: Davide Italiano Date: Fri, 27 Jul 2018 19:57:30 +0000 Subject: [PATCH 0015/1112] Recommit [DataFormatters] Add formatter for C++17 std::optional. This should have all the correct files now. Patch by Shafik Yaghmour. Differential Revision: https://reviews.llvm.org/D49271 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338156 91177308-0d34-0410-b5e6-96231b3b80d8 --- lldb.xcodeproj/project.pbxproj | 4 + .../libcxx/optional/Makefile | 7 ++ .../TestDataFormatterLibcxxOptional.py | 59 +++++++++++++ .../libcxx/optional/main.cpp | 27 ++++++ .../Plugins/Language/CPlusPlus/CMakeLists.txt | 1 + .../Language/CPlusPlus/CPlusPlusLanguage.cpp | 9 ++ source/Plugins/Language/CPlusPlus/LibCxx.cpp | 22 +++++ source/Plugins/Language/CPlusPlus/LibCxx.h | 8 ++ .../Language/CPlusPlus/LibCxxOptional.cpp | 85 +++++++++++++++++++ 9 files changed, 222 insertions(+) create mode 100644 packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile create mode 100644 packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py create mode 100644 packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp create mode 100644 source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index d8a714415320..f94a3a7706fb 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -388,6 +388,7 @@ 945261C11B9A11FC00BF138D /* LibCxxInitializerList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 945261B71B9A11E800BF138D /* LibCxxInitializerList.cpp */; }; 945261C21B9A11FC00BF138D /* LibCxxList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 945261B81B9A11E800BF138D /* LibCxxList.cpp */; }; 945261C31B9A11FC00BF138D /* LibCxxMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 945261B91B9A11E800BF138D /* LibCxxMap.cpp */; }; + E4A63A9120F55D28000D9548 /* LibCxxOptional.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4A63A9020F55D27000D9548 /* LibCxxOptional.cpp */; }; AF9FF1F71FAA79FE00474976 /* LibCxxQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF9FF1F61FAA79FE00474976 /* LibCxxQueue.cpp */; }; AF9FF1F51FAA79A400474976 /* LibCxxTuple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF9FF1F41FAA79A400474976 /* LibCxxTuple.cpp */; }; 945261C41B9A11FC00BF138D /* LibCxxUnorderedMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 945261BA1B9A11E800BF138D /* LibCxxUnorderedMap.cpp */; }; @@ -2000,6 +2001,7 @@ 945261B71B9A11E800BF138D /* LibCxxInitializerList.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxInitializerList.cpp; path = Language/CPlusPlus/LibCxxInitializerList.cpp; sourceTree = ""; }; 945261B81B9A11E800BF138D /* LibCxxList.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxList.cpp; path = Language/CPlusPlus/LibCxxList.cpp; sourceTree = ""; }; 945261B91B9A11E800BF138D /* LibCxxMap.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxMap.cpp; path = Language/CPlusPlus/LibCxxMap.cpp; sourceTree = ""; }; + E4A63A9020F55D27000D9548 /* LibCxxOptional.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxOptional.cpp; path = Language/CPlusPlus/LibCxxOptional.cpp; sourceTree = ""; }; AF9FF1F61FAA79FE00474976 /* LibCxxQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxQueue.cpp; path = Language/CPlusPlus/LibCxxQueue.cpp; sourceTree = ""; }; AF9FF1F41FAA79A400474976 /* LibCxxTuple.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxTuple.cpp; path = Language/CPlusPlus/LibCxxTuple.cpp; sourceTree = ""; }; 945261BA1B9A11E800BF138D /* LibCxxUnorderedMap.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxUnorderedMap.cpp; path = Language/CPlusPlus/LibCxxUnorderedMap.cpp; sourceTree = ""; }; @@ -6351,6 +6353,7 @@ 945261B71B9A11E800BF138D /* LibCxxInitializerList.cpp */, 945261B81B9A11E800BF138D /* LibCxxList.cpp */, 945261B91B9A11E800BF138D /* LibCxxMap.cpp */, + E4A63A9020F55D27000D9548 /* LibCxxOptional.cpp */, AF9FF1F61FAA79FE00474976 /* LibCxxQueue.cpp */, AF9FF1F41FAA79A400474976 /* LibCxxTuple.cpp */, 945261BA1B9A11E800BF138D /* LibCxxUnorderedMap.cpp */, @@ -8045,6 +8048,7 @@ AF26703B1852D01E00B6CC36 /* QueueList.cpp in Sources */, 267C012B136880DF006E963E /* OptionGroupValueObjectDisplay.cpp in Sources */, 49CA96FE1E6AACC900C03FEE /* DataEncoder.cpp in Sources */, + E4A63A9120F55D28000D9548 /* LibCxxOptional.cpp in Sources */, 26BCFC521368AE38006DC050 /* OptionGroupFormat.cpp in Sources */, 2654A6901E552ED500DA1013 /* VASprintf.cpp in Sources */, AF81DEFA1828A23F0042CF19 /* SystemRuntime.cpp in Sources */, diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile new file mode 100644 index 000000000000..a6ea665ef63c --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../../../../make + +CXX_SOURCES := main.cpp + +USE_LIBCPP := 1 +include $(LEVEL)/Makefile.rules +CXXFLAGS += -std=c++17 diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py new file mode 100644 index 000000000000..630b49693f4b --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py @@ -0,0 +1,59 @@ +""" +Test lldb data formatter subsystem. +""" + +from __future__ import print_function + + +import os +import time +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class LibcxxOptionalDataFormatterTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @add_test_categories(["libc++"]) + + def test_with_run_command(self): + """Test that that file and class static variables display correctly.""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + bkpt = self.target().FindBreakpointByID( + lldbutil.run_break_set_by_source_regexp( + self, "break here")) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + self.expect("frame variable number_not_engaged", + substrs=['Has Value=false']) + + self.expect("frame variable number_engaged", + substrs=['Has Value=true', + 'Value = 42', + '}']) + + self.expect("frame var numbers", + substrs=['(optional_int_vect) numbers = Has Value=true {', + 'Value = size=4 {', + '[0] = 1', + '[1] = 2', + '[2] = 3', + '[3] = 4', + '}', + '}']) + + self.expect("frame var ostring", + substrs=['(optional_string) ostring = Has Value=true {', + 'Value = "hello"', + '}']) diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp new file mode 100644 index 000000000000..8ff54d1f1190 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp @@ -0,0 +1,27 @@ +#include +#include +#include +#include + +using int_vect = std::vector ; +using optional_int = std::optional ; +using optional_int_vect = std::optional ; +using optional_string = std::optional ; + +int main() +{ + optional_int number_not_engaged ; + optional_int number_engaged = 42 ; + + printf( "%d\n", *number_engaged) ; + + optional_int_vect numbers{{1,2,3,4}} ; + + printf( "%d %d\n", numbers.value()[0], numbers.value()[1] ) ; + + optional_string ostring = "hello" ; + + printf( "%s\n", ostring->c_str() ) ; + + return 0; // break here +} diff --git a/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/source/Plugins/Language/CPlusPlus/CMakeLists.txt index 180440a244a4..1f0454450f44 100644 --- a/source/Plugins/Language/CPlusPlus/CMakeLists.txt +++ b/source/Plugins/Language/CPlusPlus/CMakeLists.txt @@ -9,6 +9,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN LibCxxInitializerList.cpp LibCxxList.cpp LibCxxMap.cpp + LibCxxOptional.cpp LibCxxQueue.cpp LibCxxTuple.cpp LibCxxUnorderedMap.cpp diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 2c63e6467d4c..a8516e23d694 100644 --- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -493,6 +493,10 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "libc++ std::tuple synthetic children", ConstString("^std::__(ndk)?1::tuple<.*>(( )?&)?$"), stl_synth_flags, true); + AddCXXSynthetic(cpp_category_sp, LibcxxOptionalFrontEndCreator, + "libc++ std::optional synthetic children", + ConstString("^std::__(ndk)?1::optional<.+>(( )?&)?$"), + stl_synth_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator, @@ -584,6 +588,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider, "libc++ std::atomic summary provider", ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_summary_flags, true); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibcxxOptionalSummaryProvider, + "libc++ std::optional summary provider", + ConstString("^std::__(ndk)?1::optional<.+>(( )?&)?$"), + stl_summary_flags, true); stl_summary_flags.SetSkipPointers(true); diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 95e02a473cd7..6c5a4f6095c1 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -33,6 +33,28 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; +bool lldb_private::formatters::LibcxxOptionalSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); + if (!valobj_sp) + return false; + + // An optional either contains a value or not, the member __engaged_ is + // a bool flag, it is true if the optional has a value and false otherwise. + ValueObjectSP engaged_sp( + valobj_sp->GetChildMemberWithName(ConstString("__engaged_"), true)); + + if (!engaged_sp) + return false; + + llvm::StringRef engaged_as_cstring( + engaged_sp->GetValueAsUnsigned(0) == 1 ? "true" : "false"); + + stream.Printf(" Has Value=%s ", engaged_as_cstring.data()); + + return true; +} + bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.h b/source/Plugins/Language/CPlusPlus/LibCxx.h index 3f6e0d6e14d7..0a45504cf767 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxx.h +++ b/source/Plugins/Language/CPlusPlus/LibCxx.h @@ -27,6 +27,10 @@ bool LibcxxWStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); // libc++ std::wstring +bool LibcxxOptionalSummaryProvider( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); // libc++ std::optional<> + bool LibcxxSmartPointerSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions @@ -133,6 +137,10 @@ SyntheticChildrenFrontEnd *LibcxxQueueFrontEndCreator(CXXSyntheticChildren *, SyntheticChildrenFrontEnd *LibcxxTupleFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); +SyntheticChildrenFrontEnd * +LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *, + lldb::ValueObjectSP valobj_sp); + } // namespace formatters } // namespace lldb_private diff --git a/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp new file mode 100644 index 000000000000..762b824f262a --- /dev/null +++ b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp @@ -0,0 +1,85 @@ +//===-- LibCxxOptional.cpp --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LibCxx.h" +#include "lldb/DataFormatters/FormattersHelpers.h" + +using namespace lldb; +using namespace lldb_private; + +namespace { + +class OptionalFrontEnd : public SyntheticChildrenFrontEnd { +public: + OptionalFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) { + Update(); + } + + size_t GetIndexOfChildWithName(const ConstString &name) override { + return formatters::ExtractIndexFromString(name.GetCString()); + } + + bool MightHaveChildren() override { return true; } + bool Update() override; + size_t CalculateNumChildren() override { return m_size; } + ValueObjectSP GetChildAtIndex(size_t idx) override; + +private: + size_t m_size = 0; + ValueObjectSP m_base_sp; +}; +} // namespace + +bool OptionalFrontEnd::Update() { + ValueObjectSP engaged_sp( + m_backend.GetChildMemberWithName(ConstString("__engaged_"), true)); + + if (!engaged_sp) + return false; + + // __engaged_ is a bool flag and is true if the optional contains a value. + // Converting it to unsigned gives us a size of 1 if it contains a value + // and 0 if not. + m_size = engaged_sp->GetValueAsUnsigned(0); + + return false; +} + +ValueObjectSP OptionalFrontEnd::GetChildAtIndex(size_t idx) { + if (idx >= m_size) + return ValueObjectSP(); + + // __val_ contains the underlying value of an optional if it has one. + // Currently because it is part of an anonymous union GetChildMemberWithName() + // does not peer through and find it unless we are at the parent itself. + // We can obtain the parent through __engaged_. + ValueObjectSP val_sp( + m_backend.GetChildMemberWithName(ConstString("__engaged_"), true) + ->GetParent() + ->GetChildAtIndex(0, true) + ->GetChildMemberWithName(ConstString("__val_"), true)); + + if (!val_sp) + return ValueObjectSP(); + + CompilerType holder_type = val_sp->GetCompilerType(); + + if (!holder_type) + return ValueObjectSP(); + + return val_sp->Clone(ConstString(llvm::formatv("Value").str())); +} + +SyntheticChildrenFrontEnd * +formatters::LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *, + lldb::ValueObjectSP valobj_sp) { + if (valobj_sp) + return new OptionalFrontEnd(*valobj_sp); + return nullptr; +} From 0cbfd20bab03af68d9a32d7dca378f0ac501f219 Mon Sep 17 00:00:00 2001 From: Davide Italiano Date: Fri, 27 Jul 2018 20:38:01 +0000 Subject: [PATCH 0016/1112] Revert "Recommit [DataFormatters] Add formatter for C++17 std::optional." This broke a linux bot which doesn't support -std=c++17. The solution is to add a decorator to skip these tests on machines with older compilers. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338162 91177308-0d34-0410-b5e6-96231b3b80d8 --- lldb.xcodeproj/project.pbxproj | 4 - .../libcxx/optional/Makefile | 7 -- .../TestDataFormatterLibcxxOptional.py | 59 ------------- .../libcxx/optional/main.cpp | 27 ------ .../Plugins/Language/CPlusPlus/CMakeLists.txt | 1 - .../Language/CPlusPlus/CPlusPlusLanguage.cpp | 9 -- source/Plugins/Language/CPlusPlus/LibCxx.cpp | 22 ----- source/Plugins/Language/CPlusPlus/LibCxx.h | 8 -- .../Language/CPlusPlus/LibCxxOptional.cpp | 85 ------------------- 9 files changed, 222 deletions(-) delete mode 100644 packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile delete mode 100644 packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py delete mode 100644 packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp delete mode 100644 source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index f94a3a7706fb..d8a714415320 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -388,7 +388,6 @@ 945261C11B9A11FC00BF138D /* LibCxxInitializerList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 945261B71B9A11E800BF138D /* LibCxxInitializerList.cpp */; }; 945261C21B9A11FC00BF138D /* LibCxxList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 945261B81B9A11E800BF138D /* LibCxxList.cpp */; }; 945261C31B9A11FC00BF138D /* LibCxxMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 945261B91B9A11E800BF138D /* LibCxxMap.cpp */; }; - E4A63A9120F55D28000D9548 /* LibCxxOptional.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4A63A9020F55D27000D9548 /* LibCxxOptional.cpp */; }; AF9FF1F71FAA79FE00474976 /* LibCxxQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF9FF1F61FAA79FE00474976 /* LibCxxQueue.cpp */; }; AF9FF1F51FAA79A400474976 /* LibCxxTuple.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF9FF1F41FAA79A400474976 /* LibCxxTuple.cpp */; }; 945261C41B9A11FC00BF138D /* LibCxxUnorderedMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 945261BA1B9A11E800BF138D /* LibCxxUnorderedMap.cpp */; }; @@ -2001,7 +2000,6 @@ 945261B71B9A11E800BF138D /* LibCxxInitializerList.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxInitializerList.cpp; path = Language/CPlusPlus/LibCxxInitializerList.cpp; sourceTree = ""; }; 945261B81B9A11E800BF138D /* LibCxxList.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxList.cpp; path = Language/CPlusPlus/LibCxxList.cpp; sourceTree = ""; }; 945261B91B9A11E800BF138D /* LibCxxMap.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxMap.cpp; path = Language/CPlusPlus/LibCxxMap.cpp; sourceTree = ""; }; - E4A63A9020F55D27000D9548 /* LibCxxOptional.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxOptional.cpp; path = Language/CPlusPlus/LibCxxOptional.cpp; sourceTree = ""; }; AF9FF1F61FAA79FE00474976 /* LibCxxQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxQueue.cpp; path = Language/CPlusPlus/LibCxxQueue.cpp; sourceTree = ""; }; AF9FF1F41FAA79A400474976 /* LibCxxTuple.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxTuple.cpp; path = Language/CPlusPlus/LibCxxTuple.cpp; sourceTree = ""; }; 945261BA1B9A11E800BF138D /* LibCxxUnorderedMap.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxUnorderedMap.cpp; path = Language/CPlusPlus/LibCxxUnorderedMap.cpp; sourceTree = ""; }; @@ -6353,7 +6351,6 @@ 945261B71B9A11E800BF138D /* LibCxxInitializerList.cpp */, 945261B81B9A11E800BF138D /* LibCxxList.cpp */, 945261B91B9A11E800BF138D /* LibCxxMap.cpp */, - E4A63A9020F55D27000D9548 /* LibCxxOptional.cpp */, AF9FF1F61FAA79FE00474976 /* LibCxxQueue.cpp */, AF9FF1F41FAA79A400474976 /* LibCxxTuple.cpp */, 945261BA1B9A11E800BF138D /* LibCxxUnorderedMap.cpp */, @@ -8048,7 +8045,6 @@ AF26703B1852D01E00B6CC36 /* QueueList.cpp in Sources */, 267C012B136880DF006E963E /* OptionGroupValueObjectDisplay.cpp in Sources */, 49CA96FE1E6AACC900C03FEE /* DataEncoder.cpp in Sources */, - E4A63A9120F55D28000D9548 /* LibCxxOptional.cpp in Sources */, 26BCFC521368AE38006DC050 /* OptionGroupFormat.cpp in Sources */, 2654A6901E552ED500DA1013 /* VASprintf.cpp in Sources */, AF81DEFA1828A23F0042CF19 /* SystemRuntime.cpp in Sources */, diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile deleted file mode 100644 index a6ea665ef63c..000000000000 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -LEVEL = ../../../../../make - -CXX_SOURCES := main.cpp - -USE_LIBCPP := 1 -include $(LEVEL)/Makefile.rules -CXXFLAGS += -std=c++17 diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py deleted file mode 100644 index 630b49693f4b..000000000000 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/TestDataFormatterLibcxxOptional.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -Test lldb data formatter subsystem. -""" - -from __future__ import print_function - - -import os -import time -import lldb -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil - - -class LibcxxOptionalDataFormatterTestCase(TestBase): - - mydir = TestBase.compute_mydir(__file__) - - @add_test_categories(["libc++"]) - - def test_with_run_command(self): - """Test that that file and class static variables display correctly.""" - self.build() - self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) - - bkpt = self.target().FindBreakpointByID( - lldbutil.run_break_set_by_source_regexp( - self, "break here")) - - self.runCmd("run", RUN_SUCCEEDED) - - # The stop reason of the thread should be breakpoint. - self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, - substrs=['stopped', - 'stop reason = breakpoint']) - - self.expect("frame variable number_not_engaged", - substrs=['Has Value=false']) - - self.expect("frame variable number_engaged", - substrs=['Has Value=true', - 'Value = 42', - '}']) - - self.expect("frame var numbers", - substrs=['(optional_int_vect) numbers = Has Value=true {', - 'Value = size=4 {', - '[0] = 1', - '[1] = 2', - '[2] = 3', - '[3] = 4', - '}', - '}']) - - self.expect("frame var ostring", - substrs=['(optional_string) ostring = Has Value=true {', - 'Value = "hello"', - '}']) diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp deleted file mode 100644 index 8ff54d1f1190..000000000000 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/optional/main.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include - -using int_vect = std::vector ; -using optional_int = std::optional ; -using optional_int_vect = std::optional ; -using optional_string = std::optional ; - -int main() -{ - optional_int number_not_engaged ; - optional_int number_engaged = 42 ; - - printf( "%d\n", *number_engaged) ; - - optional_int_vect numbers{{1,2,3,4}} ; - - printf( "%d %d\n", numbers.value()[0], numbers.value()[1] ) ; - - optional_string ostring = "hello" ; - - printf( "%s\n", ostring->c_str() ) ; - - return 0; // break here -} diff --git a/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/source/Plugins/Language/CPlusPlus/CMakeLists.txt index 1f0454450f44..180440a244a4 100644 --- a/source/Plugins/Language/CPlusPlus/CMakeLists.txt +++ b/source/Plugins/Language/CPlusPlus/CMakeLists.txt @@ -9,7 +9,6 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN LibCxxInitializerList.cpp LibCxxList.cpp LibCxxMap.cpp - LibCxxOptional.cpp LibCxxQueue.cpp LibCxxTuple.cpp LibCxxUnorderedMap.cpp diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index a8516e23d694..2c63e6467d4c 100644 --- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -493,10 +493,6 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "libc++ std::tuple synthetic children", ConstString("^std::__(ndk)?1::tuple<.*>(( )?&)?$"), stl_synth_flags, true); - AddCXXSynthetic(cpp_category_sp, LibcxxOptionalFrontEndCreator, - "libc++ std::optional synthetic children", - ConstString("^std::__(ndk)?1::optional<.+>(( )?&)?$"), - stl_synth_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator, @@ -588,11 +584,6 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider, "libc++ std::atomic summary provider", ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_summary_flags, true); - AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxOptionalSummaryProvider, - "libc++ std::optional summary provider", - ConstString("^std::__(ndk)?1::optional<.+>(( )?&)?$"), - stl_summary_flags, true); stl_summary_flags.SetSkipPointers(true); diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 6c5a4f6095c1..95e02a473cd7 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -33,28 +33,6 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; -bool lldb_private::formatters::LibcxxOptionalSummaryProvider( - ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { - ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); - if (!valobj_sp) - return false; - - // An optional either contains a value or not, the member __engaged_ is - // a bool flag, it is true if the optional has a value and false otherwise. - ValueObjectSP engaged_sp( - valobj_sp->GetChildMemberWithName(ConstString("__engaged_"), true)); - - if (!engaged_sp) - return false; - - llvm::StringRef engaged_as_cstring( - engaged_sp->GetValueAsUnsigned(0) == 1 ? "true" : "false"); - - stream.Printf(" Has Value=%s ", engaged_as_cstring.data()); - - return true; -} - bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.h b/source/Plugins/Language/CPlusPlus/LibCxx.h index 0a45504cf767..3f6e0d6e14d7 100644 --- a/source/Plugins/Language/CPlusPlus/LibCxx.h +++ b/source/Plugins/Language/CPlusPlus/LibCxx.h @@ -27,10 +27,6 @@ bool LibcxxWStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); // libc++ std::wstring -bool LibcxxOptionalSummaryProvider( - ValueObject &valobj, Stream &stream, - const TypeSummaryOptions &options); // libc++ std::optional<> - bool LibcxxSmartPointerSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions @@ -137,10 +133,6 @@ SyntheticChildrenFrontEnd *LibcxxQueueFrontEndCreator(CXXSyntheticChildren *, SyntheticChildrenFrontEnd *LibcxxTupleFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); -SyntheticChildrenFrontEnd * -LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *, - lldb::ValueObjectSP valobj_sp); - } // namespace formatters } // namespace lldb_private diff --git a/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp deleted file mode 100644 index 762b824f262a..000000000000 --- a/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp +++ /dev/null @@ -1,85 +0,0 @@ -//===-- LibCxxOptional.cpp --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "LibCxx.h" -#include "lldb/DataFormatters/FormattersHelpers.h" - -using namespace lldb; -using namespace lldb_private; - -namespace { - -class OptionalFrontEnd : public SyntheticChildrenFrontEnd { -public: - OptionalFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) { - Update(); - } - - size_t GetIndexOfChildWithName(const ConstString &name) override { - return formatters::ExtractIndexFromString(name.GetCString()); - } - - bool MightHaveChildren() override { return true; } - bool Update() override; - size_t CalculateNumChildren() override { return m_size; } - ValueObjectSP GetChildAtIndex(size_t idx) override; - -private: - size_t m_size = 0; - ValueObjectSP m_base_sp; -}; -} // namespace - -bool OptionalFrontEnd::Update() { - ValueObjectSP engaged_sp( - m_backend.GetChildMemberWithName(ConstString("__engaged_"), true)); - - if (!engaged_sp) - return false; - - // __engaged_ is a bool flag and is true if the optional contains a value. - // Converting it to unsigned gives us a size of 1 if it contains a value - // and 0 if not. - m_size = engaged_sp->GetValueAsUnsigned(0); - - return false; -} - -ValueObjectSP OptionalFrontEnd::GetChildAtIndex(size_t idx) { - if (idx >= m_size) - return ValueObjectSP(); - - // __val_ contains the underlying value of an optional if it has one. - // Currently because it is part of an anonymous union GetChildMemberWithName() - // does not peer through and find it unless we are at the parent itself. - // We can obtain the parent through __engaged_. - ValueObjectSP val_sp( - m_backend.GetChildMemberWithName(ConstString("__engaged_"), true) - ->GetParent() - ->GetChildAtIndex(0, true) - ->GetChildMemberWithName(ConstString("__val_"), true)); - - if (!val_sp) - return ValueObjectSP(); - - CompilerType holder_type = val_sp->GetCompilerType(); - - if (!holder_type) - return ValueObjectSP(); - - return val_sp->Clone(ConstString(llvm::formatv("Value").str())); -} - -SyntheticChildrenFrontEnd * -formatters::LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *, - lldb::ValueObjectSP valobj_sp) { - if (valobj_sp) - return new OptionalFrontEnd(*valobj_sp); - return nullptr; -} From 8e9a6ed57368d749b09282e8ec8882b5dea8b90a Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Fri, 27 Jul 2018 22:20:59 +0000 Subject: [PATCH 0017/1112] Fix whitespace in the python test suite. Summary: The test suite has often unnecessary trailing whitespace, and sometimes unnecessary trailing lines or a missing final new line. This patch just strips trailing whitespace/lines and adds missing newlines at the end. Subscribers: ki.stfu, JDevlieghere, christof, lldb-commits Differential Revision: https://reviews.llvm.org/D49943 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338171 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../TestMultipleDebuggers.py | 2 +- .../api/multithreaded/TestMultithreaded.py | 2 +- packages/Python/lldbsuite/test/decorators.py | 2 +- .../TestCallStdStringFunction.py | 2 +- .../call-restarts/TestCallThatRestarts.py | 2 +- .../call-throws/TestCallThatThrows.py | 2 +- .../expression_command/char/TestExprsChar.py | 2 +- .../expression_command/fixits/TestFixIts.py | 2 +- .../issue_11588/Test11588.py | 4 +-- .../pr35310/TestExprsBug35310.py | 2 +- .../save_jit_objects/TestSaveJITObjects.py | 4 +-- .../unwind_expression/TestUnwindExpression.py | 2 +- .../xvalue/TestXValuePrinting.py | 2 +- .../TestBadAddressBreakpoints.py | 2 +- .../TestBreakpointAutoContinue.py | 8 ++--- .../TestBreakpointLocations.py | 10 +++---- .../breakpoint_names/TestBreakpointNames.py | 30 +++++++++---------- .../TestHWBreakMultiThread.py | 6 ++-- .../serialize/TestBreakpointSerialization.py | 16 ++++------ .../TestStepOverBreakpoint.py | 12 ++++---- .../completion/TestCompletion.py | 2 +- .../bitset/TestDataFormatterLibcxxBitset.py | 4 +-- .../list/TestDataFormatterLibcxxList.py | 2 +- .../TestDataFormatterLibcxxMultiSet.py | 2 +- .../libcxx/set/TestDataFormatterLibcxxSet.py | 4 +-- .../vector/TestDataFormatterLibcxxVector.py | 2 +- .../tuple/TestDataFormatterStdTuple.py | 2 +- .../test/functionalities/exec/TestExec.py | 2 +- .../frame-language/TestGuessLanguage.py | 6 ++-- .../functionalities/frame_var/TestFrameVar.py | 10 +++---- .../gdb_remote_client/TestTargetXMLArch.py | 12 ++++---- .../gdb_remote_client/gdbclientutils.py | 2 +- .../history/TestHistoryRecall.py | 4 +-- .../load_unload/TestLoadUnload.py | 4 +-- .../load_using_paths/TestLoadUsingPaths.py | 22 +++++++------- .../pre_run_dylibs/TestPreRunDylibs.py | 2 +- .../register/intel_avx/TestZMMRegister.py | 2 +- .../return-value/TestReturnValue.py | 2 +- .../TestCreateDuringStep.py | 2 +- .../thread/num_threads/TestNumThreads.py | 2 +- .../thread/step_until/TestStepUntil.py | 2 +- .../TestWatchpointMultipleSlots.py | 4 +-- .../TestWatchpointDisable.py | 6 ++-- .../c/find_struct_type/TestFindStructTypes.py | 2 +- .../TestDynamicValueSameBase.py | 6 ++-- .../TestCppIncompleteTypes.py | 2 +- .../test/lang/cpp/llvm-style/TestLLVMStyle.py | 2 +- .../test/lang/cpp/scope/TestCppScope.py | 2 +- .../lang/cpp/trivial_abi/TestTrivialABI.py | 4 +-- packages/Python/lldbsuite/test/lldbdwarf.py | 6 ++-- packages/Python/lldbsuite/test/lldbtest.py | 10 +++---- packages/Python/lldbsuite/test/lldbutil.py | 10 +++---- .../find-app-in-bundle/TestFindAppInBundle.py | 6 ++-- .../TestBundleWithDotInFilename.py | 2 +- .../find-dsym/deep-bundle/TestDeepBundle.py | 4 +-- .../thread-names/TestInterruptThreadNames.py | 6 ++-- .../python_api/name_lookup/TestNameLookup.py | 10 +++---- .../test/python_api/sbdata/TestSBData.py | 2 +- .../test/sample_test/TestSampleTest.py | 4 +-- .../lldbsuite/test/settings/TestSettings.py | 2 +- .../startup_options/TestMiStartupOptions.py | 2 +- .../TestGdbRemote_qThreadStopInfo.py | 2 +- .../tools/lldb-server/TestLldbGdbServer.py | 2 +- 63 files changed, 149 insertions(+), 153 deletions(-) diff --git a/packages/Python/lldbsuite/test/api/multiple-debuggers/TestMultipleDebuggers.py b/packages/Python/lldbsuite/test/api/multiple-debuggers/TestMultipleDebuggers.py index 27bd472caf99..f6bde75dcb79 100644 --- a/packages/Python/lldbsuite/test/api/multiple-debuggers/TestMultipleDebuggers.py +++ b/packages/Python/lldbsuite/test/api/multiple-debuggers/TestMultipleDebuggers.py @@ -18,7 +18,7 @@ class TestMultipleSimultaneousDebuggers(TestBase): mydir = TestBase.compute_mydir(__file__) - # This test case fails non-deterministically. + # This test case fails non-deterministically. @skipIfNoSBHeaders @expectedFailureAll(bugnumber="llvm.org/pr20282") def test_multiple_debuggers(self): diff --git a/packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py b/packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py index 4e550c9c24db..dd03fcf31e87 100644 --- a/packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py +++ b/packages/Python/lldbsuite/test/api/multithreaded/TestMultithreaded.py @@ -16,7 +16,7 @@ class SBBreakpointCallbackCase(TestBase): NO_DEBUG_INFO_TESTCASE = True - + def setUp(self): TestBase.setUp(self) self.generateSource('driver.cpp') diff --git a/packages/Python/lldbsuite/test/decorators.py b/packages/Python/lldbsuite/test/decorators.py index 1fdfd2caac00..8b33cad3d1ba 100644 --- a/packages/Python/lldbsuite/test/decorators.py +++ b/packages/Python/lldbsuite/test/decorators.py @@ -791,7 +791,7 @@ def skipIfLLVMTargetMissing(target): if targets.GetItemAtIndex(i).GetStringValue(99) == target: found = True break - + return unittest2.skipIf(not found, "requires " + target) # Call sysctl on darwin to see if a specified hardware feature is available on this machine. diff --git a/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStdStringFunction.py b/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStdStringFunction.py index 079ab6d60888..8f2ea371f2b1 100644 --- a/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStdStringFunction.py +++ b/packages/Python/lldbsuite/test/expression_command/call-function/TestCallStdStringFunction.py @@ -46,7 +46,7 @@ def test_with(self): # Calling this function now succeeds, but we follow the typedef return type through to # const char *, and thus don't invoke the Summary formatter. - # clang's libstdc++ on ios arm64 inlines std::string::c_str() always; + # clang's libstdc++ on ios arm64 inlines std::string::c_str() always; # skip this part of the test. triple = self.dbg.GetSelectedPlatform().GetTriple() do_cstr_test = True diff --git a/packages/Python/lldbsuite/test/expression_command/call-restarts/TestCallThatRestarts.py b/packages/Python/lldbsuite/test/expression_command/call-restarts/TestCallThatRestarts.py index 5eb7b309c94a..1182b156e80c 100644 --- a/packages/Python/lldbsuite/test/expression_command/call-restarts/TestCallThatRestarts.py +++ b/packages/Python/lldbsuite/test/expression_command/call-restarts/TestCallThatRestarts.py @@ -48,7 +48,7 @@ def check_after_call(self, num_sigchld): "Restored the zeroth frame correctly") def call_function(self): - (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(self, 'Stop here in main.', self.main_source_spec) # Make sure the SIGCHLD behavior is pass/no-stop/no-notify: diff --git a/packages/Python/lldbsuite/test/expression_command/call-throws/TestCallThatThrows.py b/packages/Python/lldbsuite/test/expression_command/call-throws/TestCallThatThrows.py index f2ec340ac845..c6b90ba5ba02 100644 --- a/packages/Python/lldbsuite/test/expression_command/call-throws/TestCallThatThrows.py +++ b/packages/Python/lldbsuite/test/expression_command/call-throws/TestCallThatThrows.py @@ -37,7 +37,7 @@ def check_after_call(self): def call_function(self): """Test calling function that throws.""" - (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(self, 'I am about to throw.', self.main_source_spec) options = lldb.SBExpressionOptions() diff --git a/packages/Python/lldbsuite/test/expression_command/char/TestExprsChar.py b/packages/Python/lldbsuite/test/expression_command/char/TestExprsChar.py index 2f1406874765..b328ece6d39c 100644 --- a/packages/Python/lldbsuite/test/expression_command/char/TestExprsChar.py +++ b/packages/Python/lldbsuite/test/expression_command/char/TestExprsChar.py @@ -22,7 +22,7 @@ def do_test(self, dictionary=None): """These basic expression commands should work as expected.""" self.build(dictionary=dictionary) - (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, '// Break here', self.main_source_spec) frame = thread.GetFrameAtIndex(0) diff --git a/packages/Python/lldbsuite/test/expression_command/fixits/TestFixIts.py b/packages/Python/lldbsuite/test/expression_command/fixits/TestFixIts.py index 4b096149e728..9aa28f77a3fd 100644 --- a/packages/Python/lldbsuite/test/expression_command/fixits/TestFixIts.py +++ b/packages/Python/lldbsuite/test/expression_command/fixits/TestFixIts.py @@ -37,7 +37,7 @@ def test_with_dummy_target(self): def try_expressions(self): """Test calling expressions with errors that can be fixed by the FixIts.""" - (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(self, 'Stop here to evaluate expressions', self.main_source_spec) options = lldb.SBExpressionOptions() diff --git a/packages/Python/lldbsuite/test/expression_command/issue_11588/Test11588.py b/packages/Python/lldbsuite/test/expression_command/issue_11588/Test11588.py index a2d68cffe548..09b0eaaa2b15 100644 --- a/packages/Python/lldbsuite/test/expression_command/issue_11588/Test11588.py +++ b/packages/Python/lldbsuite/test/expression_command/issue_11588/Test11588.py @@ -32,8 +32,8 @@ def cleanup(): """valobj.AddressOf() should return correct values.""" self.build() - (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, - 'Set breakpoint here.', + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + 'Set breakpoint here.', lldb.SBFileSpec("main.cpp", False)) self.runCmd("command script import --allow-reload s11588.py") self.runCmd( diff --git a/packages/Python/lldbsuite/test/expression_command/pr35310/TestExprsBug35310.py b/packages/Python/lldbsuite/test/expression_command/pr35310/TestExprsBug35310.py index 9cc9df2b22be..dd3d06fd672f 100644 --- a/packages/Python/lldbsuite/test/expression_command/pr35310/TestExprsBug35310.py +++ b/packages/Python/lldbsuite/test/expression_command/pr35310/TestExprsBug35310.py @@ -25,7 +25,7 @@ def test_issue35310(self): """ self.build() - (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, '// Break here', self.main_source_spec) frame = thread.GetFrameAtIndex(0) diff --git a/packages/Python/lldbsuite/test/expression_command/save_jit_objects/TestSaveJITObjects.py b/packages/Python/lldbsuite/test/expression_command/save_jit_objects/TestSaveJITObjects.py index c1a1b375e155..fe6816f6aba1 100644 --- a/packages/Python/lldbsuite/test/expression_command/save_jit_objects/TestSaveJITObjects.py +++ b/packages/Python/lldbsuite/test/expression_command/save_jit_objects/TestSaveJITObjects.py @@ -16,7 +16,7 @@ class SaveJITObjectsTestCase(TestBase): def enumerateJITFiles(self): return [f for f in os.listdir(self.getBuildDir()) if f.startswith("jit")] - + def countJITFiles(self): return len(self.enumerateJITFiles()) @@ -31,7 +31,7 @@ def test_save_jit_objects(self): os.chdir(self.getBuildDir()) src_file = "main.c" src_file_spec = lldb.SBFileSpec(src_file) - + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( self, "break", src_file_spec) diff --git a/packages/Python/lldbsuite/test/expression_command/unwind_expression/TestUnwindExpression.py b/packages/Python/lldbsuite/test/expression_command/unwind_expression/TestUnwindExpression.py index 3b01d4470de6..c942427a8e66 100644 --- a/packages/Python/lldbsuite/test/expression_command/unwind_expression/TestUnwindExpression.py +++ b/packages/Python/lldbsuite/test/expression_command/unwind_expression/TestUnwindExpression.py @@ -23,7 +23,7 @@ class UnwindFromExpressionTest(TestBase): def build_and_run_to_bkpt(self): self.build() - (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(self, "// Set a breakpoint here to get started", self.main_spec) # Next set a breakpoint in this function, set up Expression options to stop on diff --git a/packages/Python/lldbsuite/test/expression_command/xvalue/TestXValuePrinting.py b/packages/Python/lldbsuite/test/expression_command/xvalue/TestXValuePrinting.py index 4ad4225a5fe4..3aac6488660c 100644 --- a/packages/Python/lldbsuite/test/expression_command/xvalue/TestXValuePrinting.py +++ b/packages/Python/lldbsuite/test/expression_command/xvalue/TestXValuePrinting.py @@ -22,7 +22,7 @@ def do_test(self, dictionary=None): """Printing an xvalue should work.""" self.build(dictionary=dictionary) - (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, '// Break here', self.main_source_spec) frame = thread.GetFrameAtIndex(0) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/TestBadAddressBreakpoints.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/TestBadAddressBreakpoints.py index 5014c1cd4a24..460e07ceadf0 100644 --- a/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/TestBadAddressBreakpoints.py +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/address_breakpoints/TestBadAddressBreakpoints.py @@ -31,7 +31,7 @@ def setUp(self): def address_breakpoints(self): """Test that breakpoints set on a bad address say they are bad.""" target, process, thread, bkpt = \ - lldbutil.run_to_source_breakpoint(self, + lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here", lldb.SBFileSpec("main.c")) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/auto_continue/TestBreakpointAutoContinue.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/auto_continue/TestBreakpointAutoContinue.py index 0123e732e35d..b5e38eec5793 100644 --- a/packages/Python/lldbsuite/test/functionalities/breakpoint/auto_continue/TestBreakpointAutoContinue.py +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/auto_continue/TestBreakpointAutoContinue.py @@ -34,17 +34,17 @@ def test_auto_continue_on_location(self): self.build() self.auto_continue_location() - def make_target_and_bkpt(self, additional_options=None, num_expected_loc=1, + def make_target_and_bkpt(self, additional_options=None, num_expected_loc=1, pattern="Set a breakpoint here"): exe = self.getBuildArtifact("a.out") self.target = self.dbg.CreateTarget(exe) self.assertTrue(self.target.IsValid(), "Target is not valid") - + extra_options_txt = "--auto-continue 1 " if additional_options: extra_options_txt += additional_options - bpno = lldbutil.run_break_set_by_source_regexp(self, pattern, - extra_options = extra_options_txt, + bpno = lldbutil.run_break_set_by_source_regexp(self, pattern, + extra_options = extra_options_txt, num_expected_locations = num_expected_loc) return bpno diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py index 7eb465f29599..f4835a9b9c44 100644 --- a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py @@ -46,12 +46,12 @@ def set_breakpoint (self): self.assertTrue(target, "Target %s is not valid"%(exe)) # This should create a breakpoint with 3 locations. - + bkpt = target.BreakpointCreateByLocation("main.c", self.line) # The breakpoint list should show 3 locations. self.assertEqual(bkpt.GetNumLocations(), 3, "Wrong number of locations") - + self.expect( "breakpoint list -f", "Breakpoint locations shown correctly", @@ -62,7 +62,7 @@ def set_breakpoint (self): "where = a.out`func_inlined .+unresolved, hit count = 0", "where = a.out`main .+\[inlined\].+unresolved, hit count = 0"]) - return bkpt + return bkpt def shadowed_bkpt_cond_test(self): """Test that options set on the breakpoint and location behave correctly.""" @@ -106,7 +106,7 @@ def shadowed_bkpt_command_test(self): commands = ["AAAAAA", "BBBBBB", "CCCCCC"] str_list = lldb.SBStringList() str_list.AppendList(commands, len(commands)) - + bkpt.SetCommandLineCommands(str_list) cmd_list = lldb.SBStringList() bkpt.GetCommandLineCommands(cmd_list) @@ -123,7 +123,7 @@ def shadowed_bkpt_command_test(self): bkpt.location[1].GetCommandLineCommands(loc_cmd_list) loc_list_size = loc_list.GetSize() - + # Check that the location has the right commands: self.assertEqual(loc_cmd_list.GetSize() , loc_list_size, "Added the right number of commands to location") for i in range(0,loc_list_size): diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_names/TestBreakpointNames.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_names/TestBreakpointNames.py index 8b5352866c21..b36e915e2204 100644 --- a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_names/TestBreakpointNames.py +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_names/TestBreakpointNames.py @@ -64,7 +64,7 @@ def setup_target(self): self.target = self.dbg.CreateTarget(exe) self.assertTrue(self.target, VALID_TARGET) self.main_file_spec = lldb.SBFileSpec(os.path.join(self.getSourceDir(), "main.c")) - + def check_name_in_target(self, bkpt_name): name_list = lldb.SBStringList() self.target.GetBreakpointNames(name_list) @@ -74,7 +74,7 @@ def check_name_in_target(self, bkpt_name): found_it = True break self.assertTrue(found_it, "Didn't find the name %s in the target's name list:"%(bkpt_name)) - + def setUp(self): # Call super's setUp(). TestBase.setUp(self) @@ -107,14 +107,14 @@ def do_check_names(self): matches = bkpt.MatchesName(bkpt_name) self.assertTrue(matches, "We didn't match the name we just set") - + # Make sure we don't match irrelevant names: matches = bkpt.MatchesName("NotABreakpoint") self.assertTrue(not matches, "We matched a name we didn't set.") # Make sure the name is also in the target: self.check_name_in_target(bkpt_name) - + # Add another name, make sure that works too: bkpt.AddName(other_bkpt_name) @@ -132,7 +132,7 @@ def do_check_names(self): bkpt.GetNames(name_list) num_names = name_list.GetSize() self.assertTrue(num_names == 1, "Name list has %d items, expected 1."%(num_names)) - + name = name_list.GetStringAtIndex(0) self.assertTrue(name == other_bkpt_name, "Remaining name was: %s expected %s."%(name, other_bkpt_name)) @@ -156,7 +156,7 @@ def do_check_illegal_names(self): def do_check_using_names(self): """Use Python APIs to check names work in place of breakpoint ID's.""" - + bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10) bkpt_name = "ABreakpoint" other_bkpt_name= "_AnotherBreakpoint" @@ -255,12 +255,12 @@ def do_check_configuring_names(self): bp_name.SetAutoContinue(new_auto_continue) self.assertEqual(bp_name.GetAutoContinue(), new_auto_continue, "Couldn't change auto-continue on the name") self.assertEqual(bkpt.GetAutoContinue(), new_auto_continue, "Option didn't propagate to the breakpoint.") - + # Now make this same breakpoint name - but from the command line - cmd_str = "breakpoint name configure %s -o %d -i %d -c '%s' -G %d -t %d -x %d -T '%s' -q '%s' -H '%s'"%(cl_bp_name_string, - self.is_one_shot, - self.ignore_count, - self.condition, + cmd_str = "breakpoint name configure %s -o %d -i %d -c '%s' -G %d -t %d -x %d -T '%s' -q '%s' -H '%s'"%(cl_bp_name_string, + self.is_one_shot, + self.ignore_count, + self.condition, self.auto_continue, self.tid, self.tidx, @@ -269,7 +269,7 @@ def do_check_configuring_names(self): self.help_string) for cmd in self.cmd_list: cmd_str += " -C '%s'"%(cmd) - + self.runCmd(cmd_str, check=True) # Now look up this name again and check its options: cl_name = lldb.SBBreakpointName(self.target, cl_bp_name_string) @@ -280,14 +280,14 @@ def do_check_configuring_names(self): new_help = "I do something even more interesting" cl_name.SetHelpString(new_help) self.assertEqual(new_help, cl_name.GetHelpString(), "SetHelpString didn't") - + # We should have three names now, make sure the target can list them: name_list = lldb.SBStringList() self.target.GetBreakpointNames(name_list) for name_string in [self.bp_name_string, other_bp_name_string, cl_bp_name_string]: self.assertTrue(name_string in name_list, "Didn't find %s in names"%(name_string)) - # Delete the name from the current target. Make sure that works and deletes the + # Delete the name from the current target. Make sure that works and deletes the # name from the breakpoint as well: self.target.DeleteBreakpointName(self.bp_name_string) name_list.Clear() @@ -305,7 +305,7 @@ def do_check_configuring_names(self): self.assertTrue(self.bp_name_string not in name_list, "Didn't delete %s from the dummy target"%(self.bp_name_string)) # Also make sure the name got removed from breakpoints holding it: self.assertFalse(bkpt.MatchesName(self.bp_name_string), "Didn't remove the name from the breakpoint.") - + def check_permission_results(self, bp_name): self.assertEqual(bp_name.GetAllowDelete(), False, "Didn't set allow delete.") protected_bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py index 69dfac225258..99b54329a0e1 100644 --- a/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/hardware_breakpoints/hardware_breakpoint_on_multiple_threads/TestHWBreakMultiThread.py @@ -25,7 +25,7 @@ class HardwareBreakpointMultiThreadTestCase(TestBase): @expectedFailureAndroid def test_hw_break_set_delete_multi_thread(self): self.build() - self.setTearDownCleanup() + self.setTearDownCleanup() self.break_multi_thread('delete') # LLDB supports hardware breakpoints for arm and aarch64 architectures. @@ -33,7 +33,7 @@ def test_hw_break_set_delete_multi_thread(self): @expectedFailureAndroid def test_hw_break_set_disable_multi_thread(self): self.build() - self.setTearDownCleanup() + self.setTearDownCleanup() self.break_multi_thread('disable') def setUp(self): @@ -74,7 +74,7 @@ def break_multi_thread(self, removal_type): count = 0 while count < 2 : - + self.runCmd("process continue") # We should be stopped in hw_break_function diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py index 5c3da17c254e..c615278e8d48 100644 --- a/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py @@ -65,7 +65,7 @@ def cleanup (): # Create the targets we are making breakpoints in and copying them to: self.orig_target = self.dbg.CreateTarget(exe) self.assertTrue(self.orig_target, VALID_TARGET) - + self.copy_target = self.dbg.CreateTarget(exe) self.assertTrue(self.copy_target, VALID_TARGET) @@ -91,7 +91,7 @@ def check_equivalence(self, source_bps, do_write = True): num_source_bps = source_bps.GetSize() num_copy_bps = copy_bps.GetSize() self.assertTrue(num_source_bps == num_copy_bps, "Didn't get same number of input and output breakpoints - orig: %d copy: %d"%(num_source_bps, num_copy_bps)) - + for i in range(0, num_source_bps): source_bp = source_bps.GetBreakpointAtIndex(i) source_desc = lldb.SBStream() @@ -132,7 +132,7 @@ def do_check_resolvers(self): source_bps.Append(self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list)) source_bps.Append(self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, empty_module_list,empty_cu_list)) source_bps.Append(self.orig_target.BreakpointCreateBySourceRegex("dont really care", blubby_file_spec)) - + # And some number greater than one: self.check_equivalence(source_bps) @@ -185,7 +185,7 @@ def do_check_options(self): bkpt.SetOneShot(True) bkpt.SetThreadID(10) source_bps.Append(bkpt) - + # Make sure we get one right: self.check_equivalence(source_bps) source_bps.Clear() @@ -232,7 +232,7 @@ def do_check_appending(self): bkpt.SetThreadID(10) source_bps.Append(bkpt) all_bps.Append(bkpt) - + error = lldb.SBError() error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, source_bps) self.assertTrue(error.Success(), "Failed writing breakpoints to file: %s."%(error.GetCString())) @@ -265,7 +265,7 @@ def do_check_names(self): write_bps = lldb.SBBreakpointList(self.orig_target) bkpt.AddName(good_bkpt_name) write_bps.Append(bkpt) - + error = lldb.SBError() error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, write_bps) self.assertTrue(error.Success(), "Failed writing breakpoints to file: %s."%(error.GetCString())) @@ -282,7 +282,3 @@ def do_check_names(self): error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, names_list, copy_bps) self.assertTrue(error.Success(), "Failed reading breakpoints from file: %s"%(error.GetCString())) self.assertTrue(copy_bps.GetSize() == 1, "Found the matching breakpoint.") - - - - diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py index c2084295ef79..07fd04940d96 100644 --- a/packages/Python/lldbsuite/test/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/step_over_breakpoint/TestStepOverBreakpoint.py @@ -1,8 +1,8 @@ """ Test that breakpoints do not affect stepping. -Check for correct StopReason when stepping to the line with breakpoint +Check for correct StopReason when stepping to the line with breakpoint which chould be eStopReasonBreakpoint in general, -and eStopReasonPlanComplete when breakpoint's condition fails. +and eStopReasonPlanComplete when breakpoint's condition fails. """ from __future__ import print_function @@ -19,7 +19,7 @@ class StepOverBreakpointsTestCase(TestBase): def setUp(self): TestBase.setUp(self) - + self.build() exe = self.getBuildArtifact("a.out") src = lldb.SBFileSpec("main.cpp") @@ -32,7 +32,7 @@ def setUp(self): self.line1 = line_number('main.cpp', "breakpoint_1") self.line4 = line_number('main.cpp', "breakpoint_4") - self.breakpoint1 = self.target.BreakpointCreateByLocation(src, self.line1) + self.breakpoint1 = self.target.BreakpointCreateByLocation(src, self.line1) self.assertTrue( self.breakpoint1 and self.breakpoint1.GetNumLocations() == 1, VALID_BREAKPOINT) @@ -52,7 +52,7 @@ def setUp(self): self.thread = lldbutil.get_one_thread_stopped_at_breakpoint(self.process, self.breakpoint1) self.assertIsNotNone(self.thread, "Didn't stop at breakpoint 1.") - def test_step_instruction(self): + def test_step_instruction(self): # Count instructions between breakpoint_1 and breakpoint_4 contextList = self.target.FindFunctions('main', lldb.eFunctionNameTypeAuto) self.assertEquals(contextList.GetSize(), 1) @@ -89,7 +89,7 @@ def test_step_instruction(self): @skipIf(bugnumber="llvm.org/pr31972", hostoslist=["windows"]) def test_step_over(self): #lldb.DBG.EnableLog("lldb", ["step","breakpoint"]) - + self.thread.StepOver() # We should be stopped at the breakpoint_2 line with stop plan complete reason self.assertEquals(self.process.GetState(), lldb.eStateStopped) diff --git a/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py b/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py index a3b23834ee12..4f6a073a44c5 100644 --- a/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py +++ b/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py @@ -261,7 +261,7 @@ def complete_from_to(self, str_input, patterns, turn_off_re_match=False): common_match = match_strings.GetStringAtIndex(0) if num_matches == 0: compare_string = str_input - else: + else: if common_match != None and len(common_match) > 0: compare_string = str_input + common_match else: diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/bitset/TestDataFormatterLibcxxBitset.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/bitset/TestDataFormatterLibcxxBitset.py index 4fa115e51655..a0da4e41afef 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/bitset/TestDataFormatterLibcxxBitset.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/bitset/TestDataFormatterLibcxxBitset.py @@ -49,7 +49,7 @@ def test_value(self): def test_ptr_and_ref(self): """Test that ref and ptr to std::bitset is displayed correctly""" self.build() - (_, process, _, bkpt) = lldbutil.run_to_source_breakpoint(self, + (_, process, _, bkpt) = lldbutil.run_to_source_breakpoint(self, 'Check ref and ptr', lldb.SBFileSpec("main.cpp", False)) @@ -57,6 +57,6 @@ def test_ptr_and_ref(self): self.check("ptr", 13) lldbutil.continue_to_breakpoint(process, bkpt) - + self.check("ref", 200) self.check("ptr", 200) diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py index 5f48b3541e5a..90a7e119fb84 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py @@ -90,7 +90,7 @@ def cleanup(): self.runCmd("n") # This gets up past the printf self.runCmd("n") # Now advance over the first push_back. - + self.expect("frame variable numbers_list", substrs=['list has 1 items', '[0] = ', diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/TestDataFormatterLibcxxMultiSet.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/TestDataFormatterLibcxxMultiSet.py index 72a886ff1285..0732c03de837 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/TestDataFormatterLibcxxMultiSet.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/multiset/TestDataFormatterLibcxxMultiSet.py @@ -134,7 +134,7 @@ def test_ref_and_ptr(self): """Test that the data formatters work on ref and ptr.""" self.build() (self.target, process, _, bkpt) = lldbutil.run_to_source_breakpoint( - self, "Stop here to check by ref and ptr.", + self, "Stop here to check by ref and ptr.", lldb.SBFileSpec("main.cpp", False)) # The reference should print just like the value: self.check_ii("ref") diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py index a6f1a3d2f430..8d83f2b081f8 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/set/TestDataFormatterLibcxxSet.py @@ -130,7 +130,7 @@ def test_ref_and_ptr(self): """Test that the data formatters work on ref and ptr.""" self.build() (self.target, process, _, bkpt) = lldbutil.run_to_source_breakpoint( - self, "Stop here to check by ref and ptr.", + self, "Stop here to check by ref and ptr.", lldb.SBFileSpec("main.cpp", False)) # The reference should print just like the value: self.check_ii("ref") @@ -139,4 +139,4 @@ def test_ref_and_ptr(self): substrs=["ptr =", "size=7"]) self.expect("expr ptr", substrs=["size=7"]) - + diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py index aeb10984b3b8..237e27fe1f31 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py @@ -192,7 +192,7 @@ def test_ref_and_ptr(self): self.check_numbers("ref") # The pointer should just show the right number of elements: - + self.expect("frame variable ptr", substrs=['ptr =', ' size=7']) self.expect("p ptr", substrs=['$', 'size=7']) diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/tuple/TestDataFormatterStdTuple.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/tuple/TestDataFormatterStdTuple.py index c2e02f546691..4f9047b84d0f 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/tuple/TestDataFormatterStdTuple.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/tuple/TestDataFormatterStdTuple.py @@ -40,7 +40,7 @@ def test_with_run_command(self): self.assertEqual('"foobar"', frame.GetValueForVariablePath("ts[0]").GetSummary()) self.assertFalse(frame.GetValueForVariablePath("ts[1]").IsValid()) - + self.assertEqual(1, frame.GetValueForVariablePath("tt[0]").GetValueAsUnsigned()) self.assertEqual('"baz"', frame.GetValueForVariablePath("tt[1]").GetSummary()) self.assertEqual(2, frame.GetValueForVariablePath("tt[2]").GetValueAsUnsigned()) diff --git a/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py b/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py index 611869932b61..8126a7ec750c 100644 --- a/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py +++ b/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py @@ -96,7 +96,7 @@ def cleanup(): if not skip_exec: self.assertTrue(process.GetState() == lldb.eStateStopped, "Process should be stopped at __dyld_start") - + threads = lldbutil.get_stopped_threads( process, lldb.eStopReasonExec) self.assertTrue( diff --git a/packages/Python/lldbsuite/test/functionalities/frame-language/TestGuessLanguage.py b/packages/Python/lldbsuite/test/functionalities/frame-language/TestGuessLanguage.py index 59af2de836ff..959b621521e9 100644 --- a/packages/Python/lldbsuite/test/functionalities/frame-language/TestGuessLanguage.py +++ b/packages/Python/lldbsuite/test/functionalities/frame-language/TestGuessLanguage.py @@ -18,7 +18,7 @@ class TestFrameGuessLanguage(TestBase): mydir = TestBase.compute_mydir(__file__) - # If your test case doesn't stress debug info, the + # 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 @@ -84,6 +84,6 @@ def do_test(self): self.check_language(thread, 0, c_frame_language) self.check_language(thread, 1, lldb.eLanguageTypeC_plus_plus) self.check_language(thread, 2, lldb.eLanguageTypeC_plus_plus) - - + + diff --git a/packages/Python/lldbsuite/test/functionalities/frame_var/TestFrameVar.py b/packages/Python/lldbsuite/test/functionalities/frame_var/TestFrameVar.py index 960891b9eefc..b4e1b9c07634 100644 --- a/packages/Python/lldbsuite/test/functionalities/frame_var/TestFrameVar.py +++ b/packages/Python/lldbsuite/test/functionalities/frame_var/TestFrameVar.py @@ -17,7 +17,7 @@ class TestFrameVar(TestBase): mydir = TestBase.compute_mydir(__file__) - # If your test case doesn't stress debug info, the + # 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 @@ -67,7 +67,7 @@ def do_test(self): frame = threads[0].GetFrameAtIndex(0) command_result = lldb.SBCommandReturnObject() interp = self.dbg.GetCommandInterpreter() - + # Just get args: result = interp.HandleCommand("frame var -l", command_result) self.assertEqual(result, lldb.eReturnStatusSuccessFinishResult, "frame var -a didn't succeed") @@ -85,7 +85,7 @@ def do_test(self): self.assertTrue("argv" not in output, "Locals found argv") self.assertTrue("test_var" in output, "Locals didn't find test_var") self.assertTrue("g_var" not in output, "Locals found a global") - + # Get the file statics: result = interp.HandleCommand("frame var -l -a -g", command_result) self.assertEqual(result, lldb.eReturnStatusSuccessFinishResult, "frame var -a didn't succeed") @@ -94,6 +94,6 @@ def do_test(self): self.assertTrue("argv" not in output, "Globals found argv") self.assertTrue("test_var" not in output, "Globals found test_var") self.assertTrue("g_var" in output, "Globals didn't find g_var") - - + + diff --git a/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestTargetXMLArch.py b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestTargetXMLArch.py index ef9ce7700963..184867e480b4 100644 --- a/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestTargetXMLArch.py +++ b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestTargetXMLArch.py @@ -98,12 +98,12 @@ def haltReason(self): return "T05thread:00000001;06:9038d60f00700000;07:98b4062680ffffff;10:c0d7bf1b80ffffff;" def readRegister(self, register): - regs = {0x0: "00b0060000610000", - 0xa: "68fe471c80ffffff", - 0xc: "60574a1c80ffffff", - 0xd: "18f3042680ffffff", - 0xe: "be8a4d7142000000", - 0xf: "50df471c80ffffff", + regs = {0x0: "00b0060000610000", + 0xa: "68fe471c80ffffff", + 0xc: "60574a1c80ffffff", + 0xd: "18f3042680ffffff", + 0xe: "be8a4d7142000000", + 0xf: "50df471c80ffffff", 0x10: "c0d7bf1b80ffffff" } if register in regs: return regs[register] diff --git a/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py index ebafd405e23e..d8d759a5dd58 100644 --- a/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py +++ b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py @@ -467,7 +467,7 @@ def assertPacketLogContains(self, packets): i = 0 j = 0 log = self.server.responder.packetLog - + while i < len(packets) and j < len(log): if log[j] == packets[i]: i += 1 diff --git a/packages/Python/lldbsuite/test/functionalities/history/TestHistoryRecall.py b/packages/Python/lldbsuite/test/functionalities/history/TestHistoryRecall.py index 90bd64901ee5..7956120bad32 100644 --- a/packages/Python/lldbsuite/test/functionalities/history/TestHistoryRecall.py +++ b/packages/Python/lldbsuite/test/functionalities/history/TestHistoryRecall.py @@ -17,7 +17,7 @@ class TestHistoryRecall(TestBase): mydir = TestBase.compute_mydir(__file__) - # If your test case doesn't stress debug info, the + # 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 @@ -35,7 +35,7 @@ def sample_test(self): result = lldb.SBCommandReturnObject() interp.HandleCommand("command history", result, True) interp.HandleCommand("platform list", result, True) - + interp.HandleCommand("!0", result, False) self.assertTrue(result.Succeeded(), "!0 command did not work: %s"%(result.GetError())) self.assertTrue("command history" in result.GetOutput(), "!0 didn't rerun command history") diff --git a/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py b/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py index 6302112d2fe9..ab5791c614af 100644 --- a/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py +++ b/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py @@ -20,7 +20,7 @@ class LoadUnloadTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) NO_DEBUG_INFO_TESTCASE = True - + def setUp(self): # Call super's setUp(). TestBase.setUp(self) @@ -210,7 +210,7 @@ def test_dyld_library_path(self): if not self.platformIsDarwin(): env_cmd_string += ":" + wd self.runCmd(env_cmd_string) - + # This time, the hidden library should be picked up. self.expect("run", substrs=["return", "12345"]) diff --git a/packages/Python/lldbsuite/test/functionalities/load_using_paths/TestLoadUsingPaths.py b/packages/Python/lldbsuite/test/functionalities/load_using_paths/TestLoadUsingPaths.py index 2050586adfa1..a4d0a0b958d5 100644 --- a/packages/Python/lldbsuite/test/functionalities/load_using_paths/TestLoadUsingPaths.py +++ b/packages/Python/lldbsuite/test/functionalities/load_using_paths/TestLoadUsingPaths.py @@ -20,7 +20,7 @@ class LoadUsingPathsTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) NO_DEBUG_INFO_TESTCASE = True - + def setUp(self): # Call super's setUp(). TestBase.setUp(self) @@ -52,8 +52,8 @@ def test_load_using_paths(self): # The directory with the dynamic library we did not link to. path_dir = os.path.join(self.getBuildDir(), "hidden") - (target, process, thread, - _) = lldbutil.run_to_source_breakpoint(self, + (target, process, thread, + _) = lldbutil.run_to_source_breakpoint(self, "Break here to do the load using paths", lldb.SBFileSpec("main.cpp")) error = lldb.SBError() @@ -63,18 +63,18 @@ def test_load_using_paths(self): paths.AppendString(os.path.join(self.wd, "no_such_dir")) out_spec = lldb.SBFileSpec() - + # First try with no correct directories on the path, and make sure that doesn't blow up: token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error) self.assertEqual(token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Only looked on the provided path.") - + # Now add the correct dir to the paths list and try again: paths.AppendString(self.hidden_dir) token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error) self.assertNotEqual(token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Got a valid token") self.assertEqual(out_spec, lldb.SBFileSpec(self.hidden_lib), "Found the expected library") - + # Make sure this really is in the image list: loaded_module = target.FindModule(out_spec) @@ -89,11 +89,11 @@ def test_load_using_paths(self): # Make sure the token works to unload it: process.UnloadImage(token) - # Make sure this really is no longer in the image list: + # Make sure this really is no longer in the image list: loaded_module = target.FindModule(out_spec) self.assertFalse(loaded_module.IsValid(), "The unloaded module is no longer in the image list.") - + # Make sure a relative path also works: paths.Clear() paths.AppendString(os.path.join(self.wd, "no_such_dir")) @@ -107,7 +107,7 @@ def test_load_using_paths(self): self.assertEqual(out_spec, lldb.SBFileSpec(self.hidden_lib), "Found the expected library with relative path") process.UnloadImage(token) - + # Make sure the presence of an empty path doesn't mess anything up: paths.Clear() paths.AppendString("") @@ -122,7 +122,7 @@ def test_load_using_paths(self): self.assertEqual(out_spec, lldb.SBFileSpec(self.hidden_lib), "Found the expected library with included empty path") process.UnloadImage(token) - + # Finally, passing in an absolute path should work like the basename: @@ -140,4 +140,4 @@ def test_load_using_paths(self): self.assertNotEqual(token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Got a valid token") self.assertEqual(out_spec, lldb.SBFileSpec(self.hidden_lib), "Found the expected library") - + diff --git a/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/TestPreRunDylibs.py b/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/TestPreRunDylibs.py index befb42186112..65084211cd6d 100644 --- a/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/TestPreRunDylibs.py +++ b/packages/Python/lldbsuite/test/functionalities/pre_run_dylibs/TestPreRunDylibs.py @@ -35,4 +35,4 @@ def test(self): self.assertTrue(found_it, "Couldn't find unlikely_to_occur_name in loaded libraries.") - + diff --git a/packages/Python/lldbsuite/test/functionalities/register/intel_avx/TestZMMRegister.py b/packages/Python/lldbsuite/test/functionalities/register/intel_avx/TestZMMRegister.py index 823e40155ff5..92c67c88f020 100644 --- a/packages/Python/lldbsuite/test/functionalities/register/intel_avx/TestZMMRegister.py +++ b/packages/Python/lldbsuite/test/functionalities/register/intel_avx/TestZMMRegister.py @@ -81,7 +81,7 @@ def test(self): self.expect( "register read ymm" + str(i), substrs=[pattern]) - + self.expect("continue", PROCESS_STOPPED, substrs=['stopped']) # Check stop reason; Should be either signal SIGTRAP or EXC_BREAKPOINT diff --git a/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py b/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py index b7d0d8170b3b..929bd4a73511 100644 --- a/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py +++ b/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py @@ -68,7 +68,7 @@ def test_with_python(self): # Run again and we will stop in inner_sint the second time outer_sint is called. # Then test stepping out two frames at once: - + thread_list = lldbutil.continue_to_breakpoint(self.process, inner_sint_bkpt) self.assertTrue(len(thread_list) == 1) thread = thread_list[0] diff --git a/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py b/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py index 3998db6d3256..9e30ba3e1345 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/create_during_step/TestCreateDuringStep.py @@ -90,7 +90,7 @@ def create_during_step_base(self, step_cmd, step_stop_reason): target = self.dbg.GetSelectedTarget() # This should create a breakpoint in the stepping thread. - self.bkpt = target.BreakpointCreateByLocation("main.cpp", self.breakpoint) + self.bkpt = target.BreakpointCreateByLocation("main.cpp", self.breakpoint) # Run the program. self.runCmd("run", RUN_SUCCEEDED) diff --git a/packages/Python/lldbsuite/test/functionalities/thread/num_threads/TestNumThreads.py b/packages/Python/lldbsuite/test/functionalities/thread/num_threads/TestNumThreads.py index 4c4e645635c1..724b9d8be907 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/num_threads/TestNumThreads.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/num_threads/TestNumThreads.py @@ -92,7 +92,7 @@ def test_unique_stacks(self): self.assertTrue( num_threads >= 10, 'Number of expected threads and actual threads do not match.') - + # Attempt to walk each of the thread's executing the thread3 function to # the same breakpoint. def is_thread3(thread): diff --git a/packages/Python/lldbsuite/test/functionalities/thread/step_until/TestStepUntil.py b/packages/Python/lldbsuite/test/functionalities/thread/step_until/TestStepUntil.py index 3bace5780639..b0e7add37297 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/step_until/TestStepUntil.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/step_until/TestStepUntil.py @@ -61,7 +61,7 @@ def do_until (self, args, until_lines, expected_linenum): cmd_line = "thread until" for line_num in until_lines: cmd_line += " %d"%(line_num) - + cmd_interp.HandleCommand(cmd_line, ret_obj) self.assertTrue(ret_obj.Succeeded(), "'%s' failed: %s."%(cmd_line, ret_obj.GetError())) diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/multi_watchpoint_slots/TestWatchpointMultipleSlots.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/multi_watchpoint_slots/TestWatchpointMultipleSlots.py index b51cab38aa86..22dc19ed322f 100644 --- a/packages/Python/lldbsuite/test/functionalities/watchpoint/multi_watchpoint_slots/TestWatchpointMultipleSlots.py +++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/multi_watchpoint_slots/TestWatchpointMultipleSlots.py @@ -85,7 +85,7 @@ def test_multiple_watchpoints_on_same_word(self): # Set a watchpoint at byteArray[3] self.expect("watchpoint set variable byteArray[3]", WATCHPOINT_CREATED, substrs=['Watchpoint created','size = 1']) - + # Resume inferior. self.runCmd("process continue") @@ -98,6 +98,6 @@ def test_multiple_watchpoints_on_same_word(self): else: self.expect("thread list -v", STOPPED_DUE_TO_WATCHPOINT, substrs=['stopped', 'stop reason = watchpoint 3']) - + # Resume inferior. self.runCmd("process continue") diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_disable/TestWatchpointDisable.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_disable/TestWatchpointDisable.py index 587dcabb2ba3..ea4f06218a0d 100644 --- a/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_disable/TestWatchpointDisable.py +++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_disable/TestWatchpointDisable.py @@ -65,9 +65,9 @@ def do_test(self, test_enable): wp.SetEnabled(False) self.assertTrue(not wp.IsEnabled(), "The watchpoint thinks it is still enabled") - + process.Continue() - + stop_reason = thread.GetStopReason() self.assertEqual(stop_reason, lldb.eStopReasonBreakpoint, "We didn't stop at our breakpoint.") @@ -78,4 +78,4 @@ def do_test(self, test_enable): process.Continue() stop_reason = thread.GetStopReason() self.assertEqual(stop_reason, lldb.eStopReasonWatchpoint, "We didn't stop at our watchpoint") - + diff --git a/packages/Python/lldbsuite/test/lang/c/find_struct_type/TestFindStructTypes.py b/packages/Python/lldbsuite/test/lang/c/find_struct_type/TestFindStructTypes.py index 75aef291cc49..6827fb4af0e6 100644 --- a/packages/Python/lldbsuite/test/lang/c/find_struct_type/TestFindStructTypes.py +++ b/packages/Python/lldbsuite/test/lang/c/find_struct_type/TestFindStructTypes.py @@ -17,7 +17,7 @@ class TestFindTypesOnStructType(TestBase): mydir = TestBase.compute_mydir(__file__) - # If your test case doesn't stress debug info, the + # 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 diff --git a/packages/Python/lldbsuite/test/lang/cpp/dynamic-value-same-basename/TestDynamicValueSameBase.py b/packages/Python/lldbsuite/test/lang/cpp/dynamic-value-same-basename/TestDynamicValueSameBase.py index 358b3b2d93ae..c0afb3cf4919 100644 --- a/packages/Python/lldbsuite/test/lang/cpp/dynamic-value-same-basename/TestDynamicValueSameBase.py +++ b/packages/Python/lldbsuite/test/lang/cpp/dynamic-value-same-basename/TestDynamicValueSameBase.py @@ -18,7 +18,7 @@ class DynamicValueSameBaseTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) - # If your test case doesn't stress debug info, the + # 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 @@ -35,7 +35,7 @@ def setUp(self): def sample_test(self): (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, - "Break here to get started", self.main_source_file) + "Break here to get started", self.main_source_file) # Set breakpoints in the two class methods and run to them: namesp_bkpt = target.BreakpointCreateBySourceRegex("namesp function did something.", self.main_source_file) @@ -62,5 +62,5 @@ def sample_test(self): virtual_type = virtual_this.GetType().GetUnqualifiedType() self.assertEqual(virtual_type.GetName(), "Virtual *", "Didn't get the right dynamic type") - + diff --git a/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py b/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py index 92b58ce11d77..7ce2e343b88f 100644 --- a/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py +++ b/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py @@ -49,7 +49,7 @@ def get_test_frame(self, exe): src_file = "main.cpp" src_file_spec = lldb.SBFileSpec(src_file) - (target, process, thread, main_breakpoint) = lldbutil.run_to_source_breakpoint(self, + (target, process, thread, main_breakpoint) = lldbutil.run_to_source_breakpoint(self, "break here", src_file_spec, exe_name = exe) # Get frame for current thread return thread.GetSelectedFrame() diff --git a/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py b/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py index 8e83a3ab1a4a..af362f5be5d7 100644 --- a/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py +++ b/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py @@ -4,4 +4,4 @@ lldbinline.MakeInlineTest( __file__, globals(), [ decorators.expectedFailureAll( - oslist=["windows"], bugnumber="llvm.org/pr24764")]) \ No newline at end of file + oslist=["windows"], bugnumber="llvm.org/pr24764")]) diff --git a/packages/Python/lldbsuite/test/lang/cpp/scope/TestCppScope.py b/packages/Python/lldbsuite/test/lang/cpp/scope/TestCppScope.py index 5cd9e4ed1b4f..c7afeb2dbb6f 100644 --- a/packages/Python/lldbsuite/test/lang/cpp/scope/TestCppScope.py +++ b/packages/Python/lldbsuite/test/lang/cpp/scope/TestCppScope.py @@ -18,7 +18,7 @@ def test_all_but_c(self): @expectedFailureAll(oslist=["windows"]) def test_c(self): self.do_test(True) - + def do_test(self, test_c): self.build() diff --git a/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/TestTrivialABI.py b/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/TestTrivialABI.py index 2aae7dc89d34..11263abeea3c 100644 --- a/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/TestTrivialABI.py +++ b/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/TestTrivialABI.py @@ -53,14 +53,14 @@ def check_frame(self, thread): options = lldb.SBExpressionOptions() inVal_expr = frame.EvaluateExpression("inVal", options) self.check_value(inVal_expr, 10) - + thread.StepOut() outVal_ret = thread.GetStopReturnValue() self.check_value(outVal_ret, 30) def expr_test(self, trivial): (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, - "Set a breakpoint here", self.main_source_file) + "Set a breakpoint here", self.main_source_file) # Stop in a function that takes a trivial value, and try both frame var & expr to get its value: if trivial: diff --git a/packages/Python/lldbsuite/test/lldbdwarf.py b/packages/Python/lldbsuite/test/lldbdwarf.py index 1b50eb130ab9..217f8bc0e2b7 100644 --- a/packages/Python/lldbsuite/test/lldbdwarf.py +++ b/packages/Python/lldbsuite/test/lldbdwarf.py @@ -191,7 +191,7 @@ def evaluateDwarfExpression(self, dwarf_opcode, byte_order): break if val == DW_OP_regx: - # Read register number + # Read register number self.assertTrue(len(dwarf_opcode) > (index + 1)) reg_no = int(dwarf_opcode.pop(index + 1), 16) @@ -201,7 +201,7 @@ def evaluateDwarfExpression(self, dwarf_opcode, byte_order): ["read packet: $p{0:x}#00".format(reg_no), {"direction": "send", "regex": r"^\$([0-9a-fA-F]+)#", "capture": {1: "p_response"}}],True) - + Context = self.expect_gdbremote_sequence() self.assertIsNotNone(Context) p_response = Context.get("p_response") @@ -219,7 +219,7 @@ def evaluateDwarfExpression(self, dwarf_opcode, byte_order): elif val == DW_OP_lit1: # Push literal 1 dwarf_data.append(1) - + elif val == DW_OP_lit26: # Push literal 26 dwarf_data.append(26) diff --git a/packages/Python/lldbsuite/test/lldbtest.py b/packages/Python/lldbsuite/test/lldbtest.py index d5dd90a86517..cdb227ea9f05 100644 --- a/packages/Python/lldbsuite/test/lldbtest.py +++ b/packages/Python/lldbsuite/test/lldbtest.py @@ -702,8 +702,8 @@ def getBuildDir(self): """Return the full path to the current test.""" return os.path.join(os.environ["LLDB_BUILD"], self.mydir, self.getBuildDirBasename()) - - + + def makeBuildDir(self): """Create the test-specific working directory, deleting any previous contents.""" @@ -712,11 +712,11 @@ def makeBuildDir(self): if os.path.isdir(bdir): shutil.rmtree(bdir) lldbutil.mkdir_p(bdir) - + def getBuildArtifact(self, name="a.out"): """Return absolute path to an artifact in the test's build directory.""" return os.path.join(self.getBuildDir(), name) - + def getSourcePath(self, name): """Return absolute path to a file in the test's source directory.""" return os.path.join(self.getSourceDir(), name) @@ -1844,7 +1844,7 @@ def generateSource(self, source): temp = os.path.join(self.getSourceDir(), template) with open(temp, 'r') as f: content = f.read() - + public_api_dir = os.path.join( os.environ["LLDB_SRC"], "include", "lldb", "API") diff --git a/packages/Python/lldbsuite/test/lldbutil.py b/packages/Python/lldbsuite/test/lldbutil.py index 90ac799f4897..dc84383333ee 100644 --- a/packages/Python/lldbsuite/test/lldbutil.py +++ b/packages/Python/lldbsuite/test/lldbutil.py @@ -740,7 +740,7 @@ def get_crashed_threads(test, process): def run_to_breakpoint_make_target(test, exe_name, in_cwd): if in_cwd: exe = test.getBuildArtifact(exe_name) - + # Create the target target = test.dbg.CreateTarget(exe) test.assertTrue(target, "Target: %s is not valid."%(exe_name)) @@ -756,8 +756,8 @@ def run_to_breakpoint_do_run(test, target, bkpt, launch_info): error = lldb.SBError() process = target.Launch(launch_info, error) - test.assertTrue(process, - "Could not create a valid process for %s: %s"%(target.GetExecutable().GetFilename(), + test.assertTrue(process, + "Could not create a valid process for %s: %s"%(target.GetExecutable().GetFilename(), error.GetCString())) # Frame #0 should be at our breakpoint. @@ -768,7 +768,7 @@ def run_to_breakpoint_do_run(test, target, bkpt, launch_info): thread = threads[0] return (target, process, thread, bkpt) -def run_to_name_breakpoint (test, bkpt_name, launch_info = None, +def run_to_name_breakpoint (test, bkpt_name, launch_info = None, exe_name = "a.out", bkpt_module = None, in_cwd = True): @@ -818,7 +818,7 @@ def run_to_source_breakpoint(test, bkpt_pattern, source_spec, # Set the breakpoints breakpoint = target.BreakpointCreateBySourceRegex( bkpt_pattern, source_spec, bkpt_module) - test.assertTrue(breakpoint.GetNumLocations() > 0, + test.assertTrue(breakpoint.GetNumLocations() > 0, 'No locations found for source breakpoint: "%s", file: "%s", dir: "%s"'%(bkpt_pattern, source_spec.GetFilename(), source_spec.GetDirectory())) return run_to_breakpoint_do_run(test, target, breakpoint, launch_info) diff --git a/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestFindAppInBundle.py b/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestFindAppInBundle.py index af6beeefd391..c380d5379962 100644 --- a/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestFindAppInBundle.py +++ b/packages/Python/lldbsuite/test/macosx/find-app-in-bundle/TestFindAppInBundle.py @@ -55,12 +55,12 @@ def find_app_in_bundle_test(self): error = lldb.SBError() process = target.Launch(launch_info, error) - + self.assertTrue(process.IsValid(), "Could not create a valid process for TestApp: %s"%(error.GetCString())) - + # Frame #0 should be at our breakpoint. threads = lldbutil.get_threads_stopped_at_breakpoint(process, bkpt) - + self.assertTrue(len(threads) == 1, "Expected 1 thread to stop at breakpoint, %d did."%(len(threads))) diff --git a/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/TestBundleWithDotInFilename.py b/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/TestBundleWithDotInFilename.py index 9a046cf0b294..ad90d85ab3f7 100644 --- a/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/TestBundleWithDotInFilename.py +++ b/packages/Python/lldbsuite/test/macosx/find-dsym/bundle-with-dot-in-filename/TestBundleWithDotInFilename.py @@ -47,7 +47,7 @@ def test_attach_and_check_dsyms(self): sleep(5) # Since the library that was dlopen()'ed is now removed, lldb will need to find the - # binary & dSYM via target.exec-search-paths + # binary & dSYM via target.exec-search-paths settings_str = "settings set target.exec-search-paths " + self.get_process_working_directory() + "/hide.app" self.runCmd(settings_str) diff --git a/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/TestDeepBundle.py b/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/TestDeepBundle.py index d6123e39c3fe..2ed7fdfd3fe4 100644 --- a/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/TestDeepBundle.py +++ b/packages/Python/lldbsuite/test/macosx/find-dsym/deep-bundle/TestDeepBundle.py @@ -46,7 +46,7 @@ def test_attach_and_check_dsyms(self): sleep(5) # Since the library that was dlopen()'ed is now removed, lldb will need to find the - # binary & dSYM via target.exec-search-paths + # binary & dSYM via target.exec-search-paths settings_str = "settings set target.exec-search-paths " + self.get_process_working_directory() + "/hide.app" self.runCmd(settings_str) self.runCmd("process attach -p " + str(popen.pid)) @@ -67,7 +67,7 @@ def test_attach_and_check_dsyms(self): dsym_name = mod.GetSymbolFileSpec().GetFilename() self.assertTrue (dsym_name == 'MyFramework', "Check that we found the dSYM for the bundle that was loaded") i=i+1 - + self.assertTrue(found_module, "Check that we found the framework loaded in lldb's image list") if __name__ == '__main__': diff --git a/packages/Python/lldbsuite/test/macosx/thread-names/TestInterruptThreadNames.py b/packages/Python/lldbsuite/test/macosx/thread-names/TestInterruptThreadNames.py index 925dc92951ce..515ab3f2bbd9 100644 --- a/packages/Python/lldbsuite/test/macosx/thread-names/TestInterruptThreadNames.py +++ b/packages/Python/lldbsuite/test/macosx/thread-names/TestInterruptThreadNames.py @@ -1,4 +1,4 @@ -"""Test that we get thread names when interrupting a process.""" +"""Test that we get thread names when interrupting a process.""" from __future__ import print_function @@ -63,7 +63,7 @@ def test_with_python_api(self): process.Kill() - # The process will set a global variable 'threads_up_and_running' to 1 when + # The process will set a global variable 'threads_up_and_running' to 1 when # it has has completed its setup. Sleep for one second, pause the program, # check to see if the global has that value, and continue if it does not. def wait_until_program_setup_complete(self, process, listener): @@ -107,7 +107,7 @@ def wait_for_running(self, process, listener): return False # Listen to the process events until we get an event saying the process is - # stopped. Retry up to five times in case we get other events that we are + # stopped. Retry up to five times in case we get other events that we are # not looking for. def wait_for_stop(self, process, listener): retry_count = 5 diff --git a/packages/Python/lldbsuite/test/python_api/name_lookup/TestNameLookup.py b/packages/Python/lldbsuite/test/python_api/name_lookup/TestNameLookup.py index 6511ff865bd9..ba68ca926d83 100644 --- a/packages/Python/lldbsuite/test/python_api/name_lookup/TestNameLookup.py +++ b/packages/Python/lldbsuite/test/python_api/name_lookup/TestNameLookup.py @@ -23,7 +23,7 @@ class TestNameLookup(TestBase): @expectedFailureAll(oslist=["windows"], bugnumber='llvm.org/pr21765') def test_target(self): """Exercise SBTarget.FindFunctions() with various name masks. - + A previous regression caused mangled names to not be able to be looked up. This test verifies that using a mangled name with eFunctionNameTypeFull works and that using a function basename with eFunctionNameTypeFull works for all @@ -36,7 +36,7 @@ def test_target(self): self.assertTrue(target, VALID_TARGET) exe_module = target.FindModule(target.GetExecutable()) - + c_name_to_symbol = {} cpp_name_to_symbol = {} mangled_to_symbol = {} @@ -54,7 +54,7 @@ def test_target(self): c_name_to_symbol[name] = symbol # Make sure each mangled name turns up exactly one match when looking up - # functions by full name and using the mangled name as the name in the + # functions by full name and using the mangled name as the name in the # lookup self.assertGreaterEqual(len(mangled_to_symbol), 6) for mangled in mangled_to_symbol.keys(): @@ -63,5 +63,5 @@ def test_target(self): for symbol_context in symbol_contexts: self.assertTrue(symbol_context.GetFunction().IsValid()) self.assertTrue(symbol_context.GetSymbol().IsValid()) - - + + diff --git a/packages/Python/lldbsuite/test/python_api/sbdata/TestSBData.py b/packages/Python/lldbsuite/test/python_api/sbdata/TestSBData.py index a1a400a076b5..6bdf9a2036ef 100644 --- a/packages/Python/lldbsuite/test/python_api/sbdata/TestSBData.py +++ b/packages/Python/lldbsuite/test/python_api/sbdata/TestSBData.py @@ -23,7 +23,7 @@ def setUp(self): @add_test_categories(['pyapi']) def test_byte_order_and_address_byte_size(self): - """Test the SBData::SetData() to ensure the byte order and address + """Test the SBData::SetData() to ensure the byte order and address byte size are obeyed""" addr_data = b'\x11\x22\x33\x44\x55\x66\x77\x88' error = lldb.SBError() diff --git a/packages/Python/lldbsuite/test/sample_test/TestSampleTest.py b/packages/Python/lldbsuite/test/sample_test/TestSampleTest.py index 9a1748bbabb5..97674f5336a9 100644 --- a/packages/Python/lldbsuite/test/sample_test/TestSampleTest.py +++ b/packages/Python/lldbsuite/test/sample_test/TestSampleTest.py @@ -17,7 +17,7 @@ class RenameThisSampleTestTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) - # If your test case doesn't stress debug info, the + # 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 @@ -40,7 +40,7 @@ def sample_test(self): # It optionally takes an SBLaunchOption argument if you want to pass # arguments or environment variables. (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, - "Set a breakpoint here", self.main_source_file) + "Set a breakpoint here", self.main_source_file) frame = thread.GetFrameAtIndex(0) test_var = frame.FindVariable("test_var") diff --git a/packages/Python/lldbsuite/test/settings/TestSettings.py b/packages/Python/lldbsuite/test/settings/TestSettings.py index 6b8ac7c3d5d5..d6fa5a93b72c 100644 --- a/packages/Python/lldbsuite/test/settings/TestSettings.py +++ b/packages/Python/lldbsuite/test/settings/TestSettings.py @@ -528,7 +528,7 @@ def test_all_settings_exist(self): # settings under an ".experimental" domain should have two properties: # 1. If the name does not exist with "experimental" in the name path, # the name lookup should try to find it without "experimental". So - # a previously-experimental setting that has been promoted to a + # a previously-experimental setting that has been promoted to a # "real" setting will still be set by the original name. # 2. Changing a setting with .experimental., name, where the setting # does not exist either with ".experimental." or without, should diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py b/packages/Python/lldbsuite/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py index 7c225ab87a3c..467952db7eba 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py +++ b/packages/Python/lldbsuite/test/tools/lldb-mi/startup_options/TestMiStartupOptions.py @@ -139,7 +139,7 @@ def copyScript(self, sourceFile): with open(destFile, 'w+') as dest: dest.write(src.read().replace("a.out", self.myexe)) return destFile - + @skipIfRemote # We do not currently support remote debugging via the MI. @skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_qThreadStopInfo.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_qThreadStopInfo.py index 647e57832b05..a25484e73baf 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_qThreadStopInfo.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemote_qThreadStopInfo.py @@ -16,7 +16,7 @@ class TestGdbRemote_qThreadStopInfo(gdbremote_testcase.GdbRemoteTestCaseBase): THREAD_COUNT = 5 @skipIfDarwinEmbedded # lldb-server tests not updated to work on ios etc yet - @skipIfDarwinEmbedded # + @skipIfDarwinEmbedded # def gather_stop_replies_via_qThreadStopInfo(self, thread_count): # Set up the inferior args. inferior_args = [] diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py index 82e76ca125bb..f5169e7e2029 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py @@ -1162,7 +1162,7 @@ def breakpoint_set_and_remove_work(self, want_hardware=False): BREAKPOINT_KIND = 1 # Set default packet type to Z0 (software breakpoint) - z_packet_type = 0 + z_packet_type = 0 # If hardware breakpoint is requested set packet type to Z1 if want_hardware == True: From 35c34441c13e07443ea75f6919a082faa10c94db Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Fri, 27 Jul 2018 23:37:08 +0000 Subject: [PATCH 0018/1112] Add missing boundary checks to variable completion. Summary: Stopgap patch to at least stop all the crashes I get from this code. Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D49949 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338177 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../completion/TestCompletion.py | 40 +++++++++++++++++++ .../test/functionalities/completion/main.cpp | 11 ++++- source/Symbol/Variable.cpp | 7 ++-- 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py b/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py index 4f6a073a44c5..2366d9007e79 100644 --- a/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py +++ b/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py @@ -38,6 +38,46 @@ def test_de(self): """Test that 'de' completes to 'detach '.""" self.complete_from_to('de', 'detach ') + @skipIfFreeBSD # timing out on the FreeBSD buildbot + def test_frame_variable(self): + self.build() + self.main_source = "main.cpp" + self.main_source_spec = lldb.SBFileSpec(self.main_source) + self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + '// Break here', self.main_source_spec) + self.assertEquals(process.GetState(), lldb.eStateStopped) + # FIXME: This pulls in the debug information to make the completions work, + # but the completions should also work without. + self.runCmd("frame variable fooo") + + self.complete_from_to('frame variable fo', + 'frame variable fooo') + self.complete_from_to('frame variable fooo.', + 'frame variable fooo.') + self.complete_from_to('frame variable fooo.dd', + 'frame variable fooo.dd') + + self.complete_from_to('frame variable ptr_fooo->', + 'frame variable ptr_fooo->') + self.complete_from_to('frame variable ptr_fooo->dd', + 'frame variable ptr_fooo->dd') + + self.complete_from_to('frame variable cont', + 'frame variable container') + self.complete_from_to('frame variable container.', + 'frame variable container.MemberVar') + self.complete_from_to('frame variable container.Mem', + 'frame variable container.MemberVar') + + self.complete_from_to('frame variable ptr_cont', + 'frame variable ptr_container') + self.complete_from_to('frame variable ptr_container->', + 'frame variable ptr_container->MemberVar') + self.complete_from_to('frame variable ptr_container->Mem', + 'frame variable ptr_container->MemberVar') + @skipIfFreeBSD # timing out on the FreeBSD buildbot def test_process_attach_dash_dash_con(self): """Test that 'process attach --con' completes to 'process attach --continue '.""" diff --git a/packages/Python/lldbsuite/test/functionalities/completion/main.cpp b/packages/Python/lldbsuite/test/functionalities/completion/main.cpp index b408720d2cdc..0814bb9cc0ac 100644 --- a/packages/Python/lldbsuite/test/functionalities/completion/main.cpp +++ b/packages/Python/lldbsuite/test/functionalities/completion/main.cpp @@ -7,8 +7,15 @@ class Foo } }; +struct Container { int MemberVar; }; + int main() { - Foo f; - f.Bar(1, 2); + Foo fooo; + Foo *ptr_fooo = &fooo; + fooo.Bar(1, 2); + + Container container; + Container *ptr_container = &container; + return container.MemberVar = 3; // Break here } diff --git a/source/Symbol/Variable.cpp b/source/Symbol/Variable.cpp index 8e9cadc0a5d7..af84872a97a0 100644 --- a/source/Symbol/Variable.cpp +++ b/source/Symbol/Variable.cpp @@ -644,11 +644,12 @@ static void PrivateAutoComplete( break; case '-': - if (partial_path[1] == '>' && !prefix_path.str().empty()) { + if (partial_path.size() > 1 && partial_path[1] == '>' && + !prefix_path.str().empty()) { switch (type_class) { case lldb::eTypeClassPointer: { CompilerType pointee_type(compiler_type.GetPointeeType()); - if (partial_path[2]) { + if (partial_path.size() > 2 && partial_path[2]) { // If there is more after the "->", then search deeper PrivateAutoComplete( frame, partial_path.substr(2), prefix_path + "->", @@ -672,7 +673,7 @@ static void PrivateAutoComplete( case lldb::eTypeClassUnion: case lldb::eTypeClassStruct: case lldb::eTypeClassClass: - if (partial_path[1]) { + if (partial_path.size() > 1 && partial_path[1]) { // If there is more after the ".", then search deeper PrivateAutoComplete(frame, partial_path.substr(1), prefix_path + ".", compiler_type, matches, From a70d891b584df5781cce7a35d570d08e95de6997 Mon Sep 17 00:00:00 2001 From: Alex Langford Date: Fri, 27 Jul 2018 23:38:58 +0000 Subject: [PATCH 0019/1112] Revert "Stop building liblldb with CMake's framework functionality" This reverts r338154. This change is actually unnecessary, as the CMake bug I referred to was actually not a bug but a misunderstanding of CMake. Original Differential Revision: https://reviews.llvm.org/D49888 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338178 91177308-0d34-0410-b5e6-96231b3b80d8 --- CMakeLists.txt | 16 ++++++++----- cmake/modules/AddLLDB.cmake | 6 ++--- cmake/modules/LLDBConfig.cmake | 4 +--- cmake/modules/LLDBFramework.cmake | 38 ++++++++++--------------------- scripts/CMakeLists.txt | 6 ++--- source/API/CMakeLists.txt | 23 ++++++++----------- 6 files changed, 38 insertions(+), 55 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96868154908d..00ddcdc1488f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,16 +51,15 @@ if(LLDB_BUILD_FRAMEWORK) message(FATAL_ERROR "LLDB.framework can only be generated when targeting Apple platforms") endif() - add_custom_target(lldb-framework) - set(LLDB_SUITE_TARGET lldb-framework) - set(LLDB_FRAMEWORK_DIR - ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${LLDB_FRAMEWORK_INSTALL_DIR}/LLDB.framework) # These are used to fill out LLDB-Info.plist. These are relevant when building # the framework, and must be defined before building liblldb. set(PRODUCT_NAME "LLDB") set(EXECUTABLE_NAME "LLDB") set(CURRENT_PROJECT_VERSION "360.99.0") - include(LLDBFramework) + set(LLDB_SUITE_TARGET lldb-framework) + + set(LLDB_FRAMEWORK_DIR + ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${LLDB_FRAMEWORK_INSTALL_DIR}) endif() add_subdirectory(docs) @@ -72,7 +71,7 @@ if (NOT LLDB_DISABLE_PYTHON) set(LLDB_PYTHON_TARGET_DIR ${LLDB_BINARY_DIR}/scripts) set(LLDB_WRAP_PYTHON ${LLDB_BINARY_DIR}/scripts/LLDBWrapPython.cpp) if(LLDB_BUILD_FRAMEWORK) - set(LLDB_PYTHON_TARGET_DIR "${LLDB_FRAMEWORK_DIR}/..") + set(LLDB_PYTHON_TARGET_DIR ${LLDB_FRAMEWORK_DIR}) set(LLDB_WRAP_PYTHON ${LLDB_PYTHON_TARGET_DIR}/LLDBWrapPython.cpp) else() # Don't set -m when building the framework. @@ -163,6 +162,11 @@ if(LLDB_INCLUDE_TESTS) add_subdirectory(utils/lldb-dotest) endif() +if (LLDB_BUILD_FRAMEWORK) + add_custom_target(lldb-framework) + include(LLDBFramework) +endif() + if (NOT LLDB_DISABLE_PYTHON) # Add a Post-Build Event to copy over Python files and create the symlink # to liblldb.so for the Python API(hardlink on Windows) diff --git a/cmake/modules/AddLLDB.cmake b/cmake/modules/AddLLDB.cmake index eb2dcbfa9448..129a5ef7500d 100644 --- a/cmake/modules/AddLLDB.cmake +++ b/cmake/modules/AddLLDB.cmake @@ -52,7 +52,7 @@ function(add_lldb_library name) if (PARAM_SHARED) set(out_dir lib${LLVM_LIBDIR_SUFFIX}) if(${name} STREQUAL "liblldb" AND LLDB_BUILD_FRAMEWORK) - set(out_dir ${LLDB_FRAMEWORK_INSTALL_DIR}/LLDB.framework/Versions/${LLDB_FRAMEWORK_VERSION}) + set(out_dir ${LLDB_FRAMEWORK_INSTALL_DIR}) endif() install(TARGETS ${name} COMPONENT ${name} @@ -108,7 +108,7 @@ function(add_lldb_executable name) endif() string(REGEX REPLACE "[^/]+" ".." _dots ${LLDB_FRAMEWORK_INSTALL_DIR}) set_target_properties(${name} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${LLDB_FRAMEWORK_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR} + RUNTIME_OUTPUT_DIRECTORY $${resource_dir} BUILD_WITH_INSTALL_RPATH On INSTALL_RPATH "@loader_path/../../../${resource_dots}${_dots}/${LLDB_FRAMEWORK_INSTALL_DIR}") endif() @@ -123,7 +123,7 @@ function(add_lldb_executable name) if(ARG_GENERATE_INSTALL) set(out_dir "bin") if (LLDB_BUILD_FRAMEWORK AND ARG_INCLUDE_IN_SUITE) - set(out_dir ${LLDB_FRAMEWORK_INSTALL_DIR}/LLDB.framework/${LLDB_FRAMEWORK_RESOURCE_DIR}) + set(out_dir ${LLDB_FRAMEWORK_INSTALL_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}) endif() install(TARGETS ${name} COMPONENT ${name} diff --git a/cmake/modules/LLDBConfig.cmake b/cmake/modules/LLDBConfig.cmake index b454b3361fb3..dae6e365da38 100644 --- a/cmake/modules/LLDBConfig.cmake +++ b/cmake/modules/LLDBConfig.cmake @@ -326,9 +326,7 @@ if (APPLE) set(LLDB_FRAMEWORK_INSTALL_DIR Library/Frameworks CACHE STRING "Output directory for LLDB.framework") set(LLDB_FRAMEWORK_VERSION A CACHE STRING "LLDB.framework version (default is A)") set(LLDB_FRAMEWORK_RESOURCE_DIR - Versions/${LLDB_FRAMEWORK_VERSION}/Resources) - set(LLDB_FRAMEWORK_HEADER_DIR - Versions/${LLDB_FRAMEWORK_VERSION}/Headers) + LLDB.framework/Versions/${LLDB_FRAMEWORK_VERSION}/Resources) add_definitions( -DLIBXML2_DEFINED ) list(APPEND system_libs xml2 diff --git a/cmake/modules/LLDBFramework.cmake b/cmake/modules/LLDBFramework.cmake index 4bf85813c924..abacee89d9ac 100644 --- a/cmake/modules/LLDBFramework.cmake +++ b/cmake/modules/LLDBFramework.cmake @@ -1,16 +1,3 @@ -# We intentionally do not use CMake's framework support because of a bug in -# CMake. See: https://gitlab.kitware.com/cmake/cmake/issues/18216 - -# We set up part of the framework structure first, as some scripts and build -# rules assume they exist already. -file(MAKE_DIRECTORY ${LLDB_FRAMEWORK_DIR} ${LLDB_FRAMEWORK_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}) -execute_process( - COMMAND - ${CMAKE_COMMAND} -E create_symlink ${LLDB_FRAMEWORK_VERSION} ${LLDB_FRAMEWORK_DIR}/Versions/Current - COMMAND - ${CMAKE_COMMAND} -E create_symlink Versions/Current/Resources ${LLDB_FRAMEWORK_DIR}/Resources -) - file(GLOB public_headers ${LLDB_SOURCE_DIR}/include/lldb/API/*.h) file(GLOB root_public_headers ${LLDB_SOURCE_DIR}/include/lldb/lldb-*.h) file(GLOB root_private_headers ${LLDB_SOURCE_DIR}/include/lldb/lldb-private*.h) @@ -29,8 +16,8 @@ endforeach() add_custom_target(lldb-framework-headers DEPENDS ${framework_headers}) add_custom_command(TARGET lldb-framework POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders ${LLDB_FRAMEWORK_DIR}/${LLDB_FRAMEWORK_HEADER_DIR} - COMMAND ${LLDB_SOURCE_DIR}/scripts/framework-header-fix.sh ${LLDB_FRAMEWORK_DIR}/${LLDB_FRAMEWORK_HEADER_DIR} ${LLDB_VERSION} + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders $/Headers + COMMAND ${LLDB_SOURCE_DIR}/scripts/framework-header-fix.sh $/Headers ${LLDB_VERSION} ) if (NOT IOS) @@ -38,20 +25,19 @@ if (NOT IOS) add_dependencies(lldb-framework clang-headers) endif() add_custom_command(TARGET lldb-framework POST_BUILD - COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Headers ${LLDB_FRAMEWORK_DIR}/Headers - COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/LLDB ${LLDB_FRAMEWORK_DIR}/LLDB - COMMAND ${CMAKE_COMMAND} -E create_symlink ${LLDB_FRAMEWORK_VERSION} ${LLDB_FRAMEWORK_DIR}/Versions/Current - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/clang/${LLDB_VERSION} ${LLDB_FRAMEWORK_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}/Clang + COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Headers ${LLDB_FRAMEWORK_DIR}/LLDB.framework/Headers + COMMAND ${CMAKE_COMMAND} -E create_symlink ${LLDB_FRAMEWORK_VERSION} ${LLDB_FRAMEWORK_DIR}/LLDB.framework/Versions/Current + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/clang/${LLDB_VERSION} $/Resources/Clang ) endif() -# These are used to fill out LLDB-Info.plist. These are relevant when building -# the framework, and must be defined before configuring Info.plist. -set(PRODUCT_NAME "LLDB") -set(EXECUTABLE_NAME "LLDB") -set(CURRENT_PROJECT_VERSION "360.99.0") -configure_file(${LLDB_SOURCE_DIR}/resources/LLDB-Info.plist - ${LLDB_FRAMEWORK_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}/Info.plist) +set_target_properties(liblldb PROPERTIES + OUTPUT_NAME LLDB + FRAMEWORK On + FRAMEWORK_VERSION ${LLDB_FRAMEWORK_VERSION} + MACOSX_FRAMEWORK_INFO_PLIST ${LLDB_SOURCE_DIR}/resources/LLDB-Info.plist + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LLDB_FRAMEWORK_INSTALL_DIR} + PUBLIC_HEADER "${framework_headers}") add_dependencies(lldb-framework lldb-framework-headers diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index c8e0c981281d..be5c3db53556 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -25,9 +25,9 @@ set(SWIG_INSTALL_DIR lib${LLVM_LIBDIR_SUFFIX}) if(LLDB_BUILD_FRAMEWORK) set(framework_arg --framework --target-platform Darwin) set(SWIG_PYTHON_DIR - ${LLDB_FRAMEWORK_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}/Python) + ${LLDB_PYTHON_TARGET_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}/Python) set(SWIG_INSTALL_DIR - ${LLDB_FRAMEWORK_INSTALL_DIR}/LLDB.framework/${LLDB_FRAMEWORK_RESOURCE_DIR}) + ${LLDB_FRAMEWORK_INSTALL_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}) endif() get_filename_component(CFGBLDDIR ${LLDB_WRAP_PYTHON} DIRECTORY) @@ -52,7 +52,7 @@ add_custom_command( COMMENT "Python script building LLDB Python wrapper") add_custom_target(swig_wrapper ALL DEPENDS ${LLDB_WRAP_PYTHON}) -set_source_files_properties(${LLDB_PYTHON_TARGET_DIR}/lldb.py PROPERTIES GENERATED 1) +set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/lldb.py PROPERTIES GENERATED 1) # Install the LLDB python module diff --git a/source/API/CMakeLists.txt b/source/API/CMakeLists.txt index 4032332ad08c..be9d4115cecc 100644 --- a/source/API/CMakeLists.txt +++ b/source/API/CMakeLists.txt @@ -110,20 +110,10 @@ if (LLVM_COMPILER_IS_GCC_COMPATIBLE AND PROPERTY COMPILE_FLAGS " -Wno-sequence-point -Wno-cast-qual") endif () -if (LLDB_BUILD_FRAMEWORK) - set_target_properties(liblldb - PROPERTIES - LIBRARY_OUTPUT_DIRECTORY ${LLDB_FRAMEWORK_DIR}/Versions/${LLDB_FRAMEWORK_VERSION} - PREFIX "" - SUFFIX "" - INSTALL_NAME_DIR "@rpath/LLDB.framework" - OUTPUT_NAME LLDB) -else() - set_target_properties(liblldb - PROPERTIES - VERSION ${LLDB_VERSION} - OUTPUT_NAME lldb) -endif() +set_target_properties(liblldb + PROPERTIES + VERSION ${LLDB_VERSION} +) if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows") if (NOT LLDB_EXPORT_ALL_SYMBOLS) @@ -146,6 +136,11 @@ if ( CMAKE_SYSTEM_NAME MATCHES "Windows" ) if (MSVC AND NOT LLDB_DISABLE_PYTHON) target_link_libraries(liblldb PRIVATE ${PYTHON_LIBRARY}) endif() +else() + set_target_properties(liblldb + PROPERTIES + OUTPUT_NAME lldb + ) endif() if (LLDB_WRAP_PYTHON) From 98295ab3683e164466054357e988184508237b9a Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Fri, 27 Jul 2018 23:42:34 +0000 Subject: [PATCH 0020/1112] Add the actually calculated completions to COMPLETION_MSG Summary: Otherwise this assertion message is not very useful to whoever is reading the log. Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D49947 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338179 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../test/functionalities/completion/TestCompletion.py | 4 ++-- packages/Python/lldbsuite/test/lldbtest.py | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py b/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py index 2366d9007e79..5d4fcf64511b 100644 --- a/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py +++ b/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py @@ -313,8 +313,8 @@ def complete_from_to(self, str_input, patterns, turn_off_re_match=False): if turn_off_re_match: self.expect( compare_string, msg=COMPLETION_MSG( - str_input, p), exe=False, substrs=[p]) + str_input, p, match_strings), exe=False, substrs=[p]) else: self.expect( compare_string, msg=COMPLETION_MSG( - str_input, p), exe=False, patterns=[p]) + str_input, p, match_strings), exe=False, patterns=[p]) diff --git a/packages/Python/lldbsuite/test/lldbtest.py b/packages/Python/lldbsuite/test/lldbtest.py index cdb227ea9f05..1b6302ae96a6 100644 --- a/packages/Python/lldbsuite/test/lldbtest.py +++ b/packages/Python/lldbsuite/test/lldbtest.py @@ -184,9 +184,10 @@ def CMD_MSG(str): return "Command '%s' returns successfully" % str -def COMPLETION_MSG(str_before, str_after): +def COMPLETION_MSG(str_before, str_after, completions): '''A generic message generator for the completion mechanism.''' - return "'%s' successfully completes to '%s'" % (str_before, str_after) + return ("'%s' successfully completes to '%s', but completions were:\n%s" + % (str_before, str_after, "\n".join(completions))) def EXP_MSG(str, actual, exe): From eb47ece810b45ae3389856cd96a543a4e20f7bb0 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Sun, 29 Jul 2018 19:32:36 +0000 Subject: [PATCH 0021/1112] Remove friend class declarations from DWARFUnit and DWARFCompileUnit They are no longer needed since D45170. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338224 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h | 2 -- source/Plugins/SymbolFile/DWARF/DWARFUnit.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h index 9c1fc82f58b7..d20f31505ed4 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -13,8 +13,6 @@ #include "DWARFUnit.h" class DWARFCompileUnit : public DWARFUnit { - friend class DWARFUnit; - public: static DWARFUnitSP Extract(SymbolFileDWARF *dwarf2Data, const lldb_private::DWARFDataExtractor &debug_info, diff --git a/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index c9e48c538bc1..3cc24d4202b8 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -33,8 +33,6 @@ enum DWARFProducer { }; class DWARFUnit { - friend class DWARFCompileUnit; - using die_iterator_range = llvm::iterator_range; From 36c413a228bd4b2a40d4c3eea29c31682d5f2255 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Mon, 30 Jul 2018 21:41:13 +0000 Subject: [PATCH 0022/1112] Remove unnecessary newlines from break command help text. Summary: We usually don't have trailing newlines in the short help strings. This just adds unnecessary extra lines when printing the help text of these commands. Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D50015 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338311 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Interpreter/CommandInterpreter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp index 76cb5f2896e4..64d2c3222fb6 100644 --- a/source/Interpreter/CommandInterpreter.cpp +++ b/source/Interpreter/CommandInterpreter.cpp @@ -478,7 +478,7 @@ void CommandInterpreter::LoadCommandDictionary() { std::unique_ptr break_regex_cmd_ap( new CommandObjectRegexCommand( *this, "_regexp-break", - "Set a breakpoint using one of several shorthand formats.\n", + "Set a breakpoint using one of several shorthand formats.", "\n" "_regexp-break :\n" " main.c:12 // Break at line 12 of " @@ -527,7 +527,7 @@ void CommandInterpreter::LoadCommandDictionary() { std::unique_ptr tbreak_regex_cmd_ap( new CommandObjectRegexCommand( *this, "_regexp-tbreak", - "Set a one-shot breakpoint using one of several shorthand formats.\n", + "Set a one-shot breakpoint using one of several shorthand formats.", "\n" "_regexp-break :\n" " main.c:12 // Break at line 12 of " From 521fc58ea1a14cfe3681713775b5b413dfe1e7a1 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Tue, 31 Jul 2018 01:21:36 +0000 Subject: [PATCH 0023/1112] Remove Stream::UnitTest Summary: No one is using this method, and it also doesn't really make a lot of sense to have it around. Reviewers: davide Reviewed By: davide Subscribers: davide, lldb-commits Differential Revision: https://reviews.llvm.org/D50026 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338345 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Utility/Stream.h | 2 -- source/Utility/Stream.cpp | 45 ----------------------------------- 2 files changed, 47 deletions(-) diff --git a/include/lldb/Utility/Stream.h b/include/lldb/Utility/Stream.h index bf837749fa37..4930521d9497 100644 --- a/include/lldb/Utility/Stream.h +++ b/include/lldb/Utility/Stream.h @@ -524,8 +524,6 @@ class Stream { //------------------------------------------------------------------ size_t PutULEB128(uint64_t uval); - static void UnitTest(Stream *s); - protected: //------------------------------------------------------------------ // Member variables diff --git a/source/Utility/Stream.cpp b/source/Utility/Stream.cpp index 647a0c0beb5c..7df7f7008084 100644 --- a/source/Utility/Stream.cpp +++ b/source/Utility/Stream.cpp @@ -526,48 +526,3 @@ size_t Stream::PutCStringAsRawHex8(const char *s) { m_flags.Set(eBinary); return bytes_written; } - -void Stream::UnitTest(Stream *s) { - s->PutHex8(0x12); - - s->PutChar(' '); - s->PutHex16(0x3456, endian::InlHostByteOrder()); - s->PutChar(' '); - s->PutHex16(0x3456, eByteOrderBig); - s->PutChar(' '); - s->PutHex16(0x3456, eByteOrderLittle); - - s->PutChar(' '); - s->PutHex32(0x789abcde, endian::InlHostByteOrder()); - s->PutChar(' '); - s->PutHex32(0x789abcde, eByteOrderBig); - s->PutChar(' '); - s->PutHex32(0x789abcde, eByteOrderLittle); - - s->PutChar(' '); - s->PutHex64(0x1122334455667788ull, endian::InlHostByteOrder()); - s->PutChar(' '); - s->PutHex64(0x1122334455667788ull, eByteOrderBig); - s->PutChar(' '); - s->PutHex64(0x1122334455667788ull, eByteOrderLittle); - - const char *hola = "Hello World!!!"; - s->PutChar(' '); - s->PutCString(hola); - - s->PutChar(' '); - s->Write(hola, 5); - - s->PutChar(' '); - s->PutCStringAsRawHex8(hola); - - s->PutChar(' '); - s->PutCStringAsRawHex8("01234"); - - s->PutChar(' '); - s->Printf("pid=%i", 12733); - - s->PutChar(' '); - s->PrintfAsRawHex8("pid=%i", 12733); - s->PutChar('\n'); -} From d8058bbd23b374fff792bca0ebe3b9e14dbda3b6 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Tue, 31 Jul 2018 23:53:23 +0000 Subject: [PATCH 0024/1112] Use UnknownVendor rather than UnknownArch since they're in two different enums and we're switching on vendor and not arch. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338458 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Plugins/Platform/Windows/PlatformWindows.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Plugins/Platform/Windows/PlatformWindows.cpp b/source/Plugins/Platform/Windows/PlatformWindows.cpp index ed2bcf0cbee4..45e906f88e00 100644 --- a/source/Plugins/Platform/Windows/PlatformWindows.cpp +++ b/source/Plugins/Platform/Windows/PlatformWindows.cpp @@ -78,7 +78,7 @@ PlatformSP PlatformWindows::CreateInstance(bool force, create = true; break; - case llvm::Triple::UnknownArch: + case llvm::Triple::UnknownVendor: create = !arch->TripleVendorWasSpecified(); break; From ee9ce6c0a00ae98b51cf4c5a65a7720c92c7def2 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Tue, 31 Jul 2018 23:53:24 +0000 Subject: [PATCH 0025/1112] Tidy up comment. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338459 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Plugins/Platform/Android/PlatformAndroid.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/Plugins/Platform/Android/PlatformAndroid.cpp b/source/Plugins/Platform/Android/PlatformAndroid.cpp index 1cedcde97a92..be7b745a3a2a 100644 --- a/source/Plugins/Platform/Android/PlatformAndroid.cpp +++ b/source/Plugins/Platform/Android/PlatformAndroid.cpp @@ -83,9 +83,9 @@ PlatformSP PlatformAndroid::CreateInstance(bool force, const ArchSpec *arch) { break; #if defined(__ANDROID__) - // Only accept "unknown" for the vendor if the host is android and it + // Only accept "unknown" for the vendor if the host is android and if // "unknown" wasn't specified (it was just returned because it was NOT - // specified_ + // specified). case llvm::Triple::VendorType::UnknownVendor: create = !arch->TripleVendorWasSpecified(); break; From 8c3f968261da46a6df8b848c4a0449623a2cd4a1 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Tue, 31 Jul 2018 23:53:24 +0000 Subject: [PATCH 0026/1112] Android is an environment and we were comparing the android triple against the OS rather than the environment. Also update other uses of OS when we meant environment in the android local code. NFC intended. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338460 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Plugins/Platform/Android/PlatformAndroid.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Plugins/Platform/Android/PlatformAndroid.cpp b/source/Plugins/Platform/Android/PlatformAndroid.cpp index be7b745a3a2a..4477fe371d34 100644 --- a/source/Plugins/Platform/Android/PlatformAndroid.cpp +++ b/source/Plugins/Platform/Android/PlatformAndroid.cpp @@ -95,7 +95,7 @@ PlatformSP PlatformAndroid::CreateInstance(bool force, const ArchSpec *arch) { } if (create) { - switch (triple.getOS()) { + switch (triple.getEnvironment()) { case llvm::Triple::Android: break; @@ -103,8 +103,8 @@ PlatformSP PlatformAndroid::CreateInstance(bool force, const ArchSpec *arch) { // Only accept "unknown" for the OS if the host is android and it // "unknown" wasn't specified (it was just returned because it was NOT // specified) - case llvm::Triple::OSType::UnknownOS: - create = !arch->TripleOSWasSpecified(); + case llvm::Triple::EnvironmentType::UnknownEnvironment: + create = !arch->TripleEnvironmentWasSpecified(); break; #endif default: From c7258e3a759b0be127cf152567ec27727c4d9939 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 1 Aug 2018 06:04:48 +0000 Subject: [PATCH 0027/1112] Added initial unit test for LLDB's Stream class. Summary: This adds an initial small unit test for LLDB's Stream class, which should at least cover most of the functions in the Stream class. StreamString is always in big endian mode, so that's the only stream byte order path this test covers as of now. Also, the binary mode still needs to be tested for all print methods. Also adds some FIXMEs for wrong/strange result values of the Stream class that we hit while testing those functions. Reviewers: labath Reviewed By: labath Subscribers: probinson, labath, mgorny, lldb-commits Differential Revision: https://reviews.llvm.org/D50027 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338488 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/Utility/CMakeLists.txt | 1 + unittests/Utility/StreamTest.cpp | 480 +++++++++++++++++++++++++++++++ 2 files changed, 481 insertions(+) create mode 100644 unittests/Utility/StreamTest.cpp diff --git a/unittests/Utility/CMakeLists.txt b/unittests/Utility/CMakeLists.txt index 6d9d7a4d0069..4812d41ea753 100644 --- a/unittests/Utility/CMakeLists.txt +++ b/unittests/Utility/CMakeLists.txt @@ -14,6 +14,7 @@ add_lldb_unittest(UtilityTests NameMatchesTest.cpp StatusTest.cpp StreamTeeTest.cpp + StreamTest.cpp StringExtractorTest.cpp StructuredDataTest.cpp TildeExpressionResolverTest.cpp diff --git a/unittests/Utility/StreamTest.cpp b/unittests/Utility/StreamTest.cpp new file mode 100644 index 000000000000..d5acef2ec744 --- /dev/null +++ b/unittests/Utility/StreamTest.cpp @@ -0,0 +1,480 @@ +//===-- StreamTest.cpp ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/StreamString.h" +#include "gtest/gtest.h" + +using namespace lldb_private; + +namespace { +struct StreamTest : ::testing::Test { + // Note: Stream is an abstract class, so we use StreamString to test it. To + // make it easier to change this later, only methods in this class explicitly + // refer to the StringStream class. + StreamString s; + // We return here a std::string because that way gtest can print better + // assertion messages. + std::string TakeValue() { + std::string result = s.GetString().str(); + s.Clear(); + return result; + } +}; +} + +namespace { +// A StreamTest where we expect the Stream output to be binary. +struct BinaryStreamTest : StreamTest { + void SetUp() override { + s.GetFlags().Set(Stream::eBinary); + } +}; +} + +TEST_F(StreamTest, ChangingByteOrder) { + s.SetByteOrder(lldb::eByteOrderPDP); + EXPECT_EQ(lldb::eByteOrderPDP, s.GetByteOrder()); +} + +TEST_F(StreamTest, PutChar) { + s.PutChar('a'); + EXPECT_EQ("a", TakeValue()); + + s.PutChar('1'); + EXPECT_EQ("1", TakeValue()); +} + +TEST_F(StreamTest, PutCharWhitespace) { + s.PutChar(' '); + EXPECT_EQ(" ", TakeValue()); + + s.PutChar('\n'); + EXPECT_EQ("\n", TakeValue()); + + s.PutChar('\r'); + EXPECT_EQ("\r", TakeValue()); + + s.PutChar('\t'); + EXPECT_EQ("\t", TakeValue()); +} + +TEST_F(StreamTest, PutCString) { + s.PutCString(""); + EXPECT_EQ("", TakeValue()); + + s.PutCString("foobar"); + EXPECT_EQ("foobar", TakeValue()); + + s.PutCString(" "); + EXPECT_EQ(" ", TakeValue()); +} + +TEST_F(StreamTest, PutCStringWithStringRef) { + s.PutCString(llvm::StringRef("")); + EXPECT_EQ("", TakeValue()); + + s.PutCString(llvm::StringRef("foobar")); + EXPECT_EQ("foobar", TakeValue()); + + s.PutCString(llvm::StringRef(" ")); + EXPECT_EQ(" ", TakeValue()); +} + +TEST_F(StreamTest, QuotedCString) { + s.QuotedCString("foo"); + EXPECT_EQ(R"("foo")", TakeValue()); + + s.QuotedCString("ba r"); + EXPECT_EQ(R"("ba r")", TakeValue()); + + s.QuotedCString(" "); + EXPECT_EQ(R"(" ")", TakeValue()); +} + +TEST_F(StreamTest, PutCharNull) { + s.PutChar('\0'); + EXPECT_EQ(std::string("\0", 1), TakeValue()); + + s.PutChar('a'); + EXPECT_EQ(std::string("a", 1), TakeValue()); +} + +TEST_F(StreamTest, PutCStringAsRawHex8) { + s.PutCStringAsRawHex8(""); + // FIXME: Check that printing 00 on an empty string is the intended behavior. + // It seems kind of unexpected that we print the trailing 0 byte for empty + // strings, but not for non-empty strings. + EXPECT_EQ("00", TakeValue()); + + s.PutCStringAsRawHex8("foobar"); + EXPECT_EQ("666f6f626172", TakeValue()); + + s.PutCStringAsRawHex8(" "); + EXPECT_EQ("20", TakeValue()); +} + +TEST_F(StreamTest, PutHex8) { + s.PutHex8((uint8_t)55); + EXPECT_EQ("37", TakeValue()); + s.PutHex8(std::numeric_limits::max()); + EXPECT_EQ("ff", TakeValue()); + s.PutHex8((uint8_t)0); + EXPECT_EQ("00", TakeValue()); +} + +TEST_F(StreamTest, PutNHex8) { + s.PutNHex8(0, (uint8_t)55); + EXPECT_EQ("", TakeValue()); + s.PutNHex8(1, (uint8_t)55); + EXPECT_EQ("37", TakeValue()); + s.PutNHex8(2, (uint8_t)55); + EXPECT_EQ("3737", TakeValue()); + s.PutNHex8(1, (uint8_t)56); + EXPECT_EQ("38", TakeValue()); +} + +TEST_F(StreamTest, PutHex16ByteOrderLittle) { + s.PutHex16(0x1234U, lldb::eByteOrderLittle); + EXPECT_EQ("3412", TakeValue()); + s.PutHex16(std::numeric_limits::max(), lldb::eByteOrderLittle); + EXPECT_EQ("ffff", TakeValue()); + s.PutHex16(0U, lldb::eByteOrderLittle); + EXPECT_EQ("0000", TakeValue()); +} + +TEST_F(StreamTest, PutHex16ByteOrderBig) { + s.PutHex16(0x1234U, lldb::eByteOrderBig); + EXPECT_EQ("1234", TakeValue()); + s.PutHex16(std::numeric_limits::max(), lldb::eByteOrderBig); + EXPECT_EQ("ffff", TakeValue()); + s.PutHex16(0U, lldb::eByteOrderBig); + EXPECT_EQ("0000", TakeValue()); +} + +TEST_F(StreamTest, PutHex32ByteOrderLittle) { + s.PutHex32(0x12345678U, lldb::eByteOrderLittle); + EXPECT_EQ("78563412", TakeValue()); + s.PutHex32(std::numeric_limits::max(), lldb::eByteOrderLittle); + EXPECT_EQ("ffffffff", TakeValue()); + s.PutHex32(0U, lldb::eByteOrderLittle); + EXPECT_EQ("00000000", TakeValue()); +} + +TEST_F(StreamTest, PutHex32ByteOrderBig) { + s.PutHex32(0x12345678U, lldb::eByteOrderBig); + EXPECT_EQ("12345678", TakeValue()); + s.PutHex32(std::numeric_limits::max(), lldb::eByteOrderBig); + EXPECT_EQ("ffffffff", TakeValue()); + s.PutHex32(0U, lldb::eByteOrderBig); + EXPECT_EQ("00000000", TakeValue()); +} + +TEST_F(StreamTest, PutHex64ByteOrderLittle) { + s.PutHex64(0x1234567890ABCDEFU, lldb::eByteOrderLittle); + EXPECT_EQ("efcdab9078563412", TakeValue()); + s.PutHex64(std::numeric_limits::max(), lldb::eByteOrderLittle); + EXPECT_EQ("ffffffffffffffff", TakeValue()); + s.PutHex64(0U, lldb::eByteOrderLittle); + EXPECT_EQ("0000000000000000", TakeValue()); +} + +TEST_F(StreamTest, PutHex64ByteOrderBig) { + s.PutHex64(0x1234567890ABCDEFU, lldb::eByteOrderBig); + EXPECT_EQ("1234567890abcdef", TakeValue()); + s.PutHex64(std::numeric_limits::max(), lldb::eByteOrderBig); + EXPECT_EQ("ffffffffffffffff", TakeValue()); + s.PutHex64(0U, lldb::eByteOrderBig); + EXPECT_EQ("0000000000000000", TakeValue()); +} + +//------------------------------------------------------------------------------ +// Shift operator tests. +//------------------------------------------------------------------------------ + +TEST_F(StreamTest, ShiftOperatorChars) { + s << 'a' << 'b'; + EXPECT_EQ("ab", TakeValue()); +} + +TEST_F(StreamTest, ShiftOperatorStrings) { + s << "cstring\n"; + s << llvm::StringRef("llvm::StringRef\n"); + EXPECT_EQ("cstring\nllvm::StringRef\n", TakeValue()); +} + +TEST_F(StreamTest, ShiftOperatorInts) { + s << std::numeric_limits::max() << " "; + s << std::numeric_limits::max() << " "; + s << std::numeric_limits::max() << " "; + s << std::numeric_limits::max(); + EXPECT_EQ("127 32767 2147483647 9223372036854775807", TakeValue()); +} + +TEST_F(StreamTest, ShiftOperatorUInts) { + s << std::numeric_limits::max() << " "; + s << std::numeric_limits::max() << " "; + s << std::numeric_limits::max() << " "; + s << std::numeric_limits::max(); + EXPECT_EQ("ff ffff ffffffff ffffffffffffffff", TakeValue()); +} + +TEST_F(StreamTest, ShiftOperatorPtr) { + // This test is a bit tricky because pretty much everything related to + // pointer printing seems to lead to UB or IB. So let's make the most basic + // test that just checks that we print *something*. This way we at least know + // that pointer printing doesn't do really bad things (e.g. crashing, reading + // OOB/uninitialized memory which the sanitizers would spot). + + // Shift our own pointer to the output. + int i = 3; + int *ptr = &i; + s << ptr; + + EXPECT_TRUE(!TakeValue().empty()); +} + +TEST_F(StreamTest, PutPtr) { + // See the ShiftOperatorPtr test for the rationale. + int i = 3; + int *ptr = &i; + s.PutPointer(ptr); + + EXPECT_TRUE(!TakeValue().empty()); +} + +// Alias to make it more clear that 'invalid' means for the Stream interface +// that it should use the host byte order. +const static auto hostByteOrder = lldb::eByteOrderInvalid; + +//------------------------------------------------------------------------------ +// PutRawBytes/PutBytesAsRawHex tests. +//------------------------------------------------------------------------------ + +TEST_F(StreamTest, PutBytesAsRawHex8ToBigEndian) { + uint32_t value = 0x12345678; + s.PutBytesAsRawHex8(static_cast(&value), sizeof(value), + hostByteOrder, lldb::eByteOrderBig); + EXPECT_EQ("78563412", TakeValue()); +} + +TEST_F(StreamTest, PutRawBytesToBigEndian) { + uint32_t value = 0x12345678; + s.PutRawBytes(static_cast(&value), sizeof(value), + hostByteOrder, lldb::eByteOrderBig); + EXPECT_EQ("\x78\x56\x34\x12", TakeValue()); +} + +TEST_F(StreamTest, PutBytesAsRawHex8ToLittleEndian) { + uint32_t value = 0x12345678; + s.PutBytesAsRawHex8(static_cast(&value), sizeof(value), + hostByteOrder, lldb::eByteOrderLittle); + EXPECT_EQ("12345678", TakeValue()); +} + +TEST_F(StreamTest, PutRawBytesToLittleEndian) { + uint32_t value = 0x12345678; + s.PutRawBytes(static_cast(&value), sizeof(value), + hostByteOrder, lldb::eByteOrderLittle); + EXPECT_EQ("\x12\x34\x56\x78", TakeValue()); +} + +TEST_F(StreamTest, PutBytesAsRawHex8ToMixedEndian) { + uint32_t value = 0x12345678; + s.PutBytesAsRawHex8(static_cast(&value), sizeof(value), + hostByteOrder, lldb::eByteOrderPDP); + + // FIXME: PDP byte order is not actually implemented but Stream just silently + // prints the value in some random byte order... +#if 0 + EXPECT_EQ("34127856", TakeValue()); +#endif +} + +TEST_F(StreamTest, PutRawBytesToMixedEndian) { + uint32_t value = 0x12345678; + s.PutRawBytes(static_cast(&value), sizeof(value), + lldb::eByteOrderInvalid, lldb::eByteOrderPDP); + + // FIXME: PDP byte order is not actually implemented but Stream just silently + // prints the value in some random byte order... +#if 0 + EXPECT_EQ("\x34\x12\x78\x56", TakeValue()); +#endif +} + +//------------------------------------------------------------------------------ +// ULEB128 support for binary streams. +//------------------------------------------------------------------------------ + +TEST_F(BinaryStreamTest, PutULEB128OneByte) { + auto bytes = s.PutULEB128(0x74ULL); + EXPECT_EQ("\x74", TakeValue()); + EXPECT_EQ(1U, bytes); +} + +TEST_F(BinaryStreamTest, PutULEB128TwoBytes) { + auto bytes = s.PutULEB128(0x1985ULL); + EXPECT_EQ("\x85\x33", TakeValue()); + EXPECT_EQ(2U, bytes); +} + +TEST_F(BinaryStreamTest, PutULEB128ThreeBytes) { + auto bytes = s.PutULEB128(0x5023ULL); + EXPECT_EQ("\xA3\xA0\x1", TakeValue()); + EXPECT_EQ(3U, bytes); +} + +TEST_F(BinaryStreamTest, PutULEB128FourBytes) { + auto bytes = s.PutULEB128(0xA48032ULL); + EXPECT_EQ("\xB2\x80\x92\x5", TakeValue()); + EXPECT_EQ(4U, bytes); +} + +TEST_F(BinaryStreamTest, PutULEB128FiveBytes) { + auto bytes = s.PutULEB128(0x12345678ULL); + EXPECT_EQ("\xF8\xAC\xD1\x91\x1", TakeValue()); + EXPECT_EQ(5U, bytes); +} + +TEST_F(BinaryStreamTest, PutULEB128SixBytes) { + auto bytes = s.PutULEB128(0xABFE3FAFDFULL); + EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\x15", TakeValue()); + EXPECT_EQ(6U, bytes); +} + +TEST_F(BinaryStreamTest, PutULEB128SevenBytes) { + auto bytes = s.PutULEB128(0xDABFE3FAFDFULL); + EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\x3", TakeValue()); + EXPECT_EQ(7U, bytes); +} + +TEST_F(BinaryStreamTest, PutULEB128EightBytes) { + auto bytes = s.PutULEB128(0x7CDABFE3FAFDFULL); + EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x3", TakeValue()); + EXPECT_EQ(8U, bytes); +} + +TEST_F(BinaryStreamTest, PutULEB128NineBytes) { + auto bytes = s.PutULEB128(0x327CDABFE3FAFDFULL); + EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x93\x3", TakeValue()); + EXPECT_EQ(9U, bytes); +} + +TEST_F(BinaryStreamTest, PutULEB128MaxValue) { + auto bytes = s.PutULEB128(std::numeric_limits::max()); + EXPECT_EQ("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x1", TakeValue()); + EXPECT_EQ(10U, bytes); +} + +TEST_F(BinaryStreamTest, PutULEB128Zero) { + auto bytes = s.PutULEB128(0x0U); + EXPECT_EQ(std::string("\0", 1), TakeValue()); + EXPECT_EQ(1U, bytes); +} + +TEST_F(BinaryStreamTest, PutULEB128One) { + auto bytes = s.PutULEB128(0x1U); + EXPECT_EQ("\x1", TakeValue()); + EXPECT_EQ(1U, bytes); +} + +//------------------------------------------------------------------------------ +// SLEB128 support for binary streams. +//------------------------------------------------------------------------------ + +TEST_F(BinaryStreamTest, PutSLEB128OneByte) { + auto bytes = s.PutSLEB128(0x74LL); + EXPECT_EQ(std::string("\xF4\0", 2), TakeValue()); + EXPECT_EQ(2U, bytes); +} + +TEST_F(BinaryStreamTest, PutSLEB128TwoBytes) { + auto bytes = s.PutSLEB128(0x1985LL); + EXPECT_EQ("\x85\x33", TakeValue()); + EXPECT_EQ(2U, bytes); +} + +TEST_F(BinaryStreamTest, PutSLEB128ThreeBytes) { + auto bytes = s.PutSLEB128(0x5023LL); + EXPECT_EQ("\xA3\xA0\x1", TakeValue()); + EXPECT_EQ(3U, bytes); +} + +TEST_F(BinaryStreamTest, PutSLEB128FourBytes) { + auto bytes = s.PutSLEB128(0xA48032LL); + EXPECT_EQ("\xB2\x80\x92\x5", TakeValue()); + EXPECT_EQ(4U, bytes); +} + +TEST_F(BinaryStreamTest, PutSLEB128FiveBytes) { + auto bytes = s.PutSLEB128(0x12345678LL); + EXPECT_EQ("\xF8\xAC\xD1\x91\x1", TakeValue()); + EXPECT_EQ(5U, bytes); +} + +TEST_F(BinaryStreamTest, PutSLEB128SixBytes) { + auto bytes = s.PutSLEB128(0xABFE3FAFDFLL); + EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\x15", TakeValue()); + EXPECT_EQ(6U, bytes); +} + +TEST_F(BinaryStreamTest, PutSLEB128SevenBytes) { + auto bytes = s.PutSLEB128(0xDABFE3FAFDFLL); + EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\x3", TakeValue()); + EXPECT_EQ(7U, bytes); +} + +TEST_F(BinaryStreamTest, PutSLEB128EightBytes) { + auto bytes = s.PutSLEB128(0x7CDABFE3FAFDFLL); + EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x3", TakeValue()); + EXPECT_EQ(8U, bytes); +} + +TEST_F(BinaryStreamTest, PutSLEB128NineBytes) { + auto bytes = s.PutSLEB128(0x327CDABFE3FAFDFLL); + EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x93\x3", TakeValue()); + EXPECT_EQ(9U, bytes); +} + +TEST_F(BinaryStreamTest, PutSLEB128MaxValue) { + auto bytes = s.PutSLEB128(std::numeric_limits::max()); + EXPECT_EQ(std::string("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0", 10), TakeValue()); + EXPECT_EQ(10U, bytes); +} + +TEST_F(BinaryStreamTest, PutSLEB128Zero) { + auto bytes = s.PutSLEB128(0x0); + EXPECT_EQ(std::string("\0", 1), TakeValue()); + EXPECT_EQ(1U, bytes); +} + +TEST_F(BinaryStreamTest, PutSLEB128One) { + auto bytes = s.PutSLEB128(0x1); + EXPECT_EQ(std::string("\x1", 1), TakeValue()); + EXPECT_EQ(1U, bytes); +} + +//------------------------------------------------------------------------------ +// SLEB128/ULEB128 support for non-binary streams. +//------------------------------------------------------------------------------ + +// The logic for this is very simple, so it should be enough to test some basic +// use cases. + +TEST_F(StreamTest, PutULEB128) { + auto bytes = s.PutULEB128(0x74ULL); + EXPECT_EQ("0x74", TakeValue()); + EXPECT_EQ(4U, bytes); +} + +TEST_F(StreamTest, PutSLEB128) { + auto bytes = s.PutSLEB128(0x1985LL); + EXPECT_EQ("0x6533", TakeValue()); + EXPECT_EQ(6U, bytes); +} From a98bce74c6157d0c56ccab20eafe9eee492fb627 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 1 Aug 2018 06:35:27 +0000 Subject: [PATCH 0028/1112] Removed failing StreamTest case The suspicious behavior is obviously because this method reads OOB memory, so I'll remove it for now and re-add the test alongside the fix later. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338491 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/Utility/StreamTest.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/unittests/Utility/StreamTest.cpp b/unittests/Utility/StreamTest.cpp index d5acef2ec744..2e30357bb292 100644 --- a/unittests/Utility/StreamTest.cpp +++ b/unittests/Utility/StreamTest.cpp @@ -106,12 +106,6 @@ TEST_F(StreamTest, PutCharNull) { } TEST_F(StreamTest, PutCStringAsRawHex8) { - s.PutCStringAsRawHex8(""); - // FIXME: Check that printing 00 on an empty string is the intended behavior. - // It seems kind of unexpected that we print the trailing 0 byte for empty - // strings, but not for non-empty strings. - EXPECT_EQ("00", TakeValue()); - s.PutCStringAsRawHex8("foobar"); EXPECT_EQ("666f6f626172", TakeValue()); From 9f4857b63e105339f57ba1d3241b20def4523b20 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Wed, 1 Aug 2018 17:07:40 +0000 Subject: [PATCH 0029/1112] [StackFrame] Factor GetOnlyConcreteFramesUpTo out of GetFramesUpTo (NFC) Splitting GetOnlyConcreteFramesUpTo will make it easier to implement support for synthetic tail call frames in backtraces. This is just a prep change, no functionality is affected. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338588 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Target/StackFrameList.h | 2 + source/Target/StackFrameList.cpp | 329 ++++++++++++++------------- 2 files changed, 168 insertions(+), 163 deletions(-) diff --git a/include/lldb/Target/StackFrameList.h b/include/lldb/Target/StackFrameList.h index cb9fb136fb4e..4eb8a7b87e49 100644 --- a/include/lldb/Target/StackFrameList.h +++ b/include/lldb/Target/StackFrameList.h @@ -83,6 +83,8 @@ class StackFrameList { void GetFramesUpTo(uint32_t end_idx); + void GetOnlyConcreteFramesUpTo(uint32_t end_idx, Unwind *unwinder); + bool GetAllFramesFetched() { return m_concrete_frames_fetched == UINT32_MAX; } void SetAllFramesFetched() { m_concrete_frames_fetched = UINT32_MAX; } diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp index 2380a91df41d..caec25f35ad7 100644 --- a/source/Target/StackFrameList.cpp +++ b/source/Target/StackFrameList.cpp @@ -226,8 +226,27 @@ void StackFrameList::SetCurrentInlinedDepth(uint32_t new_depth) { m_current_inlined_pc = m_thread.GetRegisterContext()->GetPC(); } +void StackFrameList::GetOnlyConcreteFramesUpTo(uint32_t end_idx, + Unwind *unwinder) { + assert(m_thread.IsValid() && "Expected valid thread"); + assert(m_frames.size() <= end_idx && "Expected there to be frames to fill"); + + if (end_idx < m_concrete_frames_fetched) + return; + + if (!unwinder) + return; + + uint32_t num_frames = unwinder->GetFramesUpTo(end_idx); + if (num_frames <= end_idx + 1) { + // Done unwinding. + m_concrete_frames_fetched = UINT32_MAX; + } + m_frames.resize(num_frames); +} + void StackFrameList::GetFramesUpTo(uint32_t end_idx) { - // this makes sure we do not fetch frames for an invalid thread + // Do not fetch frames for an invalid thread. if (!m_thread.IsValid()) return; @@ -238,201 +257,185 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { Unwind *unwinder = m_thread.GetUnwinder(); - if (m_show_inlined_frames) { + if (!m_show_inlined_frames) { + GetOnlyConcreteFramesUpTo(end_idx, unwinder); + return; + } + #if defined(DEBUG_STACK_FRAMES) - StreamFile s(stdout, false); + StreamFile s(stdout, false); #endif - // If we are hiding some frames from the outside world, we need to add - // those onto the total count of frames to fetch. However, we don't need - // to do that if end_idx is 0 since in that case we always get the first - // concrete frame and all the inlined frames below it... And of course, if - // end_idx is UINT32_MAX that means get all, so just do that... - - uint32_t inlined_depth = 0; - if (end_idx > 0 && end_idx != UINT32_MAX) { - inlined_depth = GetCurrentInlinedDepth(); - if (inlined_depth != UINT32_MAX) { - if (end_idx > 0) - end_idx += inlined_depth; - } + // If we are hiding some frames from the outside world, we need to add + // those onto the total count of frames to fetch. However, we don't need + // to do that if end_idx is 0 since in that case we always get the first + // concrete frame and all the inlined frames below it... And of course, if + // end_idx is UINT32_MAX that means get all, so just do that... + + uint32_t inlined_depth = 0; + if (end_idx > 0 && end_idx != UINT32_MAX) { + inlined_depth = GetCurrentInlinedDepth(); + if (inlined_depth != UINT32_MAX) { + if (end_idx > 0) + end_idx += inlined_depth; } + } - StackFrameSP unwind_frame_sp; - do { - uint32_t idx = m_concrete_frames_fetched++; - lldb::addr_t pc = LLDB_INVALID_ADDRESS; - lldb::addr_t cfa = LLDB_INVALID_ADDRESS; - if (idx == 0) { - // We might have already created frame zero, only create it if we need - // to - if (m_frames.empty()) { - RegisterContextSP reg_ctx_sp(m_thread.GetRegisterContext()); - - if (reg_ctx_sp) { - const bool success = - unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc); - // There shouldn't be any way not to get the frame info for frame - // 0. But if the unwinder can't make one, lets make one by hand - // with the - // SP as the CFA and see if that gets any further. - if (!success) { - cfa = reg_ctx_sp->GetSP(); - pc = reg_ctx_sp->GetPC(); - } - - unwind_frame_sp.reset(new StackFrame(m_thread.shared_from_this(), - m_frames.size(), idx, - reg_ctx_sp, cfa, pc, nullptr)); - m_frames.push_back(unwind_frame_sp); + StackFrameSP unwind_frame_sp; + do { + uint32_t idx = m_concrete_frames_fetched++; + lldb::addr_t pc = LLDB_INVALID_ADDRESS; + lldb::addr_t cfa = LLDB_INVALID_ADDRESS; + if (idx == 0) { + // We might have already created frame zero, only create it if we need + // to. + if (m_frames.empty()) { + RegisterContextSP reg_ctx_sp(m_thread.GetRegisterContext()); + + if (reg_ctx_sp) { + const bool success = + unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc); + // There shouldn't be any way not to get the frame info for frame + // 0. But if the unwinder can't make one, lets make one by hand + // with the SP as the CFA and see if that gets any further. + if (!success) { + cfa = reg_ctx_sp->GetSP(); + pc = reg_ctx_sp->GetPC(); } - } else { - unwind_frame_sp = m_frames.front(); - cfa = unwind_frame_sp->m_id.GetCallFrameAddress(); + + unwind_frame_sp.reset(new StackFrame(m_thread.shared_from_this(), + m_frames.size(), idx, reg_ctx_sp, + cfa, pc, nullptr)); + m_frames.push_back(unwind_frame_sp); } } else { - const bool success = - unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc); - if (!success) { - // We've gotten to the end of the stack. - SetAllFramesFetched(); - break; - } - const bool cfa_is_valid = true; - const bool stop_id_is_valid = false; - const bool is_history_frame = false; - unwind_frame_sp.reset(new StackFrame( - m_thread.shared_from_this(), m_frames.size(), idx, cfa, - cfa_is_valid, pc, 0, stop_id_is_valid, is_history_frame, nullptr)); - m_frames.push_back(unwind_frame_sp); + unwind_frame_sp = m_frames.front(); + cfa = unwind_frame_sp->m_id.GetCallFrameAddress(); + } + } else { + const bool success = + unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc); + if (!success) { + // We've gotten to the end of the stack. + SetAllFramesFetched(); + break; } + const bool cfa_is_valid = true; + const bool stop_id_is_valid = false; + const bool is_history_frame = false; + unwind_frame_sp.reset(new StackFrame( + m_thread.shared_from_this(), m_frames.size(), idx, cfa, cfa_is_valid, + pc, 0, stop_id_is_valid, is_history_frame, nullptr)); + m_frames.push_back(unwind_frame_sp); + } - assert(unwind_frame_sp); - SymbolContext unwind_sc = unwind_frame_sp->GetSymbolContext( - eSymbolContextBlock | eSymbolContextFunction); - Block *unwind_block = unwind_sc.block; - if (unwind_block) { - Address curr_frame_address(unwind_frame_sp->GetFrameCodeAddress()); - TargetSP target_sp = m_thread.CalculateTarget(); - // Be sure to adjust the frame address to match the address that was - // used to lookup the symbol context above. If we are in the first - // concrete frame, then we lookup using the current address, else we - // decrement the address by one to get the correct location. - if (idx > 0) { - if (curr_frame_address.GetOffset() == 0) { - // If curr_frame_address points to the first address in a section - // then after adjustment it will point to an other section. In that - // case resolve the address again to the correct section plus - // offset form. - addr_t load_addr = curr_frame_address.GetOpcodeLoadAddress( - target_sp.get(), AddressClass::eCode); - curr_frame_address.SetOpcodeLoadAddress( - load_addr - 1, target_sp.get(), AddressClass::eCode); - } else { - curr_frame_address.Slide(-1); - } + assert(unwind_frame_sp); + SymbolContext unwind_sc = unwind_frame_sp->GetSymbolContext( + eSymbolContextBlock | eSymbolContextFunction); + Block *unwind_block = unwind_sc.block; + if (unwind_block) { + Address curr_frame_address(unwind_frame_sp->GetFrameCodeAddress()); + TargetSP target_sp = m_thread.CalculateTarget(); + // Be sure to adjust the frame address to match the address that was + // used to lookup the symbol context above. If we are in the first + // concrete frame, then we lookup using the current address, else we + // decrement the address by one to get the correct location. + if (idx > 0) { + if (curr_frame_address.GetOffset() == 0) { + // If curr_frame_address points to the first address in a section + // then after adjustment it will point to an other section. In that + // case resolve the address again to the correct section plus + // offset form. + addr_t load_addr = curr_frame_address.GetOpcodeLoadAddress( + target_sp.get(), AddressClass::eCode); + curr_frame_address.SetOpcodeLoadAddress( + load_addr - 1, target_sp.get(), AddressClass::eCode); + } else { + curr_frame_address.Slide(-1); } + } - SymbolContext next_frame_sc; - Address next_frame_address; + SymbolContext next_frame_sc; + Address next_frame_address; - while (unwind_sc.GetParentOfInlinedScope( - curr_frame_address, next_frame_sc, next_frame_address)) { - next_frame_sc.line_entry.ApplyFileMappings(target_sp); - StackFrameSP frame_sp( - new StackFrame(m_thread.shared_from_this(), m_frames.size(), idx, - unwind_frame_sp->GetRegisterContextSP(), cfa, - next_frame_address, &next_frame_sc)); + while (unwind_sc.GetParentOfInlinedScope( + curr_frame_address, next_frame_sc, next_frame_address)) { + next_frame_sc.line_entry.ApplyFileMappings(target_sp); + StackFrameSP frame_sp( + new StackFrame(m_thread.shared_from_this(), m_frames.size(), idx, + unwind_frame_sp->GetRegisterContextSP(), cfa, + next_frame_address, &next_frame_sc)); - m_frames.push_back(frame_sp); - unwind_sc = next_frame_sc; - curr_frame_address = next_frame_address; - } + m_frames.push_back(frame_sp); + unwind_sc = next_frame_sc; + curr_frame_address = next_frame_address; } - } while (m_frames.size() - 1 < end_idx); - - // Don't try to merge till you've calculated all the frames in this stack. - if (GetAllFramesFetched() && m_prev_frames_sp) { - StackFrameList *prev_frames = m_prev_frames_sp.get(); - StackFrameList *curr_frames = this; + } + } while (m_frames.size() - 1 < end_idx); -// curr_frames->m_current_inlined_depth = prev_frames->m_current_inlined_depth; -// curr_frames->m_current_inlined_pc = prev_frames->m_current_inlined_pc; -// printf ("GetFramesUpTo: Copying current inlined depth: %d 0x%" PRIx64 ".\n", -// curr_frames->m_current_inlined_depth, curr_frames->m_current_inlined_pc); + // Don't try to merge till you've calculated all the frames in this stack. + if (GetAllFramesFetched() && m_prev_frames_sp) { + StackFrameList *prev_frames = m_prev_frames_sp.get(); + StackFrameList *curr_frames = this; #if defined(DEBUG_STACK_FRAMES) - s.PutCString("\nprev_frames:\n"); - prev_frames->Dump(&s); - s.PutCString("\ncurr_frames:\n"); - curr_frames->Dump(&s); - s.EOL(); + s.PutCString("\nprev_frames:\n"); + prev_frames->Dump(&s); + s.PutCString("\ncurr_frames:\n"); + curr_frames->Dump(&s); + s.EOL(); #endif - size_t curr_frame_num, prev_frame_num; + size_t curr_frame_num, prev_frame_num; - for (curr_frame_num = curr_frames->m_frames.size(), - prev_frame_num = prev_frames->m_frames.size(); - curr_frame_num > 0 && prev_frame_num > 0; - --curr_frame_num, --prev_frame_num) { - const size_t curr_frame_idx = curr_frame_num - 1; - const size_t prev_frame_idx = prev_frame_num - 1; - StackFrameSP curr_frame_sp(curr_frames->m_frames[curr_frame_idx]); - StackFrameSP prev_frame_sp(prev_frames->m_frames[prev_frame_idx]); + for (curr_frame_num = curr_frames->m_frames.size(), + prev_frame_num = prev_frames->m_frames.size(); + curr_frame_num > 0 && prev_frame_num > 0; + --curr_frame_num, --prev_frame_num) { + const size_t curr_frame_idx = curr_frame_num - 1; + const size_t prev_frame_idx = prev_frame_num - 1; + StackFrameSP curr_frame_sp(curr_frames->m_frames[curr_frame_idx]); + StackFrameSP prev_frame_sp(prev_frames->m_frames[prev_frame_idx]); #if defined(DEBUG_STACK_FRAMES) - s.Printf("\n\nCurr frame #%u ", curr_frame_idx); - if (curr_frame_sp) - curr_frame_sp->Dump(&s, true, false); - else - s.PutCString("NULL"); - s.Printf("\nPrev frame #%u ", prev_frame_idx); - if (prev_frame_sp) - prev_frame_sp->Dump(&s, true, false); - else - s.PutCString("NULL"); + s.Printf("\n\nCurr frame #%u ", curr_frame_idx); + if (curr_frame_sp) + curr_frame_sp->Dump(&s, true, false); + else + s.PutCString("NULL"); + s.Printf("\nPrev frame #%u ", prev_frame_idx); + if (prev_frame_sp) + prev_frame_sp->Dump(&s, true, false); + else + s.PutCString("NULL"); #endif - StackFrame *curr_frame = curr_frame_sp.get(); - StackFrame *prev_frame = prev_frame_sp.get(); + StackFrame *curr_frame = curr_frame_sp.get(); + StackFrame *prev_frame = prev_frame_sp.get(); - if (curr_frame == nullptr || prev_frame == nullptr) - break; + if (curr_frame == nullptr || prev_frame == nullptr) + break; - // Check the stack ID to make sure they are equal - if (curr_frame->GetStackID() != prev_frame->GetStackID()) - break; + // Check the stack ID to make sure they are equal. + if (curr_frame->GetStackID() != prev_frame->GetStackID()) + break; - prev_frame->UpdatePreviousFrameFromCurrentFrame(*curr_frame); - // Now copy the fixed up previous frame into the current frames so the - // pointer doesn't change - m_frames[curr_frame_idx] = prev_frame_sp; -// curr_frame->UpdateCurrentFrameFromPreviousFrame (*prev_frame); + prev_frame->UpdatePreviousFrameFromCurrentFrame(*curr_frame); + // Now copy the fixed up previous frame into the current frames so the + // pointer doesn't change. + m_frames[curr_frame_idx] = prev_frame_sp; #if defined(DEBUG_STACK_FRAMES) - s.Printf("\n Copying previous frame to current frame"); + s.Printf("\n Copying previous frame to current frame"); #endif - } - // We are done with the old stack frame list, we can release it now - m_prev_frames_sp.reset(); } + // We are done with the old stack frame list, we can release it now. + m_prev_frames_sp.reset(); + } #if defined(DEBUG_STACK_FRAMES) - s.PutCString("\n\nNew frames:\n"); - Dump(&s); - s.EOL(); + s.PutCString("\n\nNew frames:\n"); + Dump(&s); + s.EOL(); #endif - } else { - if (end_idx < m_concrete_frames_fetched) - return; - - if (unwinder) { - uint32_t num_frames = unwinder->GetFramesUpTo(end_idx); - if (num_frames <= end_idx + 1) { - // Done unwinding. - m_concrete_frames_fetched = UINT32_MAX; - } - m_frames.resize(num_frames); - } - } } uint32_t StackFrameList::GetNumFrames(bool can_create) { From 04d8f01bb58454c7b0133685ac6c0869d2c7ccdb Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Wed, 1 Aug 2018 17:07:56 +0000 Subject: [PATCH 0030/1112] [StackFrame] Use early returns in ResetCurrentInlinedDepth (NFC) Using early returns in this function substantially reduces the nesting level, making the logic easier to understand. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338589 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Target/StackFrameList.h | 2 +- source/Target/StackFrameList.cpp | 224 +++++++++++++-------------- 2 files changed, 109 insertions(+), 117 deletions(-) diff --git a/include/lldb/Target/StackFrameList.h b/include/lldb/Target/StackFrameList.h index 4eb8a7b87e49..864d4b43aff6 100644 --- a/include/lldb/Target/StackFrameList.h +++ b/include/lldb/Target/StackFrameList.h @@ -109,7 +109,7 @@ class StackFrameList { uint32_t m_concrete_frames_fetched; uint32_t m_current_inlined_depth; lldb::addr_t m_current_inlined_pc; - bool m_show_inlined_frames; + const bool m_show_inlined_frames; private: DISALLOW_COPY_AND_ASSIGN(StackFrameList); diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp index caec25f35ad7..5b989f73bd29 100644 --- a/source/Target/StackFrameList.cpp +++ b/source/Target/StackFrameList.cpp @@ -81,127 +81,119 @@ uint32_t StackFrameList::GetCurrentInlinedDepth() { } void StackFrameList::ResetCurrentInlinedDepth() { + if (!m_show_inlined_frames) + return; + std::lock_guard guard(m_mutex); - if (m_show_inlined_frames) { - GetFramesUpTo(0); - if (m_frames.empty()) - return; - if (!m_frames[0]->IsInlined()) { - m_current_inlined_depth = UINT32_MAX; - m_current_inlined_pc = LLDB_INVALID_ADDRESS; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - if (log && log->GetVerbose()) - log->Printf( - "ResetCurrentInlinedDepth: Invalidating current inlined depth.\n"); - } else { - // We only need to do something special about inlined blocks when we are - // at the beginning of an inlined function: - // FIXME: We probably also have to do something special if the PC is at - // the END - // of an inlined function, which coincides with the end of either its - // containing function or another inlined function. - - lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC(); - Block *block_ptr = m_frames[0]->GetFrameBlock(); - if (block_ptr) { - Address pc_as_address; - pc_as_address.SetLoadAddress(curr_pc, - &(m_thread.GetProcess()->GetTarget())); - AddressRange containing_range; - if (block_ptr->GetRangeContainingAddress(pc_as_address, - containing_range)) { - if (pc_as_address == containing_range.GetBaseAddress()) { - // If we got here because of a breakpoint hit, then set the inlined - // depth depending on where the breakpoint was set. If we got here - // because of a crash, then set the inlined depth to the deepest - // most block. Otherwise, we stopped here naturally as the result - // of a step, so set ourselves in the containing frame of the whole - // set of nested inlines, so the user can then "virtually" step - // into the frames one by one, or next over the whole mess. Note: - // We don't have to handle being somewhere in the middle of the - // stack here, since ResetCurrentInlinedDepth doesn't get called if - // there is a valid inlined depth set. - StopInfoSP stop_info_sp = m_thread.GetStopInfo(); - if (stop_info_sp) { - switch (stop_info_sp->GetStopReason()) { - case eStopReasonWatchpoint: - case eStopReasonException: - case eStopReasonExec: - case eStopReasonSignal: - // In all these cases we want to stop in the deepest most - // frame. - m_current_inlined_pc = curr_pc; - m_current_inlined_depth = 0; - break; - case eStopReasonBreakpoint: { - // FIXME: Figure out what this break point is doing, and set the - // inline depth - // appropriately. Be careful to take into account breakpoints - // that implement step over prologue, since that should do the - // default calculation. For now, if the breakpoints - // corresponding to this hit are all internal, - // I set the stop location to the top of the inlined stack, - // since that will make - // things like stepping over prologues work right. But if - // there are any non-internal breakpoints I do to the bottom of - // the stack, since that was the old behavior. - uint32_t bp_site_id = stop_info_sp->GetValue(); - BreakpointSiteSP bp_site_sp( - m_thread.GetProcess()->GetBreakpointSiteList().FindByID( - bp_site_id)); - bool all_internal = true; - if (bp_site_sp) { - uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); - for (uint32_t i = 0; i < num_owners; i++) { - Breakpoint &bp_ref = - bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); - if (!bp_ref.IsInternal()) { - all_internal = false; - } - } - } - if (!all_internal) { - m_current_inlined_pc = curr_pc; - m_current_inlined_depth = 0; - break; - } - } - LLVM_FALLTHROUGH; - default: { - // Otherwise, we should set ourselves at the container of the - // inlining, so that the user can descend into them. So first - // we check whether we have more than one inlined block sharing - // this PC: - int num_inlined_functions = 0; - - for (Block *container_ptr = block_ptr->GetInlinedParent(); - container_ptr != nullptr; - container_ptr = container_ptr->GetInlinedParent()) { - if (!container_ptr->GetRangeContainingAddress( - pc_as_address, containing_range)) - break; - if (pc_as_address != containing_range.GetBaseAddress()) - break; - - num_inlined_functions++; - } - m_current_inlined_pc = curr_pc; - m_current_inlined_depth = num_inlined_functions + 1; - Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - if (log && log->GetVerbose()) - log->Printf("ResetCurrentInlinedDepth: setting inlined " - "depth: %d 0x%" PRIx64 ".\n", - m_current_inlined_depth, curr_pc); - - } break; - } - } - } + GetFramesUpTo(0); + if (m_frames.empty()) + return; + if (!m_frames[0]->IsInlined()) { + m_current_inlined_depth = UINT32_MAX; + m_current_inlined_pc = LLDB_INVALID_ADDRESS; + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + if (log && log->GetVerbose()) + log->Printf( + "ResetCurrentInlinedDepth: Invalidating current inlined depth.\n"); + return; + } + + // We only need to do something special about inlined blocks when we are + // at the beginning of an inlined function: + // FIXME: We probably also have to do something special if the PC is at + // the END of an inlined function, which coincides with the end of either + // its containing function or another inlined function. + + Block *block_ptr = m_frames[0]->GetFrameBlock(); + if (!block_ptr) + return; + + Address pc_as_address; + lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC(); + pc_as_address.SetLoadAddress(curr_pc, &(m_thread.GetProcess()->GetTarget())); + AddressRange containing_range; + if (!block_ptr->GetRangeContainingAddress(pc_as_address, containing_range) || + pc_as_address != containing_range.GetBaseAddress()) + return; + + // If we got here because of a breakpoint hit, then set the inlined depth + // depending on where the breakpoint was set. If we got here because of a + // crash, then set the inlined depth to the deepest most block. Otherwise, + // we stopped here naturally as the result of a step, so set ourselves in the + // containing frame of the whole set of nested inlines, so the user can then + // "virtually" step into the frames one by one, or next over the whole mess. + // Note: We don't have to handle being somewhere in the middle of the stack + // here, since ResetCurrentInlinedDepth doesn't get called if there is a + // valid inlined depth set. + StopInfoSP stop_info_sp = m_thread.GetStopInfo(); + if (!stop_info_sp) + return; + switch (stop_info_sp->GetStopReason()) { + case eStopReasonWatchpoint: + case eStopReasonException: + case eStopReasonExec: + case eStopReasonSignal: + // In all these cases we want to stop in the deepest frame. + m_current_inlined_pc = curr_pc; + m_current_inlined_depth = 0; + break; + case eStopReasonBreakpoint: { + // FIXME: Figure out what this break point is doing, and set the inline + // depth appropriately. Be careful to take into account breakpoints that + // implement step over prologue, since that should do the default + // calculation. For now, if the breakpoints corresponding to this hit are + // all internal, I set the stop location to the top of the inlined stack, + // since that will make things like stepping over prologues work right. + // But if there are any non-internal breakpoints I do to the bottom of the + // stack, since that was the old behavior. + uint32_t bp_site_id = stop_info_sp->GetValue(); + BreakpointSiteSP bp_site_sp( + m_thread.GetProcess()->GetBreakpointSiteList().FindByID(bp_site_id)); + bool all_internal = true; + if (bp_site_sp) { + uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); + for (uint32_t i = 0; i < num_owners; i++) { + Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); + if (!bp_ref.IsInternal()) { + all_internal = false; } } } + if (!all_internal) { + m_current_inlined_pc = curr_pc; + m_current_inlined_depth = 0; + break; + } + } + LLVM_FALLTHROUGH; + default: { + // Otherwise, we should set ourselves at the container of the inlining, so + // that the user can descend into them. So first we check whether we have + // more than one inlined block sharing this PC: + int num_inlined_functions = 0; + + for (Block *container_ptr = block_ptr->GetInlinedParent(); + container_ptr != nullptr; + container_ptr = container_ptr->GetInlinedParent()) { + if (!container_ptr->GetRangeContainingAddress(pc_as_address, + containing_range)) + break; + if (pc_as_address != containing_range.GetBaseAddress()) + break; + + num_inlined_functions++; + } + m_current_inlined_pc = curr_pc; + m_current_inlined_depth = num_inlined_functions + 1; + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + if (log && log->GetVerbose()) + log->Printf("ResetCurrentInlinedDepth: setting inlined " + "depth: %d 0x%" PRIx64 ".\n", + m_current_inlined_depth, curr_pc); + + break; + } } } From 3d5f18c03d7f141380ab18e65f2ea4468b278986 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Wed, 1 Aug 2018 17:08:11 +0000 Subject: [PATCH 0031/1112] [StackFrame] Add doxygen comments to the StackFrameList API (NFC) Clarify how StackFrameList works by documenting its methods. Also, delete some dead code and insert some TODOs. Differential Revision: https://reviews.llvm.org/D50087 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338590 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Target/StackFrameList.h | 60 ++++++++++++++++++++++++---- source/Target/StackFrameList.cpp | 20 +--------- 2 files changed, 53 insertions(+), 27 deletions(-) diff --git a/include/lldb/Target/StackFrameList.h b/include/lldb/Target/StackFrameList.h index 864d4b43aff6..9a745a23bd09 100644 --- a/include/lldb/Target/StackFrameList.h +++ b/include/lldb/Target/StackFrameList.h @@ -10,14 +10,10 @@ #ifndef liblldb_StackFrameList_h_ #define liblldb_StackFrameList_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/StackFrame.h" namespace lldb_private { @@ -32,22 +28,33 @@ class StackFrameList { ~StackFrameList(); + /// Get the number of visible frames. Frames may be created if \p can_create + /// is true. Synthetic (inline) frames expanded from the concrete frame #0 + /// (aka invisible frames) are not included in this count. uint32_t GetNumFrames(bool can_create = true); + /// Get the frame at index \p idx. Invisible frames cannot be indexed. lldb::StackFrameSP GetFrameAtIndex(uint32_t idx); + /// Get the first concrete frame with index greater than or equal to \p idx. + /// Unlike \ref GetFrameAtIndex, this cannot return a synthetic frame. lldb::StackFrameSP GetFrameWithConcreteFrameIndex(uint32_t unwind_idx); + /// Retrieve the stack frame with the given ID \p stack_id. lldb::StackFrameSP GetFrameWithStackID(const StackID &stack_id); - // Mark a stack frame as the current frame + /// Mark a stack frame as the currently selected frame and return its index. uint32_t SetSelectedFrame(lldb_private::StackFrame *frame); + /// Get the currently selected frame index. uint32_t GetSelectedFrameIndex() const; - // Mark a stack frame as the current frame using the frame index + /// Mark a stack frame as the currently selected frame using the frame index + /// \p idx. Like \ref GetFrameAtIndex, invisible frames cannot be selected. bool SetSelectedFrameByIndex(uint32_t idx); + /// If the current inline depth (i.e the number of invisible frames) is valid, + /// subtract it from \p idx. Otherwise simply return \p idx. uint32_t GetVisibleStackFrameIndex(uint32_t idx) { if (m_current_inlined_depth < UINT32_MAX) return idx - m_current_inlined_depth; @@ -55,16 +62,23 @@ class StackFrameList { return idx; } + /// Calculate and set the current inline depth. This may be used to update + /// the StackFrameList's set of inline frames when execution stops, e.g when + /// a breakpoint is hit. void CalculateCurrentInlinedDepth(); + /// If the currently selected frame comes from the currently selected thread, + /// point the default file and line of the thread's target to the location + /// specified by the frame. void SetDefaultFileAndLineToSelectedFrame(); + /// Clear the cache of frames. void Clear(); - void InvalidateFrames(uint32_t start_idx); - void Dump(Stream *s); + /// If \p stack_frame_ptr is contained in this StackFrameList, return its + /// wrapping shared pointer. lldb::StackFrameSP GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr); @@ -101,14 +115,44 @@ class StackFrameList { typedef collection::iterator iterator; typedef collection::const_iterator const_iterator; + /// The thread this frame list describes. Thread &m_thread; + + /// The old stack frame list. + // TODO: The old stack frame list is used to fill in missing frame info + // heuristically when it's otherwise unavailable (say, because the unwinder + // fails). We should have stronger checks to make sure that this is a valid + // source of information. lldb::StackFrameListSP m_prev_frames_sp; + + /// A mutex for this frame list. + // TODO: This mutex may not always be held when required. In particular, uses + // of the StackFrameList APIs in lldb_private::Thread look suspect. Consider + // passing around a lock_guard reference to enforce proper locking. mutable std::recursive_mutex m_mutex; + + /// A cache of frames. This may need to be updated when the program counter + /// changes. collection m_frames; + + /// The currently selected frame. uint32_t m_selected_frame_idx; + + /// The number of concrete frames fetched while filling the frame list. This + /// is only used when synthetic frames are enabled. uint32_t m_concrete_frames_fetched; + + /// The number of synthetic function activations (invisible frames) expanded + /// from the concrete frame #0 activation. + // TODO: Use an optional instead of UINT32_MAX to denote invalid values. uint32_t m_current_inlined_depth; + + /// The program counter value at the currently selected synthetic activation. + /// This is only valid if m_current_inlined_depth is valid. + // TODO: Use an optional instead of UINT32_MAX to denote invalid values. lldb::addr_t m_current_inlined_pc; + + /// Whether or not to show synthetic (inline) frames. Immutable. const bool m_show_inlined_frames; private: diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp index 5b989f73bd29..595e1aaa7d53 100644 --- a/source/Target/StackFrameList.cpp +++ b/source/Target/StackFrameList.cpp @@ -436,11 +436,7 @@ uint32_t StackFrameList::GetNumFrames(bool can_create) { if (can_create) GetFramesUpTo(UINT32_MAX); - uint32_t inlined_depth = GetCurrentInlinedDepth(); - if (inlined_depth == UINT32_MAX) - return m_frames.size(); - else - return m_frames.size() - inlined_depth; + return GetVisibleStackFrameIndex(m_frames.size()); } void StackFrameList::Dump(Stream *s) { @@ -620,7 +616,6 @@ uint32_t StackFrameList::SetSelectedFrame(lldb_private::StackFrame *frame) { return m_selected_frame_idx; } -// Mark a stack frame as the current frame using the frame index bool StackFrameList::SetSelectedFrameByIndex(uint32_t idx) { std::lock_guard guard(m_mutex); StackFrameSP frame_sp(GetFrameAtIndex(idx)); @@ -652,19 +647,6 @@ void StackFrameList::Clear() { m_concrete_frames_fetched = 0; } -void StackFrameList::InvalidateFrames(uint32_t start_idx) { - std::lock_guard guard(m_mutex); - if (m_show_inlined_frames) { - Clear(); - } else { - const size_t num_frames = m_frames.size(); - while (start_idx < num_frames) { - m_frames[start_idx].reset(); - ++start_idx; - } - } -} - void StackFrameList::Merge(std::unique_ptr &curr_ap, lldb::StackFrameListSP &prev_sp) { std::unique_lock current_lock, previous_lock; From 14b1250291f41d28c8d1d75b4a53d2ac96cd9010 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 1 Aug 2018 17:12:58 +0000 Subject: [PATCH 0032/1112] Don't ignore byte_order in Stream::PutMaxHex64 Reviewers: labath Reviewed By: labath Subscribers: zturner, lldb-commits Differential Revision: https://reviews.llvm.org/D50025 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338591 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Utility/Stream.cpp | 6 +++--- unittests/Utility/StreamTest.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/source/Utility/Stream.cpp b/source/Utility/Stream.cpp index 7df7f7008084..cd0f2f56e0f4 100644 --- a/source/Utility/Stream.cpp +++ b/source/Utility/Stream.cpp @@ -427,11 +427,11 @@ size_t Stream::PutMaxHex64(uint64_t uvalue, size_t byte_size, case 1: return PutHex8((uint8_t)uvalue); case 2: - return PutHex16((uint16_t)uvalue); + return PutHex16((uint16_t)uvalue, byte_order); case 4: - return PutHex32((uint32_t)uvalue); + return PutHex32((uint32_t)uvalue, byte_order); case 8: - return PutHex64(uvalue); + return PutHex64(uvalue, byte_order); } return 0; } diff --git a/unittests/Utility/StreamTest.cpp b/unittests/Utility/StreamTest.cpp index 2e30357bb292..bc77c1962164 100644 --- a/unittests/Utility/StreamTest.cpp +++ b/unittests/Utility/StreamTest.cpp @@ -187,6 +187,32 @@ TEST_F(StreamTest, PutHex64ByteOrderBig) { EXPECT_EQ("0000000000000000", TakeValue()); } +TEST_F(StreamTest, PutMaxHex64ByteOrderBig) { + std::size_t bytes; + bytes = s.PutMaxHex64(0x12U, 1, lldb::eByteOrderBig); + EXPECT_EQ(2U, bytes); + bytes = s.PutMaxHex64(0x1234U, 2, lldb::eByteOrderBig); + EXPECT_EQ(4U, bytes); + bytes = s.PutMaxHex64(0x12345678U, 4, lldb::eByteOrderBig); + EXPECT_EQ(8U, bytes); + bytes = s.PutMaxHex64(0x1234567890ABCDEFU, 8, lldb::eByteOrderBig); + EXPECT_EQ(16U, bytes); + EXPECT_EQ("121234123456781234567890abcdef", TakeValue()); +} + +TEST_F(StreamTest, PutMaxHex64ByteOrderLittle) { + std::size_t bytes; + bytes = s.PutMaxHex64(0x12U, 1, lldb::eByteOrderLittle); + EXPECT_EQ(2U, bytes); + bytes = s.PutMaxHex64(0x1234U, 2, lldb::eByteOrderLittle); + EXPECT_EQ(4U, bytes); + bytes = s.PutMaxHex64(0x12345678U, 4, lldb::eByteOrderLittle); + EXPECT_EQ(8U, bytes); + bytes = s.PutMaxHex64(0x1234567890ABCDEFU, 8, lldb::eByteOrderLittle); + EXPECT_EQ(16U, bytes); + EXPECT_EQ("12341278563412efcdab9078563412", TakeValue()); +} + //------------------------------------------------------------------------------ // Shift operator tests. //------------------------------------------------------------------------------ From 1c36a09b4a841ee2f1664c7609dc3470f7bdfbd3 Mon Sep 17 00:00:00 2001 From: Alex Langford Date: Wed, 1 Aug 2018 17:21:18 +0000 Subject: [PATCH 0033/1112] Introduce install-lldb-framework target Summary: Previously, I thought that install-liblldb would fail because CMake had a bug related to installing frameworks. In actuality, I misunderstood the semantics of `add_custom_target`: the DEPENDS option refers to specific files, not targets. Therefore `install-liblldb` should rely on the actual liblldb getting generated rather than the target. This means that the previous patch I committed (to stop relying on CMake's framework support) is no longer needed and has been reverted. Using CMake's framework support greatly simplifies the implementation. `install-lldb-framework` (and the stripped variant) is as simple as depending on `install-liblldb` because CMake knows that liblldb was built as a framework and will install the whole framework for you. The stripped variant will depend on the stripped variants of individual tools only to ensure they actually are stripped as well. Reviewers: labath, sas Subscribers: mgorny, lldb-commits Differential Revision: https://reviews.llvm.org/D50038 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338594 91177308-0d34-0410-b5e6-96231b3b80d8 --- CMakeLists.txt | 6 ++---- cmake/modules/AddLLDB.cmake | 19 ++++++++++++++++++- cmake/modules/LLDBFramework.cmake | 11 +++-------- source/API/CMakeLists.txt | 11 +++++++++++ 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 00ddcdc1488f..65cc86b09be0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,7 @@ if(LLDB_BUILD_FRAMEWORK) message(FATAL_ERROR "LLDB.framework can only be generated when targeting Apple platforms") endif() + add_custom_target(lldb-framework) # These are used to fill out LLDB-Info.plist. These are relevant when building # the framework, and must be defined before building liblldb. set(PRODUCT_NAME "LLDB") @@ -60,6 +61,7 @@ if(LLDB_BUILD_FRAMEWORK) set(LLDB_FRAMEWORK_DIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${LLDB_FRAMEWORK_INSTALL_DIR}) + include(LLDBFramework) endif() add_subdirectory(docs) @@ -162,10 +164,6 @@ if(LLDB_INCLUDE_TESTS) add_subdirectory(utils/lldb-dotest) endif() -if (LLDB_BUILD_FRAMEWORK) - add_custom_target(lldb-framework) - include(LLDBFramework) -endif() if (NOT LLDB_DISABLE_PYTHON) # Add a Post-Build Event to copy over Python files and create the symlink diff --git a/cmake/modules/AddLLDB.cmake b/cmake/modules/AddLLDB.cmake index 129a5ef7500d..f04df784385b 100644 --- a/cmake/modules/AddLLDB.cmake +++ b/cmake/modules/AddLLDB.cmake @@ -53,6 +53,11 @@ function(add_lldb_library name) set(out_dir lib${LLVM_LIBDIR_SUFFIX}) if(${name} STREQUAL "liblldb" AND LLDB_BUILD_FRAMEWORK) set(out_dir ${LLDB_FRAMEWORK_INSTALL_DIR}) + # The framework that is generated will install with install-liblldb + # because we enable CMake's framework support. CMake will copy all the + # headers and resources for us. + add_dependencies(install-lldb-framework install-${name}) + add_dependencies(install-lldb-framework-stripped install-${name}-stripped) endif() install(TARGETS ${name} COMPONENT ${name} @@ -67,12 +72,20 @@ function(add_lldb_library name) endif() if (NOT CMAKE_CONFIGURATION_TYPES) add_llvm_install_targets(install-${name} - DEPENDS ${name} + DEPENDS $ COMPONENT ${name}) + + # install-liblldb{,-stripped} is the actual target that will install the + # framework, so it must rely on the framework being fully built first. + if (LLDB_BUILD_FRAMEWORK AND ${name} STREQUAL "liblldb") + add_dependencies(install-${name} lldb-framework) + add_dependencies(install-lldb-framework-stripped lldb-framework) + endif() endif() endif() endif() + # Hack: only some LLDB libraries depend on the clang autogenerated headers, # but it is simple enough to make all of LLDB depend on some of those # headers without negatively impacting much of anything. @@ -124,6 +137,10 @@ function(add_lldb_executable name) set(out_dir "bin") if (LLDB_BUILD_FRAMEWORK AND ARG_INCLUDE_IN_SUITE) set(out_dir ${LLDB_FRAMEWORK_INSTALL_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR}) + # While install-liblldb-stripped will handle copying the tools, it will + # not strip them. We depend on this target to guarantee a stripped version + # will get installed in the framework. + add_dependencies(install-lldb-framework-stripped install-${name}-stripped) endif() install(TARGETS ${name} COMPONENT ${name} diff --git a/cmake/modules/LLDBFramework.cmake b/cmake/modules/LLDBFramework.cmake index abacee89d9ac..4186f6c02219 100644 --- a/cmake/modules/LLDBFramework.cmake +++ b/cmake/modules/LLDBFramework.cmake @@ -31,14 +31,9 @@ if (NOT IOS) ) endif() -set_target_properties(liblldb PROPERTIES - OUTPUT_NAME LLDB - FRAMEWORK On - FRAMEWORK_VERSION ${LLDB_FRAMEWORK_VERSION} - MACOSX_FRAMEWORK_INFO_PLIST ${LLDB_SOURCE_DIR}/resources/LLDB-Info.plist - LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LLDB_FRAMEWORK_INSTALL_DIR} - PUBLIC_HEADER "${framework_headers}") - add_dependencies(lldb-framework lldb-framework-headers lldb-suite) + +add_custom_target(install-lldb-framework) +add_custom_target(install-lldb-framework-stripped) diff --git a/source/API/CMakeLists.txt b/source/API/CMakeLists.txt index be9d4115cecc..fefab4bf84ff 100644 --- a/source/API/CMakeLists.txt +++ b/source/API/CMakeLists.txt @@ -143,6 +143,17 @@ else() ) endif() +if (LLDB_BUILD_FRAMEWORK) + set_target_properties(liblldb + PROPERTIES + OUTPUT_NAME LLDB + FRAMEWORK On + FRAMEWORK_VERSION ${LLDB_FRAMEWORK_VERSION} + MACOSX_FRAMEWORK_INFO_PLIST ${LLDB_SOURCE_DIR}/resources/LLDB-Info.plist + LIBRARY_OUTPUT_DIRECTORY ${LLDB_FRAMEWORK_DIR} + ) +endif() + if (LLDB_WRAP_PYTHON) add_dependencies(liblldb swig_wrapper) endif() From f220f9fb3f1f67d349e7ca91af3f3297bc29a1a6 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 1 Aug 2018 18:28:54 +0000 Subject: [PATCH 0034/1112] Remove outdated documentation for Stream's LEB128 methods There is no format parameter for any of these methods. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338605 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Utility/Stream.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/lldb/Utility/Stream.h b/include/lldb/Utility/Stream.h index 4930521d9497..74548c082c9c 100644 --- a/include/lldb/Utility/Stream.h +++ b/include/lldb/Utility/Stream.h @@ -504,9 +504,6 @@ class Stream { /// /// @param[in] uval /// A uint64_t value that was extracted as a SLEB128 value. - /// - /// @param[in] format - /// The optional printf format that can be overridden. //------------------------------------------------------------------ size_t PutSLEB128(int64_t uval); @@ -518,9 +515,6 @@ class Stream { /// /// @param[in] uval /// A uint64_t value that was extracted as a ULEB128 value. - /// - /// @param[in] format - /// The optional printf format that can be overridden. //------------------------------------------------------------------ size_t PutULEB128(uint64_t uval); From 63e23a1aa6ec8d6d4ef8e57743f0380371a89a0a Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 1 Aug 2018 18:38:19 +0000 Subject: [PATCH 0035/1112] Fixed documentation for PutHex8 [NFC] The previous documentation was just copied from PrintfAsRawHex8 but doesn't actually fit to the PutHex8 method. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338611 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Utility/Stream.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/include/lldb/Utility/Stream.h b/include/lldb/Utility/Stream.h index 74548c082c9c..24c69ba9f573 100644 --- a/include/lldb/Utility/Stream.h +++ b/include/lldb/Utility/Stream.h @@ -121,14 +121,10 @@ class Stream { __attribute__((__format__(__printf__, 2, 3))); //------------------------------------------------------------------ - /// Format a C string from a printf style format and variable arguments and - /// encode and append the resulting C string as hex bytes. + /// Append an uint8_t value in the hexadecimal format to the stream. /// - /// @param[in] format - /// A printf style format string. - /// - /// @param[in] ... - /// Any additional arguments needed for the printf format string. + /// @param[in] uvalue + /// The value to append. /// /// @return /// The number of bytes that were appended to the stream. From 79b345680aaf603242bcacca0f1abc17370b2337 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 1 Aug 2018 21:07:18 +0000 Subject: [PATCH 0036/1112] Fix out-of-bounds read in Stream::PutCStringAsRawHex8 Summary: When I added the Stream unit test (r338488), the build bots failed due to an out-of- bound reads when passing an empty string to the PutCStringAsRawHex8 method. In r338491 I removed the test case to fix the bots. This patch fixes this in PutCStringAsRawHex8 by always checking for the terminating null character in the given string (instead of skipping it the first time). It also re-adds the test case I removed. Reviewers: vsk Reviewed By: vsk Subscribers: vsk, lldb-commits Differential Revision: https://reviews.llvm.org/D50149 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338637 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Utility/Stream.cpp | 4 ++-- unittests/Utility/StreamTest.cpp | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/source/Utility/Stream.cpp b/source/Utility/Stream.cpp index cd0f2f56e0f4..d65ff0377913 100644 --- a/source/Utility/Stream.cpp +++ b/source/Utility/Stream.cpp @@ -518,10 +518,10 @@ size_t Stream::PutCStringAsRawHex8(const char *s) { size_t bytes_written = 0; bool binary_is_set = m_flags.Test(eBinary); m_flags.Clear(eBinary); - do { + while(*s) { bytes_written += _PutHex8(*s, false); ++s; - } while (*s); + } if (binary_is_set) m_flags.Set(eBinary); return bytes_written; diff --git a/unittests/Utility/StreamTest.cpp b/unittests/Utility/StreamTest.cpp index bc77c1962164..3210a6247f20 100644 --- a/unittests/Utility/StreamTest.cpp +++ b/unittests/Utility/StreamTest.cpp @@ -106,6 +106,9 @@ TEST_F(StreamTest, PutCharNull) { } TEST_F(StreamTest, PutCStringAsRawHex8) { + s.PutCStringAsRawHex8(""); + EXPECT_EQ("", TakeValue()); + s.PutCStringAsRawHex8("foobar"); EXPECT_EQ("666f6f626172", TakeValue()); From 455030db0cd630856ce11bf981d42a6b4a88ef44 Mon Sep 17 00:00:00 2001 From: Davide Italiano Date: Wed, 1 Aug 2018 21:13:45 +0000 Subject: [PATCH 0037/1112] [DWARFASTParser] Remove special cases for `llvm-gcc` Reviewed by: aprantl, labath. Differential Revision: https://reviews.llvm.org/D48500 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338638 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 29 ++----------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index fe6f1be3ca48..833cc66fb86c 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -307,14 +307,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, decl.SetColumn(form_value.Unsigned()); break; case DW_AT_name: - type_name_cstr = form_value.AsCString(); - // Work around a bug in llvm-gcc where they give a name to a - // reference type which doesn't include the "&"... - if (tag == DW_TAG_reference_type) { - if (strchr(type_name_cstr, '&') == NULL) - type_name_cstr = NULL; - } if (type_name_cstr) type_name_const_str.SetCString(type_name_cstr); break; @@ -558,16 +551,9 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, if (attributes.ExtractFormValueAtIndex(i, form_value)) { switch (attr) { case DW_AT_decl_file: - if (die.GetCU()->DW_AT_decl_file_attributes_are_invalid()) { - // llvm-gcc outputs invalid DW_AT_decl_file attributes that - // always point to the compile unit file, so we clear this - // invalid value so that we can still unique types - // efficiently. - decl.SetFile(FileSpec("", false)); - } else - decl.SetFile( - sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( - form_value.Unsigned())); + decl.SetFile( + sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( + form_value.Unsigned())); break; case DW_AT_decl_line: @@ -2977,15 +2963,6 @@ bool DWARFASTParserClang::ParseChildMembers( class_language == eLanguageTypeObjC_plus_plus) accessibility = eAccessNone; - if (member_idx == 0 && !is_artificial && name && - (strstr(name, "_vptr$") == name)) { - // Not all compilers will mark the vtable pointer member as - // artificial (llvm-gcc). We can't have the virtual members in our - // classes otherwise it throws off all child offsets since we end up - // having and extra pointer sized member in our class layouts. - is_artificial = true; - } - // Handle static members if (is_external && member_byte_offset == UINT32_MAX) { Type *var_type = die.ResolveTypeUID(DIERef(encoding_form)); From 15d3f751cfcae4b96eea7604600cbb1f2097c5a6 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Wed, 1 Aug 2018 23:54:37 +0000 Subject: [PATCH 0038/1112] Remove unnecessary target from TestCompletion patch As Jim pointed out, we don't need to manually create a target here because we already create a target implicitly in the very next line (which means we just created a target and don't use it). This patch just removes the line that creates the first unused target. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338657 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../lldbsuite/test/functionalities/completion/TestCompletion.py | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py b/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py index 5d4fcf64511b..5971e5a673d2 100644 --- a/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py +++ b/packages/Python/lldbsuite/test/functionalities/completion/TestCompletion.py @@ -43,7 +43,6 @@ def test_frame_variable(self): self.build() self.main_source = "main.cpp" self.main_source_spec = lldb.SBFileSpec(self.main_source) - self.dbg.CreateTarget(self.getBuildArtifact("a.out")) (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, '// Break here', self.main_source_spec) From 8f45657180f58b8151cd46a263ed22527669fe38 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 2 Aug 2018 00:30:15 +0000 Subject: [PATCH 0039/1112] [LLDB] Added syntax highlighting support Summary: This patch adds syntax highlighting support to LLDB. When enabled (and lldb is allowed to use colors), printed source code is annotated with the ANSI color escape sequences. So far we have only one highlighter which is based on Clang and is responsible for all languages that are supported by Clang. It essentially just runs the raw lexer over the input and then surrounds the specific tokens with the configured escape sequences. Reviewers: zturner, davide Reviewed By: davide Subscribers: labath, teemperor, llvm-commits, mgorny, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D49334 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338662 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Core/Debugger.h | 2 + include/lldb/Core/Highlighter.h | 159 ++++++++++++ include/lldb/Target/Language.h | 12 + .../test/source-manager/TestSourceManager.py | 29 ++- source/Core/CMakeLists.txt | 1 + source/Core/Debugger.cpp | 9 + source/Core/Highlighter.cpp | 68 ++++++ source/Core/SourceManager.cpp | 45 +++- source/Plugins/Language/CMakeLists.txt | 1 + .../Plugins/Language/CPlusPlus/CMakeLists.txt | 2 + .../Language/CPlusPlus/CPlusPlusLanguage.cpp | 13 + .../Language/CPlusPlus/CPlusPlusLanguage.h | 7 + .../Language/ClangCommon/CMakeLists.txt | 9 + .../Language/ClangCommon/ClangHighlighter.cpp | 227 ++++++++++++++++++ .../Language/ClangCommon/ClangHighlighter.h | 42 ++++ source/Plugins/Language/Go/GoLanguage.cpp | 4 + source/Plugins/Language/Go/GoLanguage.h | 2 + source/Plugins/Language/Java/JavaLanguage.cpp | 4 + source/Plugins/Language/Java/JavaLanguage.h | 2 + .../Plugins/Language/OCaml/OCamlLanguage.cpp | 9 + source/Plugins/Language/OCaml/OCamlLanguage.h | 2 + source/Plugins/Language/ObjC/CMakeLists.txt | 1 + source/Plugins/Language/ObjC/ObjCLanguage.cpp | 9 + source/Plugins/Language/ObjC/ObjCLanguage.h | 7 + .../Language/ObjCPlusPlus/CMakeLists.txt | 3 +- .../ObjCPlusPlus/ObjCPlusPlusLanguage.cpp | 9 + .../ObjCPlusPlus/ObjCPlusPlusLanguage.h | 7 + source/Target/Language.cpp | 32 +++ unittests/Language/CMakeLists.txt | 1 + .../Language/Highlighting/CMakeLists.txt | 11 + .../Language/Highlighting/HighlighterTest.cpp | 221 +++++++++++++++++ 31 files changed, 942 insertions(+), 8 deletions(-) create mode 100644 include/lldb/Core/Highlighter.h create mode 100644 source/Core/Highlighter.cpp create mode 100644 source/Plugins/Language/ClangCommon/CMakeLists.txt create mode 100644 source/Plugins/Language/ClangCommon/ClangHighlighter.cpp create mode 100644 source/Plugins/Language/ClangCommon/ClangHighlighter.h create mode 100644 unittests/Language/Highlighting/CMakeLists.txt create mode 100644 unittests/Language/Highlighting/HighlighterTest.cpp diff --git a/include/lldb/Core/Debugger.h b/include/lldb/Core/Debugger.h index cc7176e5c95d..fc84b13efbb0 100644 --- a/include/lldb/Core/Debugger.h +++ b/include/lldb/Core/Debugger.h @@ -272,6 +272,8 @@ class Debugger : public std::enable_shared_from_this, bool SetUseColor(bool use_color); + bool GetHighlightSource() const; + lldb::StopShowColumn GetStopShowColumn() const; const FormatEntity::Entry *GetStopShowColumnAnsiPrefix() const; diff --git a/include/lldb/Core/Highlighter.h b/include/lldb/Core/Highlighter.h new file mode 100644 index 000000000000..55ec3ff5a6bc --- /dev/null +++ b/include/lldb/Core/Highlighter.h @@ -0,0 +1,159 @@ +//===-- Highlighter.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Highlighter_h_ +#define liblldb_Highlighter_h_ + +#include +#include + +#include "lldb/Utility/Stream.h" +#include "lldb/lldb-enumerations.h" +#include "llvm/ADT/StringRef.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// Represents style that the highlighter should apply to the given source code. +/// Stores information about how every kind of token should be annotated. +//---------------------------------------------------------------------- +struct HighlightStyle { + + //---------------------------------------------------------------------- + /// A pair of strings that should be placed around a certain token. Usually + /// stores color codes in these strings (the suffix string is often used for + /// resetting the terminal attributes back to normal). + //---------------------------------------------------------------------- + class ColorStyle { + std::string m_prefix; + std::string m_suffix; + + public: + ColorStyle() = default; + ColorStyle(llvm::StringRef prefix, llvm::StringRef suffix) { + Set(prefix, suffix); + } + + /// Applies this style to the given value. + /// \param s + /// The stream to which the result should be appended. + /// \param value + /// The value that we should place our strings around. + /// \return + /// The number of bytes that have been written to the given stream. + std::size_t Apply(Stream &s, llvm::StringRef value) const; + + /// Sets the prefix and suffix strings. + /// @param prefix + /// @param suffix + void Set(llvm::StringRef prefix, llvm::StringRef suffix); + }; + + /// Matches identifiers to variable or functions. + ColorStyle identifier; + /// Matches any string or character literals in the language: "foo" or 'f' + ColorStyle string_literal; + /// Matches scalar value literals like '42' or '0.1'. + ColorStyle scalar_literal; + /// Matches all reserved keywords in the language. + ColorStyle keyword; + /// Matches any comments in the language. + ColorStyle comment; + /// Matches commas: ',' + ColorStyle comma; + /// Matches one colon: ':' + ColorStyle colon; + /// Matches any semicolon: ';' + ColorStyle semicolons; + /// Matches operators like '+', '-', '%', '&', '=' + ColorStyle operators; + + /// Matches '{' or '}' + ColorStyle braces; + /// Matches '[' or ']' + ColorStyle square_brackets; + /// Matches '(' or ')' + ColorStyle parentheses; + + //----------------------------------------------------------------------- + // C language specific options + //----------------------------------------------------------------------- + + /// Matches directives to a preprocessor (if the language has any). + ColorStyle pp_directive; + + /// Returns a HighlightStyle that is based on vim's default highlight style. + static HighlightStyle MakeVimStyle(); +}; + +//---------------------------------------------------------------------- +/// Annotates source code with color attributes. +//---------------------------------------------------------------------- +class Highlighter { +public: + Highlighter() = default; + virtual ~Highlighter() = default; + DISALLOW_COPY_AND_ASSIGN(Highlighter); + + /// Returns a human readable name for the selected highlighter. + virtual llvm::StringRef GetName() const = 0; + + /// Highlights the given line + /// \param options + /// \param line + /// The user supplied line that needs to be highlighted. + /// \param previous_lines + /// Any previous lines the user has written which we should only use + /// for getting the context of the Highlighting right. + /// \param s + /// The stream to which the highlighted version of the user string should + /// be written. + /// \return + /// The number of bytes that have been written to the stream. + virtual std::size_t Highlight(const HighlightStyle &options, + llvm::StringRef line, + llvm::StringRef previous_lines, + Stream &s) const = 0; + + /// Utility method for calling Highlight without a stream. + std::string Highlight(const HighlightStyle &options, llvm::StringRef line, + llvm::StringRef previous_lines = "") const; +}; + +/// A default highlighter that does nothing. Used as a fallback. +class NoHighlighter : public Highlighter { +public: + llvm::StringRef GetName() const override { return "none"; } + + std::size_t Highlight(const HighlightStyle &options, llvm::StringRef line, + llvm::StringRef previous_lines, + Stream &s) const override; +}; + +/// Manages the available highlighters. +class HighlighterManager { + NoHighlighter m_no_highlighter; + +public: + /// Queries all known highlighter for one that can highlight some source code. + /// \param language_type + /// The language type that the caller thinks the source code was given in. + /// \param path + /// The path to the file the source code is from. Used as a fallback when + /// the user can't provide a language. + /// \return + /// The highlighter that wants to highlight the source code. Could be an + /// empty highlighter that does nothing. + const Highlighter &getHighlighterFor(lldb::LanguageType language_type, + llvm::StringRef path) const; +}; + +} // namespace lldb_private + +#endif // liblldb_Highlighter_h_ diff --git a/include/lldb/Target/Language.h b/include/lldb/Target/Language.h index dd7db26f3ba6..f3f8acd85f7e 100644 --- a/include/lldb/Target/Language.h +++ b/include/lldb/Target/Language.h @@ -20,6 +20,7 @@ // Other libraries and framework includes // Project includes +#include "lldb/Core/Highlighter.h" #include "lldb/Core/PluginInterface.h" #include "lldb/DataFormatters/DumpValueObjectOptions.h" #include "lldb/DataFormatters/FormatClasses.h" @@ -152,6 +153,13 @@ class Language : public PluginInterface { static Language *FindPlugin(lldb::LanguageType language); + /// Returns the Language associated with the given file path or a nullptr + /// if there is no known language. + static Language *FindPlugin(llvm::StringRef file_path); + + static Language *FindPlugin(lldb::LanguageType language, + llvm::StringRef file_path); + // return false from callback to stop iterating static void ForEach(std::function callback); @@ -159,6 +167,10 @@ class Language : public PluginInterface { virtual bool IsTopLevelFunction(Function &function); + virtual bool IsSourceFile(llvm::StringRef file_path) const = 0; + + virtual const Highlighter *GetHighlighter() const { return nullptr; } + virtual lldb::TypeCategoryImplSP GetFormatters(); virtual HardcodedFormatters::HardcodedFormatFinder GetHardcodedFormats(); diff --git a/packages/Python/lldbsuite/test/source-manager/TestSourceManager.py b/packages/Python/lldbsuite/test/source-manager/TestSourceManager.py index 0df4f8b2d2a8..dc43cd0815ae 100644 --- a/packages/Python/lldbsuite/test/source-manager/TestSourceManager.py +++ b/packages/Python/lldbsuite/test/source-manager/TestSourceManager.py @@ -22,6 +22,8 @@ def ansi_underline_surround_regex(inner_regex_text): # return re.compile(r"\[4m%s\[0m" % inner_regex_text) return "4.+\033\\[4m%s\033\\[0m" % inner_regex_text +def ansi_color_surround_regex(inner_regex_text): + return "\033\\[3[0-7]m%s\033\\[0m" % inner_regex_text class SourceManagerTestCase(TestBase): @@ -47,7 +49,7 @@ def get_expected_stop_column_number(self): # the character column after the initial whitespace. return len(stop_line) - len(stop_line.lstrip()) + 1 - def do_display_source_python_api(self, use_color, column_marker_regex): + def do_display_source_python_api(self, use_color, needle_regex, highlight_source=False): self.build() exe = self.getBuildArtifact("a.out") self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) @@ -69,6 +71,9 @@ def do_display_source_python_api(self, use_color, column_marker_regex): # Setup whether we should use ansi escape sequences, including color # and styles such as underline. self.dbg.SetUseColor(use_color) + # Disable syntax highlighting if needed. + + self.runCmd("settings set highlight-source " + str(highlight_source).lower()) filespec = lldb.SBFileSpec(self.file, False) source_mgr = self.dbg.GetSourceManager() @@ -87,10 +92,10 @@ def do_display_source_python_api(self, use_color, column_marker_regex): # => 4 printf("Hello world.\n"); // Set break point at this line. # 5 return 0; # 6 } - self.expect(stream.GetData(), "Source code displayed correctly", + self.expect(stream.GetData(), "Source code displayed correctly:\n" + stream.GetData(), exe=False, patterns=['=> %d.*Hello world' % self.line, - column_marker_regex]) + needle_regex]) # Boundary condition testings for SBStream(). LLDB should not crash! stream.Print(None) @@ -111,6 +116,24 @@ def test_display_source_python_ansi_terminal(self): underline_regex = ansi_underline_surround_regex(r".") self.do_display_source_python_api(use_color, underline_regex) + @add_test_categories(['pyapi']) + def test_display_source_python_ansi_terminal_syntax_highlighting(self): + """Test display of source using the SBSourceManager API and check for + the syntax highlighted output""" + use_color = True + syntax_highlighting = True; + + # Just pick 'int' as something that should be colored. + color_regex = ansi_color_surround_regex("int") + self.do_display_source_python_api(use_color, color_regex, syntax_highlighting) + + # Same for 'char'. + color_regex = ansi_color_surround_regex("char") + self.do_display_source_python_api(use_color, color_regex, syntax_highlighting) + + # Test that we didn't color unrelated identifiers. + self.do_display_source_python_api(use_color, r" printf\(", syntax_highlighting) + def test_move_and_then_display_source(self): """Test that target.source-map settings work by moving main.c to hidden/main.c.""" self.build() diff --git a/source/Core/CMakeLists.txt b/source/Core/CMakeLists.txt index 927a0dcc2ec1..bae5b499f449 100644 --- a/source/Core/CMakeLists.txt +++ b/source/Core/CMakeLists.txt @@ -25,6 +25,7 @@ add_lldb_library(lldbCore FileLineResolver.cpp FileSpecList.cpp FormatEntity.cpp + Highlighter.cpp IOHandler.cpp Listener.cpp Mangled.cpp diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp index 972d0bc0a6d7..b29f3565e03e 100644 --- a/source/Core/Debugger.cpp +++ b/source/Core/Debugger.cpp @@ -233,6 +233,8 @@ static PropertyDefinition g_properties[] = { nullptr, "The number of sources lines to display that come before the " "current source line when displaying a stopped context."}, + {"highlight-source", OptionValue::eTypeBoolean, true, true, nullptr, + nullptr, "If true, LLDB will highlight the displayed source code."}, {"stop-show-column", OptionValue::eTypeEnum, false, eStopShowColumnAnsiOrCaret, nullptr, s_stop_show_column_values, "If true, LLDB will use the column information from the debug info to " @@ -296,6 +298,7 @@ enum { ePropertyStopDisassemblyDisplay, ePropertyStopLineCountAfter, ePropertyStopLineCountBefore, + ePropertyHighlightSource, ePropertyStopShowColumn, ePropertyStopShowColumnAnsiPrefix, ePropertyStopShowColumnAnsiSuffix, @@ -470,6 +473,12 @@ bool Debugger::SetUseColor(bool b) { return ret; } +bool Debugger::GetHighlightSource() const { + const uint32_t idx = ePropertyHighlightSource; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_properties[idx].default_uint_value); +} + StopShowColumn Debugger::GetStopShowColumn() const { const uint32_t idx = ePropertyStopShowColumn; return (lldb::StopShowColumn)m_collection_sp->GetPropertyAtIndexAsEnumeration( diff --git a/source/Core/Highlighter.cpp b/source/Core/Highlighter.cpp new file mode 100644 index 000000000000..2ef99c800b13 --- /dev/null +++ b/source/Core/Highlighter.cpp @@ -0,0 +1,68 @@ +//===-- Highlighter.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/Highlighter.h" + +#include "lldb/Target/Language.h" +#include "lldb/Utility/AnsiTerminal.h" +#include "lldb/Utility/StreamString.h" + +using namespace lldb_private; + +std::size_t HighlightStyle::ColorStyle::Apply(Stream &s, + llvm::StringRef value) const { + s << m_prefix << value << m_suffix; + // Calculate how many bytes we have written. + return m_prefix.size() + value.size() + m_suffix.size(); +} + +void HighlightStyle::ColorStyle::Set(llvm::StringRef prefix, + llvm::StringRef suffix) { + m_prefix = lldb_utility::ansi::FormatAnsiTerminalCodes(prefix); + m_suffix = lldb_utility::ansi::FormatAnsiTerminalCodes(suffix); +} + +std::size_t NoHighlighter::Highlight(const HighlightStyle &options, + llvm::StringRef line, + llvm::StringRef previous_lines, + Stream &s) const { + // We just forward the input to the output and do no highlighting. + s << line; + return line.size(); +} + +static HighlightStyle::ColorStyle GetColor(const char *c) { + return HighlightStyle::ColorStyle(c, "${ansi.normal}"); +} + +HighlightStyle HighlightStyle::MakeVimStyle() { + HighlightStyle result; + result.comment = GetColor("${ansi.fg.purple}"); + result.scalar_literal = GetColor("${ansi.fg.red}"); + result.keyword = GetColor("${ansi.fg.green}"); + return result; +} + +const Highlighter & +HighlighterManager::getHighlighterFor(lldb::LanguageType language_type, + llvm::StringRef path) const { + Language *language = lldb_private::Language::FindPlugin(language_type, path); + if (language && language->GetHighlighter()) + return *language->GetHighlighter(); + return m_no_highlighter; +} + +std::string Highlighter::Highlight(const HighlightStyle &options, + llvm::StringRef line, + llvm::StringRef previous_lines) const { + StreamString s; + Highlight(options, line, previous_lines, s); + s.Flush(); + return s.GetString().str(); +} diff --git a/source/Core/SourceManager.cpp b/source/Core/SourceManager.cpp index a6afd64f3054..0ae1d9b9f0d9 100644 --- a/source/Core/SourceManager.cpp +++ b/source/Core/SourceManager.cpp @@ -13,6 +13,7 @@ #include "lldb/Core/AddressRange.h" // for AddressRange #include "lldb/Core/Debugger.h" #include "lldb/Core/FormatEntity.h" // for FormatEntity +#include "lldb/Core/Highlighter.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" // for ModuleList #include "lldb/Host/FileSystem.h" @@ -103,6 +104,18 @@ SourceManager::FileSP SourceManager::GetFile(const FileSpec &file_spec) { return file_sp; } +static bool should_highlight_source(DebuggerSP debugger_sp) { + if (!debugger_sp) + return false; + + // We don't use ANSI stop column formatting if the debugger doesn't think it + // should be using color. + if (!debugger_sp->GetUseColor()) + return false; + + return debugger_sp->GetHighlightSource(); +} + static bool should_show_stop_column_with_ansi(DebuggerSP debugger_sp) { // We don't use ANSI stop column formatting if we can't lookup values from // the debugger. @@ -114,6 +127,11 @@ static bool should_show_stop_column_with_ansi(DebuggerSP debugger_sp) { if (!debugger_sp->GetUseColor()) return false; + // Don't use terminal attributes when we have highlighting enabled. This + // can mess up the command line. + if (debugger_sp->GetHighlightSource()) + return false; + // We only use ANSI stop column formatting if we're either supposed to show // ANSI where available (which we know we have when we get to this point), or // if we're only supposed to use ANSI. @@ -515,6 +533,16 @@ size_t SourceManager::File::DisplaySourceLines(uint32_t line, uint32_t column, if (!m_data_sp) return 0; + std::string previous_content; + + HighlightStyle style = HighlightStyle::MakeVimStyle(); + HighlighterManager mgr; + std::string path = GetFileSpec().GetPath(/*denormalize*/ false); + // FIXME: Find a way to get the definitive language this file was written in + // and pass it to the highlighter. + auto &highlighter = + mgr.getHighlighterFor(lldb::LanguageType::eLanguageTypeUnknown, path); + const uint32_t start_line = line <= context_before ? 1 : line - context_before; const uint32_t start_line_offset = GetLineOffset(start_line); @@ -530,10 +558,19 @@ size_t SourceManager::File::DisplaySourceLines(uint32_t line, uint32_t column, size_t count = end_line_offset - start_line_offset; const uint8_t *cstr = m_data_sp->GetBytes() + start_line_offset; + auto ref = llvm::StringRef(reinterpret_cast(cstr), count); bool displayed_line = false; - if (column && (column < count)) { - auto debugger_sp = m_debugger_wp.lock(); + auto debugger_sp = m_debugger_wp.lock(); + if (should_highlight_source(debugger_sp)) { + bytes_written += + highlighter.Highlight(style, ref, previous_content, *s); + displayed_line = true; + // Add the new line to the previous lines. + previous_content += ref.str(); + } + + if (!displayed_line && column && (column < count)) { if (should_show_stop_column_with_ansi(debugger_sp) && debugger_sp) { // Check if we have any ANSI codes with which to mark this column. If // not, no need to do this work. @@ -581,10 +618,10 @@ size_t SourceManager::File::DisplaySourceLines(uint32_t line, uint32_t column, // If we didn't end up displaying the line with ANSI codes for whatever // reason, display it now sans codes. if (!displayed_line) - bytes_written = s->Write(cstr, count); + bytes_written = s->PutCString(ref); // Ensure we get an end of line character one way or another. - if (!is_newline_char(cstr[count - 1])) + if (!is_newline_char(ref.back())) bytes_written += s->EOL(); } return bytes_written; diff --git a/source/Plugins/Language/CMakeLists.txt b/source/Plugins/Language/CMakeLists.txt index 4b92a8ef866b..723cf13a08a4 100644 --- a/source/Plugins/Language/CMakeLists.txt +++ b/source/Plugins/Language/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(ClangCommon) add_subdirectory(CPlusPlus) add_subdirectory(Go) add_subdirectory(Java) diff --git a/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/source/Plugins/Language/CPlusPlus/CMakeLists.txt index 180440a244a4..e7faee84988b 100644 --- a/source/Plugins/Language/CPlusPlus/CMakeLists.txt +++ b/source/Plugins/Language/CPlusPlus/CMakeLists.txt @@ -24,6 +24,8 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN lldbSymbol lldbTarget lldbUtility + lldbPluginClangCommon + LINK_COMPONENTS Support ) diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 2c63e6467d4c..9df8853f4553 100644 --- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -1002,3 +1002,16 @@ CPlusPlusLanguage::GetHardcodedSynthetics() { return g_formatters; } + +bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const { + const auto suffixes = {".cpp", ".cxx", ".c++", ".cc", ".c", + ".h", ".hh", ".hpp", ".hxx", ".h++"}; + for (auto suffix : suffixes) { + if (file_path.endswith_lower(suffix)) + return true; + } + + // Check if we're in a STL path (where the files usually have no extension + // that we could check for. + return file_path.contains("/usr/include/c++/"); +} diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h index 7380ef321305..505ebb2fa9ea 100644 --- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h @@ -19,6 +19,7 @@ #include "llvm/ADT/StringRef.h" // Project includes +#include "Plugins/Language/ClangCommon/ClangHighlighter.h" #include "lldb/Target/Language.h" #include "lldb/Utility/ConstString.h" #include "lldb/lldb-private.h" @@ -26,6 +27,8 @@ namespace lldb_private { class CPlusPlusLanguage : public Language { + ClangHighlighter m_highlighter; + public: class MethodName { public: @@ -90,6 +93,10 @@ class CPlusPlusLanguage : public Language { HardcodedFormatters::HardcodedSyntheticFinder GetHardcodedSynthetics() override; + bool IsSourceFile(llvm::StringRef file_path) const override; + + const Highlighter *GetHighlighter() const override { return &m_highlighter; } + //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ diff --git a/source/Plugins/Language/ClangCommon/CMakeLists.txt b/source/Plugins/Language/ClangCommon/CMakeLists.txt new file mode 100644 index 000000000000..854320dd312e --- /dev/null +++ b/source/Plugins/Language/ClangCommon/CMakeLists.txt @@ -0,0 +1,9 @@ +add_lldb_library(lldbPluginClangCommon PLUGIN + ClangHighlighter.cpp + + LINK_LIBS + lldbCore + lldbUtility + LINK_COMPONENTS + Support +) diff --git a/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp b/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp new file mode 100644 index 000000000000..29da03d71dd4 --- /dev/null +++ b/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp @@ -0,0 +1,227 @@ +//===-- ClangHighlighter.cpp ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ClangHighlighter.h" + +#include "lldb/Target/Language.h" +#include "lldb/Utility/AnsiTerminal.h" +#include "lldb/Utility/StreamString.h" + +#include "clang/Basic/SourceManager.h" +#include "clang/Lex/Lexer.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/Support/MemoryBuffer.h" + +using namespace lldb_private; + +bool ClangHighlighter::isKeyword(llvm::StringRef token) const { + return keywords.find(token) != keywords.end(); +} + +ClangHighlighter::ClangHighlighter() { +#define KEYWORD(X, N) keywords.insert(#X); +#include "clang/Basic/TokenKinds.def" +} + +/// Determines which style should be applied to the given token. +/// \param highlighter +/// The current highlighter that should use the style. +/// \param token +/// The current token. +/// \param tok_str +/// The string in the source code the token represents. +/// \param options +/// The style we use for coloring the source code. +/// \param in_pp_directive +/// If we are currently in a preprocessor directive. NOTE: This is +/// passed by reference and will be updated if the current token starts +/// or ends a preprocessor directive. +/// \return +/// The ColorStyle that should be applied to the token. +static HighlightStyle::ColorStyle +determineClangStyle(const ClangHighlighter &highlighter, + const clang::Token &token, llvm::StringRef tok_str, + const HighlightStyle &options, bool &in_pp_directive) { + using namespace clang; + + if (token.is(tok::comment)) { + // If we were in a preprocessor directive before, we now left it. + in_pp_directive = false; + return options.comment; + } else if (in_pp_directive || token.getKind() == tok::hash) { + // Let's assume that the rest of the line is a PP directive. + in_pp_directive = true; + // Preprocessor directives are hard to match, so we have to hack this in. + return options.pp_directive; + } else if (tok::isStringLiteral(token.getKind())) + return options.string_literal; + else if (tok::isLiteral(token.getKind())) + return options.scalar_literal; + else if (highlighter.isKeyword(tok_str)) + return options.keyword; + else + switch (token.getKind()) { + case tok::raw_identifier: + case tok::identifier: + return options.identifier; + case tok::l_brace: + case tok::r_brace: + return options.braces; + case tok::l_square: + case tok::r_square: + return options.square_brackets; + case tok::l_paren: + case tok::r_paren: + return options.parentheses; + case tok::comma: + return options.comma; + case tok::coloncolon: + case tok::colon: + return options.colon; + + case tok::amp: + case tok::ampamp: + case tok::ampequal: + case tok::star: + case tok::starequal: + case tok::plus: + case tok::plusplus: + case tok::plusequal: + case tok::minus: + case tok::arrow: + case tok::minusminus: + case tok::minusequal: + case tok::tilde: + case tok::exclaim: + case tok::exclaimequal: + case tok::slash: + case tok::slashequal: + case tok::percent: + case tok::percentequal: + case tok::less: + case tok::lessless: + case tok::lessequal: + case tok::lesslessequal: + case tok::spaceship: + case tok::greater: + case tok::greatergreater: + case tok::greaterequal: + case tok::greatergreaterequal: + case tok::caret: + case tok::caretequal: + case tok::pipe: + case tok::pipepipe: + case tok::pipeequal: + case tok::question: + case tok::equal: + case tok::equalequal: + return options.operators; + default: + break; + } + return HighlightStyle::ColorStyle(); +} + +std::size_t ClangHighlighter::Highlight(const HighlightStyle &options, + llvm::StringRef line, + llvm::StringRef previous_lines, + Stream &result) const { + using namespace clang; + + std::size_t written_bytes = 0; + + FileSystemOptions file_opts; + FileManager file_mgr(file_opts); + + unsigned line_number = previous_lines.count('\n') + 1U; + + // Let's build the actual source code Clang needs and setup some utility + // objects. + std::string full_source = previous_lines.str() + line.str(); + llvm::IntrusiveRefCntPtr diag_ids(new DiagnosticIDs()); + llvm::IntrusiveRefCntPtr diags_opts( + new DiagnosticOptions()); + DiagnosticsEngine diags(diag_ids, diags_opts); + clang::SourceManager SM(diags, file_mgr); + auto buf = llvm::MemoryBuffer::getMemBuffer(full_source); + + FileID FID = SM.createFileID(clang::SourceManager::Unowned, buf.get()); + + // Let's just enable the latest ObjC and C++ which should get most tokens + // right. + LangOptions Opts; + Opts.ObjC2 = true; + Opts.CPlusPlus17 = true; + Opts.LineComment = true; + + Lexer lex(FID, buf.get(), SM, Opts); + // The lexer should keep whitespace around. + lex.SetKeepWhitespaceMode(true); + + // Keeps track if we have entered a PP directive. + bool in_pp_directive = false; + + // True once we actually lexed the user provided line. + bool found_user_line = false; + + Token token; + bool exit = false; + while (!exit) { + // Returns true if this is the last token we get from the lexer. + exit = lex.LexFromRawLexer(token); + + bool invalid = false; + unsigned current_line_number = + SM.getSpellingLineNumber(token.getLocation(), &invalid); + if (current_line_number != line_number) + continue; + found_user_line = true; + + // We don't need to print any tokens without a spelling line number. + if (invalid) + continue; + + // Same as above but with the column number. + invalid = false; + unsigned start = SM.getSpellingColumnNumber(token.getLocation(), &invalid); + if (invalid) + continue; + // Column numbers start at 1, but indexes in our string start at 0. + --start; + + // Annotations don't have a length, so let's skip them. + if (token.isAnnotation()) + continue; + + // Extract the token string from our source code. + llvm::StringRef tok_str = line.substr(start, token.getLength()); + + // If the token is just an empty string, we can skip all the work below. + if (tok_str.empty()) + continue; + + // See how we are supposed to highlight this token. + HighlightStyle::ColorStyle color = + determineClangStyle(*this, token, tok_str, options, in_pp_directive); + + written_bytes += color.Apply(result, tok_str); + } + + // If we went over the whole file but couldn't find our own file, then + // somehow our setup was wrong. When we're in release mode we just give the + // user the normal line and pretend we don't know how to highlight it. In + // debug mode we bail out with an assert as this should never happen. + if (!found_user_line) { + result << line; + written_bytes += line.size(); + assert(false && "We couldn't find the user line in the input file?"); + } + + return written_bytes; +} diff --git a/source/Plugins/Language/ClangCommon/ClangHighlighter.h b/source/Plugins/Language/ClangCommon/ClangHighlighter.h new file mode 100644 index 000000000000..4eb239b291b3 --- /dev/null +++ b/source/Plugins/Language/ClangCommon/ClangHighlighter.h @@ -0,0 +1,42 @@ +//===-- ClangHighlighter.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangHighlighter_h_ +#define liblldb_ClangHighlighter_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +#include "lldb/Utility/Stream.h" +#include "llvm/ADT/StringSet.h" + +// Project includes +#include "lldb/Core/Highlighter.h" + +namespace lldb_private { + +class ClangHighlighter : public Highlighter { + llvm::StringSet<> keywords; + +public: + ClangHighlighter(); + llvm::StringRef GetName() const override { return "clang"; } + + std::size_t Highlight(const HighlightStyle &options, llvm::StringRef line, + llvm::StringRef previous_lines, + Stream &s) const override; + + /// Returns true if the given string represents a keywords in any Clang + /// supported language. + bool isKeyword(llvm::StringRef token) const; +}; + +} // namespace lldb_private + +#endif // liblldb_ClangHighlighter_h_ diff --git a/source/Plugins/Language/Go/GoLanguage.cpp b/source/Plugins/Language/Go/GoLanguage.cpp index 66b4530abc76..ed99b922610e 100644 --- a/source/Plugins/Language/Go/GoLanguage.cpp +++ b/source/Plugins/Language/Go/GoLanguage.cpp @@ -125,3 +125,7 @@ GoLanguage::GetHardcodedSynthetics() { return g_formatters; } + +bool GoLanguage::IsSourceFile(llvm::StringRef file_path) const { + return file_path.endswith(".go"); +} diff --git a/source/Plugins/Language/Go/GoLanguage.h b/source/Plugins/Language/Go/GoLanguage.h index ebec1d7205fa..ee21c5634046 100644 --- a/source/Plugins/Language/Go/GoLanguage.h +++ b/source/Plugins/Language/Go/GoLanguage.h @@ -39,6 +39,8 @@ class GoLanguage : public Language { HardcodedFormatters::HardcodedSyntheticFinder GetHardcodedSynthetics() override; + bool IsSourceFile(llvm::StringRef file_path) const override; + //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ diff --git a/source/Plugins/Language/Java/JavaLanguage.cpp b/source/Plugins/Language/Java/JavaLanguage.cpp index b17862f0b6a2..634ae4caf4b0 100644 --- a/source/Plugins/Language/Java/JavaLanguage.cpp +++ b/source/Plugins/Language/Java/JavaLanguage.cpp @@ -99,3 +99,7 @@ lldb::TypeCategoryImplSP JavaLanguage::GetFormatters() { }); return g_category; } + +bool JavaLanguage::IsSourceFile(llvm::StringRef file_path) const { + return file_path.endswith(".java"); +} diff --git a/source/Plugins/Language/Java/JavaLanguage.h b/source/Plugins/Language/Java/JavaLanguage.h index 5b652502a3d1..a16ea9975b87 100644 --- a/source/Plugins/Language/Java/JavaLanguage.h +++ b/source/Plugins/Language/Java/JavaLanguage.h @@ -45,6 +45,8 @@ class JavaLanguage : public Language { bool IsNilReference(ValueObject &valobj) override; lldb::TypeCategoryImplSP GetFormatters() override; + + bool IsSourceFile(llvm::StringRef file_path) const override; }; } // namespace lldb_private diff --git a/source/Plugins/Language/OCaml/OCamlLanguage.cpp b/source/Plugins/Language/OCaml/OCamlLanguage.cpp index ec24a36fe8f3..b294f84fcff8 100644 --- a/source/Plugins/Language/OCaml/OCamlLanguage.cpp +++ b/source/Plugins/Language/OCaml/OCamlLanguage.cpp @@ -28,6 +28,15 @@ using namespace lldb; using namespace lldb_private; +bool OCamlLanguage::IsSourceFile(llvm::StringRef file_path) const { + const auto suffixes = {".ml", ".mli"}; + for (auto suffix : suffixes) { + if (file_path.endswith_lower(suffix)) + return true; + } + return false; +} + void OCamlLanguage::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), "OCaml Language", CreateInstance); diff --git a/source/Plugins/Language/OCaml/OCamlLanguage.h b/source/Plugins/Language/OCaml/OCamlLanguage.h index 21837fe5add4..c4a75db2e544 100644 --- a/source/Plugins/Language/OCaml/OCamlLanguage.h +++ b/source/Plugins/Language/OCaml/OCamlLanguage.h @@ -31,6 +31,8 @@ class OCamlLanguage : public Language { return lldb::eLanguageTypeOCaml; } + bool IsSourceFile(llvm::StringRef file_path) const override; + static void Initialize(); static void Terminate(); diff --git a/source/Plugins/Language/ObjC/CMakeLists.txt b/source/Plugins/Language/ObjC/CMakeLists.txt index 95ace3a3633a..afb68d4de831 100644 --- a/source/Plugins/Language/ObjC/CMakeLists.txt +++ b/source/Plugins/Language/ObjC/CMakeLists.txt @@ -31,6 +31,7 @@ add_lldb_library(lldbPluginObjCLanguage PLUGIN lldbTarget lldbUtility lldbPluginAppleObjCRuntime + lldbPluginClangCommon EXTRA_CXXFLAGS ${EXTRA_CXXFLAGS} ) diff --git a/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/source/Plugins/Language/ObjC/ObjCLanguage.cpp index 47874b3be8fd..d57b999206b4 100644 --- a/source/Plugins/Language/ObjC/ObjCLanguage.cpp +++ b/source/Plugins/Language/ObjC/ObjCLanguage.cpp @@ -1102,3 +1102,12 @@ bool ObjCLanguage::IsNilReference(ValueObject &valobj) { bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0; return canReadValue && isZero; } + +bool ObjCLanguage::IsSourceFile(llvm::StringRef file_path) const { + const auto suffixes = {".h", ".m", ".M"}; + for (auto suffix : suffixes) { + if (file_path.endswith_lower(suffix)) + return true; + } + return false; +} diff --git a/source/Plugins/Language/ObjC/ObjCLanguage.h b/source/Plugins/Language/ObjC/ObjCLanguage.h index 9782c5da0d67..10c30b338cba 100644 --- a/source/Plugins/Language/ObjC/ObjCLanguage.h +++ b/source/Plugins/Language/ObjC/ObjCLanguage.h @@ -17,6 +17,7 @@ // Other libraries and framework includes // Project includes +#include "Plugins/Language/ClangCommon/ClangHighlighter.h" #include "lldb/Target/Language.h" #include "lldb/Utility/ConstString.h" #include "lldb/lldb-private.h" @@ -24,6 +25,8 @@ namespace lldb_private { class ObjCLanguage : public Language { + ClangHighlighter m_highlighter; + public: class MethodName { public: @@ -121,6 +124,10 @@ class ObjCLanguage : public Language { bool IsNilReference(ValueObject &valobj) override; + bool IsSourceFile(llvm::StringRef file_path) const override; + + const Highlighter *GetHighlighter() const override { return &m_highlighter; } + //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ diff --git a/source/Plugins/Language/ObjCPlusPlus/CMakeLists.txt b/source/Plugins/Language/ObjCPlusPlus/CMakeLists.txt index 75df9794d75d..1aa5cc1ed488 100644 --- a/source/Plugins/Language/ObjCPlusPlus/CMakeLists.txt +++ b/source/Plugins/Language/ObjCPlusPlus/CMakeLists.txt @@ -1,7 +1,8 @@ add_lldb_library(lldbPluginObjCPlusPlusLanguage PLUGIN ObjCPlusPlusLanguage.cpp - + LINK_LIBS lldbCore lldbTarget + lldbPluginClangCommon ) diff --git a/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp b/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp index bfc22c9ee650..5e6d86e05318 100644 --- a/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp +++ b/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp @@ -16,6 +16,15 @@ using namespace lldb; using namespace lldb_private; +bool ObjCPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const { + const auto suffixes = {".h", ".mm"}; + for (auto suffix : suffixes) { + if (file_path.endswith_lower(suffix)) + return true; + } + return false; +} + void ObjCPlusPlusLanguage::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), "Objective-C++ Language", CreateInstance); diff --git a/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h b/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h index 588b52215c10..b1825c9d53da 100644 --- a/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h +++ b/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h @@ -14,12 +14,15 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "Plugins/Language/ClangCommon/ClangHighlighter.h" #include "lldb/Target/Language.h" #include "lldb/lldb-private.h" namespace lldb_private { class ObjCPlusPlusLanguage : public Language { + ClangHighlighter m_highlighter; + public: ObjCPlusPlusLanguage() = default; @@ -29,6 +32,10 @@ class ObjCPlusPlusLanguage : public Language { return lldb::eLanguageTypeObjC_plus_plus; } + bool IsSourceFile(llvm::StringRef file_path) const override; + + const Highlighter *GetHighlighter() const override { return &m_highlighter; } + //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ diff --git a/source/Target/Language.cpp b/source/Target/Language.cpp index cde6f8654aec..599b44222742 100644 --- a/source/Target/Language.cpp +++ b/source/Target/Language.cpp @@ -77,7 +77,39 @@ Language *Language::FindPlugin(lldb::LanguageType language) { return nullptr; } +Language *Language::FindPlugin(llvm::StringRef file_path) { + Language *result = nullptr; + ForEach([&result, file_path](Language *language) { + if (language->IsSourceFile(file_path)) { + result = language; + return false; + } + return true; + }); + return result; +} + +Language *Language::FindPlugin(LanguageType language, + llvm::StringRef file_path) { + Language *result = FindPlugin(language); + // Finding a language by file path is slower, we so we use this as the + // fallback. + if (!result) + result = FindPlugin(file_path); + return result; +} + void Language::ForEach(std::function callback) { + // If we want to iterate over all languages, we first have to complete the + // LanguagesMap. + static llvm::once_flag g_initialize; + llvm::call_once(g_initialize, [] { + for (unsigned lang = eLanguageTypeUnknown; lang < eNumLanguageTypes; + ++lang) { + FindPlugin(static_cast(lang)); + } + }); + std::lock_guard guard(GetLanguagesMutex()); LanguagesMap &map(GetLanguagesMap()); for (const auto &entry : map) { diff --git a/unittests/Language/CMakeLists.txt b/unittests/Language/CMakeLists.txt index d5e17c1f2a19..3a6e5de785e5 100644 --- a/unittests/Language/CMakeLists.txt +++ b/unittests/Language/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(CPlusPlus) +add_subdirectory(Highlighting) diff --git a/unittests/Language/Highlighting/CMakeLists.txt b/unittests/Language/Highlighting/CMakeLists.txt new file mode 100644 index 000000000000..32780ac8b824 --- /dev/null +++ b/unittests/Language/Highlighting/CMakeLists.txt @@ -0,0 +1,11 @@ +add_lldb_unittest(HighlighterTests + HighlighterTest.cpp + + LINK_LIBS + lldbPluginCPlusPlusLanguage + lldbPluginObjCLanguage + lldbPluginObjCPlusPlusLanguage + lldbPluginJavaLanguage + lldbPluginOCamlLanguage + lldbPluginGoLanguage + ) diff --git a/unittests/Language/Highlighting/HighlighterTest.cpp b/unittests/Language/Highlighting/HighlighterTest.cpp new file mode 100644 index 000000000000..8e9a2ea4e6cb --- /dev/null +++ b/unittests/Language/Highlighting/HighlighterTest.cpp @@ -0,0 +1,221 @@ +//===-- HighlighterTest.cpp -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" + +#include "lldb/Core/Highlighter.h" + +#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" +#include "Plugins/Language/Go/GoLanguage.h" +#include "Plugins/Language/Java/JavaLanguage.h" +#include "Plugins/Language/OCaml/OCamlLanguage.h" +#include "Plugins/Language/ObjC/ObjCLanguage.h" +#include "Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h" + +using namespace lldb_private; + +namespace { +class HighlighterTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); +}; +} // namespace + +void HighlighterTest::SetUpTestCase() { + // The HighlighterManager uses the language plugins under the hood, so we + // have to initialize them here for our test process. + CPlusPlusLanguage::Initialize(); + GoLanguage::Initialize(); + JavaLanguage::Initialize(); + ObjCLanguage::Initialize(); + ObjCPlusPlusLanguage::Initialize(); + OCamlLanguage::Initialize(); +} + +void HighlighterTest::TearDownTestCase() { + CPlusPlusLanguage::Terminate(); + GoLanguage::Terminate(); + JavaLanguage::Terminate(); + ObjCLanguage::Terminate(); + ObjCPlusPlusLanguage::Terminate(); + OCamlLanguage::Terminate(); +} + +static std::string getName(lldb::LanguageType type) { + HighlighterManager m; + return m.getHighlighterFor(type, "").GetName().str(); +} + +static std::string getName(llvm::StringRef path) { + HighlighterManager m; + return m.getHighlighterFor(lldb::eLanguageTypeUnknown, path).GetName().str(); +} + +TEST_F(HighlighterTest, HighlighterSelectionType) { + EXPECT_EQ(getName(lldb::eLanguageTypeC_plus_plus), "clang"); + EXPECT_EQ(getName(lldb::eLanguageTypeC_plus_plus_03), "clang"); + EXPECT_EQ(getName(lldb::eLanguageTypeC_plus_plus_11), "clang"); + EXPECT_EQ(getName(lldb::eLanguageTypeC_plus_plus_14), "clang"); + EXPECT_EQ(getName(lldb::eLanguageTypeObjC), "clang"); + EXPECT_EQ(getName(lldb::eLanguageTypeObjC_plus_plus), "clang"); + + EXPECT_EQ(getName(lldb::eLanguageTypeUnknown), "none"); + EXPECT_EQ(getName(lldb::eLanguageTypeJulia), "none"); + EXPECT_EQ(getName(lldb::eLanguageTypeJava), "none"); + EXPECT_EQ(getName(lldb::eLanguageTypeHaskell), "none"); +} + +TEST_F(HighlighterTest, HighlighterSelectionPath) { + EXPECT_EQ(getName("myfile.cc"), "clang"); + EXPECT_EQ(getName("moo.cpp"), "clang"); + EXPECT_EQ(getName("mar.cxx"), "clang"); + EXPECT_EQ(getName("foo.C"), "clang"); + EXPECT_EQ(getName("bar.CC"), "clang"); + EXPECT_EQ(getName("a/dir.CC"), "clang"); + EXPECT_EQ(getName("/a/dir.hpp"), "clang"); + EXPECT_EQ(getName("header.h"), "clang"); + + EXPECT_EQ(getName(""), "none"); + EXPECT_EQ(getName("/dev/null"), "none"); + EXPECT_EQ(getName("Factory.java"), "none"); + EXPECT_EQ(getName("poll.py"), "none"); + EXPECT_EQ(getName("reducer.hs"), "none"); +} + +TEST_F(HighlighterTest, FallbackHighlighter) { + HighlighterManager mgr; + const Highlighter &h = + mgr.getHighlighterFor(lldb::eLanguageTypePascal83, "foo.pas"); + + HighlightStyle style; + style.identifier.Set("[", "]"); + style.semicolons.Set("<", ">"); + + const char *code = "program Hello;"; + std::string output = h.Highlight(style, code); + + EXPECT_STREQ(output.c_str(), code); +} + +TEST_F(HighlighterTest, DefaultHighlighter) { + HighlighterManager mgr; + const Highlighter &h = mgr.getHighlighterFor(lldb::eLanguageTypeC, "main.c"); + + HighlightStyle style; + + const char *code = "int my_main() { return 22; } \n"; + std::string output = h.Highlight(style, code); + + EXPECT_STREQ(output.c_str(), code); +} + +//------------------------------------------------------------------------------ +// Tests highlighting with the Clang highlighter. +//------------------------------------------------------------------------------ + +static std::string highlightC(llvm::StringRef code, HighlightStyle style) { + HighlighterManager mgr; + const Highlighter &h = mgr.getHighlighterFor(lldb::eLanguageTypeC, "main.c"); + return h.Highlight(style, code); +} + +TEST_F(HighlighterTest, ClangEmptyInput) { + HighlightStyle s; + EXPECT_EQ("", highlightC("", s)); +} + +TEST_F(HighlighterTest, ClangScalarLiterals) { + HighlightStyle s; + s.scalar_literal.Set("", ""); + + EXPECT_EQ(" int i = 22;", highlightC(" int i = 22;", s)); +} + +TEST_F(HighlighterTest, ClangStringLiterals) { + HighlightStyle s; + s.string_literal.Set("", ""); + + EXPECT_EQ("const char *f = 22 + \"foo\";", + highlightC("const char *f = 22 + \"foo\";", s)); +} + +TEST_F(HighlighterTest, ClangUnterminatedString) { + HighlightStyle s; + s.string_literal.Set("", ""); + + EXPECT_EQ(" f = \"", highlightC(" f = \"", s)); +} + +TEST_F(HighlighterTest, Keywords) { + HighlightStyle s; + s.keyword.Set("", ""); + + EXPECT_EQ(" return 1; ", highlightC(" return 1; ", s)); +} + +TEST_F(HighlighterTest, Colons) { + HighlightStyle s; + s.colon.Set("", ""); + + EXPECT_EQ("foo::bar:", highlightC("foo::bar:", s)); +} + +TEST_F(HighlighterTest, ClangBraces) { + HighlightStyle s; + s.braces.Set("", ""); + + EXPECT_EQ("a{}", highlightC("a{}", s)); +} + +TEST_F(HighlighterTest, ClangSquareBrackets) { + HighlightStyle s; + s.square_brackets.Set("", ""); + + EXPECT_EQ("a[]", highlightC("a[]", s)); +} + +TEST_F(HighlighterTest, ClangCommas) { + HighlightStyle s; + s.comma.Set("", ""); + + EXPECT_EQ(" bool f = foo(), 1;", + highlightC(" bool f = foo(), 1;", s)); +} + +TEST_F(HighlighterTest, ClangPPDirectives) { + HighlightStyle s; + s.pp_directive.Set("", ""); + + EXPECT_EQ("#include \"foo\" //c", + highlightC("#include \"foo\" //c", s)); +} + +TEST_F(HighlighterTest, ClangComments) { + HighlightStyle s; + s.comment.Set("", ""); + + EXPECT_EQ(" /*com */ // com /*n*/", + highlightC(" /*com */ // com /*n*/", s)); +} + +TEST_F(HighlighterTest, ClangOperators) { + HighlightStyle s; + s.operators.Set("[", "]"); + + EXPECT_EQ(" 1[+]2[/]a[*]f[&]x[|][~]l", highlightC(" 1+2/a*f&x|~l", s)); +} + +TEST_F(HighlighterTest, ClangIdentifiers) { + HighlightStyle s; + s.identifier.Set("", ""); + + EXPECT_EQ(" foo c = bar(); return 1;", + highlightC(" foo c = bar(); return 1;", s)); +} From 9a64f719914ece38c68a61d2fb5678e3b561932b Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 2 Aug 2018 03:01:09 +0000 Subject: [PATCH 0040/1112] Added missing highlighter files to XCode project git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338669 91177308-0d34-0410-b5e6-96231b3b80d8 --- lldb.xcodeproj/project.pbxproj | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index d8a714415320..775b5de1d69d 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -158,6 +158,8 @@ 268900D313353E6F00698AC0 /* ClangExternalASTSourceCallbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E69030129C6BEF00DDECD9 /* ClangExternalASTSourceCallbacks.cpp */; }; 4966DCC4148978A10028481B /* ClangExternalASTSourceCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4966DCC3148978A10028481B /* ClangExternalASTSourceCommon.cpp */; }; 2689005F13353E0E00698AC0 /* ClangFunctionCaller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C98D3DA118FB96F00E575D0 /* ClangFunctionCaller.cpp */; }; + 58A080AC2112AABB00D5580F /* ClangHighlighter.cpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 58A080AB2112AABB00D5580F /* ClangHighlighter.cpp */; }; + 58A080AE2112AAC500D5580F /* ClangHighlighter.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 58A080AD2112AAC500D5580F /* ClangHighlighter.h */; }; 4CD44D5820C603CB0003557C /* ClangHost.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CD44D5620C603A80003557C /* ClangHost.cpp */; }; 4959511F1A1BC4BC00F6F8FC /* ClangModulesDeclVendor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4959511E1A1BC4BC00F6F8FC /* ClangModulesDeclVendor.cpp */; }; 2689006313353E0E00698AC0 /* ClangPersistentVariables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */; }; @@ -336,6 +338,8 @@ AE44FB301BB07EB20033EB62 /* GoUserExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AE44FB2C1BB07DD80033EB62 /* GoUserExpression.cpp */; }; 6D95DC011B9DC057000E318A /* HashedNameToDIE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D95DBFE1B9DC057000E318A /* HashedNameToDIE.cpp */; }; 2666ADC81B3CB675001FAFD3 /* HexagonDYLDRendezvous.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2666ADC31B3CB675001FAFD3 /* HexagonDYLDRendezvous.cpp */; }; + 58A080B42112AB3800D5580F /* Highlighter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 58A080A92112AA9400D5580F /* Highlighter.cpp */; }; + 58A080B32112AB2900D5580F /* HighlighterTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 58A080B12112AB2200D5580F /* HighlighterTest.cpp */; }; AF1729D6182C907200E0AB97 /* HistoryThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF1729D4182C907200E0AB97 /* HistoryThread.cpp */; }; AF1729D7182C907200E0AB97 /* HistoryUnwind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF1729D5182C907200E0AB97 /* HistoryUnwind.cpp */; }; 2689007113353E1A00698AC0 /* Host.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 69A01E1C1236C5D400C660B5 /* Host.cpp */; }; @@ -1279,6 +1283,8 @@ dstPath = "$(DEVELOPER_INSTALL_DIR)/usr/share/man/man1"; dstSubfolderSpec = 0; files = ( + 58A080AE2112AAC500D5580F /* ClangHighlighter.h in CopyFiles */, + 58A080AC2112AABB00D5580F /* ClangHighlighter.cpp in CopyFiles */, AF90106515AB7D3600FF120D /* lldb.1 in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 1; @@ -1518,6 +1524,8 @@ 26BC7D5510F1B77400F91463 /* ClangForward.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangForward.h; path = include/lldb/Core/ClangForward.h; sourceTree = ""; }; 4C98D3DA118FB96F00E575D0 /* ClangFunctionCaller.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangFunctionCaller.cpp; path = ExpressionParser/Clang/ClangFunctionCaller.cpp; sourceTree = ""; }; 4C98D3E0118FB98F00E575D0 /* ClangFunctionCaller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangFunctionCaller.h; path = ExpressionParser/Clang/ClangFunctionCaller.h; sourceTree = ""; }; + 58A080AB2112AABB00D5580F /* ClangHighlighter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangHighlighter.cpp; path = Language/ClangCommon/ClangHighlighter.cpp; sourceTree = ""; }; + 58A080AD2112AAC500D5580F /* ClangHighlighter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangHighlighter.h; path = Language/ClangCommon/ClangHighlighter.h; sourceTree = ""; }; 4CD44D5620C603A80003557C /* ClangHost.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ClangHost.cpp; path = ExpressionParser/Clang/ClangHost.cpp; sourceTree = ""; }; 4CD44D5720C603A90003557C /* ClangHost.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ClangHost.h; path = ExpressionParser/Clang/ClangHost.h; sourceTree = ""; }; 4959511E1A1BC4BC00F6F8FC /* ClangModulesDeclVendor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangModulesDeclVendor.cpp; path = ExpressionParser/Clang/ClangModulesDeclVendor.cpp; sourceTree = ""; }; @@ -1882,6 +1890,8 @@ 26A0DA4D140F721D006DA411 /* HashedNameToDIE.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HashedNameToDIE.h; sourceTree = ""; }; 2666ADC31B3CB675001FAFD3 /* HexagonDYLDRendezvous.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HexagonDYLDRendezvous.cpp; sourceTree = ""; }; 2666ADC41B3CB675001FAFD3 /* HexagonDYLDRendezvous.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HexagonDYLDRendezvous.h; sourceTree = ""; }; + 58A080A92112AA9400D5580F /* Highlighter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Highlighter.cpp; path = source/Core/Highlighter.cpp; sourceTree = ""; }; + 58A080B12112AB2200D5580F /* HighlighterTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HighlighterTest.cpp; path = unittests/Language/Highlighting/HighlighterTest.cpp; sourceTree = SOURCE_ROOT; }; AF1729D4182C907200E0AB97 /* HistoryThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HistoryThread.cpp; path = Utility/HistoryThread.cpp; sourceTree = ""; }; AF061F89182C980000B6A19C /* HistoryThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HistoryThread.h; path = Utility/HistoryThread.h; sourceTree = ""; }; AF1729D5182C907200E0AB97 /* HistoryUnwind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HistoryUnwind.cpp; path = Utility/HistoryUnwind.cpp; sourceTree = ""; }; @@ -3659,6 +3669,7 @@ 23CB14E51D66CBEB00EDDDE1 /* Core */ = { isa = PBXGroup; children = ( + 58A080B12112AB2200D5580F /* HighlighterTest.cpp */, 4F29D3CD21010F84003B549A /* MangledTest.cpp */, 9A3D43E31F3237D500EB767C /* ListenerTest.cpp */, 9A3D43E21F3237D500EB767C /* StateTest.cpp */, @@ -4960,6 +4971,7 @@ 26BC7C1010F1B34800F91463 /* Core */ = { isa = PBXGroup; children = ( + 58A080A92112AA9400D5580F /* Highlighter.cpp */, 26BC7D5010F1B77400F91463 /* Address.h */, 26BC7E6910F1B85900F91463 /* Address.cpp */, 26BC7D5110F1B77400F91463 /* AddressRange.h */, @@ -6405,6 +6417,8 @@ 94B638541B8FABEA004FE1E4 /* Language */ = { isa = PBXGroup; children = ( + 58A080AD2112AAC500D5580F /* ClangHighlighter.h */, + 58A080AB2112AABB00D5580F /* ClangHighlighter.cpp */, 6D0F61501C80AB1400A4ECEE /* Java */, 94B6385A1B8FB109004FE1E4 /* CPlusPlus */, AE44FB431BB4BAC20033EB62 /* Go */, @@ -7424,6 +7438,7 @@ 8C3BD9A01EF5D1FF0016C343 /* JSONTest.cpp in Sources */, 23CB15361D66DA9300EDDDE1 /* FileSpecTest.cpp in Sources */, 23E2E5251D90373D006F38BB /* ArchSpecTest.cpp in Sources */, + 58A080B32112AB2900D5580F /* HighlighterTest.cpp in Sources */, 9A2057081F3B819100F6C293 /* MemoryRegionInfoTest.cpp in Sources */, 9A20572D1F3B8E6600F6C293 /* TestCompletion.cpp in Sources */, 4C719399207D23E300FDF430 /* TestOptionArgParser.cpp in Sources */, @@ -7956,6 +7971,7 @@ 26BF51F31B3C754400016294 /* ABISysV_hexagon.cpp in Sources */, 232CB619191E00CD00EF39FC /* NativeProcessProtocol.cpp in Sources */, 8CF02AEF19DD16B100B14BE0 /* InstrumentationRuntimeStopInfo.cpp in Sources */, + 58A080B42112AB3800D5580F /* Highlighter.cpp in Sources */, 268900FC13353E6F00698AC0 /* ThreadPlanBase.cpp in Sources */, 268900FD13353E6F00698AC0 /* ThreadPlanCallFunction.cpp in Sources */, 23D4007D1C2101F2000C3885 /* DWARFDebugMacro.cpp in Sources */, From 11ea2d8e489d6d298e373e1ccffd6ee90cd0d004 Mon Sep 17 00:00:00 2001 From: Stefan Granitz Date: Thu, 2 Aug 2018 10:13:18 +0000 Subject: [PATCH 0041/1112] Unit test for Symtab::InitNameIndexes Summary: In order to exploit the potential of LLVM's new ItaniumPartialDemangler for indexing in LLDB, we expect conceptual changes in the implementation of the InitNameIndexes function. Here is a unit test that aims at covering all relevant code paths in that function. Reviewers: labath, jingham, JDevlieghere Reviewed By: JDevlieghere Subscribers: friss, teemperor, davide, clayborg, erik.pilkington, lldb-commits, mgorny Differential Revision: https://reviews.llvm.org/D49909 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338695 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/Core/CMakeLists.txt | 12 ++ .../Core/Inputs/mangled-function-names.yaml | 116 +++++++++++++++ unittests/Core/MangledTest.cpp | 134 +++++++++++++++++- 3 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 unittests/Core/Inputs/mangled-function-names.yaml diff --git a/unittests/Core/CMakeLists.txt b/unittests/Core/CMakeLists.txt index 4affb8cabca9..039b8afdf75a 100644 --- a/unittests/Core/CMakeLists.txt +++ b/unittests/Core/CMakeLists.txt @@ -11,7 +11,19 @@ add_lldb_unittest(LLDBCoreTests LINK_LIBS lldbCore lldbHost + lldbSymbol + lldbPluginObjectFileELF + lldbPluginSymbolVendorELF + lldbUtilityHelpers LLVMTestingSupport LINK_COMPONENTS Support ) + +add_dependencies(LLDBCoreTests yaml2obj) +add_definitions(-DYAML2OBJ="$") + +set(test_inputs + mangled-function-names.yaml + ) +add_unittest_inputs(LLDBCoreTests "${test_inputs}") diff --git a/unittests/Core/Inputs/mangled-function-names.yaml b/unittests/Core/Inputs/mangled-function-names.yaml new file mode 100644 index 000000000000..56fc9bdc3627 --- /dev/null +++ b/unittests/Core/Inputs/mangled-function-names.yaml @@ -0,0 +1,116 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000010 + Content: 554889E58B0425A80000005DC30F1F00 + - Name: .anothertext + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x0000000000000010 + AddressAlign: 0x0000000000000010 + Content: 554889E54883EC20488D0425A8000000C745FC00000000488945F0488B45F08B08894DECE8C7FFFFFF8B4DEC01C189C84883C4205D746573742073747200C3 + - Name: .eh_frame + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x0000000000000050 + AddressAlign: 0x0000000000000008 + Content: 1400000000000000017A5200017810011B0C0708900100001C0000001C00000090FFFFFF0D00000000410E108602430D06000000000000001C0000003C00000080FFFFFF3F00000000410E108602430D0600000000000000 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x00000000000000A8 + AddressAlign: 0x0000000000000004 + Content: '01000000' + - Name: .comment + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + Content: 5562756E747520636C616E672076657273696F6E20332E352D317562756E74753120287472756E6B2920286261736564206F6E204C4C564D20332E352900 +Symbols: + Local: + - Type: STT_SECTION + Section: .text + - Type: STT_SECTION + Section: .anothertext + Value: 0x0000000000000010 + - Type: STT_SECTION + Section: .eh_frame + Value: 0x0000000000000050 + - Type: STT_SECTION + Section: .data + Value: 0x00000000000000A8 + - Type: STT_SECTION + Section: .comment + - Name: /tmp/a.c + Type: STT_FILE + - Type: STT_FILE + Global: + - Name: somedata + Type: STT_OBJECT + Section: .anothertext + Value: 0x0000000000000045 + - Name: main + Type: STT_FUNC + Section: .anothertext + Value: 0x0000000000000010 + Size: 0x000000000000003F + - Name: _Z3foov + Type: STT_FUNC + Section: .text + Size: 0x000000000000000D + - Name: puts@GLIBC_2.5 + Type: STT_FUNC + Section: .text + Size: 0x000000000000000D + - Name: puts@GLIBC_2.6 + Type: STT_FUNC + Section: .text + Size: 0x000000000000000D + - Name: _Z5annotv@VERSION3 + Type: STT_FUNC + Section: .text + Size: 0x000000000000000D + - Name: _ZN1AC2Ev + Type: STT_FUNC + Section: .text + Size: 0x000000000000000D + - Name: _ZN1AD2Ev + Type: STT_FUNC + Section: .text + Size: 0x000000000000000D + - Name: _ZN1A3barEv + Type: STT_FUNC + Section: .text + Size: 0x000000000000000D + - Name: _ZGVZN4llvm4dbgsEvE7thestrm + Type: STT_FUNC + Section: .text + Size: 0x000000000000000D + - Name: _ZZN4llvm4dbgsEvE7thestrm + Type: STT_FUNC + Section: .text + Size: 0x000000000000000D + - Name: _ZTVN5clang4DeclE + Type: STT_FUNC + Section: .text + Size: 0x000000000000000D + - Name: -[ObjCfoo] + Type: STT_FUNC + Section: .text + Size: 0x000000000000000D + - Name: +[B ObjCbar(WithCategory)] + Type: STT_FUNC + Section: .text + Size: 0x000000000000000D + - Name: _Z12undemangableEvx42 + Type: STT_FUNC + Section: .text + Size: 0x000000000000000D +... diff --git a/unittests/Core/MangledTest.cpp b/unittests/Core/MangledTest.cpp index 7deb901f5601..40df29621fa8 100644 --- a/unittests/Core/MangledTest.cpp +++ b/unittests/Core/MangledTest.cpp @@ -7,9 +7,21 @@ // //===----------------------------------------------------------------------===// -#include "gtest/gtest.h" +#include "Plugins/ObjectFile/ELF/ObjectFileELF.h" +#include "Plugins/SymbolVendor/ELF/SymbolVendorELF.h" +#include "TestingSupport/TestUtilities.h" #include "lldb/Core/Mangled.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Symbol/SymbolContext.h" + +#include "llvm/Support/FileUtilities.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Program.h" + +#include "gtest/gtest.h" using namespace lldb; using namespace lldb_private; @@ -36,3 +48,123 @@ TEST(MangledTest, EmptyForInvalidName) { EXPECT_STREQ("", TheDemangled.GetCString()); } + +#define ASSERT_NO_ERROR(x) \ + if (std::error_code ASSERT_NO_ERROR_ec = x) { \ + llvm::SmallString<128> MessageStorage; \ + llvm::raw_svector_ostream Message(MessageStorage); \ + Message << #x ": did not return errc::success.\n" \ + << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \ + << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \ + GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \ + } else { \ + } + +TEST(MangledTest, NameIndexes_FindFunctionSymbols) { + HostInfo::Initialize(); + ObjectFileELF::Initialize(); + SymbolVendorELF::Initialize(); + + std::string Yaml = GetInputFilePath("mangled-function-names.yaml"); + llvm::SmallString<128> Obj; + ASSERT_NO_ERROR(llvm::sys::fs::createTemporaryFile( + "mangled-function-names-%%%%%%", "obj", Obj)); + + llvm::FileRemover Deleter(Obj); + llvm::StringRef Args[] = {YAML2OBJ, Yaml}; + llvm::StringRef ObjRef = Obj; + const llvm::Optional redirects[] = {llvm::None, ObjRef, + llvm::None}; + ASSERT_EQ(0, + llvm::sys::ExecuteAndWait(YAML2OBJ, Args, llvm::None, redirects)); + uint64_t Size; + ASSERT_NO_ERROR(llvm::sys::fs::file_size(Obj, Size)); + ASSERT_GT(Size, 0u); + + ModuleSpec Spec{FileSpec(Obj, false)}; + Spec.GetSymbolFileSpec().SetFile(Obj, false, FileSpec::Style::native); + auto M = std::make_shared(Spec); + + auto Count = [M](const char *Name, FunctionNameType Type) -> int { + SymbolContextList SymList; + return M->FindFunctionSymbols(ConstString(Name), Type, SymList); + }; + + // Unmangled + EXPECT_EQ(1, Count("main", eFunctionNameTypeFull)); + EXPECT_EQ(1, Count("main", eFunctionNameTypeBase)); + EXPECT_EQ(0, Count("main", eFunctionNameTypeMethod)); + + // Itanium mangled + EXPECT_EQ(1, Count("_Z3foov", eFunctionNameTypeFull)); + EXPECT_EQ(1, Count("_Z3foov", eFunctionNameTypeBase)); + EXPECT_EQ(1, Count("foo", eFunctionNameTypeBase)); + EXPECT_EQ(0, Count("foo", eFunctionNameTypeMethod)); + + // Unmangled with linker annotation + EXPECT_EQ(1, Count("puts@GLIBC_2.5", eFunctionNameTypeFull)); + EXPECT_EQ(1, Count("puts@GLIBC_2.6", eFunctionNameTypeFull)); + EXPECT_EQ(2, Count("puts", eFunctionNameTypeFull)); + EXPECT_EQ(2, Count("puts", eFunctionNameTypeBase)); + EXPECT_EQ(0, Count("puts", eFunctionNameTypeMethod)); + + // Itanium mangled with linker annotation + EXPECT_EQ(1, Count("_Z5annotv@VERSION3", eFunctionNameTypeFull)); + EXPECT_EQ(1, Count("_Z5annotv", eFunctionNameTypeFull)); + EXPECT_EQ(1, Count("_Z5annotv", eFunctionNameTypeBase)); + EXPECT_EQ(0, Count("annot", eFunctionNameTypeBase)); + EXPECT_EQ(0, Count("annot", eFunctionNameTypeMethod)); + + // Itanium mangled ctor A::A() + EXPECT_EQ(1, Count("_ZN1AC2Ev", eFunctionNameTypeFull)); + EXPECT_EQ(1, Count("_ZN1AC2Ev", eFunctionNameTypeBase)); + EXPECT_EQ(1, Count("A", eFunctionNameTypeMethod)); + EXPECT_EQ(0, Count("A", eFunctionNameTypeBase)); + + // Itanium mangled dtor A::~A() + EXPECT_EQ(1, Count("_ZN1AD2Ev", eFunctionNameTypeFull)); + EXPECT_EQ(1, Count("_ZN1AD2Ev", eFunctionNameTypeBase)); + EXPECT_EQ(1, Count("~A", eFunctionNameTypeMethod)); + EXPECT_EQ(0, Count("~A", eFunctionNameTypeBase)); + + // Itanium mangled method A::bar() + EXPECT_EQ(1, Count("_ZN1A3barEv", eFunctionNameTypeFull)); + EXPECT_EQ(1, Count("_ZN1A3barEv", eFunctionNameTypeBase)); + EXPECT_EQ(1, Count("bar", eFunctionNameTypeMethod)); + EXPECT_EQ(0, Count("bar", eFunctionNameTypeBase)); + + // Itanium mangled names that are explicitly excluded from parsing + EXPECT_EQ(1, Count("_ZGVZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeFull)); + EXPECT_EQ(1, Count("_ZGVZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeBase)); + EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeMethod)); + EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeBase)); + EXPECT_EQ(1, Count("_ZZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeFull)); + EXPECT_EQ(1, Count("_ZZN4llvm4dbgsEvE7thestrm", eFunctionNameTypeBase)); + EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeMethod)); + EXPECT_EQ(0, Count("dbgs", eFunctionNameTypeBase)); + EXPECT_EQ(1, Count("_ZTVN5clang4DeclE", eFunctionNameTypeFull)); + EXPECT_EQ(1, Count("_ZTVN5clang4DeclE", eFunctionNameTypeBase)); + EXPECT_EQ(0, Count("Decl", eFunctionNameTypeMethod)); + EXPECT_EQ(0, Count("Decl", eFunctionNameTypeBase)); + + // ObjC mangled static + EXPECT_EQ(1, Count("-[ObjCfoo]", eFunctionNameTypeFull)); + EXPECT_EQ(1, Count("-[ObjCfoo]", eFunctionNameTypeBase)); + EXPECT_EQ(0, Count("ObjCfoo", eFunctionNameTypeMethod)); + + // ObjC mangled method with category + EXPECT_EQ(1, Count("+[B ObjCbar(WithCategory)]", eFunctionNameTypeFull)); + EXPECT_EQ(1, Count("+[B ObjCbar(WithCategory)]", eFunctionNameTypeBase)); + EXPECT_EQ(0, Count("ObjCbar", eFunctionNameTypeMethod)); + + // Invalid things: unable to decode but still possible to find by full name + EXPECT_EQ(1, Count("_Z12undemangableEvx42", eFunctionNameTypeFull)); + EXPECT_EQ(1, Count("_Z12undemangableEvx42", eFunctionNameTypeBase)); + EXPECT_EQ(0, Count("_Z12undemangableEvx42", eFunctionNameTypeMethod)); + EXPECT_EQ(0, Count("undemangable", eFunctionNameTypeBase)); + EXPECT_EQ(0, Count("undemangable", eFunctionNameTypeMethod)); + + SymbolVendorELF::Terminate(); + ObjectFileELF::Terminate(); + HostInfo::Terminate(); +} From 2f3f42c2d396c27c4057629b5e4c2ce8bb533d2f Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Thu, 2 Aug 2018 12:50:23 +0000 Subject: [PATCH 0042/1112] Move ClangHighlighter.cpp to hopefully better place in Xcode project. But with a write-only format, who can really say? git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338712 91177308-0d34-0410-b5e6-96231b3b80d8 --- lldb.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index 775b5de1d69d..3faf425351bd 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -65,6 +65,7 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 228B1B672113340200E61C70 /* ClangHighlighter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 58A080AB2112AABB00D5580F /* ClangHighlighter.cpp */; }; 268900E813353E6F00698AC0 /* ABI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 497E7B9D1188F6690065CCA1 /* ABI.cpp */; }; 26DB3E161379E7AD0080DC73 /* ABIMacOSX_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DB3E071379E7AD0080DC73 /* ABIMacOSX_arm.cpp */; }; 26DB3E191379E7AD0080DC73 /* ABIMacOSX_arm64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DB3E0B1379E7AD0080DC73 /* ABIMacOSX_arm64.cpp */; }; @@ -1283,8 +1284,6 @@ dstPath = "$(DEVELOPER_INSTALL_DIR)/usr/share/man/man1"; dstSubfolderSpec = 0; files = ( - 58A080AE2112AAC500D5580F /* ClangHighlighter.h in CopyFiles */, - 58A080AC2112AABB00D5580F /* ClangHighlighter.cpp in CopyFiles */, AF90106515AB7D3600FF120D /* lldb.1 in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 1; @@ -7958,6 +7957,7 @@ 268900F313353E6F00698AC0 /* StackFrame.cpp in Sources */, 268900F413353E6F00698AC0 /* StackFrameList.cpp in Sources */, 268900F513353E6F00698AC0 /* StackID.cpp in Sources */, + 228B1B672113340200E61C70 /* ClangHighlighter.cpp in Sources */, 268900F613353E6F00698AC0 /* StopInfo.cpp in Sources */, 256CBDB41ADD0EFD00BC6CDC /* RegisterContextPOSIXCore_arm.cpp in Sources */, 267F684F1CC02E270086832B /* RegisterContextPOSIXCore_s390x.cpp in Sources */, From 003d39feb8c786d476a81e9f13118d567350bdd1 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 2 Aug 2018 16:38:34 +0000 Subject: [PATCH 0043/1112] Add byte counting mechanism to LLDB's Stream class. Summary: This patch allows LLDB's Stream class to count the bytes it has written to so far. There are two major motivations for this patch: The first one is that this will allow us to get rid of all the handwritten byte counting code we have in LLDB so far. Examples for this are pretty much all functions in LLDB that take a Stream to write to and return a size_t, which usually represents the bytes written. By moving to this centralized byte counting mechanism, we hopefully can avoid some tricky errors that happen when some code forgets to count the written bytes while writing something to a stream. The second motivation is that this is needed for the migration away from LLDB's `Stream` and towards LLVM's `raw_ostream`. My current plan is to start offering a fake raw_ostream class that just forwards to a LLDB Stream. However, for this raw_ostream wrapper we need to fulfill the raw_ostream interface with LLDB's Stream, which currently lacks the ability to count the bytes written so far (which raw_ostream exposes by it's `tell()` method). By adding this functionality it is trivial to start rolling out our raw_ostream wrapper (and then eventually completely move to raw_ostream). Also, once this fake raw_ostream is available, we can start replacing our own code writing to LLDB's Stream by LLVM code writing to raw_ostream. The best example for this is the LEB128 encoding we currently ship, which can be replaced with by LLVM's version which accepts an raw_ostream. From the point of view of the pure source changes this test does, we essentially just renamed the Write implementation in Stream to `WriteImpl` while the `Write` method everyone is using to write its raw bytes is now just forwarding and counting the written bytes. Reviewers: labath, davide Reviewed By: labath Subscribers: JDevlieghere, lldb-commits Differential Revision: https://reviews.llvm.org/D50159 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338733 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Core/StreamAsynchronousIO.h | 3 +- include/lldb/Core/StreamBuffer.h | 12 +-- include/lldb/Core/StreamFile.h | 2 +- include/lldb/Utility/Stream.h | 25 +++++- include/lldb/Utility/StreamString.h | 3 +- include/lldb/Utility/StreamTee.h | 46 +++++------ source/Core/StreamAsynchronousIO.cpp | 2 +- source/Core/StreamFile.cpp | 2 +- source/Utility/StreamString.cpp | 7 +- unittests/Utility/StreamTeeTest.cpp | 4 +- unittests/Utility/StreamTest.cpp | 101 +++++++++++++++++++++++ 11 files changed, 168 insertions(+), 39 deletions(-) diff --git a/include/lldb/Core/StreamAsynchronousIO.h b/include/lldb/Core/StreamAsynchronousIO.h index 29b109757da7..8791315dbeb5 100644 --- a/include/lldb/Core/StreamAsynchronousIO.h +++ b/include/lldb/Core/StreamAsynchronousIO.h @@ -30,7 +30,8 @@ class StreamAsynchronousIO : public Stream { void Flush() override; - size_t Write(const void *src, size_t src_len) override; +protected: + size_t WriteImpl(const void *src, size_t src_len) override; private: Debugger &m_debugger; diff --git a/include/lldb/Core/StreamBuffer.h b/include/lldb/Core/StreamBuffer.h index 307dc7e18a5e..7b2468330ad2 100644 --- a/include/lldb/Core/StreamBuffer.h +++ b/include/lldb/Core/StreamBuffer.h @@ -30,12 +30,6 @@ template class StreamBuffer : public Stream { // Nothing to do when flushing a buffer based stream... } - virtual size_t Write(const void *s, size_t length) { - if (s && length) - m_packet.append((const char *)s, ((const char *)s) + length); - return length; - } - void Clear() { m_packet.clear(); } // Beware, this might not be NULL terminated as you can expect from @@ -48,6 +42,12 @@ template class StreamBuffer : public Stream { protected: llvm::SmallVector m_packet; + + virtual size_t WriteImpl(const void *s, size_t length) { + if (s && length) + m_packet.append((const char *)s, ((const char *)s) + length); + return length; + } }; } // namespace lldb_private diff --git a/include/lldb/Core/StreamFile.h b/include/lldb/Core/StreamFile.h index a26ae84c7be5..250876bdefbc 100644 --- a/include/lldb/Core/StreamFile.h +++ b/include/lldb/Core/StreamFile.h @@ -46,13 +46,13 @@ class StreamFile : public Stream { void Flush() override; - size_t Write(const void *s, size_t length) override; protected: //------------------------------------------------------------------ // Classes that inherit from StreamFile can see and modify these //------------------------------------------------------------------ File m_file; + size_t WriteImpl(const void *s, size_t length) override; private: DISALLOW_COPY_AND_ASSIGN(StreamFile); diff --git a/include/lldb/Utility/Stream.h b/include/lldb/Utility/Stream.h index 24c69ba9f573..96a238aef9ac 100644 --- a/include/lldb/Utility/Stream.h +++ b/include/lldb/Utility/Stream.h @@ -83,7 +83,13 @@ class Stream { /// @return /// The number of bytes that were appended to the stream. //------------------------------------------------------------------ - virtual size_t Write(const void *src, size_t src_len) = 0; + size_t Write(const void *src, size_t src_len) { + size_t appended_byte_count = WriteImpl(src, src_len); + m_bytes_written += appended_byte_count; + return appended_byte_count; + } + + size_t GetWrittenBytes() const { return m_bytes_written; } //------------------------------------------------------------------ // Member functions @@ -523,8 +529,25 @@ class Stream { lldb::ByteOrder m_byte_order; ///< Byte order to use when encoding scalar types. int m_indent_level; ///< Indention level. + std::size_t m_bytes_written = 0; ///< Number of bytes written so far. size_t _PutHex8(uint8_t uvalue, bool add_prefix); + + //------------------------------------------------------------------ + /// Output character bytes to the stream. + /// + /// Appends \a src_len characters from the buffer \a src to the stream. + /// + /// @param[in] src + /// A buffer containing at least \a src_len bytes of data. + /// + /// @param[in] src_len + /// A number of bytes to append to the stream. + /// + /// @return + /// The number of bytes that were appended to the stream. + //------------------------------------------------------------------ + virtual size_t WriteImpl(const void *src, size_t src_len) = 0; }; } // namespace lldb_private diff --git a/include/lldb/Utility/StreamString.h b/include/lldb/Utility/StreamString.h index 0ae3e82a3498..28c11fcc0f8f 100644 --- a/include/lldb/Utility/StreamString.h +++ b/include/lldb/Utility/StreamString.h @@ -31,8 +31,6 @@ class StreamString : public Stream { void Flush() override; - size_t Write(const void *s, size_t length) override; - void Clear(); bool Empty() const; @@ -49,6 +47,7 @@ class StreamString : public Stream { protected: std::string m_packet; + size_t WriteImpl(const void *s, size_t length) override; }; } // namespace lldb_private diff --git a/include/lldb/Utility/StreamTee.h b/include/lldb/Utility/StreamTee.h index 569ba1979978..4f8e6ab1f002 100644 --- a/include/lldb/Utility/StreamTee.h +++ b/include/lldb/Utility/StreamTee.h @@ -70,29 +70,6 @@ class StreamTee : public Stream { } } - size_t Write(const void *s, size_t length) override { - std::lock_guard guard(m_streams_mutex); - if (m_streams.empty()) - return 0; - - size_t min_bytes_written = SIZE_MAX; - collection::iterator pos, end; - for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos) { - // Allow for our collection to contain NULL streams. This allows the - // StreamTee to be used with hard coded indexes for clients that might - // want N total streams with only a few that are set to valid values. - Stream *strm = pos->get(); - if (strm) { - const size_t bytes_written = strm->Write(s, length); - if (min_bytes_written > bytes_written) - min_bytes_written = bytes_written; - } - } - if (min_bytes_written == SIZE_MAX) - return 0; - return min_bytes_written; - } - size_t AppendStream(const lldb::StreamSP &stream_sp) { size_t new_idx = m_streams.size(); std::lock_guard guard(m_streams_mutex); @@ -131,6 +108,29 @@ class StreamTee : public Stream { typedef std::vector collection; mutable std::recursive_mutex m_streams_mutex; collection m_streams; + + size_t WriteImpl(const void *s, size_t length) override { + std::lock_guard guard(m_streams_mutex); + if (m_streams.empty()) + return 0; + + size_t min_bytes_written = SIZE_MAX; + collection::iterator pos, end; + for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos) { + // Allow for our collection to contain NULL streams. This allows the + // StreamTee to be used with hard coded indexes for clients that might + // want N total streams with only a few that are set to valid values. + Stream *strm = pos->get(); + if (strm) { + const size_t bytes_written = strm->Write(s, length); + if (min_bytes_written > bytes_written) + min_bytes_written = bytes_written; + } + } + if (min_bytes_written == SIZE_MAX) + return 0; + return min_bytes_written; + } }; } // namespace lldb_private diff --git a/source/Core/StreamAsynchronousIO.cpp b/source/Core/StreamAsynchronousIO.cpp index aae8636bff09..eb8bf3620afc 100644 --- a/source/Core/StreamAsynchronousIO.cpp +++ b/source/Core/StreamAsynchronousIO.cpp @@ -31,7 +31,7 @@ void StreamAsynchronousIO::Flush() { } } -size_t StreamAsynchronousIO::Write(const void *s, size_t length) { +size_t StreamAsynchronousIO::WriteImpl(const void *s, size_t length) { m_data.append((const char *)s, length); return length; } diff --git a/source/Core/StreamFile.cpp b/source/Core/StreamFile.cpp index f59415485021..3e7214032fa8 100644 --- a/source/Core/StreamFile.cpp +++ b/source/Core/StreamFile.cpp @@ -41,7 +41,7 @@ StreamFile::~StreamFile() {} void StreamFile::Flush() { m_file.Flush(); } -size_t StreamFile::Write(const void *s, size_t length) { +size_t StreamFile::WriteImpl(const void *s, size_t length) { m_file.Write(s, length); return length; } diff --git a/source/Utility/StreamString.cpp b/source/Utility/StreamString.cpp index 75f58de28b97..152096198858 100644 --- a/source/Utility/StreamString.cpp +++ b/source/Utility/StreamString.cpp @@ -24,12 +24,15 @@ void StreamString::Flush() { // Nothing to do when flushing a buffer based stream... } -size_t StreamString::Write(const void *s, size_t length) { +size_t StreamString::WriteImpl(const void *s, size_t length) { m_packet.append(reinterpret_cast(s), length); return length; } -void StreamString::Clear() { m_packet.clear(); } +void StreamString::Clear() { + m_packet.clear(); + m_bytes_written = 0; +} bool StreamString::Empty() const { return GetSize() == 0; } diff --git a/unittests/Utility/StreamTeeTest.cpp b/unittests/Utility/StreamTeeTest.cpp index 150a8a5b1206..9fcfbc802587 100644 --- a/unittests/Utility/StreamTeeTest.cpp +++ b/unittests/Utility/StreamTeeTest.cpp @@ -90,7 +90,9 @@ namespace { void Flush() override { ++m_flush_count; } - size_t Write(const void *src, size_t src_len) override { return src_len; } + size_t WriteImpl(const void *src, size_t src_len) override { + return src_len; + } }; } diff --git a/unittests/Utility/StreamTest.cpp b/unittests/Utility/StreamTest.cpp index 3210a6247f20..0fdee0969c0e 100644 --- a/unittests/Utility/StreamTest.cpp +++ b/unittests/Utility/StreamTest.cpp @@ -44,149 +44,211 @@ TEST_F(StreamTest, ChangingByteOrder) { TEST_F(StreamTest, PutChar) { s.PutChar('a'); + EXPECT_EQ(1U, s.GetWrittenBytes()); EXPECT_EQ("a", TakeValue()); s.PutChar('1'); + EXPECT_EQ(1U, s.GetWrittenBytes()); EXPECT_EQ("1", TakeValue()); } TEST_F(StreamTest, PutCharWhitespace) { s.PutChar(' '); + EXPECT_EQ(1U, s.GetWrittenBytes()); EXPECT_EQ(" ", TakeValue()); s.PutChar('\n'); + EXPECT_EQ(1U, s.GetWrittenBytes()); EXPECT_EQ("\n", TakeValue()); s.PutChar('\r'); + EXPECT_EQ(1U, s.GetWrittenBytes()); EXPECT_EQ("\r", TakeValue()); s.PutChar('\t'); + EXPECT_EQ(1U, s.GetWrittenBytes()); EXPECT_EQ("\t", TakeValue()); } TEST_F(StreamTest, PutCString) { s.PutCString(""); + EXPECT_EQ(0U, s.GetWrittenBytes()); EXPECT_EQ("", TakeValue()); s.PutCString("foobar"); + EXPECT_EQ(6U, s.GetWrittenBytes()); EXPECT_EQ("foobar", TakeValue()); s.PutCString(" "); + EXPECT_EQ(1U, s.GetWrittenBytes()); EXPECT_EQ(" ", TakeValue()); } TEST_F(StreamTest, PutCStringWithStringRef) { s.PutCString(llvm::StringRef("")); + EXPECT_EQ(0U, s.GetWrittenBytes()); EXPECT_EQ("", TakeValue()); s.PutCString(llvm::StringRef("foobar")); + EXPECT_EQ(6U, s.GetWrittenBytes()); EXPECT_EQ("foobar", TakeValue()); s.PutCString(llvm::StringRef(" ")); + EXPECT_EQ(1U, s.GetWrittenBytes()); EXPECT_EQ(" ", TakeValue()); } TEST_F(StreamTest, QuotedCString) { s.QuotedCString("foo"); + EXPECT_EQ(5U, s.GetWrittenBytes()); EXPECT_EQ(R"("foo")", TakeValue()); s.QuotedCString("ba r"); + EXPECT_EQ(6U, s.GetWrittenBytes()); EXPECT_EQ(R"("ba r")", TakeValue()); s.QuotedCString(" "); + EXPECT_EQ(3U, s.GetWrittenBytes()); EXPECT_EQ(R"(" ")", TakeValue()); } TEST_F(StreamTest, PutCharNull) { s.PutChar('\0'); + EXPECT_EQ(1U, s.GetWrittenBytes()); EXPECT_EQ(std::string("\0", 1), TakeValue()); s.PutChar('a'); + EXPECT_EQ(1U, s.GetWrittenBytes()); EXPECT_EQ(std::string("a", 1), TakeValue()); } TEST_F(StreamTest, PutCStringAsRawHex8) { s.PutCStringAsRawHex8(""); + EXPECT_EQ(0U, s.GetWrittenBytes()); EXPECT_EQ("", TakeValue()); s.PutCStringAsRawHex8("foobar"); + EXPECT_EQ(12U, s.GetWrittenBytes()); EXPECT_EQ("666f6f626172", TakeValue()); s.PutCStringAsRawHex8(" "); + EXPECT_EQ(2U, s.GetWrittenBytes()); EXPECT_EQ("20", TakeValue()); } TEST_F(StreamTest, PutHex8) { s.PutHex8((uint8_t)55); + EXPECT_EQ(2U, s.GetWrittenBytes()); EXPECT_EQ("37", TakeValue()); + s.PutHex8(std::numeric_limits::max()); + EXPECT_EQ(2U, s.GetWrittenBytes()); EXPECT_EQ("ff", TakeValue()); + s.PutHex8((uint8_t)0); + EXPECT_EQ(2U, s.GetWrittenBytes()); EXPECT_EQ("00", TakeValue()); } TEST_F(StreamTest, PutNHex8) { s.PutNHex8(0, (uint8_t)55); + EXPECT_EQ(0U, s.GetWrittenBytes()); EXPECT_EQ("", TakeValue()); + s.PutNHex8(1, (uint8_t)55); + EXPECT_EQ(2U, s.GetWrittenBytes()); EXPECT_EQ("37", TakeValue()); + s.PutNHex8(2, (uint8_t)55); + EXPECT_EQ(4U, s.GetWrittenBytes()); EXPECT_EQ("3737", TakeValue()); + s.PutNHex8(1, (uint8_t)56); + EXPECT_EQ(2U, s.GetWrittenBytes()); EXPECT_EQ("38", TakeValue()); } TEST_F(StreamTest, PutHex16ByteOrderLittle) { s.PutHex16(0x1234U, lldb::eByteOrderLittle); + EXPECT_EQ(4U, s.GetWrittenBytes()); EXPECT_EQ("3412", TakeValue()); + s.PutHex16(std::numeric_limits::max(), lldb::eByteOrderLittle); + EXPECT_EQ(4U, s.GetWrittenBytes()); EXPECT_EQ("ffff", TakeValue()); + s.PutHex16(0U, lldb::eByteOrderLittle); + EXPECT_EQ(4U, s.GetWrittenBytes()); EXPECT_EQ("0000", TakeValue()); } TEST_F(StreamTest, PutHex16ByteOrderBig) { s.PutHex16(0x1234U, lldb::eByteOrderBig); + EXPECT_EQ(4U, s.GetWrittenBytes()); EXPECT_EQ("1234", TakeValue()); + s.PutHex16(std::numeric_limits::max(), lldb::eByteOrderBig); + EXPECT_EQ(4U, s.GetWrittenBytes()); EXPECT_EQ("ffff", TakeValue()); + s.PutHex16(0U, lldb::eByteOrderBig); + EXPECT_EQ(4U, s.GetWrittenBytes()); EXPECT_EQ("0000", TakeValue()); } TEST_F(StreamTest, PutHex32ByteOrderLittle) { s.PutHex32(0x12345678U, lldb::eByteOrderLittle); + EXPECT_EQ(8U, s.GetWrittenBytes()); EXPECT_EQ("78563412", TakeValue()); + s.PutHex32(std::numeric_limits::max(), lldb::eByteOrderLittle); + EXPECT_EQ(8U, s.GetWrittenBytes()); EXPECT_EQ("ffffffff", TakeValue()); + s.PutHex32(0U, lldb::eByteOrderLittle); + EXPECT_EQ(8U, s.GetWrittenBytes()); EXPECT_EQ("00000000", TakeValue()); } TEST_F(StreamTest, PutHex32ByteOrderBig) { s.PutHex32(0x12345678U, lldb::eByteOrderBig); + EXPECT_EQ(8U, s.GetWrittenBytes()); EXPECT_EQ("12345678", TakeValue()); + s.PutHex32(std::numeric_limits::max(), lldb::eByteOrderBig); + EXPECT_EQ(8U, s.GetWrittenBytes()); EXPECT_EQ("ffffffff", TakeValue()); + s.PutHex32(0U, lldb::eByteOrderBig); + EXPECT_EQ(8U, s.GetWrittenBytes()); EXPECT_EQ("00000000", TakeValue()); } TEST_F(StreamTest, PutHex64ByteOrderLittle) { s.PutHex64(0x1234567890ABCDEFU, lldb::eByteOrderLittle); + EXPECT_EQ(16U, s.GetWrittenBytes()); EXPECT_EQ("efcdab9078563412", TakeValue()); + s.PutHex64(std::numeric_limits::max(), lldb::eByteOrderLittle); + EXPECT_EQ(16U, s.GetWrittenBytes()); EXPECT_EQ("ffffffffffffffff", TakeValue()); + s.PutHex64(0U, lldb::eByteOrderLittle); + EXPECT_EQ(16U, s.GetWrittenBytes()); EXPECT_EQ("0000000000000000", TakeValue()); } TEST_F(StreamTest, PutHex64ByteOrderBig) { s.PutHex64(0x1234567890ABCDEFU, lldb::eByteOrderBig); + EXPECT_EQ(16U, s.GetWrittenBytes()); EXPECT_EQ("1234567890abcdef", TakeValue()); + s.PutHex64(std::numeric_limits::max(), lldb::eByteOrderBig); + EXPECT_EQ(16U, s.GetWrittenBytes()); EXPECT_EQ("ffffffffffffffff", TakeValue()); + s.PutHex64(0U, lldb::eByteOrderBig); + EXPECT_EQ(16U, s.GetWrittenBytes()); EXPECT_EQ("0000000000000000", TakeValue()); } @@ -200,6 +262,7 @@ TEST_F(StreamTest, PutMaxHex64ByteOrderBig) { EXPECT_EQ(8U, bytes); bytes = s.PutMaxHex64(0x1234567890ABCDEFU, 8, lldb::eByteOrderBig); EXPECT_EQ(16U, bytes); + EXPECT_EQ(30U, s.GetWrittenBytes()); EXPECT_EQ("121234123456781234567890abcdef", TakeValue()); } @@ -213,6 +276,7 @@ TEST_F(StreamTest, PutMaxHex64ByteOrderLittle) { EXPECT_EQ(8U, bytes); bytes = s.PutMaxHex64(0x1234567890ABCDEFU, 8, lldb::eByteOrderLittle); EXPECT_EQ(16U, bytes); + EXPECT_EQ(30U, s.GetWrittenBytes()); EXPECT_EQ("12341278563412efcdab9078563412", TakeValue()); } @@ -222,12 +286,15 @@ TEST_F(StreamTest, PutMaxHex64ByteOrderLittle) { TEST_F(StreamTest, ShiftOperatorChars) { s << 'a' << 'b'; + EXPECT_EQ(2U, s.GetWrittenBytes()); EXPECT_EQ("ab", TakeValue()); } TEST_F(StreamTest, ShiftOperatorStrings) { s << "cstring\n"; + EXPECT_EQ(8U, s.GetWrittenBytes()); s << llvm::StringRef("llvm::StringRef\n"); + EXPECT_EQ(24U, s.GetWrittenBytes()); EXPECT_EQ("cstring\nllvm::StringRef\n", TakeValue()); } @@ -236,6 +303,7 @@ TEST_F(StreamTest, ShiftOperatorInts) { s << std::numeric_limits::max() << " "; s << std::numeric_limits::max() << " "; s << std::numeric_limits::max(); + EXPECT_EQ(40U, s.GetWrittenBytes()); EXPECT_EQ("127 32767 2147483647 9223372036854775807", TakeValue()); } @@ -244,6 +312,7 @@ TEST_F(StreamTest, ShiftOperatorUInts) { s << std::numeric_limits::max() << " "; s << std::numeric_limits::max() << " "; s << std::numeric_limits::max(); + EXPECT_EQ(33U, s.GetWrittenBytes()); EXPECT_EQ("ff ffff ffffffff ffffffffffffffff", TakeValue()); } @@ -259,6 +328,7 @@ TEST_F(StreamTest, ShiftOperatorPtr) { int *ptr = &i; s << ptr; + EXPECT_NE(0U, s.GetWrittenBytes()); EXPECT_TRUE(!TakeValue().empty()); } @@ -268,6 +338,7 @@ TEST_F(StreamTest, PutPtr) { int *ptr = &i; s.PutPointer(ptr); + EXPECT_NE(0U, s.GetWrittenBytes()); EXPECT_TRUE(!TakeValue().empty()); } @@ -283,6 +354,7 @@ TEST_F(StreamTest, PutBytesAsRawHex8ToBigEndian) { uint32_t value = 0x12345678; s.PutBytesAsRawHex8(static_cast(&value), sizeof(value), hostByteOrder, lldb::eByteOrderBig); + EXPECT_EQ(8U, s.GetWrittenBytes()); EXPECT_EQ("78563412", TakeValue()); } @@ -290,6 +362,7 @@ TEST_F(StreamTest, PutRawBytesToBigEndian) { uint32_t value = 0x12345678; s.PutRawBytes(static_cast(&value), sizeof(value), hostByteOrder, lldb::eByteOrderBig); + EXPECT_EQ(4U, s.GetWrittenBytes()); EXPECT_EQ("\x78\x56\x34\x12", TakeValue()); } @@ -297,6 +370,7 @@ TEST_F(StreamTest, PutBytesAsRawHex8ToLittleEndian) { uint32_t value = 0x12345678; s.PutBytesAsRawHex8(static_cast(&value), sizeof(value), hostByteOrder, lldb::eByteOrderLittle); + EXPECT_EQ(8U, s.GetWrittenBytes()); EXPECT_EQ("12345678", TakeValue()); } @@ -304,6 +378,7 @@ TEST_F(StreamTest, PutRawBytesToLittleEndian) { uint32_t value = 0x12345678; s.PutRawBytes(static_cast(&value), sizeof(value), hostByteOrder, lldb::eByteOrderLittle); + EXPECT_EQ(4U, s.GetWrittenBytes()); EXPECT_EQ("\x12\x34\x56\x78", TakeValue()); } @@ -337,72 +412,84 @@ TEST_F(StreamTest, PutRawBytesToMixedEndian) { TEST_F(BinaryStreamTest, PutULEB128OneByte) { auto bytes = s.PutULEB128(0x74ULL); + EXPECT_EQ(1U, s.GetWrittenBytes()); EXPECT_EQ("\x74", TakeValue()); EXPECT_EQ(1U, bytes); } TEST_F(BinaryStreamTest, PutULEB128TwoBytes) { auto bytes = s.PutULEB128(0x1985ULL); + EXPECT_EQ(2U, s.GetWrittenBytes()); EXPECT_EQ("\x85\x33", TakeValue()); EXPECT_EQ(2U, bytes); } TEST_F(BinaryStreamTest, PutULEB128ThreeBytes) { auto bytes = s.PutULEB128(0x5023ULL); + EXPECT_EQ(3U, s.GetWrittenBytes()); EXPECT_EQ("\xA3\xA0\x1", TakeValue()); EXPECT_EQ(3U, bytes); } TEST_F(BinaryStreamTest, PutULEB128FourBytes) { auto bytes = s.PutULEB128(0xA48032ULL); + EXPECT_EQ(4U, s.GetWrittenBytes()); EXPECT_EQ("\xB2\x80\x92\x5", TakeValue()); EXPECT_EQ(4U, bytes); } TEST_F(BinaryStreamTest, PutULEB128FiveBytes) { auto bytes = s.PutULEB128(0x12345678ULL); + EXPECT_EQ(5U, s.GetWrittenBytes()); EXPECT_EQ("\xF8\xAC\xD1\x91\x1", TakeValue()); EXPECT_EQ(5U, bytes); } TEST_F(BinaryStreamTest, PutULEB128SixBytes) { auto bytes = s.PutULEB128(0xABFE3FAFDFULL); + EXPECT_EQ(6U, s.GetWrittenBytes()); EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\x15", TakeValue()); EXPECT_EQ(6U, bytes); } TEST_F(BinaryStreamTest, PutULEB128SevenBytes) { auto bytes = s.PutULEB128(0xDABFE3FAFDFULL); + EXPECT_EQ(7U, s.GetWrittenBytes()); EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\x3", TakeValue()); EXPECT_EQ(7U, bytes); } TEST_F(BinaryStreamTest, PutULEB128EightBytes) { auto bytes = s.PutULEB128(0x7CDABFE3FAFDFULL); + EXPECT_EQ(8U, s.GetWrittenBytes()); EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x3", TakeValue()); EXPECT_EQ(8U, bytes); } TEST_F(BinaryStreamTest, PutULEB128NineBytes) { auto bytes = s.PutULEB128(0x327CDABFE3FAFDFULL); + EXPECT_EQ(9U, s.GetWrittenBytes()); EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x93\x3", TakeValue()); EXPECT_EQ(9U, bytes); } TEST_F(BinaryStreamTest, PutULEB128MaxValue) { auto bytes = s.PutULEB128(std::numeric_limits::max()); + EXPECT_EQ(10U, s.GetWrittenBytes()); EXPECT_EQ("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x1", TakeValue()); EXPECT_EQ(10U, bytes); } TEST_F(BinaryStreamTest, PutULEB128Zero) { auto bytes = s.PutULEB128(0x0U); + EXPECT_EQ(1U, s.GetWrittenBytes()); EXPECT_EQ(std::string("\0", 1), TakeValue()); EXPECT_EQ(1U, bytes); } TEST_F(BinaryStreamTest, PutULEB128One) { auto bytes = s.PutULEB128(0x1U); + EXPECT_EQ(1U, s.GetWrittenBytes()); EXPECT_EQ("\x1", TakeValue()); EXPECT_EQ(1U, bytes); } @@ -413,72 +500,84 @@ TEST_F(BinaryStreamTest, PutULEB128One) { TEST_F(BinaryStreamTest, PutSLEB128OneByte) { auto bytes = s.PutSLEB128(0x74LL); + EXPECT_EQ(2U, s.GetWrittenBytes()); EXPECT_EQ(std::string("\xF4\0", 2), TakeValue()); EXPECT_EQ(2U, bytes); } TEST_F(BinaryStreamTest, PutSLEB128TwoBytes) { auto bytes = s.PutSLEB128(0x1985LL); + EXPECT_EQ(2U, s.GetWrittenBytes()); EXPECT_EQ("\x85\x33", TakeValue()); EXPECT_EQ(2U, bytes); } TEST_F(BinaryStreamTest, PutSLEB128ThreeBytes) { auto bytes = s.PutSLEB128(0x5023LL); + EXPECT_EQ(3U, s.GetWrittenBytes()); EXPECT_EQ("\xA3\xA0\x1", TakeValue()); EXPECT_EQ(3U, bytes); } TEST_F(BinaryStreamTest, PutSLEB128FourBytes) { auto bytes = s.PutSLEB128(0xA48032LL); + EXPECT_EQ(4U, s.GetWrittenBytes()); EXPECT_EQ("\xB2\x80\x92\x5", TakeValue()); EXPECT_EQ(4U, bytes); } TEST_F(BinaryStreamTest, PutSLEB128FiveBytes) { auto bytes = s.PutSLEB128(0x12345678LL); + EXPECT_EQ(5U, s.GetWrittenBytes()); EXPECT_EQ("\xF8\xAC\xD1\x91\x1", TakeValue()); EXPECT_EQ(5U, bytes); } TEST_F(BinaryStreamTest, PutSLEB128SixBytes) { auto bytes = s.PutSLEB128(0xABFE3FAFDFLL); + EXPECT_EQ(6U, s.GetWrittenBytes()); EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\x15", TakeValue()); EXPECT_EQ(6U, bytes); } TEST_F(BinaryStreamTest, PutSLEB128SevenBytes) { auto bytes = s.PutSLEB128(0xDABFE3FAFDFLL); + EXPECT_EQ(7U, s.GetWrittenBytes()); EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\x3", TakeValue()); EXPECT_EQ(7U, bytes); } TEST_F(BinaryStreamTest, PutSLEB128EightBytes) { auto bytes = s.PutSLEB128(0x7CDABFE3FAFDFLL); + EXPECT_EQ(8U, s.GetWrittenBytes()); EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x3", TakeValue()); EXPECT_EQ(8U, bytes); } TEST_F(BinaryStreamTest, PutSLEB128NineBytes) { auto bytes = s.PutSLEB128(0x327CDABFE3FAFDFLL); + EXPECT_EQ(9U, s.GetWrittenBytes()); EXPECT_EQ("\xDF\xDF\xFE\xF1\xBF\xB5\xF3\x93\x3", TakeValue()); EXPECT_EQ(9U, bytes); } TEST_F(BinaryStreamTest, PutSLEB128MaxValue) { auto bytes = s.PutSLEB128(std::numeric_limits::max()); + EXPECT_EQ(10U, s.GetWrittenBytes()); EXPECT_EQ(std::string("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0", 10), TakeValue()); EXPECT_EQ(10U, bytes); } TEST_F(BinaryStreamTest, PutSLEB128Zero) { auto bytes = s.PutSLEB128(0x0); + EXPECT_EQ(1U, s.GetWrittenBytes()); EXPECT_EQ(std::string("\0", 1), TakeValue()); EXPECT_EQ(1U, bytes); } TEST_F(BinaryStreamTest, PutSLEB128One) { auto bytes = s.PutSLEB128(0x1); + EXPECT_EQ(1U, s.GetWrittenBytes()); EXPECT_EQ(std::string("\x1", 1), TakeValue()); EXPECT_EQ(1U, bytes); } @@ -492,12 +591,14 @@ TEST_F(BinaryStreamTest, PutSLEB128One) { TEST_F(StreamTest, PutULEB128) { auto bytes = s.PutULEB128(0x74ULL); + EXPECT_EQ(4U, s.GetWrittenBytes()); EXPECT_EQ("0x74", TakeValue()); EXPECT_EQ(4U, bytes); } TEST_F(StreamTest, PutSLEB128) { auto bytes = s.PutSLEB128(0x1985LL); + EXPECT_EQ(6U, s.GetWrittenBytes()); EXPECT_EQ("0x6533", TakeValue()); EXPECT_EQ(6U, bytes); } From 09a2bd256abdc5679016c93c2377ae18d536aa1d Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Thu, 2 Aug 2018 16:46:15 +0000 Subject: [PATCH 0044/1112] Add support for ARM and ARM64 breakpad generated minidump files In this patch I add support for ARM and ARM64 break pad files. There are two flavors of ARM: Apple where FP is R7, and non Apple where FP is R11. Added minimal tests that load up ARM64 and the two flavors or ARM core files with a single thread and known register values in each register. Each register is checked for the exact value. Differential Revision: https://reviews.llvm.org/D49750 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338734 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Target/Target.h | 30 +- lldb.xcodeproj/project.pbxproj | 16 + .../xcshareddata/xcschemes/desktop.xcscheme | 2 +- .../minidump-new/TestMiniDumpNew.py | 155 ++++ .../postmortem/minidump-new/arm-linux.dmp | Bin 0 -> 588 bytes .../postmortem/minidump-new/arm-macos.dmp | Bin 0 -> 588 bytes .../postmortem/minidump-new/arm64-macos.dmp | Bin 0 -> 1016 bytes .../Process/minidump/MinidumpParser.cpp | 140 +-- .../Plugins/Process/minidump/MinidumpParser.h | 1 + .../Process/minidump/ProcessMinidump.cpp | 14 +- .../minidump/RegisterContextMinidump_ARM.cpp | 532 +++++++++++ .../minidump/RegisterContextMinidump_ARM.h | 95 ++ .../RegisterContextMinidump_ARM64.cpp | 836 ++++++++++++++++++ .../minidump/RegisterContextMinidump_ARM64.h | 85 ++ .../Process/minidump/ThreadMinidump.cpp | 23 +- source/Target/Target.cpp | 22 +- 16 files changed, 1860 insertions(+), 91 deletions(-) create mode 100644 packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-linux.dmp create mode 100644 packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-macos.dmp create mode 100644 packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm64-macos.dmp create mode 100644 source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp create mode 100644 source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h create mode 100644 source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp create mode 100644 source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h diff --git a/include/lldb/Target/Target.h b/include/lldb/Target/Target.h index 75af8e80d2e5..a4a00eb2d371 100644 --- a/include/lldb/Target/Target.h +++ b/include/lldb/Target/Target.h @@ -913,28 +913,30 @@ class Target : public std::enable_shared_from_this, /// Set the architecture for this target. /// /// If the current target has no Images read in, then this just sets the - /// architecture, which will - /// be used to select the architecture of the ExecutableModule when that is - /// set. - /// If the current target has an ExecutableModule, then calling - /// SetArchitecture with a different + /// architecture, which will be used to select the architecture of the + /// ExecutableModule when that is set. If the current target has an + /// ExecutableModule, then calling SetArchitecture with a different /// architecture from the currently selected one will reset the - /// ExecutableModule to that slice - /// of the file backing the ExecutableModule. If the file backing the - /// ExecutableModule does not - /// contain a fork of this architecture, then this code will return false, and - /// the architecture - /// won't be changed. - /// If the input arch_spec is the same as the already set architecture, this - /// is a no-op. + /// ExecutableModule to that slice of the file backing the ExecutableModule. + /// If the file backing the ExecutableModule does not contain a fork of this + /// architecture, then this code will return false, and the architecture + /// won't be changed. If the input arch_spec is the same as the already set + /// architecture, this is a no-op. /// /// @param[in] arch_spec /// The new architecture. /// + /// @param[in] set_platform + /// If \b true, then the platform will be adjusted if the currently + /// selected platform is not compatible with the archicture being set. + /// If \b false, then just the architecture will be set even if the + /// currently selected platform isn't compatible (in case it might be + /// manually set following this function call). + /// /// @return /// \b true if the architecture was successfully set, \bfalse otherwise. //------------------------------------------------------------------ - bool SetArchitecture(const ArchSpec &arch_spec); + bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform = false); bool MergeArchitecture(const ArchSpec &arch_spec); diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index 3faf425351bd..f34c403c959e 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -665,6 +665,10 @@ 26474CBE18D0CB2D0073DEBA /* RegisterContextMach_i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26474CB818D0CB2D0073DEBA /* RegisterContextMach_i386.cpp */; }; 26474CC018D0CB2D0073DEBA /* RegisterContextMach_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26474CBA18D0CB2D0073DEBA /* RegisterContextMach_x86_64.cpp */; }; 26474CC918D0CB5B0073DEBA /* RegisterContextMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26474CC218D0CB5B0073DEBA /* RegisterContextMemory.cpp */; }; + 2619C4852107A9A2009CDE81 /* RegisterContextMinidump_ARM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2619C4812107A9A1009CDE81 /* RegisterContextMinidump_ARM.cpp */; }; + 2619C4872107A9A2009CDE81 /* RegisterContextMinidump_ARM.h in Headers */ = {isa = PBXBuildFile; fileRef = 2619C4832107A9A2009CDE81 /* RegisterContextMinidump_ARM.h */; }; + 2619C4842107A9A2009CDE81 /* RegisterContextMinidump_ARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2619C4802107A9A1009CDE81 /* RegisterContextMinidump_ARM64.cpp */; }; + 2619C4862107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h in Headers */ = {isa = PBXBuildFile; fileRef = 2619C4822107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h */; }; 947CF7761DC7B20D00EF980B /* RegisterContextMinidump_x86_32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 947CF7741DC7B20D00EF980B /* RegisterContextMinidump_x86_32.cpp */; }; AFD65C811D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFD65C7F1D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp */; }; AFD65C821D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = AFD65C801D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.h */; }; @@ -2542,6 +2546,10 @@ 26474CC218D0CB5B0073DEBA /* RegisterContextMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextMemory.cpp; path = Utility/RegisterContextMemory.cpp; sourceTree = ""; }; 262D24E513FB8710002D1960 /* RegisterContextMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextMemory.h; path = Utility/RegisterContextMemory.h; sourceTree = ""; }; 26474CC318D0CB5B0073DEBA /* RegisterContextMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextMemory.h; path = Utility/RegisterContextMemory.h; sourceTree = ""; }; + 2619C4812107A9A1009CDE81 /* RegisterContextMinidump_ARM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextMinidump_ARM.cpp; sourceTree = ""; }; + 2619C4832107A9A2009CDE81 /* RegisterContextMinidump_ARM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextMinidump_ARM.h; sourceTree = ""; }; + 2619C4802107A9A1009CDE81 /* RegisterContextMinidump_ARM64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextMinidump_ARM64.cpp; sourceTree = ""; }; + 2619C4822107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextMinidump_ARM64.h; sourceTree = ""; }; 947CF7741DC7B20D00EF980B /* RegisterContextMinidump_x86_32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextMinidump_x86_32.cpp; sourceTree = ""; }; 947CF7721DC7B20300EF980B /* RegisterContextMinidump_x86_32.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RegisterContextMinidump_x86_32.h; sourceTree = ""; }; AFD65C7F1D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextMinidump_x86_64.cpp; sourceTree = ""; }; @@ -3787,6 +3795,10 @@ 23E2E5351D9048E7006F38BB /* minidump */ = { isa = PBXGroup; children = ( + 2619C4812107A9A1009CDE81 /* RegisterContextMinidump_ARM.cpp */, + 2619C4832107A9A2009CDE81 /* RegisterContextMinidump_ARM.h */, + 2619C4802107A9A1009CDE81 /* RegisterContextMinidump_ARM64.cpp */, + 2619C4822107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h */, AFD65C7F1D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp */, AFD65C801D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.h */, 23E2E5361D9048FB006F38BB /* CMakeLists.txt */, @@ -6939,8 +6951,10 @@ AF6CA6681FBBAF37005A0DC3 /* ArchSpec.h in Headers */, AF235EB41FBE7858009C5541 /* RegisterInfoPOSIX_ppc64le.h in Headers */, AF2E02A41FA2CEAF00A86C34 /* ArchitectureArm.h in Headers */, + 2619C4872107A9A2009CDE81 /* RegisterContextMinidump_ARM.h in Headers */, 267F685A1CC02EBE0086832B /* RegisterInfos_s390x.h in Headers */, 267F68541CC02E920086832B /* RegisterContextLinux_s390x.h in Headers */, + 2619C4862107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h in Headers */, AF235EB11FBE77B6009C5541 /* RegisterContextPOSIX_ppc64le.h in Headers */, 267F68501CC02E270086832B /* RegisterContextPOSIXCore_s390x.h in Headers */, 4984BA181B979C08008658D4 /* ExpressionVariable.h in Headers */, @@ -7643,6 +7657,7 @@ 2689002113353DDE00698AC0 /* CommandObjectQuit.cpp in Sources */, 2689002213353DDE00698AC0 /* CommandObjectRegister.cpp in Sources */, 26BC17AF18C7F4CB00D2196D /* RegisterContextPOSIXCore_x86_64.cpp in Sources */, + 2619C4842107A9A2009CDE81 /* RegisterContextMinidump_ARM64.cpp in Sources */, 2689002313353DDE00698AC0 /* CommandObjectScript.cpp in Sources */, 2689002413353DDE00698AC0 /* CommandObjectSettings.cpp in Sources */, 2689002513353DDE00698AC0 /* CommandObjectSource.cpp in Sources */, @@ -7723,6 +7738,7 @@ 2689005113353E0400698AC0 /* StringList.cpp in Sources */, 2689005213353E0400698AC0 /* Timer.cpp in Sources */, 2689005413353E0400698AC0 /* UserSettingsController.cpp in Sources */, + 2619C4852107A9A2009CDE81 /* RegisterContextMinidump_ARM.cpp in Sources */, 23059A0719532B96007B8189 /* LinuxSignals.cpp in Sources */, 8CCB017E19BA28A80009FD44 /* ThreadCollection.cpp in Sources */, 9A77AD541E64E2760025CE04 /* RegisterInfoPOSIX_arm.cpp in Sources */, diff --git a/lldb.xcodeproj/xcshareddata/xcschemes/desktop.xcscheme b/lldb.xcodeproj/xcshareddata/xcschemes/desktop.xcscheme index d31912ef4837..f9b0cfec7b03 100644 --- a/lldb.xcodeproj/xcshareddata/xcschemes/desktop.xcscheme +++ b/lldb.xcodeproj/xcshareddata/xcschemes/desktop.xcscheme @@ -42,7 +42,7 @@ > 1) + 1 + if i & 1: + value = "%#8.8x" % (i_val | i_val << 16) + else: + value = "%#8.8x" % (i_val | i_val << 8) + self.check_register_string_value(fpr, "s%i" % (i), value, + lldb.eFormatHex) + # Check q0 - q15 + for i in range(15): + a = i * 2 + 1 + b = a + 1 + value = ("0x00%2.2x00%2.2x0000%2.2x%2.2x" + "00%2.2x00%2.2x0000%2.2x%2.2x") % (b, b, b, b, a, a, a, a) + self.check_register_string_value(fpr, "q%i" % (i), value, + lldb.eFormatHex) + + def test_linux_arm_registers(self): + """Test Linux ARM registers from a breakpad created minidump. + + The frame pointer is R11 for linux. + """ + self.verify_arm_registers(apple=False) + + def test_apple_arm_registers(self): + """Test Apple ARM registers from a breakpad created minidump. + + The frame pointer is R7 for linux. + """ + self.verify_arm_registers(apple=True) + def do_test_deeper_stack(self, binary, core, pid): target = self.dbg.CreateTarget(binary) process = target.LoadCore(core) diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-linux.dmp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-linux.dmp new file mode 100644 index 0000000000000000000000000000000000000000..3b0cb8268defef9d4cb64a7f574b8ff8ead084f9 GIT binary patch literal 588 zcmaKqPfmky5Jo?sKnpE}7D|DZHr_zHap@nnP26||*X~^C%9VS)gNax03O$0}#Wzjd z5aaLV6*__WX43Av{mtvU3$TBH|*-Vs(6&+wn~k)A?biMqd~lBY+wQiv?QHwnuJ8l1ycf>^ literal 0 HcmV?d00001 diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-macos.dmp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-macos.dmp new file mode 100644 index 0000000000000000000000000000000000000000..9ff6a8396ec5c448dbd0af82ee66812d0adec94c GIT binary patch literal 588 zcmaKqPfmky5Jo?sKnpE}7D|DZHr_zHap@nnP26||*X~^C#+`e;gNax03O$0}#Wzjd z5aaLV6*__WX43Av{mtvU3$TBH|*-Vs(6&+wn~k)A?biMqd~lBY+wQiv?QHwnuJ8k~$rsK5 literal 0 HcmV?d00001 diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm64-macos.dmp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm64-macos.dmp new file mode 100644 index 0000000000000000000000000000000000000000..ba658dd48feb905d3ca851b66fb4dcda5c8828d5 GIT binary patch literal 1016 zcmaKpNlwE+6htcn34w&znFnWN9wk5^4iJ`+*l-1|zycPqV-FinfW#HJ0!QF5yx)lv z+d^1+)xWxbcbD4J$@J#+L&``RLh{QqaRn17Lkk|k`fdKr>L(=erJkkl#N1yt#pFX` z!RFlOg~k74K$ss|ig2n6UF(eTQaS0#cG`Jq5~mq6%DU`XtxyTgfzZ75qpKja07BP5 z=sE~3g56be_m#9kCA19oMxJ{oPd=5<3J9%&&>9G>gU|*DZGzAi*gLn~TesDr650i! z0SN7Z&^`zqfY2e>zZ`+kv0M=9$@$oSxxc&p{`!1ZDxJx$( - static_cast(system_info->processor_arch)); - - switch (arch) { - case MinidumpCPUArchitecture::X86: - triple.setArch(llvm::Triple::ArchType::x86); - break; - case MinidumpCPUArchitecture::AMD64: - triple.setArch(llvm::Triple::ArchType::x86_64); - break; - case MinidumpCPUArchitecture::ARM: - triple.setArch(llvm::Triple::ArchType::arm); - break; - case MinidumpCPUArchitecture::ARM64: - triple.setArch(llvm::Triple::ArchType::aarch64); - break; - default: - triple.setArch(llvm::Triple::ArchType::UnknownArch); - break; - } - - const MinidumpOSPlatform os = static_cast( - static_cast(system_info->platform_id)); - - // TODO add all of the OSes that Minidump/breakpad distinguishes? - switch (os) { - case MinidumpOSPlatform::Win32S: - case MinidumpOSPlatform::Win32Windows: - case MinidumpOSPlatform::Win32NT: - case MinidumpOSPlatform::Win32CE: - triple.setOS(llvm::Triple::OSType::Win32); - break; - case MinidumpOSPlatform::Linux: - triple.setOS(llvm::Triple::OSType::Linux); - break; - case MinidumpOSPlatform::MacOSX: - triple.setOS(llvm::Triple::OSType::MacOSX); - break; - case MinidumpOSPlatform::Android: - triple.setOS(llvm::Triple::OSType::Linux); - triple.setEnvironment(llvm::Triple::EnvironmentType::Android); - break; - default: - triple.setOS(llvm::Triple::OSType::UnknownOS); - break; - } - - arch_spec.SetTriple(triple); - - return arch_spec; -} +ArchSpec MinidumpParser::GetArchitecture() { return m_arch; } const MinidumpMiscInfo *MinidumpParser::GetMiscInfo() { llvm::ArrayRef data = GetStream(MinidumpStreamType::MiscInfo); @@ -552,5 +488,79 @@ Status MinidumpParser::Initialize() { return error; } + // Set the architecture in m_arch + const MinidumpSystemInfo *system_info = GetSystemInfo(); + + if (!system_info) { + error.SetErrorString("invalid minidump: missing system info"); + return error; + } + + // TODO what to do about big endiand flavors of arm ? + // TODO set the arm subarch stuff if the minidump has info about it + + llvm::Triple triple; + triple.setVendor(llvm::Triple::VendorType::UnknownVendor); + + const MinidumpCPUArchitecture arch = + static_cast( + static_cast(system_info->processor_arch)); + + switch (arch) { + case MinidumpCPUArchitecture::X86: + triple.setArch(llvm::Triple::ArchType::x86); + break; + case MinidumpCPUArchitecture::AMD64: + triple.setArch(llvm::Triple::ArchType::x86_64); + break; + case MinidumpCPUArchitecture::ARM: + triple.setArch(llvm::Triple::ArchType::arm); + break; + case MinidumpCPUArchitecture::ARM64: + triple.setArch(llvm::Triple::ArchType::aarch64); + break; + default: + triple.setArch(llvm::Triple::ArchType::UnknownArch); + break; + } + + const MinidumpOSPlatform os = static_cast( + static_cast(system_info->platform_id)); + + // TODO add all of the OSes that Minidump/breakpad distinguishes? + switch (os) { + case MinidumpOSPlatform::Win32S: + case MinidumpOSPlatform::Win32Windows: + case MinidumpOSPlatform::Win32NT: + case MinidumpOSPlatform::Win32CE: + triple.setOS(llvm::Triple::OSType::Win32); + break; + case MinidumpOSPlatform::Linux: + triple.setOS(llvm::Triple::OSType::Linux); + break; + case MinidumpOSPlatform::MacOSX: + triple.setOS(llvm::Triple::OSType::MacOSX); + triple.setVendor(llvm::Triple::Apple); + break; + case MinidumpOSPlatform::IOS: + triple.setOS(llvm::Triple::OSType::IOS); + triple.setVendor(llvm::Triple::Apple); + break; + case MinidumpOSPlatform::Android: + triple.setOS(llvm::Triple::OSType::Linux); + triple.setEnvironment(llvm::Triple::EnvironmentType::Android); + break; + default: { + triple.setOS(llvm::Triple::OSType::UnknownOS); + std::string csd_version; + if (auto s = GetMinidumpString(system_info->csd_version_rva)) + csd_version = *s; + if (csd_version.find("Linux") != std::string::npos) + triple.setOS(llvm::Triple::OSType::Linux); + break; + } + } + m_arch.SetTriple(triple); + return error; } diff --git a/source/Plugins/Process/minidump/MinidumpParser.h b/source/Plugins/Process/minidump/MinidumpParser.h index 49b1eef14de5..48c752b541eb 100644 --- a/source/Plugins/Process/minidump/MinidumpParser.h +++ b/source/Plugins/Process/minidump/MinidumpParser.h @@ -98,6 +98,7 @@ class MinidumpParser { private: lldb::DataBufferSP m_data_sp; llvm::DenseMap m_directory_map; + ArchSpec m_arch; }; } // end namespace minidump diff --git a/source/Plugins/Process/minidump/ProcessMinidump.cpp b/source/Plugins/Process/minidump/ProcessMinidump.cpp index b43f22382eac..7af6301b7f1a 100644 --- a/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -29,6 +29,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Threading.h" +#include "Plugins/Process/Utility/StopInfoMachException.h" // C includes // C++ includes @@ -174,19 +175,21 @@ Status ProcessMinidump::DoLoadCore() { switch (arch.GetMachine()) { case llvm::Triple::x86: case llvm::Triple::x86_64: - // supported + case llvm::Triple::arm: + case llvm::Triple::aarch64: + // Any supported architectures must be listed here and also supported in + // ThreadMinidump::CreateRegisterContextForFrame(). break; - default: error.SetErrorStringWithFormat("unsupported minidump architecture: %s", arch.GetArchitectureName()); return error; } + GetTarget().SetArchitecture(arch, true /*set_platform*/); m_thread_list = m_minidump_parser.GetThreads(); m_active_exception = m_minidump_parser.GetExceptionStream(); ReadModuleList(); - GetTarget().SetArchitecture(arch); llvm::Optional pid = m_minidump_parser.GetPid(); if (!pid) { @@ -229,6 +232,11 @@ void ProcessMinidump::RefreshStateAfterStop() { if (arch.GetTriple().getOS() == llvm::Triple::Linux) { stop_info = StopInfo::CreateStopReasonWithSignal( *stop_thread, m_active_exception->exception_record.exception_code); + } else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) { + stop_info = StopInfoMachException::CreateStopReasonWithMachException( + *stop_thread, m_active_exception->exception_record.exception_code, 2, + m_active_exception->exception_record.exception_flags, + m_active_exception->exception_record.exception_address, 0); } else { std::string desc; llvm::raw_string_ostream desc_stream(desc); diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp new file mode 100644 index 000000000000..2d73da4e5b51 --- /dev/null +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp @@ -0,0 +1,532 @@ +//===-- RegisterContextMinidump_ARM.cpp -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Project includes +#include "RegisterContextMinidump_ARM.h" + +// Other libraries and framework includes +#include "Utility/ARM_DWARF_Registers.h" +#include "lldb/Core/RegisterValue.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBAssert.h" +#include "lldb/lldb-enumerations.h" + +// C includes +#include + +// C++ includes + +using namespace lldb; +using namespace lldb_private; +using namespace minidump; + +#define INV LLDB_INVALID_REGNUM +#define OFFSET(r) (offsetof(RegisterContextMinidump_ARM::Context, r)) + +#define DEF_R(i) \ + { \ + "r" #i, nullptr, 4, OFFSET(r[i]), eEncodingUint, eFormatHex, \ + {INV, dwarf_r##i, INV, INV, reg_r##i}, nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_R_ARG(i, n) \ + { \ + "r" #i, "arg" #n, 4, OFFSET(r[i]), eEncodingUint, eFormatHex, \ + {INV, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_D(i) \ + { \ + "d" #i, nullptr, 8, OFFSET(d[i]), eEncodingVector, eFormatVectorOfUInt8, \ + {INV, dwarf_d##i, INV, INV, reg_d##i}, nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_S(i) \ + { \ + "s" #i, nullptr, 4, OFFSET(s[i]), eEncodingIEEE754, eFormatFloat, \ + {INV, dwarf_s##i, INV, INV, reg_s##i}, nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_Q(i) \ + { \ + "q" #i, nullptr, 16, OFFSET(q[i]), eEncodingVector, eFormatVectorOfUInt8, \ + {INV, dwarf_q##i, INV, INV, reg_q##i}, nullptr, nullptr, nullptr, 0 \ + } + +// Zero based LLDB register numbers for this register context +enum { + // General Purpose Registers + reg_r0, + reg_r1, + reg_r2, + reg_r3, + reg_r4, + reg_r5, + reg_r6, + reg_r7, + reg_r8, + reg_r9, + reg_r10, + reg_r11, + reg_r12, + reg_sp, + reg_lr, + reg_pc, + reg_cpsr, + // Floating Point Registers + reg_fpscr, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_q0, + reg_q1, + reg_q2, + reg_q3, + reg_q4, + reg_q5, + reg_q6, + reg_q7, + reg_q8, + reg_q9, + reg_q10, + reg_q11, + reg_q12, + reg_q13, + reg_q14, + reg_q15, + k_num_regs +}; + +static RegisterInfo g_reg_info_apple_fp = { + "fp", + "r7", + 4, + OFFSET(r[7]), + eEncodingUint, + eFormatHex, + {INV, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7}, + nullptr, + nullptr, + nullptr, + 0}; + +static RegisterInfo g_reg_info_fp = { + "fp", + "r11", + 4, + OFFSET(r[11]), + eEncodingUint, + eFormatHex, + {INV, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11}, + nullptr, + nullptr, + nullptr, + 0}; + +// Register info definitions for this register context +static RegisterInfo g_reg_infos[] = { + DEF_R_ARG(0, 1), + DEF_R_ARG(1, 2), + DEF_R_ARG(2, 3), + DEF_R_ARG(3, 4), + DEF_R(4), + DEF_R(5), + DEF_R(6), + DEF_R(7), + DEF_R(8), + DEF_R(9), + DEF_R(10), + DEF_R(11), + DEF_R(12), + {"sp", + "r13", + 4, + OFFSET(r[13]), + eEncodingUint, + eFormatHex, + {INV, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, + nullptr, + nullptr, + nullptr, + 0}, + {"lr", + "r14", + 4, + OFFSET(r[14]), + eEncodingUint, + eFormatHex, + {INV, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, + nullptr, + nullptr, + nullptr, + 0}, + {"pc", + "r15", + 4, + OFFSET(r[15]), + eEncodingUint, + eFormatHex, + {INV, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, + nullptr, + nullptr, + nullptr, + 0}, + {"cpsr", + "psr", + 4, + OFFSET(cpsr), + eEncodingUint, + eFormatHex, + {INV, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, + nullptr, + nullptr, + nullptr, + 0}, + {"fpscr", + nullptr, + 8, + OFFSET(fpscr), + eEncodingUint, + eFormatHex, + {INV, INV, INV, INV, reg_fpscr}, + nullptr, + nullptr, + nullptr, + 0}, + DEF_D(0), + DEF_D(1), + DEF_D(2), + DEF_D(3), + DEF_D(4), + DEF_D(5), + DEF_D(6), + DEF_D(7), + DEF_D(8), + DEF_D(9), + DEF_D(10), + DEF_D(11), + DEF_D(12), + DEF_D(13), + DEF_D(14), + DEF_D(15), + DEF_D(16), + DEF_D(17), + DEF_D(18), + DEF_D(19), + DEF_D(20), + DEF_D(21), + DEF_D(22), + DEF_D(23), + DEF_D(24), + DEF_D(25), + DEF_D(26), + DEF_D(27), + DEF_D(28), + DEF_D(29), + DEF_D(30), + DEF_D(31), + DEF_S(0), + DEF_S(1), + DEF_S(2), + DEF_S(3), + DEF_S(4), + DEF_S(5), + DEF_S(6), + DEF_S(7), + DEF_S(8), + DEF_S(9), + DEF_S(10), + DEF_S(11), + DEF_S(12), + DEF_S(13), + DEF_S(14), + DEF_S(15), + DEF_S(16), + DEF_S(17), + DEF_S(18), + DEF_S(19), + DEF_S(20), + DEF_S(21), + DEF_S(22), + DEF_S(23), + DEF_S(24), + DEF_S(25), + DEF_S(26), + DEF_S(27), + DEF_S(28), + DEF_S(29), + DEF_S(30), + DEF_S(31), + DEF_Q(0), + DEF_Q(1), + DEF_Q(2), + DEF_Q(3), + DEF_Q(4), + DEF_Q(5), + DEF_Q(6), + DEF_Q(7), + DEF_Q(8), + DEF_Q(9), + DEF_Q(10), + DEF_Q(11), + DEF_Q(12), + DEF_Q(13), + DEF_Q(14), + DEF_Q(15)}; + +constexpr size_t k_num_reg_infos = llvm::array_lengthof(g_reg_infos); + +// ARM general purpose registers. +const uint32_t g_gpr_regnums[] = { + reg_r0, + reg_r1, + reg_r2, + reg_r3, + reg_r4, + reg_r5, + reg_r6, + reg_r7, + reg_r8, + reg_r9, + reg_r10, + reg_r11, + reg_r12, + reg_sp, + reg_lr, + reg_pc, + reg_cpsr, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +const uint32_t g_fpu_regnums[] = { + reg_fpscr, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_q0, + reg_q1, + reg_q2, + reg_q3, + reg_q4, + reg_q5, + reg_q6, + reg_q7, + reg_q8, + reg_q9, + reg_q10, + reg_q11, + reg_q12, + reg_q13, + reg_q14, + reg_q15, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +// Skip the last LLDB_INVALID_REGNUM in each count below by subtracting 1 +constexpr size_t k_num_gpr_regs = llvm::array_lengthof(g_gpr_regnums) - 1; +constexpr size_t k_num_fpu_regs = llvm::array_lengthof(g_fpu_regnums) - 1; + +static RegisterSet g_reg_sets[] = { + {"General Purpose Registers", "gpr", k_num_gpr_regs, g_gpr_regnums}, + {"Floating Point Registers", "fpu", k_num_fpu_regs, g_fpu_regnums}, +}; + +constexpr size_t k_num_reg_sets = llvm::array_lengthof(g_reg_sets); + +RegisterContextMinidump_ARM::RegisterContextMinidump_ARM( + Thread &thread, const DataExtractor &data, bool apple) + : RegisterContext(thread, 0), m_apple(apple) { + lldb::offset_t offset = 0; + m_regs.context_flags = data.GetU32(&offset); + for (unsigned i = 0; i < llvm::array_lengthof(m_regs.r); ++i) + m_regs.r[i] = data.GetU32(&offset); + m_regs.cpsr = data.GetU32(&offset); + m_regs.fpscr = data.GetU64(&offset); + for (unsigned i = 0; i < llvm::array_lengthof(m_regs.d); ++i) + m_regs.d[i] = data.GetU64(&offset); + lldbassert(k_num_regs == k_num_reg_infos); +} + +size_t RegisterContextMinidump_ARM::GetRegisterCount() { return k_num_regs; } + +const RegisterInfo * +RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) { + if (reg < k_num_reg_infos) { + if (m_apple) { + if (reg == reg_r7) + return &g_reg_info_apple_fp; + } else { + if (reg == reg_r11) + return &g_reg_info_fp; + } + return &g_reg_infos[reg]; + } + return nullptr; +} + +size_t RegisterContextMinidump_ARM::GetRegisterSetCount() { + return k_num_reg_sets; +} + +const RegisterSet *RegisterContextMinidump_ARM::GetRegisterSet(size_t set) { + if (set < k_num_reg_sets) + return &g_reg_sets[set]; + return nullptr; +} + +const char *RegisterContextMinidump_ARM::GetRegisterName(unsigned reg) { + if (reg < k_num_reg_infos) + return g_reg_infos[reg].name; + return nullptr; +} + +bool RegisterContextMinidump_ARM::ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) { + Status error; + reg_value.SetFromMemoryData( + reg_info, (const uint8_t *)&m_regs + reg_info->byte_offset, + reg_info->byte_size, lldb::eByteOrderLittle, error); + return error.Success(); +} + +bool RegisterContextMinidump_ARM::WriteRegister(const RegisterInfo *, + const RegisterValue &) { + return false; +} + +uint32_t RegisterContextMinidump_ARM::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + for (size_t i = 0; i < k_num_regs; ++i) { + if (g_reg_infos[i].kinds[kind] == num) + return i; + } + return LLDB_INVALID_REGNUM; +} diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h new file mode 100644 index 000000000000..c410df99b1c1 --- /dev/null +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h @@ -0,0 +1,95 @@ +//===-- RegisterContextMinidump_ARM.h ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextMinidump_ARM_h_ +#define liblldb_RegisterContextMinidump_ARM_h_ + +// Project includes +#include "MinidumpTypes.h" + +// Other libraries and framework includes +#include "Plugins/Process/Utility/RegisterInfoInterface.h" + +#include "lldb/Target/RegisterContext.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitmaskEnum.h" + +// C includes +// C++ includes + +namespace lldb_private { + +namespace minidump { + +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + +class RegisterContextMinidump_ARM : public lldb_private::RegisterContext { +public: + RegisterContextMinidump_ARM(lldb_private::Thread &thread, + const DataExtractor &data, bool apple); + + ~RegisterContextMinidump_ARM() override = default; + + void InvalidateAllRegisters() override { + // Do nothing... registers are always valid... + } + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + + bool ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) override; + + bool WriteRegister(const RegisterInfo *reg_info, + const RegisterValue ®_value) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + + // Reference: see breakpad/crashpad source + struct QRegValue { + uint64_t lo; + uint64_t hi; + }; + + struct Context { + uint32_t context_flags; + uint32_t r[16]; + uint32_t cpsr; + uint64_t fpscr; + union { + uint64_t d[32]; + uint32_t s[32]; + QRegValue q[16]; + }; + uint32_t extra[8]; + }; + +protected: + enum class Flags : uint32_t { + ARM_Flag = 0x40000000, + Integer = ARM_Flag | 0x00000002, + FloatingPoint = ARM_Flag | 0x00000004, + LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ FloatingPoint) + }; + Context m_regs; + const bool m_apple; // True if this is an Apple ARM where FP is R7 +}; + +} // end namespace minidump +} // end namespace lldb_private +#endif // liblldb_RegisterContextMinidump_ARM_h_ diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp new file mode 100644 index 000000000000..5ba58d1ca81e --- /dev/null +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp @@ -0,0 +1,836 @@ +//===-- RegisterContextMinidump_ARM64.cpp -----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Project includes +#include "RegisterContextMinidump_ARM64.h" + +// Other libraries and framework includes +#include "Utility/ARM64_DWARF_Registers.h" +#include "lldb/Core/RegisterValue.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/lldb-enumerations.h" + +// C includes +#include + +// C++ includes + +using namespace lldb; +using namespace lldb_private; +using namespace minidump; + +#define INV LLDB_INVALID_REGNUM +#define OFFSET(r) (offsetof(RegisterContextMinidump_ARM64::Context, r)) + +#define DEF_X(i) \ + { \ + "x" #i, nullptr, 8, OFFSET(x[i]), eEncodingUint, eFormatHex, \ + {INV, arm64_dwarf::x##i, INV, INV, reg_x##i}, nullptr, nullptr, \ + nullptr, 0 \ + } + +#define DEF_W(i) \ + { \ + "w" #i, nullptr, 4, OFFSET(x[i]), eEncodingUint, eFormatHex, \ + {INV, INV, INV, INV, reg_w##i}, nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_X_ARG(i, n) \ + { \ + "x" #i, "arg" #n, 8, OFFSET(x[i]), eEncodingUint, eFormatHex, \ + {INV, arm64_dwarf::x##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_x##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_V(i) \ + { \ + "v" #i, nullptr, 16, OFFSET(v[i * 16]), eEncodingVector, \ + eFormatVectorOfUInt8, {INV, arm64_dwarf::v##i, INV, INV, reg_v##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_D(i) \ + { \ + "d" #i, nullptr, 8, OFFSET(v[i * 16]), eEncodingVector, \ + eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_d##i}, nullptr, \ + nullptr, nullptr, 0 \ + } + +#define DEF_S(i) \ + { \ + "s" #i, nullptr, 4, OFFSET(v[i * 16]), eEncodingVector, \ + eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_s##i}, nullptr, \ + nullptr, nullptr, 0 \ + } + +#define DEF_H(i) \ + { \ + "h" #i, nullptr, 2, OFFSET(v[i * 16]), eEncodingVector, \ + eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_h##i}, nullptr, \ + nullptr, nullptr, 0 \ + } + +// Zero based LLDB register numbers for this register context +enum { + // General Purpose Registers + reg_x0 = 0, + reg_x1, + reg_x2, + reg_x3, + reg_x4, + reg_x5, + reg_x6, + reg_x7, + reg_x8, + reg_x9, + reg_x10, + reg_x11, + reg_x12, + reg_x13, + reg_x14, + reg_x15, + reg_x16, + reg_x17, + reg_x18, + reg_x19, + reg_x20, + reg_x21, + reg_x22, + reg_x23, + reg_x24, + reg_x25, + reg_x26, + reg_x27, + reg_x28, + reg_fp, + reg_lr, + reg_sp, + reg_pc, + reg_w0, + reg_w1, + reg_w2, + reg_w3, + reg_w4, + reg_w5, + reg_w6, + reg_w7, + reg_w8, + reg_w9, + reg_w10, + reg_w11, + reg_w12, + reg_w13, + reg_w14, + reg_w15, + reg_w16, + reg_w17, + reg_w18, + reg_w19, + reg_w20, + reg_w21, + reg_w22, + reg_w23, + reg_w24, + reg_w25, + reg_w26, + reg_w27, + reg_w28, + reg_w29, + reg_w30, + reg_w31, + reg_cpsr, + // Floating Point Registers + reg_fpsr, + reg_fpcr, + reg_v0, + reg_v1, + reg_v2, + reg_v3, + reg_v4, + reg_v5, + reg_v6, + reg_v7, + reg_v8, + reg_v9, + reg_v10, + reg_v11, + reg_v12, + reg_v13, + reg_v14, + reg_v15, + reg_v16, + reg_v17, + reg_v18, + reg_v19, + reg_v20, + reg_v21, + reg_v22, + reg_v23, + reg_v24, + reg_v25, + reg_v26, + reg_v27, + reg_v28, + reg_v29, + reg_v30, + reg_v31, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_h0, + reg_h1, + reg_h2, + reg_h3, + reg_h4, + reg_h5, + reg_h6, + reg_h7, + reg_h8, + reg_h9, + reg_h10, + reg_h11, + reg_h12, + reg_h13, + reg_h14, + reg_h15, + reg_h16, + reg_h17, + reg_h18, + reg_h19, + reg_h20, + reg_h21, + reg_h22, + reg_h23, + reg_h24, + reg_h25, + reg_h26, + reg_h27, + reg_h28, + reg_h29, + reg_h30, + reg_h31, + k_num_regs +}; + +// Register info definitions for this register context +static RegisterInfo g_reg_infos[] = { + DEF_X_ARG(0, 1), + DEF_X_ARG(1, 2), + DEF_X_ARG(2, 3), + DEF_X_ARG(3, 4), + DEF_X_ARG(4, 5), + DEF_X_ARG(5, 6), + DEF_X_ARG(6, 7), + DEF_X_ARG(7, 8), + DEF_X(8), + DEF_X(9), + DEF_X(10), + DEF_X(11), + DEF_X(12), + DEF_X(13), + DEF_X(14), + DEF_X(15), + DEF_X(16), + DEF_X(17), + DEF_X(18), + DEF_X(19), + DEF_X(20), + DEF_X(21), + DEF_X(22), + DEF_X(23), + DEF_X(24), + DEF_X(25), + DEF_X(26), + DEF_X(27), + DEF_X(28), + {"fp", + "x29", + 8, + OFFSET(x[29]), + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, INV, reg_fp}, + nullptr, + nullptr, + nullptr, + 0}, + {"lr", + "x30", + 8, + OFFSET(x[30]), + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, + nullptr, + nullptr, + nullptr, + 0}, + {"sp", + "x31", + 8, + OFFSET(x[31]), + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, + nullptr, + nullptr, + nullptr, + 0}, + {"pc", + nullptr, + 8, + OFFSET(pc), + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, + nullptr, + nullptr, + nullptr, + 0}, + // w0 - w31 + DEF_W(0), + DEF_W(1), + DEF_W(2), + DEF_W(3), + DEF_W(4), + DEF_W(5), + DEF_W(6), + DEF_W(7), + DEF_W(8), + DEF_W(9), + DEF_W(10), + DEF_W(11), + DEF_W(12), + DEF_W(13), + DEF_W(14), + DEF_W(15), + DEF_W(16), + DEF_W(17), + DEF_W(18), + DEF_W(19), + DEF_W(20), + DEF_W(21), + DEF_W(22), + DEF_W(23), + DEF_W(24), + DEF_W(25), + DEF_W(26), + DEF_W(27), + DEF_W(28), + DEF_W(29), + DEF_W(30), + DEF_W(31), + {"cpsr", + "psr", + 4, + OFFSET(cpsr), + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, + nullptr, + nullptr, + nullptr, + 0}, + {"fpsr", + nullptr, + 4, + OFFSET(fpsr), + eEncodingUint, + eFormatHex, + {INV, INV, INV, INV, reg_fpsr}, + nullptr, + nullptr, + nullptr, + 0}, + {"fpcr", + nullptr, + 4, + OFFSET(fpcr), + eEncodingUint, + eFormatHex, + {INV, INV, INV, INV, reg_fpcr}, + nullptr, + nullptr, + nullptr, + 0}, + // v0 - v31 + DEF_V(0), + DEF_V(1), + DEF_V(2), + DEF_V(3), + DEF_V(4), + DEF_V(5), + DEF_V(6), + DEF_V(7), + DEF_V(8), + DEF_V(9), + DEF_V(10), + DEF_V(11), + DEF_V(12), + DEF_V(13), + DEF_V(14), + DEF_V(15), + DEF_V(16), + DEF_V(17), + DEF_V(18), + DEF_V(19), + DEF_V(20), + DEF_V(21), + DEF_V(22), + DEF_V(23), + DEF_V(24), + DEF_V(25), + DEF_V(26), + DEF_V(27), + DEF_V(28), + DEF_V(29), + DEF_V(30), + DEF_V(31), + // d0 - d31 + DEF_D(0), + DEF_D(1), + DEF_D(2), + DEF_D(3), + DEF_D(4), + DEF_D(5), + DEF_D(6), + DEF_D(7), + DEF_D(8), + DEF_D(9), + DEF_D(10), + DEF_D(11), + DEF_D(12), + DEF_D(13), + DEF_D(14), + DEF_D(15), + DEF_D(16), + DEF_D(17), + DEF_D(18), + DEF_D(19), + DEF_D(20), + DEF_D(21), + DEF_D(22), + DEF_D(23), + DEF_D(24), + DEF_D(25), + DEF_D(26), + DEF_D(27), + DEF_D(28), + DEF_D(29), + DEF_D(30), + DEF_D(31), + // s0 - s31 + DEF_S(0), + DEF_S(1), + DEF_S(2), + DEF_S(3), + DEF_S(4), + DEF_S(5), + DEF_S(6), + DEF_S(7), + DEF_S(8), + DEF_S(9), + DEF_S(10), + DEF_S(11), + DEF_S(12), + DEF_S(13), + DEF_S(14), + DEF_S(15), + DEF_S(16), + DEF_S(17), + DEF_S(18), + DEF_S(19), + DEF_S(20), + DEF_S(21), + DEF_S(22), + DEF_S(23), + DEF_S(24), + DEF_S(25), + DEF_S(26), + DEF_S(27), + DEF_S(28), + DEF_S(29), + DEF_S(30), + DEF_S(31), + // h0 - h31 + DEF_H(0), + DEF_H(1), + DEF_H(2), + DEF_H(3), + DEF_H(4), + DEF_H(5), + DEF_H(6), + DEF_H(7), + DEF_H(8), + DEF_H(9), + DEF_H(10), + DEF_H(11), + DEF_H(12), + DEF_H(13), + DEF_H(14), + DEF_H(15), + DEF_H(16), + DEF_H(17), + DEF_H(18), + DEF_H(19), + DEF_H(20), + DEF_H(21), + DEF_H(22), + DEF_H(23), + DEF_H(24), + DEF_H(25), + DEF_H(26), + DEF_H(27), + DEF_H(28), + DEF_H(29), + DEF_H(30), + DEF_H(31), +}; + +constexpr size_t k_num_reg_infos = llvm::array_lengthof(g_reg_infos); + +// ARM64 general purpose registers. +const uint32_t g_gpr_regnums[] = { + reg_x0, + reg_x1, + reg_x2, + reg_x3, + reg_x4, + reg_x5, + reg_x6, + reg_x7, + reg_x8, + reg_x9, + reg_x10, + reg_x11, + reg_x12, + reg_x13, + reg_x14, + reg_x15, + reg_x16, + reg_x17, + reg_x18, + reg_x19, + reg_x20, + reg_x21, + reg_x22, + reg_x23, + reg_x24, + reg_x25, + reg_x26, + reg_x27, + reg_x28, + reg_fp, + reg_lr, + reg_sp, + reg_w0, + reg_w1, + reg_w2, + reg_w3, + reg_w4, + reg_w5, + reg_w6, + reg_w7, + reg_w8, + reg_w9, + reg_w10, + reg_w11, + reg_w12, + reg_w13, + reg_w14, + reg_w15, + reg_w16, + reg_w17, + reg_w18, + reg_w19, + reg_w20, + reg_w21, + reg_w22, + reg_w23, + reg_w24, + reg_w25, + reg_w26, + reg_w27, + reg_w28, + reg_w29, + reg_w30, + reg_w31, + reg_pc, + reg_cpsr, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +const uint32_t g_fpu_regnums[] = { + reg_v0, + reg_v1, + reg_v2, + reg_v3, + reg_v4, + reg_v5, + reg_v6, + reg_v7, + reg_v8, + reg_v9, + reg_v10, + reg_v11, + reg_v12, + reg_v13, + reg_v14, + reg_v15, + reg_v16, + reg_v17, + reg_v18, + reg_v19, + reg_v20, + reg_v21, + reg_v22, + reg_v23, + reg_v24, + reg_v25, + reg_v26, + reg_v27, + reg_v28, + reg_v29, + reg_v30, + reg_v31, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_h0, + reg_h1, + reg_h2, + reg_h3, + reg_h4, + reg_h5, + reg_h6, + reg_h7, + reg_h8, + reg_h9, + reg_h10, + reg_h11, + reg_h12, + reg_h13, + reg_h14, + reg_h15, + reg_h16, + reg_h17, + reg_h18, + reg_h19, + reg_h20, + reg_h21, + reg_h22, + reg_h23, + reg_h24, + reg_h25, + reg_h26, + reg_h27, + reg_h28, + reg_h29, + reg_h30, + reg_h31, + reg_fpsr, + reg_fpcr, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +// Skip the last LLDB_INVALID_REGNUM in each count below by subtracting 1 +constexpr size_t k_num_gpr_regs = llvm::array_lengthof(g_gpr_regnums) - 1; +constexpr size_t k_num_fpu_regs = llvm::array_lengthof(g_fpu_regnums) - 1; + +static RegisterSet g_reg_sets[] = { + {"General Purpose Registers", "gpr", k_num_gpr_regs, g_gpr_regnums}, + {"Floating Point Registers", "fpu", k_num_fpu_regs, g_fpu_regnums}, +}; + +constexpr size_t k_num_reg_sets = llvm::array_lengthof(g_reg_sets); + +RegisterContextMinidump_ARM64::RegisterContextMinidump_ARM64( + Thread &thread, const DataExtractor &data) + : RegisterContext(thread, 0) { + lldb::offset_t offset = 0; + m_regs.context_flags = data.GetU64(&offset); + for (unsigned i = 0; i < 32; ++i) + m_regs.x[i] = data.GetU64(&offset); + m_regs.pc = data.GetU64(&offset); + m_regs.cpsr = data.GetU32(&offset); + m_regs.fpsr = data.GetU32(&offset); + m_regs.fpcr = data.GetU32(&offset); + auto regs_data = data.GetData(&offset, sizeof(m_regs.v)); + if (regs_data) + memcpy(m_regs.v, regs_data, sizeof(m_regs.v)); + assert(k_num_regs == k_num_reg_infos); +} +size_t RegisterContextMinidump_ARM64::GetRegisterCount() { return k_num_regs; } + +const RegisterInfo * +RegisterContextMinidump_ARM64::GetRegisterInfoAtIndex(size_t reg) { + if (reg < k_num_reg_infos) + return &g_reg_infos[reg]; + return nullptr; +} + +size_t RegisterContextMinidump_ARM64::GetRegisterSetCount() { + return k_num_reg_sets; +} + +const RegisterSet *RegisterContextMinidump_ARM64::GetRegisterSet(size_t set) { + if (set < k_num_reg_sets) + return &g_reg_sets[set]; + return nullptr; +} + +const char *RegisterContextMinidump_ARM64::GetRegisterName(unsigned reg) { + if (reg < k_num_reg_infos) + return g_reg_infos[reg].name; + return nullptr; +} + +bool RegisterContextMinidump_ARM64::ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) { + Status error; + reg_value.SetFromMemoryData( + reg_info, (const uint8_t *)&m_regs + reg_info->byte_offset, + reg_info->byte_size, lldb::eByteOrderLittle, error); + return error.Success(); +} + +bool RegisterContextMinidump_ARM64::WriteRegister(const RegisterInfo *, + const RegisterValue &) { + return false; +} + +uint32_t RegisterContextMinidump_ARM64::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + for (size_t i = 0; i < k_num_regs; ++i) { + if (g_reg_infos[i].kinds[kind] == num) + return i; + } + return LLDB_INVALID_REGNUM; +} diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h new file mode 100644 index 000000000000..2a3f254c8510 --- /dev/null +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h @@ -0,0 +1,85 @@ +//===-- RegisterContextMinidump_ARM64.h -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextMinidump_ARM64_h_ +#define liblldb_RegisterContextMinidump_ARM64_h_ + +// Project includes +#include "MinidumpTypes.h" + +// Other libraries and framework includes +#include "Plugins/Process/Utility/RegisterInfoInterface.h" +#include "lldb/Target/RegisterContext.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitmaskEnum.h" + +// C includes +// C++ includes + +namespace lldb_private { + +namespace minidump { + +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + +class RegisterContextMinidump_ARM64 : public lldb_private::RegisterContext { +public: + RegisterContextMinidump_ARM64(lldb_private::Thread &thread, + const DataExtractor &data); + + ~RegisterContextMinidump_ARM64() override = default; + + void InvalidateAllRegisters() override { + // Do nothing... registers are always valid... + } + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + + bool ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) override; + + bool WriteRegister(const RegisterInfo *reg_info, + const RegisterValue ®_value) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + + // Reference: see breakpad/crashpad source + struct Context { + uint64_t context_flags; + uint64_t x[32]; + uint64_t pc; + uint32_t cpsr; + uint32_t fpsr; + uint32_t fpcr; + uint8_t v[32 * 16]; // 32 128-bit floating point registers + }; + +protected: + enum class Flags : uint32_t { + ARM64_Flag = 0x80000000, + Integer = ARM64_Flag | 0x00000002, + FloatingPoint = ARM64_Flag | 0x00000004, + LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ FloatingPoint) + }; + Context m_regs; +}; + +} // end namespace minidump +} // end namespace lldb_private +#endif // liblldb_RegisterContextMinidump_ARM64_h_ diff --git a/source/Plugins/Process/minidump/ThreadMinidump.cpp b/source/Plugins/Process/minidump/ThreadMinidump.cpp index 3fafb6134e7f..f0c1c1e2f1e3 100644 --- a/source/Plugins/Process/minidump/ThreadMinidump.cpp +++ b/source/Plugins/Process/minidump/ThreadMinidump.cpp @@ -11,6 +11,8 @@ #include "ThreadMinidump.h" #include "ProcessMinidump.h" +#include "RegisterContextMinidump_ARM.h" +#include "RegisterContextMinidump_ARM64.h" #include "RegisterContextMinidump_x86_32.h" #include "RegisterContextMinidump_x86_64.h" @@ -88,15 +90,22 @@ ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) { *this, reg_interface, gpregset, {})); break; } - default: + case llvm::Triple::aarch64: { + DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(), + lldb::eByteOrderLittle, 8); + m_thread_reg_ctx_sp.reset(new RegisterContextMinidump_ARM64(*this, data)); break; } - - if (!reg_interface) { - if (log) - log->Printf("elf-core::%s:: Architecture(%d) not supported", - __FUNCTION__, arch.GetMachine()); - assert(false && "Architecture not supported"); + case llvm::Triple::arm: { + DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(), + lldb::eByteOrderLittle, 8); + const bool apple = arch.GetTriple().getVendor() == llvm::Triple::Apple; + m_thread_reg_ctx_sp.reset( + new RegisterContextMinidump_ARM(*this, data, apple)); + break; + } + default: + break; } reg_ctx_sp = m_thread_reg_ctx_sp; diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp index 3f70741713fb..a98495d17449 100644 --- a/source/Target/Target.cpp +++ b/source/Target/Target.cpp @@ -1426,13 +1426,33 @@ void Target::SetExecutableModule(ModuleSP &executable_sp, } } -bool Target::SetArchitecture(const ArchSpec &arch_spec) { +bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); bool missing_local_arch = !m_arch.GetSpec().IsValid(); bool replace_local_arch = true; bool compatible_local_arch = false; ArchSpec other(arch_spec); + // Changing the architecture might mean that the currently selected platform + // isn't compatible. Set the platform correctly if we are asked to do so, + // otherwise assume the user will set the platform manually. + if (set_platform) { + if (other.IsValid()) { + auto platform_sp = GetPlatform(); + if (!platform_sp || + !platform_sp->IsCompatibleArchitecture(other, false, nullptr)) { + ArchSpec platform_arch; + auto arch_platform_sp = + Platform::GetPlatformForArchitecture(other, &platform_arch); + if (arch_platform_sp) { + SetPlatform(arch_platform_sp); + if (platform_arch.IsValid()) + other = platform_arch; + } + } + } + } + if (!missing_local_arch) { if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) { other.MergeFrom(m_arch.GetSpec()); From d3ab1884eddf027e7fb1ef12bfc7375dec2a2021 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Thu, 2 Aug 2018 17:44:41 +0000 Subject: [PATCH 0045/1112] Fix CMake build. Some new files were committed to the repository but not added to the CMakeLists.txt, so this patch fixes the build. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338746 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Plugins/Process/minidump/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/Plugins/Process/minidump/CMakeLists.txt b/source/Plugins/Process/minidump/CMakeLists.txt index b898ee1aa144..4126a7ea991c 100644 --- a/source/Plugins/Process/minidump/CMakeLists.txt +++ b/source/Plugins/Process/minidump/CMakeLists.txt @@ -1,6 +1,8 @@ add_lldb_library(lldbPluginProcessMinidump PLUGIN MinidumpTypes.cpp MinidumpParser.cpp + RegisterContextMinidump_ARM.cpp + RegisterContextMinidump_ARM64.cpp RegisterContextMinidump_x86_32.cpp RegisterContextMinidump_x86_64.cpp ProcessMinidump.cpp From 3ab6fe09868dc5d5d54d49adaf4569d378f772b3 Mon Sep 17 00:00:00 2001 From: Stella Stamenova Date: Thu, 2 Aug 2018 21:26:19 +0000 Subject: [PATCH 0046/1112] [lldbsuite, windows] Mark tests as XFAIL on Windows or skip them Summary: 1) Several tests that are flakey on windows fail the run even if they are marked as expected to be flakey. This is because they fail frequently enough that even a retry won't help 2) Skip several tests on Windows that will occasionally hang rather than failing or exiting. This is causing the entire test suite to hang Reviewers: asmith, labath, zturner Reviewed By: zturner Differential Revision: https://reviews.llvm.org/D50198 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338769 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../functionalities/attach_resume/TestAttachResume.py | 2 +- .../breakpoint_ignore_count/TestBreakpointIgnoreCount.py | 2 ++ .../test/functionalities/memory/cache/TestMemoryCache.py | 4 +++- .../thread/exit_during_step/TestExitDuringStep.py | 9 +++++++++ .../functionalities/thread/step_out/TestThreadStepOut.py | 3 +++ .../functionalities/thread/thread_exit/TestThreadExit.py | 4 ++++ .../lldbsuite/test/lang/cpp/virtual/TestVirtual.py | 1 + .../Python/lldbsuite/test/python_api/event/TestEvents.py | 1 + 8 files changed, 24 insertions(+), 2 deletions(-) diff --git a/packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py b/packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py index ad87796766c3..754acade015a 100644 --- a/packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py +++ b/packages/Python/lldbsuite/test/functionalities/attach_resume/TestAttachResume.py @@ -21,7 +21,7 @@ class AttachResumeTestCase(TestBase): @skipIfRemote @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr19310') - @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24778") + @skipIfWindows # llvm.org/pr24778, llvm.org/pr21753 def test_attach_continue_interrupt_detach(self): """Test attach/continue/interrupt/detach""" self.build() diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py index eb4bac7e6e66..e3bf4c27f31e 100644 --- a/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/breakpoint_ignore_count/TestBreakpointIgnoreCount.py @@ -18,12 +18,14 @@ class BreakpointIgnoreCountTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) + @skipIfWindows # This test will hang on windows llvm.org/pr21753 def test_with_run_command(self): """Exercise breakpoint ignore count with 'breakpoint set -i '.""" self.build() self.breakpoint_ignore_count() @add_test_categories(['pyapi']) + @skipIfWindows # This test will hang on windows llvm.org/pr21753 def test_with_python_api(self): """Use Python APIs to set breakpoint ignore count.""" self.build() diff --git a/packages/Python/lldbsuite/test/functionalities/memory/cache/TestMemoryCache.py b/packages/Python/lldbsuite/test/functionalities/memory/cache/TestMemoryCache.py index f45479bee0bf..6775e1634b89 100644 --- a/packages/Python/lldbsuite/test/functionalities/memory/cache/TestMemoryCache.py +++ b/packages/Python/lldbsuite/test/functionalities/memory/cache/TestMemoryCache.py @@ -24,7 +24,9 @@ def setUp(self): # Find the line number to break inside main(). self.line = line_number('main.cpp', '// Set break point at this line.') - @expectedFlakeyOS(oslist=["windows"]) + # The test is actually flakey on Windows, failing every dozen or so runs, but even with the flakey + # decorator it still fails + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr38373") def test_memory_cache(self): """Test the MemoryCache class with a sequence of 'memory read' and 'memory write' operations.""" self.build() diff --git a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py index 0343a888a0f1..f83b467f585c 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/exit_during_step/TestExitDuringStep.py @@ -18,6 +18,9 @@ class ExitDuringStepTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) @skipIfFreeBSD # llvm.org/pr21411: test is hanging + # The test is actually flakey on Windows, failing every dozen or so runs, but even with the flakey + # decorator it still fails + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr38373") def test(self): """Test thread exit during step handling.""" self.build(dictionary=self.getBuildFlags()) @@ -27,6 +30,9 @@ def test(self): True) @skipIfFreeBSD # llvm.org/pr21411: test is hanging + # The test is actually flakey on Windows, failing every dozen or so runs, but even with the flakey + # decorator it still fails + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr38373") def test_step_over(self): """Test thread exit during step-over handling.""" self.build(dictionary=self.getBuildFlags()) @@ -36,6 +42,9 @@ def test_step_over(self): False) @skipIfFreeBSD # llvm.org/pr21411: test is hanging + # The test is actually flakey on Windows, failing every dozen or so runs, but even with the flakey + # decorator it still fails + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr38373") def test_step_in(self): """Test thread exit during step-in handling.""" self.build(dictionary=self.getBuildFlags()) diff --git a/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py b/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py index 238b18837884..e786e8d7ff1e 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/step_out/TestThreadStepOut.py @@ -25,6 +25,7 @@ class ThreadStepOutTestCase(TestBase): @expectedFailureAll( oslist=["freebsd"], bugnumber="llvm.org/pr18066 inferior does not exit") + @skipIfWindows # This test will hang on windows llvm.org/pr21753 @expectedFailureAll(oslist=["windows"]) def test_step_single_thread(self): """Test thread step out on one thread via command interpreter. """ @@ -39,6 +40,7 @@ def test_step_single_thread(self): @expectedFailureAll( oslist=["freebsd"], bugnumber="llvm.org/pr19347 2nd thread stops at breakpoint") + @skipIfWindows # This test will hang on windows llvm.org/pr21753 @expectedFailureAll(oslist=["windows"]) @expectedFailureAll(oslist=["watchos"], archs=['armv7k'], bugnumber="rdar://problem/34674488") # stop reason is trace when it should be step-out def test_step_all_threads(self): @@ -54,6 +56,7 @@ def test_step_all_threads(self): @expectedFailureAll( oslist=["freebsd"], bugnumber="llvm.org/pr19347 2nd thread stops at breakpoint") + @skipIfWindows # This test will hang on windows llvm.org/pr21753 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24681") def test_python(self): """Test thread step out on one thread via Python API (dwarf).""" diff --git a/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py b/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py index 07ceb3f5f6b7..db1d31da61c9 100644 --- a/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py +++ b/packages/Python/lldbsuite/test/functionalities/thread/thread_exit/TestThreadExit.py @@ -8,6 +8,7 @@ import os import time import lldb +from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * import lldbsuite.test.lldbutil as lldbutil @@ -25,6 +26,9 @@ def setUp(self): self.break_3 = line_number('main.cpp', '// Set third breakpoint here') self.break_4 = line_number('main.cpp', '// Set fourth breakpoint here') + # The test is actually flakey on Windows, failing every dozen or so runs, but even with the flakey + # decorator it still fails + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr38373") def test(self): """Test thread exit handling.""" self.build(dictionary=self.getBuildFlags()) diff --git a/packages/Python/lldbsuite/test/lang/cpp/virtual/TestVirtual.py b/packages/Python/lldbsuite/test/lang/cpp/virtual/TestVirtual.py index b3fe9c40c198..365eb829ba64 100644 --- a/packages/Python/lldbsuite/test/lang/cpp/virtual/TestVirtual.py +++ b/packages/Python/lldbsuite/test/lang/cpp/virtual/TestVirtual.py @@ -36,6 +36,7 @@ def setUp(self): @expectedFailureAll( compiler="icc", bugnumber="llvm.org/pr16808 lldb does not call the correct virtual function with icc.") + @skipIfWindows # This test will hang on windows llvm.org/pr21753 def test_virtual_madness(self): """Test that expression works correctly with virtual inheritance as well as virtual function.""" self.build() diff --git a/packages/Python/lldbsuite/test/python_api/event/TestEvents.py b/packages/Python/lldbsuite/test/python_api/event/TestEvents.py index 8a9e456f3458..9c8fa9782079 100644 --- a/packages/Python/lldbsuite/test/python_api/event/TestEvents.py +++ b/packages/Python/lldbsuite/test/python_api/event/TestEvents.py @@ -31,6 +31,7 @@ def setUp(self): @expectedFailureAll( oslist=["linux"], bugnumber="llvm.org/pr23730 Flaky, fails ~1/10 cases") + @skipIfWindows # This test will hang on windows llvm.org/pr21753 def test_listen_for_and_print_event(self): """Exercise SBEvent API.""" self.build() From 6c99574e77ed86aacd6528b57fd0d528abf26d2c Mon Sep 17 00:00:00 2001 From: "David L. Jones" Date: Thu, 2 Aug 2018 21:45:05 +0000 Subject: [PATCH 0047/1112] [lldb] Remove unused variable. The use of this variable was removed in r338734. It now causes unused variable warnings. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338772 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Plugins/Process/minidump/ThreadMinidump.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/source/Plugins/Process/minidump/ThreadMinidump.cpp b/source/Plugins/Process/minidump/ThreadMinidump.cpp index f0c1c1e2f1e3..97493ebfd558 100644 --- a/source/Plugins/Process/minidump/ThreadMinidump.cpp +++ b/source/Plugins/Process/minidump/ThreadMinidump.cpp @@ -56,7 +56,6 @@ RegisterContextSP ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) { RegisterContextSP reg_ctx_sp; uint32_t concrete_frame_idx = 0; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (frame) concrete_frame_idx = frame->GetConcreteFrameIndex(); From 99c3f2c9e20b812d949a74cd1825612711fcbbce Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Fri, 3 Aug 2018 08:47:22 +0000 Subject: [PATCH 0048/1112] Revert "Add support for ARM and ARM64 breakpad generated minidump files" This reverts commit r338734 (and subsequent fixups in r338772 and r338746), because it breaks some minidump unit tests and introduces a lot of compiler warnings. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338828 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Target/Target.h | 30 +- lldb.xcodeproj/project.pbxproj | 16 - .../xcshareddata/xcschemes/desktop.xcscheme | 2 +- .../minidump-new/TestMiniDumpNew.py | 155 ---- .../postmortem/minidump-new/arm-linux.dmp | Bin 588 -> 0 bytes .../postmortem/minidump-new/arm-macos.dmp | Bin 588 -> 0 bytes .../postmortem/minidump-new/arm64-macos.dmp | Bin 1016 -> 0 bytes .../Plugins/Process/minidump/CMakeLists.txt | 2 - .../Process/minidump/MinidumpParser.cpp | 140 ++- .../Plugins/Process/minidump/MinidumpParser.h | 1 - .../Process/minidump/ProcessMinidump.cpp | 14 +- .../minidump/RegisterContextMinidump_ARM.cpp | 532 ----------- .../minidump/RegisterContextMinidump_ARM.h | 95 -- .../RegisterContextMinidump_ARM64.cpp | 836 ------------------ .../minidump/RegisterContextMinidump_ARM64.h | 85 -- .../Process/minidump/ThreadMinidump.cpp | 24 +- source/Target/Target.cpp | 22 +- 17 files changed, 92 insertions(+), 1862 deletions(-) delete mode 100644 packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-linux.dmp delete mode 100644 packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-macos.dmp delete mode 100644 packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm64-macos.dmp delete mode 100644 source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp delete mode 100644 source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h delete mode 100644 source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp delete mode 100644 source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h diff --git a/include/lldb/Target/Target.h b/include/lldb/Target/Target.h index a4a00eb2d371..75af8e80d2e5 100644 --- a/include/lldb/Target/Target.h +++ b/include/lldb/Target/Target.h @@ -913,30 +913,28 @@ class Target : public std::enable_shared_from_this, /// Set the architecture for this target. /// /// If the current target has no Images read in, then this just sets the - /// architecture, which will be used to select the architecture of the - /// ExecutableModule when that is set. If the current target has an - /// ExecutableModule, then calling SetArchitecture with a different + /// architecture, which will + /// be used to select the architecture of the ExecutableModule when that is + /// set. + /// If the current target has an ExecutableModule, then calling + /// SetArchitecture with a different /// architecture from the currently selected one will reset the - /// ExecutableModule to that slice of the file backing the ExecutableModule. - /// If the file backing the ExecutableModule does not contain a fork of this - /// architecture, then this code will return false, and the architecture - /// won't be changed. If the input arch_spec is the same as the already set - /// architecture, this is a no-op. + /// ExecutableModule to that slice + /// of the file backing the ExecutableModule. If the file backing the + /// ExecutableModule does not + /// contain a fork of this architecture, then this code will return false, and + /// the architecture + /// won't be changed. + /// If the input arch_spec is the same as the already set architecture, this + /// is a no-op. /// /// @param[in] arch_spec /// The new architecture. /// - /// @param[in] set_platform - /// If \b true, then the platform will be adjusted if the currently - /// selected platform is not compatible with the archicture being set. - /// If \b false, then just the architecture will be set even if the - /// currently selected platform isn't compatible (in case it might be - /// manually set following this function call). - /// /// @return /// \b true if the architecture was successfully set, \bfalse otherwise. //------------------------------------------------------------------ - bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform = false); + bool SetArchitecture(const ArchSpec &arch_spec); bool MergeArchitecture(const ArchSpec &arch_spec); diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index f34c403c959e..3faf425351bd 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -665,10 +665,6 @@ 26474CBE18D0CB2D0073DEBA /* RegisterContextMach_i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26474CB818D0CB2D0073DEBA /* RegisterContextMach_i386.cpp */; }; 26474CC018D0CB2D0073DEBA /* RegisterContextMach_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26474CBA18D0CB2D0073DEBA /* RegisterContextMach_x86_64.cpp */; }; 26474CC918D0CB5B0073DEBA /* RegisterContextMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26474CC218D0CB5B0073DEBA /* RegisterContextMemory.cpp */; }; - 2619C4852107A9A2009CDE81 /* RegisterContextMinidump_ARM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2619C4812107A9A1009CDE81 /* RegisterContextMinidump_ARM.cpp */; }; - 2619C4872107A9A2009CDE81 /* RegisterContextMinidump_ARM.h in Headers */ = {isa = PBXBuildFile; fileRef = 2619C4832107A9A2009CDE81 /* RegisterContextMinidump_ARM.h */; }; - 2619C4842107A9A2009CDE81 /* RegisterContextMinidump_ARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2619C4802107A9A1009CDE81 /* RegisterContextMinidump_ARM64.cpp */; }; - 2619C4862107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h in Headers */ = {isa = PBXBuildFile; fileRef = 2619C4822107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h */; }; 947CF7761DC7B20D00EF980B /* RegisterContextMinidump_x86_32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 947CF7741DC7B20D00EF980B /* RegisterContextMinidump_x86_32.cpp */; }; AFD65C811D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFD65C7F1D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp */; }; AFD65C821D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = AFD65C801D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.h */; }; @@ -2546,10 +2542,6 @@ 26474CC218D0CB5B0073DEBA /* RegisterContextMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextMemory.cpp; path = Utility/RegisterContextMemory.cpp; sourceTree = ""; }; 262D24E513FB8710002D1960 /* RegisterContextMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextMemory.h; path = Utility/RegisterContextMemory.h; sourceTree = ""; }; 26474CC318D0CB5B0073DEBA /* RegisterContextMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextMemory.h; path = Utility/RegisterContextMemory.h; sourceTree = ""; }; - 2619C4812107A9A1009CDE81 /* RegisterContextMinidump_ARM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextMinidump_ARM.cpp; sourceTree = ""; }; - 2619C4832107A9A2009CDE81 /* RegisterContextMinidump_ARM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextMinidump_ARM.h; sourceTree = ""; }; - 2619C4802107A9A1009CDE81 /* RegisterContextMinidump_ARM64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextMinidump_ARM64.cpp; sourceTree = ""; }; - 2619C4822107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextMinidump_ARM64.h; sourceTree = ""; }; 947CF7741DC7B20D00EF980B /* RegisterContextMinidump_x86_32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextMinidump_x86_32.cpp; sourceTree = ""; }; 947CF7721DC7B20300EF980B /* RegisterContextMinidump_x86_32.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RegisterContextMinidump_x86_32.h; sourceTree = ""; }; AFD65C7F1D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextMinidump_x86_64.cpp; sourceTree = ""; }; @@ -3795,10 +3787,6 @@ 23E2E5351D9048E7006F38BB /* minidump */ = { isa = PBXGroup; children = ( - 2619C4812107A9A1009CDE81 /* RegisterContextMinidump_ARM.cpp */, - 2619C4832107A9A2009CDE81 /* RegisterContextMinidump_ARM.h */, - 2619C4802107A9A1009CDE81 /* RegisterContextMinidump_ARM64.cpp */, - 2619C4822107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h */, AFD65C7F1D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp */, AFD65C801D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.h */, 23E2E5361D9048FB006F38BB /* CMakeLists.txt */, @@ -6951,10 +6939,8 @@ AF6CA6681FBBAF37005A0DC3 /* ArchSpec.h in Headers */, AF235EB41FBE7858009C5541 /* RegisterInfoPOSIX_ppc64le.h in Headers */, AF2E02A41FA2CEAF00A86C34 /* ArchitectureArm.h in Headers */, - 2619C4872107A9A2009CDE81 /* RegisterContextMinidump_ARM.h in Headers */, 267F685A1CC02EBE0086832B /* RegisterInfos_s390x.h in Headers */, 267F68541CC02E920086832B /* RegisterContextLinux_s390x.h in Headers */, - 2619C4862107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h in Headers */, AF235EB11FBE77B6009C5541 /* RegisterContextPOSIX_ppc64le.h in Headers */, 267F68501CC02E270086832B /* RegisterContextPOSIXCore_s390x.h in Headers */, 4984BA181B979C08008658D4 /* ExpressionVariable.h in Headers */, @@ -7657,7 +7643,6 @@ 2689002113353DDE00698AC0 /* CommandObjectQuit.cpp in Sources */, 2689002213353DDE00698AC0 /* CommandObjectRegister.cpp in Sources */, 26BC17AF18C7F4CB00D2196D /* RegisterContextPOSIXCore_x86_64.cpp in Sources */, - 2619C4842107A9A2009CDE81 /* RegisterContextMinidump_ARM64.cpp in Sources */, 2689002313353DDE00698AC0 /* CommandObjectScript.cpp in Sources */, 2689002413353DDE00698AC0 /* CommandObjectSettings.cpp in Sources */, 2689002513353DDE00698AC0 /* CommandObjectSource.cpp in Sources */, @@ -7738,7 +7723,6 @@ 2689005113353E0400698AC0 /* StringList.cpp in Sources */, 2689005213353E0400698AC0 /* Timer.cpp in Sources */, 2689005413353E0400698AC0 /* UserSettingsController.cpp in Sources */, - 2619C4852107A9A2009CDE81 /* RegisterContextMinidump_ARM.cpp in Sources */, 23059A0719532B96007B8189 /* LinuxSignals.cpp in Sources */, 8CCB017E19BA28A80009FD44 /* ThreadCollection.cpp in Sources */, 9A77AD541E64E2760025CE04 /* RegisterInfoPOSIX_arm.cpp in Sources */, diff --git a/lldb.xcodeproj/xcshareddata/xcschemes/desktop.xcscheme b/lldb.xcodeproj/xcshareddata/xcschemes/desktop.xcscheme index f9b0cfec7b03..d31912ef4837 100644 --- a/lldb.xcodeproj/xcshareddata/xcschemes/desktop.xcscheme +++ b/lldb.xcodeproj/xcshareddata/xcschemes/desktop.xcscheme @@ -42,7 +42,7 @@ > 1) + 1 - if i & 1: - value = "%#8.8x" % (i_val | i_val << 16) - else: - value = "%#8.8x" % (i_val | i_val << 8) - self.check_register_string_value(fpr, "s%i" % (i), value, - lldb.eFormatHex) - # Check q0 - q15 - for i in range(15): - a = i * 2 + 1 - b = a + 1 - value = ("0x00%2.2x00%2.2x0000%2.2x%2.2x" - "00%2.2x00%2.2x0000%2.2x%2.2x") % (b, b, b, b, a, a, a, a) - self.check_register_string_value(fpr, "q%i" % (i), value, - lldb.eFormatHex) - - def test_linux_arm_registers(self): - """Test Linux ARM registers from a breakpad created minidump. - - The frame pointer is R11 for linux. - """ - self.verify_arm_registers(apple=False) - - def test_apple_arm_registers(self): - """Test Apple ARM registers from a breakpad created minidump. - - The frame pointer is R7 for linux. - """ - self.verify_arm_registers(apple=True) - def do_test_deeper_stack(self, binary, core, pid): target = self.dbg.CreateTarget(binary) process = target.LoadCore(core) diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-linux.dmp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-linux.dmp deleted file mode 100644 index 3b0cb8268defef9d4cb64a7f574b8ff8ead084f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 588 zcmaKqPfmky5Jo?sKnpE}7D|DZHr_zHap@nnP26||*X~^C%9VS)gNax03O$0}#Wzjd z5aaLV6*__WX43Av{mtvU3$TBH|*-Vs(6&+wn~k)A?biMqd~lBY+wQiv?QHwnuJ8l1ycf>^ diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-macos.dmp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-macos.dmp deleted file mode 100644 index 9ff6a8396ec5c448dbd0af82ee66812d0adec94c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 588 zcmaKqPfmky5Jo?sKnpE}7D|DZHr_zHap@nnP26||*X~^C#+`e;gNax03O$0}#Wzjd z5aaLV6*__WX43Av{mtvU3$TBH|*-Vs(6&+wn~k)A?biMqd~lBY+wQiv?QHwnuJ8k~$rsK5 diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm64-macos.dmp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm64-macos.dmp deleted file mode 100644 index ba658dd48feb905d3ca851b66fb4dcda5c8828d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1016 zcmaKpNlwE+6htcn34w&znFnWN9wk5^4iJ`+*l-1|zycPqV-FinfW#HJ0!QF5yx)lv z+d^1+)xWxbcbD4J$@J#+L&``RLh{QqaRn17Lkk|k`fdKr>L(=erJkkl#N1yt#pFX` z!RFlOg~k74K$ss|ig2n6UF(eTQaS0#cG`Jq5~mq6%DU`XtxyTgfzZ75qpKja07BP5 z=sE~3g56be_m#9kCA19oMxJ{oPd=5<3J9%&&>9G>gU|*DZGzAi*gLn~TesDr650i! z0SN7Z&^`zqfY2e>zZ`+kv0M=9$@$oSxxc&p{`!1ZDxJx$( + static_cast(system_info->processor_arch)); + + switch (arch) { + case MinidumpCPUArchitecture::X86: + triple.setArch(llvm::Triple::ArchType::x86); + break; + case MinidumpCPUArchitecture::AMD64: + triple.setArch(llvm::Triple::ArchType::x86_64); + break; + case MinidumpCPUArchitecture::ARM: + triple.setArch(llvm::Triple::ArchType::arm); + break; + case MinidumpCPUArchitecture::ARM64: + triple.setArch(llvm::Triple::ArchType::aarch64); + break; + default: + triple.setArch(llvm::Triple::ArchType::UnknownArch); + break; + } + + const MinidumpOSPlatform os = static_cast( + static_cast(system_info->platform_id)); + + // TODO add all of the OSes that Minidump/breakpad distinguishes? + switch (os) { + case MinidumpOSPlatform::Win32S: + case MinidumpOSPlatform::Win32Windows: + case MinidumpOSPlatform::Win32NT: + case MinidumpOSPlatform::Win32CE: + triple.setOS(llvm::Triple::OSType::Win32); + break; + case MinidumpOSPlatform::Linux: + triple.setOS(llvm::Triple::OSType::Linux); + break; + case MinidumpOSPlatform::MacOSX: + triple.setOS(llvm::Triple::OSType::MacOSX); + break; + case MinidumpOSPlatform::Android: + triple.setOS(llvm::Triple::OSType::Linux); + triple.setEnvironment(llvm::Triple::EnvironmentType::Android); + break; + default: + triple.setOS(llvm::Triple::OSType::UnknownOS); + break; + } + + arch_spec.SetTriple(triple); + + return arch_spec; +} const MinidumpMiscInfo *MinidumpParser::GetMiscInfo() { llvm::ArrayRef data = GetStream(MinidumpStreamType::MiscInfo); @@ -488,79 +552,5 @@ Status MinidumpParser::Initialize() { return error; } - // Set the architecture in m_arch - const MinidumpSystemInfo *system_info = GetSystemInfo(); - - if (!system_info) { - error.SetErrorString("invalid minidump: missing system info"); - return error; - } - - // TODO what to do about big endiand flavors of arm ? - // TODO set the arm subarch stuff if the minidump has info about it - - llvm::Triple triple; - triple.setVendor(llvm::Triple::VendorType::UnknownVendor); - - const MinidumpCPUArchitecture arch = - static_cast( - static_cast(system_info->processor_arch)); - - switch (arch) { - case MinidumpCPUArchitecture::X86: - triple.setArch(llvm::Triple::ArchType::x86); - break; - case MinidumpCPUArchitecture::AMD64: - triple.setArch(llvm::Triple::ArchType::x86_64); - break; - case MinidumpCPUArchitecture::ARM: - triple.setArch(llvm::Triple::ArchType::arm); - break; - case MinidumpCPUArchitecture::ARM64: - triple.setArch(llvm::Triple::ArchType::aarch64); - break; - default: - triple.setArch(llvm::Triple::ArchType::UnknownArch); - break; - } - - const MinidumpOSPlatform os = static_cast( - static_cast(system_info->platform_id)); - - // TODO add all of the OSes that Minidump/breakpad distinguishes? - switch (os) { - case MinidumpOSPlatform::Win32S: - case MinidumpOSPlatform::Win32Windows: - case MinidumpOSPlatform::Win32NT: - case MinidumpOSPlatform::Win32CE: - triple.setOS(llvm::Triple::OSType::Win32); - break; - case MinidumpOSPlatform::Linux: - triple.setOS(llvm::Triple::OSType::Linux); - break; - case MinidumpOSPlatform::MacOSX: - triple.setOS(llvm::Triple::OSType::MacOSX); - triple.setVendor(llvm::Triple::Apple); - break; - case MinidumpOSPlatform::IOS: - triple.setOS(llvm::Triple::OSType::IOS); - triple.setVendor(llvm::Triple::Apple); - break; - case MinidumpOSPlatform::Android: - triple.setOS(llvm::Triple::OSType::Linux); - triple.setEnvironment(llvm::Triple::EnvironmentType::Android); - break; - default: { - triple.setOS(llvm::Triple::OSType::UnknownOS); - std::string csd_version; - if (auto s = GetMinidumpString(system_info->csd_version_rva)) - csd_version = *s; - if (csd_version.find("Linux") != std::string::npos) - triple.setOS(llvm::Triple::OSType::Linux); - break; - } - } - m_arch.SetTriple(triple); - return error; } diff --git a/source/Plugins/Process/minidump/MinidumpParser.h b/source/Plugins/Process/minidump/MinidumpParser.h index 48c752b541eb..49b1eef14de5 100644 --- a/source/Plugins/Process/minidump/MinidumpParser.h +++ b/source/Plugins/Process/minidump/MinidumpParser.h @@ -98,7 +98,6 @@ class MinidumpParser { private: lldb::DataBufferSP m_data_sp; llvm::DenseMap m_directory_map; - ArchSpec m_arch; }; } // end namespace minidump diff --git a/source/Plugins/Process/minidump/ProcessMinidump.cpp b/source/Plugins/Process/minidump/ProcessMinidump.cpp index 7af6301b7f1a..b43f22382eac 100644 --- a/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -29,7 +29,6 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Threading.h" -#include "Plugins/Process/Utility/StopInfoMachException.h" // C includes // C++ includes @@ -175,21 +174,19 @@ Status ProcessMinidump::DoLoadCore() { switch (arch.GetMachine()) { case llvm::Triple::x86: case llvm::Triple::x86_64: - case llvm::Triple::arm: - case llvm::Triple::aarch64: - // Any supported architectures must be listed here and also supported in - // ThreadMinidump::CreateRegisterContextForFrame(). + // supported break; + default: error.SetErrorStringWithFormat("unsupported minidump architecture: %s", arch.GetArchitectureName()); return error; } - GetTarget().SetArchitecture(arch, true /*set_platform*/); m_thread_list = m_minidump_parser.GetThreads(); m_active_exception = m_minidump_parser.GetExceptionStream(); ReadModuleList(); + GetTarget().SetArchitecture(arch); llvm::Optional pid = m_minidump_parser.GetPid(); if (!pid) { @@ -232,11 +229,6 @@ void ProcessMinidump::RefreshStateAfterStop() { if (arch.GetTriple().getOS() == llvm::Triple::Linux) { stop_info = StopInfo::CreateStopReasonWithSignal( *stop_thread, m_active_exception->exception_record.exception_code); - } else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) { - stop_info = StopInfoMachException::CreateStopReasonWithMachException( - *stop_thread, m_active_exception->exception_record.exception_code, 2, - m_active_exception->exception_record.exception_flags, - m_active_exception->exception_record.exception_address, 0); } else { std::string desc; llvm::raw_string_ostream desc_stream(desc); diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp deleted file mode 100644 index 2d73da4e5b51..000000000000 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp +++ /dev/null @@ -1,532 +0,0 @@ -//===-- RegisterContextMinidump_ARM.cpp -------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// Project includes -#include "RegisterContextMinidump_ARM.h" - -// Other libraries and framework includes -#include "Utility/ARM_DWARF_Registers.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Utility/DataExtractor.h" -#include "lldb/Utility/LLDBAssert.h" -#include "lldb/lldb-enumerations.h" - -// C includes -#include - -// C++ includes - -using namespace lldb; -using namespace lldb_private; -using namespace minidump; - -#define INV LLDB_INVALID_REGNUM -#define OFFSET(r) (offsetof(RegisterContextMinidump_ARM::Context, r)) - -#define DEF_R(i) \ - { \ - "r" #i, nullptr, 4, OFFSET(r[i]), eEncodingUint, eFormatHex, \ - {INV, dwarf_r##i, INV, INV, reg_r##i}, nullptr, nullptr, nullptr, 0 \ - } - -#define DEF_R_ARG(i, n) \ - { \ - "r" #i, "arg" #n, 4, OFFSET(r[i]), eEncodingUint, eFormatHex, \ - {INV, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \ - nullptr, nullptr, nullptr, 0 \ - } - -#define DEF_D(i) \ - { \ - "d" #i, nullptr, 8, OFFSET(d[i]), eEncodingVector, eFormatVectorOfUInt8, \ - {INV, dwarf_d##i, INV, INV, reg_d##i}, nullptr, nullptr, nullptr, 0 \ - } - -#define DEF_S(i) \ - { \ - "s" #i, nullptr, 4, OFFSET(s[i]), eEncodingIEEE754, eFormatFloat, \ - {INV, dwarf_s##i, INV, INV, reg_s##i}, nullptr, nullptr, nullptr, 0 \ - } - -#define DEF_Q(i) \ - { \ - "q" #i, nullptr, 16, OFFSET(q[i]), eEncodingVector, eFormatVectorOfUInt8, \ - {INV, dwarf_q##i, INV, INV, reg_q##i}, nullptr, nullptr, nullptr, 0 \ - } - -// Zero based LLDB register numbers for this register context -enum { - // General Purpose Registers - reg_r0, - reg_r1, - reg_r2, - reg_r3, - reg_r4, - reg_r5, - reg_r6, - reg_r7, - reg_r8, - reg_r9, - reg_r10, - reg_r11, - reg_r12, - reg_sp, - reg_lr, - reg_pc, - reg_cpsr, - // Floating Point Registers - reg_fpscr, - reg_d0, - reg_d1, - reg_d2, - reg_d3, - reg_d4, - reg_d5, - reg_d6, - reg_d7, - reg_d8, - reg_d9, - reg_d10, - reg_d11, - reg_d12, - reg_d13, - reg_d14, - reg_d15, - reg_d16, - reg_d17, - reg_d18, - reg_d19, - reg_d20, - reg_d21, - reg_d22, - reg_d23, - reg_d24, - reg_d25, - reg_d26, - reg_d27, - reg_d28, - reg_d29, - reg_d30, - reg_d31, - reg_s0, - reg_s1, - reg_s2, - reg_s3, - reg_s4, - reg_s5, - reg_s6, - reg_s7, - reg_s8, - reg_s9, - reg_s10, - reg_s11, - reg_s12, - reg_s13, - reg_s14, - reg_s15, - reg_s16, - reg_s17, - reg_s18, - reg_s19, - reg_s20, - reg_s21, - reg_s22, - reg_s23, - reg_s24, - reg_s25, - reg_s26, - reg_s27, - reg_s28, - reg_s29, - reg_s30, - reg_s31, - reg_q0, - reg_q1, - reg_q2, - reg_q3, - reg_q4, - reg_q5, - reg_q6, - reg_q7, - reg_q8, - reg_q9, - reg_q10, - reg_q11, - reg_q12, - reg_q13, - reg_q14, - reg_q15, - k_num_regs -}; - -static RegisterInfo g_reg_info_apple_fp = { - "fp", - "r7", - 4, - OFFSET(r[7]), - eEncodingUint, - eFormatHex, - {INV, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7}, - nullptr, - nullptr, - nullptr, - 0}; - -static RegisterInfo g_reg_info_fp = { - "fp", - "r11", - 4, - OFFSET(r[11]), - eEncodingUint, - eFormatHex, - {INV, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11}, - nullptr, - nullptr, - nullptr, - 0}; - -// Register info definitions for this register context -static RegisterInfo g_reg_infos[] = { - DEF_R_ARG(0, 1), - DEF_R_ARG(1, 2), - DEF_R_ARG(2, 3), - DEF_R_ARG(3, 4), - DEF_R(4), - DEF_R(5), - DEF_R(6), - DEF_R(7), - DEF_R(8), - DEF_R(9), - DEF_R(10), - DEF_R(11), - DEF_R(12), - {"sp", - "r13", - 4, - OFFSET(r[13]), - eEncodingUint, - eFormatHex, - {INV, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, - nullptr, - nullptr, - nullptr, - 0}, - {"lr", - "r14", - 4, - OFFSET(r[14]), - eEncodingUint, - eFormatHex, - {INV, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, - nullptr, - nullptr, - nullptr, - 0}, - {"pc", - "r15", - 4, - OFFSET(r[15]), - eEncodingUint, - eFormatHex, - {INV, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, - nullptr, - nullptr, - nullptr, - 0}, - {"cpsr", - "psr", - 4, - OFFSET(cpsr), - eEncodingUint, - eFormatHex, - {INV, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, - nullptr, - nullptr, - nullptr, - 0}, - {"fpscr", - nullptr, - 8, - OFFSET(fpscr), - eEncodingUint, - eFormatHex, - {INV, INV, INV, INV, reg_fpscr}, - nullptr, - nullptr, - nullptr, - 0}, - DEF_D(0), - DEF_D(1), - DEF_D(2), - DEF_D(3), - DEF_D(4), - DEF_D(5), - DEF_D(6), - DEF_D(7), - DEF_D(8), - DEF_D(9), - DEF_D(10), - DEF_D(11), - DEF_D(12), - DEF_D(13), - DEF_D(14), - DEF_D(15), - DEF_D(16), - DEF_D(17), - DEF_D(18), - DEF_D(19), - DEF_D(20), - DEF_D(21), - DEF_D(22), - DEF_D(23), - DEF_D(24), - DEF_D(25), - DEF_D(26), - DEF_D(27), - DEF_D(28), - DEF_D(29), - DEF_D(30), - DEF_D(31), - DEF_S(0), - DEF_S(1), - DEF_S(2), - DEF_S(3), - DEF_S(4), - DEF_S(5), - DEF_S(6), - DEF_S(7), - DEF_S(8), - DEF_S(9), - DEF_S(10), - DEF_S(11), - DEF_S(12), - DEF_S(13), - DEF_S(14), - DEF_S(15), - DEF_S(16), - DEF_S(17), - DEF_S(18), - DEF_S(19), - DEF_S(20), - DEF_S(21), - DEF_S(22), - DEF_S(23), - DEF_S(24), - DEF_S(25), - DEF_S(26), - DEF_S(27), - DEF_S(28), - DEF_S(29), - DEF_S(30), - DEF_S(31), - DEF_Q(0), - DEF_Q(1), - DEF_Q(2), - DEF_Q(3), - DEF_Q(4), - DEF_Q(5), - DEF_Q(6), - DEF_Q(7), - DEF_Q(8), - DEF_Q(9), - DEF_Q(10), - DEF_Q(11), - DEF_Q(12), - DEF_Q(13), - DEF_Q(14), - DEF_Q(15)}; - -constexpr size_t k_num_reg_infos = llvm::array_lengthof(g_reg_infos); - -// ARM general purpose registers. -const uint32_t g_gpr_regnums[] = { - reg_r0, - reg_r1, - reg_r2, - reg_r3, - reg_r4, - reg_r5, - reg_r6, - reg_r7, - reg_r8, - reg_r9, - reg_r10, - reg_r11, - reg_r12, - reg_sp, - reg_lr, - reg_pc, - reg_cpsr, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; -const uint32_t g_fpu_regnums[] = { - reg_fpscr, - reg_d0, - reg_d1, - reg_d2, - reg_d3, - reg_d4, - reg_d5, - reg_d6, - reg_d7, - reg_d8, - reg_d9, - reg_d10, - reg_d11, - reg_d12, - reg_d13, - reg_d14, - reg_d15, - reg_d16, - reg_d17, - reg_d18, - reg_d19, - reg_d20, - reg_d21, - reg_d22, - reg_d23, - reg_d24, - reg_d25, - reg_d26, - reg_d27, - reg_d28, - reg_d29, - reg_d30, - reg_d31, - reg_s0, - reg_s1, - reg_s2, - reg_s3, - reg_s4, - reg_s5, - reg_s6, - reg_s7, - reg_s8, - reg_s9, - reg_s10, - reg_s11, - reg_s12, - reg_s13, - reg_s14, - reg_s15, - reg_s16, - reg_s17, - reg_s18, - reg_s19, - reg_s20, - reg_s21, - reg_s22, - reg_s23, - reg_s24, - reg_s25, - reg_s26, - reg_s27, - reg_s28, - reg_s29, - reg_s30, - reg_s31, - reg_q0, - reg_q1, - reg_q2, - reg_q3, - reg_q4, - reg_q5, - reg_q6, - reg_q7, - reg_q8, - reg_q9, - reg_q10, - reg_q11, - reg_q12, - reg_q13, - reg_q14, - reg_q15, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; - -// Skip the last LLDB_INVALID_REGNUM in each count below by subtracting 1 -constexpr size_t k_num_gpr_regs = llvm::array_lengthof(g_gpr_regnums) - 1; -constexpr size_t k_num_fpu_regs = llvm::array_lengthof(g_fpu_regnums) - 1; - -static RegisterSet g_reg_sets[] = { - {"General Purpose Registers", "gpr", k_num_gpr_regs, g_gpr_regnums}, - {"Floating Point Registers", "fpu", k_num_fpu_regs, g_fpu_regnums}, -}; - -constexpr size_t k_num_reg_sets = llvm::array_lengthof(g_reg_sets); - -RegisterContextMinidump_ARM::RegisterContextMinidump_ARM( - Thread &thread, const DataExtractor &data, bool apple) - : RegisterContext(thread, 0), m_apple(apple) { - lldb::offset_t offset = 0; - m_regs.context_flags = data.GetU32(&offset); - for (unsigned i = 0; i < llvm::array_lengthof(m_regs.r); ++i) - m_regs.r[i] = data.GetU32(&offset); - m_regs.cpsr = data.GetU32(&offset); - m_regs.fpscr = data.GetU64(&offset); - for (unsigned i = 0; i < llvm::array_lengthof(m_regs.d); ++i) - m_regs.d[i] = data.GetU64(&offset); - lldbassert(k_num_regs == k_num_reg_infos); -} - -size_t RegisterContextMinidump_ARM::GetRegisterCount() { return k_num_regs; } - -const RegisterInfo * -RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) { - if (reg < k_num_reg_infos) { - if (m_apple) { - if (reg == reg_r7) - return &g_reg_info_apple_fp; - } else { - if (reg == reg_r11) - return &g_reg_info_fp; - } - return &g_reg_infos[reg]; - } - return nullptr; -} - -size_t RegisterContextMinidump_ARM::GetRegisterSetCount() { - return k_num_reg_sets; -} - -const RegisterSet *RegisterContextMinidump_ARM::GetRegisterSet(size_t set) { - if (set < k_num_reg_sets) - return &g_reg_sets[set]; - return nullptr; -} - -const char *RegisterContextMinidump_ARM::GetRegisterName(unsigned reg) { - if (reg < k_num_reg_infos) - return g_reg_infos[reg].name; - return nullptr; -} - -bool RegisterContextMinidump_ARM::ReadRegister(const RegisterInfo *reg_info, - RegisterValue ®_value) { - Status error; - reg_value.SetFromMemoryData( - reg_info, (const uint8_t *)&m_regs + reg_info->byte_offset, - reg_info->byte_size, lldb::eByteOrderLittle, error); - return error.Success(); -} - -bool RegisterContextMinidump_ARM::WriteRegister(const RegisterInfo *, - const RegisterValue &) { - return false; -} - -uint32_t RegisterContextMinidump_ARM::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - for (size_t i = 0; i < k_num_regs; ++i) { - if (g_reg_infos[i].kinds[kind] == num) - return i; - } - return LLDB_INVALID_REGNUM; -} diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h deleted file mode 100644 index c410df99b1c1..000000000000 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h +++ /dev/null @@ -1,95 +0,0 @@ -//===-- RegisterContextMinidump_ARM.h ---------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_RegisterContextMinidump_ARM_h_ -#define liblldb_RegisterContextMinidump_ARM_h_ - -// Project includes -#include "MinidumpTypes.h" - -// Other libraries and framework includes -#include "Plugins/Process/Utility/RegisterInfoInterface.h" - -#include "lldb/Target/RegisterContext.h" - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/BitmaskEnum.h" - -// C includes -// C++ includes - -namespace lldb_private { - -namespace minidump { - -LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); - -class RegisterContextMinidump_ARM : public lldb_private::RegisterContext { -public: - RegisterContextMinidump_ARM(lldb_private::Thread &thread, - const DataExtractor &data, bool apple); - - ~RegisterContextMinidump_ARM() override = default; - - void InvalidateAllRegisters() override { - // Do nothing... registers are always valid... - } - - size_t GetRegisterCount() override; - - const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; - - size_t GetRegisterSetCount() override; - - const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; - - const char *GetRegisterName(unsigned reg); - - bool ReadRegister(const RegisterInfo *reg_info, - RegisterValue ®_value) override; - - bool WriteRegister(const RegisterInfo *reg_info, - const RegisterValue ®_value) override; - - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - - // Reference: see breakpad/crashpad source - struct QRegValue { - uint64_t lo; - uint64_t hi; - }; - - struct Context { - uint32_t context_flags; - uint32_t r[16]; - uint32_t cpsr; - uint64_t fpscr; - union { - uint64_t d[32]; - uint32_t s[32]; - QRegValue q[16]; - }; - uint32_t extra[8]; - }; - -protected: - enum class Flags : uint32_t { - ARM_Flag = 0x40000000, - Integer = ARM_Flag | 0x00000002, - FloatingPoint = ARM_Flag | 0x00000004, - LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ FloatingPoint) - }; - Context m_regs; - const bool m_apple; // True if this is an Apple ARM where FP is R7 -}; - -} // end namespace minidump -} // end namespace lldb_private -#endif // liblldb_RegisterContextMinidump_ARM_h_ diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp deleted file mode 100644 index 5ba58d1ca81e..000000000000 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp +++ /dev/null @@ -1,836 +0,0 @@ -//===-- RegisterContextMinidump_ARM64.cpp -----------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// Project includes -#include "RegisterContextMinidump_ARM64.h" - -// Other libraries and framework includes -#include "Utility/ARM64_DWARF_Registers.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Utility/DataExtractor.h" -#include "lldb/lldb-enumerations.h" - -// C includes -#include - -// C++ includes - -using namespace lldb; -using namespace lldb_private; -using namespace minidump; - -#define INV LLDB_INVALID_REGNUM -#define OFFSET(r) (offsetof(RegisterContextMinidump_ARM64::Context, r)) - -#define DEF_X(i) \ - { \ - "x" #i, nullptr, 8, OFFSET(x[i]), eEncodingUint, eFormatHex, \ - {INV, arm64_dwarf::x##i, INV, INV, reg_x##i}, nullptr, nullptr, \ - nullptr, 0 \ - } - -#define DEF_W(i) \ - { \ - "w" #i, nullptr, 4, OFFSET(x[i]), eEncodingUint, eFormatHex, \ - {INV, INV, INV, INV, reg_w##i}, nullptr, nullptr, nullptr, 0 \ - } - -#define DEF_X_ARG(i, n) \ - { \ - "x" #i, "arg" #n, 8, OFFSET(x[i]), eEncodingUint, eFormatHex, \ - {INV, arm64_dwarf::x##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_x##i}, \ - nullptr, nullptr, nullptr, 0 \ - } - -#define DEF_V(i) \ - { \ - "v" #i, nullptr, 16, OFFSET(v[i * 16]), eEncodingVector, \ - eFormatVectorOfUInt8, {INV, arm64_dwarf::v##i, INV, INV, reg_v##i}, \ - nullptr, nullptr, nullptr, 0 \ - } - -#define DEF_D(i) \ - { \ - "d" #i, nullptr, 8, OFFSET(v[i * 16]), eEncodingVector, \ - eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_d##i}, nullptr, \ - nullptr, nullptr, 0 \ - } - -#define DEF_S(i) \ - { \ - "s" #i, nullptr, 4, OFFSET(v[i * 16]), eEncodingVector, \ - eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_s##i}, nullptr, \ - nullptr, nullptr, 0 \ - } - -#define DEF_H(i) \ - { \ - "h" #i, nullptr, 2, OFFSET(v[i * 16]), eEncodingVector, \ - eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_h##i}, nullptr, \ - nullptr, nullptr, 0 \ - } - -// Zero based LLDB register numbers for this register context -enum { - // General Purpose Registers - reg_x0 = 0, - reg_x1, - reg_x2, - reg_x3, - reg_x4, - reg_x5, - reg_x6, - reg_x7, - reg_x8, - reg_x9, - reg_x10, - reg_x11, - reg_x12, - reg_x13, - reg_x14, - reg_x15, - reg_x16, - reg_x17, - reg_x18, - reg_x19, - reg_x20, - reg_x21, - reg_x22, - reg_x23, - reg_x24, - reg_x25, - reg_x26, - reg_x27, - reg_x28, - reg_fp, - reg_lr, - reg_sp, - reg_pc, - reg_w0, - reg_w1, - reg_w2, - reg_w3, - reg_w4, - reg_w5, - reg_w6, - reg_w7, - reg_w8, - reg_w9, - reg_w10, - reg_w11, - reg_w12, - reg_w13, - reg_w14, - reg_w15, - reg_w16, - reg_w17, - reg_w18, - reg_w19, - reg_w20, - reg_w21, - reg_w22, - reg_w23, - reg_w24, - reg_w25, - reg_w26, - reg_w27, - reg_w28, - reg_w29, - reg_w30, - reg_w31, - reg_cpsr, - // Floating Point Registers - reg_fpsr, - reg_fpcr, - reg_v0, - reg_v1, - reg_v2, - reg_v3, - reg_v4, - reg_v5, - reg_v6, - reg_v7, - reg_v8, - reg_v9, - reg_v10, - reg_v11, - reg_v12, - reg_v13, - reg_v14, - reg_v15, - reg_v16, - reg_v17, - reg_v18, - reg_v19, - reg_v20, - reg_v21, - reg_v22, - reg_v23, - reg_v24, - reg_v25, - reg_v26, - reg_v27, - reg_v28, - reg_v29, - reg_v30, - reg_v31, - reg_d0, - reg_d1, - reg_d2, - reg_d3, - reg_d4, - reg_d5, - reg_d6, - reg_d7, - reg_d8, - reg_d9, - reg_d10, - reg_d11, - reg_d12, - reg_d13, - reg_d14, - reg_d15, - reg_d16, - reg_d17, - reg_d18, - reg_d19, - reg_d20, - reg_d21, - reg_d22, - reg_d23, - reg_d24, - reg_d25, - reg_d26, - reg_d27, - reg_d28, - reg_d29, - reg_d30, - reg_d31, - reg_s0, - reg_s1, - reg_s2, - reg_s3, - reg_s4, - reg_s5, - reg_s6, - reg_s7, - reg_s8, - reg_s9, - reg_s10, - reg_s11, - reg_s12, - reg_s13, - reg_s14, - reg_s15, - reg_s16, - reg_s17, - reg_s18, - reg_s19, - reg_s20, - reg_s21, - reg_s22, - reg_s23, - reg_s24, - reg_s25, - reg_s26, - reg_s27, - reg_s28, - reg_s29, - reg_s30, - reg_s31, - reg_h0, - reg_h1, - reg_h2, - reg_h3, - reg_h4, - reg_h5, - reg_h6, - reg_h7, - reg_h8, - reg_h9, - reg_h10, - reg_h11, - reg_h12, - reg_h13, - reg_h14, - reg_h15, - reg_h16, - reg_h17, - reg_h18, - reg_h19, - reg_h20, - reg_h21, - reg_h22, - reg_h23, - reg_h24, - reg_h25, - reg_h26, - reg_h27, - reg_h28, - reg_h29, - reg_h30, - reg_h31, - k_num_regs -}; - -// Register info definitions for this register context -static RegisterInfo g_reg_infos[] = { - DEF_X_ARG(0, 1), - DEF_X_ARG(1, 2), - DEF_X_ARG(2, 3), - DEF_X_ARG(3, 4), - DEF_X_ARG(4, 5), - DEF_X_ARG(5, 6), - DEF_X_ARG(6, 7), - DEF_X_ARG(7, 8), - DEF_X(8), - DEF_X(9), - DEF_X(10), - DEF_X(11), - DEF_X(12), - DEF_X(13), - DEF_X(14), - DEF_X(15), - DEF_X(16), - DEF_X(17), - DEF_X(18), - DEF_X(19), - DEF_X(20), - DEF_X(21), - DEF_X(22), - DEF_X(23), - DEF_X(24), - DEF_X(25), - DEF_X(26), - DEF_X(27), - DEF_X(28), - {"fp", - "x29", - 8, - OFFSET(x[29]), - eEncodingUint, - eFormatHex, - {INV, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, INV, reg_fp}, - nullptr, - nullptr, - nullptr, - 0}, - {"lr", - "x30", - 8, - OFFSET(x[30]), - eEncodingUint, - eFormatHex, - {INV, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, - nullptr, - nullptr, - nullptr, - 0}, - {"sp", - "x31", - 8, - OFFSET(x[31]), - eEncodingUint, - eFormatHex, - {INV, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, - nullptr, - nullptr, - nullptr, - 0}, - {"pc", - nullptr, - 8, - OFFSET(pc), - eEncodingUint, - eFormatHex, - {INV, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, - nullptr, - nullptr, - nullptr, - 0}, - // w0 - w31 - DEF_W(0), - DEF_W(1), - DEF_W(2), - DEF_W(3), - DEF_W(4), - DEF_W(5), - DEF_W(6), - DEF_W(7), - DEF_W(8), - DEF_W(9), - DEF_W(10), - DEF_W(11), - DEF_W(12), - DEF_W(13), - DEF_W(14), - DEF_W(15), - DEF_W(16), - DEF_W(17), - DEF_W(18), - DEF_W(19), - DEF_W(20), - DEF_W(21), - DEF_W(22), - DEF_W(23), - DEF_W(24), - DEF_W(25), - DEF_W(26), - DEF_W(27), - DEF_W(28), - DEF_W(29), - DEF_W(30), - DEF_W(31), - {"cpsr", - "psr", - 4, - OFFSET(cpsr), - eEncodingUint, - eFormatHex, - {INV, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, - nullptr, - nullptr, - nullptr, - 0}, - {"fpsr", - nullptr, - 4, - OFFSET(fpsr), - eEncodingUint, - eFormatHex, - {INV, INV, INV, INV, reg_fpsr}, - nullptr, - nullptr, - nullptr, - 0}, - {"fpcr", - nullptr, - 4, - OFFSET(fpcr), - eEncodingUint, - eFormatHex, - {INV, INV, INV, INV, reg_fpcr}, - nullptr, - nullptr, - nullptr, - 0}, - // v0 - v31 - DEF_V(0), - DEF_V(1), - DEF_V(2), - DEF_V(3), - DEF_V(4), - DEF_V(5), - DEF_V(6), - DEF_V(7), - DEF_V(8), - DEF_V(9), - DEF_V(10), - DEF_V(11), - DEF_V(12), - DEF_V(13), - DEF_V(14), - DEF_V(15), - DEF_V(16), - DEF_V(17), - DEF_V(18), - DEF_V(19), - DEF_V(20), - DEF_V(21), - DEF_V(22), - DEF_V(23), - DEF_V(24), - DEF_V(25), - DEF_V(26), - DEF_V(27), - DEF_V(28), - DEF_V(29), - DEF_V(30), - DEF_V(31), - // d0 - d31 - DEF_D(0), - DEF_D(1), - DEF_D(2), - DEF_D(3), - DEF_D(4), - DEF_D(5), - DEF_D(6), - DEF_D(7), - DEF_D(8), - DEF_D(9), - DEF_D(10), - DEF_D(11), - DEF_D(12), - DEF_D(13), - DEF_D(14), - DEF_D(15), - DEF_D(16), - DEF_D(17), - DEF_D(18), - DEF_D(19), - DEF_D(20), - DEF_D(21), - DEF_D(22), - DEF_D(23), - DEF_D(24), - DEF_D(25), - DEF_D(26), - DEF_D(27), - DEF_D(28), - DEF_D(29), - DEF_D(30), - DEF_D(31), - // s0 - s31 - DEF_S(0), - DEF_S(1), - DEF_S(2), - DEF_S(3), - DEF_S(4), - DEF_S(5), - DEF_S(6), - DEF_S(7), - DEF_S(8), - DEF_S(9), - DEF_S(10), - DEF_S(11), - DEF_S(12), - DEF_S(13), - DEF_S(14), - DEF_S(15), - DEF_S(16), - DEF_S(17), - DEF_S(18), - DEF_S(19), - DEF_S(20), - DEF_S(21), - DEF_S(22), - DEF_S(23), - DEF_S(24), - DEF_S(25), - DEF_S(26), - DEF_S(27), - DEF_S(28), - DEF_S(29), - DEF_S(30), - DEF_S(31), - // h0 - h31 - DEF_H(0), - DEF_H(1), - DEF_H(2), - DEF_H(3), - DEF_H(4), - DEF_H(5), - DEF_H(6), - DEF_H(7), - DEF_H(8), - DEF_H(9), - DEF_H(10), - DEF_H(11), - DEF_H(12), - DEF_H(13), - DEF_H(14), - DEF_H(15), - DEF_H(16), - DEF_H(17), - DEF_H(18), - DEF_H(19), - DEF_H(20), - DEF_H(21), - DEF_H(22), - DEF_H(23), - DEF_H(24), - DEF_H(25), - DEF_H(26), - DEF_H(27), - DEF_H(28), - DEF_H(29), - DEF_H(30), - DEF_H(31), -}; - -constexpr size_t k_num_reg_infos = llvm::array_lengthof(g_reg_infos); - -// ARM64 general purpose registers. -const uint32_t g_gpr_regnums[] = { - reg_x0, - reg_x1, - reg_x2, - reg_x3, - reg_x4, - reg_x5, - reg_x6, - reg_x7, - reg_x8, - reg_x9, - reg_x10, - reg_x11, - reg_x12, - reg_x13, - reg_x14, - reg_x15, - reg_x16, - reg_x17, - reg_x18, - reg_x19, - reg_x20, - reg_x21, - reg_x22, - reg_x23, - reg_x24, - reg_x25, - reg_x26, - reg_x27, - reg_x28, - reg_fp, - reg_lr, - reg_sp, - reg_w0, - reg_w1, - reg_w2, - reg_w3, - reg_w4, - reg_w5, - reg_w6, - reg_w7, - reg_w8, - reg_w9, - reg_w10, - reg_w11, - reg_w12, - reg_w13, - reg_w14, - reg_w15, - reg_w16, - reg_w17, - reg_w18, - reg_w19, - reg_w20, - reg_w21, - reg_w22, - reg_w23, - reg_w24, - reg_w25, - reg_w26, - reg_w27, - reg_w28, - reg_w29, - reg_w30, - reg_w31, - reg_pc, - reg_cpsr, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; -const uint32_t g_fpu_regnums[] = { - reg_v0, - reg_v1, - reg_v2, - reg_v3, - reg_v4, - reg_v5, - reg_v6, - reg_v7, - reg_v8, - reg_v9, - reg_v10, - reg_v11, - reg_v12, - reg_v13, - reg_v14, - reg_v15, - reg_v16, - reg_v17, - reg_v18, - reg_v19, - reg_v20, - reg_v21, - reg_v22, - reg_v23, - reg_v24, - reg_v25, - reg_v26, - reg_v27, - reg_v28, - reg_v29, - reg_v30, - reg_v31, - reg_d0, - reg_d1, - reg_d2, - reg_d3, - reg_d4, - reg_d5, - reg_d6, - reg_d7, - reg_d8, - reg_d9, - reg_d10, - reg_d11, - reg_d12, - reg_d13, - reg_d14, - reg_d15, - reg_d16, - reg_d17, - reg_d18, - reg_d19, - reg_d20, - reg_d21, - reg_d22, - reg_d23, - reg_d24, - reg_d25, - reg_d26, - reg_d27, - reg_d28, - reg_d29, - reg_d30, - reg_d31, - reg_s0, - reg_s1, - reg_s2, - reg_s3, - reg_s4, - reg_s5, - reg_s6, - reg_s7, - reg_s8, - reg_s9, - reg_s10, - reg_s11, - reg_s12, - reg_s13, - reg_s14, - reg_s15, - reg_s16, - reg_s17, - reg_s18, - reg_s19, - reg_s20, - reg_s21, - reg_s22, - reg_s23, - reg_s24, - reg_s25, - reg_s26, - reg_s27, - reg_s28, - reg_s29, - reg_s30, - reg_s31, - reg_h0, - reg_h1, - reg_h2, - reg_h3, - reg_h4, - reg_h5, - reg_h6, - reg_h7, - reg_h8, - reg_h9, - reg_h10, - reg_h11, - reg_h12, - reg_h13, - reg_h14, - reg_h15, - reg_h16, - reg_h17, - reg_h18, - reg_h19, - reg_h20, - reg_h21, - reg_h22, - reg_h23, - reg_h24, - reg_h25, - reg_h26, - reg_h27, - reg_h28, - reg_h29, - reg_h30, - reg_h31, - reg_fpsr, - reg_fpcr, - LLDB_INVALID_REGNUM // register sets need to end with this flag -}; - -// Skip the last LLDB_INVALID_REGNUM in each count below by subtracting 1 -constexpr size_t k_num_gpr_regs = llvm::array_lengthof(g_gpr_regnums) - 1; -constexpr size_t k_num_fpu_regs = llvm::array_lengthof(g_fpu_regnums) - 1; - -static RegisterSet g_reg_sets[] = { - {"General Purpose Registers", "gpr", k_num_gpr_regs, g_gpr_regnums}, - {"Floating Point Registers", "fpu", k_num_fpu_regs, g_fpu_regnums}, -}; - -constexpr size_t k_num_reg_sets = llvm::array_lengthof(g_reg_sets); - -RegisterContextMinidump_ARM64::RegisterContextMinidump_ARM64( - Thread &thread, const DataExtractor &data) - : RegisterContext(thread, 0) { - lldb::offset_t offset = 0; - m_regs.context_flags = data.GetU64(&offset); - for (unsigned i = 0; i < 32; ++i) - m_regs.x[i] = data.GetU64(&offset); - m_regs.pc = data.GetU64(&offset); - m_regs.cpsr = data.GetU32(&offset); - m_regs.fpsr = data.GetU32(&offset); - m_regs.fpcr = data.GetU32(&offset); - auto regs_data = data.GetData(&offset, sizeof(m_regs.v)); - if (regs_data) - memcpy(m_regs.v, regs_data, sizeof(m_regs.v)); - assert(k_num_regs == k_num_reg_infos); -} -size_t RegisterContextMinidump_ARM64::GetRegisterCount() { return k_num_regs; } - -const RegisterInfo * -RegisterContextMinidump_ARM64::GetRegisterInfoAtIndex(size_t reg) { - if (reg < k_num_reg_infos) - return &g_reg_infos[reg]; - return nullptr; -} - -size_t RegisterContextMinidump_ARM64::GetRegisterSetCount() { - return k_num_reg_sets; -} - -const RegisterSet *RegisterContextMinidump_ARM64::GetRegisterSet(size_t set) { - if (set < k_num_reg_sets) - return &g_reg_sets[set]; - return nullptr; -} - -const char *RegisterContextMinidump_ARM64::GetRegisterName(unsigned reg) { - if (reg < k_num_reg_infos) - return g_reg_infos[reg].name; - return nullptr; -} - -bool RegisterContextMinidump_ARM64::ReadRegister(const RegisterInfo *reg_info, - RegisterValue ®_value) { - Status error; - reg_value.SetFromMemoryData( - reg_info, (const uint8_t *)&m_regs + reg_info->byte_offset, - reg_info->byte_size, lldb::eByteOrderLittle, error); - return error.Success(); -} - -bool RegisterContextMinidump_ARM64::WriteRegister(const RegisterInfo *, - const RegisterValue &) { - return false; -} - -uint32_t RegisterContextMinidump_ARM64::ConvertRegisterKindToRegisterNumber( - lldb::RegisterKind kind, uint32_t num) { - for (size_t i = 0; i < k_num_regs; ++i) { - if (g_reg_infos[i].kinds[kind] == num) - return i; - } - return LLDB_INVALID_REGNUM; -} diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h deleted file mode 100644 index 2a3f254c8510..000000000000 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h +++ /dev/null @@ -1,85 +0,0 @@ -//===-- RegisterContextMinidump_ARM64.h -------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_RegisterContextMinidump_ARM64_h_ -#define liblldb_RegisterContextMinidump_ARM64_h_ - -// Project includes -#include "MinidumpTypes.h" - -// Other libraries and framework includes -#include "Plugins/Process/Utility/RegisterInfoInterface.h" -#include "lldb/Target/RegisterContext.h" - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/BitmaskEnum.h" - -// C includes -// C++ includes - -namespace lldb_private { - -namespace minidump { - -LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); - -class RegisterContextMinidump_ARM64 : public lldb_private::RegisterContext { -public: - RegisterContextMinidump_ARM64(lldb_private::Thread &thread, - const DataExtractor &data); - - ~RegisterContextMinidump_ARM64() override = default; - - void InvalidateAllRegisters() override { - // Do nothing... registers are always valid... - } - - size_t GetRegisterCount() override; - - const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; - - size_t GetRegisterSetCount() override; - - const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; - - const char *GetRegisterName(unsigned reg); - - bool ReadRegister(const RegisterInfo *reg_info, - RegisterValue ®_value) override; - - bool WriteRegister(const RegisterInfo *reg_info, - const RegisterValue ®_value) override; - - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, - uint32_t num) override; - - // Reference: see breakpad/crashpad source - struct Context { - uint64_t context_flags; - uint64_t x[32]; - uint64_t pc; - uint32_t cpsr; - uint32_t fpsr; - uint32_t fpcr; - uint8_t v[32 * 16]; // 32 128-bit floating point registers - }; - -protected: - enum class Flags : uint32_t { - ARM64_Flag = 0x80000000, - Integer = ARM64_Flag | 0x00000002, - FloatingPoint = ARM64_Flag | 0x00000004, - LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ FloatingPoint) - }; - Context m_regs; -}; - -} // end namespace minidump -} // end namespace lldb_private -#endif // liblldb_RegisterContextMinidump_ARM64_h_ diff --git a/source/Plugins/Process/minidump/ThreadMinidump.cpp b/source/Plugins/Process/minidump/ThreadMinidump.cpp index 97493ebfd558..3fafb6134e7f 100644 --- a/source/Plugins/Process/minidump/ThreadMinidump.cpp +++ b/source/Plugins/Process/minidump/ThreadMinidump.cpp @@ -11,8 +11,6 @@ #include "ThreadMinidump.h" #include "ProcessMinidump.h" -#include "RegisterContextMinidump_ARM.h" -#include "RegisterContextMinidump_ARM64.h" #include "RegisterContextMinidump_x86_32.h" #include "RegisterContextMinidump_x86_64.h" @@ -56,6 +54,7 @@ RegisterContextSP ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) { RegisterContextSP reg_ctx_sp; uint32_t concrete_frame_idx = 0; + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (frame) concrete_frame_idx = frame->GetConcreteFrameIndex(); @@ -89,24 +88,17 @@ ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) { *this, reg_interface, gpregset, {})); break; } - case llvm::Triple::aarch64: { - DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(), - lldb::eByteOrderLittle, 8); - m_thread_reg_ctx_sp.reset(new RegisterContextMinidump_ARM64(*this, data)); - break; - } - case llvm::Triple::arm: { - DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(), - lldb::eByteOrderLittle, 8); - const bool apple = arch.GetTriple().getVendor() == llvm::Triple::Apple; - m_thread_reg_ctx_sp.reset( - new RegisterContextMinidump_ARM(*this, data, apple)); - break; - } default: break; } + if (!reg_interface) { + if (log) + log->Printf("elf-core::%s:: Architecture(%d) not supported", + __FUNCTION__, arch.GetMachine()); + assert(false && "Architecture not supported"); + } + reg_ctx_sp = m_thread_reg_ctx_sp; } else if (m_unwinder_ap) { reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame); diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp index a98495d17449..3f70741713fb 100644 --- a/source/Target/Target.cpp +++ b/source/Target/Target.cpp @@ -1426,33 +1426,13 @@ void Target::SetExecutableModule(ModuleSP &executable_sp, } } -bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) { +bool Target::SetArchitecture(const ArchSpec &arch_spec) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); bool missing_local_arch = !m_arch.GetSpec().IsValid(); bool replace_local_arch = true; bool compatible_local_arch = false; ArchSpec other(arch_spec); - // Changing the architecture might mean that the currently selected platform - // isn't compatible. Set the platform correctly if we are asked to do so, - // otherwise assume the user will set the platform manually. - if (set_platform) { - if (other.IsValid()) { - auto platform_sp = GetPlatform(); - if (!platform_sp || - !platform_sp->IsCompatibleArchitecture(other, false, nullptr)) { - ArchSpec platform_arch; - auto arch_platform_sp = - Platform::GetPlatformForArchitecture(other, &platform_arch); - if (arch_platform_sp) { - SetPlatform(arch_platform_sp); - if (platform_arch.IsValid()) - other = platform_arch; - } - } - } - } - if (!missing_local_arch) { if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) { other.MergeFrom(m_arch.GetSpec()); From ff8363e289c1271ed67dc282868634d050e19fae Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Fri, 3 Aug 2018 16:56:33 +0000 Subject: [PATCH 0049/1112] Add raw_ostream wrapper to the Stream class Summary: This wrapper will allow us in the future to reuse LLVM methods from within the Stream class. Currently no test as this is intended to be an internal class that shouldn't have any NFC. The test for this change will be the follow up patch that migrates LLDB's LEB128 implementation to the one from LLVM. This change also adds custom move/assignment methods to Stream, as LLVM raw_ostream doesn't support these. As our internal stream has anyway no state, we can just keep the same stream object around. Reviewers: davide, labath Reviewed By: labath Subscribers: xiaobai, labath, lldb-commits Differential Revision: https://reviews.llvm.org/D50161 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338901 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Utility/Stream.h | 47 +++++++++++++++++++++++++++++++++++ source/Utility/Stream.cpp | 4 +-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/include/lldb/Utility/Stream.h b/include/lldb/Utility/Stream.h index 96a238aef9ac..3a56929a8f45 100644 --- a/include/lldb/Utility/Stream.h +++ b/include/lldb/Utility/Stream.h @@ -15,6 +15,7 @@ #include "lldb/lldb-enumerations.h" // for ByteOrder::eByteOrderInvalid #include "llvm/ADT/StringRef.h" // for StringRef #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/raw_ostream.h" #include #include // for size_t @@ -52,6 +53,17 @@ class Stream { //------------------------------------------------------------------ Stream(); + // FIXME: Streams should not be copyable. + Stream(const Stream &other) : m_forwarder(*this) { (*this) = other; } + + Stream &operator=(const Stream &rhs) { + m_flags = rhs.m_flags; + m_addr_size = rhs.m_addr_size; + m_byte_order = rhs.m_byte_order; + m_indent_level = rhs.m_indent_level; + return *this; + } + //------------------------------------------------------------------ /// Destructor //------------------------------------------------------------------ @@ -520,6 +532,13 @@ class Stream { //------------------------------------------------------------------ size_t PutULEB128(uint64_t uval); + //------------------------------------------------------------------ + /// Returns a raw_ostream that forwards the data to this Stream object. + //------------------------------------------------------------------ + llvm::raw_ostream &AsRawOstream() { + return m_forwarder; + } + protected: //------------------------------------------------------------------ // Member variables @@ -548,6 +567,34 @@ class Stream { /// The number of bytes that were appended to the stream. //------------------------------------------------------------------ virtual size_t WriteImpl(const void *src, size_t src_len) = 0; + + //---------------------------------------------------------------------- + /// @class RawOstreamForward Stream.h "lldb/Utility/Stream.h" + /// This is a wrapper class that exposes a raw_ostream interface that just + /// forwards to an LLDB stream, allowing to reuse LLVM algorithms that take + /// a raw_ostream within the LLDB code base. + //---------------------------------------------------------------------- + class RawOstreamForward : public llvm::raw_ostream { + // Note: This stream must *not* maintain its own buffer, but instead + // directly write everything to the internal Stream class. Without this, + // we would run into the problem that the Stream written byte count would + // differ from the actually written bytes by the size of the internal + // raw_ostream buffer. + + Stream &m_target; + void write_impl(const char *Ptr, size_t Size) override { + m_target.Write(Ptr, Size); + } + + uint64_t current_pos() const override { + return m_target.GetWrittenBytes(); + } + + public: + RawOstreamForward(Stream &target) + : llvm::raw_ostream(/*unbuffered*/ true), m_target(target) {} + }; + RawOstreamForward m_forwarder; }; } // namespace lldb_private diff --git a/source/Utility/Stream.cpp b/source/Utility/Stream.cpp index d65ff0377913..02a4b836dd87 100644 --- a/source/Utility/Stream.cpp +++ b/source/Utility/Stream.cpp @@ -23,11 +23,11 @@ using namespace lldb_private; Stream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order) : m_flags(flags), m_addr_size(addr_size), m_byte_order(byte_order), - m_indent_level(0) {} + m_indent_level(0), m_forwarder(*this) {} Stream::Stream() : m_flags(0), m_addr_size(4), m_byte_order(endian::InlHostByteOrder()), - m_indent_level(0) {} + m_indent_level(0), m_forwarder(*this) {} //------------------------------------------------------------------ // Destructor From 7054e200aaa75e2563d90108224fcbcf3e006b19 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Fri, 3 Aug 2018 20:51:31 +0000 Subject: [PATCH 0050/1112] Replace LLDB's LEB128 implementation with the one from LLVM Reviewers: davide, labath Reviewed By: labath Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D50162 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338920 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Utility/Stream.cpp | 44 ++++++++------------------------------- 1 file changed, 9 insertions(+), 35 deletions(-) diff --git a/source/Utility/Stream.cpp b/source/Utility/Stream.cpp index 02a4b836dd87..8af8c19f210e 100644 --- a/source/Utility/Stream.cpp +++ b/source/Utility/Stream.cpp @@ -12,6 +12,7 @@ #include "lldb/Utility/Endian.h" #include "lldb/Utility/VASPrintf.h" #include "llvm/ADT/SmallString.h" // for SmallString +#include "llvm/Support/LEB128.h" #include @@ -49,47 +50,20 @@ void Stream::Offset(uint32_t uval, const char *format) { Printf(format, uval); } // Put an SLEB128 "uval" out to the stream using the printf format in "format". //------------------------------------------------------------------ size_t Stream::PutSLEB128(int64_t sval) { - size_t bytes_written = 0; - if (m_flags.Test(eBinary)) { - bool more = true; - while (more) { - uint8_t byte = sval & 0x7fu; - sval >>= 7; - /* sign bit of byte is 2nd high order bit (0x40) */ - if ((sval == 0 && !(byte & 0x40)) || (sval == -1 && (byte & 0x40))) - more = false; - else - // more bytes to come - byte |= 0x80u; - bytes_written += Write(&byte, 1); - } - } else { - bytes_written = Printf("0x%" PRIi64, sval); - } - - return bytes_written; + if (m_flags.Test(eBinary)) + return llvm::encodeSLEB128(sval, m_forwarder); + else + return Printf("0x%" PRIi64, sval); } //------------------------------------------------------------------ // Put an ULEB128 "uval" out to the stream using the printf format in "format". //------------------------------------------------------------------ size_t Stream::PutULEB128(uint64_t uval) { - size_t bytes_written = 0; - if (m_flags.Test(eBinary)) { - do { - - uint8_t byte = uval & 0x7fu; - uval >>= 7; - if (uval != 0) { - // more bytes to come - byte |= 0x80u; - } - bytes_written += Write(&byte, 1); - } while (uval != 0); - } else { - bytes_written = Printf("0x%" PRIx64, uval); - } - return bytes_written; + if (m_flags.Test(eBinary)) + return llvm::encodeULEB128(uval, m_forwarder); + else + return Printf("0x%" PRIx64, uval); } //------------------------------------------------------------------ From 64a1bb661f7ff1beb2e65b8f87a7528787e27b06 Mon Sep 17 00:00:00 2001 From: Alex Langford Date: Fri, 3 Aug 2018 21:37:01 +0000 Subject: [PATCH 0051/1112] Modify lldb_suite.py to enable python debugging Summary: pudb and pdb interfere with the behavior of the inspect module. calling `inspect.getfile(inspect.currentframe())` returns a different result depending on whether or not you're in a debugger. Calling `os.path.abspath` on the result of `inspect.getfile(...)` normalizes the result between the two environments. Patch by Nathan Lanza Differential Revision: https://reviews.llvm.org/D49620 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338923 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/use_lldb_suite.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/use_lldb_suite.py b/test/use_lldb_suite.py index 6e24b9da8d34..6a8c12d81898 100644 --- a/test/use_lldb_suite.py +++ b/test/use_lldb_suite.py @@ -4,7 +4,9 @@ def find_lldb_root(): - lldb_root = os.path.dirname(inspect.getfile(inspect.currentframe())) + lldb_root = os.path.dirname( + os.path.abspath(inspect.getfile(inspect.currentframe())) + ) while True: lldb_root = os.path.dirname(lldb_root) if lldb_root is None: From e171e48dd7b84ab1444601dc8f0e5c3366971842 Mon Sep 17 00:00:00 2001 From: Leonard Mosescu Date: Sat, 4 Aug 2018 02:15:26 +0000 Subject: [PATCH 0052/1112] Fix a bug in VMRange I noticed a suspicious failure: [ RUN ] VMRange.CollectionContains llvm/src/tools/lldb/unittests/Utility/VMRangeTest.cpp:146: Failure Value of: VMRange::ContainsRange(collection, VMRange(0x100, 0x104)) Actual: false Expected: true Looking at the code, it is a very real bug: class RangeInRangeUnaryPredicate { public: RangeInRangeUnaryPredicate(VMRange range) : _range(range) {} // note that _range binds to a temporary! bool operator()(const VMRange &range) const { return range.Contains(_range); } const VMRange &_range; }; This change fixes the bug. Differential Revision: https://reviews.llvm.org/D50290 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338949 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Utility/VMRange.h | 18 ------------------ source/Utility/VMRange.cpp | 10 ++++++---- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/include/lldb/Utility/VMRange.h b/include/lldb/Utility/VMRange.h index f03a1b0c1f97..0e696907baa7 100644 --- a/include/lldb/Utility/VMRange.h +++ b/include/lldb/Utility/VMRange.h @@ -87,24 +87,6 @@ class VMRange { void Dump(Stream *s, lldb::addr_t base_addr = 0, uint32_t addr_width = 8) const; - class ValueInRangeUnaryPredicate { - public: - ValueInRangeUnaryPredicate(lldb::addr_t value) : _value(value) {} - bool operator()(const VMRange &range) const { - return range.Contains(_value); - } - lldb::addr_t _value; - }; - - class RangeInRangeUnaryPredicate { - public: - RangeInRangeUnaryPredicate(VMRange range) : _range(range) {} - bool operator()(const VMRange &range) const { - return range.Contains(_range); - } - const VMRange &_range; - }; - static bool ContainsValue(const VMRange::collection &coll, lldb::addr_t value); diff --git a/source/Utility/VMRange.cpp b/source/Utility/VMRange.cpp index 105b1a58c48c..7e35d3ef0c65 100644 --- a/source/Utility/VMRange.cpp +++ b/source/Utility/VMRange.cpp @@ -24,14 +24,16 @@ using namespace lldb_private; bool VMRange::ContainsValue(const VMRange::collection &coll, lldb::addr_t value) { - ValueInRangeUnaryPredicate in_range_predicate(value); - return llvm::find_if(coll, in_range_predicate) != coll.end(); + return llvm::find_if(coll, [&](const VMRange &r) { + return r.Contains(value); + }) != coll.end(); } bool VMRange::ContainsRange(const VMRange::collection &coll, const VMRange &range) { - RangeInRangeUnaryPredicate in_range_predicate(range); - return llvm::find_if(coll, in_range_predicate) != coll.end(); + return llvm::find_if(coll, [&](const VMRange &r) { + return r.Contains(range); + }) != coll.end(); } void VMRange::Dump(Stream *s, lldb::addr_t offset, uint32_t addr_width) const { From 4fd1a45a69051afeb4e6dfcde7c4b863f9d5b589 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Sat, 4 Aug 2018 05:53:07 +0000 Subject: [PATCH 0053/1112] Fixed header of StringLexer.h git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338952 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Utility/StringLexer.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/lldb/Utility/StringLexer.h b/include/lldb/Utility/StringLexer.h index e4fc81a85e0d..d779ef429481 100644 --- a/include/lldb/Utility/StringLexer.h +++ b/include/lldb/Utility/StringLexer.h @@ -1,5 +1,4 @@ -//===--------------------- StringLexer.h -------------------------*- C++ -//-*-===// +//===--------------------- StringLexer.h ------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // From c076d233b00a57157eff157127c46f4768d2eba9 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Sat, 4 Aug 2018 17:28:21 +0000 Subject: [PATCH 0054/1112] Added unit test for StringList Reviewers: labath Reviewed By: labath Subscribers: mgorny, lldb-commits Differential Revision: https://reviews.llvm.org/D50293 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338961 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/Utility/CMakeLists.txt | 1 + unittests/Utility/StringListTest.cpp | 512 +++++++++++++++++++++++++++ 2 files changed, 513 insertions(+) create mode 100644 unittests/Utility/StringListTest.cpp diff --git a/unittests/Utility/CMakeLists.txt b/unittests/Utility/CMakeLists.txt index 4812d41ea753..01d24d5d3d25 100644 --- a/unittests/Utility/CMakeLists.txt +++ b/unittests/Utility/CMakeLists.txt @@ -16,6 +16,7 @@ add_lldb_unittest(UtilityTests StreamTeeTest.cpp StreamTest.cpp StringExtractorTest.cpp + StringListTest.cpp StructuredDataTest.cpp TildeExpressionResolverTest.cpp TimeoutTest.cpp diff --git a/unittests/Utility/StringListTest.cpp b/unittests/Utility/StringListTest.cpp new file mode 100644 index 000000000000..fcd2da675f72 --- /dev/null +++ b/unittests/Utility/StringListTest.cpp @@ -0,0 +1,512 @@ +//===-- StringListTest.cpp ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/StringList.h" +#include "lldb/Utility/StreamString.h" +#include "gtest/gtest.h" + +using namespace lldb_private; + +TEST(StringListTest, DefaultConstructor) { + StringList s; + EXPECT_EQ(0U, s.GetSize()); +} + +TEST(StringListTest, Assignment) { + StringList orig; + orig.AppendString("foo"); + orig.AppendString("bar"); + + StringList s = orig; + + ASSERT_EQ(2U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + EXPECT_STREQ("bar", s.GetStringAtIndex(1)); + + ASSERT_EQ(2U, orig.GetSize()); + EXPECT_STREQ("foo", orig.GetStringAtIndex(0)); + EXPECT_STREQ("bar", orig.GetStringAtIndex(1)); +} + +TEST(StringListTest, AppendStringStdString) { + StringList s; + s.AppendString("foo"); + ASSERT_EQ(1U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + + s.AppendString("bar"); + ASSERT_EQ(2U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + EXPECT_STREQ("bar", s.GetStringAtIndex(1)); +} + +TEST(StringListTest, AppendStringCString) { + StringList s; + s.AppendString("foo", strlen("foo")); + ASSERT_EQ(1U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + + s.AppendString("bar", strlen("bar")); + ASSERT_EQ(2U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + EXPECT_STREQ("bar", s.GetStringAtIndex(1)); +} + +TEST(StringListTest, AppendStringMove) { + StringList s; + std::string foo = "foo"; + std::string bar = "bar"; + + s.AppendString(std::move(foo)); + ASSERT_EQ(1U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + + s.AppendString(std::move(bar)); + ASSERT_EQ(2U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + EXPECT_STREQ("bar", s.GetStringAtIndex(1)); +} + +TEST(StringListTest, ShiftStdString) { + StringList s; + std::string foo = "foo"; + std::string bar = "bar"; + + s << foo; + ASSERT_EQ(1U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + + s << bar; + ASSERT_EQ(2U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + EXPECT_STREQ("bar", s.GetStringAtIndex(1)); +} + +TEST(StringListTest, ShiftCString) { + StringList s; + s << "foo"; + ASSERT_EQ(1U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + + s << "bar"; + ASSERT_EQ(2U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + EXPECT_STREQ("bar", s.GetStringAtIndex(1)); +} + +TEST(StringListTest, ShiftMove) { + StringList s; + std::string foo = "foo"; + std::string bar = "bar"; + + s << std::move(foo); + ASSERT_EQ(1U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + + s << std::move(bar); + ASSERT_EQ(2U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + EXPECT_STREQ("bar", s.GetStringAtIndex(1)); +} + +TEST(StringListTest, AppendListCStringArrayEmpty) { + StringList s; + s.AppendList(nullptr, 0); + EXPECT_EQ(0U, s.GetSize()); +} + +TEST(StringListTest, AppendListCStringArray) { + StringList s; + const char *items[3] = {"foo", "", "bar"}; + s.AppendList(items, 3); + + EXPECT_EQ(3U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + EXPECT_STREQ("", s.GetStringAtIndex(1)); + EXPECT_STREQ("bar", s.GetStringAtIndex(2)); +} + +TEST(StringListTest, AppendList) { + StringList other; + other.AppendString("foo"); + other.AppendString(""); + other.AppendString("bar"); + + StringList empty; + + StringList s; + s.AppendList(other); + + EXPECT_EQ(3U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + EXPECT_STREQ("", s.GetStringAtIndex(1)); + EXPECT_STREQ("bar", s.GetStringAtIndex(2)); + + EXPECT_EQ(3U, other.GetSize()); + EXPECT_STREQ("foo", other.GetStringAtIndex(0)); + EXPECT_STREQ("", other.GetStringAtIndex(1)); + EXPECT_STREQ("bar", other.GetStringAtIndex(2)); + + s.AppendList(empty); + s.AppendList(other); + EXPECT_EQ(6U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + EXPECT_STREQ("", s.GetStringAtIndex(1)); + EXPECT_STREQ("bar", s.GetStringAtIndex(2)); + EXPECT_STREQ("foo", s.GetStringAtIndex(3)); + EXPECT_STREQ("", s.GetStringAtIndex(4)); + EXPECT_STREQ("bar", s.GetStringAtIndex(5)); + + EXPECT_EQ(3U, other.GetSize()); + EXPECT_STREQ("foo", other.GetStringAtIndex(0)); + EXPECT_STREQ("", other.GetStringAtIndex(1)); + EXPECT_STREQ("bar", other.GetStringAtIndex(2)); +} + +TEST(StringListTest, GetSize) { + StringList s; + s.AppendString("foo"); + EXPECT_EQ(1U, s.GetSize()); + + s.AppendString("foo"); + EXPECT_EQ(2U, s.GetSize()); + + s.AppendString("foobar"); + EXPECT_EQ(3U, s.GetSize()); +} + +TEST(StringListTest, SetSize) { + StringList s; + s.SetSize(3); + EXPECT_EQ(3U, s.GetSize()); + EXPECT_STREQ("", s.GetStringAtIndex(0)); + EXPECT_STREQ("", s.GetStringAtIndex(1)); + EXPECT_STREQ("", s.GetStringAtIndex(2)); +} + +TEST(StringListTest, SplitIntoLines) { + StringList s; + s.SplitIntoLines("\nfoo\nbar\n\n"); + EXPECT_EQ(4U, s.GetSize()); + EXPECT_STREQ("", s.GetStringAtIndex(0)); + EXPECT_STREQ("foo", s.GetStringAtIndex(1)); + EXPECT_STREQ("bar", s.GetStringAtIndex(2)); + EXPECT_STREQ("", s.GetStringAtIndex(3)); +} + +TEST(StringListTest, SplitIntoLinesSingleTrailingCR) { + StringList s; + s.SplitIntoLines("\r"); + EXPECT_EQ(1U, s.GetSize()); + EXPECT_STREQ("", s.GetStringAtIndex(0)); +} + +TEST(StringListTest, SplitIntoLinesEmpty) { + StringList s; + s.SplitIntoLines(""); + EXPECT_EQ(0U, s.GetSize()); +} + +TEST(StringListTest, LongestCommonPrefixEmpty) { + StringList s; + std::string prefix = "this should be cleared"; + s.LongestCommonPrefix(prefix); + EXPECT_EQ("", prefix); +} + +TEST(StringListTest, LongestCommonPrefix) { + StringList s; + s.AppendString("foo"); + s.AppendString("foobar"); + s.AppendString("foo"); + s.AppendString("foozar"); + + std::string prefix = "this should be cleared"; + s.LongestCommonPrefix(prefix); + EXPECT_EQ("foo", prefix); +} + +TEST(StringListTest, LongestCommonPrefixSingleElement) { + StringList s; + s.AppendString("foo"); + + std::string prefix = "this should be cleared"; + s.LongestCommonPrefix(prefix); + EXPECT_EQ("foo", prefix); +} + +TEST(StringListTest, LongestCommonPrefixDuplicateElement) { + StringList s; + s.AppendString("foo"); + s.AppendString("foo"); + + std::string prefix = "this should be cleared"; + s.LongestCommonPrefix(prefix); + EXPECT_EQ("foo", prefix); +} + +TEST(StringListTest, LongestCommonPrefixNoPrefix) { + StringList s; + s.AppendString("foo"); + s.AppendString("1foobar"); + s.AppendString("2foo"); + s.AppendString("3foozar"); + + std::string prefix = "this should be cleared"; + s.LongestCommonPrefix(prefix); + EXPECT_EQ("", prefix); +} + +TEST(StringListTest, Clear) { + StringList s; + s.Clear(); + EXPECT_EQ(0U, s.GetSize()); + + s.AppendString("foo"); + s.Clear(); + EXPECT_EQ(0U, s.GetSize()); + + s.AppendString("foo"); + s.AppendString("foo"); + s.Clear(); + EXPECT_EQ(0U, s.GetSize()); +} + +TEST(StringListTest, PopBack) { + StringList s; + s.AppendString("foo"); + s.AppendString("bar"); + s.AppendString("boo"); + + s.PopBack(); + EXPECT_EQ(2U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + EXPECT_STREQ("bar", s.GetStringAtIndex(1)); + + s.PopBack(); + EXPECT_EQ(1U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + + s.PopBack(); + EXPECT_EQ(0U, s.GetSize()); +} + +TEST(StringListTest, RemoveBlankLines) { + StringList s; + + // Nothing to remove yet. + s.RemoveBlankLines(); + EXPECT_EQ(0U, s.GetSize()); + + // Add some lines. + s.AppendString(""); + s.AppendString(""); + s.AppendString("\t"); + s.AppendString(""); + s.AppendString(" "); + s.AppendString(""); + s.AppendString(""); + s.AppendString("f"); + s.AppendString(""); + s.AppendString(""); + + // And remove all the empty ones again. + s.RemoveBlankLines(); + + EXPECT_EQ(3U, s.GetSize()); + EXPECT_STREQ("\t", s.GetStringAtIndex(0)); + EXPECT_STREQ(" ", s.GetStringAtIndex(1)); + EXPECT_STREQ("f", s.GetStringAtIndex(2)); +} + +TEST(StringListTest, InsertStringAtIndexStart) { + StringList s; + + s.InsertStringAtIndex(0, "bar"); + EXPECT_EQ(1U, s.GetSize()); + EXPECT_STREQ("bar", s.GetStringAtIndex(0)); + + s.InsertStringAtIndex(0, "foo"); + EXPECT_EQ(2U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + EXPECT_STREQ("bar", s.GetStringAtIndex(1)); +} + +TEST(StringListTest, InsertStringAtIndexEnd) { + StringList s; + + s.InsertStringAtIndex(0, "foo"); + EXPECT_EQ(1U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + + s.InsertStringAtIndex(1, "bar"); + EXPECT_EQ(2U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + EXPECT_STREQ("bar", s.GetStringAtIndex(1)); +} + +TEST(StringListTest, InsertStringAtIndexOutOfBounds) { + StringList s; + + s.InsertStringAtIndex(1, "foo"); + EXPECT_EQ(1U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + + // FIXME: Inserting at an OOB index will always just append to the list. This + // seems not very intuitive. + s.InsertStringAtIndex(3, "bar"); + EXPECT_EQ(2U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); + EXPECT_STREQ("bar", s.GetStringAtIndex(1)); +} + +TEST(StringListTest, InsertStringAtIndexStdString) { + StringList s; + + std::string foo = "foo"; + s.InsertStringAtIndex(0, foo); + EXPECT_EQ(1U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); +} + +TEST(StringListTest, InsertStringAtIndexMove) { + StringList s; + + std::string foo = "foo"; + s.InsertStringAtIndex(0, std::move(foo)); + EXPECT_EQ(1U, s.GetSize()); + EXPECT_STREQ("foo", s.GetStringAtIndex(0)); +} + +TEST(StringListTest, CopyListEmpty) { + StringList s; + + EXPECT_EQ("", s.CopyList()); + EXPECT_EQ("", s.CopyList("+")); +} + +TEST(StringListTest, CopyListSingle) { + StringList s; + s.AppendString("ab"); + + EXPECT_EQ("ab", s.CopyList()); + EXPECT_EQ("-ab", s.CopyList("-")); +} + +TEST(StringListTest, CopyList) { + StringList s; + s.AppendString("ab"); + s.AppendString("cd"); + + EXPECT_EQ("ab\ncd", s.CopyList()); + EXPECT_EQ("-ab\n-cd", s.CopyList("-")); +} + +TEST(StringListTest, Join) { + StringList s; + s.AppendString("ab"); + s.AppendString("cd"); + + StreamString ss; + s.Join(" ", ss); + + EXPECT_EQ("ab cd", ss.GetString()); +} + +TEST(StringListTest, JoinEmpty) { + StringList s; + + StreamString ss; + s.Join(" ", ss); + + EXPECT_EQ("", ss.GetString()); +} + +TEST(StringListTest, JoinSingle) { + StringList s; + s.AppendString("foo"); + + StreamString ss; + s.Join(" ", ss); + + EXPECT_EQ("foo", ss.GetString()); +} + +TEST(StringListTest, JoinThree) { + StringList s; + s.AppendString("1"); + s.AppendString("2"); + s.AppendString("3"); + + StreamString ss; + s.Join(" ", ss); + + EXPECT_EQ("1 2 3", ss.GetString()); +} + +TEST(StringListTest, JoinNonSpace) { + StringList s; + s.AppendString("1"); + s.AppendString("2"); + s.AppendString("3"); + + StreamString ss; + s.Join(".", ss); + + EXPECT_EQ("1.2.3", ss.GetString()); +} + +TEST(StringListTest, JoinMultiCharSeparator) { + StringList s; + s.AppendString("1"); + s.AppendString("2"); + s.AppendString("3"); + + StreamString ss; + s.Join("--", ss); + + EXPECT_EQ("1--2--3", ss.GetString()); +} + +TEST(StringListTest, GetMaxStringLengthEqualSize) { + StringList s; + s.AppendString("123"); + s.AppendString("123"); + EXPECT_EQ(3U, s.GetMaxStringLength()); +} + +TEST(StringListTest, GetMaxStringLengthIncreasingSize) { + StringList s; + s.AppendString("123"); + s.AppendString("1234"); + EXPECT_EQ(4U, s.GetMaxStringLength()); +} + +TEST(StringListTest, GetMaxStringLengthDecreasingSize) { + StringList s; + s.AppendString("1234"); + s.AppendString("123"); + EXPECT_EQ(4U, s.GetMaxStringLength()); +} + +TEST(StringListTest, GetMaxStringLengthMixed) { + StringList s; + s.AppendString("123"); + s.AppendString("1"); + s.AppendString("123"); + s.AppendString("1234"); + s.AppendString("123"); + s.AppendString("1"); + EXPECT_EQ(4U, s.GetMaxStringLength()); +} + +TEST(StringListTest, GetMaxStringLengthEmpty) { + StringList s; + EXPECT_EQ(0U, s.GetMaxStringLength()); +} From 6e0e4430cd06b16601d973f9fc82dbe3cc8b20a8 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Mon, 6 Aug 2018 00:04:51 +0000 Subject: [PATCH 0055/1112] Remove duplicated code in CommandObjectQuit Summary: We already have the same check directly before, so this code can never be reached (as seen in the test coverage). Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D50317 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338976 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Commands/CommandObjectQuit.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/source/Commands/CommandObjectQuit.cpp b/source/Commands/CommandObjectQuit.cpp index 37ed12be358f..a9c430ea51c6 100644 --- a/source/Commands/CommandObjectQuit.cpp +++ b/source/Commands/CommandObjectQuit.cpp @@ -86,13 +86,6 @@ bool CommandObjectQuit::DoExecute(Args &command, CommandReturnObject &result) { return false; } - if (command.GetArgumentCount() > 1) { - result.AppendError("Too many arguments for 'quit'. Only an optional exit " - "code is allowed"); - result.SetStatus(eReturnStatusFailed); - return false; - } - // We parse the exit code argument if there is one. if (command.GetArgumentCount() == 1) { llvm::StringRef arg = command.GetArgumentAtIndex(0); From 799d0c26ce0b7aebef020d00959f03397ab74a76 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Mon, 6 Aug 2018 08:27:59 +0000 Subject: [PATCH 0056/1112] Change ConstString::SetCStringWithMangledCounterpart to use StringRef This should simplify the upcoming demangling patch (D50071). While I was in there, I also added a quick test for the function. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@338995 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Utility/ConstString.h | 7 ++-- source/Core/Mangled.cpp | 2 +- source/Utility/ConstString.cpp | 50 ++++++++++++--------------- unittests/Utility/ConstStringTest.cpp | 17 +++++++++ 4 files changed, 44 insertions(+), 32 deletions(-) diff --git a/include/lldb/Utility/ConstString.h b/include/lldb/Utility/ConstString.h index 98b3447abe3e..b6169a084d85 100644 --- a/include/lldb/Utility/ConstString.h +++ b/include/lldb/Utility/ConstString.h @@ -373,15 +373,14 @@ class ConstString { /// them. /// /// @param[in] demangled - /// The demangled C string to correlate with the \a mangled - /// name. + /// The demangled string to correlate with the \a mangled name. /// /// @param[in] mangled /// The already uniqued mangled ConstString to correlate the /// soon to be uniqued version of \a demangled. //------------------------------------------------------------------ - void SetCStringWithMangledCounterpart(const char *demangled, - const ConstString &mangled); + void SetStringWithMangledCounterpart(llvm::StringRef demangled, + const ConstString &mangled); //------------------------------------------------------------------ /// Retrieve the mangled or demangled counterpart for a mangled or demangled diff --git a/source/Core/Mangled.cpp b/source/Core/Mangled.cpp index 545ac51c870f..043afe735fdb 100644 --- a/source/Core/Mangled.cpp +++ b/source/Core/Mangled.cpp @@ -308,7 +308,7 @@ Mangled::GetDemangledName(lldb::LanguageType language) const { break; } if (demangled_name) { - m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled); + m_demangled.SetStringWithMangledCounterpart(demangled_name, m_mangled); free(demangled_name); } } diff --git a/source/Utility/ConstString.cpp b/source/Utility/ConstString.cpp index 5ef4b2faa3b8..e903783df52e 100644 --- a/source/Utility/ConstString.cpp +++ b/source/Utility/ConstString.cpp @@ -111,38 +111,34 @@ class Pool { } const char * - GetConstCStringAndSetMangledCounterPart(const char *demangled_cstr, + GetConstCStringAndSetMangledCounterPart(llvm::StringRef demangled, const char *mangled_ccstr) { - if (demangled_cstr != nullptr) { - const char *demangled_ccstr = nullptr; + const char *demangled_ccstr = nullptr; - { - llvm::StringRef string_ref(demangled_cstr); - const uint8_t h = hash(string_ref); - llvm::sys::SmartScopedWriter wlock(m_string_pools[h].m_mutex); - - // Make string pool entry with the mangled counterpart already set - StringPoolEntryType &entry = - *m_string_pools[h] - .m_string_map.insert(std::make_pair(string_ref, mangled_ccstr)) - .first; + { + const uint8_t h = hash(demangled); + llvm::sys::SmartScopedWriter wlock(m_string_pools[h].m_mutex); - // Extract the const version of the demangled_cstr - demangled_ccstr = entry.getKeyData(); - } + // Make string pool entry with the mangled counterpart already set + StringPoolEntryType &entry = + *m_string_pools[h] + .m_string_map.insert(std::make_pair(demangled, mangled_ccstr)) + .first; - { - // Now assign the demangled const string as the counterpart of the - // mangled const string... - const uint8_t h = hash(llvm::StringRef(mangled_ccstr)); - llvm::sys::SmartScopedWriter wlock(m_string_pools[h].m_mutex); - GetStringMapEntryFromKeyData(mangled_ccstr).setValue(demangled_ccstr); - } + // Extract the const version of the demangled_cstr + demangled_ccstr = entry.getKeyData(); + } - // Return the constant demangled C string - return demangled_ccstr; + { + // Now assign the demangled const string as the counterpart of the + // mangled const string... + const uint8_t h = hash(llvm::StringRef(mangled_ccstr)); + llvm::sys::SmartScopedWriter wlock(m_string_pools[h].m_mutex); + GetStringMapEntryFromKeyData(mangled_ccstr).setValue(demangled_ccstr); } - return nullptr; + + // Return the constant demangled C string + return demangled_ccstr; } const char *GetConstTrimmedCStringWithLength(const char *cstr, @@ -306,7 +302,7 @@ void ConstString::SetString(const llvm::StringRef &s) { m_string = StringPool().GetConstCStringWithLength(s.data(), s.size()); } -void ConstString::SetCStringWithMangledCounterpart(const char *demangled, +void ConstString::SetStringWithMangledCounterpart(llvm::StringRef demangled, const ConstString &mangled) { m_string = StringPool().GetConstCStringAndSetMangledCounterPart( demangled, mangled.m_string); diff --git a/unittests/Utility/ConstStringTest.cpp b/unittests/Utility/ConstStringTest.cpp index 454f656760ca..2c87f2bc154b 100644 --- a/unittests/Utility/ConstStringTest.cpp +++ b/unittests/Utility/ConstStringTest.cpp @@ -16,3 +16,20 @@ using namespace lldb_private; TEST(ConstStringTest, format_provider) { EXPECT_EQ("foo", llvm::formatv("{0}", ConstString("foo")).str()); } + +TEST(ConstStringTest, MangledCounterpart) { + ConstString foo("foo"); + ConstString counterpart; + EXPECT_FALSE(foo.GetMangledCounterpart(counterpart)); + EXPECT_EQ("", counterpart.GetStringRef()); + + ConstString bar; + bar.SetStringWithMangledCounterpart("bar", foo); + EXPECT_EQ("bar", bar.GetStringRef()); + + EXPECT_TRUE(bar.GetMangledCounterpart(counterpart)); + EXPECT_EQ("foo", counterpart.GetStringRef()); + + EXPECT_TRUE(foo.GetMangledCounterpart(counterpart)); + EXPECT_EQ("bar", counterpart.GetStringRef()); +} From dc7e7cae660c66ed61d3a13b3696a805588ee805 Mon Sep 17 00:00:00 2001 From: Stefan Granitz Date: Mon, 6 Aug 2018 14:15:17 +0000 Subject: [PATCH 0057/1112] Add ConstString::IsNull() to tell between null vs. empty strings and fix usage in Mangled::GetDemangledName() Summary: `IsEmpty()` and `operator bool() == false` have equal semantics. Usage in Mangled::GetDemangledName() was incorrect. What it actually wants is a check for null-string. Split this off of D50071 and added a test to clarify usage. Reviewers: labath, jingham Subscribers: erik.pilkington, lldb-commits Differential Revision: https://reviews.llvm.org/D50327 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339014 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Utility/ConstString.h | 9 +++++++++ source/Core/Mangled.cpp | 4 ++-- unittests/Utility/ConstStringTest.cpp | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/include/lldb/Utility/ConstString.h b/include/lldb/Utility/ConstString.h index b6169a084d85..1c580caf2903 100644 --- a/include/lldb/Utility/ConstString.h +++ b/include/lldb/Utility/ConstString.h @@ -345,6 +345,15 @@ class ConstString { //------------------------------------------------------------------ bool IsEmpty() const { return m_string == nullptr || m_string[0] == '\0'; } + //------------------------------------------------------------------ + /// Test for null string. + /// + /// @return + /// @li \b true if there is no string associated with this instance. + /// @li \b false if there is a string associated with this instance. + //------------------------------------------------------------------ + bool IsNull() const { return m_string == nullptr; } + //------------------------------------------------------------------ /// Set the C string value. /// diff --git a/source/Core/Mangled.cpp b/source/Core/Mangled.cpp index 043afe735fdb..a6a5f8d36607 100644 --- a/source/Core/Mangled.cpp +++ b/source/Core/Mangled.cpp @@ -242,7 +242,7 @@ const ConstString & Mangled::GetDemangledName(lldb::LanguageType language) const { // Check to make sure we have a valid mangled name and that we haven't // already decoded our mangled name. - if (m_mangled && !m_demangled) { + if (m_mangled && m_demangled.IsNull()) { // We need to generate and cache the demangled name. static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "Mangled::GetDemangledName (m_mangled = %s)", @@ -312,7 +312,7 @@ Mangled::GetDemangledName(lldb::LanguageType language) const { free(demangled_name); } } - if (!m_demangled) { + if (m_demangled.IsNull()) { // Set the demangled string to the empty string to indicate we tried to // parse it once and failed. m_demangled.SetCString(""); diff --git a/unittests/Utility/ConstStringTest.cpp b/unittests/Utility/ConstStringTest.cpp index 2c87f2bc154b..add76a012e1d 100644 --- a/unittests/Utility/ConstStringTest.cpp +++ b/unittests/Utility/ConstStringTest.cpp @@ -33,3 +33,20 @@ TEST(ConstStringTest, MangledCounterpart) { EXPECT_TRUE(foo.GetMangledCounterpart(counterpart)); EXPECT_EQ("bar", counterpart.GetStringRef()); } + +TEST(ConstStringTest, NullAndEmptyStates) { + ConstString foo("foo"); + EXPECT_FALSE(!foo); + EXPECT_FALSE(foo.IsEmpty()); + EXPECT_FALSE(foo.IsNull()); + + ConstString empty(""); + EXPECT_TRUE(!empty); + EXPECT_TRUE(empty.IsEmpty()); + EXPECT_FALSE(empty.IsNull()); + + ConstString null; + EXPECT_TRUE(!null); + EXPECT_TRUE(null.IsEmpty()); + EXPECT_TRUE(null.IsNull()); +} From 569d6c184890ea293022da90cd570253064aa132 Mon Sep 17 00:00:00 2001 From: Stefan Granitz Date: Mon, 6 Aug 2018 14:15:21 +0000 Subject: [PATCH 0058/1112] Fix Mangled::Compare() git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339015 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Core/Mangled.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Core/Mangled.cpp b/source/Core/Mangled.cpp index a6a5f8d36607..b8a43be10fbc 100644 --- a/source/Core/Mangled.cpp +++ b/source/Core/Mangled.cpp @@ -195,7 +195,7 @@ void Mangled::Clear() { int Mangled::Compare(const Mangled &a, const Mangled &b) { return ConstString::Compare( a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled), - a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled)); + b.GetName(lldb::eLanguageTypeUnknown, ePreferMangled)); } //---------------------------------------------------------------------- From f6cabcbf5c95779cb6a86fa2a26000d5885be84b Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Mon, 6 Aug 2018 16:56:10 +0000 Subject: [PATCH 0059/1112] Add support for ARM and ARM64 breakpad generated minidump files (version 2). In this patch I add support for ARM and ARM64 break pad files. There are two flavors of ARM: Apple where FP is R7, and non Apple where FP is R11. Added minimal tests that load up ARM64 and the two flavors or ARM core files with a single thread and known register values in each register. Each register is checked for the exact value. This is a fixed version of: https://reviews.llvm.org/D49750 The changes from D49750 are: Don't init the m_arch in the Initialize call as a system info isn't required. This keeps the thread list, module list and other tests from failing Added -Wextended-offsetof to Xcode project so we catch use extended usages of offsetof before submission Fixed any extended offset of warnings Differential Revision: https://reviews.llvm.org/D50336 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339032 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Target/Target.h | 30 +- lldb.xcodeproj/project.pbxproj | 16 + .../minidump-new/TestMiniDumpNew.py | 155 ++++ .../postmortem/minidump-new/arm-linux.dmp | Bin 0 -> 588 bytes .../postmortem/minidump-new/arm-macos.dmp | Bin 0 -> 588 bytes .../postmortem/minidump-new/arm64-macos.dmp | Bin 0 -> 1016 bytes .../Plugins/Process/minidump/CMakeLists.txt | 2 + .../Process/minidump/MinidumpParser.cpp | 26 +- .../Plugins/Process/minidump/MinidumpParser.h | 1 + .../Process/minidump/ProcessMinidump.cpp | 14 +- .../minidump/RegisterContextMinidump_ARM.cpp | 532 +++++++++++ .../minidump/RegisterContextMinidump_ARM.h | 95 ++ .../RegisterContextMinidump_ARM64.cpp | 836 ++++++++++++++++++ .../minidump/RegisterContextMinidump_ARM64.h | 85 ++ .../Process/minidump/ThreadMinidump.cpp | 24 +- source/Target/Target.cpp | 22 +- 16 files changed, 1805 insertions(+), 33 deletions(-) create mode 100644 packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-linux.dmp create mode 100644 packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-macos.dmp create mode 100644 packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm64-macos.dmp create mode 100644 source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp create mode 100644 source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h create mode 100644 source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp create mode 100644 source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h diff --git a/include/lldb/Target/Target.h b/include/lldb/Target/Target.h index 75af8e80d2e5..a4a00eb2d371 100644 --- a/include/lldb/Target/Target.h +++ b/include/lldb/Target/Target.h @@ -913,28 +913,30 @@ class Target : public std::enable_shared_from_this, /// Set the architecture for this target. /// /// If the current target has no Images read in, then this just sets the - /// architecture, which will - /// be used to select the architecture of the ExecutableModule when that is - /// set. - /// If the current target has an ExecutableModule, then calling - /// SetArchitecture with a different + /// architecture, which will be used to select the architecture of the + /// ExecutableModule when that is set. If the current target has an + /// ExecutableModule, then calling SetArchitecture with a different /// architecture from the currently selected one will reset the - /// ExecutableModule to that slice - /// of the file backing the ExecutableModule. If the file backing the - /// ExecutableModule does not - /// contain a fork of this architecture, then this code will return false, and - /// the architecture - /// won't be changed. - /// If the input arch_spec is the same as the already set architecture, this - /// is a no-op. + /// ExecutableModule to that slice of the file backing the ExecutableModule. + /// If the file backing the ExecutableModule does not contain a fork of this + /// architecture, then this code will return false, and the architecture + /// won't be changed. If the input arch_spec is the same as the already set + /// architecture, this is a no-op. /// /// @param[in] arch_spec /// The new architecture. /// + /// @param[in] set_platform + /// If \b true, then the platform will be adjusted if the currently + /// selected platform is not compatible with the archicture being set. + /// If \b false, then just the architecture will be set even if the + /// currently selected platform isn't compatible (in case it might be + /// manually set following this function call). + /// /// @return /// \b true if the architecture was successfully set, \bfalse otherwise. //------------------------------------------------------------------ - bool SetArchitecture(const ArchSpec &arch_spec); + bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform = false); bool MergeArchitecture(const ArchSpec &arch_spec); diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index 3faf425351bd..f34c403c959e 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -665,6 +665,10 @@ 26474CBE18D0CB2D0073DEBA /* RegisterContextMach_i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26474CB818D0CB2D0073DEBA /* RegisterContextMach_i386.cpp */; }; 26474CC018D0CB2D0073DEBA /* RegisterContextMach_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26474CBA18D0CB2D0073DEBA /* RegisterContextMach_x86_64.cpp */; }; 26474CC918D0CB5B0073DEBA /* RegisterContextMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26474CC218D0CB5B0073DEBA /* RegisterContextMemory.cpp */; }; + 2619C4852107A9A2009CDE81 /* RegisterContextMinidump_ARM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2619C4812107A9A1009CDE81 /* RegisterContextMinidump_ARM.cpp */; }; + 2619C4872107A9A2009CDE81 /* RegisterContextMinidump_ARM.h in Headers */ = {isa = PBXBuildFile; fileRef = 2619C4832107A9A2009CDE81 /* RegisterContextMinidump_ARM.h */; }; + 2619C4842107A9A2009CDE81 /* RegisterContextMinidump_ARM64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2619C4802107A9A1009CDE81 /* RegisterContextMinidump_ARM64.cpp */; }; + 2619C4862107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h in Headers */ = {isa = PBXBuildFile; fileRef = 2619C4822107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h */; }; 947CF7761DC7B20D00EF980B /* RegisterContextMinidump_x86_32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 947CF7741DC7B20D00EF980B /* RegisterContextMinidump_x86_32.cpp */; }; AFD65C811D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFD65C7F1D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp */; }; AFD65C821D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = AFD65C801D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.h */; }; @@ -2542,6 +2546,10 @@ 26474CC218D0CB5B0073DEBA /* RegisterContextMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextMemory.cpp; path = Utility/RegisterContextMemory.cpp; sourceTree = ""; }; 262D24E513FB8710002D1960 /* RegisterContextMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextMemory.h; path = Utility/RegisterContextMemory.h; sourceTree = ""; }; 26474CC318D0CB5B0073DEBA /* RegisterContextMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextMemory.h; path = Utility/RegisterContextMemory.h; sourceTree = ""; }; + 2619C4812107A9A1009CDE81 /* RegisterContextMinidump_ARM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextMinidump_ARM.cpp; sourceTree = ""; }; + 2619C4832107A9A2009CDE81 /* RegisterContextMinidump_ARM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextMinidump_ARM.h; sourceTree = ""; }; + 2619C4802107A9A1009CDE81 /* RegisterContextMinidump_ARM64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextMinidump_ARM64.cpp; sourceTree = ""; }; + 2619C4822107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextMinidump_ARM64.h; sourceTree = ""; }; 947CF7741DC7B20D00EF980B /* RegisterContextMinidump_x86_32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextMinidump_x86_32.cpp; sourceTree = ""; }; 947CF7721DC7B20300EF980B /* RegisterContextMinidump_x86_32.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RegisterContextMinidump_x86_32.h; sourceTree = ""; }; AFD65C7F1D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextMinidump_x86_64.cpp; sourceTree = ""; }; @@ -3787,6 +3795,10 @@ 23E2E5351D9048E7006F38BB /* minidump */ = { isa = PBXGroup; children = ( + 2619C4812107A9A1009CDE81 /* RegisterContextMinidump_ARM.cpp */, + 2619C4832107A9A2009CDE81 /* RegisterContextMinidump_ARM.h */, + 2619C4802107A9A1009CDE81 /* RegisterContextMinidump_ARM64.cpp */, + 2619C4822107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h */, AFD65C7F1D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp */, AFD65C801D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.h */, 23E2E5361D9048FB006F38BB /* CMakeLists.txt */, @@ -6939,8 +6951,10 @@ AF6CA6681FBBAF37005A0DC3 /* ArchSpec.h in Headers */, AF235EB41FBE7858009C5541 /* RegisterInfoPOSIX_ppc64le.h in Headers */, AF2E02A41FA2CEAF00A86C34 /* ArchitectureArm.h in Headers */, + 2619C4872107A9A2009CDE81 /* RegisterContextMinidump_ARM.h in Headers */, 267F685A1CC02EBE0086832B /* RegisterInfos_s390x.h in Headers */, 267F68541CC02E920086832B /* RegisterContextLinux_s390x.h in Headers */, + 2619C4862107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h in Headers */, AF235EB11FBE77B6009C5541 /* RegisterContextPOSIX_ppc64le.h in Headers */, 267F68501CC02E270086832B /* RegisterContextPOSIXCore_s390x.h in Headers */, 4984BA181B979C08008658D4 /* ExpressionVariable.h in Headers */, @@ -7643,6 +7657,7 @@ 2689002113353DDE00698AC0 /* CommandObjectQuit.cpp in Sources */, 2689002213353DDE00698AC0 /* CommandObjectRegister.cpp in Sources */, 26BC17AF18C7F4CB00D2196D /* RegisterContextPOSIXCore_x86_64.cpp in Sources */, + 2619C4842107A9A2009CDE81 /* RegisterContextMinidump_ARM64.cpp in Sources */, 2689002313353DDE00698AC0 /* CommandObjectScript.cpp in Sources */, 2689002413353DDE00698AC0 /* CommandObjectSettings.cpp in Sources */, 2689002513353DDE00698AC0 /* CommandObjectSource.cpp in Sources */, @@ -7723,6 +7738,7 @@ 2689005113353E0400698AC0 /* StringList.cpp in Sources */, 2689005213353E0400698AC0 /* Timer.cpp in Sources */, 2689005413353E0400698AC0 /* UserSettingsController.cpp in Sources */, + 2619C4852107A9A2009CDE81 /* RegisterContextMinidump_ARM.cpp in Sources */, 23059A0719532B96007B8189 /* LinuxSignals.cpp in Sources */, 8CCB017E19BA28A80009FD44 /* ThreadCollection.cpp in Sources */, 9A77AD541E64E2760025CE04 /* RegisterInfoPOSIX_arm.cpp in Sources */, diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py index 5960215f8047..8c7cb540a37c 100644 --- a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py +++ b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py @@ -189,6 +189,161 @@ def test_snapshot_minidump(self): stop_description = thread.GetStopDescription(256) self.assertEqual(stop_description, "") + def check_register_unsigned(self, set, name, expected): + reg_value = set.GetChildMemberWithName(name) + self.assertTrue(reg_value.IsValid(), + 'Verify we have a register named "%s"' % (name)) + self.assertEqual(reg_value.GetValueAsUnsigned(), expected, + 'Verify "%s" == %i' % (name, expected)) + + def check_register_string_value(self, set, name, expected, format): + reg_value = set.GetChildMemberWithName(name) + self.assertTrue(reg_value.IsValid(), + 'Verify we have a register named "%s"' % (name)) + if format is not None: + reg_value.SetFormat(format) + self.assertEqual(reg_value.GetValue(), expected, + 'Verify "%s" has string value "%s"' % (name, + expected)) + + def test_arm64_registers(self): + """Test ARM64 registers from a breakpad created minidump.""" + # target create -c arm64-macos.dmp + self.dbg.CreateTarget(None) + self.target = self.dbg.GetSelectedTarget() + self.process = self.target.LoadCore("arm64-macos.dmp") + self.check_state() + self.assertEqual(self.process.GetNumThreads(), 1) + thread = self.process.GetThreadAtIndex(0) + self.assertEqual(thread.GetStopReason(), lldb.eStopReasonNone) + stop_description = thread.GetStopDescription(256) + self.assertEqual(stop_description, "") + registers = thread.GetFrameAtIndex(0).GetRegisters() + # Verify the GPR registers are all correct + # Verify x0 - x31 register values + gpr = registers.GetValueAtIndex(0) + for i in range(32): + v = i+1 | i+2 << 32 | i+3 << 48 + w = i+1 + self.check_register_unsigned(gpr, 'x%i' % (i), v) + self.check_register_unsigned(gpr, 'w%i' % (i), w) + # Verify arg1 - arg8 register values + for i in range(1, 9): + v = i | i+1 << 32 | i+2 << 48 + self.check_register_unsigned(gpr, 'arg%i' % (i), v) + i = 29 + v = i+1 | i+2 << 32 | i+3 << 48 + self.check_register_unsigned(gpr, 'fp', v) + i = 30 + v = i+1 | i+2 << 32 | i+3 << 48 + self.check_register_unsigned(gpr, 'lr', v) + i = 31 + v = i+1 | i+2 << 32 | i+3 << 48 + self.check_register_unsigned(gpr, 'sp', v) + self.check_register_unsigned(gpr, 'pc', 0x1000) + self.check_register_unsigned(gpr, 'cpsr', 0x11223344) + self.check_register_unsigned(gpr, 'psr', 0x11223344) + + # Verify the FPR registers are all correct + fpr = registers.GetValueAtIndex(1) + for i in range(32): + v = "0x" + d = "0x" + s = "0x" + h = "0x" + for j in range(i+15, i-1, -1): + v += "%2.2x" % (j) + for j in range(i+7, i-1, -1): + d += "%2.2x" % (j) + for j in range(i+3, i-1, -1): + s += "%2.2x" % (j) + for j in range(i+1, i-1, -1): + h += "%2.2x" % (j) + self.check_register_string_value(fpr, "v%i" % (i), v, + lldb.eFormatHex) + self.check_register_string_value(fpr, "d%i" % (i), d, + lldb.eFormatHex) + self.check_register_string_value(fpr, "s%i" % (i), s, + lldb.eFormatHex) + self.check_register_string_value(fpr, "h%i" % (i), h, + lldb.eFormatHex) + self.check_register_unsigned(gpr, 'fpsr', 0x55667788) + self.check_register_unsigned(gpr, 'fpcr', 0x99aabbcc) + + def verify_arm_registers(self, apple=False): + """ + Verify values of all ARM registers from a breakpad created + minidump. + """ + self.dbg.CreateTarget(None) + self.target = self.dbg.GetSelectedTarget() + if apple: + self.process = self.target.LoadCore("arm-macos.dmp") + else: + self.process = self.target.LoadCore("arm-linux.dmp") + self.check_state() + self.assertEqual(self.process.GetNumThreads(), 1) + thread = self.process.GetThreadAtIndex(0) + self.assertEqual(thread.GetStopReason(), lldb.eStopReasonNone) + stop_description = thread.GetStopDescription(256) + self.assertEqual(stop_description, "") + registers = thread.GetFrameAtIndex(0).GetRegisters() + # Verify the GPR registers are all correct + # Verify x0 - x31 register values + gpr = registers.GetValueAtIndex(0) + for i in range(1, 16): + self.check_register_unsigned(gpr, 'r%i' % (i), i+1) + # Verify arg1 - arg4 register values + for i in range(1, 5): + self.check_register_unsigned(gpr, 'arg%i' % (i), i) + if apple: + self.check_register_unsigned(gpr, 'fp', 0x08) + else: + self.check_register_unsigned(gpr, 'fp', 0x0c) + self.check_register_unsigned(gpr, 'lr', 0x0f) + self.check_register_unsigned(gpr, 'sp', 0x0e) + self.check_register_unsigned(gpr, 'pc', 0x10) + self.check_register_unsigned(gpr, 'cpsr', 0x11223344) + + # Verify the FPR registers are all correct + fpr = registers.GetValueAtIndex(1) + # Check d0 - d31 + self.check_register_unsigned(gpr, 'fpscr', 0x55667788aabbccdd) + for i in range(32): + value = (i+1) | (i+1) << 8 | (i+1) << 32 | (i+1) << 48 + self.check_register_unsigned(fpr, "d%i" % (i), value) + # Check s0 - s31 + for i in range(32): + i_val = (i >> 1) + 1 + if i & 1: + value = "%#8.8x" % (i_val | i_val << 16) + else: + value = "%#8.8x" % (i_val | i_val << 8) + self.check_register_string_value(fpr, "s%i" % (i), value, + lldb.eFormatHex) + # Check q0 - q15 + for i in range(15): + a = i * 2 + 1 + b = a + 1 + value = ("0x00%2.2x00%2.2x0000%2.2x%2.2x" + "00%2.2x00%2.2x0000%2.2x%2.2x") % (b, b, b, b, a, a, a, a) + self.check_register_string_value(fpr, "q%i" % (i), value, + lldb.eFormatHex) + + def test_linux_arm_registers(self): + """Test Linux ARM registers from a breakpad created minidump. + + The frame pointer is R11 for linux. + """ + self.verify_arm_registers(apple=False) + + def test_apple_arm_registers(self): + """Test Apple ARM registers from a breakpad created minidump. + + The frame pointer is R7 for linux. + """ + self.verify_arm_registers(apple=True) + def do_test_deeper_stack(self, binary, core, pid): target = self.dbg.CreateTarget(binary) process = target.LoadCore(core) diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-linux.dmp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-linux.dmp new file mode 100644 index 0000000000000000000000000000000000000000..3b0cb8268defef9d4cb64a7f574b8ff8ead084f9 GIT binary patch literal 588 zcmaKqPfmky5Jo?sKnpE}7D|DZHr_zHap@nnP26||*X~^C%9VS)gNax03O$0}#Wzjd z5aaLV6*__WX43Av{mtvU3$TBH|*-Vs(6&+wn~k)A?biMqd~lBY+wQiv?QHwnuJ8l1ycf>^ literal 0 HcmV?d00001 diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-macos.dmp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm-macos.dmp new file mode 100644 index 0000000000000000000000000000000000000000..9ff6a8396ec5c448dbd0af82ee66812d0adec94c GIT binary patch literal 588 zcmaKqPfmky5Jo?sKnpE}7D|DZHr_zHap@nnP26||*X~^C#+`e;gNax03O$0}#Wzjd z5aaLV6*__WX43Av{mtvU3$TBH|*-Vs(6&+wn~k)A?biMqd~lBY+wQiv?QHwnuJ8k~$rsK5 literal 0 HcmV?d00001 diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm64-macos.dmp b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/arm64-macos.dmp new file mode 100644 index 0000000000000000000000000000000000000000..ba658dd48feb905d3ca851b66fb4dcda5c8828d5 GIT binary patch literal 1016 zcmaKpNlwE+6htcn34w&znFnWN9wk5^4iJ`+*l-1|zycPqV-FinfW#HJ0!QF5yx)lv z+d^1+)xWxbcbD4J$@J#+L&``RLh{QqaRn17Lkk|k`fdKr>L(=erJkkl#N1yt#pFX` z!RFlOg~k74K$ss|ig2n6UF(eTQaS0#cG`Jq5~mq6%DU`XtxyTgfzZ75qpKja07BP5 z=sE~3g56be_m#9kCA19oMxJ{oPd=5<3J9%&&>9G>gU|*DZGzAi*gLn~TesDr650i! z0SN7Z&^`zqfY2e>zZ`+kv0M=9$@$oSxxc&p{`!1ZDxJx$csd_version_rva)) + csd_version = *s; + if (csd_version.find("Linux") != std::string::npos) + triple.setOS(llvm::Triple::OSType::Linux); break; + } } - - arch_spec.SetTriple(triple); - - return arch_spec; + m_arch.SetTriple(triple); + return m_arch; } const MinidumpMiscInfo *MinidumpParser::GetMiscInfo() { diff --git a/source/Plugins/Process/minidump/MinidumpParser.h b/source/Plugins/Process/minidump/MinidumpParser.h index 49b1eef14de5..48c752b541eb 100644 --- a/source/Plugins/Process/minidump/MinidumpParser.h +++ b/source/Plugins/Process/minidump/MinidumpParser.h @@ -98,6 +98,7 @@ class MinidumpParser { private: lldb::DataBufferSP m_data_sp; llvm::DenseMap m_directory_map; + ArchSpec m_arch; }; } // end namespace minidump diff --git a/source/Plugins/Process/minidump/ProcessMinidump.cpp b/source/Plugins/Process/minidump/ProcessMinidump.cpp index b43f22382eac..7af6301b7f1a 100644 --- a/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -29,6 +29,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Threading.h" +#include "Plugins/Process/Utility/StopInfoMachException.h" // C includes // C++ includes @@ -174,19 +175,21 @@ Status ProcessMinidump::DoLoadCore() { switch (arch.GetMachine()) { case llvm::Triple::x86: case llvm::Triple::x86_64: - // supported + case llvm::Triple::arm: + case llvm::Triple::aarch64: + // Any supported architectures must be listed here and also supported in + // ThreadMinidump::CreateRegisterContextForFrame(). break; - default: error.SetErrorStringWithFormat("unsupported minidump architecture: %s", arch.GetArchitectureName()); return error; } + GetTarget().SetArchitecture(arch, true /*set_platform*/); m_thread_list = m_minidump_parser.GetThreads(); m_active_exception = m_minidump_parser.GetExceptionStream(); ReadModuleList(); - GetTarget().SetArchitecture(arch); llvm::Optional pid = m_minidump_parser.GetPid(); if (!pid) { @@ -229,6 +232,11 @@ void ProcessMinidump::RefreshStateAfterStop() { if (arch.GetTriple().getOS() == llvm::Triple::Linux) { stop_info = StopInfo::CreateStopReasonWithSignal( *stop_thread, m_active_exception->exception_record.exception_code); + } else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) { + stop_info = StopInfoMachException::CreateStopReasonWithMachException( + *stop_thread, m_active_exception->exception_record.exception_code, 2, + m_active_exception->exception_record.exception_flags, + m_active_exception->exception_record.exception_address, 0); } else { std::string desc; llvm::raw_string_ostream desc_stream(desc); diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp new file mode 100644 index 000000000000..2d73da4e5b51 --- /dev/null +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp @@ -0,0 +1,532 @@ +//===-- RegisterContextMinidump_ARM.cpp -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Project includes +#include "RegisterContextMinidump_ARM.h" + +// Other libraries and framework includes +#include "Utility/ARM_DWARF_Registers.h" +#include "lldb/Core/RegisterValue.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBAssert.h" +#include "lldb/lldb-enumerations.h" + +// C includes +#include + +// C++ includes + +using namespace lldb; +using namespace lldb_private; +using namespace minidump; + +#define INV LLDB_INVALID_REGNUM +#define OFFSET(r) (offsetof(RegisterContextMinidump_ARM::Context, r)) + +#define DEF_R(i) \ + { \ + "r" #i, nullptr, 4, OFFSET(r[i]), eEncodingUint, eFormatHex, \ + {INV, dwarf_r##i, INV, INV, reg_r##i}, nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_R_ARG(i, n) \ + { \ + "r" #i, "arg" #n, 4, OFFSET(r[i]), eEncodingUint, eFormatHex, \ + {INV, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_D(i) \ + { \ + "d" #i, nullptr, 8, OFFSET(d[i]), eEncodingVector, eFormatVectorOfUInt8, \ + {INV, dwarf_d##i, INV, INV, reg_d##i}, nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_S(i) \ + { \ + "s" #i, nullptr, 4, OFFSET(s[i]), eEncodingIEEE754, eFormatFloat, \ + {INV, dwarf_s##i, INV, INV, reg_s##i}, nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_Q(i) \ + { \ + "q" #i, nullptr, 16, OFFSET(q[i]), eEncodingVector, eFormatVectorOfUInt8, \ + {INV, dwarf_q##i, INV, INV, reg_q##i}, nullptr, nullptr, nullptr, 0 \ + } + +// Zero based LLDB register numbers for this register context +enum { + // General Purpose Registers + reg_r0, + reg_r1, + reg_r2, + reg_r3, + reg_r4, + reg_r5, + reg_r6, + reg_r7, + reg_r8, + reg_r9, + reg_r10, + reg_r11, + reg_r12, + reg_sp, + reg_lr, + reg_pc, + reg_cpsr, + // Floating Point Registers + reg_fpscr, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_q0, + reg_q1, + reg_q2, + reg_q3, + reg_q4, + reg_q5, + reg_q6, + reg_q7, + reg_q8, + reg_q9, + reg_q10, + reg_q11, + reg_q12, + reg_q13, + reg_q14, + reg_q15, + k_num_regs +}; + +static RegisterInfo g_reg_info_apple_fp = { + "fp", + "r7", + 4, + OFFSET(r[7]), + eEncodingUint, + eFormatHex, + {INV, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7}, + nullptr, + nullptr, + nullptr, + 0}; + +static RegisterInfo g_reg_info_fp = { + "fp", + "r11", + 4, + OFFSET(r[11]), + eEncodingUint, + eFormatHex, + {INV, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11}, + nullptr, + nullptr, + nullptr, + 0}; + +// Register info definitions for this register context +static RegisterInfo g_reg_infos[] = { + DEF_R_ARG(0, 1), + DEF_R_ARG(1, 2), + DEF_R_ARG(2, 3), + DEF_R_ARG(3, 4), + DEF_R(4), + DEF_R(5), + DEF_R(6), + DEF_R(7), + DEF_R(8), + DEF_R(9), + DEF_R(10), + DEF_R(11), + DEF_R(12), + {"sp", + "r13", + 4, + OFFSET(r[13]), + eEncodingUint, + eFormatHex, + {INV, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, + nullptr, + nullptr, + nullptr, + 0}, + {"lr", + "r14", + 4, + OFFSET(r[14]), + eEncodingUint, + eFormatHex, + {INV, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, + nullptr, + nullptr, + nullptr, + 0}, + {"pc", + "r15", + 4, + OFFSET(r[15]), + eEncodingUint, + eFormatHex, + {INV, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, + nullptr, + nullptr, + nullptr, + 0}, + {"cpsr", + "psr", + 4, + OFFSET(cpsr), + eEncodingUint, + eFormatHex, + {INV, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, + nullptr, + nullptr, + nullptr, + 0}, + {"fpscr", + nullptr, + 8, + OFFSET(fpscr), + eEncodingUint, + eFormatHex, + {INV, INV, INV, INV, reg_fpscr}, + nullptr, + nullptr, + nullptr, + 0}, + DEF_D(0), + DEF_D(1), + DEF_D(2), + DEF_D(3), + DEF_D(4), + DEF_D(5), + DEF_D(6), + DEF_D(7), + DEF_D(8), + DEF_D(9), + DEF_D(10), + DEF_D(11), + DEF_D(12), + DEF_D(13), + DEF_D(14), + DEF_D(15), + DEF_D(16), + DEF_D(17), + DEF_D(18), + DEF_D(19), + DEF_D(20), + DEF_D(21), + DEF_D(22), + DEF_D(23), + DEF_D(24), + DEF_D(25), + DEF_D(26), + DEF_D(27), + DEF_D(28), + DEF_D(29), + DEF_D(30), + DEF_D(31), + DEF_S(0), + DEF_S(1), + DEF_S(2), + DEF_S(3), + DEF_S(4), + DEF_S(5), + DEF_S(6), + DEF_S(7), + DEF_S(8), + DEF_S(9), + DEF_S(10), + DEF_S(11), + DEF_S(12), + DEF_S(13), + DEF_S(14), + DEF_S(15), + DEF_S(16), + DEF_S(17), + DEF_S(18), + DEF_S(19), + DEF_S(20), + DEF_S(21), + DEF_S(22), + DEF_S(23), + DEF_S(24), + DEF_S(25), + DEF_S(26), + DEF_S(27), + DEF_S(28), + DEF_S(29), + DEF_S(30), + DEF_S(31), + DEF_Q(0), + DEF_Q(1), + DEF_Q(2), + DEF_Q(3), + DEF_Q(4), + DEF_Q(5), + DEF_Q(6), + DEF_Q(7), + DEF_Q(8), + DEF_Q(9), + DEF_Q(10), + DEF_Q(11), + DEF_Q(12), + DEF_Q(13), + DEF_Q(14), + DEF_Q(15)}; + +constexpr size_t k_num_reg_infos = llvm::array_lengthof(g_reg_infos); + +// ARM general purpose registers. +const uint32_t g_gpr_regnums[] = { + reg_r0, + reg_r1, + reg_r2, + reg_r3, + reg_r4, + reg_r5, + reg_r6, + reg_r7, + reg_r8, + reg_r9, + reg_r10, + reg_r11, + reg_r12, + reg_sp, + reg_lr, + reg_pc, + reg_cpsr, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +const uint32_t g_fpu_regnums[] = { + reg_fpscr, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_q0, + reg_q1, + reg_q2, + reg_q3, + reg_q4, + reg_q5, + reg_q6, + reg_q7, + reg_q8, + reg_q9, + reg_q10, + reg_q11, + reg_q12, + reg_q13, + reg_q14, + reg_q15, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +// Skip the last LLDB_INVALID_REGNUM in each count below by subtracting 1 +constexpr size_t k_num_gpr_regs = llvm::array_lengthof(g_gpr_regnums) - 1; +constexpr size_t k_num_fpu_regs = llvm::array_lengthof(g_fpu_regnums) - 1; + +static RegisterSet g_reg_sets[] = { + {"General Purpose Registers", "gpr", k_num_gpr_regs, g_gpr_regnums}, + {"Floating Point Registers", "fpu", k_num_fpu_regs, g_fpu_regnums}, +}; + +constexpr size_t k_num_reg_sets = llvm::array_lengthof(g_reg_sets); + +RegisterContextMinidump_ARM::RegisterContextMinidump_ARM( + Thread &thread, const DataExtractor &data, bool apple) + : RegisterContext(thread, 0), m_apple(apple) { + lldb::offset_t offset = 0; + m_regs.context_flags = data.GetU32(&offset); + for (unsigned i = 0; i < llvm::array_lengthof(m_regs.r); ++i) + m_regs.r[i] = data.GetU32(&offset); + m_regs.cpsr = data.GetU32(&offset); + m_regs.fpscr = data.GetU64(&offset); + for (unsigned i = 0; i < llvm::array_lengthof(m_regs.d); ++i) + m_regs.d[i] = data.GetU64(&offset); + lldbassert(k_num_regs == k_num_reg_infos); +} + +size_t RegisterContextMinidump_ARM::GetRegisterCount() { return k_num_regs; } + +const RegisterInfo * +RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) { + if (reg < k_num_reg_infos) { + if (m_apple) { + if (reg == reg_r7) + return &g_reg_info_apple_fp; + } else { + if (reg == reg_r11) + return &g_reg_info_fp; + } + return &g_reg_infos[reg]; + } + return nullptr; +} + +size_t RegisterContextMinidump_ARM::GetRegisterSetCount() { + return k_num_reg_sets; +} + +const RegisterSet *RegisterContextMinidump_ARM::GetRegisterSet(size_t set) { + if (set < k_num_reg_sets) + return &g_reg_sets[set]; + return nullptr; +} + +const char *RegisterContextMinidump_ARM::GetRegisterName(unsigned reg) { + if (reg < k_num_reg_infos) + return g_reg_infos[reg].name; + return nullptr; +} + +bool RegisterContextMinidump_ARM::ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) { + Status error; + reg_value.SetFromMemoryData( + reg_info, (const uint8_t *)&m_regs + reg_info->byte_offset, + reg_info->byte_size, lldb::eByteOrderLittle, error); + return error.Success(); +} + +bool RegisterContextMinidump_ARM::WriteRegister(const RegisterInfo *, + const RegisterValue &) { + return false; +} + +uint32_t RegisterContextMinidump_ARM::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + for (size_t i = 0; i < k_num_regs; ++i) { + if (g_reg_infos[i].kinds[kind] == num) + return i; + } + return LLDB_INVALID_REGNUM; +} diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h new file mode 100644 index 000000000000..c410df99b1c1 --- /dev/null +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h @@ -0,0 +1,95 @@ +//===-- RegisterContextMinidump_ARM.h ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextMinidump_ARM_h_ +#define liblldb_RegisterContextMinidump_ARM_h_ + +// Project includes +#include "MinidumpTypes.h" + +// Other libraries and framework includes +#include "Plugins/Process/Utility/RegisterInfoInterface.h" + +#include "lldb/Target/RegisterContext.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitmaskEnum.h" + +// C includes +// C++ includes + +namespace lldb_private { + +namespace minidump { + +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + +class RegisterContextMinidump_ARM : public lldb_private::RegisterContext { +public: + RegisterContextMinidump_ARM(lldb_private::Thread &thread, + const DataExtractor &data, bool apple); + + ~RegisterContextMinidump_ARM() override = default; + + void InvalidateAllRegisters() override { + // Do nothing... registers are always valid... + } + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + + bool ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) override; + + bool WriteRegister(const RegisterInfo *reg_info, + const RegisterValue ®_value) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + + // Reference: see breakpad/crashpad source + struct QRegValue { + uint64_t lo; + uint64_t hi; + }; + + struct Context { + uint32_t context_flags; + uint32_t r[16]; + uint32_t cpsr; + uint64_t fpscr; + union { + uint64_t d[32]; + uint32_t s[32]; + QRegValue q[16]; + }; + uint32_t extra[8]; + }; + +protected: + enum class Flags : uint32_t { + ARM_Flag = 0x40000000, + Integer = ARM_Flag | 0x00000002, + FloatingPoint = ARM_Flag | 0x00000004, + LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ FloatingPoint) + }; + Context m_regs; + const bool m_apple; // True if this is an Apple ARM where FP is R7 +}; + +} // end namespace minidump +} // end namespace lldb_private +#endif // liblldb_RegisterContextMinidump_ARM_h_ diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp new file mode 100644 index 000000000000..5ba58d1ca81e --- /dev/null +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp @@ -0,0 +1,836 @@ +//===-- RegisterContextMinidump_ARM64.cpp -----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Project includes +#include "RegisterContextMinidump_ARM64.h" + +// Other libraries and framework includes +#include "Utility/ARM64_DWARF_Registers.h" +#include "lldb/Core/RegisterValue.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/lldb-enumerations.h" + +// C includes +#include + +// C++ includes + +using namespace lldb; +using namespace lldb_private; +using namespace minidump; + +#define INV LLDB_INVALID_REGNUM +#define OFFSET(r) (offsetof(RegisterContextMinidump_ARM64::Context, r)) + +#define DEF_X(i) \ + { \ + "x" #i, nullptr, 8, OFFSET(x[i]), eEncodingUint, eFormatHex, \ + {INV, arm64_dwarf::x##i, INV, INV, reg_x##i}, nullptr, nullptr, \ + nullptr, 0 \ + } + +#define DEF_W(i) \ + { \ + "w" #i, nullptr, 4, OFFSET(x[i]), eEncodingUint, eFormatHex, \ + {INV, INV, INV, INV, reg_w##i}, nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_X_ARG(i, n) \ + { \ + "x" #i, "arg" #n, 8, OFFSET(x[i]), eEncodingUint, eFormatHex, \ + {INV, arm64_dwarf::x##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_x##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_V(i) \ + { \ + "v" #i, nullptr, 16, OFFSET(v[i * 16]), eEncodingVector, \ + eFormatVectorOfUInt8, {INV, arm64_dwarf::v##i, INV, INV, reg_v##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_D(i) \ + { \ + "d" #i, nullptr, 8, OFFSET(v[i * 16]), eEncodingVector, \ + eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_d##i}, nullptr, \ + nullptr, nullptr, 0 \ + } + +#define DEF_S(i) \ + { \ + "s" #i, nullptr, 4, OFFSET(v[i * 16]), eEncodingVector, \ + eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_s##i}, nullptr, \ + nullptr, nullptr, 0 \ + } + +#define DEF_H(i) \ + { \ + "h" #i, nullptr, 2, OFFSET(v[i * 16]), eEncodingVector, \ + eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_h##i}, nullptr, \ + nullptr, nullptr, 0 \ + } + +// Zero based LLDB register numbers for this register context +enum { + // General Purpose Registers + reg_x0 = 0, + reg_x1, + reg_x2, + reg_x3, + reg_x4, + reg_x5, + reg_x6, + reg_x7, + reg_x8, + reg_x9, + reg_x10, + reg_x11, + reg_x12, + reg_x13, + reg_x14, + reg_x15, + reg_x16, + reg_x17, + reg_x18, + reg_x19, + reg_x20, + reg_x21, + reg_x22, + reg_x23, + reg_x24, + reg_x25, + reg_x26, + reg_x27, + reg_x28, + reg_fp, + reg_lr, + reg_sp, + reg_pc, + reg_w0, + reg_w1, + reg_w2, + reg_w3, + reg_w4, + reg_w5, + reg_w6, + reg_w7, + reg_w8, + reg_w9, + reg_w10, + reg_w11, + reg_w12, + reg_w13, + reg_w14, + reg_w15, + reg_w16, + reg_w17, + reg_w18, + reg_w19, + reg_w20, + reg_w21, + reg_w22, + reg_w23, + reg_w24, + reg_w25, + reg_w26, + reg_w27, + reg_w28, + reg_w29, + reg_w30, + reg_w31, + reg_cpsr, + // Floating Point Registers + reg_fpsr, + reg_fpcr, + reg_v0, + reg_v1, + reg_v2, + reg_v3, + reg_v4, + reg_v5, + reg_v6, + reg_v7, + reg_v8, + reg_v9, + reg_v10, + reg_v11, + reg_v12, + reg_v13, + reg_v14, + reg_v15, + reg_v16, + reg_v17, + reg_v18, + reg_v19, + reg_v20, + reg_v21, + reg_v22, + reg_v23, + reg_v24, + reg_v25, + reg_v26, + reg_v27, + reg_v28, + reg_v29, + reg_v30, + reg_v31, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_h0, + reg_h1, + reg_h2, + reg_h3, + reg_h4, + reg_h5, + reg_h6, + reg_h7, + reg_h8, + reg_h9, + reg_h10, + reg_h11, + reg_h12, + reg_h13, + reg_h14, + reg_h15, + reg_h16, + reg_h17, + reg_h18, + reg_h19, + reg_h20, + reg_h21, + reg_h22, + reg_h23, + reg_h24, + reg_h25, + reg_h26, + reg_h27, + reg_h28, + reg_h29, + reg_h30, + reg_h31, + k_num_regs +}; + +// Register info definitions for this register context +static RegisterInfo g_reg_infos[] = { + DEF_X_ARG(0, 1), + DEF_X_ARG(1, 2), + DEF_X_ARG(2, 3), + DEF_X_ARG(3, 4), + DEF_X_ARG(4, 5), + DEF_X_ARG(5, 6), + DEF_X_ARG(6, 7), + DEF_X_ARG(7, 8), + DEF_X(8), + DEF_X(9), + DEF_X(10), + DEF_X(11), + DEF_X(12), + DEF_X(13), + DEF_X(14), + DEF_X(15), + DEF_X(16), + DEF_X(17), + DEF_X(18), + DEF_X(19), + DEF_X(20), + DEF_X(21), + DEF_X(22), + DEF_X(23), + DEF_X(24), + DEF_X(25), + DEF_X(26), + DEF_X(27), + DEF_X(28), + {"fp", + "x29", + 8, + OFFSET(x[29]), + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, INV, reg_fp}, + nullptr, + nullptr, + nullptr, + 0}, + {"lr", + "x30", + 8, + OFFSET(x[30]), + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, + nullptr, + nullptr, + nullptr, + 0}, + {"sp", + "x31", + 8, + OFFSET(x[31]), + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, + nullptr, + nullptr, + nullptr, + 0}, + {"pc", + nullptr, + 8, + OFFSET(pc), + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, + nullptr, + nullptr, + nullptr, + 0}, + // w0 - w31 + DEF_W(0), + DEF_W(1), + DEF_W(2), + DEF_W(3), + DEF_W(4), + DEF_W(5), + DEF_W(6), + DEF_W(7), + DEF_W(8), + DEF_W(9), + DEF_W(10), + DEF_W(11), + DEF_W(12), + DEF_W(13), + DEF_W(14), + DEF_W(15), + DEF_W(16), + DEF_W(17), + DEF_W(18), + DEF_W(19), + DEF_W(20), + DEF_W(21), + DEF_W(22), + DEF_W(23), + DEF_W(24), + DEF_W(25), + DEF_W(26), + DEF_W(27), + DEF_W(28), + DEF_W(29), + DEF_W(30), + DEF_W(31), + {"cpsr", + "psr", + 4, + OFFSET(cpsr), + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, + nullptr, + nullptr, + nullptr, + 0}, + {"fpsr", + nullptr, + 4, + OFFSET(fpsr), + eEncodingUint, + eFormatHex, + {INV, INV, INV, INV, reg_fpsr}, + nullptr, + nullptr, + nullptr, + 0}, + {"fpcr", + nullptr, + 4, + OFFSET(fpcr), + eEncodingUint, + eFormatHex, + {INV, INV, INV, INV, reg_fpcr}, + nullptr, + nullptr, + nullptr, + 0}, + // v0 - v31 + DEF_V(0), + DEF_V(1), + DEF_V(2), + DEF_V(3), + DEF_V(4), + DEF_V(5), + DEF_V(6), + DEF_V(7), + DEF_V(8), + DEF_V(9), + DEF_V(10), + DEF_V(11), + DEF_V(12), + DEF_V(13), + DEF_V(14), + DEF_V(15), + DEF_V(16), + DEF_V(17), + DEF_V(18), + DEF_V(19), + DEF_V(20), + DEF_V(21), + DEF_V(22), + DEF_V(23), + DEF_V(24), + DEF_V(25), + DEF_V(26), + DEF_V(27), + DEF_V(28), + DEF_V(29), + DEF_V(30), + DEF_V(31), + // d0 - d31 + DEF_D(0), + DEF_D(1), + DEF_D(2), + DEF_D(3), + DEF_D(4), + DEF_D(5), + DEF_D(6), + DEF_D(7), + DEF_D(8), + DEF_D(9), + DEF_D(10), + DEF_D(11), + DEF_D(12), + DEF_D(13), + DEF_D(14), + DEF_D(15), + DEF_D(16), + DEF_D(17), + DEF_D(18), + DEF_D(19), + DEF_D(20), + DEF_D(21), + DEF_D(22), + DEF_D(23), + DEF_D(24), + DEF_D(25), + DEF_D(26), + DEF_D(27), + DEF_D(28), + DEF_D(29), + DEF_D(30), + DEF_D(31), + // s0 - s31 + DEF_S(0), + DEF_S(1), + DEF_S(2), + DEF_S(3), + DEF_S(4), + DEF_S(5), + DEF_S(6), + DEF_S(7), + DEF_S(8), + DEF_S(9), + DEF_S(10), + DEF_S(11), + DEF_S(12), + DEF_S(13), + DEF_S(14), + DEF_S(15), + DEF_S(16), + DEF_S(17), + DEF_S(18), + DEF_S(19), + DEF_S(20), + DEF_S(21), + DEF_S(22), + DEF_S(23), + DEF_S(24), + DEF_S(25), + DEF_S(26), + DEF_S(27), + DEF_S(28), + DEF_S(29), + DEF_S(30), + DEF_S(31), + // h0 - h31 + DEF_H(0), + DEF_H(1), + DEF_H(2), + DEF_H(3), + DEF_H(4), + DEF_H(5), + DEF_H(6), + DEF_H(7), + DEF_H(8), + DEF_H(9), + DEF_H(10), + DEF_H(11), + DEF_H(12), + DEF_H(13), + DEF_H(14), + DEF_H(15), + DEF_H(16), + DEF_H(17), + DEF_H(18), + DEF_H(19), + DEF_H(20), + DEF_H(21), + DEF_H(22), + DEF_H(23), + DEF_H(24), + DEF_H(25), + DEF_H(26), + DEF_H(27), + DEF_H(28), + DEF_H(29), + DEF_H(30), + DEF_H(31), +}; + +constexpr size_t k_num_reg_infos = llvm::array_lengthof(g_reg_infos); + +// ARM64 general purpose registers. +const uint32_t g_gpr_regnums[] = { + reg_x0, + reg_x1, + reg_x2, + reg_x3, + reg_x4, + reg_x5, + reg_x6, + reg_x7, + reg_x8, + reg_x9, + reg_x10, + reg_x11, + reg_x12, + reg_x13, + reg_x14, + reg_x15, + reg_x16, + reg_x17, + reg_x18, + reg_x19, + reg_x20, + reg_x21, + reg_x22, + reg_x23, + reg_x24, + reg_x25, + reg_x26, + reg_x27, + reg_x28, + reg_fp, + reg_lr, + reg_sp, + reg_w0, + reg_w1, + reg_w2, + reg_w3, + reg_w4, + reg_w5, + reg_w6, + reg_w7, + reg_w8, + reg_w9, + reg_w10, + reg_w11, + reg_w12, + reg_w13, + reg_w14, + reg_w15, + reg_w16, + reg_w17, + reg_w18, + reg_w19, + reg_w20, + reg_w21, + reg_w22, + reg_w23, + reg_w24, + reg_w25, + reg_w26, + reg_w27, + reg_w28, + reg_w29, + reg_w30, + reg_w31, + reg_pc, + reg_cpsr, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +const uint32_t g_fpu_regnums[] = { + reg_v0, + reg_v1, + reg_v2, + reg_v3, + reg_v4, + reg_v5, + reg_v6, + reg_v7, + reg_v8, + reg_v9, + reg_v10, + reg_v11, + reg_v12, + reg_v13, + reg_v14, + reg_v15, + reg_v16, + reg_v17, + reg_v18, + reg_v19, + reg_v20, + reg_v21, + reg_v22, + reg_v23, + reg_v24, + reg_v25, + reg_v26, + reg_v27, + reg_v28, + reg_v29, + reg_v30, + reg_v31, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_h0, + reg_h1, + reg_h2, + reg_h3, + reg_h4, + reg_h5, + reg_h6, + reg_h7, + reg_h8, + reg_h9, + reg_h10, + reg_h11, + reg_h12, + reg_h13, + reg_h14, + reg_h15, + reg_h16, + reg_h17, + reg_h18, + reg_h19, + reg_h20, + reg_h21, + reg_h22, + reg_h23, + reg_h24, + reg_h25, + reg_h26, + reg_h27, + reg_h28, + reg_h29, + reg_h30, + reg_h31, + reg_fpsr, + reg_fpcr, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +// Skip the last LLDB_INVALID_REGNUM in each count below by subtracting 1 +constexpr size_t k_num_gpr_regs = llvm::array_lengthof(g_gpr_regnums) - 1; +constexpr size_t k_num_fpu_regs = llvm::array_lengthof(g_fpu_regnums) - 1; + +static RegisterSet g_reg_sets[] = { + {"General Purpose Registers", "gpr", k_num_gpr_regs, g_gpr_regnums}, + {"Floating Point Registers", "fpu", k_num_fpu_regs, g_fpu_regnums}, +}; + +constexpr size_t k_num_reg_sets = llvm::array_lengthof(g_reg_sets); + +RegisterContextMinidump_ARM64::RegisterContextMinidump_ARM64( + Thread &thread, const DataExtractor &data) + : RegisterContext(thread, 0) { + lldb::offset_t offset = 0; + m_regs.context_flags = data.GetU64(&offset); + for (unsigned i = 0; i < 32; ++i) + m_regs.x[i] = data.GetU64(&offset); + m_regs.pc = data.GetU64(&offset); + m_regs.cpsr = data.GetU32(&offset); + m_regs.fpsr = data.GetU32(&offset); + m_regs.fpcr = data.GetU32(&offset); + auto regs_data = data.GetData(&offset, sizeof(m_regs.v)); + if (regs_data) + memcpy(m_regs.v, regs_data, sizeof(m_regs.v)); + assert(k_num_regs == k_num_reg_infos); +} +size_t RegisterContextMinidump_ARM64::GetRegisterCount() { return k_num_regs; } + +const RegisterInfo * +RegisterContextMinidump_ARM64::GetRegisterInfoAtIndex(size_t reg) { + if (reg < k_num_reg_infos) + return &g_reg_infos[reg]; + return nullptr; +} + +size_t RegisterContextMinidump_ARM64::GetRegisterSetCount() { + return k_num_reg_sets; +} + +const RegisterSet *RegisterContextMinidump_ARM64::GetRegisterSet(size_t set) { + if (set < k_num_reg_sets) + return &g_reg_sets[set]; + return nullptr; +} + +const char *RegisterContextMinidump_ARM64::GetRegisterName(unsigned reg) { + if (reg < k_num_reg_infos) + return g_reg_infos[reg].name; + return nullptr; +} + +bool RegisterContextMinidump_ARM64::ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) { + Status error; + reg_value.SetFromMemoryData( + reg_info, (const uint8_t *)&m_regs + reg_info->byte_offset, + reg_info->byte_size, lldb::eByteOrderLittle, error); + return error.Success(); +} + +bool RegisterContextMinidump_ARM64::WriteRegister(const RegisterInfo *, + const RegisterValue &) { + return false; +} + +uint32_t RegisterContextMinidump_ARM64::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + for (size_t i = 0; i < k_num_regs; ++i) { + if (g_reg_infos[i].kinds[kind] == num) + return i; + } + return LLDB_INVALID_REGNUM; +} diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h new file mode 100644 index 000000000000..2a3f254c8510 --- /dev/null +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h @@ -0,0 +1,85 @@ +//===-- RegisterContextMinidump_ARM64.h -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextMinidump_ARM64_h_ +#define liblldb_RegisterContextMinidump_ARM64_h_ + +// Project includes +#include "MinidumpTypes.h" + +// Other libraries and framework includes +#include "Plugins/Process/Utility/RegisterInfoInterface.h" +#include "lldb/Target/RegisterContext.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitmaskEnum.h" + +// C includes +// C++ includes + +namespace lldb_private { + +namespace minidump { + +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + +class RegisterContextMinidump_ARM64 : public lldb_private::RegisterContext { +public: + RegisterContextMinidump_ARM64(lldb_private::Thread &thread, + const DataExtractor &data); + + ~RegisterContextMinidump_ARM64() override = default; + + void InvalidateAllRegisters() override { + // Do nothing... registers are always valid... + } + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + + bool ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) override; + + bool WriteRegister(const RegisterInfo *reg_info, + const RegisterValue ®_value) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + + // Reference: see breakpad/crashpad source + struct Context { + uint64_t context_flags; + uint64_t x[32]; + uint64_t pc; + uint32_t cpsr; + uint32_t fpsr; + uint32_t fpcr; + uint8_t v[32 * 16]; // 32 128-bit floating point registers + }; + +protected: + enum class Flags : uint32_t { + ARM64_Flag = 0x80000000, + Integer = ARM64_Flag | 0x00000002, + FloatingPoint = ARM64_Flag | 0x00000004, + LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ FloatingPoint) + }; + Context m_regs; +}; + +} // end namespace minidump +} // end namespace lldb_private +#endif // liblldb_RegisterContextMinidump_ARM64_h_ diff --git a/source/Plugins/Process/minidump/ThreadMinidump.cpp b/source/Plugins/Process/minidump/ThreadMinidump.cpp index 3fafb6134e7f..97493ebfd558 100644 --- a/source/Plugins/Process/minidump/ThreadMinidump.cpp +++ b/source/Plugins/Process/minidump/ThreadMinidump.cpp @@ -11,6 +11,8 @@ #include "ThreadMinidump.h" #include "ProcessMinidump.h" +#include "RegisterContextMinidump_ARM.h" +#include "RegisterContextMinidump_ARM64.h" #include "RegisterContextMinidump_x86_32.h" #include "RegisterContextMinidump_x86_64.h" @@ -54,7 +56,6 @@ RegisterContextSP ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) { RegisterContextSP reg_ctx_sp; uint32_t concrete_frame_idx = 0; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (frame) concrete_frame_idx = frame->GetConcreteFrameIndex(); @@ -88,15 +89,22 @@ ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) { *this, reg_interface, gpregset, {})); break; } - default: + case llvm::Triple::aarch64: { + DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(), + lldb::eByteOrderLittle, 8); + m_thread_reg_ctx_sp.reset(new RegisterContextMinidump_ARM64(*this, data)); break; } - - if (!reg_interface) { - if (log) - log->Printf("elf-core::%s:: Architecture(%d) not supported", - __FUNCTION__, arch.GetMachine()); - assert(false && "Architecture not supported"); + case llvm::Triple::arm: { + DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(), + lldb::eByteOrderLittle, 8); + const bool apple = arch.GetTriple().getVendor() == llvm::Triple::Apple; + m_thread_reg_ctx_sp.reset( + new RegisterContextMinidump_ARM(*this, data, apple)); + break; + } + default: + break; } reg_ctx_sp = m_thread_reg_ctx_sp; diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp index 3f70741713fb..a98495d17449 100644 --- a/source/Target/Target.cpp +++ b/source/Target/Target.cpp @@ -1426,13 +1426,33 @@ void Target::SetExecutableModule(ModuleSP &executable_sp, } } -bool Target::SetArchitecture(const ArchSpec &arch_spec) { +bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); bool missing_local_arch = !m_arch.GetSpec().IsValid(); bool replace_local_arch = true; bool compatible_local_arch = false; ArchSpec other(arch_spec); + // Changing the architecture might mean that the currently selected platform + // isn't compatible. Set the platform correctly if we are asked to do so, + // otherwise assume the user will set the platform manually. + if (set_platform) { + if (other.IsValid()) { + auto platform_sp = GetPlatform(); + if (!platform_sp || + !platform_sp->IsCompatibleArchitecture(other, false, nullptr)) { + ArchSpec platform_arch; + auto arch_platform_sp = + Platform::GetPlatformForArchitecture(other, &platform_arch); + if (arch_platform_sp) { + SetPlatform(arch_platform_sp); + if (platform_arch.IsValid()) + other = platform_arch; + } + } + } + } + if (!missing_local_arch) { if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) { other.MergeFrom(m_arch.GetSpec()); From b6738d5e2b326a03a7b464cb6e7edbb7711dc9e4 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Mon, 6 Aug 2018 17:07:50 +0000 Subject: [PATCH 0060/1112] Fix offsetof usage that got lost when passing patches between linux and mac. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339033 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../minidump/RegisterContextMinidump_ARM.cpp | 16 +++++++++------- .../minidump/RegisterContextMinidump_ARM64.cpp | 14 +++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp index 2d73da4e5b51..6e08c8e9f6e5 100644 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp @@ -31,33 +31,35 @@ using namespace minidump; #define DEF_R(i) \ { \ - "r" #i, nullptr, 4, OFFSET(r[i]), eEncodingUint, eFormatHex, \ + "r" #i, nullptr, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \ {INV, dwarf_r##i, INV, INV, reg_r##i}, nullptr, nullptr, nullptr, 0 \ } #define DEF_R_ARG(i, n) \ { \ - "r" #i, "arg" #n, 4, OFFSET(r[i]), eEncodingUint, eFormatHex, \ + "r" #i, "arg" #n, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \ {INV, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \ nullptr, nullptr, nullptr, 0 \ } #define DEF_D(i) \ { \ - "d" #i, nullptr, 8, OFFSET(d[i]), eEncodingVector, eFormatVectorOfUInt8, \ - {INV, dwarf_d##i, INV, INV, reg_d##i}, nullptr, nullptr, nullptr, 0 \ + "d" #i, nullptr, 8, OFFSET(d) + i * 8, eEncodingVector, \ + eFormatVectorOfUInt8, {INV, dwarf_d##i, INV, INV, reg_d##i}, \ + nullptr, nullptr, nullptr, 0 \ } #define DEF_S(i) \ { \ - "s" #i, nullptr, 4, OFFSET(s[i]), eEncodingIEEE754, eFormatFloat, \ + "s" #i, nullptr, 4, OFFSET(s) + i * 4, eEncodingIEEE754, eFormatFloat, \ {INV, dwarf_s##i, INV, INV, reg_s##i}, nullptr, nullptr, nullptr, 0 \ } #define DEF_Q(i) \ { \ - "q" #i, nullptr, 16, OFFSET(q[i]), eEncodingVector, eFormatVectorOfUInt8, \ - {INV, dwarf_q##i, INV, INV, reg_q##i}, nullptr, nullptr, nullptr, 0 \ + "q" #i, nullptr, 16, OFFSET(q) + i * 16, eEncodingVector, \ + eFormatVectorOfUInt8, {INV, dwarf_q##i, INV, INV, reg_q##i}, \ + nullptr, nullptr, nullptr, 0 \ } // Zero based LLDB register numbers for this register context diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp index 5ba58d1ca81e..29800747a0b5 100644 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp @@ -30,48 +30,48 @@ using namespace minidump; #define DEF_X(i) \ { \ - "x" #i, nullptr, 8, OFFSET(x[i]), eEncodingUint, eFormatHex, \ + "x" #i, nullptr, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \ {INV, arm64_dwarf::x##i, INV, INV, reg_x##i}, nullptr, nullptr, \ nullptr, 0 \ } #define DEF_W(i) \ { \ - "w" #i, nullptr, 4, OFFSET(x[i]), eEncodingUint, eFormatHex, \ + "w" #i, nullptr, 4, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \ {INV, INV, INV, INV, reg_w##i}, nullptr, nullptr, nullptr, 0 \ } #define DEF_X_ARG(i, n) \ { \ - "x" #i, "arg" #n, 8, OFFSET(x[i]), eEncodingUint, eFormatHex, \ + "x" #i, "arg" #n, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \ {INV, arm64_dwarf::x##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_x##i}, \ nullptr, nullptr, nullptr, 0 \ } #define DEF_V(i) \ { \ - "v" #i, nullptr, 16, OFFSET(v[i * 16]), eEncodingVector, \ + "v" #i, nullptr, 16, OFFSET(v) + i * 16, eEncodingVector, \ eFormatVectorOfUInt8, {INV, arm64_dwarf::v##i, INV, INV, reg_v##i}, \ nullptr, nullptr, nullptr, 0 \ } #define DEF_D(i) \ { \ - "d" #i, nullptr, 8, OFFSET(v[i * 16]), eEncodingVector, \ + "d" #i, nullptr, 8, OFFSET(v) + i * 16, eEncodingVector, \ eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_d##i}, nullptr, \ nullptr, nullptr, 0 \ } #define DEF_S(i) \ { \ - "s" #i, nullptr, 4, OFFSET(v[i * 16]), eEncodingVector, \ + "s" #i, nullptr, 4, OFFSET(v) + i * 16, eEncodingVector, \ eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_s##i}, nullptr, \ nullptr, nullptr, 0 \ } #define DEF_H(i) \ { \ - "h" #i, nullptr, 2, OFFSET(v[i * 16]), eEncodingVector, \ + "h" #i, nullptr, 2, OFFSET(v) + i * 16, eEncodingVector, \ eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_h##i}, nullptr, \ nullptr, nullptr, 0 \ } From 67ed3cc7467f6615edae73cf712a4484daa1a17b Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Mon, 6 Aug 2018 17:26:53 +0000 Subject: [PATCH 0061/1112] Fix more offsetof issues. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339034 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Process/minidump/RegisterContextMinidump_ARM.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp index 6e08c8e9f6e5..5e7bc7a36ef9 100644 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp @@ -171,7 +171,7 @@ static RegisterInfo g_reg_info_apple_fp = { "fp", "r7", 4, - OFFSET(r[7]), + OFFSET(r) + 7 * 4, eEncodingUint, eFormatHex, {INV, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7}, @@ -184,7 +184,7 @@ static RegisterInfo g_reg_info_fp = { "fp", "r11", 4, - OFFSET(r[11]), + OFFSET(r) + 11 * 4, eEncodingUint, eFormatHex, {INV, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11}, @@ -211,7 +211,7 @@ static RegisterInfo g_reg_infos[] = { {"sp", "r13", 4, - OFFSET(r[13]), + OFFSET(r) + 13 * 4, eEncodingUint, eFormatHex, {INV, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, @@ -222,7 +222,7 @@ static RegisterInfo g_reg_infos[] = { {"lr", "r14", 4, - OFFSET(r[14]), + OFFSET(r) + 14 * 4, eEncodingUint, eFormatHex, {INV, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, @@ -233,7 +233,7 @@ static RegisterInfo g_reg_infos[] = { {"pc", "r15", 4, - OFFSET(r[15]), + OFFSET(r) + 15 * 4, eEncodingUint, eFormatHex, {INV, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, From dfaba774eb65efcfc9c1d32d2b64447b29104fe3 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Mon, 6 Aug 2018 20:13:52 +0000 Subject: [PATCH 0062/1112] [IRMemoryMap] Avoid redundant zero-init in the Allocation constructor (NFC) In the lldb-bench/arithmetic benchmark, 1.7% of the total running time is spent zero-initializing a std::vector that has already been zeroed. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339051 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Utility/DataBufferHeap.h | 3 ++- source/Expression/IRMemoryMap.cpp | 6 +----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/include/lldb/Utility/DataBufferHeap.h b/include/lldb/Utility/DataBufferHeap.h index d64e5b7563a9..59c3f64a422e 100644 --- a/include/lldb/Utility/DataBufferHeap.h +++ b/include/lldb/Utility/DataBufferHeap.h @@ -90,7 +90,8 @@ class DataBufferHeap : public DataBuffer { /// Set the number of bytes in the data buffer. /// /// Sets the number of bytes that this object should be able to contain. - /// This can be used prior to copying data into the buffer. + /// This can be used prior to copying data into the buffer. Note that this + /// zero-initializes up to \p byte_size bytes. /// /// @param[in] byte_size /// The new size in bytes that this data buffer should attempt diff --git a/source/Expression/IRMemoryMap.cpp b/source/Expression/IRMemoryMap.cpp index 1953e80852ff..6c01c28208b9 100644 --- a/source/Expression/IRMemoryMap.cpp +++ b/source/Expression/IRMemoryMap.cpp @@ -278,15 +278,11 @@ IRMemoryMap::Allocation::Allocation(lldb::addr_t process_alloc, default: assert(0 && "We cannot reach this!"); case eAllocationPolicyHostOnly: + case eAllocationPolicyMirror: m_data.SetByteSize(size); - memset(m_data.GetBytes(), 0, size); break; case eAllocationPolicyProcessOnly: break; - case eAllocationPolicyMirror: - m_data.SetByteSize(size); - memset(m_data.GetBytes(), 0, size); - break; } } From f055ce7eb893cd0d17ebcfd4125018f46f983aff Mon Sep 17 00:00:00 2001 From: Stephane Sezer Date: Mon, 6 Aug 2018 22:04:08 +0000 Subject: [PATCH 0063/1112] Add a relocation for R_AARCH64_ABS32 in ObjectFileELF Summary: .rela.debug_info relocations are being done via ObjectFileELF::ApplyRelocations for aarch64. Currently, the switch case that iterates over the relocation type is only implemented for a few different types and `assert(false)`es over the rest. Implement the relocation for R_AARCH64_ABS32 in ApplyRelocations Reviewers: sas, xiaobai, peter.smith, clayborg, javed.absar, espindola Differential Revision: https://reviews.llvm.org/D49407 Change by Nathan Lanza git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339068 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 8701908378f1..1ec003a4cfd1 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -2697,15 +2697,20 @@ unsigned ObjectFileELF::ApplyRelocations( break; } case R_X86_64_32: - case R_X86_64_32S: { + case R_X86_64_32S: + case R_AARCH64_ABS32: { symbol = symtab->FindSymbolByID(reloc_symbol(rel)); if (symbol) { addr_t value = symbol->GetAddressRef().GetFileAddress(); value += ELFRelocation::RelocAddend32(rel); - assert( - (reloc_type(rel) == R_X86_64_32 && (value <= UINT32_MAX)) || - (reloc_type(rel) == R_X86_64_32S && - ((int64_t)value <= INT32_MAX && (int64_t)value >= INT32_MIN))); + if (!((IsRelocABS32(rel) && value <= UINT32_MAX) || + (reloc_type(rel) == R_X86_64_32S && + ((int64_t)value <= INT32_MAX && + (int64_t)value >= INT32_MIN)))) { + Log *log = + lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES); + log->Printf("Failed to apply debug info relocations"); + } uint32_t truncated_addr = (value & 0xFFFFFFFF); DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); uint32_t *dst = reinterpret_cast( From 8dbfa524035fb4ac48833385ff35fb762056cdb4 Mon Sep 17 00:00:00 2001 From: Stephane Sezer Date: Mon, 6 Aug 2018 22:21:28 +0000 Subject: [PATCH 0064/1112] Revert "Add a relocation for R_AARCH64_ABS32 in ObjectFileELF" This reverts commit f055ce7eb893cd0d17ebcfd4125018f46f983aff. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339071 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 1ec003a4cfd1..8701908378f1 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -2697,20 +2697,15 @@ unsigned ObjectFileELF::ApplyRelocations( break; } case R_X86_64_32: - case R_X86_64_32S: - case R_AARCH64_ABS32: { + case R_X86_64_32S: { symbol = symtab->FindSymbolByID(reloc_symbol(rel)); if (symbol) { addr_t value = symbol->GetAddressRef().GetFileAddress(); value += ELFRelocation::RelocAddend32(rel); - if (!((IsRelocABS32(rel) && value <= UINT32_MAX) || - (reloc_type(rel) == R_X86_64_32S && - ((int64_t)value <= INT32_MAX && - (int64_t)value >= INT32_MIN)))) { - Log *log = - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES); - log->Printf("Failed to apply debug info relocations"); - } + assert( + (reloc_type(rel) == R_X86_64_32 && (value <= UINT32_MAX)) || + (reloc_type(rel) == R_X86_64_32S && + ((int64_t)value <= INT32_MAX && (int64_t)value >= INT32_MIN))); uint32_t truncated_addr = (value & 0xFFFFFFFF); DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); uint32_t *dst = reinterpret_cast( From 6dcc661eda1182a3fda1b8b4952fc3b13f77d894 Mon Sep 17 00:00:00 2001 From: Stella Stamenova Date: Mon, 6 Aug 2018 22:37:53 +0000 Subject: [PATCH 0065/1112] [lit, python] Always add quotes around the python path in lit Summary: The issue with the python path is that the path to python on Windows can contain spaces. To make the tests always work, the path to python needs to be surrounded by quotes. This is a companion change to: https://reviews.llvm.org/D50206 Reviewers: asmith, zturner Differential Revision: https://reviews.llvm.org/D50280 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339076 91177308-0d34-0410-b5e6-96231b3b80d8 --- lit/lit.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lit/lit.cfg b/lit/lit.cfg index 7e1fcf7520ca..98d69bb4c817 100644 --- a/lit/lit.cfg +++ b/lit/lit.cfg @@ -54,7 +54,7 @@ config.environment['LLVM_SRC_ROOT'] = getattr(config, 'llvm_src_root', '') config.environment['PYTHON_EXECUTABLE'] = getattr(config, 'python_executable', '') # Register substitutions -config.substitutions.append(('%python', config.python_executable)) +config.substitutions.append(('%python', "'%s'" % (config.python_executable))) debugserver = lit.util.which('debugserver', lldb_tools_dir) lldb = "%s -S %s/lit-lldb-init" % (lit.util.which('lldb', lldb_tools_dir), From d3f69c4e1e016673145715a68a07fc39cf170f94 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Tue, 7 Aug 2018 11:07:21 +0000 Subject: [PATCH 0066/1112] Move RegisterValue,Scalar,State from Core to Utility These three classes have no external dependencies, but they are used from various low-level APIs. Moving them down to Utility improves overall code layering (although it still does not break any particular dependency completely). The XCode project will need to be updated after this change. Differential Revision: https://reviews.llvm.org/D49740 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339127 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Core/Value.h | 2 +- include/lldb/Core/ValueObjectRegister.h | 10 ++++---- include/lldb/Expression/DWARFExpression.h | 2 +- include/lldb/Target/StackFrame.h | 2 +- include/lldb/Target/ThreadPlanTracer.h | 2 +- .../lldb/{Core => Utility}/RegisterValue.h | 20 +++++----------- include/lldb/{Core => Utility}/Scalar.h | 16 +++++-------- include/lldb/{Core => Utility}/State.h | 16 ++++++------- source/API/SBDebugger.cpp | 2 +- source/API/SBProcess.cpp | 2 +- source/API/SBThread.cpp | 2 +- source/API/SBThreadPlan.cpp | 2 +- source/API/SBValue.cpp | 2 +- .../CommandObjectBreakpointCommand.cpp | 2 +- source/Commands/CommandObjectProcess.cpp | 2 +- source/Commands/CommandObjectRegister.cpp | 4 ++-- source/Commands/CommandObjectTarget.cpp | 2 +- source/Commands/CommandObjectThread.cpp | 2 +- source/Commands/CommandObjectType.cpp | 2 +- .../CommandObjectWatchpointCommand.cpp | 2 +- source/Core/CMakeLists.txt | 3 --- source/Core/Debugger.cpp | 10 ++++---- source/Core/DumpRegisterValue.cpp | 2 +- source/Core/EmulateInstruction.cpp | 2 +- source/Core/FormatEntity.cpp | 8 +++---- source/Core/IOHandler.cpp | 2 +- source/Core/Value.cpp | 4 ++-- source/Core/ValueObject.cpp | 4 ++-- source/Core/ValueObjectCast.cpp | 2 +- source/Core/ValueObjectChild.cpp | 4 ++-- source/Core/ValueObjectConstResult.cpp | 2 +- source/Core/ValueObjectConstResultImpl.cpp | 2 +- source/Core/ValueObjectDynamicValue.cpp | 2 +- source/Core/ValueObjectMemory.cpp | 2 +- source/Core/ValueObjectRegister.cpp | 4 ++-- source/Core/ValueObjectVariable.cpp | 6 ++--- source/Expression/DWARFExpression.cpp | 4 ++-- source/Expression/FunctionCaller.cpp | 2 +- source/Expression/IRInterpreter.cpp | 2 +- source/Expression/IRMemoryMap.cpp | 2 +- source/Expression/Materializer.cpp | 2 +- source/Host/common/NativeProcessProtocol.cpp | 2 +- source/Host/common/NativeRegisterContext.cpp | 2 +- source/Interpreter/CommandInterpreter.cpp | 2 +- source/Interpreter/OptionValueArch.cpp | 2 +- source/Interpreter/OptionValueDictionary.cpp | 2 +- source/Interpreter/OptionValueFileSpec.cpp | 2 +- .../Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp | 4 ++-- .../ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp | 4 ++-- .../ABI/MacOSX-i386/ABIMacOSX_i386.cpp | 4 ++-- source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp | 4 ++-- .../Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp | 4 ++-- .../ABI/SysV-hexagon/ABISysV_hexagon.cpp | 2 +- source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp | 2 +- source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp | 2 +- .../ABI/SysV-mips64/ABISysV_mips64.cpp | 2 +- source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp | 2 +- .../Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp | 2 +- .../Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp | 2 +- .../ABI/SysV-x86_64/ABISysV_x86_64.cpp | 2 +- .../DynamicLoaderDarwinKernel.cpp | 2 +- .../MacOSX-DYLD/DynamicLoaderDarwin.cpp | 2 +- .../MacOSX-DYLD/DynamicLoaderMacOS.cpp | 2 +- .../MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp | 2 +- .../Clang/ClangExpressionDeclMap.cpp | 2 +- .../Clang/ClangFunctionCaller.cpp | 2 +- .../ExpressionParser/Clang/IRForTarget.cpp | 2 +- .../Instruction/ARM/EmulationStateARM.cpp | 4 ++-- .../ARM64/EmulateInstructionARM64.cpp | 2 +- .../MIPS/EmulateInstructionMIPS.cpp | 2 +- .../MIPS64/EmulateInstructionMIPS64.cpp | 2 +- .../ItaniumABI/ItaniumABILanguageRuntime.cpp | 2 +- .../LanguageRuntime/Go/GoLanguageRuntime.cpp | 2 +- .../AppleObjCRuntime/AppleObjCRuntime.cpp | 2 +- .../AppleObjCRuntime/AppleObjCRuntimeV1.cpp | 2 +- .../AppleObjCRuntime/AppleObjCRuntimeV2.cpp | 2 +- .../RenderScriptRuntime.cpp | 2 +- .../ObjectFile/Mach-O/ObjectFileMachO.cpp | 2 +- .../OperatingSystem/Go/OperatingSystemGo.cpp | 2 +- .../Python/OperatingSystemPython.cpp | 2 +- .../Platform/Android/PlatformAndroid.cpp | 2 +- .../Platform/FreeBSD/PlatformFreeBSD.cpp | 2 +- .../Plugins/Platform/Linux/PlatformLinux.cpp | 2 +- .../Platform/NetBSD/PlatformNetBSD.cpp | 2 +- .../Platform/OpenBSD/PlatformOpenBSD.cpp | 2 +- .../Process/Darwin/NativeProcessDarwin.cpp | 2 +- .../Plugins/Process/FreeBSD/FreeBSDThread.cpp | 4 ++-- .../Process/FreeBSD/ProcessFreeBSD.cpp | 6 ++--- .../Process/FreeBSD/ProcessMonitor.cpp | 4 ++-- ...RegisterContextPOSIXProcessMonitor_arm.cpp | 2 +- ...gisterContextPOSIXProcessMonitor_arm64.cpp | 2 +- ...isterContextPOSIXProcessMonitor_mips64.cpp | 2 +- ...sterContextPOSIXProcessMonitor_powerpc.cpp | 2 +- ...RegisterContextPOSIXProcessMonitor_x86.cpp | 2 +- .../Process/Linux/NativeProcessLinux.cpp | 4 ++-- .../Linux/NativeRegisterContextLinux.cpp | 2 +- .../Linux/NativeRegisterContextLinux_arm.cpp | 2 +- .../NativeRegisterContextLinux_arm64.cpp | 2 +- .../NativeRegisterContextLinux_mips64.cpp | 2 +- .../NativeRegisterContextLinux_ppc64le.cpp | 2 +- .../NativeRegisterContextLinux_s390x.cpp | 2 +- .../NativeRegisterContextLinux_x86_64.cpp | 2 +- .../Process/Linux/NativeThreadLinux.cpp | 2 +- .../MacOSX-Kernel/CommunicationKDP.cpp | 2 +- .../Process/MacOSX-Kernel/ProcessKDP.cpp | 4 ++-- .../Process/MacOSX-Kernel/ThreadKDP.cpp | 2 +- source/Plugins/Process/NetBSD/CMakeLists.txt | 1 - .../Process/NetBSD/NativeProcessNetBSD.cpp | 2 +- .../NativeRegisterContextNetBSD_x86_64.cpp | 2 +- .../Process/NetBSD/NativeThreadNetBSD.cpp | 4 ++-- .../Utility/RegisterContextDarwin_arm.cpp | 4 ++-- .../Utility/RegisterContextDarwin_arm64.cpp | 4 ++-- .../Utility/RegisterContextDarwin_i386.cpp | 4 ++-- .../Utility/RegisterContextDarwin_x86_64.cpp | 4 ++-- .../Process/Utility/RegisterContextDummy.cpp | 2 +- .../Utility/RegisterContextHistory.cpp | 2 +- .../Process/Utility/RegisterContextLLDB.cpp | 2 +- .../RegisterContextMacOSXFrameBackchain.cpp | 4 ++-- .../Process/Utility/RegisterContextMemory.cpp | 2 +- .../Utility/RegisterContextPOSIX_arm.cpp | 4 ++-- .../Utility/RegisterContextPOSIX_arm64.cpp | 4 ++-- .../Utility/RegisterContextPOSIX_mips64.cpp | 4 ++-- .../Utility/RegisterContextPOSIX_powerpc.cpp | 4 ++-- .../Utility/RegisterContextPOSIX_ppc64le.cpp | 4 ++-- .../Utility/RegisterContextPOSIX_s390x.cpp | 4 ++-- .../Utility/RegisterContextPOSIX_x86.cpp | 4 ++-- .../Process/Windows/Common/ProcessWindows.cpp | 2 +- .../Windows/Common/TargetThreadWindows.cpp | 2 +- .../Common/x64/RegisterContextWindows_x64.cpp | 2 +- .../Common/x86/RegisterContextWindows_x86.cpp | 2 +- .../Process/elf-core/ProcessElfCore.cpp | 2 +- .../elf-core/RegisterContextPOSIXCore_arm.cpp | 2 +- .../RegisterContextPOSIXCore_arm64.cpp | 2 +- .../RegisterContextPOSIXCore_mips64.cpp | 2 +- .../RegisterContextPOSIXCore_powerpc.cpp | 2 +- .../RegisterContextPOSIXCore_ppc64le.cpp | 2 +- .../RegisterContextPOSIXCore_s390x.cpp | 2 +- .../RegisterContextPOSIXCore_x86_64.cpp | 2 +- .../GDBRemoteCommunicationClient.cpp | 2 +- .../GDBRemoteCommunicationServerLLGS.cpp | 4 ++-- .../gdb-remote/GDBRemoteRegisterContext.cpp | 4 ++-- .../Process/gdb-remote/ProcessGDBRemote.cpp | 2 +- .../Process/gdb-remote/ThreadGDBRemote.cpp | 2 +- .../Process/mach-core/ProcessMachCore.cpp | 2 +- .../Process/mach-core/ThreadMachCore.cpp | 2 +- .../Process/minidump/ProcessMinidump.cpp | 2 +- .../minidump/RegisterContextMinidump_ARM.cpp | 2 +- .../RegisterContextMinidump_ARM64.cpp | 2 +- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 2 +- .../UnwindAssemblyInstEmulation.h | 2 +- source/Symbol/ClangASTContext.cpp | 2 +- source/Symbol/CompilerType.cpp | 2 +- source/Symbol/Type.cpp | 2 +- source/Target/ExecutionContext.cpp | 2 +- source/Target/Memory.cpp | 2 +- source/Target/Process.cpp | 2 +- source/Target/RegisterContext.cpp | 4 ++-- source/Target/StackFrame.cpp | 2 +- source/Target/Target.cpp | 2 +- source/Target/TargetList.cpp | 2 +- source/Target/Thread.cpp | 2 +- source/Target/ThreadList.cpp | 2 +- source/Target/ThreadPlan.cpp | 2 +- source/Target/ThreadPlanPython.cpp | 2 +- source/Target/ThreadPlanTracer.cpp | 2 +- source/Utility/CMakeLists.txt | 3 +++ source/{Core => Utility}/RegisterValue.cpp | 4 ++-- source/{Core => Utility}/Scalar.cpp | 4 ++-- source/{Core => Utility}/State.cpp | 2 +- unittests/Core/CMakeLists.txt | 1 - unittests/Core/ScalarTest.cpp | 2 +- unittests/Utility/CMakeLists.txt | 2 ++ unittests/Utility/RegisterValueTest.cpp | 23 +++++++++++++++++++ unittests/{Core => Utility}/StateTest.cpp | 2 +- .../tools/lldb-server/tests/MessageObjects.h | 2 +- 175 files changed, 262 insertions(+), 253 deletions(-) rename include/lldb/{Core => Utility}/RegisterValue.h (96%) rename include/lldb/{Core => Utility}/Scalar.h (98%) rename include/lldb/{Core => Utility}/State.h (91%) rename source/{Core => Utility}/RegisterValue.cpp (99%) rename source/{Core => Utility}/Scalar.cpp (99%) rename source/{Core => Utility}/State.cpp (98%) create mode 100644 unittests/Utility/RegisterValueTest.cpp rename unittests/{Core => Utility}/StateTest.cpp (95%) diff --git a/include/lldb/Core/Value.h b/include/lldb/Core/Value.h index 801e818c6f5c..fbb58d7ce69e 100644 --- a/include/lldb/Core/Value.h +++ b/include/lldb/Core/Value.h @@ -10,9 +10,9 @@ #ifndef liblldb_Value_h_ #define liblldb_Value_h_ -#include "lldb/Core/Scalar.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-enumerations.h" // for ByteOrder, ByteOrder::eB... #include "lldb/lldb-private-enumerations.h" // for AddressType diff --git a/include/lldb/Core/ValueObjectRegister.h b/include/lldb/Core/ValueObjectRegister.h index 2aaef9bee99e..86310bd545bd 100644 --- a/include/lldb/Core/ValueObjectRegister.h +++ b/include/lldb/Core/ValueObjectRegister.h @@ -10,14 +10,14 @@ #ifndef liblldb_ValueObjectRegister_h_ #define liblldb_ValueObjectRegister_h_ -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/CompilerType.h" // for CompilerType #include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-enumerations.h" // for ValueType, ValueType::eValueTy... -#include "lldb/lldb-forward.h" // for RegisterContextSP, ValueObjectSP -#include "lldb/lldb-private-types.h" // for RegisterInfo, RegisterSet (ptr... +#include "lldb/Utility/RegisterValue.h" +#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN +#include "lldb/lldb-enumerations.h" // for ValueType, ValueType::eValueTy... +#include "lldb/lldb-forward.h" // for RegisterContextSP, ValueObjectSP +#include "lldb/lldb-private-types.h" // for RegisterInfo, RegisterSet (ptr... #include // for size_t #include // for uint32_t, uint64_t, int32_t diff --git a/include/lldb/Expression/DWARFExpression.h b/include/lldb/Expression/DWARFExpression.h index b4bd9697da58..5865e577f630 100644 --- a/include/lldb/Expression/DWARFExpression.h +++ b/include/lldb/Expression/DWARFExpression.h @@ -12,8 +12,8 @@ #include "lldb/Core/Address.h" #include "lldb/Core/Disassembler.h" -#include "lldb/Core/Scalar.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private.h" #include diff --git a/include/lldb/Target/StackFrame.h b/include/lldb/Target/StackFrame.h index ce9b16227672..83ef2fef8002 100644 --- a/include/lldb/Target/StackFrame.h +++ b/include/lldb/Target/StackFrame.h @@ -19,11 +19,11 @@ // Project includes #include "lldb/Utility/Flags.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/ValueObjectList.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/StackID.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/UserID.h" diff --git a/include/lldb/Target/ThreadPlanTracer.h b/include/lldb/Target/ThreadPlanTracer.h index 65115383efaa..b32a69c197b2 100644 --- a/include/lldb/Target/ThreadPlanTracer.h +++ b/include/lldb/Target/ThreadPlanTracer.h @@ -15,9 +15,9 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Core/RegisterValue.h" #include "lldb/Symbol/TaggedASTType.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/lldb-private.h" namespace lldb_private { diff --git a/include/lldb/Core/RegisterValue.h b/include/lldb/Utility/RegisterValue.h similarity index 96% rename from include/lldb/Core/RegisterValue.h rename to include/lldb/Utility/RegisterValue.h index b369c3dff9a9..015747a1df9a 100644 --- a/include/lldb/Core/RegisterValue.h +++ b/include/lldb/Utility/RegisterValue.h @@ -7,31 +7,23 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_RegisterValue_h -#define lldb_RegisterValue_h +#ifndef LLDB_UTILITY_REGISTERVALUE_H +#define LLDB_UTILITY_REGISTERVALUE_H -#include "lldb/Core/Scalar.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" // for Status #include "lldb/lldb-enumerations.h" // for ByteOrder, Format #include "lldb/lldb-types.h" // for offset_t - #include "llvm/ADT/APInt.h" #include "llvm/ADT/StringRef.h" // for StringRef - -#include // for uint32_t, uint8_t, uint64_t, uin... -#include +#include // for uint32_t, uint8_t, uint64_t, uin... +#include namespace lldb_private { class DataExtractor; -} -namespace lldb_private { class Stream; -} -namespace lldb_private { struct RegisterInfo; -} -namespace lldb_private { class RegisterValue { public: @@ -276,4 +268,4 @@ class RegisterValue { } // namespace lldb_private -#endif // lldb_RegisterValue_h +#endif // LLDB_UTILITY_REGISTERVALUE_H diff --git a/include/lldb/Core/Scalar.h b/include/lldb/Utility/Scalar.h similarity index 98% rename from include/lldb/Core/Scalar.h rename to include/lldb/Utility/Scalar.h index 40671a242ec3..74c9b879b204 100644 --- a/include/lldb/Core/Scalar.h +++ b/include/lldb/Utility/Scalar.h @@ -7,25 +7,21 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Scalar_h_ -#define liblldb_Scalar_h_ +#ifndef LLDB_UTILITY_SCALAR_H +#define LLDB_UTILITY_SCALAR_H #include "lldb/Utility/Status.h" // for Status #include "lldb/lldb-enumerations.h" // for Encoding, ByteOrder #include "lldb/lldb-private-types.h" // for type128 - #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" - -#include // for size_t -#include // for uint32_t, uint64_t, int64_t +#include // for size_t +#include // for uint32_t, uint64_t, int64_t namespace lldb_private { class DataExtractor; -} -namespace lldb_private { class Stream; -} +} // namespace lldb_private #define NUM_OF_WORDS_INT128 2 #define BITWIDTH_INT128 128 @@ -375,4 +371,4 @@ bool operator>=(const Scalar &lhs, const Scalar &rhs); } // namespace lldb_private -#endif // liblldb_Scalar_h_ +#endif // LLDB_UTILITY_SCALAR_H diff --git a/include/lldb/Core/State.h b/include/lldb/Utility/State.h similarity index 91% rename from include/lldb/Core/State.h rename to include/lldb/Utility/State.h index 68f0fee254b3..efe901ae595b 100644 --- a/include/lldb/Core/State.h +++ b/include/lldb/Utility/State.h @@ -7,16 +7,14 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_State_h_ -#define liblldb_State_h_ +#ifndef LLDB_UTILITY_STATE_H +#define LLDB_UTILITY_STATE_H +#include "lldb/lldb-enumerations.h" // for StateType +#include "llvm/ADT/StringRef.h" // for StringRef #include "llvm/Support/FormatProviders.h" - -#include "lldb/lldb-enumerations.h" // for StateType -#include "llvm/ADT/StringRef.h" // for StringRef #include "llvm/Support/raw_ostream.h" // for raw_ostream - -#include // for uint32_t +#include // for uint32_t namespace lldb_private { @@ -80,6 +78,6 @@ template <> struct format_provider { Stream << lldb_private::StateAsCString(state); } }; -} +} // namespace llvm -#endif // liblldb_State_h_ +#endif // LLDB_UTILITY_STATE_H diff --git a/source/API/SBDebugger.cpp b/source/API/SBDebugger.cpp index a651141003a4..5403d0acc0d6 100644 --- a/source/API/SBDebugger.cpp +++ b/source/API/SBDebugger.cpp @@ -41,7 +41,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/StructuredDataImpl.h" #include "lldb/DataFormatters/DataVisualization.h" @@ -53,6 +52,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/TargetList.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/State.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" diff --git a/source/API/SBProcess.cpp b/source/API/SBProcess.cpp index 4d5ddc86ccf9..e79231d3723d 100644 --- a/source/API/SBProcess.cpp +++ b/source/API/SBProcess.cpp @@ -18,7 +18,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Process.h" @@ -28,6 +27,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" // Project includes diff --git a/source/API/SBThread.cpp b/source/API/SBThread.cpp index 0d25b85f57d2..b7af4593add5 100644 --- a/source/API/SBThread.cpp +++ b/source/API/SBThread.cpp @@ -14,7 +14,6 @@ #include "lldb/API/SBSymbolContext.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/ValueObject.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -32,6 +31,7 @@ #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Target/ThreadPlanStepRange.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StructuredData.h" diff --git a/source/API/SBThreadPlan.cpp b/source/API/SBThreadPlan.cpp index 131f84195908..393abcb8424e 100644 --- a/source/API/SBThreadPlan.cpp +++ b/source/API/SBThreadPlan.cpp @@ -14,7 +14,6 @@ #include "lldb/API/SBSymbolContext.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Symbol/CompileUnit.h" @@ -31,6 +30,7 @@ #include "lldb/Target/ThreadPlanStepInstruction.h" #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Target/ThreadPlanStepRange.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StructuredData.h" diff --git a/source/API/SBValue.cpp b/source/API/SBValue.cpp index a270c0471e9f..67ad6259cde0 100644 --- a/source/API/SBValue.cpp +++ b/source/API/SBValue.cpp @@ -18,7 +18,6 @@ #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/Module.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Section.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" @@ -38,6 +37,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Stream.h" #include "lldb/API/SBDebugger.h" diff --git a/source/Commands/CommandObjectBreakpointCommand.cpp b/source/Commands/CommandObjectBreakpointCommand.cpp index f2546cbed848..42733827c488 100644 --- a/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/source/Commands/CommandObjectBreakpointCommand.cpp @@ -18,13 +18,13 @@ #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/IOHandler.h" -#include "lldb/Core/State.h" #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/State.h" #include "llvm/ADT/STLExtras.h" diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp index eb5a19aa4d39..68d192834b43 100644 --- a/source/Commands/CommandObjectProcess.cpp +++ b/source/Commands/CommandObjectProcess.cpp @@ -17,7 +17,6 @@ #include "lldb/Breakpoint/BreakpointSite.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Host/OptionParser.h" #include "lldb/Host/StringConvert.h" @@ -32,6 +31,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Commands/CommandObjectRegister.cpp b/source/Commands/CommandObjectRegister.cpp index 4dadc5d68d20..ae444f7955d4 100644 --- a/source/Commands/CommandObjectRegister.cpp +++ b/source/Commands/CommandObjectRegister.cpp @@ -10,8 +10,6 @@ #include "CommandObjectRegister.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/DumpRegisterValue.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -27,6 +25,8 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Errno.h" using namespace lldb; diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp index 8be43cbf9bb0..4ef3fdd545ad 100644 --- a/source/Commands/CommandObjectTarget.cpp +++ b/source/Commands/CommandObjectTarget.cpp @@ -15,7 +15,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/ValueObjectPrinter.h" #include "lldb/Host/OptionParser.h" @@ -51,6 +50,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadSpec.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Timer.h" #include "llvm/Support/FileSystem.h" diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp index 3be559963df1..312771322809 100644 --- a/source/Commands/CommandObjectThread.cpp +++ b/source/Commands/CommandObjectThread.cpp @@ -14,7 +14,6 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/SourceManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/ValueObject.h" #include "lldb/Host/Host.h" #include "lldb/Host/OptionParser.h" @@ -37,6 +36,7 @@ #include "lldb/Target/ThreadPlanStepInstruction.h" #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Target/ThreadPlanStepRange.h" +#include "lldb/Utility/State.h" #include "lldb/lldb-private.h" using namespace lldb; diff --git a/source/Commands/CommandObjectType.cpp b/source/Commands/CommandObjectType.cpp index 6bcc334198fc..6eff1b0fea60 100644 --- a/source/Commands/CommandObjectType.cpp +++ b/source/Commands/CommandObjectType.cpp @@ -18,7 +18,6 @@ // Project includes #include "lldb/Core/Debugger.h" #include "lldb/Core/IOHandler.h" -#include "lldb/Core/State.h" #include "lldb/DataFormatters/DataVisualization.h" #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -39,6 +38,7 @@ #include "lldb/Target/ThreadList.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StringList.h" // Other libraries and framework includes diff --git a/source/Commands/CommandObjectWatchpointCommand.cpp b/source/Commands/CommandObjectWatchpointCommand.cpp index 74015a433831..135b9c790f09 100644 --- a/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/source/Commands/CommandObjectWatchpointCommand.cpp @@ -18,13 +18,13 @@ #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/IOHandler.h" -#include "lldb/Core/State.h" #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Core/CMakeLists.txt b/source/Core/CMakeLists.txt index bae5b499f449..b1c6593c1652 100644 --- a/source/Core/CMakeLists.txt +++ b/source/Core/CMakeLists.txt @@ -34,12 +34,9 @@ add_lldb_library(lldbCore ModuleList.cpp Opcode.cpp PluginManager.cpp - RegisterValue.cpp - Scalar.cpp SearchFilter.cpp Section.cpp SourceManager.cpp - State.cpp StreamAsynchronousIO.cpp StreamFile.cpp UserSettingsController.cpp diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp index b29f3565e03e..f5eab84eb300 100644 --- a/source/Core/Debugger.cpp +++ b/source/Core/Debugger.cpp @@ -12,11 +12,10 @@ #include "lldb/Breakpoint/Breakpoint.h" // for Breakpoint, Brea... #include "lldb/Core/Event.h" // for Event, EventData... #include "lldb/Core/FormatEntity.h" -#include "lldb/Core/Listener.h" // for Listener -#include "lldb/Core/Mangled.h" // for Mangled -#include "lldb/Core/ModuleList.h" // for Mangled +#include "lldb/Core/Listener.h" // for Listener +#include "lldb/Core/Mangled.h" // for Mangled +#include "lldb/Core/ModuleList.h" // for Mangled #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamAsynchronousIO.h" #include "lldb/Core/StreamFile.h" #include "lldb/DataFormatters/DataVisualization.h" @@ -43,7 +42,8 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadList.h" // for ThreadList #include "lldb/Utility/AnsiTerminal.h" -#include "lldb/Utility/Log.h" // for LLDB_LOG_OPTION_... +#include "lldb/Utility/Log.h" // for LLDB_LOG_OPTION_... +#include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" // for Stream #include "lldb/Utility/StreamCallback.h" #include "lldb/Utility/StreamString.h" diff --git a/source/Core/DumpRegisterValue.cpp b/source/Core/DumpRegisterValue.cpp index 99334ca78a6d..d7196a585667 100644 --- a/source/Core/DumpRegisterValue.cpp +++ b/source/Core/DumpRegisterValue.cpp @@ -9,8 +9,8 @@ #include "lldb/Core/DumpRegisterValue.h" #include "lldb/Core/DumpDataExtractor.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/StreamString.h" #include "lldb/lldb-private-types.h" diff --git a/source/Core/EmulateInstruction.cpp b/source/Core/EmulateInstruction.cpp index 469022119c9e..71f65aa830fa 100644 --- a/source/Core/EmulateInstruction.cpp +++ b/source/Core/EmulateInstruction.cpp @@ -12,7 +12,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/DumpRegisterValue.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/StreamFile.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Target/Process.h" @@ -20,6 +19,7 @@ #include "lldb/Target/StackFrame.h" // for StackFrame #include "lldb/Utility/ConstString.h" // for ConstString #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" // for Stream, Stream::::eBinary #include "lldb/Utility/StreamString.h" diff --git a/source/Core/FormatEntity.cpp b/source/Core/FormatEntity.cpp index 743c7c404994..bfaf5a0e0070 100644 --- a/source/Core/FormatEntity.cpp +++ b/source/Core/FormatEntity.cpp @@ -14,7 +14,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/DumpRegisterValue.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" // for RegisterValue #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/DataVisualization.h" @@ -45,9 +44,10 @@ #include "lldb/Utility/ArchSpec.h" // for ArchSpec #include "lldb/Utility/ConstString.h" // for ConstString, oper... #include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Log.h" // for Log -#include "lldb/Utility/Logging.h" // for GetLogIfAllCatego... -#include "lldb/Utility/SharingPtr.h" // for SharingPtr +#include "lldb/Utility/Log.h" // for Log +#include "lldb/Utility/Logging.h" // for GetLogIfAllCatego... +#include "lldb/Utility/RegisterValue.h" // for RegisterValue +#include "lldb/Utility/SharingPtr.h" // for SharingPtr #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StringList.h" // for StringList diff --git a/source/Core/IOHandler.cpp b/source/Core/IOHandler.cpp index e7ebeea1b88d..ee7513d4a610 100644 --- a/source/Core/IOHandler.cpp +++ b/source/Core/IOHandler.cpp @@ -40,7 +40,6 @@ #ifndef LLDB_DISABLE_CURSES #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" -#include "lldb/Core/State.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectRegister.h" #include "lldb/Symbol/Block.h" @@ -53,6 +52,7 @@ #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/State.h" #endif #include "llvm/ADT/StringRef.h" // for StringRef diff --git a/source/Core/Value.cpp b/source/Core/Value.cpp index 254c9008babb..a3cf8318a38f 100644 --- a/source/Core/Value.cpp +++ b/source/Core/Value.cpp @@ -9,9 +9,8 @@ #include "lldb/Core/Value.h" -#include "lldb/Core/Address.h" // for Address +#include "lldb/Core/Address.h" // for Address #include "lldb/Core/Module.h" -#include "lldb/Core/State.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" @@ -26,6 +25,7 @@ #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" // for InlHostByteOrder #include "lldb/Utility/FileSpec.h" // for FileSpec +#include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" #include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS #include "lldb/lldb-forward.h" // for DataBufferSP, ModuleSP diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp index 244ea2936fb4..ddf6ed213e63 100644 --- a/source/Core/ValueObject.cpp +++ b/source/Core/ValueObject.cpp @@ -11,7 +11,6 @@ #include "lldb/Core/Address.h" // for Address #include "lldb/Core/Module.h" -#include "lldb/Core/Scalar.h" // for Scalar #include "lldb/Core/ValueObjectCast.h" #include "lldb/Core/ValueObjectChild.h" #include "lldb/Core/ValueObjectConstResult.h" @@ -20,7 +19,7 @@ #include "lldb/Core/ValueObjectSyntheticFilter.h" #include "lldb/DataFormatters/DataVisualization.h" #include "lldb/DataFormatters/DumpValueObjectOptions.h" // for DumpValueObj... -#include "lldb/DataFormatters/FormatManager.h" // for FormatManager +#include "lldb/DataFormatters/FormatManager.h" // for FormatManager #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/TypeFormat.h" // for TypeFormatImpl_F... #include "lldb/DataFormatters/TypeSummary.h" // for TypeSummaryOptions @@ -47,6 +46,7 @@ #include "lldb/Utility/Flags.h" // for Flags #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" // for GetLogIfAllCateg... +#include "lldb/Utility/Scalar.h" // for Scalar #include "lldb/Utility/SharingPtr.h" // for SharingPtr #include "lldb/Utility/Stream.h" // for Stream #include "lldb/Utility/StreamString.h" diff --git a/source/Core/ValueObjectCast.cpp b/source/Core/ValueObjectCast.cpp index e0978f692bc5..f6ec026e0791 100644 --- a/source/Core/ValueObjectCast.cpp +++ b/source/Core/ValueObjectCast.cpp @@ -9,11 +9,11 @@ #include "lldb/Core/ValueObjectCast.h" -#include "lldb/Core/Scalar.h" // for operator!=, Scalar #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Utility/Scalar.h" // for operator!=, Scalar #include "lldb/Utility/Status.h" // for Status namespace lldb_private { diff --git a/source/Core/ValueObjectChild.cpp b/source/Core/ValueObjectChild.cpp index 019daa2fd3d2..00526c656564 100644 --- a/source/Core/ValueObjectChild.cpp +++ b/source/Core/ValueObjectChild.cpp @@ -9,12 +9,12 @@ #include "lldb/Core/ValueObjectChild.h" -#include "lldb/Core/Scalar.h" // for Scalar -#include "lldb/Core/Value.h" // for Value, Value::ValueType::e... +#include "lldb/Core/Value.h" // for Value, Value::ValueType::e... #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Utility/Flags.h" // for Flags +#include "lldb/Utility/Scalar.h" // for Scalar #include "lldb/Utility/Status.h" // for Status #include "lldb/lldb-forward.h" // for ProcessSP, ModuleSP diff --git a/source/Core/ValueObjectConstResult.cpp b/source/Core/ValueObjectConstResult.cpp index 1023696c35a7..e02ed1d5300b 100644 --- a/source/Core/ValueObjectConstResult.cpp +++ b/source/Core/ValueObjectConstResult.cpp @@ -9,7 +9,6 @@ #include "lldb/Core/ValueObjectConstResult.h" -#include "lldb/Core/Scalar.h" // for Scalar #include "lldb/Core/ValueObjectDynamicValue.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/ExecutionContext.h" @@ -18,6 +17,7 @@ #include "lldb/Utility/DataBuffer.h" // for DataBuffer #include "lldb/Utility/DataBufferHeap.h" // for DataBufferHeap #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Scalar.h" // for Scalar namespace lldb_private { class Module; diff --git a/source/Core/ValueObjectConstResultImpl.cpp b/source/Core/ValueObjectConstResultImpl.cpp index 714634ed56e3..58e1cc9eba41 100644 --- a/source/Core/ValueObjectConstResultImpl.cpp +++ b/source/Core/ValueObjectConstResultImpl.cpp @@ -9,7 +9,6 @@ #include "lldb/Core/ValueObjectConstResultImpl.h" -#include "lldb/Core/Scalar.h" // for Scalar #include "lldb/Core/Value.h" // for Value, Value::Val... #include "lldb/Core/ValueObject.h" // for ValueObject #include "lldb/Core/ValueObjectConstResult.h" @@ -19,6 +18,7 @@ #include "lldb/Target/ExecutionContext.h" #include "lldb/Utility/DataBufferHeap.h" // for DataBufferHeap #include "lldb/Utility/Endian.h" // for InlHostByteOrder +#include "lldb/Utility/Scalar.h" // for Scalar #include "lldb/Utility/SharingPtr.h" // for SharingPtr #include // for string diff --git a/source/Core/ValueObjectDynamicValue.cpp b/source/Core/ValueObjectDynamicValue.cpp index e9b48310b0c6..d835e6965d47 100644 --- a/source/Core/ValueObjectDynamicValue.cpp +++ b/source/Core/ValueObjectDynamicValue.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/ValueObjectDynamicValue.h" -#include "lldb/Core/Scalar.h" // for Scalar, operator!= #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/CompilerType.h" @@ -20,6 +19,7 @@ #include "lldb/Utility/DataExtractor.h" // for DataExtractor #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" // for GetLogIfAllCategoriesSet +#include "lldb/Utility/Scalar.h" // for Scalar, operator!= #include "lldb/Utility/Status.h" // for Status #include "lldb/lldb-types.h" // for addr_t, offset_t diff --git a/source/Core/ValueObjectMemory.cpp b/source/Core/ValueObjectMemory.cpp index 3e71fea6bb35..1a816463eec9 100644 --- a/source/Core/ValueObjectMemory.cpp +++ b/source/Core/ValueObjectMemory.cpp @@ -8,13 +8,13 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/ValueObjectMemory.h" -#include "lldb/Core/Scalar.h" // for Scalar, operator!= #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/Type.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataExtractor.h" // for DataExtractor +#include "lldb/Utility/Scalar.h" // for Scalar, operator!= #include "lldb/Utility/Status.h" // for Status #include "lldb/lldb-types.h" // for addr_t #include "llvm/Support/ErrorHandling.h" // for llvm_unreachable diff --git a/source/Core/ValueObjectRegister.cpp b/source/Core/ValueObjectRegister.cpp index 05022d3ed10a..818df06a4468 100644 --- a/source/Core/ValueObjectRegister.cpp +++ b/source/Core/ValueObjectRegister.cpp @@ -10,8 +10,7 @@ #include "lldb/Core/ValueObjectRegister.h" #include "lldb/Core/Module.h" -#include "lldb/Core/Scalar.h" // for Scalar -#include "lldb/Core/Value.h" // for Value, Value::ContextType:... +#include "lldb/Core/Value.h" // for Value, Value::ContextType:... #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/TypeSystem.h" // for TypeSystem #include "lldb/Target/ExecutionContext.h" @@ -20,6 +19,7 @@ #include "lldb/Target/StackFrame.h" // for StackFrame #include "lldb/Target/Target.h" #include "lldb/Utility/DataExtractor.h" // for DataExtractor +#include "lldb/Utility/Scalar.h" // for Scalar #include "lldb/Utility/Status.h" // for Status #include "lldb/Utility/Stream.h" // for Stream diff --git a/source/Core/ValueObjectVariable.cpp b/source/Core/ValueObjectVariable.cpp index bfe5c3de7fbf..e09bb17a219c 100644 --- a/source/Core/ValueObjectVariable.cpp +++ b/source/Core/ValueObjectVariable.cpp @@ -12,8 +12,6 @@ #include "lldb/Core/Address.h" // for Address #include "lldb/Core/AddressRange.h" // for AddressRange #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" // for Scalar, operator!= #include "lldb/Core/Value.h" #include "lldb/Expression/DWARFExpression.h" // for DWARFExpression #include "lldb/Symbol/Declaration.h" // for Declaration @@ -27,7 +25,9 @@ #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/DataExtractor.h" // for DataExtractor +#include "lldb/Utility/DataExtractor.h" // for DataExtractor +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" // for Scalar, operator!= #include "lldb/Utility/Status.h" // for Status #include "lldb/lldb-private-enumerations.h" // for AddressType::eAddressTy... #include "lldb/lldb-types.h" // for addr_t diff --git a/source/Expression/DWARFExpression.cpp b/source/Expression/DWARFExpression.cpp index 55eb65f32b5a..53244094ac0a 100644 --- a/source/Expression/DWARFExpression.cpp +++ b/source/Expression/DWARFExpression.cpp @@ -16,12 +16,12 @@ #include #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" #include "lldb/Core/dwarf.h" #include "lldb/Utility/DataEncoder.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/VMRange.h" diff --git a/source/Expression/FunctionCaller.cpp b/source/Expression/FunctionCaller.cpp index 9742ed0b270e..4485d15823f3 100644 --- a/source/Expression/FunctionCaller.cpp +++ b/source/Expression/FunctionCaller.cpp @@ -14,7 +14,6 @@ // Project includes #include "lldb/Expression/FunctionCaller.h" #include "lldb/Core/Module.h" -#include "lldb/Core/State.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectList.h" #include "lldb/Expression/DiagnosticManager.h" @@ -31,6 +30,7 @@ #include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" using namespace lldb_private; diff --git a/source/Expression/IRInterpreter.cpp b/source/Expression/IRInterpreter.cpp index abf86b739f07..5acb2e914427 100644 --- a/source/Expression/IRInterpreter.cpp +++ b/source/Expression/IRInterpreter.cpp @@ -10,7 +10,6 @@ #include "lldb/Expression/IRInterpreter.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/ValueObject.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/IRExecutionUnit.h" @@ -19,6 +18,7 @@ #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" diff --git a/source/Expression/IRMemoryMap.cpp b/source/Expression/IRMemoryMap.cpp index 6c01c28208b9..b4f6fb768875 100644 --- a/source/Expression/IRMemoryMap.cpp +++ b/source/Expression/IRMemoryMap.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "lldb/Expression/IRMemoryMap.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -16,6 +15,7 @@ #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" using namespace lldb_private; diff --git a/source/Expression/Materializer.cpp b/source/Expression/Materializer.cpp index 74a965e015ce..12591a73d1ac 100644 --- a/source/Expression/Materializer.cpp +++ b/source/Expression/Materializer.cpp @@ -13,7 +13,6 @@ // Project includes #include "lldb/Expression/Materializer.h" #include "lldb/Core/DumpDataExtractor.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Expression/ExpressionVariable.h" @@ -27,6 +26,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/source/Host/common/NativeProcessProtocol.cpp b/source/Host/common/NativeProcessProtocol.cpp index 3e8648f81473..7ccf84612728 100644 --- a/source/Host/common/NativeProcessProtocol.cpp +++ b/source/Host/common/NativeProcessProtocol.cpp @@ -8,13 +8,13 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/common/NativeProcessProtocol.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Host/common/NativeRegisterContext.h" #include "lldb/Host/common/NativeThreadProtocol.h" #include "lldb/Host/common/SoftwareBreakpoint.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/lldb-enumerations.h" using namespace lldb; diff --git a/source/Host/common/NativeRegisterContext.cpp b/source/Host/common/NativeRegisterContext.cpp index 49b8284da970..6e6632aa710f 100644 --- a/source/Host/common/NativeRegisterContext.cpp +++ b/source/Host/common/NativeRegisterContext.cpp @@ -9,8 +9,8 @@ #include "lldb/Host/common/NativeRegisterContext.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Host/PosixApi.h" #include "lldb/Host/common/NativeProcessProtocol.h" diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp index 64d2c3222fb6..648222747362 100644 --- a/source/Interpreter/CommandInterpreter.cpp +++ b/source/Interpreter/CommandInterpreter.cpp @@ -42,9 +42,9 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/Timer.h" diff --git a/source/Interpreter/OptionValueArch.cpp b/source/Interpreter/OptionValueArch.cpp index d4f1fcb8a70a..e9480d738882 100644 --- a/source/Interpreter/OptionValueArch.cpp +++ b/source/Interpreter/OptionValueArch.cpp @@ -13,11 +13,11 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Core/State.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; diff --git a/source/Interpreter/OptionValueDictionary.cpp b/source/Interpreter/OptionValueDictionary.cpp index 2e8a8427237b..73aa617f58fd 100644 --- a/source/Interpreter/OptionValueDictionary.cpp +++ b/source/Interpreter/OptionValueDictionary.cpp @@ -14,10 +14,10 @@ // Other libraries and framework includes #include "llvm/ADT/StringRef.h" // Project includes -#include "lldb/Core/State.h" #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Interpreter/OptionValueFileSpec.cpp b/source/Interpreter/OptionValueFileSpec.cpp index 2b93628679ce..158db98fedcb 100644 --- a/source/Interpreter/OptionValueFileSpec.cpp +++ b/source/Interpreter/OptionValueFileSpec.cpp @@ -9,13 +9,13 @@ #include "lldb/Interpreter/OptionValueFileSpec.h" -#include "lldb/Core/State.h" #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Host/FileSystem.h" #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/DataBufferLLVM.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp index e0e293d7ae68..371ba39adfcc 100644 --- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp +++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp @@ -20,8 +20,6 @@ // Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Symbol/UnwindPlan.h" @@ -30,6 +28,8 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Utility/ARMDefines.h" diff --git a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp index 85f864ec7561..65d50957ab3d 100644 --- a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp +++ b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp @@ -19,8 +19,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Symbol/UnwindPlan.h" @@ -30,6 +28,8 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "Utility/ARM64_DWARF_Registers.h" diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp index 9e5e39ec28ca..3ddeff586850 100644 --- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp +++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp @@ -20,8 +20,6 @@ // Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Target/Process.h" @@ -29,6 +27,8 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" using namespace lldb; diff --git a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp index af7ac469e6db..ff91aa5a1963 100644 --- a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp +++ b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp @@ -20,8 +20,6 @@ // Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Symbol/UnwindPlan.h" @@ -30,6 +28,8 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Utility/ARMDefines.h" diff --git a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp index 2c221689954c..da9ed3331584 100644 --- a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp +++ b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp @@ -20,8 +20,6 @@ // Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Symbol/UnwindPlan.h" @@ -31,6 +29,8 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "Utility/ARM64_DWARF_Registers.h" diff --git a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp index a30416cf5a8e..3a39370eafad 100644 --- a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp +++ b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp @@ -18,7 +18,6 @@ // Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -32,6 +31,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; diff --git a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp index e7ddfccea338..fe198e1d4ab2 100644 --- a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp +++ b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp @@ -17,7 +17,6 @@ // Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -31,6 +30,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; diff --git a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp index ce02f8677a63..b1ba64522c7f 100644 --- a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp +++ b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp @@ -18,7 +18,6 @@ // Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -32,6 +31,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; diff --git a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp index b958abf25637..e867b15a00f2 100644 --- a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp +++ b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp @@ -18,7 +18,6 @@ // Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -32,6 +31,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp index e93dcdbe1a59..1cfca8784234 100644 --- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp +++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp @@ -18,7 +18,6 @@ // Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -32,6 +31,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp index d0140a0c894a..8047ff332b61 100644 --- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp +++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp @@ -20,7 +20,6 @@ #include "Utility/PPC64_DWARF_Registers.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -35,6 +34,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "clang/AST/ASTContext.h" diff --git a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp index 31e2825c0fa2..df42d4a6cb4b 100644 --- a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp +++ b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp @@ -18,7 +18,6 @@ // Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -32,6 +31,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; diff --git a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp index 36ae3a49827c..22306f6eaa59 100644 --- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp +++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp @@ -19,7 +19,6 @@ // Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -33,6 +32,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; diff --git a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp index 8999000dff8c..00dd1df24948 100644 --- a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp +++ b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp @@ -15,7 +15,6 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Host/Symbols.h" #include "lldb/Interpreter/OptionValueProperties.h" @@ -29,6 +28,7 @@ #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "DynamicLoaderDarwinKernel.h" diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp index c6439a30c8a3..6494b786658d 100644 --- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp +++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp @@ -15,7 +15,6 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Host/FileSystem.h" #include "lldb/Symbol/ClangASTContext.h" @@ -32,6 +31,7 @@ #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN #ifdef ENABLE_DEBUG_PRINTF diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp index 4a8ad38d1785..4d5f6cbe3cd7 100644 --- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp +++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp @@ -12,7 +12,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolVendor.h" @@ -21,6 +20,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "DynamicLoaderDarwin.h" #include "DynamicLoaderMacOS.h" diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp index 265f19d0ca06..561d4e1d2839 100644 --- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp +++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp @@ -13,7 +13,6 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" @@ -27,6 +26,7 @@ #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "DynamicLoaderDarwin.h" #include "DynamicLoaderMacOSXDYLD.h" diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index 0811a7999920..9c2f8c4b6c92 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -17,7 +17,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Expression/Materializer.h" @@ -44,6 +43,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private.h" #include "clang/AST/ASTConsumer.h" diff --git a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp index e3e0ed49181e..b24072940a86 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp +++ b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp @@ -27,7 +27,6 @@ // Project includes #include "lldb/Core/Module.h" -#include "lldb/Core/State.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectList.h" #include "lldb/Expression/IRExecutionUnit.h" @@ -44,6 +43,7 @@ #include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" using namespace lldb_private; diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp index e51c9ee07b9f..bc18d27eeb1d 100644 --- a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp +++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp @@ -25,7 +25,6 @@ #include "clang/AST/ASTContext.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/dwarf.h" #include "lldb/Expression/IRExecutionUnit.h" #include "lldb/Expression/IRInterpreter.h" @@ -36,6 +35,7 @@ #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" #include diff --git a/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/source/Plugins/Instruction/ARM/EmulationStateARM.cpp index d1032f56f31c..d770b3bdc52e 100644 --- a/source/Plugins/Instruction/ARM/EmulationStateARM.cpp +++ b/source/Plugins/Instruction/ARM/EmulationStateARM.cpp @@ -9,12 +9,12 @@ #include "EmulationStateARM.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Interpreter/OptionValueArray.h" #include "lldb/Interpreter/OptionValueDictionary.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StackFrame.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "Utility/ARM_DWARF_Registers.h" diff --git a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp index 2f484ab5ea97..ef0630ee5ab5 100644 --- a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp +++ b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp @@ -13,10 +13,10 @@ #include "lldb/Core/Address.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Stream.h" #include "Plugins/Process/Utility/ARMDefines.h" diff --git a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp index b65747e12890..fe8dbd2bc5b9 100644 --- a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp +++ b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp @@ -14,12 +14,12 @@ #include "lldb/Core/Address.h" #include "lldb/Core/Opcode.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Target/Target.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Stream.h" #include "llvm-c/Disassembler.h" #include "llvm/MC/MCAsmInfo.h" diff --git a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp index 5af12ad141aa..17e284e5423b 100644 --- a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp +++ b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp @@ -14,12 +14,12 @@ #include "lldb/Core/Address.h" #include "lldb/Core/Opcode.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/PosixApi.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Stream.h" #include "llvm-c/Disassembler.h" #include "llvm/MC/MCAsmInfo.h" diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index fc661bbbf2c9..cc00855c1a3d 100644 --- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -14,7 +14,6 @@ #include "lldb/Core/Mangled.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectMemory.h" #include "lldb/Interpreter/CommandObject.h" @@ -32,6 +31,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include diff --git a/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp index 6670f89dde5f..12af4910bcda 100644 --- a/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp +++ b/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp @@ -13,7 +13,6 @@ #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectMemory.h" #include "lldb/Symbol/GoASTContext.h" @@ -28,6 +27,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "llvm/ADT/Twine.h" diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp index fef42c78b24f..af0e90d72c6b 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp @@ -17,7 +17,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Section.h" #include "lldb/Core/ValueObject.h" #include "lldb/Expression/DiagnosticManager.h" @@ -32,6 +31,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp index 5001c0461b3b..dc3955db9a54 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp @@ -17,7 +17,6 @@ #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" #include "lldb/Expression/FunctionCaller.h" #include "lldb/Expression/UtilityFunction.h" #include "lldb/Symbol/ClangASTContext.h" @@ -29,6 +28,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index d217ed3ff325..a808512fb0c8 100644 --- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -28,7 +28,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Section.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Expression/DiagnosticManager.h" @@ -52,6 +51,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp index 4eb15369aa1e..5434be714509 100644 --- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp +++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp @@ -20,7 +20,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/DumpDataExtractor.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/DumpValueObjectOptions.h" #include "lldb/Expression/UserExpression.h" @@ -43,6 +42,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Status.h" diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 91e7f3353270..39b3c644adb3 100644 --- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -23,7 +23,6 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/RangeMap.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Section.h" #include "lldb/Core/StreamFile.h" #include "lldb/Host/Host.h" @@ -41,6 +40,7 @@ #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" diff --git a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp index 3f6083931513..c8cc1511175a 100644 --- a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp +++ b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp @@ -21,7 +21,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Section.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -39,6 +38,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadList.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/StreamString.h" using namespace lldb; diff --git a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp index d6252c473270..0134aed8165f 100644 --- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -20,7 +20,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/ScriptInterpreter.h" @@ -32,6 +31,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadList.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StructuredData.h" diff --git a/source/Plugins/Platform/Android/PlatformAndroid.cpp b/source/Plugins/Platform/Android/PlatformAndroid.cpp index 4477fe371d34..b1252bb94f77 100644 --- a/source/Plugins/Platform/Android/PlatformAndroid.cpp +++ b/source/Plugins/Platform/Android/PlatformAndroid.cpp @@ -9,12 +9,12 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Section.h" #include "lldb/Core/ValueObject.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/StringConvert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/UriParser.h" // Project includes diff --git a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp index bc8111d1078b..c5ca0c85654b 100644 --- a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp +++ b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp @@ -23,12 +23,12 @@ #include "lldb/Breakpoint/BreakpointSite.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" diff --git a/source/Plugins/Platform/Linux/PlatformLinux.cpp b/source/Plugins/Platform/Linux/PlatformLinux.cpp index dbde91d7ab2d..a11c6d8e374b 100644 --- a/source/Plugins/Platform/Linux/PlatformLinux.cpp +++ b/source/Plugins/Platform/Linux/PlatformLinux.cpp @@ -21,12 +21,12 @@ // Project includes #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" diff --git a/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp index 3aa8ecb4c228..2a86c7f8b82b 100644 --- a/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp +++ b/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp @@ -21,12 +21,12 @@ // Project includes #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" diff --git a/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp index 10ca8fbfbdd7..afb4e9d85cd9 100644 --- a/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp +++ b/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp @@ -21,12 +21,12 @@ // Project includes #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp index 3505443abcb0..557de955de82 100644 --- a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp +++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp @@ -19,10 +19,10 @@ // C++ includes // LLDB includes -#include "lldb/Core/State.h" #include "lldb/Host/PseudoTerminal.h" #include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "CFBundle.h" diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp index 3576a7f26f86..8ecb9ae70503 100644 --- a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp +++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp @@ -18,8 +18,8 @@ // C++ Includes // Other libraries and framework includes -#include "lldb/Core/State.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/State.h" // Project includes #include "FreeBSDThread.h" @@ -42,7 +42,6 @@ #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/HostNativeThread.h" @@ -50,6 +49,7 @@ #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Utility/State.h" #include "llvm/ADT/SmallString.h" using namespace lldb; diff --git a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp index fa0bcea8f6bd..eec4933f4f47 100644 --- a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp +++ b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp @@ -24,12 +24,12 @@ // Other libraries and framework includes #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/State.h" #include "FreeBSDThread.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" @@ -44,7 +44,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/DynamicLoader.h" @@ -52,6 +51,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/State.h" #include "lldb/Host/posix/Fcntl.h" diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp index 51fdf2e5ef33..1076aec92e40 100644 --- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp @@ -21,14 +21,14 @@ // C++ Includes // Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Host/Host.h" #include "lldb/Host/PseudoTerminal.h" #include "lldb/Host/ThreadLauncher.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Thread.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "llvm/Support/Errno.h" diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp index 8ddc253aea5d..0642a30ade70 100644 --- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp +++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp @@ -7,9 +7,9 @@ // //===---------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "ProcessFreeBSD.h" #include "ProcessMonitor.h" diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp index 93ffeb5ea79b..b35ee18d6a96 100644 --- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp +++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp @@ -7,9 +7,9 @@ // //===---------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h" #include "ProcessFreeBSD.h" diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp index 734167e1fc98..17df44cf85ee 100644 --- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp +++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h" #include "ProcessFreeBSD.h" diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp index 5cc6cd290629..a8d75963ea6b 100644 --- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp +++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "ProcessFreeBSD.h" #include "ProcessMonitor.h" diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp index 7db7f803b371..68fd5ac13bb0 100644 --- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp +++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/FreeBSD/ProcessFreeBSD.h" #include "Plugins/Process/FreeBSD/ProcessMonitor.h" diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/source/Plugins/Process/Linux/NativeProcessLinux.cpp index 3fb886e1c7a3..b474e12d0718 100644 --- a/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -25,8 +25,6 @@ // Other libraries and framework includes #include "lldb/Core/EmulateInstruction.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostProcess.h" #include "lldb/Host/PseudoTerminal.h" @@ -41,6 +39,8 @@ #include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Target/Target.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StringExtractor.h" #include "llvm/Support/Errno.h" diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp index c8a8355f9cb9..79f635c88985 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp @@ -9,10 +9,10 @@ #include "NativeRegisterContextLinux.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/Host/common/NativeThreadProtocol.h" #include "lldb/Host/linux/Ptrace.h" +#include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/Linux/NativeProcessLinux.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp index 749291684620..09d3a12942f0 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp @@ -15,9 +15,9 @@ #include "Plugins/Process/Linux/Procfs.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp index 41fe446f728c..4a5809698a66 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp @@ -16,10 +16,10 @@ // C++ Includes // Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Linux/NativeProcessLinux.h" diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp index 69194b3c0663..ea51048a423a 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp @@ -21,12 +21,12 @@ #include "Plugins/Process/Utility/RegisterContextLinux_mips.h" #include "Plugins/Process/Utility/RegisterContextLinux_mips64.h" #include "lldb/Core/EmulateInstruction.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-private-enumerations.h" diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp index 6aa4af64ab51..da51fda1c80b 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp @@ -14,10 +14,10 @@ #include "NativeRegisterContextLinux_ppc64le.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Linux/NativeProcessLinux.h" diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp index 36da2b001054..1bc916b69bcd 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp @@ -11,10 +11,10 @@ #include "NativeRegisterContextLinux_s390x.h" #include "Plugins/Process/Linux/NativeProcessLinux.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Utility/RegisterContextLinux_s390x.h" diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp index 87f4b8da053e..50bf29b094df 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp @@ -11,10 +11,10 @@ #include "NativeRegisterContextLinux_x86_64.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/source/Plugins/Process/Linux/NativeThreadLinux.cpp index 4ab2a9ae6245..b64689c9d17b 100644 --- a/source/Plugins/Process/Linux/NativeThreadLinux.cpp +++ b/source/Plugins/Process/Linux/NativeThreadLinux.cpp @@ -16,12 +16,12 @@ #include "NativeRegisterContextLinux.h" #include "SingleStepCheck.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostNativeThread.h" #include "lldb/Host/linux/Ptrace.h" #include "lldb/Host/linux/Support.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/lldb-enumerations.h" #include "llvm/ADT/SmallString.h" diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp index 116155d9a232..ff6bc575fc7e 100644 --- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp +++ b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp @@ -18,13 +18,13 @@ // Other libraries and framework includes #include "lldb/Core/DumpDataExtractor.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Target/Process.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/UUID.h" // Project includes diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp index 2e707ab2e363..c9ec685e541d 100644 --- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp @@ -19,8 +19,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" -#include "lldb/Utility/UUID.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Host.h" #include "lldb/Host/Symbols.h" @@ -37,7 +35,9 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StringExtractor.h" +#include "lldb/Utility/UUID.h" #include "llvm/Support/Threading.h" diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp index 7fca0fc24fdb..b1caba089674 100644 --- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp +++ b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp @@ -12,7 +12,6 @@ #include "lldb/Utility/SafeMachO.h" #include "lldb/Breakpoint/Watchpoint.h" -#include "lldb/Core/State.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" @@ -20,6 +19,7 @@ #include "lldb/Target/Unwind.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "Plugins/Process/Utility/StopInfoMachException.h" diff --git a/source/Plugins/Process/NetBSD/CMakeLists.txt b/source/Plugins/Process/NetBSD/CMakeLists.txt index 92a6014ced07..e131e6d70468 100644 --- a/source/Plugins/Process/NetBSD/CMakeLists.txt +++ b/source/Plugins/Process/NetBSD/CMakeLists.txt @@ -5,7 +5,6 @@ add_lldb_library(lldbPluginProcessNetBSD PLUGIN NativeThreadNetBSD.cpp LINK_LIBS - lldbCore lldbHost lldbSymbol lldbTarget diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp index 1a4cb21d000e..54d2e8b552fd 100644 --- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp +++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp @@ -15,12 +15,12 @@ // Other libraries and framework includes #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostProcess.h" #include "lldb/Host/common/NativeBreakpoint.h" #include "lldb/Host/common/NativeRegisterContext.h" #include "lldb/Host/posix/ProcessLauncherPosixFork.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/State.h" #include "llvm/Support/Errno.h" // System includes - They have to be included after framework includes because diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp index 16b6f2c52dd5..78da3527122f 100644 --- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp +++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp @@ -11,10 +11,10 @@ #include "NativeRegisterContextNetBSD_x86_64.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h" diff --git a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp index 83f1da78d01d..6f5d1120e40d 100644 --- a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp +++ b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp @@ -14,9 +14,9 @@ #include "Plugins/Process/POSIX/CrashReason.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/State.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/State.h" #include diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp index 5d9ff02fafdd..210374f4257d 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp @@ -12,12 +12,12 @@ // C++ Includes // Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "Plugins/Process/Utility/InstructionUtils.h" diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp index 03ce7ef9f524..bcc3568715be 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp @@ -13,14 +13,14 @@ // C++ Includes // Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp index 24414211d9aa..466a83bdce77 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp @@ -12,12 +12,12 @@ // C++ Includes // Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp index ecad8240b294..a4619bba27d6 100644 --- a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp +++ b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp @@ -14,12 +14,12 @@ // C++ Includes // Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" diff --git a/source/Plugins/Process/Utility/RegisterContextDummy.cpp b/source/Plugins/Process/Utility/RegisterContextDummy.cpp index dd6ca92a74ee..c51c30f45a5d 100644 --- a/source/Plugins/Process/Utility/RegisterContextDummy.cpp +++ b/source/Plugins/Process/Utility/RegisterContextDummy.cpp @@ -11,7 +11,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/AddressRange.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/FuncUnwinders.h" @@ -28,6 +27,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/lldb-private.h" #include "RegisterContextDummy.h" diff --git a/source/Plugins/Process/Utility/RegisterContextHistory.cpp b/source/Plugins/Process/Utility/RegisterContextHistory.cpp index cc0d696b338a..c9b77663a803 100644 --- a/source/Plugins/Process/Utility/RegisterContextHistory.cpp +++ b/source/Plugins/Process/Utility/RegisterContextHistory.cpp @@ -11,7 +11,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/AddressRange.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/FuncUnwinders.h" @@ -28,6 +27,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/lldb-private.h" #include "RegisterContextHistory.h" diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index ba9a8071bcfb..664f325c03dd 100644 --- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -10,7 +10,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/AddressRange.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/ArmUnwindInfo.h" @@ -31,6 +30,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/lldb-private.h" #include "RegisterContextLLDB.h" diff --git a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp index 77c1bea34851..e90a7b49d795 100644 --- a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp +++ b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp @@ -12,11 +12,11 @@ // C Includes // C++ Includes // Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" // Project includes #include "lldb/Utility/StringExtractorGDBRemote.h" diff --git a/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/source/Plugins/Process/Utility/RegisterContextMemory.cpp index 76189ea781de..986328d8e474 100644 --- a/source/Plugins/Process/Utility/RegisterContextMemory.cpp +++ b/source/Plugins/Process/Utility/RegisterContextMemory.cpp @@ -14,10 +14,10 @@ // Other libraries and framework includes // Project includes #include "DynamicRegisterInfo.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp index 352e251e3b64..b0e53cfcc91f 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp @@ -11,14 +11,14 @@ #include #include -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_arm.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp index 3ff93cde2347..8b00dfc81eab 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp @@ -11,14 +11,14 @@ #include #include -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_arm64.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp index 98d1e6fa8817..9270d09f7293 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp @@ -11,14 +11,14 @@ #include #include -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_mips64.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp index 9f0552539723..47a8e2c3f9e9 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp @@ -12,14 +12,14 @@ #include #include -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_powerpc.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp index 41ae5ec6b51a..ef221c963dc4 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp @@ -11,14 +11,14 @@ #include #include -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_ppc64le.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp index 662ac38405ef..24f131099be4 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp @@ -11,14 +11,14 @@ #include #include -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_s390x.h" diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp index d2a06e1b7897..b846b447809f 100644 --- a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp +++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp @@ -11,14 +11,14 @@ #include #include -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_x86.h" diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp index b14081f76617..18e3b76da942 100644 --- a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp +++ b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp @@ -18,7 +18,6 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostNativeProcessBase.h" #include "lldb/Host/HostProcess.h" #include "lldb/Host/windows/HostThreadWindows.h" @@ -28,6 +27,7 @@ #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/State.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Format.h" diff --git a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp index 3903280918cc..b121dc7bf15e 100644 --- a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp +++ b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/State.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/HostNativeThreadBase.h" #include "lldb/Host/windows/HostThreadWindows.h" @@ -15,6 +14,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" +#include "lldb/Utility/State.h" #include "Plugins/Process/Utility/UnwindLLDB.h" #include "ProcessWindows.h" diff --git a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp index 4aa6c785f83c..6605151d776f 100644 --- a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp +++ b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/windows/HostThreadWindows.h" #include "lldb/Host/windows/windows.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private-types.h" diff --git a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp index fd486f3d0829..e012f9105f31 100644 --- a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp +++ b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/windows/HostThreadWindows.h" #include "lldb/Host/windows/windows.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private-types.h" diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 7bb7b72eaac1..8597a8b30ce6 100644 --- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -18,7 +18,6 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Target.h" @@ -26,6 +25,7 @@ #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/Support/Threading.h" diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp index 0d683153d9ed..80c6c0207a1e 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp @@ -9,8 +9,8 @@ #include "RegisterContextPOSIXCore_arm.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp index 919f8901d39a..017646b44b5c 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp @@ -9,8 +9,8 @@ #include "RegisterContextPOSIXCore_arm64.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp index 532a1f5c0831..beeb9b666ccd 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp @@ -9,8 +9,8 @@ #include "RegisterContextPOSIXCore_mips64.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp index 8670e341a277..d4f86b354784 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp @@ -9,9 +9,9 @@ #include "RegisterContextPOSIXCore_powerpc.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp index 2237e72353ac..8116a1c7ea57 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp @@ -9,9 +9,9 @@ #include "RegisterContextPOSIXCore_ppc64le.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp index f0edbf1ea854..875bb1647281 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp @@ -9,9 +9,9 @@ #include "RegisterContextPOSIXCore_s390x.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp index a1f26d52444b..27295492f43d 100644 --- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp +++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp @@ -8,9 +8,9 @@ //===----------------------------------------------------------------------===// #include "RegisterContextPOSIXCore_x86_64.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index c8b59d5d236b..919a9c4ed115 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -19,7 +19,6 @@ // Other libraries and framework includes #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/XML.h" #include "lldb/Symbol/Symbol.h" @@ -31,6 +30,7 @@ #include "lldb/Utility/JSON.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" // Project includes diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index 50392fa38956..618f980f3dd6 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -21,8 +21,6 @@ #include // Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/State.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Debug.h" #include "lldb/Host/File.h" @@ -41,6 +39,8 @@ #include "lldb/Utility/JSON.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/UriParser.h" #include "llvm/ADT/Triple.h" diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index 07dab751f4b9..8b042e1d470b 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -12,12 +12,12 @@ // C Includes // C++ Includes // Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" // Project includes #include "ProcessGDBRemote.h" diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index b3d33b19bd66..4950148ccc1f 100644 --- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -34,7 +34,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" #include "lldb/DataFormatters/FormatManager.h" @@ -68,6 +67,7 @@ #include "lldb/Utility/Args.h" #include "lldb/Utility/CleanUp.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index a525c16b9f13..36a2cffec3bc 100644 --- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -10,7 +10,6 @@ #include "ThreadGDBRemote.h" #include "lldb/Breakpoint/Watchpoint.h" -#include "lldb/Core/State.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -20,6 +19,7 @@ #include "lldb/Target/UnixSignals.h" #include "lldb/Target/Unwind.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "ProcessGDBRemote.h" diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/source/Plugins/Process/mach-core/ProcessMachCore.cpp index bfa35ed506a9..1f1f5e5bb305 100644 --- a/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -23,7 +23,6 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/MemoryRegionInfo.h" @@ -32,6 +31,7 @@ #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" // Project includes #include "ProcessMachCore.h" diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/source/Plugins/Process/mach-core/ThreadMachCore.cpp index c262dd47f978..6898f53bef31 100644 --- a/source/Plugins/Process/mach-core/ThreadMachCore.cpp +++ b/source/Plugins/Process/mach-core/ThreadMachCore.cpp @@ -12,7 +12,6 @@ #include "lldb/Utility/SafeMachO.h" #include "lldb/Breakpoint/Watchpoint.h" -#include "lldb/Core/State.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -21,6 +20,7 @@ #include "lldb/Target/Unwind.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "ProcessMachCore.h" diff --git a/source/Plugins/Process/minidump/ProcessMinidump.cpp b/source/Plugins/Process/minidump/ProcessMinidump.cpp index 7af6301b7f1a..86ee2122a976 100644 --- a/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -16,7 +16,6 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/SectionLoadList.h" @@ -25,6 +24,7 @@ #include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Threading.h" diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp index 5e7bc7a36ef9..0b4230d01fc7 100644 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp @@ -12,7 +12,7 @@ // Other libraries and framework includes #include "Utility/ARM_DWARF_Registers.h" -#include "lldb/Core/RegisterValue.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/lldb-enumerations.h" diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp index 29800747a0b5..2d461ca18789 100644 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp @@ -12,7 +12,7 @@ // Other libraries and framework includes #include "Utility/ARM64_DWARF_Registers.h" -#include "lldb/Core/RegisterValue.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/lldb-enumerations.h" diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index ac320ac52b08..08514c1354e9 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -17,12 +17,12 @@ #include "lldb/Core/ModuleList.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Section.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" diff --git a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h index e587c93b427c..af7def8f50bf 100644 --- a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h +++ b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h @@ -15,9 +15,9 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/EmulateInstruction.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Target/UnwindAssembly.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/lldb-private.h" class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly { diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp index 95e7f8a68d44..9f6ddcd156b5 100644 --- a/source/Symbol/ClangASTContext.cpp +++ b/source/Symbol/ClangASTContext.cpp @@ -76,7 +76,6 @@ #include "lldb/Core/DumpDataExtractor.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/ThreadSafeDenseMap.h" #include "lldb/Core/UniqueCStringMap.h" @@ -97,6 +96,7 @@ #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Scalar.h" #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h" #include "Plugins/SymbolFile/PDB/PDBASTParser.h" diff --git a/source/Symbol/CompilerType.cpp b/source/Symbol/CompilerType.cpp index 2dd1d3ebd04b..adb798247947 100644 --- a/source/Symbol/CompilerType.cpp +++ b/source/Symbol/CompilerType.cpp @@ -10,7 +10,6 @@ #include "lldb/Symbol/CompilerType.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/StreamFile.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ClangExternalASTSourceCommon.h" @@ -20,6 +19,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" diff --git a/source/Symbol/Type.cpp b/source/Symbol/Type.cpp index b62c55f76e2b..6d7ec43710f6 100644 --- a/source/Symbol/Type.cpp +++ b/source/Symbol/Type.cpp @@ -14,9 +14,9 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/Module.h" -#include "lldb/Core/Scalar.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" #include "lldb/Symbol/CompilerType.h" diff --git a/source/Target/ExecutionContext.cpp b/source/Target/ExecutionContext.cpp index 73c64916cf1f..44cd811a60f1 100644 --- a/source/Target/ExecutionContext.cpp +++ b/source/Target/ExecutionContext.cpp @@ -12,12 +12,12 @@ // Other libraries and framework includes // Project includes #include "lldb/Target/ExecutionContext.h" -#include "lldb/Core/State.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/State.h" using namespace lldb_private; diff --git a/source/Target/Memory.cpp b/source/Target/Memory.cpp index ad1b4093155d..e946d3295f62 100644 --- a/source/Target/Memory.cpp +++ b/source/Target/Memory.cpp @@ -14,10 +14,10 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/RangeMap.h" -#include "lldb/Core/State.h" #include "lldb/Target/Process.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp index c3d8abc9f78d..48888bbc1e26 100644 --- a/source/Target/Process.cpp +++ b/source/Target/Process.cpp @@ -25,7 +25,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/IRDynamicChecks.h" @@ -70,6 +69,7 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/SelectHelper.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Target/RegisterContext.cpp b/source/Target/RegisterContext.cpp index eaec03d9b595..9a84f707ec68 100644 --- a/source/Target/RegisterContext.cpp +++ b/source/Target/RegisterContext.cpp @@ -13,8 +13,6 @@ // Project includes #include "lldb/Target/RegisterContext.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Target/ExecutionContext.h" @@ -24,6 +22,8 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Target/StackFrame.cpp b/source/Target/StackFrame.cpp index 2b9260f95f3f..ce7aa0e68483 100644 --- a/source/Target/StackFrame.cpp +++ b/source/Target/StackFrame.cpp @@ -17,7 +17,6 @@ #include "lldb/Core/FormatEntity.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -34,6 +33,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp index a98495d17449..d0d447609abc 100644 --- a/source/Target/Target.cpp +++ b/source/Target/Target.cpp @@ -29,7 +29,6 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" #include "lldb/Core/SourceManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/ValueObject.h" #include "lldb/Expression/REPL.h" @@ -58,6 +57,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" diff --git a/source/Target/TargetList.cpp b/source/Target/TargetList.cpp index b9c852b414e2..2c9f5418e97c 100644 --- a/source/Target/TargetList.cpp +++ b/source/Target/TargetList.cpp @@ -14,7 +14,6 @@ #include "lldb/Core/Event.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -22,6 +21,7 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/TildeExpressionResolver.h" #include "lldb/Utility/Timer.h" diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp index 5ac1de7ae01b..7fbad420700c 100644 --- a/source/Target/Thread.cpp +++ b/source/Target/Thread.cpp @@ -18,7 +18,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/FormatEntity.h" #include "lldb/Core/Module.h" -#include "lldb/Core/State.h" #include "lldb/Core/ValueObject.h" #include "lldb/Host/Host.h" #include "lldb/Interpreter/OptionValueFileSpecList.h" @@ -49,6 +48,7 @@ #include "lldb/Target/Unwind.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "lldb/lldb-enumerations.h" diff --git a/source/Target/ThreadList.cpp b/source/Target/ThreadList.cpp index ee57a401f742..5ca743d67383 100644 --- a/source/Target/ThreadList.cpp +++ b/source/Target/ThreadList.cpp @@ -15,7 +15,6 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/State.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Thread.h" @@ -23,6 +22,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Target/ThreadPlan.cpp b/source/Target/ThreadPlan.cpp index 31ee1e922494..7aa4b4734c89 100644 --- a/source/Target/ThreadPlan.cpp +++ b/source/Target/ThreadPlan.cpp @@ -13,12 +13,12 @@ // Project includes #include "lldb/Target/ThreadPlan.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/State.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Target/ThreadPlanPython.cpp b/source/Target/ThreadPlanPython.cpp index 7796b8a0ab20..39e607341a79 100644 --- a/source/Target/ThreadPlanPython.cpp +++ b/source/Target/ThreadPlanPython.cpp @@ -14,7 +14,6 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/Debugger.h" -#include "lldb/Core/State.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Target/Process.h" @@ -24,6 +23,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanPython.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Target/ThreadPlanTracer.cpp b/source/Target/ThreadPlanTracer.cpp index acbbd4d8bcc2..0b99650dd5d5 100644 --- a/source/Target/ThreadPlanTracer.cpp +++ b/source/Target/ThreadPlanTracer.cpp @@ -15,7 +15,6 @@ #include "lldb/Core/Disassembler.h" #include "lldb/Core/DumpRegisterValue.h" #include "lldb/Core/Module.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" #include "lldb/Symbol/TypeList.h" @@ -30,6 +29,7 @@ #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Utility/CMakeLists.txt b/source/Utility/CMakeLists.txt index 91f3c8773731..eed72f0c26e6 100644 --- a/source/Utility/CMakeLists.txt +++ b/source/Utility/CMakeLists.txt @@ -60,9 +60,12 @@ add_lldb_library(lldbUtility Logging.cpp NameMatches.cpp Range.cpp + RegisterValue.cpp RegularExpression.cpp + Scalar.cpp SelectHelper.cpp SharingPtr.cpp + State.cpp Status.cpp Stream.cpp StreamCallback.cpp diff --git a/source/Core/RegisterValue.cpp b/source/Utility/RegisterValue.cpp similarity index 99% rename from source/Core/RegisterValue.cpp rename to source/Utility/RegisterValue.cpp index 4f908609dde9..44dfead124db 100644 --- a/source/Core/RegisterValue.cpp +++ b/source/Utility/RegisterValue.cpp @@ -7,11 +7,11 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" +#include "lldb/Utility/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" diff --git a/source/Core/Scalar.cpp b/source/Utility/Scalar.cpp similarity index 99% rename from source/Core/Scalar.cpp rename to source/Utility/Scalar.cpp index 6a7186969ef2..aba9acb0cadd 100644 --- a/source/Core/Scalar.cpp +++ b/source/Utility/Scalar.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/Scalar.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" @@ -38,7 +38,7 @@ static Scalar::Type PromoteToMaxType( const Scalar *&promoted_rhs_ptr // Pointer to the resulting possibly // promoted value of rhs (at most one of // lhs/rhs will get promoted) - ) { +) { Scalar result; // Initialize the promoted values for both the right and left hand side // values to be the objects themselves. If no promotion is needed (both right diff --git a/source/Core/State.cpp b/source/Utility/State.cpp similarity index 98% rename from source/Core/State.cpp rename to source/Utility/State.cpp index 4697ca4b5f17..9ee2d04a22bd 100644 --- a/source/Core/State.cpp +++ b/source/Utility/State.cpp @@ -11,7 +11,7 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Core/State.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; diff --git a/unittests/Core/CMakeLists.txt b/unittests/Core/CMakeLists.txt index 039b8afdf75a..f435b2785405 100644 --- a/unittests/Core/CMakeLists.txt +++ b/unittests/Core/CMakeLists.txt @@ -5,7 +5,6 @@ add_lldb_unittest(LLDBCoreTests ListenerTest.cpp MangledTest.cpp ScalarTest.cpp - StateTest.cpp StreamCallbackTest.cpp LINK_LIBS diff --git a/unittests/Core/ScalarTest.cpp b/unittests/Core/ScalarTest.cpp index 9c241c26e66c..4f995c047b48 100644 --- a/unittests/Core/ScalarTest.cpp +++ b/unittests/Core/ScalarTest.cpp @@ -9,9 +9,9 @@ #include "gtest/gtest.h" -#include "lldb/Core/Scalar.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" #include "llvm/Testing/Support/Error.h" diff --git a/unittests/Utility/CMakeLists.txt b/unittests/Utility/CMakeLists.txt index 01d24d5d3d25..5bfd9a5b3e61 100644 --- a/unittests/Utility/CMakeLists.txt +++ b/unittests/Utility/CMakeLists.txt @@ -12,6 +12,8 @@ add_lldb_unittest(UtilityTests JSONTest.cpp LogTest.cpp NameMatchesTest.cpp + RegisterValueTest.cpp + StateTest.cpp StatusTest.cpp StreamTeeTest.cpp StreamTest.cpp diff --git a/unittests/Utility/RegisterValueTest.cpp b/unittests/Utility/RegisterValueTest.cpp new file mode 100644 index 000000000000..711bbcb965e6 --- /dev/null +++ b/unittests/Utility/RegisterValueTest.cpp @@ -0,0 +1,23 @@ +//===-- RegisterValueTest.cpp -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/RegisterValue.h" +#include "gtest/gtest.h" + +using namespace lldb_private; + +TEST(RegisterValueTest, GetSet8) { + RegisterValue R8(uint8_t(47)); + EXPECT_EQ(47u, R8.GetAsUInt8()); + R8 = uint8_t(42); + EXPECT_EQ(42u, R8.GetAsUInt8()); + EXPECT_EQ(42u, R8.GetAsUInt16()); + EXPECT_EQ(42u, R8.GetAsUInt32()); + EXPECT_EQ(42u, R8.GetAsUInt64()); +} diff --git a/unittests/Core/StateTest.cpp b/unittests/Utility/StateTest.cpp similarity index 95% rename from unittests/Core/StateTest.cpp rename to unittests/Utility/StateTest.cpp index 76cdaac82055..8d5665aca6c0 100644 --- a/unittests/Core/StateTest.cpp +++ b/unittests/Utility/StateTest.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/State.h" +#include "lldb/Utility/State.h" #include "llvm/Support/FormatVariadic.h" #include "gtest/gtest.h" diff --git a/unittests/tools/lldb-server/tests/MessageObjects.h b/unittests/tools/lldb-server/tests/MessageObjects.h index ac090c6d7f32..e8d5ba94580e 100644 --- a/unittests/tools/lldb-server/tests/MessageObjects.h +++ b/unittests/tools/lldb-server/tests/MessageObjects.h @@ -10,8 +10,8 @@ #ifndef LLDB_SERVER_TESTS_MESSAGEOBJECTS_H #define LLDB_SERVER_TESTS_MESSAGEOBJECTS_H -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/Host.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/StructuredData.h" #include "lldb/lldb-types.h" #include "llvm/ADT/DenseMap.h" From 035f8a3fd19c5ddf2defd6d187a57919c71d69ef Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Tue, 7 Aug 2018 12:16:49 +0000 Subject: [PATCH 0067/1112] Fix a couple of extended-offsetof warnings that had slipped through git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339130 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Process/minidump/RegisterContextMinidump_ARM64.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp index 2d461ca18789..84f13b52c646 100644 --- a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp +++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp @@ -313,7 +313,7 @@ static RegisterInfo g_reg_infos[] = { {"fp", "x29", 8, - OFFSET(x[29]), + OFFSET(x) + 29 * 8, eEncodingUint, eFormatHex, {INV, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, INV, reg_fp}, @@ -324,7 +324,7 @@ static RegisterInfo g_reg_infos[] = { {"lr", "x30", 8, - OFFSET(x[30]), + OFFSET(x) + 30 * 8, eEncodingUint, eFormatHex, {INV, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, @@ -335,7 +335,7 @@ static RegisterInfo g_reg_infos[] = { {"sp", "x31", 8, - OFFSET(x[31]), + OFFSET(x) + 31 * 8, eEncodingUint, eFormatHex, {INV, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, From b3d3cee97d06efbe1c94bc623320bd85d603e2a0 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Tue, 7 Aug 2018 13:10:16 +0000 Subject: [PATCH 0068/1112] Move ScalarTest to follow the class being tested This should have been a part of r339127, but I missed it somehow. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339136 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/Core/CMakeLists.txt | 2 -- unittests/Utility/CMakeLists.txt | 2 ++ unittests/{Core => Utility}/ScalarTest.cpp | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename unittests/{Core => Utility}/ScalarTest.cpp (100%) diff --git a/unittests/Core/CMakeLists.txt b/unittests/Core/CMakeLists.txt index f435b2785405..f34df10eda88 100644 --- a/unittests/Core/CMakeLists.txt +++ b/unittests/Core/CMakeLists.txt @@ -4,7 +4,6 @@ add_lldb_unittest(LLDBCoreTests EventTest.cpp ListenerTest.cpp MangledTest.cpp - ScalarTest.cpp StreamCallbackTest.cpp LINK_LIBS @@ -14,7 +13,6 @@ add_lldb_unittest(LLDBCoreTests lldbPluginObjectFileELF lldbPluginSymbolVendorELF lldbUtilityHelpers - LLVMTestingSupport LINK_COMPONENTS Support ) diff --git a/unittests/Utility/CMakeLists.txt b/unittests/Utility/CMakeLists.txt index 5bfd9a5b3e61..877f891ef71a 100644 --- a/unittests/Utility/CMakeLists.txt +++ b/unittests/Utility/CMakeLists.txt @@ -13,6 +13,7 @@ add_lldb_unittest(UtilityTests LogTest.cpp NameMatchesTest.cpp RegisterValueTest.cpp + ScalarTest.cpp StateTest.cpp StatusTest.cpp StreamTeeTest.cpp @@ -31,6 +32,7 @@ add_lldb_unittest(UtilityTests LINK_LIBS lldbUtility lldbUtilityHelpers + LLVMTestingSupport LINK_COMPONENTS Support ) diff --git a/unittests/Core/ScalarTest.cpp b/unittests/Utility/ScalarTest.cpp similarity index 100% rename from unittests/Core/ScalarTest.cpp rename to unittests/Utility/ScalarTest.cpp From 30f4e4d63d264356d5b8c75491002725ad862288 Mon Sep 17 00:00:00 2001 From: Tatyana Krasnukha Date: Tue, 7 Aug 2018 16:46:11 +0000 Subject: [PATCH 0069/1112] Check result after setting PC value. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339153 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Commands/CommandObjectTarget.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp index 4ef3fdd545ad..60c80904ad70 100644 --- a/source/Commands/CommandObjectTarget.cpp +++ b/source/Commands/CommandObjectTarget.cpp @@ -2740,10 +2740,15 @@ class CommandObjectTargetModulesLoad } if (set_pc) { ThreadList &thread_list = process->GetThreadList(); - ThreadSP curr_thread(thread_list.GetSelectedThread()); RegisterContextSP reg_context( - curr_thread->GetRegisterContext()); - reg_context->SetPC(file_entry.GetLoadAddress(target)); + thread_list.GetSelectedThread()->GetRegisterContext()); + addr_t file_entry_addr = file_entry.GetLoadAddress(target); + if (!reg_context->SetPC(file_entry_addr)) { + result.AppendErrorWithFormat("failed to set PC value to " + "0x%" PRIx64 "\n", + file_entry_addr); + result.SetStatus(eReturnStatusFailed); + } } } } else { From 8b0fcb3c32f631910fbdb23d295e96ac7078f35e Mon Sep 17 00:00:00 2001 From: Alex Langford Date: Tue, 7 Aug 2018 17:34:13 +0000 Subject: [PATCH 0070/1112] Add instructions for building LLDB on Mac OS X with CMake Summary: There were previously no instructions for building LLDB on Mac OS X with CMake. It's sufficiently close to building on Linux/FreeBSD/NetBSD that a well-motivated developer could figure out the steps themselves. However, having an explicit guide is better and can provide Mac OS X specific configurations (e.g. LLDB_BUILD_FRAMEWORK). Reviewers: labath, clayborg Subscribers: emaste, krytarowski Differential Revision: https://reviews.llvm.org/D50362 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339155 91177308-0d34-0410-b5e6-96231b3b80d8 --- www/build.html | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/www/build.html b/www/build.html index fd35b5116ba6..62a758f7b6a8 100755 --- a/www/build.html +++ b/www/build.html @@ -143,7 +143,7 @@

Working with both Ninja and MSVC

Building LLDB on Mac OS X

-

Building on Mac OS X is as easy as downloading the code and building the Xcode project or workspace:

+

There are two ways to build LLDB on Mac OS X: Using Xcode and using CMake

Preliminaries

@@ -151,13 +151,34 @@

Preliminaries

  • XCode 4.3 or newer requires the "Command Line Tools" component (XCode->Preferences->Downloads->Components).
  • Mac OS X Lion or newer requires installing Swig.
  • -

    Building LLDB

    +

    Building LLDB with Xcode

    +

    Building on Mac OS X with Xcode is as easy as downloading the code and building the Xcode project or workspace:

    • Download the lldb sources.
    • Follow the code signing instructions in lldb/docs/code-signing.txt
    • In Xcode 3.x: lldb/lldb.xcodeproj, select the lldb-tool target, and build.
    • In Xcode 4.x: lldb/lldb.xcworkspace, select the lldb-tool scheme, and build.
    +

    Building LLDB with CMake

    +

    First download the LLVM, Clang, and LLDB sources. Refer to this page for precise instructions on this step.

    +

    Refer to the code signing instructions in lldb/docs/code-signing.txt for info on codesigning debugserver during the build.

    +

    Using CMake is documented on the Building LLVM with CMake page. + Ninja is the recommended generator to use when building LLDB with CMake.

    + + > cmake $PATH_TO_LLVM -G Ninja +
    > ninja lldb +
    +

    + As noted in the "Building LLVM with CMake" page mentioned above, you can pass + variables to cmake to change build behavior. If LLDB is built as a part of LLVM, + then you can pass LLVM-specific CMake variables to cmake when building LLDB. +

    +

    Here are some commonly used LLDB-specific CMake variables:

    +
      +
    • LLDB_EXPORT_ALL_SYMBOLS:BOOL : Exports all symbols. Useful in conjunction with CMAKE_BUILD_TYPE=Debug.
    • +
    • LLDB_BUILD_FRAMEWORK:BOOL : Builds LLDB.framework as Xcode would
    • +
    • LLDB_CODESIGN_IDENTITY:STRING : Determines the codesign identity to use. An empty string means skip building debugserver to avoid codesigning.
    • +
    From cafa3f4ad0df661d2325b5bb72e49a500eef5429 Mon Sep 17 00:00:00 2001 From: Alexander Polyakov Date: Tue, 7 Aug 2018 17:55:26 +0000 Subject: [PATCH 0071/1112] [lldb-mi] Re-implement MI HandleProcessEventStateSuspended. Summary: Now this function uses SB API instead of HandleCommand. Reviewers: aprantl, clayborg, labath Reviewed By: aprantl Subscribers: ki.stfu, lldb-commits Differential Revision: https://reviews.llvm.org/D49632 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339160 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp index dceb29f5908f..865a139e6e8e 100644 --- a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp +++ b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp @@ -950,6 +950,7 @@ bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged( bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateSuspended( const lldb::SBEvent &vEvent) { bool bOk = MIstatus::success; + lldb::SBStream streamOut; lldb::SBDebugger &rDebugger = CMICmnLLDBDebugSessionInfo::Instance().GetDebugger(); lldb::SBProcess sbProcess = @@ -958,16 +959,17 @@ bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateSuspended( if (rDebugger.GetSelectedTarget() == target) { if (!UpdateSelectedThread()) return MIstatus::failure; - - lldb::SBCommandReturnObject result; - const lldb::ReturnStatus status = - rDebugger.GetCommandInterpreter().HandleCommand("process status", - result, false); - MIunused(status); - bOk = TextToStderr(result.GetError()); - bOk = bOk && TextToStdout(result.GetOutput()); + sbProcess.GetDescription(streamOut); + // Add a delimiter between process' and threads' info. + streamOut.Printf("\n"); + for (uint32_t i = 0, e = sbProcess.GetNumThreads(); i < e; ++i) { + const lldb::SBThread thread = sbProcess.GetThreadAtIndex(i); + if (!thread.IsValid()) + continue; + thread.GetDescription(streamOut); + } + bOk = TextToStdout(streamOut.GetData()); } else { - lldb::SBStream streamOut; const MIuint nTargetIndex = rDebugger.GetIndexOfTarget(target); if (nTargetIndex != UINT_MAX) streamOut.Printf("Target %d: (", nTargetIndex); From 56e792dbe2446785d1acfcb0ae02dcdc7ce2a0c1 Mon Sep 17 00:00:00 2001 From: Leonard Mosescu Date: Tue, 7 Aug 2018 18:00:30 +0000 Subject: [PATCH 0072/1112] Misc module/dwarf logging improvements This change improves the logging for the lldb.module category to note a few interesting cases: 1. Local object file found, but specs not matching 2. Local object file not found, using a placeholder module The handling and logging for the cases wehre we fail to load compressed dwarf symbols is also improved. Differential Revision: https://reviews.llvm.org/D50274 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339161 91177308-0d34-0410-b5e6-96231b3b80d8 --- lit/Modules/compressed-sections.yaml | 3 +- source/Core/Module.cpp | 8 +++-- .../Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 29 +++++++++++-------- .../Process/minidump/ProcessMinidump.cpp | 6 ++++ source/Target/Process.cpp | 6 ++-- 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/lit/Modules/compressed-sections.yaml b/lit/Modules/compressed-sections.yaml index c75dc857522a..3a0805c06d64 100644 --- a/lit/Modules/compressed-sections.yaml +++ b/lit/Modules/compressed-sections.yaml @@ -28,5 +28,4 @@ Sections: # CHECK-NEXT: Type: regular # CHECK-NEXT: VM size: 0 # CHECK-NEXT: File size: 8 -# CHECK-NEXT: Data: -# CHECK-NEXT: DEADBEEF BAADF00D +# CHECK-NEXT: Data: () diff --git a/source/Core/Module.cpp b/source/Core/Module.cpp index 3b1a4fd7be0f..b078cd30aeab 100644 --- a/source/Core/Module.cpp +++ b/source/Core/Module.cpp @@ -162,9 +162,13 @@ Module::Module(const ModuleSpec &module_spec) // fill any ivars in so we don't accidentally grab the wrong file later since // they don't match... ModuleSpec matching_module_spec; - if (modules_specs.FindMatchingModuleSpec(module_spec, matching_module_spec) == - 0) + if (!modules_specs.FindMatchingModuleSpec(module_spec, + matching_module_spec)) { + if (log) { + log->Printf("Found local object file but the specs didn't match"); + } return; + } if (module_spec.GetFileSpec()) m_mod_time = FileSystem::GetModificationTime(module_spec.GetFileSpec()); diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 8701908378f1..6a81746ffe4b 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -1390,7 +1390,7 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) // In case of MIPSR6, the LLDB_NT_OWNER_GNU note is missing for some // cases (e.g. compile with -nostdlib) Hence set OS to Linux - arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); + arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); } } @@ -1494,7 +1494,7 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, const uint32_t sub_type = subTypeFromElfHeader(header); arch_spec.SetArchitecture(eArchTypeELF, header.e_machine, sub_type, header.e_ident[EI_OSABI]); - + // Validate if it is ok to remove GetOsFromOSABI. Note, that now the OS is // determined based on EI_OSABI flag and the info extracted from ELF notes // (see RefineModuleDetailsFromNote). However in some cases that still @@ -3385,8 +3385,6 @@ size_t ObjectFileELF::ReadSectionData(Section *section, if (section->GetObjectFile() != this) return section->GetObjectFile()->ReadSectionData(section, section_data); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES); - size_t result = ObjectFile::ReadSectionData(section, section_data); if (result == 0 || !section->Test(SHF_COMPRESSED)) return result; @@ -3397,20 +3395,27 @@ size_t ObjectFileELF::ReadSectionData(Section *section, size_t(section_data.GetByteSize())}, GetByteOrder() == eByteOrderLittle, GetAddressByteSize() == 8); if (!Decompressor) { - LLDB_LOG_ERROR(log, Decompressor.takeError(), - "Unable to initialize decompressor for section {0}", - section->GetName()); - return result; + GetModule()->ReportWarning( + "Unable to initialize decompressor for section '%s': %s", + section->GetName().GetCString(), + llvm::toString(Decompressor.takeError()).c_str()); + section_data.Clear(); + return 0; } + auto buffer_sp = std::make_shared(Decompressor->getDecompressedSize(), 0); - if (auto Error = Decompressor->decompress( + if (auto error = Decompressor->decompress( {reinterpret_cast(buffer_sp->GetBytes()), size_t(buffer_sp->GetByteSize())})) { - LLDB_LOG_ERROR(log, std::move(Error), "Decompression of section {0} failed", - section->GetName()); - return result; + GetModule()->ReportWarning( + "Decompression of section '%s' failed: %s", + section->GetName().GetCString(), + llvm::toString(std::move(error)).c_str()); + section_data.Clear(); + return 0; } + section_data.SetData(buffer_sp); return buffer_sp->GetByteSize(); } diff --git a/source/Plugins/Process/minidump/ProcessMinidump.cpp b/source/Plugins/Process/minidump/ProcessMinidump.cpp index 86ee2122a976..95229b9934d1 100644 --- a/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -365,6 +365,12 @@ void ProcessMinidump::ReadModuleList() { // This enables most LLDB functionality involving address-to-module // translations (ex. identifing the module for a stack frame PC) and // modules/sections commands (ex. target modules list, ...) + if (log) { + log->Printf("Unable to locate the matching object file, creating a " + "placeholder module for: %s", + name.getValue().c_str()); + } + auto placeholder_module = std::make_shared(module_spec); placeholder_module->CreateImageSection(module, GetTarget()); diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp index 48888bbc1e26..f3c078326545 100644 --- a/source/Target/Process.cpp +++ b/source/Target/Process.cpp @@ -5842,7 +5842,7 @@ void Process::ModulesDidLoad(ModuleList &module_list) { // that loaded. // Iterate over a copy of this language runtime list in case the language - // runtime ModulesDidLoad somehow causes the language riuntime to be + // runtime ModulesDidLoad somehow causes the language runtime to be // unloaded. LanguageRuntimeCollection language_runtimes(m_language_runtimes); for (const auto &pair : language_runtimes) { @@ -6095,7 +6095,7 @@ void Process::MapSupportedStructuredDataPlugins( // For each StructuredDataPlugin, if the plugin handles any of the types in // the supported_type_names, map that type name to that plugin. Stop when // we've consumed all the type names. - // FIXME: should we return an error if there are type names nobody + // FIXME: should we return an error if there are type names nobody // supports? for (uint32_t plugin_index = 0; !const_type_names.empty(); plugin_index++) { auto create_instance = @@ -6103,7 +6103,7 @@ void Process::MapSupportedStructuredDataPlugins( plugin_index); if (!create_instance) break; - + // Create the plugin. StructuredDataPluginSP plugin_sp = (*create_instance)(*this); if (!plugin_sp) { From 592a40608a8cd7818ebe0d81f5896a66b02b0b50 Mon Sep 17 00:00:00 2001 From: Alexander Polyakov Date: Tue, 7 Aug 2018 20:23:57 +0000 Subject: [PATCH 0073/1112] Add new API to SBTarget class Summary: The new API appends an image search path to the target's path mapping list. Reviewers: aprantl, clayborg, labath Reviewed By: aprantl Subscribers: ki.stfu, lldb-commits Differential Revision: https://reviews.llvm.org/D49739 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339175 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/API/SBTarget.h | 3 +++ scripts/interface/SBTarget.i | 5 +++++ source/API/SBTarget.cpp | 20 ++++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/include/lldb/API/SBTarget.h b/include/lldb/API/SBTarget.h index 8d99545902fe..586231110e27 100644 --- a/include/lldb/API/SBTarget.h +++ b/include/lldb/API/SBTarget.h @@ -272,6 +272,9 @@ class LLDB_API SBTarget { lldb::SBFileSpec GetExecutable(); + void AppendImageSearchPath(const char *from, const char *to, + lldb::SBError &error); + bool AddModule(lldb::SBModule &module); lldb::SBModule AddModule(const char *path, const char *triple, diff --git a/scripts/interface/SBTarget.i b/scripts/interface/SBTarget.i index 08fb268c08bf..e6a7010bb245 100644 --- a/scripts/interface/SBTarget.i +++ b/scripts/interface/SBTarget.i @@ -373,6 +373,11 @@ public: lldb::SBFileSpec GetExecutable (); + void + AppendImageSearchPath (const char *from, + const char *to, + SBError &error); + bool AddModule (lldb::SBModule &module); diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp index 550d336906d3..15cdb0f312c9 100644 --- a/source/API/SBTarget.cpp +++ b/source/API/SBTarget.cpp @@ -1457,6 +1457,26 @@ bool SBTarget::DeleteAllWatchpoints() { return false; } +void SBTarget::AppendImageSearchPath(const char *from, const char *to, + lldb::SBError &error) { + TargetSP target_sp(GetSP()); + if (!target_sp) + return error.SetErrorString("invalid target"); + + const ConstString csFrom(from), csTo(to); + if (!csFrom) + return error.SetErrorString(" path can't be empty"); + if (!csTo) + return error.SetErrorString(" path can't be empty"); + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + if (log) + log->Printf("SBTarget(%p)::%s: '%s' -> '%s'", + static_cast(target_sp.get()), __FUNCTION__, + from, to); + target_sp->GetImageSearchPathList().Append(csFrom, csTo, true); +} + lldb::SBModule SBTarget::AddModule(const char *path, const char *triple, const char *uuid_cstr) { return AddModule(path, triple, uuid_cstr, NULL); From 41e8493dce7c03d30a33f1f46190c1e8ee613d86 Mon Sep 17 00:00:00 2001 From: Alexander Polyakov Date: Tue, 7 Aug 2018 20:45:46 +0000 Subject: [PATCH 0074/1112] [lldb-mi] Re-implement target-select command Now target-select uses SB API instead of HandleCommand. This patch has been reviewed along with the r339175. Differential Revision: https://reviews.llvm.org/D49739 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339178 91177308-0d34-0410-b5e6-96231b3b80d8 --- lit/lit.cfg | 10 +++- lit/tools/lldb-mi/target/inputs/main.c | 4 ++ .../target/inputs/target-select-so-path.py | 39 ++++++++++++ lit/tools/lldb-mi/target/lit.local.cfg | 1 + .../lldb-mi/target/target-select-so-path.test | 25 ++++++++ tools/lldb-mi/MICmdCmdTarget.cpp | 59 ++++++------------- 6 files changed, 95 insertions(+), 43 deletions(-) create mode 100644 lit/tools/lldb-mi/target/inputs/main.c create mode 100644 lit/tools/lldb-mi/target/inputs/target-select-so-path.py create mode 100644 lit/tools/lldb-mi/target/lit.local.cfg create mode 100644 lit/tools/lldb-mi/target/target-select-so-path.test diff --git a/lit/lit.cfg b/lit/lit.cfg index 98d69bb4c817..48a03f86ea40 100644 --- a/lit/lit.cfg +++ b/lit/lit.cfg @@ -56,7 +56,10 @@ config.environment['PYTHON_EXECUTABLE'] = getattr(config, 'python_executable', ' # Register substitutions config.substitutions.append(('%python', "'%s'" % (config.python_executable))) -debugserver = lit.util.which('debugserver', lldb_tools_dir) +if platform.system() in ['Darwin']: + debugserver = lit.util.which('debugserver', lldb_tools_dir) +else: + debugserver = lit.util.which('lldb-server', lldb_tools_dir) lldb = "%s -S %s/lit-lldb-init" % (lit.util.which('lldb', lldb_tools_dir), config.test_source_root) @@ -91,7 +94,10 @@ config.substitutions.append(('%lldbmi', lldbmi + " --synchronous")) config.substitutions.append(('%lldb', lldb)) if debugserver is not None: - config.substitutions.append(('%debugserver', debugserver)) + if platform.system() in ['Darwin']: + config.substitutions.append(('%debugserver', debugserver)) + else: + config.substitutions.append(('%debugserver', debugserver + ' gdbserver')) for pattern in [r"\bFileCheck\b", r"\blldb-test\b", diff --git a/lit/tools/lldb-mi/target/inputs/main.c b/lit/tools/lldb-mi/target/inputs/main.c new file mode 100644 index 000000000000..8c74b3496f7c --- /dev/null +++ b/lit/tools/lldb-mi/target/inputs/main.c @@ -0,0 +1,4 @@ +int main(void) { + int x = 0; + return x; +} diff --git a/lit/tools/lldb-mi/target/inputs/target-select-so-path.py b/lit/tools/lldb-mi/target/inputs/target-select-so-path.py new file mode 100644 index 000000000000..dd271e3a6648 --- /dev/null +++ b/lit/tools/lldb-mi/target/inputs/target-select-so-path.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python2 + +import os +import sys +import subprocess + + +hostname = 'localhost' + +(r, w) = os.pipe() +args = sys.argv +# Get debugserver, lldb-mi and FileCheck executables' paths with arguments. +debugserver = ' '.join([args[1], '--pipe', str(w), hostname + ':0']) +lldbmi = args[2] +test_file = args[3] +filecheck = 'FileCheck ' + test_file + +# Run debugserver, lldb-mi and FileCheck. +debugserver_proc = subprocess.Popen(debugserver.split()) +lldbmi_proc = subprocess.Popen(lldbmi, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, shell=True) +filecheck_proc = subprocess.Popen(filecheck, stdin=lldbmi_proc.stdout, + shell=True) + +# Get a tcp port chosen by debugserver. +# The number quite big to get lldb-server's output and to not hang. +bytes_to_read = 10 +port_bytes = os.read(r, bytes_to_read) +port = str(port_bytes.decode('utf-8').strip('\x00')) + +with open(test_file, 'r') as f: + # Replace '$PORT' with a free port number and pass + # test's content to lldb-mi. + lldbmi_proc.stdin.write(f.read().replace('$PORT', port)) + lldbmi_proc.wait() + filecheck_proc.wait() + +debugserver_proc.kill() +exit(filecheck_proc.returncode) diff --git a/lit/tools/lldb-mi/target/lit.local.cfg b/lit/tools/lldb-mi/target/lit.local.cfg new file mode 100644 index 000000000000..df9b335dd131 --- /dev/null +++ b/lit/tools/lldb-mi/target/lit.local.cfg @@ -0,0 +1 @@ +config.suffixes = ['.test'] diff --git a/lit/tools/lldb-mi/target/target-select-so-path.test b/lit/tools/lldb-mi/target/target-select-so-path.test new file mode 100644 index 000000000000..f5e2df952b86 --- /dev/null +++ b/lit/tools/lldb-mi/target/target-select-so-path.test @@ -0,0 +1,25 @@ +# UNSUPPORTED: windows +# +# RUN: %cc -o %t %p/inputs/main.c -g +# RUN: python %p/inputs/target-select-so-path.py "%debugserver" "%lldbmi %t" %s + +# Test that -target-select command can hook up a path +# added by gdb-set solib-search-path. + +# Check that we have a valid target created via file-exec-and-symbols. +# CHECK: ^done + +-interpreter-exec console "target modules search-paths list" +# CHECK ^done + +-gdb-set solib-search-path /example/dir +# CHECK: ^done + +-target-select remote localhost:$PORT +# CHECK: ^connected + +-interpreter-exec console "target modules search-paths list" +# CHECK: ~"[0] \".\" -> \"/example/dir\"\n" +# CHECK-NEXT: ^done + +-gdb-exit diff --git a/tools/lldb-mi/MICmdCmdTarget.cpp b/tools/lldb-mi/MICmdCmdTarget.cpp index a82bd682de81..0666fc4c60ec 100644 --- a/tools/lldb-mi/MICmdCmdTarget.cpp +++ b/tools/lldb-mi/MICmdCmdTarget.cpp @@ -10,9 +10,8 @@ // Overview: CMICmdCmdTargetSelect implementation. // Third Party Headers: -#include "lldb/API/SBCommandInterpreter.h" -#include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBStream.h" +#include "lldb/API/SBError.h" // In-house headers: #include "MICmdArgValNumber.h" @@ -52,7 +51,7 @@ CMICmdCmdTargetSelect::CMICmdCmdTargetSelect() // Return: None. // Throws: None. //-- -CMICmdCmdTargetSelect::~CMICmdCmdTargetSelect() {} +CMICmdCmdTargetSelect::~CMICmdCmdTargetSelect() = default; //++ //------------------------------------------------------------------------------------ @@ -93,16 +92,17 @@ bool CMICmdCmdTargetSelect::Execute() { CMICmnLLDBDebugSessionInfo &rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance()); + lldb::SBTarget target = rSessionInfo.GetTarget(); - // Check we have a valid target - // Note: target created via 'file-exec-and-symbols' command - if (!rSessionInfo.GetTarget().IsValid()) { + // Check we have a valid target. + // Note: target created via 'file-exec-and-symbols' command. + if (!target.IsValid()) { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT), m_cmdData.strMiCmd.c_str())); return MIstatus::failure; } - // Verify that we are executing remotely + // Verify that we are executing remotely. const CMIUtilString &rRemoteType(pArgType->GetValue()); if (rRemoteType != "remote") { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_TYPE), @@ -111,33 +111,25 @@ bool CMICmdCmdTargetSelect::Execute() { return MIstatus::failure; } - // Create a URL pointing to the remote gdb stub + // Create a URL pointing to the remote gdb stub. const CMIUtilString strUrl = CMIUtilString::Format("connect://%s", pArgParameters->GetValue().c_str()); - // Ask LLDB to connect to the target port - const char *pPlugin("gdb-remote"); lldb::SBError error; - lldb::SBProcess process = rSessionInfo.GetTarget().ConnectRemote( + // Ask LLDB to connect to the target port. + const char *pPlugin("gdb-remote"); + lldb::SBProcess process = target.ConnectRemote( rSessionInfo.GetListener(), strUrl.c_str(), pPlugin, error); - // Verify that we have managed to connect successfully - lldb::SBStream errMsg; - error.GetDescription(errMsg); + // Verify that we have managed to connect successfully. if (!process.IsValid()) { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_PLUGIN), m_cmdData.strMiCmd.c_str(), - errMsg.GetData())); - return MIstatus::failure; - } - if (error.Fail()) { - SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_CONNECT_TO_TARGET), - m_cmdData.strMiCmd.c_str(), - errMsg.GetData())); + error.GetCString())); return MIstatus::failure; } - // Set the environment path if we were given one + // Set the environment path if we were given one. CMIUtilString strWkDir; if (rSessionInfo.SharedDataRetrieve( rSessionInfo.m_constStrSharedDataKeyWkDir, strWkDir)) { @@ -150,28 +142,13 @@ bool CMICmdCmdTargetSelect::Execute() { } } - // Set the shared object path if we were given one + // Set the shared object path if we were given one. CMIUtilString strSolibPath; if (rSessionInfo.SharedDataRetrieve( - rSessionInfo.m_constStrSharedDataSolibPath, strSolibPath)) { - lldb::SBDebugger &rDbgr = rSessionInfo.GetDebugger(); - lldb::SBCommandInterpreter cmdIterpreter = rDbgr.GetCommandInterpreter(); - - CMIUtilString strCmdString = CMIUtilString::Format( - "target modules search-paths add . %s", strSolibPath.c_str()); - - lldb::SBCommandReturnObject retObj; - cmdIterpreter.HandleCommand(strCmdString.c_str(), retObj, false); + rSessionInfo.m_constStrSharedDataSolibPath, strSolibPath)) + target.AppendImageSearchPath(".", strSolibPath.c_str(), error); - if (!retObj.Succeeded()) { - SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FNFAILED), - m_cmdData.strMiCmd.c_str(), - "target-select")); - return MIstatus::failure; - } - } - - return MIstatus::success; + return HandleSBError(error); } //++ From 8d973d4e973832d1ddce729815d52b24f89cc603 Mon Sep 17 00:00:00 2001 From: Stella Stamenova Date: Tue, 7 Aug 2018 20:58:02 +0000 Subject: [PATCH 0075/1112] [lit, python] Change the order of the quotes in the lit cfg file Double quotes are always correct in paths on windows while single quotes only work sometimes. By swapping the order of the quotes in the subsitution we guarantee that the quotes will be correct on Windows. Both sets work correctly on Linux in the test environment. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339180 91177308-0d34-0410-b5e6-96231b3b80d8 --- lit/lit.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lit/lit.cfg b/lit/lit.cfg index 48a03f86ea40..2489353289f1 100644 --- a/lit/lit.cfg +++ b/lit/lit.cfg @@ -54,7 +54,7 @@ config.environment['LLVM_SRC_ROOT'] = getattr(config, 'llvm_src_root', '') config.environment['PYTHON_EXECUTABLE'] = getattr(config, 'python_executable', '') # Register substitutions -config.substitutions.append(('%python', "'%s'" % (config.python_executable))) +config.substitutions.append(('%python', '"%s"' % (config.python_executable))) if platform.system() in ['Darwin']: debugserver = lit.util.which('debugserver', lldb_tools_dir) From 417a3616c2ac142a5d8813edacc9ff37ce162546 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Tue, 7 Aug 2018 21:05:34 +0000 Subject: [PATCH 0076/1112] Fix the Xcode project for the Core -> Utility moves. Scalar.{h,cpp}, RegisterValue.{h,cpp}, State.{h,cpp} were moved. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339181 91177308-0d34-0410-b5e6-96231b3b80d8 --- lldb.xcodeproj/project.pbxproj | 42 ++++++++++++++++------------------ 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index f34c403c959e..d3d56fe7577e 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -65,7 +65,6 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ - 228B1B672113340200E61C70 /* ClangHighlighter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 58A080AB2112AABB00D5580F /* ClangHighlighter.cpp */; }; 268900E813353E6F00698AC0 /* ABI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 497E7B9D1188F6690065CCA1 /* ABI.cpp */; }; 26DB3E161379E7AD0080DC73 /* ABIMacOSX_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DB3E071379E7AD0080DC73 /* ABIMacOSX_arm.cpp */; }; 26DB3E191379E7AD0080DC73 /* ABIMacOSX_arm64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DB3E0B1379E7AD0080DC73 /* ABIMacOSX_arm64.cpp */; }; @@ -159,8 +158,7 @@ 268900D313353E6F00698AC0 /* ClangExternalASTSourceCallbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26E69030129C6BEF00DDECD9 /* ClangExternalASTSourceCallbacks.cpp */; }; 4966DCC4148978A10028481B /* ClangExternalASTSourceCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4966DCC3148978A10028481B /* ClangExternalASTSourceCommon.cpp */; }; 2689005F13353E0E00698AC0 /* ClangFunctionCaller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C98D3DA118FB96F00E575D0 /* ClangFunctionCaller.cpp */; }; - 58A080AC2112AABB00D5580F /* ClangHighlighter.cpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 58A080AB2112AABB00D5580F /* ClangHighlighter.cpp */; }; - 58A080AE2112AAC500D5580F /* ClangHighlighter.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 58A080AD2112AAC500D5580F /* ClangHighlighter.h */; }; + 228B1B672113340200E61C70 /* ClangHighlighter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 58A080AB2112AABB00D5580F /* ClangHighlighter.cpp */; }; 4CD44D5820C603CB0003557C /* ClangHost.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CD44D5620C603A80003557C /* ClangHost.cpp */; }; 4959511F1A1BC4BC00F6F8FC /* ClangModulesDeclVendor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4959511E1A1BC4BC00F6F8FC /* ClangModulesDeclVendor.cpp */; }; 2689006313353E0E00698AC0 /* ClangPersistentVariables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */; }; @@ -2624,8 +2622,8 @@ 2654A6841E54D5EE00DA1013 /* RegisterNumber.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RegisterNumber.h; path = include/lldb/Target/RegisterNumber.h; sourceTree = ""; }; 4CA9D13C1FCE07AF00300E18 /* RegisterUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterUtilities.cpp; sourceTree = ""; }; 4CA9D13D1FCE07AF00300E18 /* RegisterUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterUtilities.h; sourceTree = ""; }; - 26C6886E137880C400407EDF /* RegisterValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterValue.cpp; path = source/Core/RegisterValue.cpp; sourceTree = ""; }; - 26C6886D137880B900407EDF /* RegisterValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RegisterValue.h; path = include/lldb/Core/RegisterValue.h; sourceTree = ""; }; + 26C6886E137880C400407EDF /* RegisterValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterValue.cpp; path = source/Utility/RegisterValue.cpp; sourceTree = ""; }; + 26C6886D137880B900407EDF /* RegisterValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RegisterValue.h; path = include/lldb/Utility/RegisterValue.h; sourceTree = ""; }; 26764C9F1E48F528008D3573 /* RegularExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegularExpression.cpp; path = source/Utility/RegularExpression.cpp; sourceTree = ""; }; 26764C9C1E48F516008D3573 /* RegularExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RegularExpression.h; path = include/lldb/Utility/RegularExpression.h; sourceTree = ""; }; 23D065821D4A7BDA0008EDE6 /* RenderScriptExpressionOpts.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderScriptExpressionOpts.cpp; sourceTree = ""; }; @@ -2834,8 +2832,8 @@ B2A5872514313B480092BFBA /* SBWatchpoint.i */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; path = SBWatchpoint.i; sourceTree = ""; }; 26BC7D7810F1B77400F91463 /* STLUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = STLUtils.h; path = include/lldb/Core/STLUtils.h; sourceTree = ""; }; 4CAB257C18EC9DB800BAD33E /* SafeMachO.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SafeMachO.h; path = include/lldb/Utility/SafeMachO.h; sourceTree = ""; }; - 26BC7E8D10F1B85900F91463 /* Scalar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Scalar.cpp; path = source/Core/Scalar.cpp; sourceTree = ""; }; - 26BC7D7410F1B77400F91463 /* Scalar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Scalar.h; path = include/lldb/Core/Scalar.h; sourceTree = ""; }; + 26BC7E8D10F1B85900F91463 /* Scalar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Scalar.cpp; path = source/Utility/Scalar.cpp; sourceTree = ""; }; + 26BC7D7410F1B77400F91463 /* Scalar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Scalar.h; path = include/lldb/Utility/Scalar.h; sourceTree = ""; }; 23CB14E91D66CC0E00EDDDE1 /* ScalarTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScalarTest.cpp; sourceTree = ""; }; 9A82010B10FFB49800182560 /* ScriptInterpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScriptInterpreter.cpp; path = source/Interpreter/ScriptInterpreter.cpp; sourceTree = ""; }; 26BC7DE510F1B7F900F91463 /* ScriptInterpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScriptInterpreter.h; path = include/lldb/Interpreter/ScriptInterpreter.h; sourceTree = ""; }; @@ -2873,8 +2871,8 @@ 26BC7DF610F1B81A00F91463 /* StackFrameList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StackFrameList.h; path = include/lldb/Target/StackFrameList.h; sourceTree = ""; }; 26BC7F3A10F1B90C00F91463 /* StackID.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StackID.cpp; path = source/Target/StackID.cpp; sourceTree = ""; }; 26BC7DF710F1B81A00F91463 /* StackID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StackID.h; path = include/lldb/Target/StackID.h; sourceTree = ""; }; - 26BC7E9010F1B85900F91463 /* State.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = State.cpp; path = source/Core/State.cpp; sourceTree = ""; }; - 26BC7D7710F1B77400F91463 /* State.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = State.h; path = include/lldb/Core/State.h; sourceTree = ""; }; + 26BC7E9010F1B85900F91463 /* State.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = State.cpp; path = source/Utility/State.cpp; sourceTree = ""; }; + 26BC7D7710F1B77400F91463 /* State.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = State.h; path = include/lldb/Utility/State.h; sourceTree = ""; }; 9A3D43E21F3237D500EB767C /* StateTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StateTest.cpp; sourceTree = ""; }; 492DB7E81EC662D100B9E9AF /* Status.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Status.cpp; path = source/Utility/Status.cpp; sourceTree = ""; }; 492DB7E61EC662B100B9E9AF /* Status.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Status.h; path = include/lldb/Utility/Status.h; sourceTree = ""; }; @@ -2910,7 +2908,7 @@ 2660D9F611922A1300958FBD /* StringExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringExtractor.cpp; path = source/Utility/StringExtractor.cpp; sourceTree = ""; }; 26A375831D59486000D6CBDB /* StringExtractor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = StringExtractor.h; path = include/lldb/Utility/StringExtractor.h; sourceTree = ""; }; 2676A093119C93C8008A98EF /* StringExtractorGDBRemote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringExtractorGDBRemote.cpp; path = source/Utility/StringExtractorGDBRemote.cpp; sourceTree = ""; }; - 2676A094119C93C8008A98EF /* StringExtractorGDBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringExtractorGDBRemote.h; path = source/Utility/StringExtractorGDBRemote.h; sourceTree = ""; }; + 2676A094119C93C8008A98EF /* StringExtractorGDBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringExtractorGDBRemote.h; path = include/lldb/Utility/StringExtractorGDBRemote.h; sourceTree = ""; }; 2321F9441BDD346100BA9A93 /* StringExtractorTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringExtractorTest.cpp; sourceTree = ""; }; 94380B8119940B0A00BFE4A8 /* StringLexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringLexer.cpp; path = source/Utility/StringLexer.cpp; sourceTree = ""; }; 94380B8019940B0300BFE4A8 /* StringLexer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = StringLexer.h; path = include/lldb/Utility/StringLexer.h; sourceTree = ""; }; @@ -3515,24 +3513,26 @@ 2321F9421BDD343A00BA9A93 /* Utility */ = { isa = PBXGroup; children = ( - 58EAC73D2106A0740029571E /* StreamTeeTest.cpp */, 7F94D7172040A13A006EE3EA /* CleanUpTest.cpp */, 23E2E5161D903689006F38BB /* ArchSpecTest.cpp */, 9A3D43C81F3150D200EB767C /* ConstStringTest.cpp */, 23CB14FD1D66CD2400EDDDE1 /* FileSpecTest.cpp */, + 8C3BD99F1EF5D1B50016C343 /* JSONTest.cpp */, 9A3D43C71F3150D200EB767C /* LogTest.cpp */, 9A3D43CB1F3150D200EB767C /* NameMatchesTest.cpp */, + 23CB14E91D66CC0E00EDDDE1 /* ScalarTest.cpp */, + 9A3D43E21F3237D500EB767C /* StateTest.cpp */, 9A3D43C61F3150D200EB767C /* StatusTest.cpp */, + 58EAC73D2106A0740029571E /* StreamTeeTest.cpp */, + 2321F9441BDD346100BA9A93 /* StringExtractorTest.cpp */, 9A3D43CA1F3150D200EB767C /* StructuredDataTest.cpp */, 9A3D43C91F3150D200EB767C /* TildeExpressionResolverTest.cpp */, 9A3D43CC1F3150D200EB767C /* TimeoutTest.cpp */, 9A3D43C51F3150D200EB767C /* TimerTest.cpp */, + 2321F9461BDD346100BA9A93 /* UriParserTest.cpp */, 9A3D43C41F3150D200EB767C /* VASprintfTest.cpp */, 2321F9431BDD346100BA9A93 /* CMakeLists.txt */, 23CB15041D66CD9200EDDDE1 /* Inputs */, - 2321F9441BDD346100BA9A93 /* StringExtractorTest.cpp */, - 8C3BD99F1EF5D1B50016C343 /* JSONTest.cpp */, - 2321F9461BDD346100BA9A93 /* UriParserTest.cpp */, ); path = Utility; sourceTree = ""; @@ -3679,12 +3679,10 @@ 58A080B12112AB2200D5580F /* HighlighterTest.cpp */, 4F29D3CD21010F84003B549A /* MangledTest.cpp */, 9A3D43E31F3237D500EB767C /* ListenerTest.cpp */, - 9A3D43E21F3237D500EB767C /* StateTest.cpp */, 9A3D43E11F3237D500EB767C /* StreamCallbackTest.cpp */, 23CB14E71D66CC0E00EDDDE1 /* CMakeLists.txt */, 23CB14E61D66CC0E00EDDDE1 /* BroadcasterTest.cpp */, 23CB14E81D66CC0E00EDDDE1 /* DataExtractorTest.cpp */, - 23CB14E91D66CC0E00EDDDE1 /* ScalarTest.cpp */, ); path = Core; sourceTree = ""; @@ -4519,14 +4517,20 @@ 943BDEFD1AA7B2F800789CE8 /* LLDBAssert.cpp */, 3F81691C1ABA242B001DA9DF /* NameMatches.h */, 3F8169181ABA2419001DA9DF /* NameMatches.cpp */, + 26C6886D137880B900407EDF /* RegisterValue.h */, + 26C6886E137880C400407EDF /* RegisterValue.cpp */, 26764C9C1E48F516008D3573 /* RegularExpression.h */, 26764C9F1E48F528008D3573 /* RegularExpression.cpp */, 4CAB257C18EC9DB800BAD33E /* SafeMachO.h */, + 26BC7D7410F1B77400F91463 /* Scalar.h */, + 26BC7E8D10F1B85900F91463 /* Scalar.cpp */, 26A375841D59487700D6CBDB /* SelectHelper.h */, 26A3757F1D59462700D6CBDB /* SelectHelper.cpp */, 261B5A5211C3F2AD00AABD0A /* SharingPtr.cpp */, 4C2FAE2E135E3A70001EDE44 /* SharedCluster.h */, 261B5A5311C3F2AD00AABD0A /* SharingPtr.h */, + 26BC7D7710F1B77400F91463 /* State.h */, + 26BC7E9010F1B85900F91463 /* State.cpp */, 492DB7E61EC662B100B9E9AF /* Status.h */, 492DB7E81EC662D100B9E9AF /* Status.cpp */, 26764C9B1E48F50C008D3573 /* Stream.h */, @@ -5043,18 +5047,12 @@ 26BC7D7110F1B77400F91463 /* PluginManager.h */, 26BC7E8A10F1B85900F91463 /* PluginManager.cpp */, 2626B6AD143E1BEA00EF935C /* RangeMap.h */, - 26C6886D137880B900407EDF /* RegisterValue.h */, - 26C6886E137880C400407EDF /* RegisterValue.cpp */, - 26BC7D7410F1B77400F91463 /* Scalar.h */, - 26BC7E8D10F1B85900F91463 /* Scalar.cpp */, 26BC7CF910F1B71400F91463 /* SearchFilter.h */, 26BC7E1510F1B83100F91463 /* SearchFilter.cpp */, 26BC7D7510F1B77400F91463 /* Section.h */, 26BC7E8E10F1B85900F91463 /* Section.cpp */, 26BC7D7610F1B77400F91463 /* SourceManager.h */, 26BC7E8F10F1B85900F91463 /* SourceManager.cpp */, - 26BC7D7710F1B77400F91463 /* State.h */, - 26BC7E9010F1B85900F91463 /* State.cpp */, 26BC7D7810F1B77400F91463 /* STLUtils.h */, 9A4F35111368A54100823F52 /* StreamAsynchronousIO.h */, 9A4F350F1368A51A00823F52 /* StreamAsynchronousIO.cpp */, From 1e57d1c2ee8d06cd1818860b95d16501a6f5f2bb Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Tue, 7 Aug 2018 21:09:55 +0000 Subject: [PATCH 0077/1112] If a function starts with line number 0, don't try to check if a breakpoint crossed function boundaries. clang doesn't use line number 0 (to mean artifically generated code) very often, but swift does it quite often. We were rejecting all by line breakpoints in functions that started at line 0. But that's a special marker so we can just not do this test in that case. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339182 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../breakpoint/move_nearest/TestMoveNearest.py | 6 ++++++ .../test/functionalities/breakpoint/move_nearest/main.cpp | 2 +- source/Breakpoint/BreakpointResolverFileLine.cpp | 6 +++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/TestMoveNearest.py b/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/TestMoveNearest.py index 16d5bc75473c..b8281e9c85bd 100644 --- a/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/TestMoveNearest.py +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/TestMoveNearest.py @@ -18,6 +18,8 @@ def setUp(self): # Find the line number to break inside main(). self.line1 = line_number('foo.h', '// !BR1') self.line2 = line_number('foo.h', '// !BR2') + self.line_between = line_number('main.cpp', "// BR_Between") + print("BR_Between found at", self.line_between) self.line_main = line_number('main.cpp', '// !BR_main') def test(self): @@ -61,3 +63,7 @@ def test(self): # "return .." lldbutil.run_break_set_by_file_and_line(self, 'main.cpp', self.line_main+2, extra_options="-m 1") + + # Make sure we don't put move the breakpoint if it is set between two functions: + lldbutil.run_break_set_by_file_and_line(self, 'main.cpp', + self.line_between, extra_options="-m 1", num_expected_locations=0) diff --git a/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/main.cpp b/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/main.cpp index c9295a5c7d3c..76a22a5420fe 100644 --- a/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/main.cpp +++ b/packages/Python/lldbsuite/test/functionalities/breakpoint/move_nearest/main.cpp @@ -1,7 +1,7 @@ #include "foo.h" int call_foo2() { return foo2(); } - +// BR_Between int main() // !BR_main { diff --git a/source/Breakpoint/BreakpointResolverFileLine.cpp b/source/Breakpoint/BreakpointResolverFileLine.cpp index ecef88eb9989..a846f5bf9122 100644 --- a/source/Breakpoint/BreakpointResolverFileLine.cpp +++ b/source/Breakpoint/BreakpointResolverFileLine.cpp @@ -181,8 +181,12 @@ void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list, // inline int foo2() { ... } // // but that's the best we can do for now. + // One complication, if the line number returned from GetStartLineSourceInfo + // is 0, then we can't do this calculation. That can happen if + // GetStartLineSourceInfo gets an error, or if the first line number in + // the function really is 0 - which happens for some languages. const int decl_line_is_too_late_fudge = 1; - if (m_line_number < line - decl_line_is_too_late_fudge) { + if (line && m_line_number < line - decl_line_is_too_late_fudge) { LLDB_LOG(log, "removing symbol context at {0}:{1}", file, line); sc_list.RemoveContextAtIndex(i); --i; From 8b805a67ef4080fea64b51a3469e9082e0d267ab Mon Sep 17 00:00:00 2001 From: Alexander Polyakov Date: Tue, 7 Aug 2018 21:41:59 +0000 Subject: [PATCH 0078/1112] Add documentation for SBTarget::AppendImageSearchPath git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339189 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/API/SBTarget.h | 1 + scripts/interface/SBTarget.i | 3 +++ 2 files changed, 4 insertions(+) diff --git a/include/lldb/API/SBTarget.h b/include/lldb/API/SBTarget.h index 586231110e27..cc3489cee9b6 100644 --- a/include/lldb/API/SBTarget.h +++ b/include/lldb/API/SBTarget.h @@ -272,6 +272,7 @@ class LLDB_API SBTarget { lldb::SBFileSpec GetExecutable(); + // Append the path mapping (from -> to) to the target's paths mapping list. void AppendImageSearchPath(const char *from, const char *to, lldb::SBError &error); diff --git a/scripts/interface/SBTarget.i b/scripts/interface/SBTarget.i index e6a7010bb245..ca3cb7ee5873 100644 --- a/scripts/interface/SBTarget.i +++ b/scripts/interface/SBTarget.i @@ -373,6 +373,9 @@ public: lldb::SBFileSpec GetExecutable (); + %feature("docstring", " + /// Append the path mapping (from -> to) to the target's paths mapping list. + ") AppendImageSearchPath; void AppendImageSearchPath (const char *from, const char *to, From e7bb6b02d3fa68f76b01bda0c87f601a1c9b0da9 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Tue, 7 Aug 2018 23:24:24 +0000 Subject: [PATCH 0079/1112] Removed duplicated commented-out code [NFC] git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339202 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Symbol/ClangASTContext.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp index 9f6ddcd156b5..301b9b38b865 100644 --- a/source/Symbol/ClangASTContext.cpp +++ b/source/Symbol/ClangASTContext.cpp @@ -628,7 +628,6 @@ void ClangASTContext::SetExternalSource( if (ast) { ast->setExternalSource(ast_source_ap); ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true); - // ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true); } } @@ -639,7 +638,6 @@ void ClangASTContext::RemoveExternalSource() { llvm::IntrusiveRefCntPtr empty_ast_source_ap; ast->setExternalSource(empty_ast_source_ap); ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false); - // ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(false); } } From a1254570c76307914c2c9652172a9c2745e75843 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Tue, 7 Aug 2018 23:47:05 +0000 Subject: [PATCH 0080/1112] Removed doxygen comment that doesn't fit to function signature git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339204 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h index b67387930190..cb29731579dc 100644 --- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h +++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h @@ -325,12 +325,6 @@ class ClangExpressionDeclMap : public ClangASTSource { /// @param[in] namespace_decl /// If valid and module is non-NULL, the parent namespace. /// - /// @param[in] name - /// The name as a plain C string. The NameSearchContext contains - /// a DeclarationName for the name so at first the name may seem - /// redundant, but ClangExpressionDeclMap operates in RTTI land so - /// it can't access DeclarationName. - /// /// @param[in] current_id /// The ID for the current FindExternalVisibleDecls invocation, /// for logging purposes. From 9acd265ae3803fdf8b53273aae9bff6ef39caa99 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Tue, 7 Aug 2018 23:48:25 +0000 Subject: [PATCH 0081/1112] [StackFrame] Add more clarifying comments to StackFrameList (NFC) git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339205 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Target/StackFrameList.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp index 595e1aaa7d53..f177df0ccdf3 100644 --- a/source/Target/StackFrameList.cpp +++ b/source/Target/StackFrameList.cpp @@ -234,6 +234,9 @@ void StackFrameList::GetOnlyConcreteFramesUpTo(uint32_t end_idx, // Done unwinding. m_concrete_frames_fetched = UINT32_MAX; } + + // Don't create the frames eagerly. Defer this work to GetFrameAtIndex, + // which can lazily query the unwinder to create frames. m_frames.resize(num_frames); } @@ -567,9 +570,6 @@ StackFrameSP StackFrameList::GetFrameWithStackID(const StackID &stack_id) { if ((*pos)->GetStackID() == stack_id) return *pos; } - - // if (m_frames.back()->GetStackID() < stack_id) - // frame_idx = m_frames.size(); } do { frame_sp = GetFrameAtIndex(frame_idx); From 3600b37150fd84b187f396db270f447d9e9a3be7 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Tue, 7 Aug 2018 23:48:40 +0000 Subject: [PATCH 0082/1112] Delete a dead Function constructor (NFC) git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339206 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Symbol/Function.h | 34 ---------------------------------- source/Symbol/Function.cpp | 11 ----------- 2 files changed, 45 deletions(-) diff --git a/include/lldb/Symbol/Function.h b/include/lldb/Symbol/Function.h index 28c6b4857b10..f93b77236e8c 100644 --- a/include/lldb/Symbol/Function.h +++ b/include/lldb/Symbol/Function.h @@ -348,40 +348,6 @@ class Function : public UserID, public SymbolContextScope { lldb::user_id_t func_type_uid, const Mangled &mangled, Type *func_type, const AddressRange &range); - //------------------------------------------------------------------ - /// Construct with a compile unit, function UID, function type UID, optional - /// mangled name, function type, and a section offset based address range. - /// - /// @param[in] comp_unit - /// The compile unit to which this function belongs. - /// - /// @param[in] func_uid - /// The UID for this function. This value is provided by the - /// SymbolFile plug-in and can be any value that allows - /// the plug-in to quickly find and parse more detailed - /// information when and if more information is needed. - /// - /// @param[in] func_type_uid - /// The type UID for the function Type to allow for lazy type - /// parsing from the debug information. - /// - /// @param[in] mangled - /// The optional mangled name for this function. If empty, there - /// is no mangled information. - /// - /// @param[in] func_type - /// The optional function type. If NULL, the function type will - /// be parsed on demand when accessed using the - /// Function::GetType() function by asking the SymbolFile - /// plug-in to get the type for \a func_type_uid. - /// - /// @param[in] range - /// The section offset based address for this function. - //------------------------------------------------------------------ - Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, - lldb::user_id_t func_type_uid, const char *mangled, Type *func_type, - const AddressRange &range); - //------------------------------------------------------------------ /// Destructor. //------------------------------------------------------------------ diff --git a/source/Symbol/Function.cpp b/source/Symbol/Function.cpp index f642c186a19f..4064eb5163ac 100644 --- a/source/Symbol/Function.cpp +++ b/source/Symbol/Function.cpp @@ -141,17 +141,6 @@ Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, assert(comp_unit != nullptr); } -Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, - lldb::user_id_t type_uid, const char *mangled, Type *type, - const AddressRange &range) - : UserID(func_uid), m_comp_unit(comp_unit), m_type_uid(type_uid), - m_type(type), m_mangled(ConstString(mangled), true), m_block(func_uid), - m_range(range), m_frame_base(nullptr), m_flags(), - m_prologue_byte_size(0) { - m_block.SetParentScope(this); - assert(comp_unit != nullptr); -} - Function::~Function() {} void Function::GetStartLineSourceInfo(FileSpec &source_file, From 1d80326c57325888f0d104b647cc8c5e17788a92 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Wed, 8 Aug 2018 21:26:49 +0000 Subject: [PATCH 0083/1112] [IRMemoryMap] Shrink Allocation and make it move-only (NFC) Profiling data show that Allocation::operator= is hot (see the data attached to the Phab review). Reorder a few fields within Allocation to avoid implicit structure padding and shrink the structure. This should make copies a bit cheaper. Also, given that an Allocation contains a std::vector (by way of DataBufferHeap), it's preferable to make it move-only instead of permitting expensive copies. As an added benefit this allows us to have a single Allocation constructor instead of two. Differential Revision: https://reviews.llvm.org/D50271 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339290 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Expression/IRMemoryMap.h | 28 +++++++++++++-------------- source/Expression/IRMemoryMap.cpp | 11 ++++++----- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/include/lldb/Expression/IRMemoryMap.h b/include/lldb/Expression/IRMemoryMap.h index df8a03f4763f..026ca6b98110 100644 --- a/include/lldb/Expression/IRMemoryMap.h +++ b/include/lldb/Expression/IRMemoryMap.h @@ -39,7 +39,7 @@ class IRMemoryMap { IRMemoryMap(lldb::TargetSP target_sp); ~IRMemoryMap(); - enum AllocationPolicy { + enum AllocationPolicy : uint8_t { eAllocationPolicyInvalid = 0, ///< It is an error for an allocation to have this policy. eAllocationPolicyHostOnly, ///< This allocation was created in the host and @@ -91,32 +91,32 @@ class IRMemoryMap { private: struct Allocation { lldb::addr_t - m_process_alloc; ///< The (unaligned) base for the remote allocation + m_process_alloc; ///< The (unaligned) base for the remote allocation. lldb::addr_t - m_process_start; ///< The base address of the allocation in the process - size_t m_size; ///< The size of the requested allocation - uint32_t m_permissions; ///< The access permissions on the memory in the - ///process. In the host, the memory is always - ///read/write. - uint8_t m_alignment; ///< The alignment of the requested allocation + m_process_start; ///< The base address of the allocation in the process. + size_t m_size; ///< The size of the requested allocation. DataBufferHeap m_data; - ///< Flags + /// Flags. Keep these grouped together to avoid structure padding. AllocationPolicy m_policy; bool m_leak; + uint8_t m_permissions; ///< The access permissions on the memory in the + /// process. In the host, the memory is always + /// read/write. + uint8_t m_alignment; ///< The alignment of the requested allocation. public: Allocation(lldb::addr_t process_alloc, lldb::addr_t process_start, size_t size, uint32_t permissions, uint8_t alignment, AllocationPolicy m_policy); - Allocation() - : m_process_alloc(LLDB_INVALID_ADDRESS), - m_process_start(LLDB_INVALID_ADDRESS), m_size(0), m_permissions(0), - m_alignment(0), m_data(), m_policy(eAllocationPolicyInvalid), - m_leak(false) {} + DISALLOW_COPY_AND_ASSIGN(Allocation); }; + static_assert(sizeof(Allocation) <= + (4 * sizeof(lldb::addr_t)) + sizeof(DataBufferHeap), + "IRMemoryMap::Allocation is larger than expected"); + lldb::ProcessWP m_process_wp; lldb::TargetWP m_target_wp; typedef std::map AllocationMap; diff --git a/source/Expression/IRMemoryMap.cpp b/source/Expression/IRMemoryMap.cpp index b4f6fb768875..e4c85d6ce727 100644 --- a/source/Expression/IRMemoryMap.cpp +++ b/source/Expression/IRMemoryMap.cpp @@ -272,8 +272,8 @@ IRMemoryMap::Allocation::Allocation(lldb::addr_t process_alloc, uint32_t permissions, uint8_t alignment, AllocationPolicy policy) : m_process_alloc(process_alloc), m_process_start(process_start), - m_size(size), m_permissions(permissions), m_alignment(alignment), - m_policy(policy), m_leak(false) { + m_size(size), m_policy(policy), m_leak(false), m_permissions(permissions), + m_alignment(alignment) { switch (policy) { default: assert(0 && "We cannot reach this!"); @@ -389,9 +389,10 @@ lldb::addr_t IRMemoryMap::Malloc(size_t size, uint8_t alignment, lldb::addr_t mask = alignment - 1; aligned_address = (allocation_address + mask) & (~mask); - m_allocations[aligned_address] = - Allocation(allocation_address, aligned_address, allocation_size, - permissions, alignment, policy); + m_allocations.emplace( + std::piecewise_construct, std::forward_as_tuple(aligned_address), + std::forward_as_tuple(allocation_address, aligned_address, + allocation_size, permissions, alignment, policy)); if (zero_memory) { Status write_error; From 401e0c6c1dd3efe13362c19f27d5c1e3e123d8e6 Mon Sep 17 00:00:00 2001 From: Stefan Granitz Date: Wed, 8 Aug 2018 21:57:37 +0000 Subject: [PATCH 0084/1112] Use rich mangling information in Symtab::InitNameIndexes() Summary: I set up a new review, because not all the code I touched was marked as a change in old one anymore. In preparation for this review, there were two earlier ones: * https://reviews.llvm.org/D49612 introduced the ItaniumPartialDemangler to LLDB demangling without conceptual changes * https://reviews.llvm.org/D49909 added a unit test that covers all relevant code paths in the InitNameIndexes() function Primary goals for this patch are: (1) Use ItaniumPartialDemangler's rich mangling info for building LLDB's name index. (2) Provide a uniform interface. (3) Improve indexing performance. The central implementation in this patch is our new function for explicit demangling: ``` const RichManglingInfo * Mangled::DemangleWithRichManglingInfo(RichManglingContext &, SkipMangledNameFn *) ``` It takes a context object and a filter function and provides read-only access to the rich mangling info on success, or otherwise returns null. The two new classes are: * `RichManglingInfo` offers a uniform interface to query symbol properties like `getFunctionDeclContextName()` or `isCtorOrDtor()` that are forwarded to the respective provider internally (`llvm::ItaniumPartialDemangler` or `lldb_private::CPlusPlusLanguage::MethodName`). * `RichManglingContext` works a bit like `LLVMContext`, it the actual `RichManglingInfo` returned from `DemangleWithRichManglingInfo()` and handles lifetime and configuration. It is likely stack-allocated and can be reused for multiple queries during batch processing. The idea here is that `DemangleWithRichManglingInfo()` acts like a gate keeper. It only provides access to `RichManglingInfo` on success, which in turn avoids the need to handle a `NoInfo` state in every single one of its getters. Having it stored within the context, avoids extra heap allocations and aids (3). As instantiations of the IPD the are considered expensive, the context is the ideal place to store it too. An efficient filtering function `SkipMangledNameFn` is another piece in the performance puzzle and it helps to mimic the original behavior of `InitNameIndexes`. Future potential: * `DemangleWithRichManglingInfo()` is thread-safe, IFF using different contexts in different threads. This may be exploited in the future. (It's another thing that it has in common with `LLVMContext`.) * The old implementation only parsed and indexed Itanium mangled names. The new `RichManglingInfo` can be extended for various mangling schemes and languages. One problem with the implementation of RichManglingInfo is the inaccessibility of class `CPlusPlusLanguage::MethodName` (defined in source/Plugins/Language/..), from within any header in the Core components of LLDB. The rather hacky solution is to store a type erased reference and cast it to the correct type on access in the cpp - see `RichManglingInfo::get()`. At the moment there seems to be no better way to do it. IMHO `CPlusPlusLanguage::MethodName` should be a top-level class in order to enable forward delcarations (but that is a rather big change I guess). First simple profiling shows a good speedup. `target create clang` now takes 0.64s on average. Before the change I observed runtimes between 0.76s an 1.01s. This is still no bulletproof data (I only ran it on one machine!), but it's a promising indicator I think. Reviewers: labath, jingham, JDevlieghere, erik.pilkington Subscribers: zturner, clayborg, mgorny, lldb-commits Differential Revision: https://reviews.llvm.org/D50071 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339291 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Core/Mangled.h | 46 ++++- include/lldb/Core/RichManglingContext.h | 110 +++++++++++ include/lldb/Symbol/Symtab.h | 9 + include/lldb/lldb-forward.h | 11 ++ lldb.xcodeproj/project.pbxproj | 20 +- source/Core/CMakeLists.txt | 1 + source/Core/Mangled.cpp | 175 ++++++++++++----- source/Core/RichManglingContext.cpp | 178 +++++++++++++++++ source/Symbol/Symtab.cpp | 212 ++++++++++++--------- unittests/Core/CMakeLists.txt | 1 + unittests/Core/RichManglingContextTest.cpp | 114 +++++++++++ 11 files changed, 730 insertions(+), 147 deletions(-) create mode 100644 include/lldb/Core/RichManglingContext.h create mode 100644 source/Core/RichManglingContext.cpp create mode 100644 unittests/Core/RichManglingContextTest.cpp diff --git a/include/lldb/Core/Mangled.h b/include/lldb/Core/Mangled.h index d263297ecfc6..12edf8200e43 100644 --- a/include/lldb/Core/Mangled.h +++ b/include/lldb/Core/Mangled.h @@ -11,18 +11,15 @@ #define liblldb_Mangled_h_ #if defined(__cplusplus) +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" + #include "lldb/Utility/ConstString.h" -#include "lldb/lldb-enumerations.h" // for LanguageType -#include "llvm/ADT/StringRef.h" // for StringRef -#include // for size_t +#include "llvm/ADT/StringRef.h" -namespace lldb_private { -class RegularExpression; -} -namespace lldb_private { -class Stream; -} +#include +#include namespace lldb_private { @@ -238,7 +235,6 @@ class Mangled { return true; return GetDemangledName(language) == name; } - bool NameMatches(const RegularExpression ®ex, lldb::LanguageType language) const; @@ -300,6 +296,36 @@ class Mangled { //---------------------------------------------------------------------- lldb::LanguageType GuessLanguage() const; + /// Function signature for filtering mangled names. + using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme); + + //---------------------------------------------------------------------- + /// Trigger explicit demangling to obtain rich mangling information. This is + /// optimized for batch processing while populating a name index. To get the + /// pure demangled name string for a single entity, use GetDemangledName() + /// instead. + /// + /// For names that match the Itanium mangling scheme, this uses LLVM's + /// ItaniumPartialDemangler. All other names fall back to LLDB's builtin + /// parser currently. + /// + /// This function is thread-safe when used with different \a context + /// instances in different threads. + /// + /// @param[in] context + /// The context for this function. A single instance can be stack- + /// allocated in the caller's frame and used for multiple calls. + /// + /// @param[in] skip_mangled_name + /// A filtering function for skipping entities based on name and mangling + /// scheme. This can be null if unused. + /// + /// @return + /// True on success, false otherwise. + //---------------------------------------------------------------------- + bool DemangleWithRichManglingInfo(RichManglingContext &context, + SkipMangledNameFn *skip_mangled_name); + private: //---------------------------------------------------------------------- /// Mangled member variables. diff --git a/include/lldb/Core/RichManglingContext.h b/include/lldb/Core/RichManglingContext.h new file mode 100644 index 000000000000..bfa910c0b43c --- /dev/null +++ b/include/lldb/Core/RichManglingContext.h @@ -0,0 +1,110 @@ +//===-- RichManglingContext.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RichManglingContext_h_ +#define liblldb_RichManglingContext_h_ + +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private.h" + +#include "lldb/Utility/ConstString.h" + +#include "llvm/ADT/Any.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Demangle/Demangle.h" + +namespace lldb_private { + +/// Uniform wrapper for access to rich mangling information from different +/// providers. See Mangled::DemangleWithRichManglingInfo() +class RichManglingContext { +public: + RichManglingContext() + : m_provider(None), m_ipd_buf_size(2048), m_ipd_str_len(0) { + m_ipd_buf = static_cast(std::malloc(m_ipd_buf_size)); + m_ipd_buf[m_ipd_str_len] = '\0'; + } + + ~RichManglingContext() { std::free(m_ipd_buf); } + + /// Use the ItaniumPartialDemangler to obtain rich mangling information from + /// the given mangled name. + bool FromItaniumName(const ConstString &mangled); + + /// Use the legacy language parser implementation to obtain rich mangling + /// information from the given demangled name. + bool FromCxxMethodName(const ConstString &demangled); + + /// If this symbol describes a constructor or destructor. + bool IsCtorOrDtor() const; + + /// If this symbol describes a function. + bool IsFunction() const; + + /// Get the base name of a function. This doesn't include trailing template + /// arguments, ie "a::b" gives "b". The result will overwrite the + /// internal buffer. It can be obtained via GetBufferRef(). + void ParseFunctionBaseName(); + + /// Get the context name for a function. For "a::b::c", this function returns + /// "a::b". The result will overwrite the internal buffer. It can be obtained + /// via GetBufferRef(). + void ParseFunctionDeclContextName(); + + /// Get the entire demangled name. The result will overwrite the internal + /// buffer. It can be obtained via GetBufferRef(). + void ParseFullName(); + + /// Obtain a StringRef to the internal buffer that holds the result of the + /// most recent ParseXy() operation. The next ParseXy() call invalidates it. + llvm::StringRef GetBufferRef() const { + assert(m_provider != None && "Initialize a provider first"); + return m_buffer; + } + +private: + enum InfoProvider { None, ItaniumPartialDemangler, PluginCxxLanguage }; + + /// Selects the rich mangling info provider. + InfoProvider m_provider; + + /// Reference to the buffer used for results of ParseXy() operations. + llvm::StringRef m_buffer; + + /// Members for ItaniumPartialDemangler + llvm::ItaniumPartialDemangler m_ipd; + char *m_ipd_buf; + size_t m_ipd_buf_size; + size_t m_ipd_str_len; + + /// Members for PluginCxxLanguage + /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The + /// respective header is in Plugins and including it from here causes cyclic + /// dependency. Instead keep a llvm::Any and cast it on-access in the cpp. + llvm::Any m_cxx_method_parser; + + /// Clean up memory and set a new info provider for this instance. + void ResetProvider(InfoProvider new_provider); + + /// Uniform handling of string buffers for ItaniumPartialDemangler. + void processIPDStrResult(char *ipd_res, size_t res_len); + + /// Cast the given parser to the given type. Ideally we would have a type + /// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we + /// can't access CPlusPlusLanguage::MethodName from within the header. + template static ParserT *get(llvm::Any parser) { + assert(parser.hasValue()); + assert(llvm::any_isa(parser)); + return llvm::any_cast(parser); + } +}; + +} // namespace lldb_private + +#endif diff --git a/include/lldb/Symbol/Symtab.h b/include/lldb/Symbol/Symtab.h index 3d24862af365..7c16d05ee0ad 100644 --- a/include/lldb/Symbol/Symtab.h +++ b/include/lldb/Symbol/Symtab.h @@ -197,6 +197,15 @@ class Symtab { void SymbolIndicesToSymbolContextList(std::vector &symbol_indexes, SymbolContextList &sc_list); + void RegisterMangledNameEntry( + NameToIndexMap::Entry &entry, std::set &class_contexts, + std::vector> &backlog, + RichManglingContext &rmc); + + void RegisterBacklogEntry(const NameToIndexMap::Entry &entry, + const char *decl_context, + const std::set &class_contexts); + DISALLOW_COPY_AND_ASSIGN(Symtab); }; diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h index e3964268dfda..5bb910706681 100644 --- a/include/lldb/lldb-forward.h +++ b/include/lldb/lldb-forward.h @@ -191,6 +191,7 @@ class RegisterLocationList; class RegisterValue; class RegularExpression; class REPL; +class RichManglingContext; class Scalar; class ScriptInterpreter; class ScriptInterpreterLocker; @@ -492,5 +493,15 @@ typedef std::shared_ptr WatchpointSP; } // namespace lldb +//---------------------------------------------------------------------- +// llvm forward declarations +//---------------------------------------------------------------------- +namespace llvm { + +struct ItaniumPartialDemangler; +class StringRef; + +} // namespace llvm + #endif // #if defined(__cplusplus) #endif // LLDB_lldb_forward_h_ diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index d3d56fe7577e..9a3871152c61 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -487,6 +487,9 @@ 8C3BD9961EF45DA50016C343 /* MainThreadCheckerRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C3BD9951EF45D9B0016C343 /* MainThreadCheckerRuntime.cpp */; }; 2689004313353E0400698AC0 /* Mangled.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E8010F1B85900F91463 /* Mangled.cpp */; }; 4F29D3CF21010FA3003B549A /* MangledTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F29D3CD21010F84003B549A /* MangledTest.cpp */; }; + 4FBC04EF211A06820015A814 /* RichManglingContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 4FBC04EE211A06820015A814 /* RichManglingContext.h */; }; + 4FBC04ED211A06200015A814 /* RichManglingContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4FBC04EC211A06200015A814 /* RichManglingContext.cpp */; }; + 4FBC04F5211A13770015A814 /* RichManglingContextTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4FBC04F3211A0F0F0015A814 /* RichManglingContextTest.cpp */; }; 4CD44CFC20B37C440003557C /* ManualDWARFIndex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CD44CF920B37C440003557C /* ManualDWARFIndex.cpp */; }; 49DCF702170E70120092F75E /* Materializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DCF700170E70120092F75E /* Materializer.cpp */; }; 2690B3711381D5C300ECFBAE /* Memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2690B3701381D5C300ECFBAE /* Memory.cpp */; }; @@ -2198,6 +2201,9 @@ 26BC7E8010F1B85900F91463 /* Mangled.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Mangled.cpp; path = source/Core/Mangled.cpp; sourceTree = ""; }; 26BC7D6910F1B77400F91463 /* Mangled.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Mangled.h; path = include/lldb/Core/Mangled.h; sourceTree = ""; }; 4F29D3CD21010F84003B549A /* MangledTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MangledTest.cpp; sourceTree = ""; }; + 4FBC04EE211A06820015A814 /* RichManglingContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RichManglingContext.h; path = include/lldb/Core/RichManglingContext.h; sourceTree = ""; }; + 4FBC04EC211A06200015A814 /* RichManglingContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RichManglingContext.cpp; path = source/Core/RichManglingContext.cpp; sourceTree = ""; }; + 4FBC04F3211A0F0F0015A814 /* RichManglingContextTest.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RichManglingContextTest.cpp; sourceTree = ""; }; 4CD44CF920B37C440003557C /* ManualDWARFIndex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ManualDWARFIndex.cpp; sourceTree = ""; }; 4CD44D0020B37C580003557C /* ManualDWARFIndex.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ManualDWARFIndex.h; sourceTree = ""; }; 2682100C143A59AE004BCF2D /* MappedHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MappedHash.h; path = include/lldb/Core/MappedHash.h; sourceTree = ""; }; @@ -3676,13 +3682,14 @@ 23CB14E51D66CBEB00EDDDE1 /* Core */ = { isa = PBXGroup; children = ( + 23CB14E61D66CC0E00EDDDE1 /* BroadcasterTest.cpp */, + 23CB14E71D66CC0E00EDDDE1 /* CMakeLists.txt */, + 23CB14E81D66CC0E00EDDDE1 /* DataExtractorTest.cpp */, 58A080B12112AB2200D5580F /* HighlighterTest.cpp */, - 4F29D3CD21010F84003B549A /* MangledTest.cpp */, 9A3D43E31F3237D500EB767C /* ListenerTest.cpp */, + 4F29D3CD21010F84003B549A /* MangledTest.cpp */, + 4FBC04F3211A0F0F0015A814 /* RichManglingContextTest.cpp */, 9A3D43E11F3237D500EB767C /* StreamCallbackTest.cpp */, - 23CB14E71D66CC0E00EDDDE1 /* CMakeLists.txt */, - 23CB14E61D66CC0E00EDDDE1 /* BroadcasterTest.cpp */, - 23CB14E81D66CC0E00EDDDE1 /* DataExtractorTest.cpp */, ); path = Core; sourceTree = ""; @@ -5047,6 +5054,8 @@ 26BC7D7110F1B77400F91463 /* PluginManager.h */, 26BC7E8A10F1B85900F91463 /* PluginManager.cpp */, 2626B6AD143E1BEA00EF935C /* RangeMap.h */, + 4FBC04EE211A06820015A814 /* RichManglingContext.h */, + 4FBC04EC211A06200015A814 /* RichManglingContext.cpp */, 26BC7CF910F1B71400F91463 /* SearchFilter.h */, 26BC7E1510F1B83100F91463 /* SearchFilter.cpp */, 26BC7D7510F1B77400F91463 /* Section.h */, @@ -6955,6 +6964,7 @@ 2619C4862107A9A2009CDE81 /* RegisterContextMinidump_ARM64.h in Headers */, AF235EB11FBE77B6009C5541 /* RegisterContextPOSIX_ppc64le.h in Headers */, 267F68501CC02E270086832B /* RegisterContextPOSIXCore_s390x.h in Headers */, + 4FBC04EF211A06820015A814 /* RichManglingContext.h in Headers */, 4984BA181B979C08008658D4 /* ExpressionVariable.h in Headers */, 26C7C4841BFFEA7E009BD01F /* WindowsMiniDump.h in Headers */, 30B38A001CAAA6D7009524E3 /* ClangUtil.h in Headers */, @@ -7473,6 +7483,7 @@ 9A2057181F3B861400F6C293 /* TestType.cpp in Sources */, 9A2057171F3B861400F6C293 /* TestDWARFCallFrameInfo.cpp in Sources */, 4F29D3CF21010FA3003B549A /* MangledTest.cpp in Sources */, + 4FBC04F5211A13770015A814 /* RichManglingContextTest.cpp in Sources */, 9A3D43EC1F3237F900EB767C /* ListenerTest.cpp in Sources */, 9A3D43DC1F3151C400EB767C /* TimeoutTest.cpp in Sources */, 9A3D43D61F3151C400EB767C /* ConstStringTest.cpp in Sources */, @@ -7590,6 +7601,7 @@ 4C0083401B9F9BA900D5CF24 /* UtilityFunction.cpp in Sources */, AF415AE71D949E4400FCE0D4 /* x86AssemblyInspectionEngine.cpp in Sources */, 26474CCD18D0CB5B0073DEBA /* RegisterContextPOSIX_x86.cpp in Sources */, + 4FBC04ED211A06200015A814 /* RichManglingContext.cpp in Sources */, AEB0E4591BD6E9F800B24093 /* LLVMUserExpression.cpp in Sources */, 2689FFEF13353DB600698AC0 /* Breakpoint.cpp in Sources */, 267A47FB1B1411C40021A5BC /* NativeRegisterContext.cpp in Sources */, diff --git a/source/Core/CMakeLists.txt b/source/Core/CMakeLists.txt index b1c6593c1652..b746939213fa 100644 --- a/source/Core/CMakeLists.txt +++ b/source/Core/CMakeLists.txt @@ -34,6 +34,7 @@ add_lldb_library(lldbCore ModuleList.cpp Opcode.cpp PluginManager.cpp + RichManglingContext.cpp SearchFilter.cpp Section.cpp SourceManager.cpp diff --git a/source/Core/Mangled.cpp b/source/Core/Mangled.cpp index b8a43be10fbc..64d44958bdc1 100644 --- a/source/Core/Mangled.cpp +++ b/source/Core/Mangled.cpp @@ -16,6 +16,7 @@ #pragma comment(lib, "dbghelp.lib") #endif +#include "lldb/Core/RichManglingContext.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" @@ -232,6 +233,128 @@ void Mangled::SetValue(const ConstString &name) { } } +//---------------------------------------------------------------------- +// Local helpers for different demangling implementations. +//---------------------------------------------------------------------- +static char *GetMSVCDemangledStr(const char *M) { +#if defined(_MSC_VER) + const size_t demangled_length = 2048; + char *demangled_cstr = static_cast(::malloc(demangled_length)); + ::ZeroMemory(demangled_cstr, demangled_length); + DWORD result = safeUndecorateName(M, demangled_cstr, demangled_length); + + if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { + if (demangled_cstr && demangled_cstr[0]) + log->Printf("demangled msvc: %s -> \"%s\"", M, demangled_cstr); + else + log->Printf("demangled msvc: %s -> error: 0x%lu", M, result); + } + + if (result != 0) { + return demangled_cstr; + } else { + ::free(demangled_cstr); + return nullptr; + } +#else + return nullptr; +#endif +} + +static char *GetItaniumDemangledStr(const char *M, + llvm::ItaniumPartialDemangler &ipd) { + char *demangled_cstr = nullptr; + bool err = ipd.partialDemangle(M); + if (!err) { + // Default buffer and size (will realloc in case it's too small). + size_t demangled_size = 80; + demangled_cstr = static_cast(std::malloc(demangled_size)); + demangled_cstr = ipd.finishDemangle(demangled_cstr, &demangled_size); + + assert(demangled_cstr && + "finishDemangle must always succeed if partialDemangle did"); + assert(demangled_cstr[demangled_size - 1] == '\0' && + "Expected demangled_size to return length including trailing null"); + } + + if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { + if (demangled_cstr) + log->Printf("demangled itanium: %s -> \"%s\"", M, demangled_cstr); + else + log->Printf("demangled itanium: %s -> error: failed to demangle", M); + } + + return demangled_cstr; +} + +//---------------------------------------------------------------------- +// Explicit demangling for scheduled requests during batch processing. This +// makes use of ItaniumPartialDemangler's rich demangle info +//---------------------------------------------------------------------- +bool Mangled::DemangleWithRichManglingInfo( + RichManglingContext &context, SkipMangledNameFn *skip_mangled_name) { + // We need to generate and cache the demangled name. + static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); + Timer scoped_timer(func_cat, + "Mangled::DemangleWithRichNameIndexInfo (m_mangled = %s)", + m_mangled.GetCString()); + + // Others are not meant to arrive here. ObjC names or C's main() for example + // have their names stored in m_demangled, while m_mangled is empty. + assert(m_mangled); + + // Check whether or not we are interested in this name at all. + ManglingScheme scheme = cstring_mangling_scheme(m_mangled.GetCString()); + if (skip_mangled_name && skip_mangled_name(m_mangled.GetStringRef(), scheme)) + return false; + + switch (scheme) { + case eManglingSchemeNone: + // The current mangled_name_filter would allow llvm_unreachable here. + return false; + + case eManglingSchemeItanium: + // We want the rich mangling info here, so we don't care whether or not + // there is a demangled string in the pool already. + if (context.FromItaniumName(m_mangled)) { + // If we got an info, we have a name. Copy to string pool and connect the + // counterparts to accelerate later access in GetDemangledName(). + context.ParseFullName(); + m_demangled.SetStringWithMangledCounterpart(context.GetBufferRef(), + m_mangled); + return true; + } else { + m_demangled.SetCString(""); + return false; + } + + case eManglingSchemeMSVC: { + // We have no rich mangling for MSVC-mangled names yet, so first try to + // demangle it if necessary. + if (!m_demangled && !m_mangled.GetMangledCounterpart(m_demangled)) { + if (char *d = GetMSVCDemangledStr(m_mangled.GetCString())) { + // If we got an info, we have a name. Copy to string pool and connect + // the counterparts to accelerate later access in GetDemangledName(). + m_demangled.SetStringWithMangledCounterpart(llvm::StringRef(d), + m_mangled); + ::free(d); + } else { + m_demangled.SetCString(""); + } + } + + if (m_demangled.IsEmpty()) { + // Cannot demangle it, so don't try parsing. + return false; + } else { + // Demangled successfully, we can try and parse it with + // CPlusPlusLanguage::MethodName. + return context.FromCxxMethodName(m_demangled); + } + } + } +} + //---------------------------------------------------------------------- // Generate the demangled name on demand using this accessor. Code in this // class will need to use this accessor if it wishes to decode the demangled @@ -248,8 +371,6 @@ Mangled::GetDemangledName(lldb::LanguageType language) const { Timer scoped_timer(func_cat, "Mangled::GetDemangledName (m_mangled = %s)", m_mangled.GetCString()); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE); - // Don't bother running anything that isn't mangled const char *mangled_name = m_mangled.GetCString(); ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)}; @@ -259,56 +380,20 @@ Mangled::GetDemangledName(lldb::LanguageType language) const { // add it to our map. char *demangled_name = nullptr; switch (mangling_scheme) { - case eManglingSchemeMSVC: { -#if defined(_MSC_VER) - if (log) - log->Printf("demangle msvc: %s", mangled_name); - const size_t demangled_length = 2048; - demangled_name = static_cast(::malloc(demangled_length)); - ::ZeroMemory(demangled_name, demangled_length); - DWORD result = - safeUndecorateName(mangled_name, demangled_name, demangled_length); - if (log) { - if (demangled_name && demangled_name[0]) - log->Printf("demangled msvc: %s -> \"%s\"", mangled_name, - demangled_name); - else - log->Printf("demangled msvc: %s -> error: 0x%lu", mangled_name, - result); - } - - if (result == 0) { - free(demangled_name); - demangled_name = nullptr; - } -#endif + case eManglingSchemeMSVC: + demangled_name = GetMSVCDemangledStr(mangled_name); break; - } case eManglingSchemeItanium: { - llvm::ItaniumPartialDemangler IPD; - bool demangle_err = IPD.partialDemangle(mangled_name); - if (!demangle_err) { - // Default buffer and size (realloc is used in case it's too small). - size_t demangled_size = 80; - demangled_name = static_cast(::malloc(demangled_size)); - demangled_name = IPD.finishDemangle(demangled_name, &demangled_size); - } - - if (log) { - if (demangled_name) - log->Printf("demangled itanium: %s -> \"%s\"", mangled_name, - demangled_name); - else - log->Printf("demangled itanium: %s -> error: failed to demangle", - mangled_name); - } + llvm::ItaniumPartialDemangler ipd; + demangled_name = GetItaniumDemangledStr(mangled_name, ipd); break; } case eManglingSchemeNone: - break; + llvm_unreachable("eManglingSchemeNone was handled already"); } if (demangled_name) { - m_demangled.SetStringWithMangledCounterpart(demangled_name, m_mangled); + m_demangled.SetStringWithMangledCounterpart( + llvm::StringRef(demangled_name), m_mangled); free(demangled_name); } } diff --git a/source/Core/RichManglingContext.cpp b/source/Core/RichManglingContext.cpp new file mode 100644 index 000000000000..da009e4ddf43 --- /dev/null +++ b/source/Core/RichManglingContext.cpp @@ -0,0 +1,178 @@ +//===-- RichManglingContext.cpp ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/RichManglingContext.h" + +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" + +#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" + +#include "llvm/ADT/StringRef.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// RichManglingContext +//---------------------------------------------------------------------- +void RichManglingContext::ResetProvider(InfoProvider new_provider) { + // If we want to support parsers for other languages some day, we need a + // switch here to delete the correct parser type. + if (m_cxx_method_parser.hasValue()) { + assert(m_provider == PluginCxxLanguage); + delete get(m_cxx_method_parser); + m_cxx_method_parser.reset(); + } + + assert(new_provider != None && "Only reset to a valid provider"); + m_provider = new_provider; +} + +bool RichManglingContext::FromItaniumName(const ConstString &mangled) { + bool err = m_ipd.partialDemangle(mangled.GetCString()); + if (!err) { + ResetProvider(ItaniumPartialDemangler); + } + + if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { + if (!err) { + ParseFullName(); + LLDB_LOG(log, "demangled itanium: {0} -> \"{1}\"", mangled, m_ipd_buf); + } else { + LLDB_LOG(log, "demangled itanium: {0} -> error: failed to demangle", + mangled); + } + } + + return !err; // true == success +} + +bool RichManglingContext::FromCxxMethodName(const ConstString &demangled) { + ResetProvider(PluginCxxLanguage); + m_cxx_method_parser = new CPlusPlusLanguage::MethodName(demangled); + return true; +} + +bool RichManglingContext::IsCtorOrDtor() const { + assert(m_provider != None && "Initialize a provider first"); + switch (m_provider) { + case ItaniumPartialDemangler: + return m_ipd.isCtorOrDtor(); + case PluginCxxLanguage: { + // We can only check for destructors here. + auto base_name = + get(m_cxx_method_parser)->GetBasename(); + return base_name.startswith("~"); + } + case None: + return false; + } +} + +bool RichManglingContext::IsFunction() const { + assert(m_provider != None && "Initialize a provider first"); + switch (m_provider) { + case ItaniumPartialDemangler: + return m_ipd.isFunction(); + case PluginCxxLanguage: + return get(m_cxx_method_parser)->IsValid(); + case None: + return false; + } +} + +void RichManglingContext::processIPDStrResult(char *ipd_res, size_t res_size) { + if (LLVM_UNLIKELY(ipd_res == nullptr)) { + assert(res_size == m_ipd_buf_size && + "Failed IPD queries keep the original size in the N parameter"); + + // Error case: Clear the buffer. + m_ipd_str_len = 0; + m_ipd_buf[m_ipd_str_len] = '\0'; + } else { + // IPD's res_size includes null terminator. + size_t res_len = res_size - 1; + assert(ipd_res[res_len] == '\0' && + "IPD returns null-terminated strings and we rely on that"); + + if (LLVM_UNLIKELY(ipd_res != m_ipd_buf)) { + // Realloc case: Take over the new buffer. + m_ipd_buf = ipd_res; // std::realloc freed or reused the old buffer. + m_ipd_buf_size = + res_size; // Actual buffer may be bigger, but we can't know. + m_ipd_str_len = res_len; + + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE); + if (log) + log->Printf("ItaniumPartialDemangler Realloc: new buffer size %lu", + m_ipd_buf_size); + } else { + // 99% case: Just remember the string length. + m_ipd_str_len = res_len; + } + } + + m_buffer = llvm::StringRef(m_ipd_buf, m_ipd_str_len); +} + +void RichManglingContext::ParseFunctionBaseName() { + assert(m_provider != None && "Initialize a provider first"); + switch (m_provider) { + case ItaniumPartialDemangler: { + auto n = m_ipd_buf_size; + auto buf = m_ipd.getFunctionBaseName(m_ipd_buf, &n); + processIPDStrResult(buf, n); + return; + } + case PluginCxxLanguage: + m_buffer = + get(m_cxx_method_parser)->GetBasename(); + return; + case None: + return; + } +} + +void RichManglingContext::ParseFunctionDeclContextName() { + assert(m_provider != None && "Initialize a provider first"); + switch (m_provider) { + case ItaniumPartialDemangler: { + auto n = m_ipd_buf_size; + auto buf = m_ipd.getFunctionDeclContextName(m_ipd_buf, &n); + processIPDStrResult(buf, n); + return; + } + case PluginCxxLanguage: + m_buffer = + get(m_cxx_method_parser)->GetContext(); + return; + case None: + return; + } +} + +void RichManglingContext::ParseFullName() { + assert(m_provider != None && "Initialize a provider first"); + switch (m_provider) { + case ItaniumPartialDemangler: { + auto n = m_ipd_buf_size; + auto buf = m_ipd.finishDemangle(m_ipd_buf, &n); + processIPDStrResult(buf, n); + return; + } + case PluginCxxLanguage: + m_buffer = get(m_cxx_method_parser) + ->GetFullName() + .GetStringRef(); + return; + case None: + return; + } +} diff --git a/source/Symbol/Symtab.cpp b/source/Symbol/Symtab.cpp index c502b18555f0..96b31154492e 100644 --- a/source/Symbol/Symtab.cpp +++ b/source/Symbol/Symtab.cpp @@ -10,9 +10,10 @@ #include #include -#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" + #include "lldb/Core/Module.h" +#include "lldb/Core/RichManglingContext.h" #include "lldb/Core/STLUtils.h" #include "lldb/Core/Section.h" #include "lldb/Symbol/ObjectFile.h" @@ -23,6 +24,8 @@ #include "lldb/Utility/Stream.h" #include "lldb/Utility/Timer.h" +#include "llvm/ADT/StringRef.h" + using namespace lldb; using namespace lldb_private; @@ -215,6 +218,39 @@ const Symbol *Symtab::SymbolAtIndex(size_t idx) const { //---------------------------------------------------------------------- // InitNameIndexes //---------------------------------------------------------------------- +static bool lldb_skip_name(llvm::StringRef mangled, + Mangled::ManglingScheme scheme) { + switch (scheme) { + case Mangled::eManglingSchemeItanium: { + if (mangled.size() < 3 || !mangled.startswith("_Z")) + return true; + + // Avoid the following types of symbols in the index. + switch (mangled[2]) { + case 'G': // guard variables + case 'T': // virtual tables, VTT structures, typeinfo structures + names + case 'Z': // named local entities (if we eventually handle + // eSymbolTypeData, we will want this back) + return true; + + default: + break; + } + + // Include this name in the index. + return false; + } + + // No filters for this scheme yet. Include all names in indexing. + case Mangled::eManglingSchemeMSVC: + return false; + + // Don't try and demangle things we can't categorize. + case Mangled::eManglingSchemeNone: + return true; + } +} + void Symtab::InitNameIndexes() { // Protected function, no need to lock mutex... if (!m_name_indexes_computed) { @@ -243,16 +279,19 @@ void Symtab::InitNameIndexes() { m_name_to_index.Reserve(actual_count); #endif - NameToIndexMap::Entry entry; - - // The "const char *" in "class_contexts" must come from a - // ConstString::GetCString() + // The "const char *" in "class_contexts" and backlog::value_type::second + // must come from a ConstString::GetCString() std::set class_contexts; - UniqueCStringMap mangled_name_to_index; - std::vector symbol_contexts(num_symbols, nullptr); + std::vector> backlog; + backlog.reserve(num_symbols / 2); + + // Instantiation of the demangler is expensive, so better use a single one + // for all entries during batch processing. + RichManglingContext rmc; + NameToIndexMap::Entry entry; for (entry.value = 0; entry.value < num_symbols; ++entry.value) { - const Symbol *symbol = &m_symbols[entry.value]; + Symbol *symbol = &m_symbols[entry.value]; // Don't let trampolines get into the lookup by name map If we ever need // the trampoline symbols to be searchable by name we can remove this and @@ -261,7 +300,9 @@ void Symtab::InitNameIndexes() { if (symbol->IsTrampoline()) continue; - const Mangled &mangled = symbol->GetMangled(); + // If the symbol's name string matched a Mangled::ManglingScheme, it is + // stored in the mangled field. + Mangled &mangled = symbol->GetMangled(); entry.cstring = mangled.GetMangledName(); if (entry.cstring) { m_name_to_index.Append(entry); @@ -274,70 +315,15 @@ void Symtab::InitNameIndexes() { m_name_to_index.Append(entry); } - const SymbolType symbol_type = symbol->GetType(); - if (symbol_type == eSymbolTypeCode || - symbol_type == eSymbolTypeResolver) { - llvm::StringRef entry_ref(entry.cstring.GetStringRef()); - if (entry_ref[0] == '_' && entry_ref[1] == 'Z' && - (entry_ref[2] != 'T' && // avoid virtual table, VTT structure, - // typeinfo structure, and typeinfo - // name - entry_ref[2] != 'G' && // avoid guard variables - entry_ref[2] != 'Z')) // named local entities (if we - // eventually handle eSymbolTypeData, - // we will want this back) - { - CPlusPlusLanguage::MethodName cxx_method( - mangled.GetDemangledName(lldb::eLanguageTypeC_plus_plus)); - entry.cstring = ConstString(cxx_method.GetBasename()); - if (entry.cstring) { - // ConstString objects permanently store the string in the pool - // so calling GetCString() on the value gets us a const char * - // that will never go away - const char *const_context = - ConstString(cxx_method.GetContext()).GetCString(); - - if (!const_context || const_context[0] == 0) { - // No context for this function so this has to be a basename - m_basename_to_index.Append(entry); - // If there is no context (no namespaces or class scopes that - // come before the function name) then this also could be a - // fullname. - m_name_to_index.Append(entry); - } else { - entry_ref = entry.cstring.GetStringRef(); - if (entry_ref[0] == '~' || - !cxx_method.GetQualifiers().empty()) { - // The first character of the demangled basename is '~' which - // means we have a class destructor. We can use this - // information to help us know what is a class and what - // isn't. - if (class_contexts.find(const_context) == class_contexts.end()) - class_contexts.insert(const_context); - m_method_to_index.Append(entry); - } else { - if (class_contexts.find(const_context) != - class_contexts.end()) { - // The current decl context is in our "class_contexts" - // which means this is a method on a class - m_method_to_index.Append(entry); - } else { - // We don't know if this is a function basename or a - // method, so put it into a temporary collection so once we - // are done we can look in class_contexts to see if each - // entry is a class or just a function and will put any - // remaining items into m_method_to_index or - // m_basename_to_index as needed - mangled_name_to_index.Append(entry); - symbol_contexts[entry.value] = const_context; - } - } - } - } - } + const SymbolType type = symbol->GetType(); + if (type == eSymbolTypeCode || type == eSymbolTypeResolver) { + if (mangled.DemangleWithRichManglingInfo(rmc, lldb_skip_name)) + RegisterMangledNameEntry(entry, class_contexts, backlog, rmc); } } + // Symbol name strings that didn't match a Mangled::ManglingScheme, are + // stored in the demangled field. entry.cstring = mangled.GetDemangledName(symbol->GetLanguage()); if (entry.cstring) { m_name_to_index.Append(entry); @@ -367,25 +353,10 @@ void Symtab::InitNameIndexes() { } } - size_t count; - if (!mangled_name_to_index.IsEmpty()) { - count = mangled_name_to_index.GetSize(); - for (size_t i = 0; i < count; ++i) { - if (mangled_name_to_index.GetValueAtIndex(i, entry.value)) { - entry.cstring = mangled_name_to_index.GetCStringAtIndex(i); - if (symbol_contexts[entry.value] && - class_contexts.find(symbol_contexts[entry.value]) != - class_contexts.end()) { - m_method_to_index.Append(entry); - } else { - // If we got here, we have something that had a context (was inside - // a namespace or class) yet we don't know if the entry - m_method_to_index.Append(entry); - m_basename_to_index.Append(entry); - } - } - } + for (const auto &record : backlog) { + RegisterBacklogEntry(record.first, record.second, class_contexts); } + m_name_to_index.Sort(); m_name_to_index.SizeToFit(); m_selector_to_index.Sort(); @@ -397,6 +368,71 @@ void Symtab::InitNameIndexes() { } } +void Symtab::RegisterMangledNameEntry( + NameToIndexMap::Entry &entry, std::set &class_contexts, + std::vector> &backlog, + RichManglingContext &rmc) { + // Only register functions that have a base name. + rmc.ParseFunctionBaseName(); + llvm::StringRef base_name = rmc.GetBufferRef(); + if (base_name.empty()) + return; + + // The base name will be our entry's name. + entry.cstring = ConstString(base_name); + + rmc.ParseFunctionDeclContextName(); + llvm::StringRef decl_context = rmc.GetBufferRef(); + + // Register functions with no context. + if (decl_context.empty()) { + // This has to be a basename + m_basename_to_index.Append(entry); + // If there is no context (no namespaces or class scopes that come before + // the function name) then this also could be a fullname. + m_name_to_index.Append(entry); + return; + } + + // Make sure we have a pool-string pointer and see if we already know the + // context name. + const char *decl_context_ccstr = ConstString(decl_context).GetCString(); + auto it = class_contexts.find(decl_context_ccstr); + + // Register constructors and destructors. They are methods and create + // declaration contexts. + if (rmc.IsCtorOrDtor()) { + m_method_to_index.Append(entry); + if (it == class_contexts.end()) + class_contexts.insert(it, decl_context_ccstr); + return; + } + + // Register regular methods with a known declaration context. + if (it != class_contexts.end()) { + m_method_to_index.Append(entry); + return; + } + + // Regular methods in unknown declaration contexts are put to the backlog. We + // will revisit them once we processed all remaining symbols. + backlog.push_back(std::make_pair(entry, decl_context_ccstr)); +} + +void Symtab::RegisterBacklogEntry( + const NameToIndexMap::Entry &entry, const char *decl_context, + const std::set &class_contexts) { + auto it = class_contexts.find(decl_context); + if (it != class_contexts.end()) { + m_method_to_index.Append(entry); + } else { + // If we got here, we have something that had a context (was inside + // a namespace or class) yet we don't know the entry + m_method_to_index.Append(entry); + m_basename_to_index.Append(entry); + } +} + void Symtab::PreloadSymbols() { std::lock_guard guard(m_mutex); InitNameIndexes(); diff --git a/unittests/Core/CMakeLists.txt b/unittests/Core/CMakeLists.txt index f34df10eda88..88187c2409c2 100644 --- a/unittests/Core/CMakeLists.txt +++ b/unittests/Core/CMakeLists.txt @@ -4,6 +4,7 @@ add_lldb_unittest(LLDBCoreTests EventTest.cpp ListenerTest.cpp MangledTest.cpp + RichManglingContextTest.cpp StreamCallbackTest.cpp LINK_LIBS diff --git a/unittests/Core/RichManglingContextTest.cpp b/unittests/Core/RichManglingContextTest.cpp new file mode 100644 index 000000000000..bf680999f19e --- /dev/null +++ b/unittests/Core/RichManglingContextTest.cpp @@ -0,0 +1,114 @@ +//===-- RichManglingContextTest.cpp -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/RichManglingContext.h" + +#include "lldb/Utility/ConstString.h" + +#include "gtest/gtest.h" + +using namespace lldb; +using namespace lldb_private; + +TEST(RichManglingContextTest, Basic) { + RichManglingContext RMC; + ConstString mangled("_ZN3foo3barEv"); + EXPECT_TRUE(RMC.FromItaniumName(mangled)); + + EXPECT_TRUE(RMC.IsFunction()); + EXPECT_FALSE(RMC.IsCtorOrDtor()); + + RMC.ParseFunctionDeclContextName(); + EXPECT_EQ("foo", RMC.GetBufferRef()); + + RMC.ParseFunctionBaseName(); + EXPECT_EQ("bar", RMC.GetBufferRef()); + + RMC.ParseFullName(); + EXPECT_EQ("foo::bar()", RMC.GetBufferRef()); +} + +TEST(RichManglingContextTest, FromCxxMethodName) { + RichManglingContext ItaniumRMC; + ConstString mangled("_ZN3foo3barEv"); + EXPECT_TRUE(ItaniumRMC.FromItaniumName(mangled)); + + RichManglingContext CxxMethodRMC; + ConstString demangled("foo::bar()"); + EXPECT_TRUE(CxxMethodRMC.FromCxxMethodName(demangled)); + + EXPECT_TRUE(ItaniumRMC.IsFunction() == CxxMethodRMC.IsFunction()); + EXPECT_TRUE(ItaniumRMC.IsCtorOrDtor() == CxxMethodRMC.IsCtorOrDtor()); + + ItaniumRMC.ParseFunctionDeclContextName(); + CxxMethodRMC.ParseFunctionDeclContextName(); + EXPECT_TRUE(ItaniumRMC.GetBufferRef() == CxxMethodRMC.GetBufferRef()); + + ItaniumRMC.ParseFunctionBaseName(); + CxxMethodRMC.ParseFunctionBaseName(); + EXPECT_TRUE(ItaniumRMC.GetBufferRef() == CxxMethodRMC.GetBufferRef()); + + ItaniumRMC.ParseFullName(); + CxxMethodRMC.ParseFullName(); + EXPECT_TRUE(ItaniumRMC.GetBufferRef() == CxxMethodRMC.GetBufferRef()); +} + +TEST(RichManglingContextTest, SwitchProvider) { + RichManglingContext RMC; + llvm::StringRef mangled = "_ZN3foo3barEv"; + llvm::StringRef demangled = "foo::bar()"; + + EXPECT_TRUE(RMC.FromItaniumName(ConstString(mangled))); + RMC.ParseFullName(); + EXPECT_EQ("foo::bar()", RMC.GetBufferRef()); + + EXPECT_TRUE(RMC.FromCxxMethodName(ConstString(demangled))); + RMC.ParseFullName(); + EXPECT_EQ("foo::bar()", RMC.GetBufferRef()); + + EXPECT_TRUE(RMC.FromItaniumName(ConstString(mangled))); + RMC.ParseFullName(); + EXPECT_EQ("foo::bar()", RMC.GetBufferRef()); +} + +TEST(RichManglingContextTest, IPDRealloc) { + // The demangled name should fit into the Itanium default buffer. + const char *short_mangled = "_ZN3foo3barEv"; + + // The demangled name for this will certainly not fit into the default buffer. + const char *long_mangled = + "_ZNK3shk6detail17CallbackPublisherIZNS_5ThrowERKNSt15__exception_" + "ptr13exception_ptrEEUlOT_E_E9SubscribeINS0_9ConcatMapINS0_" + "18CallbackSubscriberIZNS_6GetAllIiNS1_IZZNS_9ConcatMapIZNS_6ConcatIJNS1_" + "IZZNS_3MapIZZNS_7IfEmptyIS9_EEDaS7_ENKUlS6_E_clINS1_IZZNS_4TakeIiEESI_" + "S7_ENKUlS6_E_clINS1_IZZNS_6FilterIZNS_9ElementAtEmEUlS7_E_EESI_S7_" + "ENKUlS6_E_clINS1_IZZNSL_ImEESI_S7_ENKUlS6_E_clINS1_IZNS_4FromINS0_" + "22InfiniteRangeContainerIiEEEESI_S7_EUlS7_E_EEEESI_S6_EUlS7_E_EEEESI_S6_" + "EUlS7_E_EEEESI_S6_EUlS7_E_EEEESI_S6_EUlS7_E_EESI_S7_ENKUlS6_E_clIS14_" + "EESI_S6_EUlS7_E_EERNS1_IZZNSH_IS9_EESI_S7_ENKSK_IS14_EESI_S6_EUlS7_E0_" + "EEEEESI_DpOT_EUlS7_E_EESI_S7_ENKUlS6_E_clINS1_IZNS_5StartIJZNS_" + "4JustIJS19_S1C_EEESI_S1F_EUlvE_ZNS1K_IJS19_S1C_EEESI_S1F_EUlvE0_EEESI_" + "S1F_EUlS7_E_EEEESI_S6_EUlS7_E_EEEESt6vectorIS6_SaIS6_EERKT0_NS_" + "12ElementCountEbEUlS7_E_ZNSD_IiS1Q_EES1T_S1W_S1X_bEUlOS3_E_ZNSD_IiS1Q_" + "EES1T_S1W_S1X_bEUlvE_EES1G_S1O_E25ConcatMapValuesSubscriberEEEDaS7_"; + + RichManglingContext RMC; + + // Demangle the short one and remember the buffer address. + EXPECT_TRUE(RMC.FromItaniumName(ConstString(short_mangled))); + RMC.ParseFullName(); + const char *short_demangled_ptr = RMC.GetBufferRef().data(); + + // Demangle the long one and make sure the buffer address changed. + EXPECT_TRUE(RMC.FromItaniumName(ConstString(long_mangled))); + RMC.ParseFullName(); + const char *long_demangled_ptr = RMC.GetBufferRef().data(); + + EXPECT_TRUE(short_demangled_ptr != long_demangled_ptr); +} From a063373af4d295e48017ca218d1030aac13b0af5 Mon Sep 17 00:00:00 2001 From: Stefan Granitz Date: Wed, 8 Aug 2018 21:57:42 +0000 Subject: [PATCH 0085/1112] Add ConstString test FromMidOfBufferStringRef Summary: It was not immediately clear to me whether or not non-null-terminated StringRef's are supported in ConstString and/or the counterpart mechanism. From this test it seems to be fine. Maybe useful to keep? Reviewers: labath Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D50334 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339292 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/Utility/ConstStringTest.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/unittests/Utility/ConstStringTest.cpp b/unittests/Utility/ConstStringTest.cpp index add76a012e1d..5ad6ea986bd0 100644 --- a/unittests/Utility/ConstStringTest.cpp +++ b/unittests/Utility/ConstStringTest.cpp @@ -34,6 +34,26 @@ TEST(ConstStringTest, MangledCounterpart) { EXPECT_EQ("bar", counterpart.GetStringRef()); } +TEST(ConstStringTest, FromMidOfBufferStringRef) { + // StringRef's into bigger buffer: no null termination + const char *buffer = "foobarbaz"; + llvm::StringRef foo_ref(buffer, 3); + llvm::StringRef bar_ref(buffer + 3, 3); + + ConstString foo(foo_ref); + + ConstString bar; + bar.SetStringWithMangledCounterpart(bar_ref, foo); + EXPECT_EQ("bar", bar.GetStringRef()); + + ConstString counterpart; + EXPECT_TRUE(bar.GetMangledCounterpart(counterpart)); + EXPECT_EQ("foo", counterpart.GetStringRef()); + + EXPECT_TRUE(foo.GetMangledCounterpart(counterpart)); + EXPECT_EQ("bar", counterpart.GetStringRef()); +} + TEST(ConstStringTest, NullAndEmptyStates) { ConstString foo("foo"); EXPECT_FALSE(!foo); From 16328ba78b30be86a940194638c64aa1e2e9c063 Mon Sep 17 00:00:00 2001 From: Tatyana Krasnukha Date: Thu, 9 Aug 2018 11:42:28 +0000 Subject: [PATCH 0086/1112] Remove unused type Either from Utility library. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339328 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Utility/Either.h | 162 +++++++++++---------------------- lldb.xcodeproj/project.pbxproj | 2 - 2 files changed, 54 insertions(+), 110 deletions(-) diff --git a/include/lldb/Utility/Either.h b/include/lldb/Utility/Either.h index 0dc340b64e86..ec683096859b 100644 --- a/include/lldb/Utility/Either.h +++ b/include/lldb/Utility/Either.h @@ -12,115 +12,61 @@ #include "llvm/ADT/Optional.h" -#include - namespace lldb_utility { -template class Either { -private: - enum class Selected { One, Two }; - - Selected m_selected; - union { - T1 m_t1; - T2 m_t2; - }; - -public: - Either(const T1 &t1) { - m_t1 = t1; - m_selected = Selected::One; - } - - Either(const T2 &t2) { - m_t2 = t2; - m_selected = Selected::Two; - } - - Either(const Either &rhs) { - switch (rhs.m_selected) { - case Selected::One: - m_t1 = rhs.GetAs().getValue(); - m_selected = Selected::One; - break; - case Selected::Two: - m_t2 = rhs.GetAs().getValue(); - m_selected = Selected::Two; - break; - } - } - - template ::value>::type - * = nullptr> - llvm::Optional GetAs() const { - switch (m_selected) { - case Selected::One: - return m_t1; - default: - return llvm::Optional(); - } - } - - template ::value>::type - * = nullptr> - llvm::Optional GetAs() const { - switch (m_selected) { - case Selected::Two: - return m_t2; - default: - return llvm::Optional(); - } - } - - template - ResultType Apply(std::function if_T1, - std::function if_T2) const { - switch (m_selected) { - case Selected::One: - return if_T1(m_t1); - case Selected::Two: - return if_T2(m_t2); - } - } - - bool operator==(const Either &rhs) { - return (GetAs() == rhs.GetAs()) && (GetAs() == rhs.GetAs()); - } - - explicit operator bool() { - switch (m_selected) { - case Selected::One: - return (bool)m_t1; - case Selected::Two: - return (bool)m_t2; - } - } - - Either &operator=(const Either &rhs) { - switch (rhs.m_selected) { - case Selected::One: - m_t1 = rhs.GetAs().getValue(); - m_selected = Selected::One; - break; - case Selected::Two: - m_t2 = rhs.GetAs().getValue(); - m_selected = Selected::Two; - break; - } - return *this; - } - - ~Either() { - switch (m_selected) { - case Selected::One: - m_t1.T1::~T1(); - break; - case Selected::Two: - m_t2.T2::~T2(); - break; - } - } -}; - + template + class Either { + private: + enum class Selected { + One, Two + }; + + Selected m_selected; + union { + T1 m_t1; + T2 m_t2; + }; + + public: + Either(const T1& t1) + { + m_t1 = t1; + m_selected = Selected::One; + } + + Either(const T2& t2) + { + m_t2 = t2; + m_selected = Selected::Two; + } + + template ::value>::type * = nullptr > + llvm::Optional + GetAs() + { + switch (m_selected) + { + case Selected::One: + return m_t1; + default: + return llvm::Optional(); + } + } + + template ::value>::type * = nullptr > + llvm::Optional + GetAs() + { + switch (m_selected) + { + case Selected::Two: + return m_t2; + default: + return llvm::Optional(); + } + } + }; + } // namespace lldb_utility #endif // #ifndef liblldb_Either_h_ + diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index 9a3871152c61..e4e92a2738cc 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -1777,7 +1777,6 @@ 26CFDCA2186163A4000E63E5 /* Editline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Editline.cpp; sourceTree = ""; }; 26CFDCA01861638D000E63E5 /* Editline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Editline.h; path = include/lldb/Host/Editline.h; sourceTree = ""; }; 2326CF511BDD693B00A5CEAC /* EditlineTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditlineTest.cpp; sourceTree = ""; }; - 9481FE6B1B5F2D9200DED357 /* Either.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Either.h; path = include/lldb/Utility/Either.h; sourceTree = ""; }; 26D9FDC812F784FD0003F2EE /* EmulateInstruction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = EmulateInstruction.cpp; path = source/Core/EmulateInstruction.cpp; sourceTree = ""; }; 26D9FDC612F784E60003F2EE /* EmulateInstruction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EmulateInstruction.h; path = include/lldb/Core/EmulateInstruction.h; sourceTree = ""; }; 9A22A15D135E30370024DDC3 /* EmulateInstructionARM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EmulateInstructionARM.cpp; sourceTree = ""; }; @@ -4510,7 +4509,6 @@ 49CA96E81E6AAC6600C03FEE /* DataEncoder.cpp */, 49CA96F41E6AAC8E00C03FEE /* DataExtractor.h */, 49CA96E91E6AAC6600C03FEE /* DataExtractor.cpp */, - 9481FE6B1B5F2D9200DED357 /* Either.h */, 26BC7DD310F1B7D500F91463 /* Endian.h */, AFC2DCE61E6E2ED000283714 /* FastDemangle.cpp */, AFC2DCED1E6E2F9800283714 /* FastDemangle.h */, From 37f3c8e7b2d0551a9d7b3268ef34c0481cf2a1a2 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Thu, 9 Aug 2018 13:21:05 +0000 Subject: [PATCH 0087/1112] Darwin: mark test unsupported while we sort out how to make it generic. This test relies on communicating with debugserver via an unnamed (pre-opened) pipe, but macOS's version of debugserver doesn't seem to support that mode of operation. So disable the test for now. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339343 91177308-0d34-0410-b5e6-96231b3b80d8 --- lit/tools/lldb-mi/target/target-select-so-path.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lit/tools/lldb-mi/target/target-select-so-path.test b/lit/tools/lldb-mi/target/target-select-so-path.test index f5e2df952b86..33ba1fd4635d 100644 --- a/lit/tools/lldb-mi/target/target-select-so-path.test +++ b/lit/tools/lldb-mi/target/target-select-so-path.test @@ -1,4 +1,4 @@ -# UNSUPPORTED: windows +# UNSUPPORTED: windows, darwin # # RUN: %cc -o %t %p/inputs/main.c -g # RUN: python %p/inputs/target-select-so-path.py "%debugserver" "%lldbmi %t" %s From 3f0e16cfe858eea5010f70606d2ba9a170263bf0 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 9 Aug 2018 15:29:32 +0000 Subject: [PATCH 0088/1112] Also display the output and error output of a failed command Summary: Instead of just printing the current "False is not True, ..." message when we fail to run a certain command, this patch also adds the actual command output or error output that we received to the assertion message. Reviewers: davide Reviewed By: davide Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D50492 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339351 91177308-0d34-0410-b5e6-96231b3b80d8 --- packages/Python/lldbsuite/test/lldbtest.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/Python/lldbsuite/test/lldbtest.py b/packages/Python/lldbsuite/test/lldbtest.py index 1b6302ae96a6..1c8b1d6bc228 100644 --- a/packages/Python/lldbsuite/test/lldbtest.py +++ b/packages/Python/lldbsuite/test/lldbtest.py @@ -2074,8 +2074,13 @@ def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False): print("Command '" + cmd + "' failed!", file=sbuf) if check: + output = "" + if self.res.GetOutput(): + output += "\nCommand output:\n" + self.res.GetOutput() + if self.res.GetError(): + output += "\nError output:\n" + self.res.GetError() self.assertTrue(self.res.Succeeded(), - msg if msg else CMD_MSG(cmd)) + msg if (msg + output) else CMD_MSG(cmd + output)) def match( self, From e14404bf267370a20f39e5b7efc2f583f8885542 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Thu, 9 Aug 2018 15:57:43 +0000 Subject: [PATCH 0089/1112] Added missing null checks to fix r339351 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339353 91177308-0d34-0410-b5e6-96231b3b80d8 --- packages/Python/lldbsuite/test/lldbtest.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/Python/lldbsuite/test/lldbtest.py b/packages/Python/lldbsuite/test/lldbtest.py index 1c8b1d6bc228..b287a0feea1c 100644 --- a/packages/Python/lldbsuite/test/lldbtest.py +++ b/packages/Python/lldbsuite/test/lldbtest.py @@ -2079,8 +2079,12 @@ def runCmd(self, cmd, msg=None, check=True, trace=False, inHistory=False): output += "\nCommand output:\n" + self.res.GetOutput() if self.res.GetError(): output += "\nError output:\n" + self.res.GetError() + if msg: + msg += output + if cmd: + cmd += output self.assertTrue(self.res.Succeeded(), - msg if (msg + output) else CMD_MSG(cmd + output)) + msg if (msg) else CMD_MSG(cmd)) def match( self, From 9aee5b8e3eedd0ef5c3a479d5306c482bfbb8b71 Mon Sep 17 00:00:00 2001 From: Fred Riss Date: Thu, 9 Aug 2018 16:33:40 -0700 Subject: [PATCH 0090/1112] Fix the lldb-gtest target --- lldb.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index 34e94e510cf9..f647654ae56f 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -10084,7 +10084,7 @@ "$(inherited)", ); PATH = /opt/local/bin; - PRODUCT_NAME = "lib$(TARGET_NAME)"; + PRODUCT_NAME = "lldb-gtest"; SKIP_INSTALL = YES; STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = static; USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/lib/Target/ARM"; From 45ecb21d5df9541ce91411171852d38fecc1547f Mon Sep 17 00:00:00 2001 From: Fred Riss Date: Thu, 9 Aug 2018 16:41:39 -0700 Subject: [PATCH 0091/1112] Revert "Remove unused type Either from Utility library." This reverts commit 16328ba78b30be86a940194638c64aa1e2e9c063. The Swift debugger uses the type. --- include/lldb/Utility/Either.h | 162 ++++++++++++++++++++++----------- lldb.xcodeproj/project.pbxproj | 2 + 2 files changed, 110 insertions(+), 54 deletions(-) diff --git a/include/lldb/Utility/Either.h b/include/lldb/Utility/Either.h index ec683096859b..0dc340b64e86 100644 --- a/include/lldb/Utility/Either.h +++ b/include/lldb/Utility/Either.h @@ -12,61 +12,115 @@ #include "llvm/ADT/Optional.h" +#include + namespace lldb_utility { - template - class Either { - private: - enum class Selected { - One, Two - }; - - Selected m_selected; - union { - T1 m_t1; - T2 m_t2; - }; - - public: - Either(const T1& t1) - { - m_t1 = t1; - m_selected = Selected::One; - } - - Either(const T2& t2) - { - m_t2 = t2; - m_selected = Selected::Two; - } - - template ::value>::type * = nullptr > - llvm::Optional - GetAs() - { - switch (m_selected) - { - case Selected::One: - return m_t1; - default: - return llvm::Optional(); - } - } - - template ::value>::type * = nullptr > - llvm::Optional - GetAs() - { - switch (m_selected) - { - case Selected::Two: - return m_t2; - default: - return llvm::Optional(); - } - } - }; - +template class Either { +private: + enum class Selected { One, Two }; + + Selected m_selected; + union { + T1 m_t1; + T2 m_t2; + }; + +public: + Either(const T1 &t1) { + m_t1 = t1; + m_selected = Selected::One; + } + + Either(const T2 &t2) { + m_t2 = t2; + m_selected = Selected::Two; + } + + Either(const Either &rhs) { + switch (rhs.m_selected) { + case Selected::One: + m_t1 = rhs.GetAs().getValue(); + m_selected = Selected::One; + break; + case Selected::Two: + m_t2 = rhs.GetAs().getValue(); + m_selected = Selected::Two; + break; + } + } + + template ::value>::type + * = nullptr> + llvm::Optional GetAs() const { + switch (m_selected) { + case Selected::One: + return m_t1; + default: + return llvm::Optional(); + } + } + + template ::value>::type + * = nullptr> + llvm::Optional GetAs() const { + switch (m_selected) { + case Selected::Two: + return m_t2; + default: + return llvm::Optional(); + } + } + + template + ResultType Apply(std::function if_T1, + std::function if_T2) const { + switch (m_selected) { + case Selected::One: + return if_T1(m_t1); + case Selected::Two: + return if_T2(m_t2); + } + } + + bool operator==(const Either &rhs) { + return (GetAs() == rhs.GetAs()) && (GetAs() == rhs.GetAs()); + } + + explicit operator bool() { + switch (m_selected) { + case Selected::One: + return (bool)m_t1; + case Selected::Two: + return (bool)m_t2; + } + } + + Either &operator=(const Either &rhs) { + switch (rhs.m_selected) { + case Selected::One: + m_t1 = rhs.GetAs().getValue(); + m_selected = Selected::One; + break; + case Selected::Two: + m_t2 = rhs.GetAs().getValue(); + m_selected = Selected::Two; + break; + } + return *this; + } + + ~Either() { + switch (m_selected) { + case Selected::One: + m_t1.T1::~T1(); + break; + case Selected::Two: + m_t2.T2::~T2(); + break; + } + } +}; + } // namespace lldb_utility #endif // #ifndef liblldb_Either_h_ - diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index e4e92a2738cc..9a3871152c61 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -1777,6 +1777,7 @@ 26CFDCA2186163A4000E63E5 /* Editline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Editline.cpp; sourceTree = ""; }; 26CFDCA01861638D000E63E5 /* Editline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Editline.h; path = include/lldb/Host/Editline.h; sourceTree = ""; }; 2326CF511BDD693B00A5CEAC /* EditlineTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditlineTest.cpp; sourceTree = ""; }; + 9481FE6B1B5F2D9200DED357 /* Either.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Either.h; path = include/lldb/Utility/Either.h; sourceTree = ""; }; 26D9FDC812F784FD0003F2EE /* EmulateInstruction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = EmulateInstruction.cpp; path = source/Core/EmulateInstruction.cpp; sourceTree = ""; }; 26D9FDC612F784E60003F2EE /* EmulateInstruction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EmulateInstruction.h; path = include/lldb/Core/EmulateInstruction.h; sourceTree = ""; }; 9A22A15D135E30370024DDC3 /* EmulateInstructionARM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EmulateInstructionARM.cpp; sourceTree = ""; }; @@ -4509,6 +4510,7 @@ 49CA96E81E6AAC6600C03FEE /* DataEncoder.cpp */, 49CA96F41E6AAC8E00C03FEE /* DataExtractor.h */, 49CA96E91E6AAC6600C03FEE /* DataExtractor.cpp */, + 9481FE6B1B5F2D9200DED357 /* Either.h */, 26BC7DD310F1B7D500F91463 /* Endian.h */, AFC2DCE61E6E2ED000283714 /* FastDemangle.cpp */, AFC2DCED1E6E2F9800283714 /* FastDemangle.h */, From b608e4a871ee8b1387f147a3610605d7b6144023 Mon Sep 17 00:00:00 2001 From: Tatyana Krasnukha Date: Fri, 10 Aug 2018 13:01:26 +0000 Subject: [PATCH 0092/1112] Amend "Remove unused type Either from Utility library". git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339430 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Utility/Either.h | 72 ----------------------------------- 1 file changed, 72 deletions(-) delete mode 100644 include/lldb/Utility/Either.h diff --git a/include/lldb/Utility/Either.h b/include/lldb/Utility/Either.h deleted file mode 100644 index ec683096859b..000000000000 --- a/include/lldb/Utility/Either.h +++ /dev/null @@ -1,72 +0,0 @@ -//===-- Either.h -----------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_Either_h_ -#define liblldb_Either_h_ - -#include "llvm/ADT/Optional.h" - -namespace lldb_utility { - template - class Either { - private: - enum class Selected { - One, Two - }; - - Selected m_selected; - union { - T1 m_t1; - T2 m_t2; - }; - - public: - Either(const T1& t1) - { - m_t1 = t1; - m_selected = Selected::One; - } - - Either(const T2& t2) - { - m_t2 = t2; - m_selected = Selected::Two; - } - - template ::value>::type * = nullptr > - llvm::Optional - GetAs() - { - switch (m_selected) - { - case Selected::One: - return m_t1; - default: - return llvm::Optional(); - } - } - - template ::value>::type * = nullptr > - llvm::Optional - GetAs() - { - switch (m_selected) - { - case Selected::Two: - return m_t2; - default: - return llvm::Optional(); - } - } - }; - -} // namespace lldb_utility - -#endif // #ifndef liblldb_Either_h_ - From 1774377b11a2ed36bc0f3c88515451dd81fd18b2 Mon Sep 17 00:00:00 2001 From: Stefan Granitz Date: Fri, 10 Aug 2018 15:21:33 +0000 Subject: [PATCH 0093/1112] RichManglingContext: Make m_ipd_str_len a local variable and simplify processIPDStrResult + polishing in test and Mangled git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339440 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Core/RichManglingContext.h | 7 ++-- source/Core/Mangled.cpp | 8 ++-- source/Core/RichManglingContext.cpp | 45 ++++++++++------------ unittests/Core/RichManglingContextTest.cpp | 21 +++++----- 4 files changed, 39 insertions(+), 42 deletions(-) diff --git a/include/lldb/Core/RichManglingContext.h b/include/lldb/Core/RichManglingContext.h index bfa910c0b43c..393305c37421 100644 --- a/include/lldb/Core/RichManglingContext.h +++ b/include/lldb/Core/RichManglingContext.h @@ -25,10 +25,9 @@ namespace lldb_private { /// providers. See Mangled::DemangleWithRichManglingInfo() class RichManglingContext { public: - RichManglingContext() - : m_provider(None), m_ipd_buf_size(2048), m_ipd_str_len(0) { + RichManglingContext() : m_provider(None), m_ipd_buf_size(2048) { m_ipd_buf = static_cast(std::malloc(m_ipd_buf_size)); - m_ipd_buf[m_ipd_str_len] = '\0'; + m_ipd_buf[0] = '\0'; } ~RichManglingContext() { std::free(m_ipd_buf); } @@ -65,6 +64,7 @@ class RichManglingContext { /// most recent ParseXy() operation. The next ParseXy() call invalidates it. llvm::StringRef GetBufferRef() const { assert(m_provider != None && "Initialize a provider first"); + assert(m_buffer.data() != nullptr && "Parse first"); return m_buffer; } @@ -81,7 +81,6 @@ class RichManglingContext { llvm::ItaniumPartialDemangler m_ipd; char *m_ipd_buf; size_t m_ipd_buf_size; - size_t m_ipd_str_len; /// Members for PluginCxxLanguage /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The diff --git a/source/Core/Mangled.cpp b/source/Core/Mangled.cpp index 64d44958bdc1..c01df6cb59c6 100644 --- a/source/Core/Mangled.cpp +++ b/source/Core/Mangled.cpp @@ -261,9 +261,10 @@ static char *GetMSVCDemangledStr(const char *M) { #endif } -static char *GetItaniumDemangledStr(const char *M, - llvm::ItaniumPartialDemangler &ipd) { +static char *GetItaniumDemangledStr(const char *M) { char *demangled_cstr = nullptr; + + llvm::ItaniumPartialDemangler ipd; bool err = ipd.partialDemangle(M); if (!err) { // Default buffer and size (will realloc in case it's too small). @@ -384,8 +385,7 @@ Mangled::GetDemangledName(lldb::LanguageType language) const { demangled_name = GetMSVCDemangledStr(mangled_name); break; case eManglingSchemeItanium: { - llvm::ItaniumPartialDemangler ipd; - demangled_name = GetItaniumDemangledStr(mangled_name, ipd); + demangled_name = GetItaniumDemangledStr(mangled_name); break; } case eManglingSchemeNone: diff --git a/source/Core/RichManglingContext.cpp b/source/Core/RichManglingContext.cpp index da009e4ddf43..0ff602f7ad1d 100644 --- a/source/Core/RichManglingContext.cpp +++ b/source/Core/RichManglingContext.cpp @@ -89,37 +89,32 @@ bool RichManglingContext::IsFunction() const { } void RichManglingContext::processIPDStrResult(char *ipd_res, size_t res_size) { + // Error case: Clear the buffer. if (LLVM_UNLIKELY(ipd_res == nullptr)) { assert(res_size == m_ipd_buf_size && "Failed IPD queries keep the original size in the N parameter"); - // Error case: Clear the buffer. - m_ipd_str_len = 0; - m_ipd_buf[m_ipd_str_len] = '\0'; - } else { - // IPD's res_size includes null terminator. - size_t res_len = res_size - 1; - assert(ipd_res[res_len] == '\0' && - "IPD returns null-terminated strings and we rely on that"); - - if (LLVM_UNLIKELY(ipd_res != m_ipd_buf)) { - // Realloc case: Take over the new buffer. - m_ipd_buf = ipd_res; // std::realloc freed or reused the old buffer. - m_ipd_buf_size = - res_size; // Actual buffer may be bigger, but we can't know. - m_ipd_str_len = res_len; - - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE); - if (log) - log->Printf("ItaniumPartialDemangler Realloc: new buffer size %lu", - m_ipd_buf_size); - } else { - // 99% case: Just remember the string length. - m_ipd_str_len = res_len; - } + m_ipd_buf[0] = '\0'; + m_buffer = llvm::StringRef(m_ipd_buf, 0); + return; + } + + // IPD's res_size includes null terminator. + assert(ipd_res[res_size - 1] == '\0' && + "IPD returns null-terminated strings and we rely on that"); + + // Update buffer/size on realloc. + if (LLVM_UNLIKELY(ipd_res != m_ipd_buf || res_size > m_ipd_buf_size)) { + m_ipd_buf = ipd_res; // std::realloc freed or reused the old buffer. + m_ipd_buf_size = res_size; // May actually be bigger, but we can't know. + + if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) + LLDB_LOG(log, "ItaniumPartialDemangler Realloc: new buffer size is {0}", + m_ipd_buf_size); } - m_buffer = llvm::StringRef(m_ipd_buf, m_ipd_str_len); + // 99% case: Just remember the string length. + m_buffer = llvm::StringRef(m_ipd_buf, res_size - 1); } void RichManglingContext::ParseFunctionBaseName() { diff --git a/unittests/Core/RichManglingContextTest.cpp b/unittests/Core/RichManglingContextTest.cpp index bf680999f19e..19329ac82086 100644 --- a/unittests/Core/RichManglingContextTest.cpp +++ b/unittests/Core/RichManglingContextTest.cpp @@ -79,10 +79,10 @@ TEST(RichManglingContextTest, SwitchProvider) { TEST(RichManglingContextTest, IPDRealloc) { // The demangled name should fit into the Itanium default buffer. - const char *short_mangled = "_ZN3foo3barEv"; + const char *ShortMangled = "_ZN3foo3barEv"; // The demangled name for this will certainly not fit into the default buffer. - const char *long_mangled = + const char *LongMangled = "_ZNK3shk6detail17CallbackPublisherIZNS_5ThrowERKNSt15__exception_" "ptr13exception_ptrEEUlOT_E_E9SubscribeINS0_9ConcatMapINS0_" "18CallbackSubscriberIZNS_6GetAllIiNS1_IZZNS_9ConcatMapIZNS_6ConcatIJNS1_" @@ -100,15 +100,18 @@ TEST(RichManglingContextTest, IPDRealloc) { RichManglingContext RMC; - // Demangle the short one and remember the buffer address. - EXPECT_TRUE(RMC.FromItaniumName(ConstString(short_mangled))); + // Demangle the short one. + EXPECT_TRUE(RMC.FromItaniumName(ConstString(ShortMangled))); RMC.ParseFullName(); - const char *short_demangled_ptr = RMC.GetBufferRef().data(); + const char *ShortDemangled = RMC.GetBufferRef().data(); - // Demangle the long one and make sure the buffer address changed. - EXPECT_TRUE(RMC.FromItaniumName(ConstString(long_mangled))); + // Demangle the long one. + EXPECT_TRUE(RMC.FromItaniumName(ConstString(LongMangled))); RMC.ParseFullName(); - const char *long_demangled_ptr = RMC.GetBufferRef().data(); + const char *LongDemangled = RMC.GetBufferRef().data(); - EXPECT_TRUE(short_demangled_ptr != long_demangled_ptr); + // Make sure a new buffer was allocated or the default buffer was extended. + bool AllocatedNewBuffer = (ShortDemangled != LongDemangled); + bool ExtendedExistingBuffer = (strlen(LongDemangled) > 2048); + EXPECT_TRUE(AllocatedNewBuffer || ExtendedExistingBuffer); } From 949996cd01b30827b1c172895d1c1619ad0833b4 Mon Sep 17 00:00:00 2001 From: Stella Stamenova Date: Fri, 10 Aug 2018 17:52:45 +0000 Subject: [PATCH 0094/1112] [tests, libstdcxx] Add missing test category on the TestDataFormatterStdUniquePtr tests Each test needs to be marked with the add_test_categories decorator individually. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339457 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py index 5d05418a8b49..f782a2a8baea 100644 --- a/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py +++ b/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py @@ -66,6 +66,7 @@ def test_with_run_command(self): @skipIfWindows # libstdcpp not ported to Windows @skipIfDarwin # doesn't compile on Darwin @skipIfwatchOS # libstdcpp not ported to watchos + @add_test_categories(["libstdcxx"]) def test_recursive_unique_ptr(self): # Tests that LLDB can handle when we have a loop in the unique_ptr # reference chain and that it correctly handles the different options From 64f43c2811ea3d66928fec156d3fc22c81d4f5de Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Fri, 10 Aug 2018 21:31:44 +0000 Subject: [PATCH 0095/1112] Remove copy-pasted and unrelated comment [NFC] That comment was copied from the CombineConsecutiveEntriesWithEqualData() implementation below, and doesn't actually describe what's happening in the current function. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339473 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Core/RangeMap.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/lldb/Core/RangeMap.h b/include/lldb/Core/RangeMap.h index 45bda26e2659..ab73f6038772 100644 --- a/include/lldb/Core/RangeMap.h +++ b/include/lldb/Core/RangeMap.h @@ -169,8 +169,6 @@ template class RangeArray { #ifdef ASSERT_RANGEMAP_ARE_SORTED bool IsSorted() const { typename Collection::const_iterator pos, end, prev; - // First we determine if we can combine any of the Entry objects so we - // don't end up allocating and making a new collection for no reason for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++) { if (prev != end && *pos < *prev) From cd557a941515835223652aa7440d7c25ee1b4545 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Sat, 11 Aug 2018 23:40:27 +0000 Subject: [PATCH 0096/1112] Use a DenseMap for looking up functions by UID in CompileUnit::FindFunctionByUID Summary: Instead of iterating over our vector of functions, we might as well use a map here to directly get the function we need. Thanks to Vedant for pointing this out. Reviewers: vsk Reviewed By: vsk Subscribers: mgrang, lldb-commits Differential Revision: https://reviews.llvm.org/D50225 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339504 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Symbol/CompileUnit.h | 28 +++++++-------- source/Core/Module.cpp | 10 +++--- source/Symbol/CompileUnit.cpp | 57 +++++++++++++++---------------- 3 files changed, 46 insertions(+), 49 deletions(-) diff --git a/include/lldb/Symbol/CompileUnit.h b/include/lldb/Symbol/CompileUnit.h index b816439cee13..0c9ae2f99898 100644 --- a/include/lldb/Symbol/CompileUnit.h +++ b/include/lldb/Symbol/CompileUnit.h @@ -18,6 +18,8 @@ #include "lldb/Utility/UserID.h" #include "lldb/lldb-enumerations.h" +#include "llvm/ADT/DenseMap.h" + namespace lldb_private { //---------------------------------------------------------------------- /// @class CompileUnit CompileUnit.h "lldb/Symbol/CompileUnit.h" @@ -163,21 +165,19 @@ class CompileUnit : public std::enable_shared_from_this, void GetDescription(Stream *s, lldb::DescriptionLevel level) const; //------------------------------------------------------------------ - /// Get a shared pointer to a function in this compile unit by index. + /// Apply a lambda to each function in this compile unit. /// - /// Typically called when iterating though all functions in a compile unit - /// after all functions have been parsed. This provides raw access to the - /// function shared pointer list and will not cause the SymbolFile plug-in - /// to parse any unparsed functions. + /// This provides raw access to the function shared pointer list and will not + /// cause the SymbolFile plug-in to parse any unparsed functions. /// - /// @param[in] idx - /// An index into the function list. + /// @note Prefer using FindFunctionByUID over this if possible. /// - /// @return - /// A shared pointer to a function that might contain a NULL - /// Function class pointer. + /// @param[in] lambda + /// The lambda that should be applied to every function. The lambda can + /// return true if the iteration should be aborted earlier. //------------------------------------------------------------------ - lldb::FunctionSP GetFunctionAtIndex(size_t idx); + void ForeachFunction( + llvm::function_ref lambda) const; //------------------------------------------------------------------ /// Dump the compile unit contents to the stream \a s. @@ -415,9 +415,9 @@ class CompileUnit : public std::enable_shared_from_this, lldb::LanguageType m_language; ///< The programming language enumeration value. Flags m_flags; ///< Compile unit flags that help with partial parsing. - std::vector m_functions; ///< The sparsely populated list of - ///shared pointers to functions - ///< that gets populated as functions get partially parsed. + + /// Maps UIDs to functions. + llvm::DenseMap m_functions_by_uid; std::vector m_imported_modules; ///< All modules, including the ///current module, imported by ///this diff --git a/source/Core/Module.cpp b/source/Core/Module.cpp index b078cd30aeab..8cb60dcdf233 100644 --- a/source/Core/Module.cpp +++ b/source/Core/Module.cpp @@ -371,15 +371,13 @@ void Module::ParseAllDebugSymbols() { symbols->ParseCompileUnitFunctions(sc); - for (size_t func_idx = 0; - (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != - nullptr; - ++func_idx) { + sc.comp_unit->ForeachFunction([&sc, &symbols](const FunctionSP &f) { + sc.function = f.get(); symbols->ParseFunctionBlocks(sc); - // Parse the variables for this function and all its blocks symbols->ParseVariablesForContext(sc); - } + return false; + }); // Parse all types for this compile unit sc.function = nullptr; diff --git a/source/Symbol/CompileUnit.cpp b/source/Symbol/CompileUnit.cpp index a4f0d4231e2f..7302561ba3c8 100644 --- a/source/Symbol/CompileUnit.cpp +++ b/source/Symbol/CompileUnit.cpp @@ -22,7 +22,7 @@ CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, lldb::LanguageType language, lldb_private::LazyBool is_optimized) : ModuleChild(module_sp), FileSpec(pathname, false), UserID(cu_sym_id), - m_user_data(user_data), m_language(language), m_flags(0), m_functions(), + m_user_data(user_data), m_language(language), m_flags(0), m_support_files(), m_line_table_ap(), m_variables(), m_is_optimized(is_optimized) { if (language != eLanguageTypeUnknown) @@ -35,7 +35,7 @@ CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, lldb::LanguageType language, lldb_private::LazyBool is_optimized) : ModuleChild(module_sp), FileSpec(fspec), UserID(cu_sym_id), - m_user_data(user_data), m_language(language), m_flags(0), m_functions(), + m_user_data(user_data), m_language(language), m_flags(0), m_support_files(), m_line_table_ap(), m_variables(), m_is_optimized(is_optimized) { if (language != eLanguageTypeUnknown) @@ -66,6 +66,22 @@ void CompileUnit::GetDescription(Stream *s, << (const FileSpec &)*this << "\", language = \"" << language << '"'; } +void CompileUnit::ForeachFunction( + llvm::function_ref lambda) const { + std::vector sorted_functions; + sorted_functions.reserve(m_functions_by_uid.size()); + for (auto &p : m_functions_by_uid) + sorted_functions.push_back(p.second); + std::sort(sorted_functions.begin(), sorted_functions.end(), + [](const lldb::FunctionSP &a, const lldb::FunctionSP &b) { + return a->GetID() < b->GetID(); + }); + + for (auto &f : sorted_functions) + if (lambda(f)) + return; +} + //---------------------------------------------------------------------- // Dump the current contents of this object. No functions that cause on demand // parsing of functions, globals, statics are called, so this is a good @@ -89,13 +105,12 @@ void CompileUnit::Dump(Stream *s, bool show_context) const { s->IndentLess(); } - if (!m_functions.empty()) { + if (!m_functions_by_uid.empty()) { s->IndentMore(); - std::vector::const_iterator pos; - std::vector::const_iterator end = m_functions.end(); - for (pos = m_functions.begin(); pos != end; ++pos) { - (*pos)->Dump(s, show_context); - } + ForeachFunction([&s, show_context](const FunctionSP &f) { + f->Dump(s, show_context); + return false; + }); s->IndentLess(); s->EOL(); @@ -106,15 +121,7 @@ void CompileUnit::Dump(Stream *s, bool show_context) const { // Add a function to this compile unit //---------------------------------------------------------------------- void CompileUnit::AddFunction(FunctionSP &funcSP) { - // TODO: order these by address - m_functions.push_back(funcSP); -} - -FunctionSP CompileUnit::GetFunctionAtIndex(size_t idx) { - FunctionSP funcSP; - if (idx < m_functions.size()) - funcSP = m_functions[idx]; - return funcSP; + m_functions_by_uid[funcSP->GetID()] = funcSP; } //---------------------------------------------------------------------- @@ -163,18 +170,10 @@ FunctionSP CompileUnit::GetFunctionAtIndex(size_t idx) { //} FunctionSP CompileUnit::FindFunctionByUID(lldb::user_id_t func_uid) { - FunctionSP funcSP; - if (!m_functions.empty()) { - std::vector::const_iterator pos; - std::vector::const_iterator end = m_functions.end(); - for (pos = m_functions.begin(); pos != end; ++pos) { - if ((*pos)->GetID() == func_uid) { - funcSP = *pos; - break; - } - } - } - return funcSP; + auto it = m_functions_by_uid.find(func_uid); + if (it == m_functions_by_uid.end()) + return FunctionSP(); + return it->second; } lldb::LanguageType CompileUnit::GetLanguage() { From fe39baedaf133c29b107309d9f2cdd86b1130c90 Mon Sep 17 00:00:00 2001 From: Stefan Granitz Date: Mon, 13 Aug 2018 16:45:06 +0000 Subject: [PATCH 0097/1112] Straight forward FastDemangle replacement in SubsPrimitiveParmItanium Summary: Removing FastDemangle will greatly reduce maintenance efforts. This patch replaces the last point of use in LLDB. Semantics should be kept intact. Once this is agreed upon, we can: * Remove the FastDemangle sources * Add more features e.g. substitutions in template parameters, considering all variations, etc. Depends on LLVM patch https://reviews.llvm.org/D50586 Reviewers: erik.pilkington, friss, jingham, JDevlieghere Subscribers: kristof.beyls, chrib, lldb-commits Differential Revision: https://reviews.llvm.org/D50587 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339583 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Language/CPlusPlus/CPlusPlusLanguage.cpp | 95 +++++++++++-------- .../CPlusPlus/CPlusPlusLanguageTest.cpp | 1 + 2 files changed, 58 insertions(+), 38 deletions(-) diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 9df8853f4553..8148044496c5 100644 --- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -21,6 +21,7 @@ // Other libraries and framework includes #include "llvm/ADT/StringRef.h" +#include "llvm/Demangle/Demangle.h" // Project includes #include "lldb/Core/PluginManager.h" @@ -30,7 +31,6 @@ #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/DataFormatters/VectorType.h" #include "lldb/Utility/ConstString.h" -#include "lldb/Utility/FastDemangle.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" @@ -278,48 +278,67 @@ bool CPlusPlusLanguage::ExtractContextAndIdentifier( static ConstString SubsPrimitiveParmItanium(llvm::StringRef mangled, llvm::StringRef search, llvm::StringRef replace) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE); - - const size_t max_len = - mangled.size() + mangled.count(search) * replace.size() + 1; - - // Make a temporary buffer to fix up the mangled parameter types and copy the - // original there - std::string output_buf; - output_buf.reserve(max_len); - output_buf.insert(0, mangled.str()); - ptrdiff_t replaced_offset = 0; - - auto swap_parms_hook = [&](const char *parsee) { - if (!parsee || !*parsee) - return; - - // Check whether we've found a substitutee - llvm::StringRef s(parsee); - if (s.startswith(search)) { - // account for the case where a replacement is of a different length to - // the original - replaced_offset += replace.size() - search.size(); - - ptrdiff_t replace_idx = (mangled.size() - s.size()) + replaced_offset; - output_buf.erase(replace_idx, search.size()); - output_buf.insert(replace_idx, replace.str()); + class PrimitiveParmSubs { + llvm::StringRef mangled; + llvm::StringRef search; + llvm::StringRef replace; + ptrdiff_t read_pos; + std::string output; + std::back_insert_iterator writer; + + public: + PrimitiveParmSubs(llvm::StringRef m, llvm::StringRef s, llvm::StringRef r) + : mangled(m), search(s), replace(r), read_pos(0), + writer(std::back_inserter(output)) {} + + void Substitute(llvm::StringRef tail) { + assert(tail.data() >= mangled.data() && + tail.data() < mangled.data() + mangled.size() && + "tail must point into range of mangled"); + + if (tail.startswith(search)) { + auto reader = mangled.begin() + read_pos; + ptrdiff_t read_len = tail.data() - (mangled.data() + read_pos); + + // First write the unmatched part of the original. Then write the + // replacement string. Finally skip the search string in the original. + writer = std::copy(reader, reader + read_len, writer); + writer = std::copy(replace.begin(), replace.end(), writer); + read_pos += read_len + search.size(); + } + } + + ConstString Finalize() { + // If we did a substitution, write the remaining part of the original. + if (read_pos > 0) { + writer = std::copy(mangled.begin() + read_pos, mangled.end(), writer); + read_pos = mangled.size(); + } + + return ConstString(output); + } + + static void Callback(void *context, const char *match) { + ((PrimitiveParmSubs *)context)->Substitute(llvm::StringRef(match)); } }; - // FastDemangle will call our hook for each instance of a primitive type, + // FastDemangle will call back for each instance of a primitive type, // allowing us to perform substitution - char *const demangled = - FastDemangle(mangled.str().c_str(), mangled.size(), swap_parms_hook); - - if (log) - log->Printf("substituted mangling for %s:{%s} %s:{%s}\n", - mangled.str().c_str(), demangled, output_buf.c_str(), - FastDemangle(output_buf.c_str())); - // FastDemangle malloc'd this string. - free(demangled); + PrimitiveParmSubs parmSubs(mangled, search, replace); + assert(mangled.data()[mangled.size()] == '\0' && "Expect C-String"); + bool err = llvm::itaniumFindTypesInMangledName(mangled.data(), &parmSubs, + PrimitiveParmSubs::Callback); + ConstString result = parmSubs.Finalize(); + + if (Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)) { + if (err) + LLDB_LOG(log, "Failed to substitute mangling in {0}", mangled); + else if (result) + LLDB_LOG(log, "Substituted mangling {0} -> {1}", mangled, result); + } - return output_buf == mangled ? ConstString() : ConstString(output_buf); + return result; } uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings( diff --git a/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp b/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp index 7a81b878f633..81d3ac51fd93 100644 --- a/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp +++ b/unittests/Language/CPlusPlus/CPlusPlusLanguageTest.cpp @@ -183,4 +183,5 @@ TEST(CPlusPlusLanguage, FindAlternateFunctionManglings) { EXPECT_THAT(FindAlternate("_ZN1A1fEa"), Contains("_ZN1A1fEc")); EXPECT_THAT(FindAlternate("_ZN1A1fEx"), Contains("_ZN1A1fEl")); EXPECT_THAT(FindAlternate("_ZN1A1fEy"), Contains("_ZN1A1fEm")); + EXPECT_THAT(FindAlternate("_ZN1A1fEai"), Contains("_ZN1A1fEci")); } From 4f9cb7bed3a6adae995484701bdbdd1735a921d9 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Mon, 13 Aug 2018 20:43:06 +0000 Subject: [PATCH 0098/1112] Added test for Core/Range class. Summary: We can optimize and refactor some of the classes in RangeMap.h, but first we should have some tests for all the data structures in there. This adds a first batch of tests for the Range class itself. There are some unexpected results happening when mixing invalid and valid ranges, so I added some FIXME's for that in the tests. Reviewers: vsk Reviewed By: vsk Subscribers: mgorny, lldb-commits Differential Revision: https://reviews.llvm.org/D50620 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339611 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/Core/CMakeLists.txt | 1 + unittests/Core/RangeTest.cpp | 330 ++++++++++++++++++++++++++++++++++ 2 files changed, 331 insertions(+) create mode 100644 unittests/Core/RangeTest.cpp diff --git a/unittests/Core/CMakeLists.txt b/unittests/Core/CMakeLists.txt index 88187c2409c2..b40e7093a850 100644 --- a/unittests/Core/CMakeLists.txt +++ b/unittests/Core/CMakeLists.txt @@ -4,6 +4,7 @@ add_lldb_unittest(LLDBCoreTests EventTest.cpp ListenerTest.cpp MangledTest.cpp + RangeTest.cpp RichManglingContextTest.cpp StreamCallbackTest.cpp diff --git a/unittests/Core/RangeTest.cpp b/unittests/Core/RangeTest.cpp new file mode 100644 index 000000000000..337c2fa11515 --- /dev/null +++ b/unittests/Core/RangeTest.cpp @@ -0,0 +1,330 @@ +//===-- RangeTest.cpp ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/RangeMap.h" + +#include +#include + +#include "gtest/gtest.h" + +using namespace lldb; +using namespace lldb_private; + +TEST(RangeTest, SizeTypes) { + Range r; + static_assert(std::is_same::value, + "RangeBase type is not equal to the given one."); + static_assert(std::is_same::value, + "RangeEnd type is not equal to the given one."); + static_assert(std::is_same::value, + "Size type is not equal to the given one."); +} + +typedef Range RangeT; + +TEST(RangeTest, DefaultConstructor) { + RangeT r; + EXPECT_FALSE(r.IsValid()); + EXPECT_EQ(0U, r.GetByteSize()); + EXPECT_EQ(0U, r.GetRangeBase()); + EXPECT_EQ(0U, r.GetRangeEnd()); +} + +TEST(RangeTest, Constructor) { + RangeT r(3, 5); + EXPECT_TRUE(r.IsValid()); + EXPECT_EQ(5U, r.GetByteSize()); + EXPECT_EQ(3U, r.GetRangeBase()); + EXPECT_EQ(8U, r.GetRangeEnd()); +} + +TEST(RangeTest, Copy) { + RangeT orig(3, 5); + RangeT r = orig; + EXPECT_TRUE(r.IsValid()); + EXPECT_EQ(5U, r.GetByteSize()); + EXPECT_EQ(3U, r.GetRangeBase()); + EXPECT_EQ(8U, r.GetRangeEnd()); +} + +TEST(RangeTest, Clear) { + RangeT r(3, 5); + r.Clear(); + EXPECT_TRUE(r == RangeT()); +} + +TEST(RangeTest, ClearWithStarAddress) { + RangeT r(3, 5); + r.Clear(4); + EXPECT_TRUE(r == RangeT(4, 0)); +} + +TEST(RangeTest, SetRangeBase) { + RangeT r(3, 5); + r.SetRangeBase(6); + EXPECT_EQ(6U, r.GetRangeBase()); + EXPECT_EQ(11U, r.GetRangeEnd()); + EXPECT_EQ(5U, r.GetByteSize()); +} + +TEST(RangeTest, Slide) { + RangeT r(3, 5); + r.Slide(1); + EXPECT_EQ(4U, r.GetRangeBase()); + EXPECT_EQ(9U, r.GetRangeEnd()); + EXPECT_EQ(5U, r.GetByteSize()); + + r.Slide(2); + EXPECT_EQ(6U, r.GetRangeBase()); + EXPECT_EQ(11U, r.GetRangeEnd()); + EXPECT_EQ(5U, r.GetByteSize()); +} + +TEST(RangeTest, SlideZero) { + RangeT r(3, 5); + r.Slide(0); + EXPECT_EQ(3U, r.GetRangeBase()); + EXPECT_EQ(8U, r.GetRangeEnd()); + EXPECT_EQ(5U, r.GetByteSize()); +} + +TEST(RangeTest, ContainsAddr) { + RangeT r(3, 5); + EXPECT_FALSE(r.Contains(0)); + EXPECT_FALSE(r.Contains(1)); + EXPECT_FALSE(r.Contains(2)); + EXPECT_TRUE(r.Contains(3)); + EXPECT_TRUE(r.Contains(4)); + EXPECT_TRUE(r.Contains(5)); + EXPECT_TRUE(r.Contains(6)); + EXPECT_TRUE(r.Contains(7)); + EXPECT_FALSE(r.Contains(8)); + EXPECT_FALSE(r.Contains(9)); + EXPECT_FALSE(r.Contains(10)); +} + +TEST(RangeTest, ContainsAddrInvalid) { + RangeT r; + EXPECT_FALSE(r.Contains(0)); + EXPECT_FALSE(r.Contains(1)); + EXPECT_FALSE(r.Contains(2)); + EXPECT_FALSE(r.Contains(3)); + EXPECT_FALSE(r.Contains(4)); +} + +TEST(RangeTest, ContainsEndInclusive) { + RangeT r(3, 5); + EXPECT_FALSE(r.ContainsEndInclusive(0)); + EXPECT_FALSE(r.ContainsEndInclusive(1)); + EXPECT_FALSE(r.ContainsEndInclusive(2)); + EXPECT_TRUE(r.ContainsEndInclusive(3)); + EXPECT_TRUE(r.ContainsEndInclusive(4)); + EXPECT_TRUE(r.ContainsEndInclusive(5)); + EXPECT_TRUE(r.ContainsEndInclusive(6)); + EXPECT_TRUE(r.ContainsEndInclusive(7)); + EXPECT_TRUE(r.ContainsEndInclusive(8)); + EXPECT_FALSE(r.ContainsEndInclusive(9)); + EXPECT_FALSE(r.ContainsEndInclusive(10)); +} + +TEST(RangeTest, ContainsEndInclusiveInvalid) { + RangeT r; + // FIXME: This is probably not intended. + EXPECT_TRUE(r.ContainsEndInclusive(0)); + + EXPECT_FALSE(r.ContainsEndInclusive(1)); + EXPECT_FALSE(r.ContainsEndInclusive(2)); +} + +TEST(RangeTest, ContainsRange) { + RangeT r(3, 5); + + // Range always contains itself. + EXPECT_TRUE(r.Contains(r)); + // Invalid range. + EXPECT_FALSE(r.Contains(RangeT())); + // Range starts and ends before. + EXPECT_FALSE(r.Contains(RangeT(0, 3))); + // Range starts before but contains beginning. + EXPECT_FALSE(r.Contains(RangeT(0, 4))); + // Range starts before but contains beginning and more. + EXPECT_FALSE(r.Contains(RangeT(0, 5))); + // Range starts before and contains the other. + EXPECT_FALSE(r.Contains(RangeT(0, 9))); + // Range is fully inside. + EXPECT_TRUE(r.Contains(RangeT(4, 3))); + // Range has same start, but not as large. + EXPECT_TRUE(r.Contains(RangeT(3, 4))); + // Range has same end, but starts earlier. + EXPECT_TRUE(r.Contains(RangeT(4, 4))); + // Range starts inside, but stops after the end of r. + EXPECT_FALSE(r.Contains(RangeT(4, 5))); + // Range starts directly after r. + EXPECT_FALSE(r.Contains(RangeT(8, 2))); + // Range starts directly after r. + EXPECT_FALSE(r.Contains(RangeT(9, 2))); + + // Invalid range with different start. + // FIXME: The first two probably not intended. + EXPECT_TRUE(r.Contains(RangeT(3, 0))); + EXPECT_TRUE(r.Contains(RangeT(4, 0))); + EXPECT_FALSE(r.Contains(RangeT(8, 0))); +} + +TEST(RangeTest, ContainsRangeStartingFromZero) { + RangeT r(0, 3); + EXPECT_TRUE(r.Contains(r)); + + // FIXME: This is probably not intended. + EXPECT_TRUE(r.Contains(RangeT())); +} + +TEST(RangeTest, Union) { + RangeT r(3, 5); + + // Ranges that we can't merge because it's not adjoin/intersecting. + EXPECT_FALSE(r.Union(RangeT(9, 1))); + // Check that we didn't modify our range. + EXPECT_EQ(r, RangeT(3, 5)); + + // Another range we can't merge, but before r. + EXPECT_FALSE(r.Union(RangeT(1, 1))); + EXPECT_EQ(r, RangeT(3, 5)); + + // Merge an adjoin range after. + EXPECT_TRUE(r.Union(RangeT(8, 2))); + EXPECT_EQ(r, RangeT(3, 7)); + + // Merge an adjoin range before. + EXPECT_TRUE(r.Union(RangeT(1, 2))); + EXPECT_EQ(r, RangeT(1, 9)); + + // Merge an intersecting range after. + EXPECT_TRUE(r.Union(RangeT(8, 3))); + EXPECT_EQ(r, RangeT(1, 10)); + + // Merge an intersecting range before. + EXPECT_TRUE(r.Union(RangeT(0, 1))); + EXPECT_EQ(r, RangeT(0, 11)); + + // Merge a few ranges inside that shouldn't do anything. + EXPECT_TRUE(r.Union(RangeT(0, 3))); + EXPECT_EQ(r, RangeT(0, 11)); + EXPECT_TRUE(r.Union(RangeT(5, 1))); + EXPECT_EQ(r, RangeT(0, 11)); + EXPECT_TRUE(r.Union(RangeT(9, 2))); + EXPECT_EQ(r, RangeT(0, 11)); +} + +TEST(RangeTest, DoesAdjoinOrIntersect) { + RangeT r(3, 4); + + EXPECT_FALSE(r.DoesAdjoinOrIntersect(RangeT(1, 1))); + EXPECT_TRUE(r.DoesAdjoinOrIntersect(RangeT(1, 2))); + EXPECT_TRUE(r.DoesAdjoinOrIntersect(RangeT(2, 2))); + EXPECT_TRUE(r.DoesAdjoinOrIntersect(RangeT(4, 2))); + EXPECT_TRUE(r.DoesAdjoinOrIntersect(RangeT(6, 2))); + EXPECT_TRUE(r.DoesAdjoinOrIntersect(RangeT(7, 2))); + EXPECT_FALSE(r.DoesAdjoinOrIntersect(RangeT(8, 2))); +} + +TEST(RangeTest, DoesIntersect) { + RangeT r(3, 4); + + EXPECT_FALSE(r.DoesIntersect(RangeT(1, 1))); + EXPECT_FALSE(r.DoesIntersect(RangeT(1, 2))); + EXPECT_TRUE(r.DoesIntersect(RangeT(2, 2))); + EXPECT_TRUE(r.DoesIntersect(RangeT(4, 2))); + EXPECT_TRUE(r.DoesIntersect(RangeT(6, 2))); + EXPECT_FALSE(r.DoesIntersect(RangeT(7, 2))); + EXPECT_FALSE(r.DoesIntersect(RangeT(8, 2))); +} + +TEST(RangeTest, LessThan) { + RangeT r(10, 20); + + // Equal range. + EXPECT_FALSE(r < RangeT(10, 20)); + EXPECT_FALSE(RangeT(10, 20) < r); + + auto expect_ordered_less_than = [](RangeT r1, RangeT r2) { + EXPECT_TRUE(r1 < r2); + EXPECT_FALSE(r2 < r1); + }; + + // Same start, but bigger size. + expect_ordered_less_than(r, RangeT(10, 21)); + + // Start before and ends before. + expect_ordered_less_than(RangeT(9, 20), r); + + // Start before and equal size. + expect_ordered_less_than(RangeT(9, 21), r); + + // Start before and bigger size. + expect_ordered_less_than(RangeT(9, 22), r); + + // Start after and ends before. + expect_ordered_less_than(r, RangeT(11, 18)); + + // Start after and equal size. + expect_ordered_less_than(r, RangeT(11, 19)); + + // Start after and bigger size. + expect_ordered_less_than(r, RangeT(11, 20)); +} + +TEST(RangeTest, Equal) { + RangeT r(10, 20); + + // Equal range. + EXPECT_TRUE(r == RangeT(10, 20)); + + // Same start, different size. + EXPECT_FALSE(r == RangeT(10, 21)); + + // Different start, same size. + EXPECT_FALSE(r == RangeT(9, 20)); + + // Different start, different size. + EXPECT_FALSE(r == RangeT(9, 21)); + EXPECT_FALSE(r == RangeT(11, 19)); +} + +TEST(RangeTest, NotEqual) { + RangeT r(10, 20); + + EXPECT_FALSE(r != RangeT(10, 20)); + + EXPECT_TRUE(r != RangeT(10, 21)); + EXPECT_TRUE(r != RangeT(9, 20)); + EXPECT_TRUE(r != RangeT(9, 21)); +} + +// Comparison tests for invalid ranges (size == 0). + +TEST(RangeTest, LessThanInvalid) { + EXPECT_TRUE(RangeT() < RangeT(1, 0)); + EXPECT_TRUE(RangeT() < RangeT(2, 0)); + EXPECT_TRUE(RangeT(1, 0) < RangeT(2, 0)); +} + +TEST(RangeTest, EqualInvalid) { + RangeT r; + EXPECT_TRUE(r == RangeT()); + // Another invalid range, but with a different start. + EXPECT_FALSE(r == RangeT(3, 0)); +} + +TEST(RangeTest, NotEqualInvalid) { + RangeT r; + EXPECT_FALSE(r != RangeT()); + EXPECT_FALSE(r == RangeT(3, 0)); +} From fdd65985979d0bd1cbcf6b000f73d7e1b4d39b2c Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Mon, 13 Aug 2018 21:20:29 +0000 Subject: [PATCH 0099/1112] Update TestTargetXMLArch.py test for llvm triple change with unspecified components in r339294. git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339615 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../test/functionalities/gdb_remote_client/TestTargetXMLArch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestTargetXMLArch.py b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestTargetXMLArch.py index 184867e480b4..57c5ff0aac25 100644 --- a/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestTargetXMLArch.py +++ b/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestTargetXMLArch.py @@ -121,4 +121,4 @@ def readRegister(self, register): if self.TraceOn(): interp.HandleCommand("target list", result) print(result.GetOutput()) - self.assertTrue(target.GetTriple().startswith('x86_64--')) + self.assertTrue(target.GetTriple().startswith('x86_64-unknown-unknown')) From 47392bbc1f093f7516376d91c72f2b413a97de6e Mon Sep 17 00:00:00 2001 From: Aleksandr Urakov Date: Tue, 14 Aug 2018 07:57:44 +0000 Subject: [PATCH 0100/1112] [PDB] Parse UDT symbols and pointers to members (combined patch) Summary: In this patch I've tried to combine the best ideas from D49368 and D49410, so it implements following: - Completion of UDTs from a PDB with a filling of a layout info; - Pointers to members; - Fixes the bug relating to a virtual base offset reading from `vbtable`. The offset was treated as an unsigned, but it can be a negative sometimes. - Support of MSInheritance attribute Reviewers: asmith, zturner, rnk, labath, clayborg, lldb-commits Reviewed By: zturner Subscribers: aleksandr.urakov, stella.stamenova, JDevlieghere, lldb-commits Differential Revision: https://reviews.llvm.org/D49980 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339649 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Symbol/ClangASTContext.h | 2 + lit/SymbolFile/PDB/Inputs/ClassLayoutTest.cpp | 111 +++++ lit/SymbolFile/PDB/Inputs/PointerTypeTest.cpp | 23 + lit/SymbolFile/PDB/Inputs/UdtLayoutTest.cpp | 61 +++ .../PDB/Inputs/UdtLayoutTest.script | 4 + lit/SymbolFile/PDB/class-layout.test | 92 ++++ lit/SymbolFile/PDB/pointers.test | 38 ++ lit/SymbolFile/PDB/udt-layout.test | 51 +++ .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 91 +--- .../Plugins/SymbolFile/PDB/PDBASTParser.cpp | 393 +++++++++++++++++- source/Plugins/SymbolFile/PDB/PDBASTParser.h | 38 ++ .../Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | 29 +- source/Symbol/ClangASTContext.cpp | 110 ++++- 13 files changed, 926 insertions(+), 117 deletions(-) create mode 100644 lit/SymbolFile/PDB/Inputs/ClassLayoutTest.cpp create mode 100644 lit/SymbolFile/PDB/Inputs/PointerTypeTest.cpp create mode 100644 lit/SymbolFile/PDB/Inputs/UdtLayoutTest.cpp create mode 100644 lit/SymbolFile/PDB/Inputs/UdtLayoutTest.script create mode 100644 lit/SymbolFile/PDB/class-layout.test create mode 100644 lit/SymbolFile/PDB/pointers.test create mode 100644 lit/SymbolFile/PDB/udt-layout.test diff --git a/include/lldb/Symbol/ClangASTContext.h b/include/lldb/Symbol/ClangASTContext.h index 9364149d98e7..ac77ab153655 100644 --- a/include/lldb/Symbol/ClangASTContext.h +++ b/include/lldb/Symbol/ClangASTContext.h @@ -831,6 +831,8 @@ class ClangASTContext : public TypeSystem { bool is_static, bool is_inline, bool is_explicit, bool is_attr_used, bool is_artificial); + void AddMethodOverridesForCXXRecordType(lldb::opaque_compiler_type_t type); + // C++ Base Classes clang::CXXBaseSpecifier * CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type, diff --git a/lit/SymbolFile/PDB/Inputs/ClassLayoutTest.cpp b/lit/SymbolFile/PDB/Inputs/ClassLayoutTest.cpp new file mode 100644 index 000000000000..3c4b005cdf1b --- /dev/null +++ b/lit/SymbolFile/PDB/Inputs/ClassLayoutTest.cpp @@ -0,0 +1,111 @@ +// To avoid linking MSVC specific libs, we don't test virtual/override methods +// that needs vftable support in this file. + +// Enum. +enum Enum { RED, GREEN, BLUE }; +Enum EnumVar; + +// Union. +union Union { + short Row; + unsigned short Col; + int Line : 16; // Test named bitfield. + short : 8; // Unnamed bitfield symbol won't be generated in PDB. + long Table; +}; +Union UnionVar; + +// Struct. +struct Struct; +typedef Struct StructTypedef; + +struct Struct { + bool A; + unsigned char UCharVar; + unsigned int UIntVar; + long long LongLongVar; + Enum EnumVar; // Test struct has UDT member. + int array[10]; +}; +struct Struct StructVar; + +struct _List; // Forward declaration. +struct Complex { + struct _List *array[90]; + struct { // Test unnamed struct. MSVC treats it as `int x` + int x; + }; + union { // Test unnamed union. MSVC treats it as `int a; float b;` + int a; + float b; + }; +}; +struct Complex c; + +struct _List { // Test doubly linked list. + struct _List *current; + struct _List *previous; + struct _List *next; +}; +struct _List ListVar; + +typedef struct { + int a; +} UnnamedStruct; // Test unnamed typedef-ed struct. +UnnamedStruct UnnanmedVar; + +// Class. +namespace MemberTest { +class Base { +public: + Base() {} + ~Base() {} + +public: + int Get() { return 0; } + +protected: + int a; +}; +class Friend { +public: + int f() { return 3; } +}; +class Class : public Base { // Test base class. + friend Friend; + static int m_static; // Test static member variable. +public: + Class() : m_public(), m_private(), m_protected() {} + explicit Class(int a) { m_public = a; } // Test first reference of m_public. + ~Class() {} + + static int StaticMemberFunc(int a, ...) { + return 1; + } // Test static member function. + int Get() { return 1; } + int f(Friend c) { return c.f(); } + inline bool operator==(const Class &rhs) const // Test operator. + { + return (m_public == rhs.m_public); + } + +public: + int m_public; + struct Struct m_struct; + +private: + Union m_union; + int m_private; + +protected: + friend class Friend; + int m_protected; +}; +} // namespace MemberTest + +int main() { + MemberTest::Base B1; + B1.Get(); + MemberTest::Class::StaticMemberFunc(1, 10, 2); + return 0; +} diff --git a/lit/SymbolFile/PDB/Inputs/PointerTypeTest.cpp b/lit/SymbolFile/PDB/Inputs/PointerTypeTest.cpp new file mode 100644 index 000000000000..6612c30f00df --- /dev/null +++ b/lit/SymbolFile/PDB/Inputs/PointerTypeTest.cpp @@ -0,0 +1,23 @@ +int main() { + // Test pointer to array. + int array[2][4]; + int(*array_pointer)[2][4] = &array; + + struct ST { + int a; + int f(int x) { return 1; } + }; + + ST s = {10}; + + // Test pointer to a local. + int *p_int = &s.a; + + // Test pointer to data member. + int ST::*p_member_field = &ST::a; + + // Test pointer to member function. + int (ST::*p_member_method)(int) = &ST::f; + + return 0; +} diff --git a/lit/SymbolFile/PDB/Inputs/UdtLayoutTest.cpp b/lit/SymbolFile/PDB/Inputs/UdtLayoutTest.cpp new file mode 100644 index 000000000000..59a4fc585d77 --- /dev/null +++ b/lit/SymbolFile/PDB/Inputs/UdtLayoutTest.cpp @@ -0,0 +1,61 @@ +struct A { + explicit A(int u) { _u._u3 = u; } + A(const A &) = default; + virtual ~A() = default; + +private: + union U { + char _u1; + short _u2; + int _u3; + }; + + A::U _u; +}; + +#pragma pack(push, 1) +template struct B : public virtual A { + B(char a, unsigned short b, int c) : A(a + b + c), _a(a), _b(b), _c(c) {} + +private: + char _a; + unsigned short : 3; + unsigned short _b : 6; + unsigned short : 4; + int _c; +}; +#pragma pack(pop) + +#pragma pack(push, 16) +class C : private virtual B<0>, public virtual B<1>, private B<2>, public B<3> { +public: + C(char x, char y, char z) + : A(x - y + z), B<0>(x, y, z), B<1>(x * 2, y * 2, z * 2), + B<2>(x * 3, y * 3, z * 3), B<3>(x * 4, y * 4, z * 4), _x(x * 5), + _y(y * 5), _z(z * 5) {} + + static int abc; + +private: + int _x; + short _y; + char _z; +}; +int C::abc = 123; +#pragma pack(pop) + +class List { +public: + List() = default; + List(List *p, List *n, C v) : Prev(p), Next(n), Value(v) {} + +private: + List *Prev = nullptr; + List *Next = nullptr; + C Value{1, 2, 3}; +}; + +int main() { + List ls[16]; + return 0; +} diff --git a/lit/SymbolFile/PDB/Inputs/UdtLayoutTest.script b/lit/SymbolFile/PDB/Inputs/UdtLayoutTest.script new file mode 100644 index 000000000000..91de55f4ade4 --- /dev/null +++ b/lit/SymbolFile/PDB/Inputs/UdtLayoutTest.script @@ -0,0 +1,4 @@ +breakpoint set --file UdtLayoutTest.cpp --line 60 +run +target variable +frame variable diff --git a/lit/SymbolFile/PDB/class-layout.test b/lit/SymbolFile/PDB/class-layout.test new file mode 100644 index 000000000000..b5204bfbdbab --- /dev/null +++ b/lit/SymbolFile/PDB/class-layout.test @@ -0,0 +1,92 @@ +REQUIRES: windows +RUN: clang-cl -m32 /Z7 /c /GS- %S/Inputs/ClassLayoutTest.cpp /o %T/ClassLayoutTest.cpp.obj +RUN: link %T/ClassLayoutTest.cpp.obj /DEBUG /nodefaultlib /ENTRY:main /OUT:%T/ClassLayoutTest.cpp.exe +RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck %s +RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=ENUM %s +RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=UNION %s +RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=STRUCT %s +RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=COMPLEX %s +RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=LIST %s +RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=UNNAMED-STRUCT %s +RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=BASE %s +RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=FRIEND %s +RUN: lldb-test symbols %T/ClassLayoutTest.cpp.exe | FileCheck --check-prefix=CLASS %s + +CHECK: Module [[MOD:.*]] +CHECK: {{^[0-9A-F]+}}: SymbolVendor ([[MOD]]) +CHECK: {{^[0-9A-F]+}}: CompileUnit{{[{]0x[0-9a-f]+[}]}}, language = "c++", file = '{{.*}}\ClassLayoutTest.cpp' + +ENUM: name = "Enum", size = 4, decl = ClassLayoutTest.cpp:5 +ENUM-SAME: enum Enum { +ENUM: RED, +ENUM: GREEN, +ENUM: BLUE +ENUM:} + +UNION: name = "Union", size = 4, decl = ClassLayoutTest.cpp:9 +UNION-SAME: union Union { +UNION: short Row; +UNION: unsigned short Col; +UNION: int Line : 16; +UNION: long Table; +UNION:} + +STRUCT: name = "Struct", size = 64, decl = ClassLayoutTest.cpp:22 +STRUCT-SAME: struct Struct { +STRUCT: bool A; +STRUCT: unsigned char UCharVar; +STRUCT: unsigned int UIntVar; +STRUCT: long long LongLongVar; +STRUCT: Enum EnumVar; +STRUCT: int array[10]; +STRUCT:} + +COMPLEX: name = "Complex", size = 368, decl = ClassLayoutTest.cpp:33 +COMPLEX-SAME: struct Complex { +COMPLEX: _List *array[90]; +COMPLEX: int x; +COMPLEX: int a; +COMPLEX: float b; +COMPLEX:} + +LIST: name = "_List", size = 12, decl = ClassLayoutTest.cpp:45 +LIST-SAME: struct _List { +LIST: _List *current; +LIST: _List *previous; +LIST: _List *next; +LIST:} + +UNNAMED-STRUCT: name = "UnnamedStruct", size = 4, decl = ClassLayoutTest.cpp:52 +UNNAMED-STRUCT-SAME: struct UnnamedStruct { +UNNAMED-STRUCT: int a; +UNNAMED-STRUCT:} + +BASE: name = "MemberTest::Base", size = 4, decl = ClassLayoutTest.cpp:59 +BASE-SAME: class MemberTest::Base { +BASE: int a; +BASE: void {{.*}}Base(); +BASE: {{.*}}~Base(); +BASE: int {{.*}}Get(); +BASE:} + +FRIEND: name = "MemberTest::Friend", size = 1, decl = ClassLayoutTest.cpp:70 +FRIEND-SAME: class MemberTest::Friend { +FRIEND: int f(); +FRIEND: } + +CLASS: name = "MemberTest::Class", size = 88, decl = ClassLayoutTest.cpp:74 +CLASS-SAME: class MemberTest::Class : public MemberTest::Base { +CLASS: static int m_static; +CLASS: int m_public; +CLASS: Struct m_struct; +CLASS: Union m_union; +CLASS: int m_private; +CLASS: int m_protected; +CLASS: void Class(); +CLASS: void Class(int); +CLASS: ~MemberTest::Class(); +CLASS: static int {{.*}}StaticMemberFunc(int, ...); +CLASS: int Get(); +CLASS: int f(MemberTest::Friend); +CLASS: bool operator==(const MemberTest::Class &) +CLASS:} diff --git a/lit/SymbolFile/PDB/pointers.test b/lit/SymbolFile/PDB/pointers.test new file mode 100644 index 000000000000..48cdf4dd0bf6 --- /dev/null +++ b/lit/SymbolFile/PDB/pointers.test @@ -0,0 +1,38 @@ +REQUIRES: windows +RUN: clang-cl -m32 /Z7 /c /GS- %S/Inputs/PointerTypeTest.cpp /o %T/PointerTypeTest.cpp.obj +RUN: link %T/PointerTypeTest.cpp.obj /DEBUG /nodefaultlib /ENTRY:main /OUT:%T/PointerTypeTest.cpp.exe +RUN: lldb-test symbols %T/PointerTypeTest.cpp.exe | FileCheck %s +RUN: lldb-test symbols %T/PointerTypeTest.cpp.exe | FileCheck --check-prefix=MAIN-ST-F %s +RUN: lldb-test symbols %T/PointerTypeTest.cpp.exe | FileCheck --check-prefix=MAIN-ST %s +RUN: lldb-test symbols %T/PointerTypeTest.cpp.exe | FileCheck --check-prefix=MAIN %s +RUN: lldb-test symbols %T/PointerTypeTest.cpp.exe | FileCheck --check-prefix=F %s + +CHECK: Module [[MOD:.*]] +CHECK: {{^[0-9A-F]+}}: CompileUnit{{[{]0x[0-9a-f]+[}]}}, language = "c++", file = '{{.*}}\PointerTypeTest.cpp' + +MAIN-ST-F: name = "main::ST::f" +MAIN-ST-F-SAME: decl = PointerTypeTest.cpp:8 +MAIN-ST-F-SAME: compiler_type = {{.*}} int (int) + +MAIN-ST: name = "main::ST", size = 4, decl = PointerTypeTest.cpp:6, compiler_type = {{.*}} struct main::ST { +MAIN-ST-NEXT: int a; +MAIN-ST-NEXT: int {{.*}}f(int); +MAIN-ST-NEXT:} + +MAIN: Function{[[FID1:.*]]}, mangled = _main +MAIN-NEXT: Block{[[FID1]]} +MAIN: Variable{{.*}}, name = "array_pointer" +MAIN-SAME: (int (*)[2][4]), scope = local +MAIN: Variable{{.*}}, name = "p_int" +MAIN-SAME: (int *), scope = local +MAIN: Variable{{.*}}, name = "p_member_field" +MAIN-SAME: (int main::ST::*), scope = local +MAIN: Variable{{.*}}, name = "p_member_method" +MAIN-SAME: (int (main::ST::*)(int)), scope = local + +F: Function{[[FID2:.*]]}, demangled = {{.*}}f(int) +F-NEXT: Block{[[FID2]]} +F: Variable{{.*}}, name = "this" +F-SAME: (main::ST *), scope = parameter, location = {{.*}}, artificial +F: Variable{{.*}}, name = "x" +F-SAME: (int), scope = parameter, decl = PointerTypeTest.cpp:8 diff --git a/lit/SymbolFile/PDB/udt-layout.test b/lit/SymbolFile/PDB/udt-layout.test new file mode 100644 index 000000000000..3bca6875a655 --- /dev/null +++ b/lit/SymbolFile/PDB/udt-layout.test @@ -0,0 +1,51 @@ +REQUIRES: windows +RUN: clang-cl /Zi %S/Inputs/UdtLayoutTest.cpp /o %t.exe +RUN: %lldb -b -s %S/Inputs/UdtLayoutTest.script -- %t.exe | FileCheck %s + +CHECK:(int) int C::abc = 123 +CHECK:(List [16]) ls = { +CHECK: [15] = { +CHECK: Prev = 0x00000000 +CHECK: Next = 0x00000000 +CHECK: Value = { +CHECK: B<0> = { +CHECK: A = { +CHECK: _u = (_u1 = '\x02', _u2 = 2, _u3 = 2) +CHECK: } +CHECK: _a = '\x01' +CHECK: _b = 2 +CHECK: _c = 3 +CHECK: } +CHECK: B<1> = { +CHECK: A = { +CHECK: _u = (_u1 = '\x02', _u2 = 2, _u3 = 2) +CHECK: } +CHECK: _a = '\x02' +CHECK: _b = 4 +CHECK: _c = 6 +CHECK: } +CHECK: B<2> = { +CHECK: A = { +CHECK: _u = (_u1 = '\x02', _u2 = 2, _u3 = 2) +CHECK: } +CHECK: _a = '\x03' +CHECK: _b = 6 +CHECK: _c = 9 +CHECK: } +CHECK: B<3> = { +CHECK: A = { +CHECK: _u = (_u1 = '\x02', _u2 = 2, _u3 = 2) +CHECK: } +CHECK: _a = '\x04' +CHECK: _b = 8 +CHECK: _c = 12 +CHECK: } +CHECK: A = { +CHECK: _u = (_u1 = '\x02', _u2 = 2, _u3 = 2) +CHECK: } +CHECK: _x = 5 +CHECK: _y = 10 +CHECK: _z = '\x0f' +CHECK: } +CHECK: } +CHECK:} diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 833cc66fb86c..2955d38f332e 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -2094,95 +2094,6 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos( return template_param_infos.args.size() == template_param_infos.names.size(); } -// Checks whether m1 is an overload of m2 (as opposed to an override). This is -// called by addOverridesForMethod to distinguish overrides (which share a -// vtable entry) from overloads (which require distinct entries). -static bool isOverload(clang::CXXMethodDecl *m1, clang::CXXMethodDecl *m2) { - // FIXME: This should detect covariant return types, but currently doesn't. - lldbassert(&m1->getASTContext() == &m2->getASTContext() && - "Methods should have the same AST context"); - clang::ASTContext &context = m1->getASTContext(); - - const auto *m1Type = - llvm::cast( - context.getCanonicalType(m1->getType())); - - const auto *m2Type = - llvm::cast( - context.getCanonicalType(m2->getType())); - - auto compareArgTypes = - [&context](const clang::QualType &m1p, const clang::QualType &m2p) { - return context.hasSameType(m1p.getUnqualifiedType(), - m2p.getUnqualifiedType()); - }; - - // FIXME: In C++14 and later, we can just pass m2Type->param_type_end() - // as a fourth parameter to std::equal(). - return (m1->getNumParams() != m2->getNumParams()) || - !std::equal(m1Type->param_type_begin(), m1Type->param_type_end(), - m2Type->param_type_begin(), compareArgTypes); -} - -// If decl is a virtual method, walk the base classes looking for methods that -// decl overrides. This table of overridden methods is used by IRGen to -// determine the vtable layout for decl's parent class. -static void addOverridesForMethod(clang::CXXMethodDecl *decl) { - if (!decl->isVirtual()) - return; - - clang::CXXBasePaths paths; - - auto find_overridden_methods = - [decl](const clang::CXXBaseSpecifier *specifier, clang::CXXBasePath &path) { - if (auto *base_record = - llvm::dyn_cast( - specifier->getType()->getAs()->getDecl())) { - - clang::DeclarationName name = decl->getDeclName(); - - // If this is a destructor, check whether the base class destructor is - // virtual. - if (name.getNameKind() == clang::DeclarationName::CXXDestructorName) - if (auto *baseDtorDecl = base_record->getDestructor()) { - if (baseDtorDecl->isVirtual()) { - path.Decls = baseDtorDecl; - return true; - } else - return false; - } - - // Otherwise, search for name in the base class. - for (path.Decls = base_record->lookup(name); !path.Decls.empty(); - path.Decls = path.Decls.slice(1)) { - if (auto *method_decl = - llvm::dyn_cast(path.Decls.front())) - if (method_decl->isVirtual() && !isOverload(decl, method_decl)) { - path.Decls = method_decl; - return true; - } - } - } - - return false; - }; - - if (decl->getParent()->lookupInBases(find_overridden_methods, paths)) { - for (auto *overridden_decl : paths.found_decls()) - decl->addOverriddenMethod( - llvm::cast(overridden_decl)); - } -} - -// If clang_type is a CXXRecordDecl, builds the method override list for each -// of its virtual methods. -static void addMethodOverrides(ClangASTContext &ast, CompilerType &clang_type) { - if (auto *record = - ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType())) - for (auto *method : record->methods()) - addOverridesForMethod(method); -} - bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, CompilerType &clang_type) { @@ -2391,7 +2302,7 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, } } - addMethodOverrides(m_ast, clang_type); + m_ast.AddMethodOverridesForCXXRecordType(clang_type.GetOpaqueQualType()); ClangASTContext::BuildIndirectFields(clang_type); ClangASTContext::CompleteTagDeclarationDefinition(clang_type); diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp index 8bea994aae5d..713fa6e6703b 100644 --- a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -9,11 +9,15 @@ #include "PDBASTParser.h" +#include "SymbolFilePDB.h" + #include "clang/AST/CharUnits.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "lldb/Core/Module.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ClangExternalASTSourceCommon.h" #include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/Declaration.h" #include "lldb/Symbol/SymbolFile.h" @@ -48,8 +52,9 @@ int TranslateUdtKind(PDB_UdtType pdb_kind) { return clang::TTK_Union; case PDB_UdtType::Interface: return clang::TTK_Interface; + default: + llvm_unreachable("unsuported PDB UDT type"); } - return -1; } lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) { @@ -199,6 +204,68 @@ bool GetDeclarationForSymbol(const PDBSymbol &symbol, Declaration &decl) { decl.SetLine(first_line_up->getLineNumber()); return true; } + +AccessType TranslateMemberAccess(PDB_MemberAccess access) { + switch (access) { + case PDB_MemberAccess::Private: + return eAccessPrivate; + case PDB_MemberAccess::Protected: + return eAccessProtected; + case PDB_MemberAccess::Public: + return eAccessPublic; + default: + return eAccessNone; + } +} + +AccessType GetDefaultAccessibilityForUdtKind(PDB_UdtType udt_kind) { + switch (udt_kind) { + case PDB_UdtType::Struct: + case PDB_UdtType::Union: + return eAccessPublic; + case PDB_UdtType::Class: + case PDB_UdtType::Interface: + return eAccessPrivate; + default: + llvm_unreachable("unsupported PDB UDT type"); + } +} + +AccessType GetAccessibilityForUdt(const PDBSymbolTypeUDT &udt) { + AccessType access = TranslateMemberAccess(udt.getAccess()); + if (access != lldb::eAccessNone || !udt.isNested()) + return access; + + auto parent = udt.getClassParent(); + if (!parent) + return lldb::eAccessNone; + + auto parent_udt = llvm::dyn_cast(parent.get()); + if (!parent_udt) + return lldb::eAccessNone; + + return GetDefaultAccessibilityForUdtKind(parent_udt->getUdtKind()); +} + +clang::MSInheritanceAttr::Spelling GetMSInheritance( + const PDBSymbolTypeUDT &udt) { + int base_count = 0; + bool has_virtual = false; + + auto bases_enum = udt.findAllChildren(); + if (bases_enum) { + while (auto base = bases_enum->getNext()) { + base_count++; + has_virtual |= base->isVirtualBaseClass(); + } + } + + if (has_virtual) + return clang::MSInheritanceAttr::Keyword_virtual_inheritance; + if (base_count > 1) + return clang::MSInheritanceAttr::Keyword_multiple_inheritance; + return clang::MSInheritanceAttr::Keyword_single_inheritance; +} } // namespace PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {} @@ -216,29 +283,90 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { Declaration decl; switch (type.getSymTag()) { + case PDB_SymType::BaseClass: { + auto symbol_file = m_ast.GetSymbolFile(); + if (!symbol_file) + return nullptr; + + auto ty = symbol_file->ResolveTypeUID(type.getRawSymbol().getTypeId()); + return ty ? ty->shared_from_this() : nullptr; + } break; case PDB_SymType::UDT: { auto udt = llvm::dyn_cast(&type); assert(udt); - AccessType access = lldb::eAccessPublic; - PDB_UdtType udt_kind = udt->getUdtKind(); - auto tag_type_kind = TranslateUdtKind(udt_kind); - if (tag_type_kind == -1) + + // Note that, unnamed UDT being typedef-ed is generated as a UDT symbol + // other than a Typedef symbol in PDB. For example, + // typedef union { short Row; short Col; } Union; + // is generated as a named UDT in PDB: + // union Union { short Row; short Col; } + // Such symbols will be handled here. + + // Some UDT with trival ctor has zero length. Just ignore. + if (udt->getLength() == 0) + return nullptr; + + // Ignore unnamed-tag UDTs. + if (udt->getName().empty()) return nullptr; - if (udt_kind == PDB_UdtType::Class) - access = lldb::eAccessPrivate; + auto access = GetAccessibilityForUdt(*udt); + + auto tag_type_kind = TranslateUdtKind(udt->getUdtKind()); + + ClangASTMetadata metadata; + metadata.SetUserID(type.getSymIndexId()); + metadata.SetIsDynamicCXXType(false); CompilerType clang_type = m_ast.CreateRecordType( tu_decl_ctx, access, udt->getName().c_str(), tag_type_kind, - lldb::eLanguageTypeC_plus_plus, nullptr); + lldb::eLanguageTypeC_plus_plus, &metadata); + assert(clang_type.IsValid()); + + if (udt->isConstType()) + clang_type = clang_type.AddConstModifier(); + + if (udt->isVolatileType()) + clang_type = clang_type.AddVolatileModifier(); + + clang::CXXRecordDecl *record_decl = + m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType()); + assert(record_decl); + auto inheritance_attr = clang::MSInheritanceAttr::CreateImplicit( + *m_ast.getASTContext(), GetMSInheritance(*udt)); + record_decl->addAttr(inheritance_attr); + + ClangASTContext::StartTagDeclarationDefinition(clang_type); - m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true); + Type::ResolveStateTag type_resolve_state_tag; + auto children = udt->findAllChildren(); + if (!children || children->getChildCount() == 0) { + // PDB does not have symbol of forwarder. We assume we get an udt w/o any + // fields. Just complete it at this point. + ClangASTContext::CompleteTagDeclarationDefinition(clang_type); + m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), false); + + type_resolve_state_tag = Type::eResolveStateFull; + } else { + // Add the type to the forward declarations. It will help us to avoid + // an endless recursion in CompleteTypeFromUdt function. + auto clang_type_removed_fast_quals = + ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType(); + m_forward_decl_clang_type_to_uid[clang_type_removed_fast_quals] = + type.getSymIndexId(); + + m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true); + + type_resolve_state_tag = Type::eResolveStateForward; + } + + GetDeclarationForSymbol(type, decl); return std::make_shared( type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(udt->getName()), udt->getLength(), nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, clang_type, - lldb_private::Type::eResolveStateForward); + type_resolve_state_tag); } break; case PDB_SymType::Enum: { auto enum_type = llvm::dyn_cast(&type); @@ -441,6 +569,26 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { if (!pointee_type) return nullptr; + if (pointer_type->isPointerToDataMember() || + pointer_type->isPointerToMemberFunction()) { + auto class_parent_uid = pointer_type->getRawSymbol().getClassParentId(); + auto class_parent_type = + m_ast.GetSymbolFile()->ResolveTypeUID(class_parent_uid); + assert(class_parent_type); + + CompilerType pointer_ast_type; + pointer_ast_type = ClangASTContext::CreateMemberPointerType( + class_parent_type->GetLayoutCompilerType(), + pointee_type->GetForwardCompilerType()); + assert(pointer_ast_type); + + return std::make_shared( + pointer_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), + pointer_type->getLength(), nullptr, LLDB_INVALID_UID, + lldb_private::Type::eEncodingIsUID, decl, pointer_ast_type, + lldb_private::Type::eResolveStateForward); + } + CompilerType pointer_ast_type; pointer_ast_type = pointee_type->GetFullCompilerType(); if (pointer_type->isReference()) @@ -471,6 +619,47 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { return nullptr; } +bool PDBASTParser::CompleteTypeFromPDB( + lldb_private::CompilerType &compiler_type) { + if (GetClangASTImporter().CanImport(compiler_type)) + return GetClangASTImporter().CompleteType(compiler_type); + + // Remove the type from the forward declarations to avoid + // an endless recursion for types like a linked list. + CompilerType compiler_type_no_qualifiers = + ClangUtil::RemoveFastQualifiers(compiler_type); + auto uid_it = m_forward_decl_clang_type_to_uid.find( + compiler_type_no_qualifiers.GetOpaqueQualType()); + if (uid_it == m_forward_decl_clang_type_to_uid.end()) + return true; + + auto symbol_file = static_cast(m_ast.GetSymbolFile()); + if (!symbol_file) + return false; + + std::unique_ptr symbol = + symbol_file->GetPDBSession().getSymbolById(uid_it->getSecond()); + if (!symbol) + return false; + + m_forward_decl_clang_type_to_uid.erase(uid_it); + + ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), + false); + + switch (symbol->getSymTag()) { + case PDB_SymType::UDT: { + auto udt = llvm::dyn_cast(symbol.get()); + if (!udt) + return false; + + return CompleteTypeFromUDT(*symbol_file, compiler_type, *udt); + } + default: + llvm_unreachable("not a forward clang type decl!"); + } +} + bool PDBASTParser::AddEnumValue(CompilerType enum_type, const PDBSymbolData &enum_value) const { Declaration decl; @@ -513,3 +702,187 @@ bool PDBASTParser::AddEnumValue(CompilerType enum_type, enum_type.GetOpaqueQualType(), underlying_type, decl, name.c_str(), raw_value, byte_size * 8); } + +bool PDBASTParser::CompleteTypeFromUDT( + lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &compiler_type, + llvm::pdb::PDBSymbolTypeUDT &udt) { + ClangASTImporter::LayoutInfo layout_info; + layout_info.bit_size = udt.getLength() * 8; + + auto nested_enums = udt.findAllChildren(); + if (nested_enums) + while (auto nested = nested_enums->getNext()) + symbol_file.ResolveTypeUID(nested->getSymIndexId()); + + auto bases_enum = udt.findAllChildren(); + if (bases_enum) + AddRecordBases(symbol_file, compiler_type, + TranslateUdtKind(udt.getUdtKind()), *bases_enum, + layout_info); + + auto members_enum = udt.findAllChildren(); + if (members_enum) + AddRecordMembers(symbol_file, compiler_type, *members_enum, layout_info); + + auto methods_enum = udt.findAllChildren(); + if (methods_enum) + AddRecordMethods(symbol_file, compiler_type, *methods_enum); + + m_ast.AddMethodOverridesForCXXRecordType(compiler_type.GetOpaqueQualType()); + ClangASTContext::BuildIndirectFields(compiler_type); + ClangASTContext::CompleteTagDeclarationDefinition(compiler_type); + + clang::CXXRecordDecl *record_decl = + m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType()); + if (!record_decl) + return static_cast(compiler_type); + + GetClangASTImporter().InsertRecordDecl(record_decl, layout_info); + + return static_cast(compiler_type); +} + +void PDBASTParser::AddRecordMembers( + lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &record_type, + PDBDataSymbolEnumerator &members_enum, + lldb_private::ClangASTImporter::LayoutInfo &layout_info) const { + while (auto member = members_enum.getNext()) { + if (member->isCompilerGenerated()) + continue; + + auto member_name = member->getName(); + + auto member_type = symbol_file.ResolveTypeUID(member->getTypeId()); + if (!member_type) + continue; + + auto member_comp_type = member_type->GetLayoutCompilerType(); + if (!member_comp_type.GetCompleteType()) { + symbol_file.GetObjectFile()->GetModule()->ReportError( + ":: Class '%s' has a member '%s' of type '%s' " + "which does not have a complete definition.", + record_type.GetTypeName().GetCString(), member_name.c_str(), + member_comp_type.GetTypeName().GetCString()); + if (ClangASTContext::StartTagDeclarationDefinition(member_comp_type)) + ClangASTContext::CompleteTagDeclarationDefinition(member_comp_type); + } + + auto access = TranslateMemberAccess(member->getAccess()); + + switch (member->getDataKind()) { + case PDB_DataKind::Member: { + auto location_type = member->getLocationType(); + + auto bit_size = member->getLength(); + if (location_type == PDB_LocType::ThisRel) + bit_size *= 8; + + auto decl = ClangASTContext::AddFieldToRecordType( + record_type, member_name.c_str(), member_comp_type, access, bit_size); + if (!decl) + continue; + + auto offset = member->getOffset() * 8; + if (location_type == PDB_LocType::BitField) + offset += member->getBitPosition(); + + layout_info.field_offsets.insert(std::make_pair(decl, offset)); + + break; + } + case PDB_DataKind::StaticMember: + ClangASTContext::AddVariableToRecordType(record_type, member_name.c_str(), + member_comp_type, access); + break; + default: + llvm_unreachable("unsupported PDB data kind"); + } + } +} + +void PDBASTParser::AddRecordBases( + lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &record_type, int record_kind, + PDBBaseClassSymbolEnumerator &bases_enum, + lldb_private::ClangASTImporter::LayoutInfo &layout_info) const { + std::vector base_classes; + while (auto base = bases_enum.getNext()) { + auto base_type = symbol_file.ResolveTypeUID(base->getTypeId()); + if (!base_type) + continue; + + auto base_comp_type = base_type->GetFullCompilerType(); + if (!base_comp_type.GetCompleteType()) { + symbol_file.GetObjectFile()->GetModule()->ReportError( + ":: Class '%s' has a base class '%s' " + "which does not have a complete definition.", + record_type.GetTypeName().GetCString(), + base_comp_type.GetTypeName().GetCString()); + if (ClangASTContext::StartTagDeclarationDefinition(base_comp_type)) + ClangASTContext::CompleteTagDeclarationDefinition(base_comp_type); + } + + auto access = TranslateMemberAccess(base->getAccess()); + + auto is_virtual = base->isVirtualBaseClass(); + + auto base_class_spec = m_ast.CreateBaseClassSpecifier( + base_comp_type.GetOpaqueQualType(), access, is_virtual, + record_kind == clang::TTK_Class); + if (!base_class_spec) + continue; + + base_classes.push_back(base_class_spec); + + if (is_virtual) + continue; + + auto decl = m_ast.GetAsCXXRecordDecl(base_comp_type.GetOpaqueQualType()); + if (!decl) + continue; + + auto offset = clang::CharUnits::fromQuantity(base->getOffset()); + layout_info.base_offsets.insert(std::make_pair(decl, offset)); + } + if (!base_classes.empty()) { + m_ast.SetBaseClassesForClassType(record_type.GetOpaqueQualType(), + &base_classes.front(), + base_classes.size()); + ClangASTContext::DeleteBaseClassSpecifiers(&base_classes.front(), + base_classes.size()); + } +} + +void PDBASTParser::AddRecordMethods( + lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &record_type, + PDBFuncSymbolEnumerator &methods_enum) const { + while (auto method = methods_enum.getNext()) { + auto method_type = symbol_file.ResolveTypeUID(method->getSymIndexId()); + // MSVC specific __vecDelDtor. + if (!method_type) + break; + + auto method_comp_type = method_type->GetFullCompilerType(); + if (!method_comp_type.GetCompleteType()) { + symbol_file.GetObjectFile()->GetModule()->ReportError( + ":: Class '%s' has a method '%s' whose type cannot be completed.", + record_type.GetTypeName().GetCString(), + method_comp_type.GetTypeName().GetCString()); + if (ClangASTContext::StartTagDeclarationDefinition(method_comp_type)) + ClangASTContext::CompleteTagDeclarationDefinition(method_comp_type); + } + + // TODO: get mangled name for the method. + m_ast.AddMethodToCXXRecordType( + record_type.GetOpaqueQualType(), method->getName().c_str(), + /*mangled_name*/ nullptr, method_comp_type, + TranslateMemberAccess(method->getAccess()), method->isVirtual(), + method->isStatic(), method->hasInlineAttribute(), + /*is_explicit*/ false, // FIXME: Need this field in CodeView. + /*is_attr_used*/ false, + /*is_artificial*/ method->isCompilerGenerated()); + } +} diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.h b/source/Plugins/SymbolFile/PDB/PDBASTParser.h index d1ac138b8115..5d18d0eac85d 100644 --- a/source/Plugins/SymbolFile/PDB/PDBASTParser.h +++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.h @@ -28,9 +28,14 @@ class CompilerType; namespace llvm { namespace pdb { +template class ConcreteSymbolEnumerator; + class PDBSymbol; class PDBSymbolData; +class PDBSymbolFunc; +class PDBSymbolTypeBaseClass; class PDBSymbolTypeBuiltin; +class PDBSymbolTypeUDT; } // namespace pdb } // namespace llvm @@ -40,13 +45,46 @@ class PDBASTParser { ~PDBASTParser(); lldb::TypeSP CreateLLDBTypeFromPDBType(const llvm::pdb::PDBSymbol &type); + bool CompleteTypeFromPDB(lldb_private::CompilerType &compiler_type); + + lldb_private::ClangASTImporter &GetClangASTImporter() { + return m_ast_importer; + } private: + typedef llvm::DenseMap + ClangTypeToUidMap; + typedef llvm::pdb::ConcreteSymbolEnumerator + PDBDataSymbolEnumerator; + typedef llvm::pdb::ConcreteSymbolEnumerator + PDBBaseClassSymbolEnumerator; + typedef llvm::pdb::ConcreteSymbolEnumerator + PDBFuncSymbolEnumerator; + bool AddEnumValue(lldb_private::CompilerType enum_type, const llvm::pdb::PDBSymbolData &data) const; + bool CompleteTypeFromUDT(lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &compiler_type, + llvm::pdb::PDBSymbolTypeUDT &udt); + void AddRecordMembers( + lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &record_type, + PDBDataSymbolEnumerator &members_enum, + lldb_private::ClangASTImporter::LayoutInfo &layout_info) const; + void AddRecordBases( + lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &record_type, + int record_kind, + PDBBaseClassSymbolEnumerator &bases_enum, + lldb_private::ClangASTImporter::LayoutInfo &layout_info) const; + void AddRecordMethods( + lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &record_type, + PDBFuncSymbolEnumerator &methods_enum) const; lldb_private::ClangASTContext &m_ast; lldb_private::ClangASTImporter m_ast_importer; + ClangTypeToUidMap m_forward_decl_clang_type_to_uid; }; #endif // LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 05f3017819fa..d5b88171a013 100644 --- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -45,7 +45,7 @@ #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" -#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" +#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" // For IsCPPMangledName #include "Plugins/SymbolFile/PDB/PDBASTParser.h" #include "Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h" @@ -459,10 +459,13 @@ size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) { // This should cause the type to get cached and stored in the `m_types` // lookup. - if (!ResolveTypeUID(symbol->getSymIndexId())) - continue; - - ++num_added; + if (auto type = ResolveTypeUID(symbol->getSymIndexId())) { + // Resolve the type completely to avoid a completion + // (and so a list change, which causes an iterators invalidation) + // during a TypeList dumping + type->GetFullCompilerType(); + ++num_added; + } } } }; @@ -568,8 +571,20 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) { } bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) { - // TODO: Implement this - return false; + std::lock_guard guard( + GetObjectFile()->GetModule()->GetMutex()); + + ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null( + GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus)); + if (!clang_ast_ctx) + return false; + + PDBASTParser *pdb = + llvm::dyn_cast(clang_ast_ctx->GetPDBParser()); + if (!pdb) + return false; + + return pdb->CompleteTypeFromPDB(compiler_type); } lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) { diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp index 301b9b38b865..043aaa3f2e2d 100644 --- a/source/Symbol/ClangASTContext.cpp +++ b/source/Symbol/ClangASTContext.cpp @@ -124,6 +124,84 @@ ClangASTContextSupportsLanguage(lldb::LanguageType language) { // Use Clang for D until there is a proper language plugin for it language == eLanguageTypeD; } + +// Checks whether m1 is an overload of m2 (as opposed to an override). This is +// called by addOverridesForMethod to distinguish overrides (which share a +// vtable entry) from overloads (which require distinct entries). +bool isOverload(clang::CXXMethodDecl *m1, clang::CXXMethodDecl *m2) { + // FIXME: This should detect covariant return types, but currently doesn't. + lldbassert(&m1->getASTContext() == &m2->getASTContext() && + "Methods should have the same AST context"); + clang::ASTContext &context = m1->getASTContext(); + + const auto *m1Type = llvm::cast( + context.getCanonicalType(m1->getType())); + + const auto *m2Type = llvm::cast( + context.getCanonicalType(m2->getType())); + + auto compareArgTypes = [&context](const clang::QualType &m1p, + const clang::QualType &m2p) { + return context.hasSameType(m1p.getUnqualifiedType(), + m2p.getUnqualifiedType()); + }; + + // FIXME: In C++14 and later, we can just pass m2Type->param_type_end() + // as a fourth parameter to std::equal(). + return (m1->getNumParams() != m2->getNumParams()) || + !std::equal(m1Type->param_type_begin(), m1Type->param_type_end(), + m2Type->param_type_begin(), compareArgTypes); +} + +// If decl is a virtual method, walk the base classes looking for methods that +// decl overrides. This table of overridden methods is used by IRGen to +// determine the vtable layout for decl's parent class. +void addOverridesForMethod(clang::CXXMethodDecl *decl) { + if (!decl->isVirtual()) + return; + + clang::CXXBasePaths paths; + + auto find_overridden_methods = + [decl](const clang::CXXBaseSpecifier *specifier, + clang::CXXBasePath &path) { + if (auto *base_record = llvm::dyn_cast( + specifier->getType()->getAs()->getDecl())) { + + clang::DeclarationName name = decl->getDeclName(); + + // If this is a destructor, check whether the base class destructor is + // virtual. + if (name.getNameKind() == clang::DeclarationName::CXXDestructorName) + if (auto *baseDtorDecl = base_record->getDestructor()) { + if (baseDtorDecl->isVirtual()) { + path.Decls = baseDtorDecl; + return true; + } else + return false; + } + + // Otherwise, search for name in the base class. + for (path.Decls = base_record->lookup(name); !path.Decls.empty(); + path.Decls = path.Decls.slice(1)) { + if (auto *method_decl = + llvm::dyn_cast(path.Decls.front())) + if (method_decl->isVirtual() && !isOverload(decl, method_decl)) { + path.Decls = method_decl; + return true; + } + } + } + + return false; + }; + + if (decl->getParent()->lookupInBases(find_overridden_methods, paths)) { + for (auto *overridden_decl : paths.found_decls()) + decl->addOverriddenMethod( + llvm::cast(overridden_decl)); + } +} } typedef lldb_private::ThreadSafeDenseMap @@ -6371,7 +6449,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( language_flags = 0; const bool idx_is_valid = idx < GetNumChildren(type, omit_empty_base_classes); - uint32_t bit_offset; + int32_t bit_offset; switch (parent_type_class) { case clang::Type::Builtin: if (idx_is_valid) { @@ -6463,8 +6541,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( cxx_record_decl, base_class_decl); const lldb::addr_t base_offset_addr = vbtable_ptr + vbtable_index * 4; - const uint32_t base_offset = - process->ReadUnsignedIntegerFromMemory( + const int32_t base_offset = + process->ReadSignedIntegerFromMemory( base_offset_addr, 4, UINT32_MAX, err); if (base_offset != UINT32_MAX) { handled = true; @@ -6488,8 +6566,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( vtable_ptr + base_offset_offset.getQuantity(); const uint32_t base_offset_size = process->GetAddressByteSize(); - const uint64_t base_offset = - process->ReadUnsignedIntegerFromMemory( + const int64_t base_offset = + process->ReadSignedIntegerFromMemory( base_offset_addr, base_offset_size, UINT32_MAX, err); if (base_offset < UINT32_MAX) { @@ -8127,6 +8205,13 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType( return cxx_method_decl; } +void ClangASTContext::AddMethodOverridesForCXXRecordType( + lldb::opaque_compiler_type_t type) { + if (auto *record = GetAsCXXRecordDecl(type)) + for (auto *method : record->methods()) + addOverridesForMethod(method); +} + #pragma mark C++ Base Classes clang::CXXBaseSpecifier * @@ -9666,11 +9751,16 @@ bool ClangASTContext::LayoutRecordType( llvm::DenseMap &vbase_offsets) { ClangASTContext *ast = (ClangASTContext *)baton; - DWARFASTParserClang *dwarf_ast_parser = - (DWARFASTParserClang *)ast->GetDWARFParser(); - return dwarf_ast_parser->GetClangASTImporter().LayoutRecordType( - record_decl, bit_size, alignment, field_offsets, base_offsets, - vbase_offsets); + lldb_private::ClangASTImporter *importer = nullptr; + if (ast->m_dwarf_ast_parser_ap) + importer = &ast->m_dwarf_ast_parser_ap->GetClangASTImporter(); + if (!importer && ast->m_pdb_ast_parser_ap) + importer = &ast->m_pdb_ast_parser_ap->GetClangASTImporter(); + if (!importer) + return false; + + return importer->LayoutRecordType(record_decl, bit_size, alignment, + field_offsets, base_offsets, vbase_offsets); } //---------------------------------------------------------------------- From 8999a2f5189944a506367e0776e1e53d7232f569 Mon Sep 17 00:00:00 2001 From: Stefan Granitz Date: Tue, 14 Aug 2018 11:07:18 +0000 Subject: [PATCH 0101/1112] Fix: ConstString::GetConstCStringAndSetMangledCounterPart() should update the value if the key exists already Summary: This issue came up because it caused problems in our unit tests. The StringPool did connect counterparts only once and silently ignored the values passed in subsequent calls. The simplest solution for the unit tests would be silent overwrite. In practice, however, it seems useful to assert that we never overwrite a different mangled counterpart. If we ever have mangled counterparts for other languages than C++, this makes it more likely to notice collisions. I added an assertion that allows the following cases: * inserting a new value * overwriting the empty string * overwriting with an identical value I fixed the unit tests, which used "random" strings and thus produced collisions. It would be even better if there was a way to reset or isolate the StringPool, but that's a different story. Reviewers: jingham, friss, labath Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D50536 git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339669 91177308-0d34-0410-b5e6-96231b3b80d8 --- source/Utility/ConstString.cpp | 15 ++++++--- unittests/Utility/ConstStringTest.cpp | 46 +++++++++++++++++++-------- 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/source/Utility/ConstString.cpp b/source/Utility/ConstString.cpp index e903783df52e..d4bfbcc7a64d 100644 --- a/source/Utility/ConstString.cpp +++ b/source/Utility/ConstString.cpp @@ -119,11 +119,16 @@ class Pool { const uint8_t h = hash(demangled); llvm::sys::SmartScopedWriter wlock(m_string_pools[h].m_mutex); - // Make string pool entry with the mangled counterpart already set - StringPoolEntryType &entry = - *m_string_pools[h] - .m_string_map.insert(std::make_pair(demangled, mangled_ccstr)) - .first; + // Make or update string pool entry with the mangled counterpart + StringPool &map = m_string_pools[h].m_string_map; + StringPoolEntryType &entry = *map.try_emplace(demangled).first; + + assert((entry.second == nullptr || entry.second == mangled_ccstr || + strlen(entry.second) == 0) && + "The demangled string must have a unique counterpart or otherwise " + "it must be empty"); + + entry.second = mangled_ccstr; // Extract the const version of the demangled_cstr demangled_ccstr = entry.getKeyData(); diff --git a/unittests/Utility/ConstStringTest.cpp b/unittests/Utility/ConstStringTest.cpp index 5ad6ea986bd0..2bae896002bc 100644 --- a/unittests/Utility/ConstStringTest.cpp +++ b/unittests/Utility/ConstStringTest.cpp @@ -18,25 +18,45 @@ TEST(ConstStringTest, format_provider) { } TEST(ConstStringTest, MangledCounterpart) { - ConstString foo("foo"); + ConstString uvw("uvw"); ConstString counterpart; - EXPECT_FALSE(foo.GetMangledCounterpart(counterpart)); + EXPECT_FALSE(uvw.GetMangledCounterpart(counterpart)); EXPECT_EQ("", counterpart.GetStringRef()); - ConstString bar; - bar.SetStringWithMangledCounterpart("bar", foo); - EXPECT_EQ("bar", bar.GetStringRef()); + ConstString xyz; + xyz.SetStringWithMangledCounterpart("xyz", uvw); + EXPECT_EQ("xyz", xyz.GetStringRef()); - EXPECT_TRUE(bar.GetMangledCounterpart(counterpart)); - EXPECT_EQ("foo", counterpart.GetStringRef()); + EXPECT_TRUE(xyz.GetMangledCounterpart(counterpart)); + EXPECT_EQ("uvw", counterpart.GetStringRef()); - EXPECT_TRUE(foo.GetMangledCounterpart(counterpart)); - EXPECT_EQ("bar", counterpart.GetStringRef()); + EXPECT_TRUE(uvw.GetMangledCounterpart(counterpart)); + EXPECT_EQ("xyz", counterpart.GetStringRef()); +} + +TEST(ConstStringTest, UpdateMangledCounterpart) { + { // Add counterpart + ConstString some1; + some1.SetStringWithMangledCounterpart("some", ConstString("")); + } + { // Overwrite empty string + ConstString some2; + some2.SetStringWithMangledCounterpart("some", ConstString("one")); + } + { // Overwrite with identical value + ConstString some2; + some2.SetStringWithMangledCounterpart("some", ConstString("one")); + } + { // Check counterpart is set + ConstString counterpart; + EXPECT_TRUE(ConstString("some").GetMangledCounterpart(counterpart)); + EXPECT_EQ("one", counterpart.GetStringRef()); + } } TEST(ConstStringTest, FromMidOfBufferStringRef) { // StringRef's into bigger buffer: no null termination - const char *buffer = "foobarbaz"; + const char *buffer = "abcdefghi"; llvm::StringRef foo_ref(buffer, 3); llvm::StringRef bar_ref(buffer + 3, 3); @@ -44,14 +64,14 @@ TEST(ConstStringTest, FromMidOfBufferStringRef) { ConstString bar; bar.SetStringWithMangledCounterpart(bar_ref, foo); - EXPECT_EQ("bar", bar.GetStringRef()); + EXPECT_EQ("def", bar.GetStringRef()); ConstString counterpart; EXPECT_TRUE(bar.GetMangledCounterpart(counterpart)); - EXPECT_EQ("foo", counterpart.GetStringRef()); + EXPECT_EQ("abc", counterpart.GetStringRef()); EXPECT_TRUE(foo.GetMangledCounterpart(counterpart)); - EXPECT_EQ("bar", counterpart.GetStringRef()); + EXPECT_EQ("def", counterpart.GetStringRef()); } TEST(ConstStringTest, NullAndEmptyStates) { From 235b0d55f3f941c08a49711795ea7d2fdcd55910 Mon Sep 17 00:00:00 2001 From: Stefan Granitz Date: Tue, 14 Aug 2018 11:32:51 +0000 Subject: [PATCH 0102/1112] Remove unused FastDemangle sources git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@339671 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/lldb/Utility/FastDemangle.h | 26 - lldb.xcodeproj/project.pbxproj | 6 - .../Language/CPlusPlus/CPlusPlusLanguage.cpp | 2 +- source/Utility/CMakeLists.txt | 1 - source/Utility/FastDemangle.cpp | 2393 ----------------- 5 files changed, 1 insertion(+), 2427 deletions(-) delete mode 100644 include/lldb/Utility/FastDemangle.h delete mode 100644 source/Utility/FastDemangle.cpp diff --git a/include/lldb/Utility/FastDemangle.h b/include/lldb/Utility/FastDemangle.h deleted file mode 100644 index f779aaa04606..000000000000 --- a/include/lldb/Utility/FastDemangle.h +++ /dev/null @@ -1,26 +0,0 @@ -//===-- FastDemangle.h ------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_FastDemangle_h_ -#define liblldb_FastDemangle_h_ - -#include - -#include - -namespace lldb_private { - -char *FastDemangle(const char *mangled_name); - -char * -FastDemangle(const char *mangled_name, size_t mangled_name_length, - std::function primitive_type_hook = nullptr); -} - -#endif diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj index e4e92a2738cc..c7465c8db151 100644 --- a/lldb.xcodeproj/project.pbxproj +++ b/lldb.xcodeproj/project.pbxproj @@ -295,7 +295,6 @@ 49A1CAC51430E8DE00306AC9 /* ExpressionSourceCode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A1CAC31430E8BD00306AC9 /* ExpressionSourceCode.cpp */; }; 4984BA161B979973008658D4 /* ExpressionVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4984BA151B979973008658D4 /* ExpressionVariable.cpp */; }; 4984BA181B979C08008658D4 /* ExpressionVariable.h in Headers */ = {isa = PBXBuildFile; fileRef = 4984BA171B979C08008658D4 /* ExpressionVariable.h */; }; - AFC2DCE71E6E2ED000283714 /* FastDemangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFC2DCE61E6E2ED000283714 /* FastDemangle.cpp */; }; 2689006E13353E1A00698AC0 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C6EA213011581005E16B0 /* File.cpp */; }; 3FDFDDBD199C3A06009756A7 /* FileAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FDFDDBC199C3A06009756A7 /* FileAction.cpp */; }; 3FDFDDBF199D345E009756A7 /* FileCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3FDFDDBE199D345E009756A7 /* FileCache.cpp */; }; @@ -1807,8 +1806,6 @@ 4C29E77D1BA2403F00DFF855 /* ExpressionTypeSystemHelper.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = ExpressionTypeSystemHelper.h; path = include/lldb/Expression/ExpressionTypeSystemHelper.h; sourceTree = ""; }; 4984BA151B979973008658D4 /* ExpressionVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExpressionVariable.cpp; path = source/Expression/ExpressionVariable.cpp; sourceTree = ""; }; 4984BA171B979C08008658D4 /* ExpressionVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExpressionVariable.h; path = include/lldb/Expression/ExpressionVariable.h; sourceTree = ""; }; - AFC2DCE61E6E2ED000283714 /* FastDemangle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FastDemangle.cpp; path = source/Utility/FastDemangle.cpp; sourceTree = ""; }; - AFC2DCED1E6E2F9800283714 /* FastDemangle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FastDemangle.h; path = include/lldb/Utility/FastDemangle.h; sourceTree = ""; }; 260C6EA213011581005E16B0 /* File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = File.cpp; sourceTree = ""; }; 260C6EA013011578005E16B0 /* File.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = File.h; path = include/lldb/Host/File.h; sourceTree = ""; }; 3FDFDDBC199C3A06009756A7 /* FileAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FileAction.cpp; path = source/Target/FileAction.cpp; sourceTree = ""; }; @@ -4510,8 +4507,6 @@ 49CA96F41E6AAC8E00C03FEE /* DataExtractor.h */, 49CA96E91E6AAC6600C03FEE /* DataExtractor.cpp */, 26BC7DD310F1B7D500F91463 /* Endian.h */, - AFC2DCE61E6E2ED000283714 /* FastDemangle.cpp */, - AFC2DCED1E6E2F9800283714 /* FastDemangle.h */, 4CBFF0471F579A36004AFA92 /* Flags.h */, 236124A61986B50E004EFC37 /* IOObject.h */, 236124A21986B4E2004EFC37 /* IOObject.cpp */, @@ -8005,7 +8000,6 @@ 268900FF13353E6F00698AC0 /* ThreadPlanShouldStopHere.cpp in Sources */, 2579065F1BD0488D00178368 /* DomainSocket.cpp in Sources */, 2689010013353E6F00698AC0 /* ThreadPlanStepInstruction.cpp in Sources */, - AFC2DCE71E6E2ED000283714 /* FastDemangle.cpp in Sources */, 232CB61B191E00CD00EF39FC /* NativeThreadProtocol.cpp in Sources */, 4CD44CFB20B37C440003557C /* DWARFIndex.cpp in Sources */, 2689010113353E6F00698AC0 /* ThreadPlanStepOut.cpp in Sources */, diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 8148044496c5..46c9c40885f3 100644 --- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -323,7 +323,7 @@ static ConstString SubsPrimitiveParmItanium(llvm::StringRef mangled, } }; - // FastDemangle will call back for each instance of a primitive type, + // The demangler will call back for each instance of a primitive type, // allowing us to perform substitution PrimitiveParmSubs parmSubs(mangled, search, replace); assert(mangled.data()[mangled.size()] == '\0' && "Expect C-String"); diff --git a/source/Utility/CMakeLists.txt b/source/Utility/CMakeLists.txt index eed72f0c26e6..6d05de566979 100644 --- a/source/Utility/CMakeLists.txt +++ b/source/Utility/CMakeLists.txt @@ -51,7 +51,6 @@ add_lldb_library(lldbUtility DataEncoder.cpp DataExtractor.cpp Environment.cpp - FastDemangle.cpp FileSpec.cpp IOObject.cpp JSON.cpp diff --git a/source/Utility/FastDemangle.cpp b/source/Utility/FastDemangle.cpp deleted file mode 100644 index d92670a9199b..000000000000 --- a/source/Utility/FastDemangle.cpp +++ /dev/null @@ -1,2393 +0,0 @@ -//===-- FastDemangle.cpp ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Utility/FastDemangle.h" - -#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH - -#include - -#include -#include -#include - -//#define DEBUG_FAILURES 1 -//#define DEBUG_SUBSTITUTIONS 1 -//#define DEBUG_TEMPLATE_ARGS 1 -//#define DEBUG_HIGHWATER 1 -//#define DEBUG_REORDERING 1 - -namespace { - -/// Represents the collection of qualifiers on a type - -enum Qualifiers { - QualifierNone = 0, - QualifierConst = 1, - QualifierRestrict = 2, - QualifierVolatile = 4, - QualifierReference = 8, - QualifierRValueReference = 16, - QualifierPointer = 32 -}; - -/// Categorizes the recognized operators - -enum class OperatorKind { - Unary, - Postfix, - Binary, - Ternary, - Other, - ConversionOperator, - Vendor, - NoMatch -}; - -/// Represents one of the recognized two-character operator abbreviations used -/// when parsing operators as names and expressions - -struct Operator { - const char *name; - OperatorKind kind; -}; - -/// Represents a range of characters in the output buffer, typically for use -/// with RewriteRange() - -struct BufferRange { - int offset; - int length; -}; - -/// Transient state required while parsing a name - -struct NameState { - bool parse_function_params; - bool is_last_generic; - bool has_no_return_type; - BufferRange last_name_range; -}; - -/// LLDB's fast C++ demangler -/// -/// This is an incomplete implementation designed to speed up the demangling -/// process that is often a bottleneck when LLDB stops a process for the first -/// time. Where the implementation doesn't know how to demangle a symbol it -/// fails gracefully to allow the caller to fall back to the existing -/// demangler. -/// -/// Over time the full mangling spec should be supported without compromising -/// performance for the most common cases. - -class SymbolDemangler { -public: - //---------------------------------------------------- - // Public API - //---------------------------------------------------- - - /// Create a SymbolDemangler - /// - /// The newly created demangler allocates and owns scratch memory sufficient - /// for demangling typical symbols. Additional memory will be allocated if - /// needed and managed by the demangler instance. - - SymbolDemangler() { - m_buffer = (char *)malloc(8192); - m_buffer_end = m_buffer + 8192; - m_owns_buffer = true; - - m_rewrite_ranges = (BufferRange *)malloc(128 * sizeof(BufferRange)); - m_rewrite_ranges_size = 128; - m_owns_m_rewrite_ranges = true; - } - - /// Create a SymbolDemangler that uses provided scratch memory - /// - /// The provided memory is not owned by the demangler. It will be - /// overwritten during calls to GetDemangledCopy() but can be used for other - /// purposes between calls. The provided memory will not be freed when this - /// instance is destroyed. - /// - /// If demangling a symbol requires additional space it will be allocated - /// and managed by the demangler instance. - /// - /// @param storage_ptr Valid pointer to at least storage_size bytes of space - /// that the SymbolDemangler can use during demangling - /// - /// @param storage_size Number of bytes of space available scratch memory - /// referenced by storage_ptr - - SymbolDemangler(void *storage_ptr, size_t storage_size, - std::function builtins_hook = nullptr) - : m_builtins_hook(builtins_hook) { - // Use up to 1/8th of the provided space for rewrite ranges - m_rewrite_ranges_size = (storage_size >> 3) / sizeof(BufferRange); - m_rewrite_ranges = (BufferRange *)storage_ptr; - m_owns_m_rewrite_ranges = false; - - // Use the rest for the character buffer - m_buffer = - (char *)storage_ptr + m_rewrite_ranges_size * sizeof(BufferRange); - m_buffer_end = (const char *)storage_ptr + storage_size; - m_owns_buffer = false; - } - - /// Destroys the SymbolDemangler and deallocates any scratch memory that it - /// owns - - ~SymbolDemangler() { - if (m_owns_buffer) - free(m_buffer); - if (m_owns_m_rewrite_ranges) - free(m_rewrite_ranges); - } - -#ifdef DEBUG_HIGHWATER - int highwater_store = 0; - int highwater_buffer = 0; -#endif - - /// Parses the provided mangled name and returns a newly allocated - /// demangling - /// - /// @param mangled_name Valid null-terminated C++ mangled name following the - /// Itanium C++ ABI mangling specification as implemented by Clang - /// - /// @result Newly allocated null-terminated demangled name when demangling - /// is successful, and nullptr when demangling fails. The caller is - /// responsible for freeing the allocated memory. - - char *GetDemangledCopy(const char *mangled_name, - long mangled_name_length = 0) { - if (!ParseMangling(mangled_name, mangled_name_length)) - return nullptr; - -#ifdef DEBUG_HIGHWATER - int rewrite_count = m_next_substitute_index + - (m_rewrite_ranges_size - 1 - m_next_template_arg_index); - int buffer_size = (int)(m_write_ptr - m_buffer); - if (rewrite_count > highwater_store) - highwater_store = rewrite_count; - if (buffer_size > highwater_buffer) - highwater_buffer = buffer_size; -#endif - - int length = (int)(m_write_ptr - m_buffer); - char *copy = (char *)malloc(length + 1); - memcpy(copy, m_buffer, length); - copy[length] = '\0'; - return copy; - } - -private: - //---------------------------------------------------- - // Grow methods - // - // Manage the storage used during demangling - //---------------------------------------------------- - - void GrowBuffer(long min_growth = 0) { - // By default, double the size of the buffer - long growth = m_buffer_end - m_buffer; - - // Avoid growing by more than 1MB at a time - if (growth > 1 << 20) - growth = 1 << 20; - - // ... but never grow by less than requested, or 1K, whichever is greater - if (min_growth < 1024) - min_growth = 1024; - if (growth < min_growth) - growth = min_growth; - - // Allocate the new m_buffer and migrate content - long new_size = (m_buffer_end - m_buffer) + growth; - char *new_buffer = (char *)malloc(new_size); - memcpy(new_buffer, m_buffer, m_write_ptr - m_buffer); - if (m_owns_buffer) - free(m_buffer); - m_owns_buffer = true; - - // Update references to the new buffer - m_write_ptr = new_buffer + (m_write_ptr - m_buffer); - m_buffer = new_buffer; - m_buffer_end = m_buffer + new_size; - } - - void GrowRewriteRanges() { - // By default, double the size of the array - int growth = m_rewrite_ranges_size; - - // Apply reasonable minimum and maximum sizes for growth - if (growth > 128) - growth = 128; - if (growth < 16) - growth = 16; - - // Allocate the new array and migrate content - int bytes = (m_rewrite_ranges_size + growth) * sizeof(BufferRange); - BufferRange *new_ranges = (BufferRange *)malloc(bytes); - for (int index = 0; index < m_next_substitute_index; index++) { - new_ranges[index] = m_rewrite_ranges[index]; - } - for (int index = m_rewrite_ranges_size - 1; - index > m_next_template_arg_index; index--) { - new_ranges[index + growth] = m_rewrite_ranges[index]; - } - if (m_owns_m_rewrite_ranges) - free(m_rewrite_ranges); - m_owns_m_rewrite_ranges = true; - - // Update references to the new array - m_rewrite_ranges = new_ranges; - m_rewrite_ranges_size += growth; - m_next_template_arg_index += growth; - } - - //---------------------------------------------------- - // Range and state management - //---------------------------------------------------- - - int GetStartCookie() { return (int)(m_write_ptr - m_buffer); } - - BufferRange EndRange(int start_cookie) { - return {start_cookie, (int)(m_write_ptr - (m_buffer + start_cookie))}; - } - - void ReorderRange(BufferRange source_range, int insertion_point_cookie) { - // Ensure there's room the preserve the source range - if (m_write_ptr + source_range.length > m_buffer_end) { - GrowBuffer(m_write_ptr + source_range.length - m_buffer_end); - } - - // Reorder the content - memcpy(m_write_ptr, m_buffer + source_range.offset, source_range.length); - memmove(m_buffer + insertion_point_cookie + source_range.length, - m_buffer + insertion_point_cookie, - source_range.offset - insertion_point_cookie); - memcpy(m_buffer + insertion_point_cookie, m_write_ptr, source_range.length); - - // Fix up rewritable ranges, covering both substitutions and templates - int index = 0; - while (true) { - if (index == m_next_substitute_index) - index = m_next_template_arg_index + 1; - if (index == m_rewrite_ranges_size) - break; - - // Affected ranges are either shuffled forward when after the insertion - // but before the source, or backward when inside the source - int candidate_offset = m_rewrite_ranges[index].offset; - if (candidate_offset >= insertion_point_cookie) { - if (candidate_offset < source_range.offset) { - m_rewrite_ranges[index].offset += source_range.length; - } else if (candidate_offset >= source_range.offset) { - m_rewrite_ranges[index].offset -= - (source_range.offset - insertion_point_cookie); - } - } - ++index; - } - } - - void EndSubstitution(int start_cookie) { - if (m_next_substitute_index == m_next_template_arg_index) - GrowRewriteRanges(); - - int index = m_next_substitute_index++; - m_rewrite_ranges[index] = EndRange(start_cookie); -#ifdef DEBUG_SUBSTITUTIONS - printf("Saved substitution # %d = %.*s\n", index, - m_rewrite_ranges[index].length, m_buffer + start_cookie); -#endif - } - - void EndTemplateArg(int start_cookie) { - if (m_next_substitute_index == m_next_template_arg_index) - GrowRewriteRanges(); - - int index = m_next_template_arg_index--; - m_rewrite_ranges[index] = EndRange(start_cookie); -#ifdef DEBUG_TEMPLATE_ARGS - printf("Saved template arg # %d = %.*s\n", - m_rewrite_ranges_size - index - 1, m_rewrite_ranges[index].length, - m_buffer + start_cookie); -#endif - } - - void ResetTemplateArgs() { - // TODO: this works, but is it the right thing to do? - // Should we push/pop somehow at the call sites? - m_next_template_arg_index = m_rewrite_ranges_size - 1; - } - - //---------------------------------------------------- - // Write methods - // - // Appends content to the existing output buffer - //---------------------------------------------------- - - void Write(char character) { - if (m_write_ptr == m_buffer_end) - GrowBuffer(); - *m_write_ptr++ = character; - } - - void Write(const char *content) { Write(content, strlen(content)); } - - void Write(const char *content, long content_length) { - char *end_m_write_ptr = m_write_ptr + content_length; - if (end_m_write_ptr > m_buffer_end) { - if (content >= m_buffer && content < m_buffer_end) { - long offset = content - m_buffer; - GrowBuffer(end_m_write_ptr - m_buffer_end); - content = m_buffer + offset; - } else { - GrowBuffer(end_m_write_ptr - m_buffer_end); - } - end_m_write_ptr = m_write_ptr + content_length; - } - memcpy(m_write_ptr, content, content_length); - m_write_ptr = end_m_write_ptr; - } -#define WRITE(x) Write(x, sizeof(x) - 1) - - void WriteTemplateStart() { Write('<'); } - - void WriteTemplateEnd() { - // Put a space between terminal > characters when nesting templates - if (m_write_ptr != m_buffer && *(m_write_ptr - 1) == '>') - WRITE(" >"); - else - Write('>'); - } - - void WriteCommaSpace() { WRITE(", "); } - - void WriteNamespaceSeparator() { WRITE("::"); } - - void WriteStdPrefix() { WRITE("std::"); } - - void WriteQualifiers(int qualifiers, bool space_before_reference = true) { - if (qualifiers & QualifierPointer) - Write('*'); - if (qualifiers & QualifierConst) - WRITE(" const"); - if (qualifiers & QualifierVolatile) - WRITE(" volatile"); - if (qualifiers & QualifierRestrict) - WRITE(" restrict"); - if (qualifiers & QualifierReference) { - if (space_before_reference) - WRITE(" &"); - else - Write('&'); - } - if (qualifiers & QualifierRValueReference) { - if (space_before_reference) - WRITE(" &&"); - else - WRITE("&&"); - } - } - - //---------------------------------------------------- - // Rewrite methods - // - // Write another copy of content already present earlier in the output buffer - //---------------------------------------------------- - - void RewriteRange(BufferRange range) { - Write(m_buffer + range.offset, range.length); - } - - bool RewriteSubstitution(int index) { - if (index < 0 || index >= m_next_substitute_index) { -#ifdef DEBUG_FAILURES - printf("*** Invalid substitution #%d\n", index); -#endif - return false; - } - RewriteRange(m_rewrite_ranges[index]); - return true; - } - - bool RewriteTemplateArg(int template_index) { - int index = m_rewrite_ranges_size - 1 - template_index; - if (template_index < 0 || index <= m_next_template_arg_index) { -#ifdef DEBUG_FAILURES - printf("*** Invalid template arg reference #%d\n", template_index); -#endif - return false; - } - RewriteRange(m_rewrite_ranges[index]); - return true; - } - - //---------------------------------------------------- - // TryParse methods - // - // Provide information with return values instead of writing to the output - // buffer - // - // Values indicating failure guarantee that the pre- call m_read_ptr is - // unchanged - //---------------------------------------------------- - - int TryParseNumber() { - unsigned char digit = *m_read_ptr - '0'; - if (digit > 9) - return -1; - - int count = digit; - while (true) { - digit = *++m_read_ptr - '0'; - if (digit > 9) - break; - - count = count * 10 + digit; - } - return count; - } - - int TryParseBase36Number() { - char digit = *m_read_ptr; - int count; - if (digit >= '0' && digit <= '9') - count = digit -= '0'; - else if (digit >= 'A' && digit <= 'Z') - count = digit -= ('A' - 10); - else - return -1; - - while (true) { - digit = *++m_read_ptr; - if (digit >= '0' && digit <= '9') - digit -= '0'; - else if (digit >= 'A' && digit <= 'Z') - digit -= ('A' - 10); - else - break; - - count = count * 36 + digit; - } - return count; - } - - // ::= v # void - // ::= w # wchar_t - // ::= b # bool - // ::= c # char - // ::= a # signed char - // ::= h # unsigned char - // ::= s # short - // ::= t # unsigned short - // ::= i # int - // ::= j # unsigned int - // ::= l # long - // ::= m # unsigned long - // ::= x # long long, __int64 - // ::= y # unsigned long long, __int64 - // ::= n # __int128 - // ::= o # unsigned __int128 - // ::= f # float - // ::= d # double - // ::= e # long double, __float80 - // ::= g # __float128 - // ::= z # ellipsis - // ::= Dd # IEEE 754r decimal floating point (64 bits) - // ::= De # IEEE 754r decimal floating point (128 bits) - // ::= Df # IEEE 754r decimal floating point (32 bits) - // ::= Dh # IEEE 754r half-precision floating point (16 bits) - // ::= Di # char32_t - // ::= Ds # char16_t - // ::= Da # auto (in dependent new-expressions) - // ::= Dn # std::nullptr_t (i.e., decltype(nullptr)) - // ::= u # vendor extended type - - const char *TryParseBuiltinType() { - if (m_builtins_hook) - m_builtins_hook(m_read_ptr); - - switch (*m_read_ptr++) { - case 'v': - return "void"; - case 'w': - return "wchar_t"; - case 'b': - return "bool"; - case 'c': - return "char"; - case 'a': - return "signed char"; - case 'h': - return "unsigned char"; - case 's': - return "short"; - case 't': - return "unsigned short"; - case 'i': - return "int"; - case 'j': - return "unsigned int"; - case 'l': - return "long"; - case 'm': - return "unsigned long"; - case 'x': - return "long long"; - case 'y': - return "unsigned long long"; - case 'n': - return "__int128"; - case 'o': - return "unsigned __int128"; - case 'f': - return "float"; - case 'd': - return "double"; - case 'e': - return "long double"; - case 'g': - return "__float128"; - case 'z': - return "..."; - case 'D': { - switch (*m_read_ptr++) { - case 'd': - return "decimal64"; - case 'e': - return "decimal128"; - case 'f': - return "decimal32"; - case 'h': - return "decimal16"; - case 'i': - return "char32_t"; - case 's': - return "char16_t"; - case 'a': - return "auto"; - case 'c': - return "decltype(auto)"; - case 'n': - return "std::nullptr_t"; - default: - --m_read_ptr; - } - } - } - --m_read_ptr; - return nullptr; - } - - // - // ::= aa # && - // ::= ad # & (unary) - // ::= an # & - // ::= aN # &= - // ::= aS # = - // ::= cl # () - // ::= cm # , - // ::= co # ~ - // ::= da # delete[] - // ::= de # * (unary) - // ::= dl # delete - // ::= dv # / - // ::= dV # /= - // ::= eo # ^ - // ::= eO # ^= - // ::= eq # == - // ::= ge # >= - // ::= gt # > - // ::= ix # [] - // ::= le # <= - // ::= ls # << - // ::= lS # <<= - // ::= lt # < - // ::= mi # - - // ::= mI # -= - // ::= ml # * - // ::= mL # *= - // ::= mm # -- (postfix in context) - // ::= na # new[] - // ::= ne # != - // ::= ng # - (unary) - // ::= nt # ! - // ::= nw # new - // ::= oo # || - // ::= or # | - // ::= oR # |= - // ::= pm # ->* - // ::= pl # + - // ::= pL # += - // ::= pp # ++ (postfix in context) - // ::= ps # + (unary) - // ::= pt # -> - // ::= qu # ? - // ::= rm # % - // ::= rM # %= - // ::= rs # >> - // ::= rS # >>= - // ::= cv # (cast) - // ::= v # vendor extended - // operator - - Operator TryParseOperator() { - switch (*m_read_ptr++) { - case 'a': - switch (*m_read_ptr++) { - case 'a': - return {"&&", OperatorKind::Binary}; - case 'd': - return {"&", OperatorKind::Unary}; - case 'n': - return {"&", OperatorKind::Binary}; - case 'N': - return {"&=", OperatorKind::Binary}; - case 'S': - return {"=", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'c': - switch (*m_read_ptr++) { - case 'l': - return {"()", OperatorKind::Other}; - case 'm': - return {",", OperatorKind::Other}; - case 'o': - return {"~", OperatorKind::Unary}; - case 'v': - return {nullptr, OperatorKind::ConversionOperator}; - } - --m_read_ptr; - break; - case 'd': - switch (*m_read_ptr++) { - case 'a': - return {" delete[]", OperatorKind::Other}; - case 'e': - return {"*", OperatorKind::Unary}; - case 'l': - return {" delete", OperatorKind::Other}; - case 'v': - return {"/", OperatorKind::Binary}; - case 'V': - return {"/=", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'e': - switch (*m_read_ptr++) { - case 'o': - return {"^", OperatorKind::Binary}; - case 'O': - return {"^=", OperatorKind::Binary}; - case 'q': - return {"==", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'g': - switch (*m_read_ptr++) { - case 'e': - return {">=", OperatorKind::Binary}; - case 't': - return {">", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'i': - switch (*m_read_ptr++) { - case 'x': - return {"[]", OperatorKind::Other}; - } - --m_read_ptr; - break; - case 'l': - switch (*m_read_ptr++) { - case 'e': - return {"<=", OperatorKind::Binary}; - case 's': - return {"<<", OperatorKind::Binary}; - case 'S': - return {"<<=", OperatorKind::Binary}; - case 't': - return {"<", OperatorKind::Binary}; - // case 'i': return { "?", OperatorKind::Binary }; - } - --m_read_ptr; - break; - case 'm': - switch (*m_read_ptr++) { - case 'i': - return {"-", OperatorKind::Binary}; - case 'I': - return {"-=", OperatorKind::Binary}; - case 'l': - return {"*", OperatorKind::Binary}; - case 'L': - return {"*=", OperatorKind::Binary}; - case 'm': - return {"--", OperatorKind::Postfix}; - } - --m_read_ptr; - break; - case 'n': - switch (*m_read_ptr++) { - case 'a': - return {" new[]", OperatorKind::Other}; - case 'e': - return {"!=", OperatorKind::Binary}; - case 'g': - return {"-", OperatorKind::Unary}; - case 't': - return {"!", OperatorKind::Unary}; - case 'w': - return {" new", OperatorKind::Other}; - } - --m_read_ptr; - break; - case 'o': - switch (*m_read_ptr++) { - case 'o': - return {"||", OperatorKind::Binary}; - case 'r': - return {"|", OperatorKind::Binary}; - case 'R': - return {"|=", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'p': - switch (*m_read_ptr++) { - case 'm': - return {"->*", OperatorKind::Binary}; - case 's': - return {"+", OperatorKind::Unary}; - case 'l': - return {"+", OperatorKind::Binary}; - case 'L': - return {"+=", OperatorKind::Binary}; - case 'p': - return {"++", OperatorKind::Postfix}; - case 't': - return {"->", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'q': - switch (*m_read_ptr++) { - case 'u': - return {"?", OperatorKind::Ternary}; - } - --m_read_ptr; - break; - case 'r': - switch (*m_read_ptr++) { - case 'm': - return {"%", OperatorKind::Binary}; - case 'M': - return {"%=", OperatorKind::Binary}; - case 's': - return {">>", OperatorKind::Binary}; - case 'S': - return {">=", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'v': - char digit = *m_read_ptr; - if (digit >= '0' && digit <= '9') { - m_read_ptr++; - return {nullptr, OperatorKind::Vendor}; - } - --m_read_ptr; - break; - } - --m_read_ptr; - return {nullptr, OperatorKind::NoMatch}; - } - - // ::= [r] [V] [K] - // ::= R # & ref-qualifier - // ::= O # && ref-qualifier - - int TryParseQualifiers(bool allow_cv, bool allow_ro) { - int qualifiers = QualifierNone; - char next = *m_read_ptr; - if (allow_cv) { - if (next == 'r') // restrict - { - qualifiers |= QualifierRestrict; - next = *++m_read_ptr; - } - if (next == 'V') // volatile - { - qualifiers |= QualifierVolatile; - next = *++m_read_ptr; - } - if (next == 'K') // const - { - qualifiers |= QualifierConst; - next = *++m_read_ptr; - } - } - if (allow_ro) { - if (next == 'R') { - ++m_read_ptr; - qualifiers |= QualifierReference; - } else if (next == 'O') { - ++m_read_ptr; - qualifiers |= QualifierRValueReference; - } - } - return qualifiers; - } - - // := _ # when number < 10 - // := __ _ # when number >= 10 - // extension := decimal-digit+ - - int TryParseDiscriminator() { - const char *discriminator_start = m_read_ptr; - - // Test the extension first, since it's what Clang uses - int discriminator_value = TryParseNumber(); - if (discriminator_value != -1) - return discriminator_value; - - char next = *m_read_ptr; - if (next == '_') { - next = *++m_read_ptr; - if (next == '_') { - ++m_read_ptr; - discriminator_value = TryParseNumber(); - if (discriminator_value != -1 && *m_read_ptr++ != '_') { - return discriminator_value; - } - } else if (next >= '0' && next <= '9') { - ++m_read_ptr; - return next - '0'; - } - } - - // Not a valid discriminator - m_read_ptr = discriminator_start; - return -1; - } - - //---------------------------------------------------- - // Parse methods - // - // Consume input starting from m_read_ptr and produce buffered output at - // m_write_ptr - // - // Failures return false and may leave m_read_ptr in an indeterminate state - //---------------------------------------------------- - - bool Parse(char character) { - if (*m_read_ptr++ == character) - return true; -#ifdef DEBUG_FAILURES - printf("*** Expected '%c'\n", character); -#endif - return false; - } - - // ::= [n] - - bool ParseNumber(bool allow_negative = false) { - if (allow_negative && *m_read_ptr == 'n') { - Write('-'); - ++m_read_ptr; - } - const char *before_digits = m_read_ptr; - while (true) { - unsigned char digit = *m_read_ptr - '0'; - if (digit > 9) - break; - ++m_read_ptr; - } - if (int digit_count = (int)(m_read_ptr - before_digits)) { - Write(before_digits, digit_count); - return true; - } -#ifdef DEBUG_FAILURES - printf("*** Expected number\n"); -#endif - return false; - } - - // ::= S _ - // ::= S_ - // ::= Sa # ::std::allocator ::= Sb # - // ::std::basic_string ::= Ss # ::std::basic_string < char, - // ::std::char_traits, - // ::std::allocator > - // ::= Si # ::std::basic_istream - // > ::= So # ::std::basic_ostream > ::= Sd # - // ::std::basic_iostream > - - bool ParseSubstitution() { - const char *substitution; - switch (*m_read_ptr) { - case 'a': - substitution = "std::allocator"; - break; - case 'b': - substitution = "std::basic_string"; - break; - case 's': - substitution = "std::string"; - break; - case 'i': - substitution = "std::istream"; - break; - case 'o': - substitution = "std::ostream"; - break; - case 'd': - substitution = "std::iostream"; - break; - default: - // A failed attempt to parse a number will return -1 which turns out to be - // perfect here as S_ is the first substitution, S0_ the next and so - // forth - int substitution_index = TryParseBase36Number(); - if (*m_read_ptr++ != '_') { -#ifdef DEBUG_FAILURES - printf("*** Expected terminal _ in substitution\n"); -#endif - return false; - } - return RewriteSubstitution(substitution_index + 1); - } - Write(substitution); - ++m_read_ptr; - return true; - } - - // ::= F [Y] [] E - // - // ::= + # types are possible - // return type, then parameter types - - bool ParseFunctionType(int inner_qualifiers = QualifierNone) { -#ifdef DEBUG_FAILURES - printf("*** Function types not supported\n"); -#endif - // TODO: first steps toward an implementation follow, but they're far - // from complete. Function types tend to bracket other types eg: int (*)() - // when used as the type for "name" becomes int (*name)(). This makes - // substitution et al ... interesting. - return false; - -#if 0 // TODO - if (*m_read_ptr == 'Y') - ++m_read_ptr; - - int return_type_start_cookie = GetStartCookie(); - if (!ParseType()) - return false; - Write(' '); - - int insert_cookie = GetStartCookie(); - Write('('); - bool first_param = true; - int qualifiers = QualifierNone; - while (true) - { - switch (*m_read_ptr) - { - case 'E': - ++m_read_ptr; - Write(')'); - break; - case 'v': - ++m_read_ptr; - continue; - case 'R': - case 'O': - if (*(m_read_ptr + 1) == 'E') - { - qualifiers = TryParseQualifiers (false, true); - Parse('E'); - break; - } - // fallthrough - default: - { - if (first_param) - first_param = false; - else WriteCommaSpace(); - - if (!ParseType()) - return false; - continue; - } - } - break; - } - - if (qualifiers) - { - WriteQualifiers (qualifiers); - EndSubstitution (return_type_start_cookie); - } - - if (inner_qualifiers) - { - int qualifier_start_cookie = GetStartCookie(); - Write ('('); - WriteQualifiers (inner_qualifiers); - Write (')'); - ReorderRange (EndRange (qualifier_start_cookie), insert_cookie); - } - return true; -#endif // TODO - } - - // ::= A _ - // ::= A [] _ - - bool ParseArrayType(int qualifiers = QualifierNone) { -#ifdef DEBUG_FAILURES - printf("*** Array type unsupported\n"); -#endif - // TODO: We fail horribly when recalling these as substitutions or - // templates and trying to constify them eg: - // _ZN4llvm2cl5applyIA28_cNS0_3optIbLb0ENS0_6parserIbEEEEEEvRKT_PT0_ - // - // TODO: Chances are we don't do any better with references and pointers - // that should be type (&) [] instead of type & [] - - return false; - -#if 0 // TODO - if (*m_read_ptr == '_') - { - ++m_read_ptr; - if (!ParseType()) - return false; - if (qualifiers) - WriteQualifiers(qualifiers); - WRITE(" []"); - return true; - } - else - { - const char *before_digits = m_read_ptr; - if (TryParseNumber() != -1) - { - const char *after_digits = m_read_ptr; - if (!Parse('_')) - return false; - if (!ParseType()) - return false; - if (qualifiers) - WriteQualifiers(qualifiers); - Write(' '); - Write('['); - Write(before_digits, after_digits - before_digits); - } - else - { - int type_insertion_cookie = GetStartCookie(); - if (!ParseExpression()) - return false; - if (!Parse('_')) - return false; - - int type_start_cookie = GetStartCookie(); - if (!ParseType()) - return false; - if (qualifiers) - WriteQualifiers(qualifiers); - Write(' '); - Write('['); - ReorderRange (EndRange (type_start_cookie), type_insertion_cookie); - } - Write(']'); - return true; - } -#endif // TODO - } - - // ::= M - - // TODO: Determine how to handle pointers to function members correctly, - // currently not an issue because we don't have function types at all... - bool ParsePointerToMemberType() { - int insertion_cookie = GetStartCookie(); - Write(' '); - if (!ParseType()) - return false; - WRITE("::*"); - - int type_cookie = GetStartCookie(); - if (!ParseType()) - return false; - ReorderRange(EndRange(type_cookie), insertion_cookie); - return true; - } - - // ::= T_ # first template parameter - // ::= T _ - - bool ParseTemplateParam() { - int count = TryParseNumber(); - if (!Parse('_')) - return false; - - // When no number is present we get -1, which is convenient since T_ is the - // zeroth element T0_ is element 1, and so on - return RewriteTemplateArg(count + 1); - } - - // - // Dv _ - bool TryParseVectorType() { - const int dimension = TryParseNumber(); - if (dimension == -1) - return false; - - if (*m_read_ptr++ != '_') - return false; - - char vec_dimens[32] = {'\0'}; - ::snprintf(vec_dimens, sizeof vec_dimens - 1, " __vector(%d)", dimension); - ParseType(); - Write(vec_dimens); - return true; - } - - // ::= - // ::= - // ::= - // ::= - // ::= - // ::= - // ::= - // ::= - // ::= - // ::= - // ::= P # pointer-to - // ::= R # reference-to - // ::= O # rvalue reference-to (C++0x) - // ::= C # complex pair (C 2000) - // ::= G # imaginary (C 2000) - // ::= Dp # pack expansion (C++0x) - // ::= U # vendor extended type qualifier - // extension := U # objc-type extension - // := # starts with Dv - - // ::= objcproto # k0 = 9 + - // + k1 := # - // PU<11+>objcproto 11objc_object 11objc_object -> id - - bool ParseType() { -#ifdef DEBUG_FAILURES - const char *failed_type = m_read_ptr; -#endif - int type_start_cookie = GetStartCookie(); - bool suppress_substitution = false; - - int qualifiers = TryParseQualifiers(true, false); - switch (*m_read_ptr) { - case 'D': - ++m_read_ptr; - switch (*m_read_ptr++) { - case 'p': - if (!ParseType()) - return false; - break; - case 'v': - if (!TryParseVectorType()) - return false; - break; - case 'T': - case 't': - default: -#ifdef DEBUG_FAILURES - printf("*** Unsupported type: %.3s\n", failed_type); -#endif - return false; - } - break; - case 'T': - ++m_read_ptr; - if (!ParseTemplateParam()) - return false; - break; - case 'M': - ++m_read_ptr; - if (!ParsePointerToMemberType()) - return false; - break; - case 'A': - ++m_read_ptr; - if (!ParseArrayType()) - return false; - break; - case 'F': - ++m_read_ptr; - if (!ParseFunctionType()) - return false; - break; - case 'S': - if (*++m_read_ptr == 't') { - ++m_read_ptr; - WriteStdPrefix(); - if (!ParseName()) - return false; - } else { - suppress_substitution = true; - if (!ParseSubstitution()) - return false; - } - break; - case 'P': { - switch (*++m_read_ptr) { - case 'F': - ++m_read_ptr; - if (!ParseFunctionType(QualifierPointer)) - return false; - break; - default: - if (!ParseType()) - return false; - Write('*'); - break; - } - break; - } - case 'R': { - ++m_read_ptr; - if (!ParseType()) - return false; - Write('&'); - break; - } - case 'O': { - ++m_read_ptr; - if (!ParseType()) - return false; - Write('&'); - Write('&'); - break; - } - case 'C': - case 'G': - case 'U': -#ifdef DEBUG_FAILURES - printf("*** Unsupported type: %.3s\n", failed_type); -#endif - return false; - // Test for common cases to avoid TryParseBuiltinType() overhead - case 'N': - case 'Z': - case 'L': - if (!ParseName()) - return false; - break; - default: - if (const char *builtin = TryParseBuiltinType()) { - Write(builtin); - suppress_substitution = true; - } else { - if (!ParseName()) - return false; - } - break; - } - - // Allow base substitutions to be suppressed, but always record - // substitutions for the qualified variant - if (!suppress_substitution) - EndSubstitution(type_start_cookie); - if (qualifiers) { - WriteQualifiers(qualifiers, false); - EndSubstitution(type_start_cookie); - } - return true; - } - - // ::= Ut [ ] _ - // ::= - // - // ::= Ul E [ ] _ - // - // ::= + # Parameter types or "v" if the lambda - // has no parameters - - bool ParseUnnamedTypeName(NameState &name_state) { - switch (*m_read_ptr++) { - case 't': { - int cookie = GetStartCookie(); - WRITE("'unnamed"); - const char *before_digits = m_read_ptr; - if (TryParseNumber() != -1) - Write(before_digits, m_read_ptr - before_digits); - if (!Parse('_')) - return false; - Write('\''); - name_state.last_name_range = EndRange(cookie); - return true; - } - case 'b': { - int cookie = GetStartCookie(); - WRITE("'block"); - const char *before_digits = m_read_ptr; - if (TryParseNumber() != -1) - Write(before_digits, m_read_ptr - before_digits); - if (!Parse('_')) - return false; - Write('\''); - name_state.last_name_range = EndRange(cookie); - return true; - } - case 'l': -#ifdef DEBUG_FAILURES - printf("*** Lambda type names unsupported\n"); -#endif - return false; - } -#ifdef DEBUG_FAILURES - printf("*** Unknown unnamed type %.3s\n", m_read_ptr - 2); -#endif - return false; - } - - // ::= C1 # complete object constructor - // ::= C2 # base object constructor - // ::= C3 # complete object allocating constructor - - bool ParseCtor(NameState &name_state) { - char next = *m_read_ptr; - if (next == '1' || next == '2' || next == '3' || next == '5') { - RewriteRange(name_state.last_name_range); - name_state.has_no_return_type = true; - ++m_read_ptr; - return true; - } -#ifdef DEBUG_FAILURES - printf("*** Broken constructor\n"); -#endif - return false; - } - - // ::= D0 # deleting destructor - // ::= D1 # complete object destructor - // ::= D2 # base object destructor - - bool ParseDtor(NameState &name_state) { - char next = *m_read_ptr; - if (next == '0' || next == '1' || next == '2' || next == '5') { - Write('~'); - RewriteRange(name_state.last_name_range); - name_state.has_no_return_type = true; - ++m_read_ptr; - return true; - } -#ifdef DEBUG_FAILURES - printf("*** Broken destructor\n"); -#endif - return false; - } - - // See TryParseOperator() - - bool ParseOperatorName(NameState &name_state) { -#ifdef DEBUG_FAILURES - const char *operator_ptr = m_read_ptr; -#endif - Operator parsed_operator = TryParseOperator(); - if (parsed_operator.name) { - WRITE("operator"); - Write(parsed_operator.name); - return true; - } - - // Handle special operators - switch (parsed_operator.kind) { - case OperatorKind::Vendor: - WRITE("operator "); - return ParseSourceName(); - case OperatorKind::ConversionOperator: - ResetTemplateArgs(); - name_state.has_no_return_type = true; - WRITE("operator "); - return ParseType(); - default: -#ifdef DEBUG_FAILURES - printf("*** Unknown operator: %.2s\n", operator_ptr); -#endif - return false; - } - } - - // ::= - - bool ParseSourceName() { - int count = TryParseNumber(); - if (count == -1) { -#ifdef DEBUG_FAILURES - printf("*** Malformed source name, missing length count\n"); -#endif - return false; - } - - const char *next_m_read_ptr = m_read_ptr + count; - if (next_m_read_ptr > m_read_end) { -#ifdef DEBUG_FAILURES - printf("*** Malformed source name, premature termination\n"); -#endif - return false; - } - - if (count >= 10 && strncmp(m_read_ptr, "_GLOBAL__N", 10) == 0) - WRITE("(anonymous namespace)"); - else - Write(m_read_ptr, count); - - m_read_ptr = next_m_read_ptr; - return true; - } - - // ::= - // ::= - // ::= - // ::= - - bool ParseUnqualifiedName(NameState &name_state) { - // Note that these are detected directly in ParseNestedName for performance - // rather than switching on the same options twice - char next = *m_read_ptr; - switch (next) { - case 'C': - ++m_read_ptr; - return ParseCtor(name_state); - case 'D': - ++m_read_ptr; - return ParseDtor(name_state); - case 'U': - ++m_read_ptr; - return ParseUnnamedTypeName(name_state); - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': { - int name_start_cookie = GetStartCookie(); - if (!ParseSourceName()) - return false; - name_state.last_name_range = EndRange(name_start_cookie); - return true; - } - default: - return ParseOperatorName(name_state); - }; - } - - // ::= - // ::= St # ::std:: - // extension ::= StL - - bool ParseUnscopedName(NameState &name_state) { - if (*m_read_ptr == 'S' && *(m_read_ptr + 1) == 't') { - WriteStdPrefix(); - if (*(m_read_ptr += 2) == 'L') - ++m_read_ptr; - } - return ParseUnqualifiedName(name_state); - } - - bool ParseIntegerLiteral(const char *prefix, const char *suffix, - bool allow_negative) { - if (prefix) - Write(prefix); - if (!ParseNumber(allow_negative)) - return false; - if (suffix) - Write(suffix); - return Parse('E'); - } - - bool ParseBooleanLiteral() { - switch (*m_read_ptr++) { - case '0': - WRITE("false"); - break; - case '1': - WRITE("true"); - break; - default: -#ifdef DEBUG_FAILURES - printf("*** Boolean literal not 0 or 1\n"); -#endif - return false; - } - return Parse('E'); - } - - // ::= L E # - // integer literal - // ::= L E # - // floating literal - // ::= L E # - // string literal - // ::= L E # - // nullptr literal (i.e., "LDnE") - // ::= L _ E # - // complex floating point literal (C 2000) - // ::= L E # - // external name - - bool ParseExpressionPrimary() { - switch (*m_read_ptr++) { - case 'b': - return ParseBooleanLiteral(); - case 'x': - return ParseIntegerLiteral(nullptr, "ll", true); - case 'l': - return ParseIntegerLiteral(nullptr, "l", true); - case 'i': - return ParseIntegerLiteral(nullptr, nullptr, true); - case 'n': - return ParseIntegerLiteral("(__int128)", nullptr, true); - case 'j': - return ParseIntegerLiteral(nullptr, "u", false); - case 'm': - return ParseIntegerLiteral(nullptr, "ul", false); - case 'y': - return ParseIntegerLiteral(nullptr, "ull", false); - case 'o': - return ParseIntegerLiteral("(unsigned __int128)", nullptr, false); - case '_': - if (*m_read_ptr++ == 'Z') { - if (!ParseEncoding()) - return false; - return Parse('E'); - } - --m_read_ptr; - LLVM_FALLTHROUGH; - case 'w': - case 'c': - case 'a': - case 'h': - case 's': - case 't': - case 'f': - case 'd': - case 'e': -#ifdef DEBUG_FAILURES - printf("*** Unsupported primary expression %.5s\n", m_read_ptr - 1); -#endif - return false; - case 'T': -// Invalid mangled name per -// http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html -#ifdef DEBUG_FAILURES - printf("*** Invalid primary expr encoding\n"); -#endif - return false; - default: - --m_read_ptr; - Write('('); - if (!ParseType()) - return false; - Write(')'); - if (!ParseNumber()) - return false; - return Parse('E'); - } - } - - // ::= - // ::= - // ::= - - bool ParseUnresolvedType() { - int type_start_cookie = GetStartCookie(); - switch (*m_read_ptr++) { - case 'T': - if (!ParseTemplateParam()) - return false; - EndSubstitution(type_start_cookie); - return true; - case 'S': { - if (*m_read_ptr != 't') - return ParseSubstitution(); - - ++m_read_ptr; - WriteStdPrefix(); - NameState type_name = {}; - if (!ParseUnqualifiedName(type_name)) - return false; - EndSubstitution(type_start_cookie); - return true; - } - case 'D': - default: -#ifdef DEBUG_FAILURES - printf("*** Unsupported unqualified type: %3s\n", m_read_ptr - 1); -#endif - return false; - } - } - - // ::= # - // unresolved name - // extension ::= # - // unresolved operator-function-id - // extension ::= # - // unresolved operator template-id - // ::= on # - // unresolved operator-function-id - // ::= on # - // unresolved operator template-id - // ::= dn # - // destructor or pseudo-destructor; - // # - // e.g. - // ~X - // or - // ~X - - bool ParseBaseUnresolvedName() { -#ifdef DEBUG_FAILURES - printf("*** Base unresolved name unsupported\n"); -#endif - return false; - } - - // - // extension ::= srN [] - // * E - // ::= [gs] # x - // or (with "gs") ::x - // ::= [gs] sr + E - // - // # - // A::x, - // N::y, - // A::z; - // "gs" - // means - // leading - // "::" - // ::= sr # - // T::x / decltype(p)::x - // extension ::= sr - // - // # - // T::N::x - // /decltype(p)::N::x - // (ignored) ::= srN + - // E - - bool ParseUnresolvedName() { -#ifdef DEBUG_FAILURES - printf("*** Unresolved names not supported\n"); -#endif - // TODO: grammar for all of this seems unclear... - return false; - -#if 0 // TODO - if (*m_read_ptr == 'g' && *(m_read_ptr + 1) == 's') - { - m_read_ptr += 2; - WriteNamespaceSeparator(); - } -#endif // TODO - } - - // ::= - // ::= - // ::= - // - // ::= cl + E # - // call - // ::= cv # - // conversion with one argument - // ::= cv _ * E # - // conversion with a different number of arguments - // ::= [gs] nw * _ E # new - // (expr-list) type - // ::= [gs] nw * _ # new - // (expr-list) type (init) - // ::= [gs] na * _ E # - // new[] (expr-list) type - // ::= [gs] na * _ # - // new[] (expr-list) type (init) - // ::= [gs] dl # - // delete expression - // ::= [gs] da # - // delete[] expression - // ::= pp_ # - // prefix ++ - // ::= mm_ # - // prefix -- - // ::= ti # - // typeid (type) - // ::= te # - // typeid (expression) - // ::= dc # - // dynamic_cast (expression) - // ::= sc # - // static_cast (expression) - // ::= cc # - // const_cast (expression) - // ::= rc # - // reinterpret_cast (expression) - // ::= st # - // sizeof (a type) - // ::= sz # - // sizeof (an expression) - // ::= at # - // alignof (a type) - // ::= az # - // alignof (an expression) - // ::= nx # - // noexcept (expression) - // ::= - // ::= - // ::= dt # - // expr.name - // ::= pt # - // expr->name - // ::= ds # - // expr.*expr - // ::= sZ # - // size of a parameter pack - // ::= sZ # - // size of a function parameter pack - // ::= sp # - // pack expansion - // ::= tw # - // throw expression - // ::= tr # - // throw with no operand (rethrow) - // ::= # - // f(p), N::f(p), ::f(p), - // # - // freestanding - // dependent - // name - // (e.g., - // T::x), - // # - // objectless - // nonstatic - // member - // reference - // ::= - - bool ParseExpression() { - Operator expression_operator = TryParseOperator(); - switch (expression_operator.kind) { - case OperatorKind::Unary: - Write(expression_operator.name); - Write('('); - if (!ParseExpression()) - return false; - Write(')'); - return true; - case OperatorKind::Binary: - if (!ParseExpression()) - return false; - Write(expression_operator.name); - return ParseExpression(); - case OperatorKind::Ternary: - if (!ParseExpression()) - return false; - Write('?'); - if (!ParseExpression()) - return false; - Write(':'); - return ParseExpression(); - case OperatorKind::NoMatch: - break; - case OperatorKind::Other: - default: -#ifdef DEBUG_FAILURES - printf("*** Unsupported operator: %s\n", expression_operator.name); -#endif - return false; - } - - switch (*m_read_ptr++) { - case 'T': - return ParseTemplateParam(); - case 'L': - return ParseExpressionPrimary(); - case 's': - if (*m_read_ptr++ == 'r') - return ParseUnresolvedName(); - --m_read_ptr; - LLVM_FALLTHROUGH; - default: - return ParseExpressionPrimary(); - } - } - - // ::= # - // type or template - // ::= X E # - // expression - // ::= # - // simple expressions - // ::= J * E # - // argument pack - // ::= LZ E # - // extension - - bool ParseTemplateArg() { - switch (*m_read_ptr) { - case 'J': -#ifdef DEBUG_FAILURES - printf("*** Template argument packs unsupported\n"); -#endif - return false; - case 'X': - ++m_read_ptr; - if (!ParseExpression()) - return false; - return Parse('E'); - case 'L': - ++m_read_ptr; - return ParseExpressionPrimary(); - default: - return ParseType(); - } - } - - // ::= I * E - // extension, the abi says + - - bool ParseTemplateArgs(bool record_template_args = false) { - if (record_template_args) - ResetTemplateArgs(); - - bool first_arg = true; - while (*m_read_ptr != 'E') { - if (first_arg) - first_arg = false; - else - WriteCommaSpace(); - - int template_start_cookie = GetStartCookie(); - if (!ParseTemplateArg()) - return false; - if (record_template_args) - EndTemplateArg(template_start_cookie); - } - ++m_read_ptr; - return true; - } - - // ::= N [] [] - // E - // ::= N [] [] - // E - // - // ::= - // ::= - // ::= - // ::= - // ::= # empty - // ::= - // ::= - // extension ::= L - // - // ::=