Skip to content

Commit 0e691c4

Browse files
authored
Merge pull request #62747 from DougGregor/expression-macro-attr
[Macro] Add the expression attribute for macro declarations
2 parents 60e573a + f78f572 commit 0e691c4

17 files changed

+78
-51
lines changed

include/swift/AST/Decl.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8297,6 +8297,17 @@ class MissingMemberDecl : public Decl {
82978297
}
82988298
};
82998299

8300+
/// The context in which a macro can be used, which determines the syntax it
8301+
/// uses.
8302+
enum class MacroContext: uint8_t {
8303+
/// An expression macro, referenced explicitly via "#stringify" or similar
8304+
/// in the source code.
8305+
Expression = 0x01,
8306+
};
8307+
8308+
/// The contexts in which a particular macro declaration can be used.
8309+
using MacroContexts = OptionSet<MacroContext>;
8310+
83008311
/// Provides a declaration of a macro.
83018312
///
83028313
/// Macros are declared within the source code with the `macro` introducer.
@@ -8348,6 +8359,9 @@ class MacroDecl : public GenericContext, public ValueDecl {
83488359
/// Retrieve the interface type produced when expanding this macro.
83498360
Type getResultInterfaceType() const;
83508361

8362+
/// Determine the contexts in which this macro can be applied.
8363+
MacroContexts getMacroContexts() const;
8364+
83518365
static bool classof(const DeclContext *C) {
83528366
if (auto D = C->getAsDecl())
83538367
return classof(D);

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6781,6 +6781,9 @@ WARNING(macro_type_access_warn,none,
67816781
(bool, AccessLevel, AccessLevel, bool))
67826782
ERROR(macro_in_nested,none,
67836783
"macro %0 can only be declared at file scope", (DeclName))
6784+
ERROR(macro_without_context,none,
6785+
"macro %0 must declare its applicable contexts (e.g., '@expression')",
6786+
(DeclName))
67846787

67856788
//------------------------------------------------------------------------------
67866789
// MARK: Move Only Errors

include/swift/AST/MacroDefinition.h

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,6 @@ namespace swift {
2525
/// Provides the definition of a macro.
2626
class MacroDefinition {
2727
public:
28-
/// The kind of macro, which determines how it can be used in source code.
29-
enum Kind: uint8_t {
30-
/// An expression macro.
31-
Expression,
32-
};
33-
3428
/// Describes a missing macro definition.
3529
struct MissingDefinition {
3630
Identifier externalModuleName;
@@ -50,19 +44,18 @@ class MacroDefinition {
5044
InProcess,
5145
};
5246

53-
Kind kind;
5447
ImplementationKind implKind;
5548

5649
private:
5750
void *opaqueHandle;
5851

59-
MacroDefinition(Kind kind, ImplementationKind implKind, void *opaqueHandle)
60-
: kind(kind), implKind(implKind), opaqueHandle(opaqueHandle) { }
52+
MacroDefinition(ImplementationKind implKind, void *opaqueHandle)
53+
: implKind(implKind), opaqueHandle(opaqueHandle) { }
6154

6255
public:
6356
static MacroDefinition forUndefined() {
6457
return MacroDefinition{
65-
Kind::Expression, ImplementationKind::Undefined, nullptr
58+
ImplementationKind::Undefined, nullptr
6659
};
6760
}
6861

@@ -72,8 +65,8 @@ class MacroDefinition {
7265
Identifier externalMacroTypeName
7366
);
7467

75-
static MacroDefinition forInProcess(Kind kind, void *opaqueHandle) {
76-
return MacroDefinition{kind, ImplementationKind::InProcess, opaqueHandle};
68+
static MacroDefinition forInProcess(void *opaqueHandle) {
69+
return MacroDefinition{ImplementationKind::InProcess, opaqueHandle};
7770
}
7871

7972
/// Return the opaque handle for an in-process macro definition.

lib/AST/Decl.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9670,6 +9670,13 @@ SourceRange MacroDecl::getSourceRange() const {
96709670
return SourceRange(macroLoc, endLoc);
96719671
}
96729672

9673+
MacroContexts MacroDecl::getMacroContexts() const {
9674+
MacroContexts contexts = None;
9675+
if (getAttrs().hasAttribute<ExpressionAttr>())
9676+
contexts |= MacroContext::Expression;
9677+
return contexts;
9678+
}
9679+
96739680
SourceRange MacroExpansionDecl::getSourceRange() const {
96749681
SourceLoc endLoc;
96759682
if (ArgList)
@@ -9689,9 +9696,7 @@ MacroDefinition MacroDefinition::forMissing(
96899696
auto def = ctx.AllocateObjectCopy(
96909697
MissingDefinition{externalModuleName, externalMacroTypeName}
96919698
);
9692-
return MacroDefinition{
9693-
Kind::Expression, ImplementationKind::Missing, def
9694-
};
9699+
return MacroDefinition{ImplementationKind::Missing, def};
96959700
}
96969701

96979702
NominalTypeDecl *

lib/Sema/TypeCheckAttr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
159159
IGNORED_ATTR(Preconcurrency)
160160
IGNORED_ATTR(BackDeploy)
161161
IGNORED_ATTR(Documentation)
162+
IGNORED_ATTR(Expression)
162163
#undef IGNORED_ATTR
163164

164165
void visitAlignmentAttr(AlignmentAttr *attr) {

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,8 @@ namespace {
16251625
UNINTERESTING_ATTR(NoEagerMove)
16261626

16271627
UNINTERESTING_ATTR(RuntimeMetadata)
1628+
1629+
UNINTERESTING_ATTR(Expression)
16281630
#undef UNINTERESTING_ATTR
16291631

16301632
void visitAvailableAttr(AvailableAttr *attr) {

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2000,6 +2000,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
20002000

20012001
if (!MD->getDeclContext()->isModuleScopeContext())
20022002
MD->diagnose(diag::macro_in_nested, MD->getName());
2003+
if (!MD->getMacroContexts())
2004+
MD->diagnose(diag::macro_without_context, MD->getName());
20032005
}
20042006

20052007
void visitMacroExpansionDecl(MacroExpansionDecl *MED) {

lib/Sema/TypeCheckMacros.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,7 @@ MacroDefinition MacroDefinitionRequest::evaluate(
113113
swift_ASTGen_destroyMacro(inProcess);
114114
});
115115

116-
return MacroDefinition::forInProcess(
117-
MacroDefinition::Expression, inProcess);
116+
return MacroDefinition::forInProcess(inProcess);
118117
}
119118
}
120119
#endif

test/IDE/complete_decl_attribute.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ struct _S {
315315
// ON_MEMBER_LAST-DAG: Keyword/None: typeWrapper[#Declaration Attribute#]; name=typeWrapper
316316
// ON_MEMBER_LAST-DAG: Keyword/None: typeWrapperIgnored[#Declaration Attribute#]; name=typeWrapperIgnored
317317
// ON_MEMBER_LAST-DAG: Keyword/None: runtimeMetadata[#Declaration Attribute#]; name=runtimeMetadata
318+
// ON_MEMBER_LAST-DAG: Keyword/None: expression[#Declaration Attribute#]; name=expression
318319
// ON_MEMBER_LAST-NOT: Keyword
319320
// ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
320321
// ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#MyPropertyWrapper#]; name=MyPropertyWrapper
@@ -387,6 +388,7 @@ func dummy2() {}
387388
// KEYWORD_LAST-DAG: Keyword/None: typeWrapper[#Declaration Attribute#]; name=typeWrapper
388389
// KEYWORD_LAST-DAG: Keyword/None: typeWrapperIgnored[#Declaration Attribute#]; name=typeWrapperIgnored
389390
// KEYWORD_LAST-DAG: Keyword/None: runtimeMetadata[#Declaration Attribute#]; name=runtimeMetadata
391+
// KEYWORD_LAST-DAG: Keyword/None: expression[#Declaration Attribute#]; name=expression
390392
// KEYWORD_LAST-NOT: Keyword
391393
// KEYWORD_LAST-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
392394
// KEYWORD_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#MyPropertyWrapper#]; name=MyPropertyWrapper

test/Macros/macro_availability_macosx.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
@available(macOS 12.0, *)
55
struct X { }
66

7-
macro m1: X = A.B // expected-error{{'X' is only available in macOS 12.0 or newer}}
7+
@expression macro m1: X = A.B // expected-error{{'X' is only available in macOS 12.0 or newer}}
88

99
@available(macOS 12.0, *)
10-
macro m2: X = A.B
10+
@expression macro m2: X = A.B

0 commit comments

Comments
 (0)