Skip to content

Commit 177a2f3

Browse files
committed
Make most namespace-scope operators hidden friends
1 parent 9c80d7c commit 177a2f3

12 files changed

Lines changed: 171 additions & 199 deletions

File tree

include/phasar/DataFlow/IfdsIde/EdgeFunctionUtils.h

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -69,49 +69,48 @@ template <typename L> struct ConstantEdgeFunction {
6969

7070
[[nodiscard]] constexpr bool isConstant() const noexcept { return true; }
7171

72-
// -- constant data member
72+
[[nodiscard]] friend constexpr bool
73+
operator==(ConstantEdgeFunction<L> LHS, ConstantEdgeFunction<L> RHS) noexcept
74+
requires CanEfficientlyPassByValue<ConstantEdgeFunction>
75+
{
76+
return LHS.Value == RHS.Value;
77+
}
7378

74-
value_type Value{};
75-
};
79+
[[nodiscard]] friend constexpr bool
80+
operator==(const ConstantEdgeFunction<L> &LHS,
81+
const ConstantEdgeFunction<L> &RHS) noexcept
82+
requires(!CanEfficientlyPassByValue<ConstantEdgeFunction>)
83+
{
84+
return LHS.Value == RHS.Value;
85+
}
7686

77-
template <typename L>
78-
requires CanEfficientlyPassByValue<ConstantEdgeFunction<L>>
79-
[[nodiscard]] constexpr bool operator==(ConstantEdgeFunction<L> LHS,
80-
ConstantEdgeFunction<L> RHS) noexcept {
81-
return LHS.Value == RHS.Value;
82-
}
87+
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
88+
const ConstantEdgeFunction &Id) {
89+
OS << "ConstantEF";
90+
if constexpr (is_llvm_printable_v<
91+
typename ConstantEdgeFunction<L>::value_type>) {
92+
OS << '[' << Id.Value << ']';
93+
}
94+
return OS;
95+
}
8396

84-
template <typename L>
85-
requires(!CanEfficientlyPassByValue<ConstantEdgeFunction<L>>)
86-
[[nodiscard]] constexpr bool
87-
operator==(const ConstantEdgeFunction<L> &LHS,
88-
const ConstantEdgeFunction<L> &RHS) noexcept {
89-
return LHS.Value == RHS.Value;
90-
}
97+
[[nodiscard]] friend auto hash_value(const ConstantEdgeFunction &CEF) noexcept
98+
requires(is_std_hashable_v<typename NonTopBotValue<L>::type> ||
99+
is_llvm_hashable_v<typename NonTopBotValue<L>::type>)
100+
{
101+
using value_type = typename ConstantEdgeFunction<L>::value_type;
102+
if constexpr (is_std_hashable_v<value_type>) {
103+
return std::hash<value_type>{}(CEF.Value);
104+
} else {
105+
using llvm::hash_value;
106+
return hash_value(CEF.Value);
107+
}
108+
}
91109

92-
template <typename L>
93-
[[nodiscard]] llvm::raw_ostream &
94-
operator<<(llvm::raw_ostream &OS, ByConstRef<ConstantEdgeFunction<L>> Id) {
95-
OS << "ConstantEF";
96-
if constexpr (is_llvm_printable_v<
97-
typename ConstantEdgeFunction<L>::value_type>) {
98-
OS << '[' << Id.Value << ']';
99-
}
100-
return OS;
101-
}
110+
// -- constant data member
102111

103-
template <typename L>
104-
requires(is_std_hashable_v<typename NonTopBotValue<L>::type> ||
105-
is_llvm_hashable_v<typename NonTopBotValue<L>::type>)
106-
[[nodiscard]] auto hash_value(const ConstantEdgeFunction<L> &CEF) noexcept {
107-
using value_type = typename ConstantEdgeFunction<L>::value_type;
108-
if constexpr (is_std_hashable_v<value_type>) {
109-
return std::hash<value_type>{}(CEF.Value);
110-
} else {
111-
using llvm::hash_value;
112-
return hash_value(CEF.Value);
113-
}
114-
}
112+
value_type Value{};
113+
};
115114

