Skip to content

Commit 56e7cce

Browse files
committed
[Macros] Parse MacroExpansionExpr and MacroExpansionDecl
Introduce `MacroExpansionExpr` and `MacroExpansionDecl` and plumb it through. Parse them in roughly the same way we parse `ObjectLiteralExpr`. The syntax is gated under `-enable-experimental-feature Macros`.
1 parent 82d78a3 commit 56e7cce

34 files changed

+464
-53
lines changed

include/swift/AST/Decl.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ enum class DescriptiveDeclKind : uint8_t {
189189
MissingMember,
190190
Requirement,
191191
OpaqueResultType,
192-
OpaqueVarType
192+
OpaqueVarType,
193+
MacroExpansion
193194
};
194195

195196
/// Describes which spelling was used in the source for the 'static' or 'class'
@@ -8253,6 +8254,33 @@ class MissingMemberDecl : public Decl {
82538254
}
82548255
};
82558256

8257+
class MacroExpansionDecl : public Decl {
8258+
SourceLoc PoundLoc;
8259+
DeclNameRef Macro;
8260+
DeclNameLoc MacroLoc;
8261+
ArgumentList *ArgList;
8262+
Decl *Rewritten;
8263+
8264+
public:
8265+
MacroExpansionDecl(DeclContext *dc, SourceLoc poundLoc, DeclNameRef macro,
8266+
DeclNameLoc macroLoc, ArgumentList *args)
8267+
: Decl(DeclKind::MacroExpansion, dc), PoundLoc(poundLoc),
8268+
Macro(macro), MacroLoc(macroLoc), ArgList(args), Rewritten(nullptr) {}
8269+
8270+
SourceRange getSourceRange() const;
8271+
SourceLoc getLocFromSource() const { return PoundLoc; }
8272+
SourceLoc getPoundLoc() const { return PoundLoc; }
8273+
DeclNameLoc getMacroLoc() const { return MacroLoc; }
8274+
DeclNameRef getMacro() const { return Macro; }
8275+
ArgumentList *getArgs() const { return ArgList; }
8276+
Decl *getRewritten() const { return Rewritten; }
8277+
void setRewritten(Decl *rewritten) { Rewritten = rewritten; }
8278+
8279+
static bool classof(const Decl *D) {
8280+
return D->getKind() == DeclKind::MacroExpansion;
8281+
}
8282+
};
8283+
82568284
/// Find references to the given generic parameter in the type signature of the
82578285
/// given declaration using the given generic signature.
82588286
///

include/swift/AST/DeclNodes.def

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,9 @@ ABSTRACT_DECL(Operator, Decl)
192192
OPERATOR_DECL(PostfixOperator, OperatorDecl)
193193
DECL_RANGE(Operator, InfixOperator, PostfixOperator)
194194

195-
LAST_DECL(PostfixOperator)
195+
DECL(MacroExpansion, Decl)
196+
197+
LAST_DECL(MacroExpansion)
196198

197199
#undef NOMINAL_TYPE_DECL
198200
#undef CONTEXT_DECL

include/swift/AST/DiagnosticsParse.def

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1998,5 +1998,14 @@ ERROR(expected_multiple_closures_block_rbrace,none,
19981998
ERROR(foreign_diagnostic,none,
19991999
"%0", (StringRef))
20002000

2001+
//------------------------------------------------------------------------------
2002+
// MARK: macro expansion
2003+
//------------------------------------------------------------------------------
2004+
2005+
ERROR(macro_expansion_expr_expected_macro_identifier,none,
2006+
"expected a macro identifier for a pound literal expression", ())
2007+
ERROR(macro_expansion_decl_expected_macro_identifier,none,
2008+
"expected a macro identifier for a pound literal declaration", ())
2009+
20012010
#define UNDEFINE_DIAGNOSTIC_MACROS
20022011
#include "DefineDiagnosticMacros.h"

include/swift/AST/Expr.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5952,6 +5952,41 @@ class TypeJoinExpr final : public Expr,
59525952
}
59535953
};
59545954

