Skip to content

Commit a82e17b

Browse files
authored
Merge pull request #62934 from rxwei/freestanding-declaration-macros
[Macros] Freestanding declaration macros
2 parents f1607c9 + f17b7c4 commit a82e17b

36 files changed

+934
-128
lines changed

include/swift/AST/Attr.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "swift/AST/ConcreteDeclRef.h"
3434
#include "swift/AST/DeclNameLoc.h"
3535
#include "swift/AST/KnownProtocols.h"
36+
#include "swift/AST/MacroDeclaration.h"
3637
#include "swift/AST/Ownership.h"
3738
#include "swift/AST/PlatformKind.h"
3839
#include "swift/AST/Requirement.h"
@@ -2302,6 +2303,40 @@ class ObjCImplementationAttr final : public DeclAttribute {
23022303
}
23032304
};
23042305

2306+
class DeclarationAttr final
2307+
: public DeclAttribute,
2308+
private llvm::TrailingObjects<DeclarationAttr, MacroIntroducedDeclName> {
2309+
friend TrailingObjects;
2310+
2311+
MacroContext macroContext;
2312+
unsigned numPeerNames, numMemberNames;
2313+
2314+
DeclarationAttr(SourceLoc atLoc, SourceRange range, MacroContext macroContext,
2315+
ArrayRef<MacroIntroducedDeclName> peerNames,
2316+
ArrayRef<MacroIntroducedDeclName> memberNames,
2317+
bool implicit);
2318+
2319+
public:
2320+
static DeclarationAttr *create(ASTContext &ctx, SourceLoc atLoc,
2321+
SourceRange range, MacroContext macroContext,
2322+
ArrayRef<MacroIntroducedDeclName> peerNames,
2323+
ArrayRef<MacroIntroducedDeclName> memberNames,
2324+
bool implicit);
2325+
2326+
size_t numTrailingObjects(OverloadToken<MacroIntroducedDeclName>) const {
2327+
return numPeerNames + numMemberNames;
2328+
}
2329+
2330+
MacroContext getMacroContext() const { return macroContext; }
2331+
ArrayRef<MacroIntroducedDeclName> getPeerAndMemberNames() const;
2332+
ArrayRef<MacroIntroducedDeclName> getPeerNames() const;
2333+
ArrayRef<MacroIntroducedDeclName> getMemberNames() const;
2334+
2335+
static bool classof(const DeclAttribute *DA) {
2336+
return DA->getKind() == DAK_Declaration;
2337+
}
2338+
};
2339+
23052340
/// Attributes that may be applied to declarations.
23062341
class DeclAttributes {
23072342
/// Linked list of declaration attributes.

include/swift/AST/Decl.h

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8331,17 +8331,6 @@ class MissingMemberDecl : public Decl {
83318331
}
83328332
};
83338333

