Skip to content

Commit adfffeb

Browse files
committed
[lldb/Core] Add SourceLocationSpec class (NFC)
A source location specifier class that holds a Declaration object containing a FileSpec with line and column information. The column line is optional. It also holds search flags that can be fetched by resolvers to look inlined declarations and/or exact matches. It describes a specific location in a source file and allows the user to perform checks and comparaisons between multiple instances of that class. Differential Revision: https://reviews.llvm.org/D100962 Signed-off-by: Med Ismail Bennani <[email protected]>
1 parent 1435f6b commit adfffeb

File tree

5 files changed

+454
-0
lines changed

5 files changed

+454
-0
lines changed
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
//===-- SourceLocationSpec.h ------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_UTILITY_SOURCELOCATIONSPEC_H
10+
#define LLDB_UTILITY_SOURCELOCATIONSPEC_H
11+
12+
#include "lldb/Core/Declaration.h"
13+
#include "lldb/lldb-defines.h"
14+
#include "llvm/ADT/Optional.h"
15+
16+
#include <string>
17+
18+
namespace lldb_private {
19+
20+
/// \class SourceLocationSpec SourceLocationSpec.h
21+
/// "lldb/Core/SourceLocationSpec.h" A source location specifier class.
22+
///
23+
/// A source location specifier class that holds a Declaration object containing
24+
/// a FileSpec with line and column information. The column line is optional.
25+
/// It also holds search flags that can be fetched by resolvers to look inlined
26+
/// declarations and/or exact matches.
27+
class SourceLocationSpec {
28+
public:
29+
/// Constructor.
30+
///
31+
/// Takes a \a file_spec with a \a line number and a \a column number. If
32+
/// \a column is null or not provided, it is set to llvm::None.
33+
///
34+
/// \param[in] file_spec
35+
/// The full or partial path to a file.
36+
///
37+
/// \param[in] line
38+
/// The line number in the source file.
39+
///
40+
/// \param[in] column
41+
/// The column number in the line of the source file.
42+
///
43+
/// \param[in] check_inlines
44+
/// Whether to look for a match in inlined declaration.
45+
///
46+
/// \param[in] exact_match
47+
/// Whether to look for an exact match.
48+
///
49+
explicit SourceLocationSpec(FileSpec file_spec, uint32_t line,
50+
llvm::Optional<uint16_t> column = llvm::None,
51+
bool check_inlines = false,
52+
bool exact_match = false);
53+
54+
SourceLocationSpec() = delete;
55+
56+
/// Convert to boolean operator.
57+
///
58+
/// This allows code to check a SourceLocationSpec object to see if it
59+
/// contains anything valid using code such as:
60+
///
61+
/// \code
62+
/// SourceLocationSpec location_spec(...);
63+
/// if (location_spec)
64+
/// { ...
65+
/// \endcode
66+
///
67+
/// \return
68+
/// A pointer to this object if both the file_spec and the line are valid,
69+
/// nullptr otherwise.
70+
explicit operator bool() const;
71+
72+
/// Logical NOT operator.
73+
///
74+
/// This allows code to check a SourceLocationSpec object to see if it is
75+
/// invalid using code such as:
76+
///
77+
/// \code
78+
/// SourceLocationSpec location_spec(...);
79+
/// if (!location_spec)
80+
/// { ...
81+
/// \endcode
82+
///
83+
/// \return
84+
/// Returns \b true if the object has an invalid file_spec or line number,
85+
/// \b false otherwise.
86+
bool operator!() const;
87+
88+
/// Equal to operator
89+
///
90+
/// Tests if this object is equal to \a rhs.
91+
///
92+
/// \param[in] rhs
93+
/// A const SourceLocationSpec object reference to compare this object
94+
/// to.
95+
///
96+
/// \return
97+
/// \b true if this object is equal to \a rhs, \b false
98+
/// otherwise.
99+
bool operator==(const SourceLocationSpec &rhs) const;
100+
101+
/// Not equal to operator
102+
///
103+
/// Tests if this object is not equal to \a rhs.
104+
///
105+
/// \param[in] rhs
106+
/// A const SourceLocationSpec object reference to compare this object
107+
/// to.
108+
///
109+
/// \return
110+
/// \b true if this object is equal to \a rhs, \b false
111+
/// otherwise.
112+
bool operator!=(const SourceLocationSpec &rhs) const;
113+
114+
/// Less than to operator
115+
///
116+
/// Tests if this object is less than \a rhs.
117+
///
118+
/// \param[in] rhs
119+
/// A const SourceLocationSpec object reference to compare this object
120+
/// to.
121+
///
122+
/// \return
123+
/// \b true if this object is less than \a rhs, \b false
124+
/// otherwise.
125+
bool operator<(const SourceLocationSpec &rhs) const;
126+
127+
/// Compare two SourceLocationSpec objects.
128+
///
129+
/// If \a full is true, then the file_spec, the line and column must match.
130+
/// If \a full is false, then only the file_spec and line number for \a lhs
131+
/// and \a rhs are compared. This allows a SourceLocationSpec object that have
132+
/// no column information to match a SourceLocationSpec objects that have
133+
/// column information with matching file_spec and line component.
134+
///
135+
/// \param[in] lhs
136+
/// A const reference to the Left Hand Side object to compare.
137+
///
138+
/// \param[in] rhs
139+
/// A const reference to the Right Hand Side object to compare.
140+
///
141+
/// \param[in] full
142+
/// If true, then the file_spec, the line and column must match for a
143+
/// compare to return zero (equal to). If false, then only the file_spec
144+
/// and line number for \a lhs and \a rhs are compared, else a full
145+
/// comparison is done.
146+
///
147+
/// \return -1 if \a lhs is less than \a rhs, 0 if \a lhs is equal to \a rhs,
148+
/// 1 if \a lhs is greater than \a rhs
149+
static int Compare(const SourceLocationSpec &lhs,
150+
const SourceLocationSpec &rhs);
151+
152+
static bool Equal(const SourceLocationSpec &lhs,
153+
const SourceLocationSpec &rhs, bool full);
154+
155+
/// Dump this object to a Stream.
156+
///
157+
/// Dump the object to the supplied stream \a s, starting with the file name,
158+
/// then the line number and if available the column number.
159+
///
160+
/// \param[in] s
161+
/// The stream to which to dump the object description.
162+
void Dump(Stream &s) const;
163+
164+
std::string GetString() const;
165+
166+
FileSpec GetFileSpec() const { return m_declaration.GetFile(); }
167+
168+
llvm::Optional<uint32_t> GetLine() const;
169+
170+
llvm::Optional<uint16_t> GetColumn() const;
171+
172+
bool GetCheckInlines() const { return m_check_inlines; }
173+
174+
bool GetExactMatch() const { return m_exact_match; }
175+
176+
protected:
177+
Declaration m_declaration;
178+
/// Tells if the resolver should look in inlined declaration.
179+
bool m_check_inlines;
180+
/// Tells if the resolver should look for an exact match.
181+
bool m_exact_match;
182+
};
183+
184+
/// Dump a SourceLocationSpec object to a stream
185+
Stream &operator<<(Stream &s, const SourceLocationSpec &loc);
186+
} // namespace lldb_private
187+
188+
#endif // LLDB_UTILITY_SOURCELOCATIONSPEC_H

