Skip to content

Commit 4a7e767

Browse files
committed
AST: Add llvm::raw_ostream conveniences for availability constructs.
Make it easier to debug availability by printing to output streams like `llvm::errs()`. NFC.
1 parent d19d4ee commit 4a7e767

File tree

6 files changed

+118
-3
lines changed

6 files changed

+118
-3
lines changed

include/swift/AST/AvailabilityConstraint.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/AST/PlatformKindUtils.h"
2424
#include "swift/Basic/LLVM.h"
2525
#include "swift/Basic/OptionSet.h"
26+
#include "llvm/Support/raw_ostream.h"
2627

2728
namespace swift {
2829

@@ -140,6 +141,8 @@ class AvailabilityConstraint {
140141
/// Some availability constraints are active for type-checking but cannot
141142
/// be translated directly into an `if #available(...)` runtime query.
142143
bool isActiveForRuntimeQueries(const ASTContext &ctx) const;
144+
145+
void print(raw_ostream &os) const;
143146
};
144147

145148
/// Represents a set of availability constraints that restrict use of a
@@ -161,6 +164,8 @@ class DeclAvailabilityConstraints {
161164
using const_iterator = Storage::const_iterator;
162165
const_iterator begin() const { return constraints.begin(); }
163166
const_iterator end() const { return constraints.end(); }
167+
168+
void print(raw_ostream &os) const;
164169
};
165170

166171
enum class AvailabilityConstraintFlag : uint8_t {
@@ -185,4 +190,21 @@ DeclAvailabilityConstraints getAvailabilityConstraintsForDecl(
185190
AvailabilityConstraintFlags flags = std::nullopt);
186191
} // end namespace swift
187192

193+
namespace llvm {
194+
195+
inline llvm::raw_ostream &
196+
operator<<(llvm::raw_ostream &os,
197+
const swift::AvailabilityConstraint &constraint) {
198+
constraint.print(os);
199+
return os;
200+
}
201+
202+
inline llvm::raw_ostream &
203+
operator<<(llvm::raw_ostream &os,
204+
const swift::DeclAvailabilityConstraints &constraints) {
205+
constraints.print(os);
206+
return os;
207+
}
208+
209+
} // end namespace llvm
188210
#endif

include/swift/AST/AvailabilityContext.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/AST/PlatformKindUtils.h"
2424
#include "swift/Basic/Debug.h"
2525
#include "swift/Basic/LLVM.h"
26+
#include "llvm/Support/raw_ostream.h"
2627
#include <optional>
2728

2829
namespace swift {
@@ -148,4 +149,14 @@ class AvailabilityContext {
148149

149150
} // end namespace swift
150151

152+
namespace llvm {
153+
154+
inline llvm::raw_ostream &
155+
operator<<(llvm::raw_ostream &os, const swift::AvailabilityContext &context) {
156+
context.print(os);
157+
return os;
158+
}
159+
160+
} // end namespace llvm
161+
151162
#endif

include/swift/AST/AvailabilityDomain.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "llvm/ADT/FoldingSet.h"
2929
#include "llvm/ADT/PointerEmbeddedInt.h"
3030
#include "llvm/ADT/PointerUnion.h"
31+
#include "llvm/Support/raw_ostream.h"
3132

3233
namespace swift {
3334
class ASTContext;
@@ -521,6 +522,12 @@ struct PointerLikeTypeTraits<swift::AvailabilityDomainOrIdentifier> {
521522
};
522523
};
523524

525+
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
526+
const swift::AvailabilityDomain &domain) {
527+
domain.print(os);
528+
return os;
529+
}
530+
524531
} // end namespace llvm
525532

526533
#endif

include/swift/AST/AvailabilityRange.h

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include "swift/Basic/LLVM.h"
2222
#include "llvm/ADT/FoldingSet.h"
2323
#include "llvm/Support/VersionTuple.h"
24-
#include <optional>
24+
#include "llvm/Support/raw_ostream.h"
2525