8334-
/// The context in which a macro can be used, which determines the syntax it
8335-
/// uses.
8336-
enum class MacroContext: uint8_t {
8337-
/// An expression macro, referenced explicitly via "#stringify" or similar
8338-
/// in the source code.
8339-
Expression = 0x01,
8340-
};
8341-
8342-
/// The contexts in which a particular macro declaration can be used.
8343-
using MacroContexts = OptionSet<MacroContext>;
8344-
83458334
/// Provides a declaration of a macro.
83468335
///
83478336
/// Macros are declared within the source code with the `macro` introducer.
@@ -8414,7 +8403,10 @@ class MacroExpansionDecl : public Decl {
84148403
SourceLoc LeftAngleLoc, RightAngleLoc;
84158404
ArrayRef<TypeRepr *> GenericArgs;
84168405
ArgumentList *ArgList;
8417-
Decl *Rewritten;
8406+
ArrayRef<Decl *> Rewritten;
8407+
8408+
/// The referenced macro.
8409+
ConcreteDeclRef macroRef;
84188410

84198411
public:
84208412
MacroExpansionDecl(DeclContext *dc, SourceLoc poundLoc, DeclNameRef macro,
@@ -8426,7 +8418,7 @@ class MacroExpansionDecl : public Decl {
84268418
: Decl(DeclKind::MacroExpansion, dc), PoundLoc(poundLoc),
84278419
Macro(macro), MacroLoc(macroLoc),
84288420
LeftAngleLoc(leftAngleLoc), RightAngleLoc(rightAngleLoc),
8429-
GenericArgs(genericArgs), ArgList(args), Rewritten(nullptr) {}
8421+
GenericArgs(genericArgs), ArgList(args), Rewritten({}) {}
84308422

84318423
ArrayRef<TypeRepr *> getGenericArgs() const { return GenericArgs; }
84328424

@@ -8440,8 +8432,10 @@ class MacroExpansionDecl : public Decl {
84408432
DeclNameLoc getMacroLoc() const { return MacroLoc; }
84418433
DeclNameRef getMacro() const { return Macro; }
84428434
ArgumentList *getArgs() const { return ArgList; }
8443-
Decl *getRewritten() const { return Rewritten; }
8444-
void setRewritten(Decl *rewritten) { Rewritten = rewritten; }
8435+
ArrayRef<Decl *> getRewritten() const { return Rewritten; }
8436+
void setRewritten(ArrayRef<Decl *> rewritten) { Rewritten = rewritten; }
8437+
ConcreteDeclRef getMacroRef() const { return macroRef; }
8438+
void setMacroRef(ConcreteDeclRef ref) { macroRef = ref; }
84458439

84468440
static bool classof(const Decl *D) {
84478441
return D->getKind() == DeclKind::MacroExpansion;

include/swift/AST/DiagnosticsParse.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,6 +2009,9 @@ ERROR(macro_expansion_expr_expected_macro_identifier,PointsToFirstBadToken,
20092009
ERROR(macro_expansion_decl_expected_macro_identifier,PointsToFirstBadToken,
20102010
"expected a macro identifier for a pound literal declaration", ())
20112011

2012+
ERROR(declaration_attr_expected_kind,PointsToFirstBadToken,
2013+
"expected a declaration macro kind ('freestanding' or 'attached')", ())
2014+
20122015
ERROR(parser_round_trip_error,none,
20132016
"source file did not round-trip through the new Swift parser", ())
20142017
ERROR(parser_new_parser_errors,none,

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6780,6 +6780,8 @@ ERROR(experimental_no_metadata_feature_can_only_be_used_when_enabled,
67806780

67816781
ERROR(expected_macro_expansion_expr,PointsToFirstBadToken,
67826782
"expected macro expansion to produce an expression", ())
6783+
ERROR(expected_macro_expansion_decls,PointsToFirstBadToken,
6784+
"expected macro expansion to produce declarations", ())
67836785
ERROR(macro_undefined,PointsToFirstBadToken,
67846786
"no macro named %0", (Identifier))
67856787
ERROR(external_macro_not_found,none,
@@ -6836,6 +6838,8 @@ ERROR(macro_definition_unsupported,none,
68366838
ERROR(external_macro_arg_not_type_name,none,
68376839
"argument to `#externalMacro` must be a string literal naming "
68386840
"the external macro's %select{module|type}", (unsigned))
6841+
ERROR(attached_declaration_macro_not_supported,none,
6842+
"attached declaration macros are not yet supported", ())
68396843

68406844
//------------------------------------------------------------------------------
68416845
// MARK: Move Only Errors

include/swift/AST/MacroDeclaration.h

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//===--- MacroDeclaration.h - Swift Macro Declaration -----------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Data structures that configure the declaration of a macro.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_AST_MACRO_DECLARATION_H
18+
#define SWIFT_AST_MACRO_DECLARATION_H
19+
20+
#include "swift/AST/Identifier.h"
21+
22+
namespace swift {
23+
24+
/// The context in which a macro can be used, which determines the syntax it
25+
/// uses.
26+
enum class MacroContext: uint8_t {
27+
/// An expression macro, referenced explicitly via "#stringify" or similar
28+
/// in the source code.
29+
Expression = 0x01,
30+
/// A freestanding declaration macro.
31+
FreestandingDeclaration = 0x02,
32+
/// An attached declaration macro.
33+
AttachedDeclaration = 0x03,
34+
};
35+
36+
/// The contexts in which a particular macro declaration can be used.
37+
using MacroContexts = OptionSet<MacroContext>;
38+
39+
enum class MacroIntroducedDeclNameKind {
40+
Named,
41+
Overloaded,
42+
Accessors,
43+
Prefixed,
44+
Suffixed,
45+
Arbitrary,
46+
};
47+
48+
class MacroIntroducedDeclName {
49+
public:
50+
using Kind = MacroIntroducedDeclNameKind;
51+
52+
private:
53+
Kind kind;
54+
Identifier identifier;
55+
56+
public:
57+
MacroIntroducedDeclName(Kind kind, Identifier identifier = Identifier())
58+
: kind(kind), identifier(identifier) {};
59+
60+
static MacroIntroducedDeclName getNamed(Identifier name) {
61+
return MacroIntroducedDeclName(Kind::Named, name);
62+
}
63+
64+
static MacroIntroducedDeclName getOverloaded() {
65+
return MacroIntroducedDeclName(Kind::Overloaded);
66+
}
67+
68+
static MacroIntroducedDeclName getAccessors() {
69+
return MacroIntroducedDeclName(Kind::Accessors);
70+
}
71+
72+
static MacroIntroducedDeclName getPrefixed(Identifier prefix) {
73+
return MacroIntroducedDeclName(Kind::Prefixed, prefix);
74+
}
75+
76+
static MacroIntroducedDeclName getSuffixed(Identifier suffix) {
77+
return MacroIntroducedDeclName(Kind::Suffixed, suffix);
78+
}
79+
80+
static MacroIntroducedDeclName getArbitrary() {
81+
return MacroIntroducedDeclName(Kind::Arbitrary);
82+
}
83+
84+
Kind getKind() const { return kind; }
85+
Identifier getIdentifier() const { return identifier; }
86+
};
87+
88+
}
89+
90+
#endif // SWIFT_AST_MACRO_DECLARATION_H

include/swift/AST/TypeCheckRequests.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3765,6 +3765,23 @@ class GetTypeWrapperInitializer
37653765
bool isCached() const { return true; }
37663766
};
37673767

3768+
/// Check whether this is a protocol that has a type wrapper attribute
3769+
/// or one of its dependencies does.
3770+
class UsesTypeWrapperFeature
3771+
: public SimpleRequest<UsesTypeWrapperFeature, bool(NominalTypeDecl *),
3772+
RequestFlags::Cached> {
3773+
public:
3774+
using SimpleRequest::SimpleRequest;
3775+
3776+
private:
3777+
friend SimpleRequest;
3778+
3779+
bool evaluate(Evaluator &evaluator, NominalTypeDecl *) const;
3780+
3781+
public:
3782+
bool isCached() const { return true; }
3783+
};
3784+
37683785
/// Find the definition of a given macro.
37693786
class MacroDefinitionRequest
37703787
: public SimpleRequest<MacroDefinitionRequest,
@@ -3785,6 +3802,24 @@ class MacroDefinitionRequest
37853802
bool isCached() const { return true; }
37863803
};
37873804

3805+
/// Find the definition of a given macro.
3806+
class ExpandMacroExpansionDeclRequest
3807+
: public SimpleRequest<ExpandMacroExpansionDeclRequest,
3808+
ArrayRef<Decl *>(MacroExpansionDecl *),
3809+
RequestFlags::Cached> {
3810+
public:
3811+
using SimpleRequest::SimpleRequest;
3812+
3813+
private:
3814+
friend SimpleRequest;
3815+
3816+
ArrayRef<Decl *> evaluate(Evaluator &evaluator,
3817+
MacroExpansionDecl *med) const;
3818+
3819+
public:
3820+
bool isCached() const { return true; }
3821+
};
3822+
37883823
/// Resolve an external macro given its module and type name.
37893824
class ExternalMacroDefinitionRequest
37903825
: public SimpleRequest<ExternalMacroDefinitionRequest,

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,9 @@ SWIFT_REQUEST(TypeChecker, MacroDefinitionRequest,
449449
SWIFT_REQUEST(TypeChecker, ExternalMacroDefinitionRequest,
450450
ExternalMacroDefinition(ASTContext *, Identifier, Identifier),
451451
Cached, NoLocationInfo)
452+
SWIFT_REQUEST(TypeChecker, ExpandMacroExpansionDeclRequest,
453+
ArrayRef<Decl *>(MacroExpansionDecl *),
454+
Cached, NoLocationInfo)
452455
SWIFT_REQUEST(TypeChecker, SynthesizeRuntimeMetadataAttrGenerator,
453456
Expr *(CustomAttr *, ValueDecl *),
454457
Cached, NoLocationInfo)

include/swift/AST/TypeMemberVisitor.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ class TypeMemberVisitor : public DeclVisitor<ImplClass, RetTy> {
7878
asImpl().visit(dd);
7979
}
8080
}
81+
82+
/// Visit expanded macros.
83+
void visitMacroExpansionDecl(MacroExpansionDecl *D) {
84+
for (auto *decl : D->getRewritten())
85+
asImpl().visit(decl);
86+
}
8187
};
8288

8389
template<typename ImplClass, typename RetTy = void>

include/swift/Parse/Parser.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,10 @@ class Parser {
10901090
bool parseDocumentationAttributeArgument(Optional<StringRef> &Metadata,
10911091
Optional<AccessLevel> &Visibility);
10921092

1093+
/// Parse the @declaration attribute.
1094+
ParserResult<DeclarationAttr> parseDeclarationAttribute(SourceLoc AtLoc,
1095+
SourceLoc Loc);
1096+
10931097
/// Parse a specific attribute.
10941098
ParserStatus parseDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
10951099
PatternBindingInitializer *&initContext,

lib/AST/ASTWalker.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,8 +428,9 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
428428
bool visitMacroExpansionDecl(MacroExpansionDecl *MED) {
429429
if (MED->getArgs() && doIt(MED->getArgs()))
430430
return true;
431-
if (MED->getRewritten() && doIt(MED->getRewritten()))
432-
return true;
431+
for (auto *decl : MED->getRewritten())
432+
if (doIt(decl))
433+
return true;
433434
return false;
434435
}
435436

lib/AST/Attr.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,6 +1483,8 @@ StringRef DeclAttribute::getAttrName() const {
14831483
return "_expose";
14841484
case DAK_Documentation:
14851485
return "_documentation";
1486+
case DAK_Declaration:
1487+
return "declaration";
14861488
}
14871489
llvm_unreachable("bad DeclAttrKind");
14881490
}
@@ -2308,6 +2310,52 @@ bool CustomAttr::isArgUnsafe() const {
23082310
return isArgUnsafeBit;
23092311
}
23102312

2313+
DeclarationAttr::DeclarationAttr(SourceLoc atLoc, SourceRange range,
2314+
MacroContext macroContext,
2315+
ArrayRef<MacroIntroducedDeclName> peerNames,
2316+
ArrayRef<MacroIntroducedDeclName> memberNames,
2317+
bool implicit)
2318+
: DeclAttribute(DAK_Declaration, atLoc, range, implicit),
2319+
macroContext(macroContext), numPeerNames(peerNames.size()),
2320+
numMemberNames(memberNames.size()) {
2321+
auto *trailingNamesBuffer = getTrailingObjects<MacroIntroducedDeclName>();
2322+
std::uninitialized_copy(peerNames.begin(), peerNames.end(),
2323+
trailingNamesBuffer);
2324+
std::uninitialized_copy(memberNames.begin(), memberNames.end(),
2325+
trailingNamesBuffer + peerNames.size());
2326+
}
2327+
2328+
DeclarationAttr *
2329+
DeclarationAttr::create(ASTContext &ctx, SourceLoc atLoc, SourceRange range,
2330+
MacroContext macroContext,
2331+
ArrayRef<MacroIntroducedDeclName> peerNames,
2332+
ArrayRef<MacroIntroducedDeclName> memberNames,
2333+
bool implicit) {
2334+
unsigned size = totalSizeToAlloc<MacroIntroducedDeclName>(
2335+
peerNames.size() + memberNames.size());
2336+
auto *mem = ctx.Allocate(size, alignof(DeclarationAttr));
2337+
return new (mem) DeclarationAttr(atLoc, range, macroContext, peerNames,
2338+
memberNames, implicit);
2339+
}
2340+
2341+
ArrayRef<MacroIntroducedDeclName> DeclarationAttr::getPeerAndMemberNames() const {
2342+
return {
2343+
getTrailingObjects<MacroIntroducedDeclName>(),
2344+
numPeerNames + numMemberNames
2345+
};
2346+
}
2347+
2348+
ArrayRef<MacroIntroducedDeclName> DeclarationAttr::getPeerNames() const {
2349+
return {getTrailingObjects<MacroIntroducedDeclName>(), numPeerNames};
2350+
}
2351+
2352+
ArrayRef<MacroIntroducedDeclName> DeclarationAttr::getMemberNames() const {
2353+
return {
2354+
getTrailingObjects<MacroIntroducedDeclName>() + numPeerNames,
2355+
numMemberNames
2356+
};
2357+
}
2358+
23112359
const DeclAttribute *
23122360
DeclAttributes::getEffectiveSendableAttr() const {
23132361
const NonSendableAttr *assumedAttr = nullptr;

lib/AST/Decl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9713,6 +9713,8 @@ MacroContexts MacroDecl::getMacroContexts() const {
97139713
MacroContexts contexts = None;
97149714
if (getAttrs().hasAttribute<ExpressionAttr>())
97159715
contexts |= MacroContext::Expression;
9716+
for (auto attr : getAttrs().getAttributes<DeclarationAttr>())
9717+
contexts |= attr->getMacroContext();
97169718
return contexts;
97179719
}
97189720

lib/AST/NameLookup.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "swift/AST/ParameterList.h"
3232
#include "swift/AST/PropertyWrappers.h"
3333
#include "swift/AST/SourceFile.h"
34+
#include "swift/AST/TypeCheckRequests.h"
3435
#include "swift/Basic/Debug.h"
3536
#include "swift/Basic/STLExtras.h"
3637
#include "swift/Basic/SourceManager.h"

0 commit comments

Comments
 (0)