5955+
class MacroExpansionExpr final : public Expr {
5956+
private:
5957+
Expr *Macro;
5958+
Expr *Rewritten;
5959+
ArgumentList *ArgList;
5960+
SourceLoc PoundLoc;
5961+
5962+
public:
5963+
explicit MacroExpansionExpr(SourceLoc poundLoc, Expr *macro,
5964+
ArgumentList *argList, bool isImplicit = false,
5965+
Type ty = Type())
5966+
: Expr(ExprKind::MacroExpansion, isImplicit, ty), Macro(macro),
5967+
Rewritten(nullptr), ArgList(argList), PoundLoc(poundLoc) {}
5968+
5969+
Expr *getMacro() const { return Macro; }
5970+
void setMacro(Expr *macro) { Macro = macro; }
5971+
5972+
Expr *getRewritten() const { return Rewritten; }
5973+
void setRewritten(Expr *rewritten) { Rewritten = rewritten; }
5974+
5975+
ArgumentList *getArgs() const { return ArgList; }
5976+
void setArgs(ArgumentList *newArgs) { ArgList = newArgs; }
5977+
5978+
SourceLoc getLoc() const { return PoundLoc; }
5979+
5980+
SourceRange getSourceRange() const {
5981+
return SourceRange(
5982+
PoundLoc, ArgList ? ArgList->getEndLoc() : Macro->getEndLoc());
5983+
}
5984+
5985+
static bool classof(const Expr *E) {
5986+
return E->getKind() == ExprKind::MacroExpansion;
5987+
}
5988+
};
5989+
59555990
inline bool Expr::isInfixOperator() const {
59565991
return isa<BinaryExpr>(this) || isa<TernaryExpr>(this) ||
59575992
isa<AssignExpr>(this) || isa<ExplicitCastExpr>(this);

include/swift/AST/ExprNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ UNCHECKED_EXPR(KeyPathDot, Expr)
207207
UNCHECKED_EXPR(OneWay, Expr)
208208
EXPR(Tap, Expr)
209209
UNCHECKED_EXPR(TypeJoin, Expr)
210+
EXPR(MacroExpansion, Expr)
210211
LAST_EXPR(TypeJoin)
211212

212213
#undef EXPR_RANGE

include/swift/Basic/Features.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ EXPERIMENTAL_FEATURE(ImplicitSome)
145145
/// corresponding syntax tree.
146146
EXPERIMENTAL_FEATURE(ParserASTGen)
147147

148+
EXPERIMENTAL_FEATURE(Macros)
149+
148150
#undef EXPERIMENTAL_FEATURE
149151
#undef UPCOMING_FEATURE
150152
#undef SUPPRESSIBLE_LANGUAGE_FEATURE

include/swift/Parse/Parser.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,6 +1306,9 @@ class Parser {
13061306
ParserResult<PrecedenceGroupDecl>
13071307
parseDeclPrecedenceGroup(ParseDeclOptions flags, DeclAttributes &attributes);
13081308

1309+
ParserResult<MacroExpansionDecl>
1310+
parseDeclMacroExpansion(ParseDeclOptions flags, DeclAttributes &attributes);
1311+
13091312
ParserResult<TypeRepr> parseDeclResultType(Diag<> MessageID);
13101313

13111314
/// Get the location for a type error.
@@ -1809,6 +1812,7 @@ class Parser {
18091812
bool isExprBasic);
18101813
ParserResult<Expr> parseExprCallSuffix(ParserResult<Expr> fn,
18111814
bool isExprBasic);
1815+
ParserResult<Expr> parseExprMacroExpansion(bool isExprBasic);
18121816
ParserResult<Expr> parseExprCollection();
18131817
ParserResult<Expr> parseExprCollectionElement(Optional<bool> &isDictionary);
18141818
ParserResult<Expr> parseExprPoundUnknown(SourceLoc LSquareLoc);

lib/AST/ASTDumper.cpp

Lines changed: 82 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,63 @@ static StringRef getAssociativityString(Associativity value) {
308308
llvm_unreachable("Unhandled Associativity in switch.");
309309
}
310310

311+
static void printArgument(raw_ostream &OS, const Argument &arg,
312+
unsigned indentLevel,
313+
std::function<void(Expr *)> printRec) {
314+
OS.indent(indentLevel);
315+
PrintWithColorRAII(OS, ParenthesisColor) << '(';
316+
PrintWithColorRAII(OS, ExprColor) << "argument";
317+
318+
auto label = arg.getLabel();
319+
if (!label.empty()) {
320+
PrintWithColorRAII(OS, ArgumentsColor) << " label=";
321+
PrintWithColorRAII(OS, ArgumentsColor) << label.str();
322+
}
323+
if (arg.isInOut())
324+
PrintWithColorRAII(OS, ArgModifierColor) << " inout";
325+
326+
OS << '\n';
327+
printRec(arg.getExpr());
328+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
329+
}
330+
331+
static void printArgumentList(raw_ostream &OS,
332+
const ArgumentList *argList,
333+
unsigned &indentLevel,
334+
std::function<void(Expr *)> printRec,
335+
bool indent = true) {
336+
if (indent)
337+
indentLevel += 2;
338+
339+
OS.indent(indentLevel);
340+
PrintWithColorRAII(OS, ParenthesisColor) << '(';
341+
PrintWithColorRAII(OS, ExprColor) << "argument_list";
342+
343+
if (argList->isImplicit())
344+
PrintWithColorRAII(OS, ArgModifierColor) << " implicit";
345+
346+
if (argList->hasAnyArgumentLabels()) {
347+
PrintWithColorRAII(OS, ArgumentsColor) << " labels=";
348+
for (auto arg : *argList) {
349+
auto label = arg.getLabel();
350+
PrintWithColorRAII(OS, ArgumentsColor)
351+
<< (label.empty() ? "_" : label.str()) << ":";
352+
}
353+
}
354+
355+
indentLevel += 2;
356+
for (auto arg : *argList) {
357+
OS << '\n';
358+
printArgument(OS, arg, indentLevel, printRec);
359+
}
360+
indentLevel -= 2;
361+
362+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
363+
364+
if (indent)
365+
indentLevel -= 2;
366+
}
367+
311368
//===----------------------------------------------------------------------===//
312369
// Decl printing.
313370
//===----------------------------------------------------------------------===//
@@ -1246,6 +1303,18 @@ namespace {
12461303
<< '\"' << MMD->getName() << '\"';
12471304
PrintWithColorRAII(OS, ParenthesisColor) << ')';
12481305
}
1306+
1307+
void visitMacroExpansionDecl(MacroExpansionDecl *MED) {
1308+
printCommon(MED, "macro_expansion_decl ");
1309+
OS << MED->getMacro();
1310+
if (MED->getArgs()) {
1311+
OS << '\n';
1312+
OS.indent(Indent + 2);
1313+
printArgumentList(OS, MED->getArgs(), Indent,
1314+
[&](Expr *E) { printRec(E); });
1315+
}
1316+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
1317+
}
12491318
};
12501319
} // end anonymous namespace
12511320

