Skip to content

Commit 89bda71

Browse files
authored
Merge pull request #69840 from DougGregor/macro-role-metaprogramming
[Macros] Macro-metaprogram macro roles
2 parents 4557ed6 + ffa5ba7 commit 89bda71

File tree

18 files changed

+237
-340
lines changed

18 files changed

+237
-340
lines changed

include/swift/AST/MacroDeclaration.h

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -32,37 +32,17 @@ enum class MacroSyntax: uint8_t {
3232
Attached,
3333
};
3434

35+
enum class MacroRoleBits: uint8_t {
36+
#define MACRO_ROLE(Name, Description) Name,
37+
#include "swift/Basic/MacroRoles.def"
38+
};
39+
3540
/// The context in which a macro can be used, which determines the syntax it
3641
/// uses.
3742
enum class MacroRole: uint32_t {
38-
/// An expression macro, referenced explicitly via "#stringify" or similar
39-
/// in the source code.
40-
Expression = 0x01,
41-
/// A freestanding declaration macro.
42-
Declaration = 0x02,
43-
/// An attached macro that declares accessors for a variable or subscript
44-
/// declaration.
45-
Accessor = 0x04,
46-
/// An attached macro that generates attributes for the
47-
/// members inside the declaration.
48-
MemberAttribute = 0x08,
49-
/// An attached macro that generates synthesized members
50-
/// inside the declaration.
51-
Member = 0x10,
52-
/// An attached macro that generates declarations that are peers
53-
/// of the declaration the macro is attached to.
54-
Peer = 0x20,
55-
/// An attached macro that adds conformances to the declaration the
56-
/// macro is attached to.
57-
Conformance = 0x40,
58-
/// A freestanding macro that expands to expressions, statements and
59-
/// declarations in a code block.
60-
CodeItem = 0x80,
61-
/// An attached macro that adds extensions to the declaration the
62-
/// macro is attached to.
63-
Extension = 0x100,
64-
65-
// NOTE: When adding a new macro role, also add it to `getAllMacroRoles`.
43+
#define MACRO_ROLE(Name, Description) \
44+
Name = 1 << static_cast<uint8_t>(MacroRoleBits::Name),
45+
#include "swift/Basic/MacroRoles.def"
6646
};
6747

6848
/// Returns an enumeratable list of all macro roles.

include/swift/Basic/MacroRoles.def

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//===--- MacroRoles.def - Known macro roles --*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 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+
// This file defines all of the kinds of macro roles. Clients should define
14+
// either MACRO_ROLE or both ATTACHED_MACRO_ROLE and FREESTANDING_MACRO_ROLE.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef ATTACHED_MACRO_ROLE
19+
# define ATTACHED_MACRO_ROLE(Name, Description) MACRO_ROLE(Name, Description)
20+
#endif
21+
22+
#ifndef FREESTANDING_MACRO_ROLE
23+
# define FREESTANDING_MACRO_ROLE(Name, Description) MACRO_ROLE(Name, Description)
24+
#endif
25+
26+
#ifndef EXPERIMENTAL_ATTACHED_MACRO_ROLE
27+
# define EXPERIMENTAL_ATTACHED_MACRO_ROLE(Name, Description, Feature) \
28+
ATTACHED_MACRO_ROLE(Name, Description)
29+
#endif
30+
31+
#ifndef EXPERIMENTAL_FREESTANDING_MACRO_ROLE
32+
# define EXPERIMENTAL_FREESTANDING_MACRO_ROLE(Name, Description, Feature) \
33+
FREESTANDING_MACRO_ROLE(Name, Description)
34+
#endif
35+
36+
/// An expression macro, referenced explicitly via "#stringify" or similar
37+
/// in the source code.
38+
FREESTANDING_MACRO_ROLE(Expression, "expression")
39+
40+
/// A freestanding declaration macro.
41+
FREESTANDING_MACRO_ROLE(Declaration, "declaration")
42+
43+
44+
/// An attached macro that declares accessors for a variable or subscript
45+
/// declaration.
46+
ATTACHED_MACRO_ROLE(Accessor, "accessor")
47+
48+
/// An attached macro that generates attributes for the
49+
/// members inside the declaration.
50+
ATTACHED_MACRO_ROLE(MemberAttribute, "memberAttribute")
51+
52+
/// An attached macro that generates synthesized members
53+
/// inside the declaration.
54+
ATTACHED_MACRO_ROLE(Member, "member")
55+
56+
/// An attached macro that generates declarations that are peers
57+
/// of the declaration the macro is attached to.
58+
ATTACHED_MACRO_ROLE(Peer, "peer")
59+
60+
/// An attached macro that adds conformances to the declaration the
61+
/// macro is attached to.
62+
ATTACHED_MACRO_ROLE(Conformance, "conformance")
63+
64+
/// A freestanding macro that expands to expressions, statements and
65+
/// declarations in a code block.
66+
EXPERIMENTAL_FREESTANDING_MACRO_ROLE(CodeItem, "codeItem", CodeItemMacros)
67+
68+
/// An attached macro that adds extensions to the declaration the
69+
/// macro is attached to.
70+
ATTACHED_MACRO_ROLE(Extension, "extension")
71+
72+
#undef ATTACHED_MACRO_ROLE
73+
#undef FREESTANDING_MACRO_ROLE
74+
#undef EXPERIMENTAL_ATTACHED_MACRO_ROLE
75+
#undef EXPERIMENTAL_FREESTANDING_MACRO_ROLE
76+
77+
#ifdef MACRO_ROLE
78+
# undef MACRO_ROLE
79+
#endif