2626
namespace swift {
2727
class ASTContext;
@@ -317,11 +317,20 @@ class AvailabilityRange {
317317

318318
/// Returns a representation of this range as a string for debugging purposes.
319319
std::string getAsString() const {
320-
return "AvailabilityRange(" + getVersionString() + ")";
320+
return "AvailabilityRange(" + getVersionDescription() + ")";
321321
}
322322

323-
/// Returns a representation of the raw version range as a string for
323+
/// Returns a representation of the version range as a string for
324324
/// debugging purposes.
325+
std::string getVersionDescription() const {
326+
if (Range.hasLowerEndpoint())
327+
return Range.getLowerEndpoint().getAsString();
328+
else
329+
return Range.isEmpty() ? "never" : "always";
330+
}
331+
332+
/// Returns a string representation of the raw version range. It is an error
333+
/// to call this if the range is "always" or "never".
325334
std::string getVersionString() const {
326335
ASSERT(Range.hasLowerEndpoint());
327336
return Range.getLowerEndpoint().getAsString();
@@ -330,4 +339,20 @@ class AvailabilityRange {
330339

331340
} // end namespace swift
332341

342+
namespace llvm {
343+
344+
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
345+
const swift::VersionRange &range) {
346+
os << range.getAsString();
347+
return os;
348+
}
349+
350+
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
351+
const swift::AvailabilityRange &range) {
352+
os << range.getAsString();
353+
return os;
354+
}
355+
356+
} // namespace llvm
357+
333358
#endif

include/swift/AST/AvailabilitySpec.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "llvm/ADT/StringMap.h"
2828
#include "llvm/ADT/iterator_range.h"
2929
#include "llvm/Support/VersionTuple.h"
30+
#include "llvm/Support/raw_ostream.h"
3031

3132
namespace swift {
3233
class ASTContext;
@@ -241,4 +242,20 @@ class AvailabilityMacroMap {
241242

242243
} // end namespace swift
243244

245+
namespace llvm {
246+
247+
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
248+
const swift::AvailabilitySpec *spec) {
249+
spec->print(os);
250+
return os;
251+
}
252+
253+
inline llvm::raw_ostream &
254+
operator<<(llvm::raw_ostream &os, const swift::SemanticAvailabilitySpec &spec) {
255+
spec.print(os);
256+
return os;
257+
}
258+
259+
} // end namespace llvm
260+
244261
#endif

lib/AST/AvailabilityConstraint.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,27 @@ bool AvailabilityConstraint::isActiveForRuntimeQueries(
4545
/*forRuntimeQuery=*/true);
4646
}
4747

48+
void AvailabilityConstraint::print(llvm::raw_ostream &os) const {
49+
os << "AvailabilityConstraint(";
50+
getAttr().getDomain().print(os);
51+
os << ", ";
52+
53+
switch (getReason()) {
54+
case Reason::UnconditionallyUnavailable:
55+
os << "unavailable";
56+
break;
57+
case Reason::Obsoleted:
58+
os << "obsoleted: " << getAttr().getObsoleted().value();
59+
break;
60+
case Reason::UnavailableForDeployment:
61+
case Reason::PotentiallyUnavailable:
62+
os << "introduced: " << getAttr().getIntroduced().value();
63+
break;
64+
}
65+
66+
os << ")";
67+
}
68+
4869
static bool constraintIsStronger(const AvailabilityConstraint &lhs,
4970
const AvailabilityConstraint &rhs) {
5071
DEBUG_ASSERT(lhs.getDomain() == rhs.getDomain());
@@ -117,6 +138,17 @@ DeclAvailabilityConstraints::getPrimaryConstraint() const {
117138
return result;
118139
}
119140

141+
void DeclAvailabilityConstraints::print(llvm::raw_ostream &os) const {
142+
os << "{\n";
143+
llvm::interleave(
144+
constraints,
145+
[&os](const AvailabilityConstraint &constraint) {
146+
os << " " << constraint;
147+
},
148+
[&os] { os << ",\n"; });
149+
os << "\n}";
150+
}
151+
120152
static bool canIgnoreConstraintInUnavailableContexts(
121153
const Decl *decl, const AvailabilityConstraint &constraint) {
122154
auto domain = constraint.getDomain();
@@ -293,3 +325,4 @@ swift::getAvailabilityConstraintsForDecl(const Decl *decl,
293325

294326
return constraints;
295327
}
328+

0 commit comments

Comments
 (0)