@@ -1258,8 +1327,6 @@ void ParameterList::dump(raw_ostream &OS, unsigned Indent) const {
12581327
llvm::errs() << '\n';
12591328
}
12601329

1261-
1262-
12631330
void Decl::dump() const {
12641331
dump(llvm::errs(), 0);
12651332
}
@@ -2574,55 +2641,9 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
25742641
PrintWithColorRAII(OS, ParenthesisColor) << ')';
25752642
}
25762643

2577-
void printArgument(const Argument &arg) {
2578-
OS.indent(Indent);
2579-
PrintWithColorRAII(OS, ParenthesisColor) << '(';
2580-
PrintWithColorRAII(OS, ExprColor) << "argument";
2581-
2582-
auto label = arg.getLabel();
2583-
if (!label.empty()) {
2584-
PrintWithColorRAII(OS, ArgumentsColor) << " label=";
2585-
PrintWithColorRAII(OS, ArgumentsColor) << label.str();
2586-
}
2587-
if (arg.isInOut())
2588-
PrintWithColorRAII(OS, ArgModifierColor) << " inout";
2589-
2590-
OS << '\n';
2591-
printRec(arg.getExpr());
2592-
PrintWithColorRAII(OS, ParenthesisColor) << ')';
2593-
}
2594-
25952644
void printArgumentList(const ArgumentList *argList, bool indent = true) {
2596-
if (indent)
2597-
Indent += 2;
2598-
2599-
OS.indent(Indent);
2600-
PrintWithColorRAII(OS, ParenthesisColor) << '(';
2601-
PrintWithColorRAII(OS, ExprColor) << "argument_list";
2602-
2603-
if (argList->isImplicit())
2604-
PrintWithColorRAII(OS, ArgModifierColor) << " implicit";
2605-
2606-
if (argList->hasAnyArgumentLabels()) {
2607-
PrintWithColorRAII(OS, ArgumentsColor) << " labels=";
2608-
for (auto arg : *argList) {
2609-
auto label = arg.getLabel();
2610-
PrintWithColorRAII(OS, ArgumentsColor)
2611-
<< (label.empty() ? "_" : label.str()) << ":";
2612-
}
2613-
}
2614-
2615-
Indent += 2;
2616-
for (auto arg : *argList) {
2617-
OS << '\n';
2618-
printArgument(arg);
2619-
}
2620-
Indent -= 2;
2621-
2622-
PrintWithColorRAII(OS, ParenthesisColor) << ')';
2623-
2624-
if (indent)
2625-
Indent -= 2;
2645+
::printArgumentList(OS, argList, Indent, [&](Expr *E) { printRec(E); },
2646+
indent);
26262647
}
26272648

