Skip to content

Commit 530bd69

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 530bd69

34 files changed

+432
-53
lines changed

include/swift/AST/Decl.h

Lines changed: 27 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,31 @@ class MissingMemberDecl : public Decl {
82538254
}
82548255
};
82558256

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

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: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5952,6 +5952,40 @@ 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(PoundLoc, ArgList->getEndLoc());
5982+
}
5983+
5984+
static bool classof(const Expr *E) {
5985+
return E->getKind() == ExprKind::MacroExpansion;
5986+
}
5987+
};
5988+
59555989
inline bool Expr::isInfixOperator() const {
59565990
return isa<BinaryExpr>(this) || isa<TernaryExpr>(this) ||
59575991
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: 77 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,15 @@ 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() << '\n';
1310+
OS.indent(Indent + 2);
1311+
printArgumentList(OS, MED->getArgs(), Indent,
1312+
[&](Expr *E) { printRec(E); });
1313+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
1314+
}
12491315
};
12501316
} // end anonymous namespace
12511317

@@ -1258,8 +1324,6 @@ void ParameterList::dump(raw_ostream &OS, unsigned Indent) const {
12581324
llvm::errs() << '\n';
12591325
}
12601326

1261-
1262-
12631327
void Decl::dump() const {
12641328
dump(llvm::errs(), 0);
12651329
}
@@ -2574,55 +2638,9 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
25742638
PrintWithColorRAII(OS, ParenthesisColor) << ')';
25752639
}
25762640

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-
25952641
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;
2642+
::printArgumentList(OS, argList, Indent, [&](Expr *E) { printRec(E); },
2643+
indent);
26262644
}
26272645

26282646
void printApplyExpr(ApplyExpr *E, const char *NodeName) {
@@ -2952,6 +2970,15 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
29522970

29532971
PrintWithColorRAII(OS, ParenthesisColor) << ')';
29542972
}
2973+
2974+
void visitMacroExpansionExpr(MacroExpansionExpr *E) {
2975+
printCommon(E, "macro_expansion_expr");
2976+
OS << '\n';
2977+
printRec(E->getMacro());
2978+
OS << '\n';
2979+
printArgumentList(E->getArgs());
2980+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
2981+
}
29552982
};
29562983

29572984
} // end anonymous namespace

lib/AST/ASTPrinter.cpp

Lines changed: 22 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,21 @@ void PrintAST::visitMissingMemberDecl(MissingMemberDecl *decl) {
44294433
Printer << " */";
44304434
}
44314435

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

4933+
void PrintAST::visitMacroExpansionExpr(MacroExpansionExpr *expr) {
4934+
}
4935+
49144936
void PrintAST::visitBraceStmt(BraceStmt *stmt) {
49154937
printBraceStmt(stmt);
49164938
}

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.

lib/AST/ASTWalker.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,12 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
401401
return false;
402402
}
403403

404+
bool visitMacroExpansionDecl(MacroExpansionDecl *MED) {
405+
if (doIt(MED->getArgs()))
406+
return true;
407+
return false;
408+
}
409+
404410
bool visitAbstractFunctionDecl(AbstractFunctionDecl *AFD) {
405411
#ifndef NDEBUG
406412
PrettyStackTraceDecl debugStack("walking into body of", AFD);
@@ -1238,6 +1244,22 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
12381244
return E;
12391245
}
12401246

1247+
Expr *visitMacroExpansionExpr(MacroExpansionExpr *E) {
1248+
auto *macro = doIt(E->getMacro());
1249+
if (!macro) return nullptr;
1250+
Expr *rewritten = nullptr;
1251+
if (E->getRewritten()) {
1252+
rewritten = doIt(E->getRewritten());
1253+
if (!rewritten) return nullptr;
1254+
}
1255+
auto *args = doIt(E->getArgs());
1256+
if (!args) return nullptr;
1257+
E->setMacro(macro);
1258+
E->setRewritten(rewritten);
1259+
E->setArgs(args);
1260+
return E;
1261+
}
1262+
12411263
//===--------------------------------------------------------------------===//
12421264
// Everything Else
12431265
//===--------------------------------------------------------------------===//

0 commit comments

Comments
 (0)