116115
template <typename L> struct AllBottom final {
117116
using l_t = L;
@@ -295,6 +294,10 @@ template <typename L> struct EdgeFunctionComposer {
295294
return First.depth() + Second.depth();
296295
}
297296

297+
friend auto hash_value(const EdgeFunctionComposer &EFC) noexcept {
298+
return llvm::hash_combine(EFC.First, EFC.Second);
299+
}
300+
298301
// -- data members
299302

300303
EdgeFunction<l_t> First{};
@@ -303,11 +306,6 @@ template <typename L> struct EdgeFunctionComposer {
303306

304307
static_assert(HasDepth<EdgeFunctionComposer<int>>);
305308

306-
template <typename L>
307-
auto hash_value(const EdgeFunctionComposer<L> &EFC) noexcept {
308-
return llvm::hash_combine(EFC.First, EFC.Second);
309-
}
310-
311309
template <typename L, uint8_t N> struct JoinEdgeFunction {
312310
using l_t = L;
313311
using JLattice = JoinLatticeTraits<L>;

include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,12 @@ class IDESolver
215215
getSolverResults().dumpResults(*ICF, OS);
216216
}
217217

218+
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
219+
const IDESolver &Solver) {
220+
Solver.dumpResults(OS);
221+
return OS;
222+
}
223+
218224
void dumpAllInterPathEdges() {
219225
llvm::outs() << "COMPUTED INTER PATH EDGES" << '\n';
220226
auto Interpe = this->computedInterPathEdges.cellSet();
@@ -1917,14 +1923,6 @@ class IDESolver
19171923
std::map<std::pair<n_t, d_t>, size_t> FSummaryReuse;
19181924
};
19191925

1920-
template <typename AnalysisDomainTy, typename Container>
1921-
llvm::raw_ostream &
1922-
operator<<(llvm::raw_ostream &OS,
1923-
const IDESolver<AnalysisDomainTy, Container> &Solver) {
1924-
Solver.dumpResults(OS);
1925-
return OS;
1926-
}
1927-
19281926
template <typename Problem, typename ICF>
19291927
IDESolver(Problem &, ICF *)
19301928
-> IDESolver<typename Problem::ProblemAnalysisDomain,

include/phasar/Domain/LatticeDomain.h

Lines changed: 68 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,17 @@ template <typename L>
6767
struct LatticeDomain : public std::variant<Top, L, Bottom> {
6868
using std::variant<Top, L, Bottom>::variant;
6969

70-
[[nodiscard]] inline bool isBottom() const noexcept {
70+
[[nodiscard]] constexpr bool isBottom() const noexcept {
7171
return std::holds_alternative<Bottom>(*this);
7272
}
73-
[[nodiscard]] inline bool isTop() const noexcept {
73+
[[nodiscard]] constexpr bool isTop() const noexcept {
7474
return std::holds_alternative<Top>(*this);
7575
}
7676

77-
[[nodiscard]] inline L *getValueOrNull() noexcept {
77+
[[nodiscard]] constexpr L *getValueOrNull() noexcept {
7878
return std::get_if<L>(this);
7979
}
80-
[[nodiscard]] inline const L *getValueOrNull() const noexcept {
80+
[[nodiscard]] constexpr const L *getValueOrNull() const noexcept {
8181
return std::get_if<L>(this);
8282
}
8383

@@ -93,119 +93,95 @@ struct LatticeDomain : public std::variant<Top, L, Bottom> {
9393
return hash_value(std::get<L>(LD));
9494
}
9595

96-
[[nodiscard]] inline L &assertGetValue() noexcept {
96+
[[nodiscard]] constexpr L &assertGetValue() noexcept {
9797
assert(std::holds_alternative<L>(*this));
9898
return std::get<L>(*this);
9999
}
100-
[[nodiscard]] inline const L &assertGetValue() const noexcept {
100+
[[nodiscard]] constexpr const L &assertGetValue() const noexcept {
101101
assert(std::holds_alternative<L>(*this));
102102
return std::get<L>(*this);
103103
}
104104

105105
template <typename TransformFn, typename... ArgsT>
106-
void onValue(TransformFn Transform, ArgsT &&...Args) {
106+
constexpr void onValue(TransformFn Transform, ArgsT &&...Args) {
107107
if (auto *Val = getValueOrNull()) {
108108
std::invoke(std::move(Transform), *Val, PSR_FWD(Args)...);
109109
}
110110
}
111-
};
112111

113-
template <typename L>
114-
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
115-
const LatticeDomain<L> &LD) {
116-
if (LD.isBottom()) {
117-
return OS << "Bottom";
118-
}
119-
if (LD.isTop()) {
120-
return OS << "Top";
112+
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
113+
const LatticeDomain &LD) {
114+
if (LD.isBottom()) {
115+
return OS << "Bottom";
116+
}
117+
if (LD.isTop()) {
118+
return OS << "Top";
119+
}
120+
121+
const auto *Val = LD.getValueOrNull();
122+
assert(Val && "Only alternative remaining is L");
123+
if constexpr (is_llvm_printable_v<L>) {
124+
return OS << *Val;
125+
} else {
126+
return OS << PrettyPrinter{*Val};
127+
}
121128
}
122129

123-
const auto *Val = LD.getValueOrNull();
124-
assert(Val && "Only alternative remaining is L");
125-
if constexpr (is_llvm_printable_v<L>) {
126-
return OS << *Val;
127-
} else {
128-
return OS << PrettyPrinter{*Val};
130+
friend std::ostream &operator<<(std::ostream &OS, const LatticeDomain &LD) {
131+
llvm::raw_os_ostream ROS(OS);
132+
ROS << LD;
133+
return OS;
129134
}
130-
}
131135

132-
template <typename L>
133-
inline std::ostream &operator<<(std::ostream &OS, const LatticeDomain<L> &LD) {
134-
llvm::raw_os_ostream ROS(OS);
135-
ROS << LD;
136-
return OS;
137-
}
136+
constexpr bool operator==(const LatticeDomain &Rhs) const {
137+
if (this->index() != Rhs.index()) {
138+
return false;
139+
}
140+
if (auto LhsPtr = this->getValueOrNull()) {
141+
/// No need to check whether Rhs is an L; the indices are already the same
142+
return *LhsPtr == *Rhs.getValueOrNull();
143+
}
144+
return true;
145+
}
138146

139-
template <typename L>
140-
inline bool operator==(const LatticeDomain<L> &Lhs,
141-
const LatticeDomain<L> &Rhs) {
142-
if (Lhs.index() != Rhs.index()) {
147+
template <typename LL>
148+
requires AreEqualityComparable<L, LL>
149+
constexpr bool operator==(const LL &Rhs) const {
150+
if (auto LVal = this->getValueOrNull()) {
151+
return *LVal == Rhs;
152+
}
143153
return false;
144154
}
145-
if (auto LhsPtr = Lhs.getValueOrNull()) {
146-
/// No need to check whether Lhs is an L; the indices are already the same
147-
return *LhsPtr == *Rhs.getValueOrNull();
148-
}
149-
return true;
150-
}
151155

152-
template <typename L, typename LL>
153-
requires AreEqualityComparable<LL, L>
154-
inline bool operator==(const LL &Lhs, const LatticeDomain<L> &Rhs) {
155-
if (auto RVal = Rhs.getValueOrNull()) {
156-
return Lhs == *RVal;
156+
constexpr bool operator==(Bottom /*Rhs*/) const noexcept {
157+
return this->isBottom();
157158
}
158-
return false;
159-
}
160-
161-
template <typename L, typename LL>
162-
requires AreEqualityComparable<LL, L>
163-
inline bool operator==(const LatticeDomain<L> &Lhs, const LL &Rhs) {
164-
return Rhs == Lhs;
165-
}
166159

167-
template <typename L>
168-
inline bool operator==(const LatticeDomain<L> &Lhs, Bottom /*Rhs*/) noexcept {
169-
return Lhs.isBottom();
170-
}
171-
172-
template <typename L>
173-
inline bool operator==(const LatticeDomain<L> &Lhs, Top /*Rhs*/) noexcept {
174-
return Lhs.isTop();
175-
}
176-
177-
template <typename L>
178-
inline bool operator==(Bottom /*Lhs*/, const LatticeDomain<L> &Rhs) noexcept {
179-
return Rhs.isBottom();
180-
}
181-
182-
template <typename L>
183-
inline bool operator==(Top /*Lhs*/, const LatticeDomain<L> &Rhs) noexcept {
184-
return Rhs.isTop();
185-
}
186-
187-
template <typename L>
188-
inline bool operator<(const LatticeDomain<L> &Lhs,
189-
const LatticeDomain<L> &Rhs) {
190-
/// Top < (Lhs::L < Rhs::L) < Bottom
191-
if (Rhs.isTop()) {
192-
return false;
160+
constexpr bool operator==(Top /*Rhs*/) const noexcept {
161+
return this->isTop();
193162
}
194-
if (Lhs.isTop()) {
195-
return true;
196-
}
197-
if (auto LhsPtr = Lhs.getValueOrNull()) {
198-
if (auto RhsPtr = Rhs.getValueOrNull()) {
199-
return *LhsPtr < *RhsPtr;
163+
164+
constexpr bool operator<(const LatticeDomain &Rhs) const {
165+
/// Top < (Lhs::L < Rhs::L) < Bottom
166+
if (Rhs.isTop()) {
167+
return false;
200168
}
201-
} else if (Lhs.isBottom()) {
202-
return false;
203-
}
204-
if (Rhs.isBottom()) {
205-
return true;
169+
if (this->isTop()) {
170+
return true;
171+
}
172+
if (auto LhsPtr = this->getValueOrNull()) {
173+
if (auto RhsPtr = Rhs.getValueOrNull()) {
174+
return *LhsPtr < *RhsPtr;
175+
}
176+
} else if (this->isBottom()) {
177+
return false;
178+
}
179+
if (Rhs.isBottom()) {
180+
return true;
181+
}
182+
llvm_unreachable("All comparison cases should be handled above.");
206183
}
207-
llvm_unreachable("All comparison cases should be handled above.");
208-
}
184+
};
209185

210186
template <typename L> struct JoinLatticeTraits<LatticeDomain<L>> {
211187
using l_t = L;
@@ -242,7 +218,7 @@ template <typename L>
242218
struct NonTopBotValue<LatticeDomain<L>> {
243219
using type = L;
244220

245-
static L unwrap(LatticeDomain<L> Value) noexcept(
221+
constexpr static L unwrap(LatticeDomain<L> Value) noexcept(
246222
std::is_nothrow_move_constructible_v<L>) {
247223
return std::get<L>(std::move(Value));
248224
}

include/phasar/PhasarLLVM/DataFlow/IfdsIde/Problems/IDEInstInteractionAnalysis.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -154,20 +154,20 @@ class IDEIIAFlowFact {
154154
print(OS);
155155
return Ret;
156156
}
157-
};
158157

159-
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
160-
const IDEIIAFlowFact &FlowFact) {
161-
FlowFact.print(OS);
162-
return OS;
163-
}
158+
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
159+
const IDEIIAFlowFact &FlowFact) {
160+
FlowFact.print(OS);
161+
return OS;
162+
}
164163

165-
inline std::ostream &operator<<(std::ostream &OS,
166-
const IDEIIAFlowFact &FlowFact) {
167-
llvm::raw_os_ostream Rso(OS);
168-
FlowFact.print(Rso);
169-
return OS;
170-
}
164+
friend std::ostream &operator<<(std::ostream &OS,
165+
const IDEIIAFlowFact &FlowFact) {
166+
llvm::raw_os_ostream Rso(OS);
167+
FlowFact.print(Rso);
168+
return OS;
169+
}
170+
};
171171

172172
} // namespace psr
173173

include/phasar/PhasarLLVM/Passes/GeneralStatisticsAnalysis.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ struct GeneralStatistics {
7575
std::string ModuleName{};
7676

7777
void printAsJson(llvm::raw_ostream &OS = llvm::outs()) const;
78-
};
7978

80-
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
81-
const GeneralStatistics &Statistics);
79+
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
80+
const GeneralStatistics &Statistics);
81+
};
8282

8383
/**
8484
* This class uses the Module Pass Mechanism of LLVM to compute

0 commit comments

Comments
 (0)