Skip to content

[Macros] Parse MacroExpansionExpr and MacroExpansionDecl #61662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ enum class DescriptiveDeclKind : uint8_t {
MissingMember,
Requirement,
OpaqueResultType,
OpaqueVarType
OpaqueVarType,
MacroExpansion
};

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

class MacroExpansionDecl : public Decl {
SourceLoc PoundLoc;
DeclNameRef Macro;
DeclNameLoc MacroLoc;
ArgumentList *ArgList;
Decl *Rewritten;

public:
MacroExpansionDecl(DeclContext *dc, SourceLoc poundLoc, DeclNameRef macro,
DeclNameLoc macroLoc, ArgumentList *args)
: Decl(DeclKind::MacroExpansion, dc), PoundLoc(poundLoc),
Macro(macro), MacroLoc(macroLoc), ArgList(args), Rewritten(nullptr) {}

SourceRange getSourceRange() const;
SourceLoc getLocFromSource() const { return PoundLoc; }
SourceLoc getPoundLoc() const { return PoundLoc; }
DeclNameLoc getMacroLoc() const { return MacroLoc; }
DeclNameRef getMacro() const { return Macro; }
ArgumentList *getArgs() const { return ArgList; }
Decl *getRewritten() const { return Rewritten; }
void setRewritten(Decl *rewritten) { Rewritten = rewritten; }

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

/// Find references to the given generic parameter in the type signature of the
/// given declaration using the given generic signature.
///
Expand Down
4 changes: 3 additions & 1 deletion include/swift/AST/DeclNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,9 @@ ABSTRACT_DECL(Operator, Decl)
OPERATOR_DECL(PostfixOperator, OperatorDecl)
DECL_RANGE(Operator, InfixOperator, PostfixOperator)

LAST_DECL(PostfixOperator)
DECL(MacroExpansion, Decl)

LAST_DECL(MacroExpansion)

#undef NOMINAL_TYPE_DECL
#undef CONTEXT_DECL
Expand Down
9 changes: 9 additions & 0 deletions include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -1998,5 +1998,14 @@ ERROR(expected_multiple_closures_block_rbrace,none,
ERROR(foreign_diagnostic,none,
"%0", (StringRef))

//------------------------------------------------------------------------------
// MARK: macro expansion
//------------------------------------------------------------------------------

ERROR(macro_expansion_expr_expected_macro_identifier,none,
"expected a macro identifier for a pound literal expression", ())
ERROR(macro_expansion_decl_expected_macro_identifier,none,
"expected a macro identifier for a pound literal declaration", ())

#define UNDEFINE_DIAGNOSTIC_MACROS
#include "DefineDiagnosticMacros.h"
35 changes: 35 additions & 0 deletions include/swift/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -5952,6 +5952,41 @@ class TypeJoinExpr final : public Expr,
}
};

class MacroExpansionExpr final : public Expr {
private:
Expr *Macro;
Expr *Rewritten;
ArgumentList *ArgList;
SourceLoc PoundLoc;

public:
explicit MacroExpansionExpr(SourceLoc poundLoc, Expr *macro,
ArgumentList *argList, bool isImplicit = false,
Type ty = Type())
: Expr(ExprKind::MacroExpansion, isImplicit, ty), Macro(macro),
Rewritten(nullptr), ArgList(argList), PoundLoc(poundLoc) {}

Expr *getMacro() const { return Macro; }
void setMacro(Expr *macro) { Macro = macro; }

Expr *getRewritten() const { return Rewritten; }
void setRewritten(Expr *rewritten) { Rewritten = rewritten; }

ArgumentList *getArgs() const { return ArgList; }
void setArgs(ArgumentList *newArgs) { ArgList = newArgs; }

SourceLoc getLoc() const { return PoundLoc; }

SourceRange getSourceRange() const {
return SourceRange(
PoundLoc, ArgList ? ArgList->getEndLoc() : Macro->getEndLoc());
}

static bool classof(const Expr *E) {
return E->getKind() == ExprKind::MacroExpansion;
}
};