lldb/source/Core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ add_lldb_library(lldbCore
4848
RichManglingContext.cpp
4949
SearchFilter.cpp
5050
Section.cpp
51+
SourceLocationSpec.cpp
5152
SourceManager.cpp
5253
StreamAsynchronousIO.cpp
5354
StreamFile.cpp
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//===-- SourceLocationSpec.cpp --------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "lldb/Core/SourceLocationSpec.h"
10+
#include "lldb/Utility/StreamString.h"
11+
12+
using namespace lldb;
13+
using namespace lldb_private;
14+
15+
SourceLocationSpec::SourceLocationSpec(FileSpec file_spec, uint32_t line,
16+
llvm::Optional<uint16_t> column,
17+
bool check_inlines, bool exact_match)
18+
: m_declaration(file_spec, line,
19+
column.getValueOr(LLDB_INVALID_COLUMN_NUMBER)),
20+
m_check_inlines(check_inlines), m_exact_match(exact_match) {}
21+
22+
SourceLocationSpec::operator bool() const { return m_declaration.IsValid(); }
23+
24+
bool SourceLocationSpec::operator!() const { return !operator bool(); }
25+
26+
bool SourceLocationSpec::operator==(const SourceLocationSpec &rhs) const {
27+
return m_declaration == rhs.m_declaration &&
28+
m_check_inlines == rhs.GetCheckInlines() &&
29+
m_exact_match == rhs.GetExactMatch();
30+
}
31+
32+
bool SourceLocationSpec::operator!=(const SourceLocationSpec &rhs) const {
33+
return !(*this == rhs);
34+
}
35+
36+
bool SourceLocationSpec::operator<(const SourceLocationSpec &rhs) const {
37+
return SourceLocationSpec::Compare(*this, rhs) < 0;
38+
}
39+
40+
Stream &lldb_private::operator<<(Stream &s, const SourceLocationSpec &loc) {
41+
loc.Dump(s);
42+
return s;
43+
}
44+
45+
int SourceLocationSpec::Compare(const SourceLocationSpec &lhs,
46+
const SourceLocationSpec &rhs) {
47+
return Declaration::Compare(lhs.m_declaration, rhs.m_declaration);
48+
}
49+
50+
bool SourceLocationSpec::Equal(const SourceLocationSpec &lhs,
51+
const SourceLocationSpec &rhs, bool full) {
52+
return full ? lhs == rhs
53+
: (lhs.GetFileSpec() == rhs.GetFileSpec() &&
54+
lhs.GetLine() == rhs.GetLine());
55+
}
56+
57+
void SourceLocationSpec::Dump(Stream &s) const {
58+
s << "check inlines = " << llvm::toStringRef(m_check_inlines);
59+
s << ", exact match = " << llvm::toStringRef(m_exact_match);
60+
m_declaration.Dump(&s, true);
61+
}
62+
63+
std::string SourceLocationSpec::GetString() const {
64+
StreamString ss;
65+
Dump(ss);
66+
return ss.GetString().str();
67+
}
68+
69+
llvm::Optional<uint32_t> SourceLocationSpec::GetLine() const {
70+
uint32_t line = m_declaration.GetLine();
71+
if (line == 0 || line == LLDB_INVALID_LINE_NUMBER)
72+
return llvm::None;
73+
return line;
74+
}
75+
76+
llvm::Optional<uint16_t> SourceLocationSpec::GetColumn() const {
77+
uint16_t column = m_declaration.GetColumn();
78+
if (column == LLDB_INVALID_COLUMN_NUMBER)
79+
return llvm::None;
80+
return column;
81+
}

lldb/unittests/Core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ add_lldb_unittest(LLDBCoreTests
55
MangledTest.cpp
66
ModuleSpecTest.cpp
77
RichManglingContextTest.cpp
8+
SourceLocationSpecTest.cpp
89
SourceManagerTest.cpp
910
StreamCallbackTest.cpp
1011
UniqueCStringMapTest.cpp

0 commit comments

Comments
 (0)