Skip to content

Implement experimental @abi attribute #76878

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 15 commits into from
Dec 20, 2024
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
9 changes: 7 additions & 2 deletions include/swift/AST/ASTBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,11 @@ BridgedDeclAttribute BridgedDeclAttribute_createSimple(
BridgedASTContext cContext, BridgedDeclAttrKind cKind,
BridgedSourceLoc cAtLoc, BridgedSourceLoc cNameLoc);

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

enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedAccessLevel {
BridgedAccessLevelPrivate,
BridgedAccessLevelFilePrivate,
Expand Down Expand Up @@ -918,8 +923,8 @@ BridgedUnavailableFromAsyncAttr BridgedUnavailableFromAsyncAttr_createParsed(

struct BridgedFingerprint;

SWIFT_NAME("BridgedDecl.setAttrs(self:_:)")
void BridgedDecl_setAttrs(BridgedDecl decl, BridgedDeclAttributes attrs);
SWIFT_NAME("BridgedDecl.attachParsedAttrs(self:_:)")
void BridgedDecl_attachParsedAttrs(BridgedDecl decl, BridgedDeclAttributes attrs);

enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedStaticSpelling {
BridgedStaticSpellingNone,
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/ASTBridgingWrappers.def
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@

// Some of the base classes need to be nullable to allow them to be used as
// optional parameters.
AST_BRIDGING_WRAPPER_NONNULL(Decl)
AST_BRIDGING_WRAPPER_NULLABLE(Decl)
AST_BRIDGING_WRAPPER_NONNULL(DeclContext)
AST_BRIDGING_WRAPPER_NONNULL(SourceFile)
AST_BRIDGING_WRAPPER_NULLABLE(Stmt)
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ namespace llvm {
}

namespace swift {
class ABIAttr;
class AbstractFunctionDecl;
class ASTContext;
enum class Associativity : unsigned char;
Expand Down
8 changes: 8 additions & 0 deletions include/swift/AST/ASTMangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,14 @@ class ASTMangler : public Mangler {
return tryMangleSubstitution(type.getPointer());
}

protected:
using Mangler::addSubstitution;
void addSubstitution(const Decl *decl);

using Mangler::tryMangleSubstitution;
bool tryMangleSubstitution(const Decl *decl);

public:
std::string mangleClosureEntity(const AbstractClosureExpr *closure,
SymbolKind SKind);

Expand Down
41 changes: 41 additions & 0 deletions include/swift/AST/ASTScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ class ASTScopeImpl : public ASTAllocated<ASTScopeImpl> {
friend class IterableTypeBodyPortion;
friend class ScopeCreator;
friend class ASTSourceFileScope;
friend class ABIAttributeScope;
friend class Lowering::SILGenFunction;

#pragma mark - tree state
Expand Down Expand Up @@ -250,12 +251,15 @@ class ASTScopeImpl : public ASTAllocated<ASTScopeImpl> {

void printRange(llvm::raw_ostream &out) const;

void printParents(llvm::raw_ostream &out) const;

protected:
virtual void printSpecifics(llvm::raw_ostream &out) const {}
virtual NullablePtr<const void> addressForPrinting() const;

public:
SWIFT_DEBUG_DUMP;
SWIFT_DEBUG_DUMPER(dumpParents());

void dumpOneScopeMapLocation(std::pair<unsigned, unsigned> lineColumn);

Expand Down Expand Up @@ -302,6 +306,9 @@ class ASTScopeImpl : public ASTAllocated<ASTScopeImpl> {
SourceFile *sourceFile, SourceLoc loc,
llvm::function_ref<bool(ASTScope::PotentialMacro)> consume);

static ABIAttr *lookupEnclosingABIAttributeScope(
SourceFile *sourceFile, SourceLoc loc);

static CatchNode lookupCatchNode(ModuleDecl *module, SourceLoc loc);

/// Scopes that cannot bind variables may set this to true to create more
Expand Down Expand Up @@ -945,6 +952,40 @@ class CustomAttributeScope final : public ASTScopeImpl {
}
};

/// The scope for ABI attributes and their arguments.
///
/// Source locations for the attribute name and its arguments are in the
/// custom attribute, so lookup is invoked from within the attribute
/// itself.
class ABIAttributeScope final : public ASTScopeImpl {
public:
ABIAttr *attr;
Decl *decl;

ABIAttributeScope(ABIAttr *attr, Decl *decl)
: ASTScopeImpl(ScopeKind::ABIAttribute), attr(attr), decl(decl) {}
virtual ~ABIAttributeScope() {}

protected:
ASTScopeImpl *expandSpecifically(ScopeCreator &) override;

public:
SourceRange
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
NullablePtr<const void> addressForPrinting() const override { return decl; }

bool ignoreInDebugInfo() const override { return true; }

private:
AnnotatedInsertionPoint
expandAScopeThatCreatesANewInsertionPoint(ScopeCreator &);

public:
static bool classof(const ASTScopeImpl *scope) {
return scope->getKind() == ScopeKind::ABIAttribute;
}
};

/// PatternBindingDecl's (PBDs) are tricky (See the comment for \c
/// PatternBindingDecl):
///
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/ASTScopeNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ SCOPE_NODE(CaseLabelItem)
SCOPE_NODE(CaseStmtBody)
STMT_SCOPE_NODE(BraceStmt)
EXPR_SCOPE_NODE(Try)
DECL_ATTRIBUTE_SCOPE_NODE(ABIAttribute)

#undef DECL_ATTRIBUTE_SCOPE_NODE
#undef EXPR_SCOPE_NODE
Expand Down
52 changes: 47 additions & 5 deletions include/swift/AST/Attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "swift/AST/StorageImpl.h"
#include "swift/Basic/Debug.h"
#include "swift/Basic/EnumTraits.h"
#include "swift/Basic/Feature.h"
#include "swift/Basic/InlineBitfield.h"
#include "swift/Basic/Located.h"
#include "swift/Basic/OptimizationMode.h"
Expand Down Expand Up @@ -491,6 +492,8 @@ class DeclAttribute : public AttributeBase {
LLVM_READNONE
static bool canAttributeAppearOnDeclKind(DeclAttrKind DAK, DeclKind DK);

static std::optional<Feature> getRequiredFeature(DeclAttrKind DK);

/// Returns the source name of the attribute, without the @ or any arguments.
StringRef getAttrName() const;

Expand Down Expand Up @@ -2875,6 +2878,12 @@ template <typename ATTR, bool AllowInvalid> struct ToAttributeKind {
return cast<ATTR>(Attr);
return std::nullopt;
}

std::optional<ATTR *> operator()(DeclAttribute *Attr) {
if (isa<ATTR>(Attr) && (Attr->isValid() || AllowInvalid))
return cast<ATTR>(Attr);
return std::nullopt;
}
};

/// The @_allowFeatureSuppression(Foo, Bar) attribute. The feature
Expand Down Expand Up @@ -2908,6 +2917,31 @@ class AllowFeatureSuppressionAttr final
UNIMPLEMENTED_CLONE(AllowFeatureSuppressionAttr)
};

/// Defines the @abi attribute.
class ABIAttr : public DeclAttribute {
public:
ABIAttr(Decl *abiDecl, SourceLoc AtLoc, SourceRange Range, bool Implicit)
: DeclAttribute(DeclAttrKind::ABI, AtLoc, Range, Implicit),
abiDecl(abiDecl)
{ }

ABIAttr(Decl *abiDecl, bool Implicit)
: ABIAttr(abiDecl, SourceLoc(), SourceRange(), Implicit) {}

/// The declaration which will be used to compute a mangled name.
///
/// \note For a \c VarDecl with a parent \c PatternBindingDecl , this should
/// point to the parent \c PatternBindingDecl . (That accommodates the way
/// sibling \c VarDecl s share attributes.)
Decl *abiDecl;

static bool classof(const DeclAttribute *DA) {
return DA->getKind() == DeclAttrKind::ABI;
}

UNIMPLEMENTED_CLONE(ABIAttr)
};

/// Attributes that may be applied to declarations.
class DeclAttributes {
/// Linked list of declaration attributes.
Expand Down Expand Up @@ -3047,17 +3081,25 @@ class DeclAttributes {
}

public:
template <typename ATTR, bool AllowInvalid>
template <typename ATTR, typename Iterator, bool AllowInvalid>
using AttributeKindRange =
OptionalTransformRange<iterator_range<const_iterator>,
OptionalTransformRange<iterator_range<Iterator>,
ToAttributeKind<ATTR, AllowInvalid>,
const_iterator>;
Iterator>;

/// Return a range with all attributes in DeclAttributes with AttrKind
/// ATTR.
template <typename ATTR, bool AllowInvalid = false>
AttributeKindRange<ATTR, const_iterator, AllowInvalid> getAttributes() const {
return AttributeKindRange<ATTR, const_iterator, AllowInvalid>(
make_range(begin(), end()), ToAttributeKind<ATTR, AllowInvalid>());
}

/// Return a range with all attributes in DeclAttributes with AttrKind
/// ATTR.
template <typename ATTR, bool AllowInvalid = false>
AttributeKindRange<ATTR, AllowInvalid> getAttributes() const {
return AttributeKindRange<ATTR, AllowInvalid>(
AttributeKindRange<ATTR, iterator, AllowInvalid> getAttributes() {
return AttributeKindRange<ATTR, iterator, AllowInvalid>(
make_range(begin(), end()), ToAttributeKind<ATTR, AllowInvalid>());
}

Expand Down
Loading