include/swift/Basic/SourceManager.h

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,29 +34,8 @@ class GeneratedSourceInfo {
3434
public:
3535
/// The kind of generated source code.
3636
enum Kind {
37-
/// The expansion of a freestanding expression macro.
38-
ExpressionMacroExpansion,
39-
40-
/// The expansion of a freestanding declaration macro.
41-
FreestandingDeclMacroExpansion,
42-
43-
/// The expansion of an accessor attached macro.
44-
AccessorMacroExpansion,
45-
46-
/// The expansion of a member attribute attached macro.
47-
MemberAttributeMacroExpansion,
48-
49-
/// The expansion of an attached member macro.
50-
MemberMacroExpansion,
51-
52-
/// The expansion of an attached peer macro.
53-
PeerMacroExpansion,
54-
55-
/// The expansion of an attached conformance macro.
56-
ConformanceMacroExpansion,
57-
58-
/// The expansion of an attached extension macro.
59-
ExtensionMacroExpansion,
37+
#define MACRO_ROLE(Name, Description) Name##MacroExpansion,
38+
#include "swift/Basic/MacroRoles.def"
6039

6140
/// A new function body that is replacing an existing function body.
6241
ReplacedFunctionBody,

lib/AST/ASTMangler.cpp

Lines changed: 30 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3873,80 +3873,54 @@ void ASTMangler::appendMacroExpansionContext(
38733873
DeclContext *outerExpansionDC;
38743874
DeclBaseName baseName;
38753875
unsigned discriminator;
3876+
3877+
// Determine the macro role.
38763878
MacroRole role;
38773879
switch (generatedSourceInfo->kind) {
3878-
case GeneratedSourceInfo::ExpressionMacroExpansion: {
3880+
#define MACRO_ROLE(Name, Description) \
3881+
case GeneratedSourceInfo::Name##MacroExpansion: \
3882+
role = MacroRole::Name; \
3883+
break;
3884+
#include "swift/Basic/MacroRoles.def"
3885+
3886+
case GeneratedSourceInfo::PrettyPrinted:
3887+
case GeneratedSourceInfo::ReplacedFunctionBody:
3888+
return appendContext(origDC, StringRef());
3889+
}
3890+
3891+
switch (generatedSourceInfo->kind) {
3892+
// Freestanding macros
3893+
#define FREESTANDING_MACRO_ROLE(Name, Description) \
3894+
case GeneratedSourceInfo::Name##MacroExpansion:
3895+
#define ATTACHED_MACRO_ROLE(Name, Description)
3896+
#include "swift/Basic/MacroRoles.def"
3897+
{
38793898
auto parent = ASTNode::getFromOpaqueValue(generatedSourceInfo->astNode);
38803899
if (auto expr =
38813900
cast_or_null<MacroExpansionExpr>(parent.dyn_cast<Expr *>())) {
38823901
outerExpansionLoc = expr->getLoc();
38833902
baseName = expr->getMacroName().getBaseName();
38843903
discriminator = expr->getDiscriminator();
3885-
role = MacroRole::Expression;
38863904
outerExpansionDC = expr->getDeclContext();
38873905
} else {
38883906
auto decl = cast<MacroExpansionDecl>(parent.get<Decl *>());
38893907
outerExpansionLoc = decl->getLoc();
38903908
baseName = decl->getMacroName().getBaseName();
38913909
discriminator = decl->getDiscriminator();
3892-
role = MacroRole::Declaration;
38933910
outerExpansionDC = decl->getDeclContext();
38943911
}
38953912
break;
38963913
}
38973914

3898-
case GeneratedSourceInfo::FreestandingDeclMacroExpansion: {
3899-
auto expansion =
3900-
cast<MacroExpansionDecl>(
3901-
ASTNode::getFromOpaqueValue(generatedSourceInfo->astNode)
3902-
.get<Decl *>());
3903-
outerExpansionLoc = expansion->getLoc();
3904-
outerExpansionDC = expansion->getDeclContext();
3905-
discriminator = expansion->getDiscriminator();
3906-
role = MacroRole::Declaration;
3907-
baseName = expansion->getMacroName().getBaseName();
3908-
break;
3909-
}
3910-
3911-
case GeneratedSourceInfo::AccessorMacroExpansion:
3912-
case GeneratedSourceInfo::MemberAttributeMacroExpansion:
3913-
case GeneratedSourceInfo::MemberMacroExpansion:
3914-
case GeneratedSourceInfo::PeerMacroExpansion:
3915-
case GeneratedSourceInfo::ConformanceMacroExpansion:
3916-
case GeneratedSourceInfo::ExtensionMacroExpansion: {
3915+
// Attached macros
3916+
#define FREESTANDING_MACRO_ROLE(Name, Description)
3917+
#define ATTACHED_MACRO_ROLE(Name, Description) \
3918+
case GeneratedSourceInfo::Name##MacroExpansion:
3919+
#include "swift/Basic/MacroRoles.def"
3920+
{
39173921
auto decl = ASTNode::getFromOpaqueValue(generatedSourceInfo->astNode)
39183922
.get<Decl *>();
39193923
auto attr = generatedSourceInfo->attachedMacroCustomAttr;
3920-
3921-
switch (generatedSourceInfo->kind) {
3922-
case GeneratedSourceInfo::AccessorMacroExpansion:
3923-
role = MacroRole::Accessor;
3924-
break;
3925-
3926-
case GeneratedSourceInfo::MemberAttributeMacroExpansion:
3927-
role = MacroRole::MemberAttribute;
3928-
break;
3929-
3930-
case GeneratedSourceInfo::MemberMacroExpansion:
3931-
role = MacroRole::Member;
3932-
break;
3933-
3934-
case GeneratedSourceInfo::PeerMacroExpansion:
3935-
role = MacroRole::Peer;
3936-
break;
3937-
3938-
case GeneratedSourceInfo::ConformanceMacroExpansion:
3939-
role = MacroRole::Conformance;
3940-
break;
3941-
3942-
case GeneratedSourceInfo::ExtensionMacroExpansion:
3943-
role = MacroRole::Extension;
3944-
break;
3945-
3946-
default:
3947-
llvm_unreachable("Unhandled macro role");
3948-
}
3949-
39503924
outerExpansionLoc = decl->getLoc();
39513925
outerExpansionDC = decl->getDeclContext();
39523926

@@ -3956,13 +3930,12 @@ void ASTMangler::appendMacroExpansionContext(
39563930
baseName = ctx.getIdentifier("__unknown_macro__");
39573931

39583932
discriminator = decl->getAttachedMacroDiscriminator(baseName, role, attr);
3959-
39603933
break;
39613934
}
39623935

39633936
case GeneratedSourceInfo::PrettyPrinted:
39643937
case GeneratedSourceInfo::ReplacedFunctionBody:
3965-
return appendContext(origDC, StringRef());
3938+
llvm_unreachable("Exited above");
39663939
}
39673940

39683941
// If we hit the point where the structure is represented as a DeclContext,
@@ -3982,9 +3955,9 @@ void ASTMangler::appendMacroExpansionOperator(
39823955
appendIdentifier(macroName);
39833956

39843957
switch (role) {
3985-
case MacroRole::Expression:
3986-
case MacroRole::Declaration:
3987-
case MacroRole::CodeItem:
3958+
#define FREESTANDING_MACRO_ROLE(Name, Description) case MacroRole::Name:
3959+
#define ATTACHED_MACRO_ROLE(Name, Description)
3960+
#include "swift/Basic/MacroRoles.def"
39883961
appendOperator("fMf", Index(discriminator));
39893962
break;
39903963

0 commit comments

Comments
 (0)