Skip to content

[ASTGen] Generate AvailableAttr #79125

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

Merged
merged 1 commit into from
Feb 5, 2025
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
194 changes: 174 additions & 20 deletions include/swift/AST/ASTBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ template<typename T> class ArrayRef;
}

namespace swift {
class AvailabilityDomain;
class Argument;
class ASTContext;
struct ASTNode;
Expand Down Expand Up @@ -65,6 +66,23 @@ class BridgedCanType;
class BridgedASTContext;
struct BridgedSubstitutionMap;
class BridgedParameterList;
enum BridgedPlatformKind : size_t;

// Forward declare the underlying AST node type for each wrapper.
namespace swift {
#define AST_BRIDGING_WRAPPER(Name) class Name;
#include "swift/AST/ASTBridgingWrappers.def"
} // end namespace swift

// Define the bridging wrappers for each AST node.
#define AST_BRIDGING_WRAPPER(Name) BRIDGING_WRAPPER_NONNULL(swift::Name, Name)
#include "swift/AST/ASTBridgingWrappers.def"

// For nullable nodes, also define a nullable variant.
#define AST_BRIDGING_WRAPPER_NULLABLE(Name) \
BRIDGING_WRAPPER_NULLABLE(swift::Name, Name)
#define AST_BRIDGING_WRAPPER_NONNULL(Name)
#include "swift/AST/ASTBridgingWrappers.def"

//===----------------------------------------------------------------------===//
// MARK: Identifier
Expand Down Expand Up @@ -282,6 +300,10 @@ SWIFT_NAME("BridgedASTContext.langOptsGetCompilerVersion(self:_:)")
SwiftInt BridgedASTContext_langOptsGetCompilerVersion(BridgedASTContext cContext,
SwiftInt* _Nullable * _Nonnull cComponents);

SWIFT_NAME("getter:BridgedASTContext.availabilityMacroMap(self:)")
BridgedAvailabilityMacroMap
BridgedASTContext_getAvailabilityMacroMap(BridgedASTContext cContext);

/* Deallocate an array of Swift int values that was allocated in C++. */
void deallocateIntBuffer(SwiftInt * _Nullable cComponents);

Expand Down Expand Up @@ -354,22 +376,6 @@ struct BridgedASTNode {
BRIDGED_INLINE swift::ASTNode unbridged() const;
};

// Forward declare the underlying AST node type for each wrapper.
namespace swift {
#define AST_BRIDGING_WRAPPER(Name) class Name;
#include "swift/AST/ASTBridgingWrappers.def"
} // end namespace swift

// Define the bridging wrappers for each AST node.
#define AST_BRIDGING_WRAPPER(Name) BRIDGING_WRAPPER_NONNULL(swift::Name, Name)
#include "swift/AST/ASTBridgingWrappers.def"

// For nullable nodes, also define a nullable variant.
#define AST_BRIDGING_WRAPPER_NULLABLE(Name) \
BRIDGING_WRAPPER_NULLABLE(swift::Name, Name)
#define AST_BRIDGING_WRAPPER_NONNULL(Name)
#include "swift/AST/ASTBridgingWrappers.def"

// Declare `.asDecl` on each BridgedXXXDecl type, which upcasts a wrapper for
// a Decl subclass to a BridgedDecl.
#define DECL(Id, Parent) \
Expand Down Expand Up @@ -565,6 +571,120 @@ SWIFT_NAME("getter:BridgedClosureExpr.asDeclContext(self:)")
BridgedDeclContext
BridgedClosureExpr_asDeclContext(BridgedClosureExpr cClosure);

//===----------------------------------------------------------------------===//
// MARK: Availability
//===----------------------------------------------------------------------===//

enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedPlatformKind : size_t {
BridgedPlatformKind_None,
#define AVAILABILITY_PLATFORM(X, PrettyName) BridgedPlatformKind_##X,
#include "swift/AST/PlatformKinds.def"
};

SWIFT_NAME("BridgedPlatformKind.init(from:)")
BridgedPlatformKind BridgedPlatformKind_fromString(BridgedStringRef cStr);

SWIFT_NAME("BridgedAvailabilityMacroMap.has(self:name:)")
bool BridgedAvailabilityMacroMap_hasName(BridgedAvailabilityMacroMap map,
BridgedStringRef name);

SWIFT_NAME("BridgedAvailabilityMacroMap.has(self:name:version:)")
bool BridgedAvailabilityMacroMap_hasNameAndVersion(
BridgedAvailabilityMacroMap map, BridgedStringRef name,
BridgedVersionTuple version);

SWIFT_NAME("BridgedAvailabilityMacroMap.get(self:name:version:)")
BridgedArrayRef
BridgedAvailabilityMacroMap_getSpecs(BridgedAvailabilityMacroMap map,
BridgedStringRef name,
BridgedVersionTuple version);

struct BridgedAvailabilityMacroDefinition {
BridgedStringRef name;
BridgedVersionTuple version;
BridgedArrayRef specs;
};

enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedAvailabilitySpecKind {
BridgedAvailabilitySpecKindPlatformVersionConstraint,
BridgedAvailabilitySpecKindOtherPlatform,
BridgedAvailabilitySpecKindLanguageVersionConstraint,
BridgedAvailabilitySpecKindPackageDescriptionVersionConstraint,
};

struct BridgedAvailabilityDomain;

SWIFT_NAME("getter:BridgedAvailabilitySpec.sourceRange(self:)")
BridgedSourceRange
BridgedAvailabilitySpec_getSourceRange(BridgedAvailabilitySpec spec);

SWIFT_NAME("getter:BridgedAvailabilitySpec.domain(self:)")
BridgedAvailabilityDomain
BridgedAvailabilitySpec_getDomain(BridgedAvailabilitySpec spec);

SWIFT_NAME("getter:BridgedAvailabilitySpec.version(self:)")
BridgedVersionTuple
BridgedAvailabilitySpec_getVersion(BridgedAvailabilitySpec spec);

SWIFT_NAME("getter:BridgedAvailabilitySpec.versionRange(self:)")
BridgedSourceRange
BridgedAvailabilitySpec_getVersionRange(BridgedAvailabilitySpec spec);

SWIFT_NAME("BridgedPlatformVersionConstraintAvailabilitySpec.createParsed(_:"
"platform:platformLoc:version:runtimeVersion:versionRange:)")
BridgedPlatformVersionConstraintAvailabilitySpec
BridgedPlatformVersionConstraintAvailabilitySpec_createParsed(
BridgedASTContext cContext, BridgedPlatformKind cPlatform,
BridgedSourceLoc cPlatformLoc, BridgedVersionTuple cVersion,
BridgedVersionTuple cRuntimeVersion, BridgedSourceRange cVersionSrcRange);

SWIFT_NAME("BridgedPlatformAgnosticVersionConstraintAvailabilitySpec."
"createParsed(_:kind:nameLoc:version:versionRange:)")
BridgedPlatformAgnosticVersionConstraintAvailabilitySpec
BridgedPlatformAgnosticVersionConstraintAvailabilitySpec_createParsed(
BridgedASTContext cContext, BridgedAvailabilitySpecKind cKind,
BridgedSourceLoc cNameLoc, BridgedVersionTuple cVersion,
BridgedSourceRange cVersionSrcRange);

SWIFT_NAME("BridgedOtherPlatformAvailabilitySpec.createParsed(_:loc:)")
BridgedOtherPlatformAvailabilitySpec
BridgedOtherPlatformAvailabilitySpec_createParsed(BridgedASTContext cContext,
BridgedSourceLoc cLoc);

SWIFT_NAME("getter:BridgedPlatformVersionConstraintAvailabilitySpec."
"asAvailabilitySpec(self:)")
BridgedAvailabilitySpec
BridgedPlatformVersionConstraintAvailabilitySpec_asAvailabilitySpec(
BridgedPlatformVersionConstraintAvailabilitySpec spec);

SWIFT_NAME("getter:BridgedPlatformAgnosticVersionConstraintAvailabilitySpec."
"asAvailabilitySpec(self:)")
BridgedAvailabilitySpec
BridgedPlatformAgnosticVersionConstraintAvailabilitySpec_asAvailabilitySpec(
BridgedPlatformAgnosticVersionConstraintAvailabilitySpec spec);

SWIFT_NAME(
"getter:BridgedOtherPlatformAvailabilitySpec.asAvailabilitySpec(self:)")
BridgedAvailabilitySpec BridgedOtherPlatformAvailabilitySpec_asAvailabilitySpec(
BridgedOtherPlatformAvailabilitySpec spec);

struct BridgedAvailabilityDomain {
void *_Nullable opaque;

BridgedAvailabilityDomain() : opaque(nullptr) {};
BRIDGED_INLINE BridgedAvailabilityDomain(swift::AvailabilityDomain domain);
BRIDGED_INLINE swift::AvailabilityDomain unbridged() const;

BRIDGED_INLINE static BridgedAvailabilityDomain forUniversal();
BRIDGED_INLINE static BridgedAvailabilityDomain
forPlatform(BridgedPlatformKind platformKind);
BRIDGED_INLINE static BridgedAvailabilityDomain forSwiftLanguage();
BRIDGED_INLINE static BridgedAvailabilityDomain forPackageDescription();
BRIDGED_INLINE static BridgedAvailabilityDomain forEmbedded();

bool isNull() const { return opaque == nullptr; };
};

//===----------------------------------------------------------------------===//
// MARK: DeclAttributes
//===----------------------------------------------------------------------===//
Expand All @@ -581,7 +701,7 @@ BridgedDeclAttrKind BridgedDeclAttrKind_fromString(BridgedStringRef cStr);
struct BridgedDeclAttributes {
BridgedNullableDeclAttribute chain;

BridgedDeclAttributes() : chain(nullptr){};
BridgedDeclAttributes() : chain(nullptr) {};

BRIDGED_INLINE BridgedDeclAttributes(swift::DeclAttributes attrs);

Expand All @@ -598,9 +718,43 @@ BridgedDeclAttribute BridgedDeclAttribute_createSimple(
BridgedSourceLoc cAtLoc, BridgedSourceLoc cNameLoc);

SWIFT_NAME("BridgedABIAttr.createParsed(_:atLoc:range:abiDecl:)")
BridgedABIAttr BridgedABIAttr_createParsed(
BridgedASTContext cContext, BridgedSourceLoc atLoc,
BridgedSourceRange range, BridgedNullableDecl abiDecl);
BridgedABIAttr BridgedABIAttr_createParsed(BridgedASTContext cContext,
BridgedSourceLoc atLoc,
BridgedSourceRange range,
BridgedNullableDecl abiDecl);

enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedAvailableAttrKind {
BridgedAvailableAttrKindDefault,
BridgedAvailableAttrKindDeprecated,
BridgedAvailableAttrKindUnavailable,
BridgedAvailableAttrKindNoAsync,
};

SWIFT_NAME(
"BridgedAvailableAttr.createParsed(_:atLoc:range:domain:domainLoc:kind:message:"
"renamed:introduced:introducedRange:deprecated:deprecatedRange:"
"obsoleted:obsoletedRange:)")
BridgedAvailableAttr BridgedAvailableAttr_createParsed(
BridgedASTContext cContext, BridgedSourceLoc cAtLoc,
BridgedSourceRange cRange, BridgedAvailabilityDomain cDomain, BridgedSourceLoc cDomainLoc,
BridgedAvailableAttrKind cKind, BridgedStringRef cMessage,
BridgedStringRef cRenamed, BridgedVersionTuple cIntroduced,
BridgedSourceRange cIntroducedRange, BridgedVersionTuple cDeprecated,
BridgedSourceRange cDeprecatedRange, BridgedVersionTuple cObsoleted,
BridgedSourceRange cObsoletedRange);

SWIFT_NAME(
"BridgedAvailableAttr.createParsed(_:atLoc:range:domainString:domainLoc:kind:message:"
"renamed:introduced:introducedRange:deprecated:deprecatedRange:"
"obsoleted:obsoletedRange:)")
BridgedAvailableAttr BridgedAvailableAttr_createParsedStr(
BridgedASTContext cContext, BridgedSourceLoc cAtLoc,
BridgedSourceRange cRange, BridgedStringRef cDomainString, BridgedSourceLoc cDomainLoc,
BridgedAvailableAttrKind cKind, BridgedStringRef cMessage,
BridgedStringRef cRenamed, BridgedVersionTuple cIntroduced,
BridgedSourceRange cIntroducedRange, BridgedVersionTuple cDeprecated,
BridgedSourceRange cDeprecatedRange, BridgedVersionTuple cObsoleted,
BridgedSourceRange cObsoletedRange);

enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedExecutionKind {
BridgedExecutionKindConcurrent,
Expand Down
9 changes: 9 additions & 0 deletions include/swift/AST/ASTBridgingImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "swift/AST/ASTContext.h"
#include "swift/AST/ArgumentList.h"
#include "swift/AST/AvailabilityDomain.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Expr.h"
#include "swift/AST/IfConfigClauseRangeInfo.h"
Expand Down Expand Up @@ -236,6 +237,14 @@ swift::DeclAttributes BridgedDeclAttributes::unbridged() const {
return attrs;
}

BridgedAvailabilityDomain::BridgedAvailabilityDomain(
swift::AvailabilityDomain domain)
: opaque(domain.getOpaqueValue()) {}

swift::AvailabilityDomain BridgedAvailabilityDomain::unbridged() const {
return swift::AvailabilityDomain::fromOpaque(opaque);
}

//===----------------------------------------------------------------------===//
// MARK: BridgedParamDecl
//===----------------------------------------------------------------------===//
Expand Down
5 changes: 5 additions & 0 deletions include/swift/AST/ASTBridgingWrappers.def
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ AST_BRIDGING_WRAPPER_NULLABLE(CustomAttributeInitializer)
AST_BRIDGING_WRAPPER_NONNULL(TypeAttributes)
AST_BRIDGING_WRAPPER_NONNULL(CustomAttribute)
AST_BRIDGING_WRAPPER_NULLABLE(ArgumentList)
AST_BRIDGING_WRAPPER_NULLABLE(AvailabilitySpec)
AST_BRIDGING_WRAPPER_NULLABLE(PlatformVersionConstraintAvailabilitySpec)
AST_BRIDGING_WRAPPER_NULLABLE(PlatformAgnosticVersionConstraintAvailabilitySpec)
AST_BRIDGING_WRAPPER_NULLABLE(OtherPlatformAvailabilitySpec)
AST_BRIDGING_WRAPPER_NONNULL(AvailabilityMacroMap)

// Non-AST types to generate wrappers for.
AST_BRIDGING_WRAPPER_NULLABLE(DiagnosticEngine)
Expand Down
7 changes: 2 additions & 5 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -996,11 +996,8 @@ class ASTContext final {
return getMultiPayloadEnumTagSinglePayloadAvailability();
}

/// Cache of the availability macros parsed from the command line arguments.
///
/// This is an implementation detail, access via
/// \c Parser::parseAllAvailabilityMacroArguments.
AvailabilityMacroMap &getAvailabilityMacroCache() const;
/// Availability macros parsed from the command line arguments.
const AvailabilityMacroMap &getAvailabilityMacroMap() const;

/// Test support utility for loading a platform remap file
/// in case an SDK is not specified to the compilation.
Expand Down
12 changes: 6 additions & 6 deletions include/swift/AST/AvailabilityDomain.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,6 @@ class AvailabilityDomain final {

AvailabilityDomain(Storage storage) : storage(storage) {};

static AvailabilityDomain fromOpaque(void *opaque) {
return AvailabilityDomain(Storage::getFromOpaqueValue(opaque));
}

void *getOpaqueValue() const { return storage.getOpaqueValue(); }

std::optional<InlineDomain> getInlineDomain() const {
return storage.is<InlineDomainPtr>()
? static_cast<std::optional<InlineDomain>>(
Expand Down Expand Up @@ -161,6 +155,12 @@ class AvailabilityDomain final {
static std::optional<AvailabilityDomain>
builtinDomainForString(StringRef string, const DeclContext *declContext);

static AvailabilityDomain fromOpaque(void *opaque) {
return AvailabilityDomain(Storage::getFromOpaqueValue(opaque));
}

void *getOpaqueValue() const { return storage.getOpaqueValue(); }

Kind getKind() const {
if (auto inlineDomain = getInlineDomain())
return inlineDomain->getKind();
Expand Down
46 changes: 42 additions & 4 deletions include/swift/AST/AvailabilitySpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@
#ifndef SWIFT_AST_AVAILABILITY_SPEC_H
#define SWIFT_AST_AVAILABILITY_SPEC_H

#include "swift/AST/ASTAllocated.h"
#include "swift/AST/Identifier.h"
#include "swift/AST/PlatformKind.h"
#include "swift/Basic/SourceLoc.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/VersionTuple.h"

namespace swift {
class ASTContext;
class AvailabilityDomain;

enum class VersionComparison { GreaterThanEqual };

Expand Down Expand Up @@ -54,6 +57,12 @@ class AvailabilitySpec : public ASTAllocated<AvailabilitySpec> {
AvailabilitySpecKind getKind() const { return Kind; }

SourceRange getSourceRange() const;

std::optional<AvailabilityDomain> getDomain() const;

llvm::VersionTuple getVersion() const;

SourceRange getVersionSrcRange() const;
};

/// An availability specification that guards execution based on the
Expand Down Expand Up @@ -222,11 +231,40 @@ class OtherPlatformAvailabilitySpec : public AvailabilitySpec {
/// parsing a version tuple.
class AvailabilityMacroMap {
public:
typedef llvm::DenseMap<llvm::VersionTuple,
SmallVector<AvailabilitySpec *, 4>> VersionEntry;
typedef llvm::DenseMap<llvm::VersionTuple, SmallVector<AvailabilitySpec *, 4>>
VersionEntry;
llvm::StringMap<VersionEntry> Impl;

bool hasMacroName(StringRef name) const {
return Impl.find(name) != Impl.end();
}

bool WasParsed = false;
llvm::DenseMap<StringRef, VersionEntry> Impl;
bool hasMacroNameVersion(StringRef name, llvm::VersionTuple version) const {
auto entry = Impl.find(name);
if (entry == Impl.end()) {
return false;
}
return entry->second.find(version) != entry->second.end();
}

void addEntry(StringRef name, llvm::VersionTuple version,
ArrayRef<AvailabilitySpec *> specs) {
assert(!hasMacroNameVersion(name, version));
Impl[name][version].assign(specs.begin(), specs.end());
}

ArrayRef<AvailabilitySpec *> getEntry(StringRef name,
llvm::VersionTuple version) {
auto versions = Impl.find(name);
if (versions == Impl.end()) {
return {};
}
auto entry = versions->second.find(version);
if (entry == versions->second.end()) {
return {};
}
return entry->second;
}
};

} // end namespace swift
Expand Down
Loading