inline bool Expr::isInfixOperator() const {
return isa<BinaryExpr>(this) || isa<TernaryExpr>(this) ||
isa<AssignExpr>(this) || isa<ExplicitCastExpr>(this);
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/ExprNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ UNCHECKED_EXPR(KeyPathDot, Expr)
UNCHECKED_EXPR(OneWay, Expr)
EXPR(Tap, Expr)
UNCHECKED_EXPR(TypeJoin, Expr)
EXPR(MacroExpansion, Expr)
LAST_EXPR(TypeJoin)

#undef EXPR_RANGE
Expand Down
2 changes: 2 additions & 0 deletions include/swift/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ EXPERIMENTAL_FEATURE(ImplicitSome)
/// corresponding syntax tree.
EXPERIMENTAL_FEATURE(ParserASTGen)

EXPERIMENTAL_FEATURE(Macros)

#undef EXPERIMENTAL_FEATURE
#undef UPCOMING_FEATURE
#undef SUPPRESSIBLE_LANGUAGE_FEATURE
Expand Down
4 changes: 4 additions & 0 deletions include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,9 @@ class Parser {
ParserResult<PrecedenceGroupDecl>
parseDeclPrecedenceGroup(ParseDeclOptions flags, DeclAttributes &attributes);

ParserResult<MacroExpansionDecl>
parseDeclMacroExpansion(ParseDeclOptions flags, DeclAttributes &attributes);

ParserResult<TypeRepr> parseDeclResultType(Diag<> MessageID);

/// Get the location for a type error.
Expand Down Expand Up @@ -1809,6 +1812,7 @@ class Parser {
bool isExprBasic);
ParserResult<Expr> parseExprCallSuffix(ParserResult<Expr> fn,
bool isExprBasic);
ParserResult<Expr> parseExprMacroExpansion(bool isExprBasic);
ParserResult<Expr> parseExprCollection();
ParserResult<Expr> parseExprCollectionElement(Optional<bool> &isDictionary);
ParserResult<Expr> parseExprPoundUnknown(SourceLoc LSquareLoc);
Expand Down
132 changes: 82 additions & 50 deletions lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,63 @@ static StringRef getAssociativityString(Associativity value) {
llvm_unreachable("Unhandled Associativity in switch.");
}

static void printArgument(raw_ostream &OS, const Argument &arg,
unsigned indentLevel,
std::function<void(Expr *)> printRec) {
OS.indent(indentLevel);
PrintWithColorRAII(OS, ParenthesisColor) << '(';
PrintWithColorRAII(OS, ExprColor) << "argument";

auto label = arg.getLabel();
if (!label.empty()) {
PrintWithColorRAII(OS, ArgumentsColor) << " label=";
PrintWithColorRAII(OS, ArgumentsColor) << label.str();
}
if (arg.isInOut())
PrintWithColorRAII(OS, ArgModifierColor) << " inout";

OS << '\n';
printRec(arg.getExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

static void printArgumentList(raw_ostream &OS,
const ArgumentList *argList,
unsigned &indentLevel,
std::function<void(Expr *)> printRec,
bool indent = true) {
if (indent)
indentLevel += 2;

OS.indent(indentLevel);
PrintWithColorRAII(OS, ParenthesisColor) << '(';
PrintWithColorRAII(OS, ExprColor) << "argument_list";

if (argList->isImplicit())
PrintWithColorRAII(OS, ArgModifierColor) << " implicit";

if (argList->hasAnyArgumentLabels()) {
PrintWithColorRAII(OS, ArgumentsColor) << " labels=";
for (auto arg : *argList) {
auto label = arg.getLabel();
PrintWithColorRAII(OS, ArgumentsColor)
<< (label.empty() ? "_" : label.str()) << ":";
}
}

indentLevel += 2;
for (auto arg : *argList) {
OS << '\n';
printArgument(OS, arg, indentLevel, printRec);
}
indentLevel -= 2;

PrintWithColorRAII(OS, ParenthesisColor) << ')';

if (indent)
indentLevel -= 2;
}

//===----------------------------------------------------------------------===//
// Decl printing.
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1246,6 +1303,18 @@ namespace {
<< '\"' << MMD->getName() << '\"';
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

void visitMacroExpansionDecl(MacroExpansionDecl *MED) {
printCommon(MED, "macro_expansion_decl ");
OS << MED->getMacro();
if (MED->getArgs()) {
OS << '\n';
OS.indent(Indent + 2);
printArgumentList(OS, MED->getArgs(), Indent,
[&](Expr *E) { printRec(E); });
}
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
};
} // end anonymous namespace

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



void Decl::dump() const {
dump(llvm::errs(), 0);
}
Expand Down Expand Up @@ -2574,55 +2641,9 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

void printArgument(const Argument &arg) {
OS.indent(Indent);
PrintWithColorRAII(OS, ParenthesisColor) << '(';
PrintWithColorRAII(OS, ExprColor) << "argument";

auto label = arg.getLabel();
if (!label.empty()) {
PrintWithColorRAII(OS, ArgumentsColor) << " label=";
PrintWithColorRAII(OS, ArgumentsColor) << label.str();
}
if (arg.isInOut())
PrintWithColorRAII(OS, ArgModifierColor) << " inout";

OS << '\n';
printRec(arg.getExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

void printArgumentList(const ArgumentList *argList, bool indent = true) {
if (indent)
Indent += 2;

OS.indent(Indent);
PrintWithColorRAII(OS, ParenthesisColor) << '(';
PrintWithColorRAII(OS, ExprColor) << "argument_list";

if (argList->isImplicit())
PrintWithColorRAII(OS, ArgModifierColor) << " implicit";

if (argList->hasAnyArgumentLabels()) {
PrintWithColorRAII(OS, ArgumentsColor) << " labels=";
for (auto arg : *argList) {
auto label = arg.getLabel();
PrintWithColorRAII(OS, ArgumentsColor)
<< (label.empty() ? "_" : label.str()) << ":";
}
}

Indent += 2;
for (auto arg : *argList) {
OS << '\n';
printArgument(arg);
}
Indent -= 2;

PrintWithColorRAII(OS, ParenthesisColor) << ')';

if (indent)
Indent -= 2;
::printArgumentList(OS, argList, Indent, [&](Expr *E) { printRec(E); },
indent);
}

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

PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

void visitMacroExpansionExpr(MacroExpansionExpr *E) {
printCommon(E, "macro_expansion_expr");
OS << '\n';
printRec(E->getMacro());
if (E->getArgs()) {
OS << '\n';
printArgumentList(E->getArgs());
}
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
};

} // end anonymous namespace
Expand Down
25 changes: 25 additions & 0 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2733,6 +2733,10 @@ static bool usesFeatureActors(Decl *decl) {
return false;
}

static bool usesFeatureMacros(Decl *decl) {
return isa<MacroExpansionDecl>(decl);
}

static bool usesFeatureConcurrentFunctions(Decl *decl) {
return false;
}
Expand Down Expand Up @@ -4429,6 +4433,24 @@ void PrintAST::visitMissingMemberDecl(MissingMemberDecl *decl) {
Printer << " */";
}

void PrintAST::visitMacroExpansionDecl(MacroExpansionDecl *decl) {
Printer << '#' << decl->getMacro();
if (decl->getArgs()) {
Printer << '(';
auto args = decl->getArgs()->getOriginalArgs();
bool isFirst = true;
// FIXME: handle trailing closures.
for (auto arg : *args) {
if (!isFirst) {
Printer << ", ";
}
printArgument(arg);
isFirst = false;
}
Printer << ')';
}
}

void PrintAST::visitIntegerLiteralExpr(IntegerLiteralExpr *expr) {
Printer << expr->getDigitsText();
}
Expand Down Expand Up @@ -4911,6 +4933,9 @@ void PrintAST::visitPropertyWrapperValuePlaceholderExpr(swift::PropertyWrapperVa
void PrintAST::visitDifferentiableFunctionExtractOriginalExpr(swift::DifferentiableFunctionExtractOriginalExpr *expr) {
}

void PrintAST::visitMacroExpansionExpr(MacroExpansionExpr *expr) {
}

void PrintAST::visitBraceStmt(BraceStmt *stmt) {
printBraceStmt(stmt);
}
Expand Down
1 change: 1 addition & 0 deletions lib/AST/ASTScopeCreation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ class NodeAdder
VISIT_AND_IGNORE(ParamDecl)
VISIT_AND_IGNORE(PoundDiagnosticDecl)
VISIT_AND_IGNORE(MissingMemberDecl)
VISIT_AND_IGNORE(MacroExpansionDecl)

// Only members of the active clause are in scope, and those
// are visited separately.
Expand Down
Loading