Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AST: Remove inline AvailabilityDomain from SemanticAvailableAttr #78637

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
AST: Remove inline AvailabilityDomain from SemanticAvailableAttr.
Now that AvailableAttr has storage for its cached AvailabilityDomain, it's no
longer necessary to store an AvailabilityDomain inline in
SemanticAvailableAttr.

NFC.
  • Loading branch information
tshortli committed Jan 14, 2025
commit afc5dc98dd259dddcc6560fcd7efb17ec49348b4
49 changes: 43 additions & 6 deletions include/swift/AST/Attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,13 @@ class AvailableAttr : public DeclAttribute {
/// resolved successfully.
std::optional<AvailabilityDomain> getCachedDomain() const { return Domain; }

/// Returns true if the `AvailabilityDomain` associated with the attribute
/// has been resolved successfully.
bool hasCachedDomain() const {
// For now, domains are always set on construction of the attribute.
return true;
}

/// Returns the kind of availability the attribute specifies.
Kind getKind() const { return static_cast<Kind>(Bits.AvailableAttr.Kind); }

Expand Down Expand Up @@ -3189,20 +3196,24 @@ class ParsedDeclAttributes {
}
};

/// A wrapper for `AvailableAttr` that is enriched with additional semantic
/// informaton, like its corresponding `AvailabilityDomain`.
/// A wrapper for `AvailableAttr` that enriches it with additional semantic
/// informaton that can only be determined using the `AvailabilityDomain`
/// associated with the attribute. A `SemanticAvailableAttr` can only be
/// constructed with an `AvailableAttr` that has a resolved
/// `AvailabilityDomain`.
class SemanticAvailableAttr final {
const AvailableAttr *attr;
AvailabilityDomain domain;

public:
SemanticAvailableAttr(const AvailableAttr *attr, AvailabilityDomain domain)
: attr(attr), domain(domain) {
SemanticAvailableAttr(const AvailableAttr *attr) : attr(attr) {
assert(attr);
assert(attr->hasCachedDomain());
}

const AvailableAttr *getParsedAttr() const { return attr; }
const AvailabilityDomain getDomain() const { return domain; }
const AvailabilityDomain getDomain() const {
return attr->getCachedDomain().value();
}

/// The version tuple written in source for the `introduced:` component.
std::optional<llvm::VersionTuple> getIntroduced() const {
Expand Down Expand Up @@ -3640,6 +3651,32 @@ struct EnumTraits<TypeAttrKind> {

} // end namespace swift

namespace llvm {
using swift::AvailableAttr;
using swift::SemanticAvailableAttr;

// A SemanticAvailableAttr just wraps an `AvailableAttr *` and is therefore
// "pointer like".
template <typename T>
struct PointerLikeTypeTraits;
template <>
struct PointerLikeTypeTraits<SemanticAvailableAttr> {
public:
static inline void *getAsVoidPointer(SemanticAvailableAttr attr) {
return reinterpret_cast<void *>(
const_cast<AvailableAttr *>(attr.getParsedAttr()));
}
static inline SemanticAvailableAttr getFromVoidPointer(void *P) {
return SemanticAvailableAttr(static_cast<AvailableAttr *>(P));
}
enum {
NumLowBitsAvailable =
PointerLikeTypeTraits<AvailableAttr *>::NumLowBitsAvailable
};
};

} // end namespace llvm

#undef UNIMPLEMENTED_CLONE

#endif
2 changes: 1 addition & 1 deletion lib/AST/Attr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -918,7 +918,7 @@ ParsedDeclAttrFilter::operator()(const DeclAttribute *Attr) const {
}

bool SemanticAvailableAttr::isActive(ASTContext &ctx) const {
return domain.isActive(ctx);
return getDomain().isActive(ctx);
}

std::optional<SemanticAvailableAttr>
Expand Down
6 changes: 2 additions & 4 deletions lib/AST/Availability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,9 +447,7 @@ Decl::getSemanticAvailableAttrs(bool includeInactive) const {

std::optional<SemanticAvailableAttr>
Decl::getSemanticAvailableAttr(const AvailableAttr *attr) const {
if (auto domain = attr->getCachedDomain())
return SemanticAvailableAttr(attr, *domain);
return std::nullopt;
return SemanticAvailableAttr(attr);
}

std::optional<SemanticAvailableAttr>
Expand Down Expand Up @@ -790,7 +788,7 @@ bool AvailabilityInference::isAvailableAsSPI(const Decl *D) {

AvailabilityRange
SemanticAvailableAttr::getIntroducedRange(const ASTContext &Ctx) const {
assert(domain.isActive(Ctx));
assert(getDomain().isActive(Ctx));

auto *attr = getParsedAttr();
if (!attr->Introduced.has_value())
Expand Down
3 changes: 1 addition & 2 deletions lib/Serialization/Serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3058,9 +3058,8 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
ENCODE_VER_TUPLE(Obsoleted, theAttr->Obsoleted)

assert(theAttr->Rename.empty() || !theAttr->hasCachedRenamedDecl());

assert(theAttr->hasCachedDomain());
auto domain = theAttr->getCachedDomain();
assert(domain);

// FIXME: [availability] Serialize domain and kind directly.
llvm::SmallString<32> blob;
Expand Down