26282649
void printApplyExpr(ApplyExpr *E, const char *NodeName) {
@@ -2952,6 +2973,17 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
29522973

29532974
PrintWithColorRAII(OS, ParenthesisColor) << ')';
29542975
}
2976+
2977+
void visitMacroExpansionExpr(MacroExpansionExpr *E) {
2978+
printCommon(E, "macro_expansion_expr");
2979+
OS << '\n';
2980+
printRec(E->getMacro());
2981+
if (E->getArgs()) {
2982+
OS << '\n';
2983+
printArgumentList(E->getArgs());
2984+
}
2985+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
2986+
}
29552987
};
29562988

29572989
} // end anonymous namespace

lib/AST/ASTPrinter.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2733,6 +2733,10 @@ static bool usesFeatureActors(Decl *decl) {
27332733
return false;
27342734
}
27352735

2736+
static bool usesFeatureMacros(Decl *decl) {
2737+
return isa<MacroExpansionDecl>(decl);
2738+
}
2739+
27362740
static bool usesFeatureConcurrentFunctions(Decl *decl) {
27372741
return false;
27382742
}
@@ -4429,6 +4433,24 @@ void PrintAST::visitMissingMemberDecl(MissingMemberDecl *decl) {
44294433
Printer << " */";
44304434
}
44314435

4436+
void PrintAST::visitMacroExpansionDecl(MacroExpansionDecl *decl) {
4437+
Printer << '#' << decl->getMacro();
4438+
if (decl->getArgs()) {
4439+
Printer << '(';
4440+
auto args = decl->getArgs()->getOriginalArgs();
4441+
bool isFirst = true;
4442+
// FIXME: handle trailing closures.
4443+
for (auto arg : *args) {
4444+
if (!isFirst) {
4445+
Printer << ", ";
4446+
}
4447+
printArgument(arg);
4448+
isFirst = false;
4449+
}
4450+
Printer << ')';
4451+
}
4452+
}
4453+
44324454
void PrintAST::visitIntegerLiteralExpr(IntegerLiteralExpr *expr) {
44334455
Printer << expr->getDigitsText();
44344456
}
@@ -4911,6 +4933,9 @@ void PrintAST::visitPropertyWrapperValuePlaceholderExpr(swift::PropertyWrapperVa
49114933
void PrintAST::visitDifferentiableFunctionExtractOriginalExpr(swift::DifferentiableFunctionExtractOriginalExpr *expr) {
49124934
}
49134935

4936+
void PrintAST::visitMacroExpansionExpr(MacroExpansionExpr *expr) {
4937+
}
4938+
49144939
void PrintAST::visitBraceStmt(BraceStmt *stmt) {
49154940
printBraceStmt(stmt);
49164941
}

lib/AST/ASTScopeCreation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ class NodeAdder
282282
VISIT_AND_IGNORE(ParamDecl)
283283
VISIT_AND_IGNORE(PoundDiagnosticDecl)
284284
VISIT_AND_IGNORE(MissingMemberDecl)
285+
VISIT_AND_IGNORE(MacroExpansionDecl)
285286

286287
// Only members of the active clause are in scope, and those
287288
// are visited separately.

0 commit comments

Comments
 (0)