Skip to content

Commit 3407d35

Browse files
committed
[Macros] Parse macro declarations fully, and treat them as normal declarations
1 parent 4582317 commit 3407d35

32 files changed

+416
-419
lines changed

include/swift/AST/ASTScope.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,35 @@ class EnumElementScope : public ASTScopeImpl {
11871187
void expandAScopeThatDoesNotCreateANewInsertionPoint(ScopeCreator &);
11881188
};
11891189

1190+
class MacroDeclScope final : public ASTScopeImpl {
1191+
public:
1192+
MacroDecl *const decl;
1193+
1194+
MacroDeclScope(MacroDecl *e) : decl(e) {}
1195+
virtual ~MacroDeclScope() {}
1196+
1197+
protected:
1198+
ASTScopeImpl *expandSpecifically(ScopeCreator &scopeCreator) override;
1199+
1200+
private:
1201+
void expandAScopeThatDoesNotCreateANewInsertionPoint(ScopeCreator &);
1202+
1203+
public:
1204+
std::string getClassName() const override;
1205+
SourceRange
1206+
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
1207+
1208+
protected:
1209+
void printSpecifics(llvm::raw_ostream &out) const override;
1210+
1211+
public:
1212+
virtual NullablePtr<Decl> getDeclIfAny() const override { return decl; }
1213+
Decl *getDecl() const { return decl; }
1214+
1215+
protected:
1216+
NullablePtr<const GenericParamList> genericParams() const override;
1217+
};
1218+
11901219
class AbstractStmtScope : public ASTScopeImpl {
11911220
public:
11921221
SourceRange

include/swift/AST/Decl.h

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8278,41 +8278,41 @@ class MissingMemberDecl : public Decl {
82788278
/// representation in the source code, but are still declarations.
82798279
class MacroDecl : public GenericContext, public ValueDecl {
82808280
public:
8281-
/// The kind of macro, which determines how it can be used in source code.
8282-
enum Kind: uint8_t {
8283-
/// An expression macro.
8284-
Expression,
8285-
};
8281+
/// The location of the 'macro' keyword.
8282+
SourceLoc macroLoc;
82868283

8287-
/// Describes how the macro is implemented.
8288-
enum class ImplementationKind: uint8_t {
8289-
/// The macro is built-in to the compiler, linked against the same
8290-
/// underlying syntax tree libraries.
8291-
Builtin,
8284+
/// The parameter list for a function-like macro.
8285+
ParameterList *parameterList;
82928286

8293-
/// The macro was defined in a compiler plugin.
8294-
Plugin,
8295-
};
8287+
/// Where the '->' or ':' is located, for a function- or value-like macro,
8288+
/// respectively.
8289+
SourceLoc arrowOrColonLoc;
82968290

8297-
/// The kind of macro.
8298-
const Kind kind;
8291+
/// The result type.
8292+
TypeLoc resultType;
82998293

8300-
/// How the macro is implemented.
8301-
const ImplementationKind implementationKind;
8294+
/// The module name for the external macro definition.
8295+
Identifier externalModuleName;
83028296

8303-
/// Supplemental modules that should be imported when
8304-
const ArrayRef<ModuleDecl *> supplementalSignatureModules;
8297+
/// The location of the module name for the external macro definition.
8298+
SourceLoc externalModuleNameLoc;
83058299

8306-
/// An opaque handle to the representation of the macro.
8307-
void * const opaqueHandle;
8300+
/// The type name for the external macro definition.
8301+
Identifier externalMacroTypeName;
83088302

8309-
public:
8310-
MacroDecl(
8311-
Kind kind, ImplementationKind implementationKind, Identifier name,
8312-
ModuleDecl *owningModule,
8313-
ArrayRef<ModuleDecl *> supplementalSignatureModules,
8314-
void *opaqueHandle
8315-
);
8303+
/// The location of the type name for the external macro definition.
8304+
SourceLoc externalMacroTypeNameLoc;
8305+
8306+
MacroDecl(SourceLoc macroLoc, DeclName name, SourceLoc nameLoc,
8307+
GenericParamList *genericParams,
8308+
ParameterList *parameterList,
8309+
SourceLoc arrowOrColonLoc,
8310+
TypeRepr *resultType,
8311+
Identifier externalModuleName,
8312+
SourceLoc externalModuleNameLoc,
8313+
Identifier externalMacroTypeName,
8314+
SourceLoc externalMacroTypeNameLoc,
8315+
DeclContext *parent);
83168316

83178317
SourceRange getSourceRange() const;
83188318

@@ -8479,6 +8479,8 @@ inline bool ValueDecl::hasCurriedSelf() const {
84798479
inline bool ValueDecl::hasParameterList() const {
84808480
if (auto *eed = dyn_cast<EnumElementDecl>(this))
84818481
return eed->hasAssociatedValues();
8482+
if (auto *macro = dyn_cast<MacroDecl>(this))
8483+
return macro->parameterList != nullptr;
84828484
return isa<AbstractFunctionDecl>(this) || isa<SubscriptDecl>(this);
84838485
}
84848486

include/swift/AST/DiagnosticsParse.def

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2006,15 +2006,17 @@ ERROR(expected_macro_value_type,PointsToFirstBadToken,
20062006
ERROR(no_default_arg_macro,none,
20072007
"default arguments are not allowed in macros", ())
20082008
ERROR(expected_lparen_macro,PointsToFirstBadToken,
2009-
"expected '(' for macro parameters or ':' for a value-like macro''", ())
2010-
ERROR(macro_decl_expected_arrow,none,
2011-
"expected '->' after macro parameter list", ())
2009+
"expected '(' for macro parameters or ':' for a value-like macro", ())
20122010
ERROR(expected_type_macro_result,PointsToFirstBadToken,
20132011
"expected macro result type", ())
2014-
ERROR(macro_decl_expected_equal,none,
2012+
ERROR(macro_decl_expected_equal,PointsToFirstBadToken,
20152013
"expected '=' to introduce external macro name", ())
2016-
ERROR(macro_decl_expected_period,none,
2014+
ERROR(macro_decl_expected_macro_module,PointsToFirstBadToken,
2015+
"expected external macro name", ())
2016+
ERROR(macro_decl_expected_period,PointsToFirstBadToken,
20172017
"expected '.' between external macro module and type name", ())
2018+
ERROR(macro_decl_expected_macro_type,PointsToFirstBadToken,
2019+
"expected external macro type name", ())
20182020

20192021
ERROR(macro_expansion_expr_expected_macro_identifier,none,
20202022
"expected a macro identifier for a pound literal expression", ())

include/swift/AST/Expr.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6021,6 +6021,9 @@ class MacroExpansionExpr final : public Expr {
60216021
ArgumentList *ArgList;
60226022
Expr *Rewritten;
60236023

6024+
/// The referenced macro.
6025+
ConcreteDeclRef macroRef;
6026+
60246027
public:
60256028
explicit MacroExpansionExpr(SourceLoc poundLoc, DeclNameRef macroName,
60266029
DeclNameLoc macroNameLoc,
@@ -6053,6 +6056,9 @@ class MacroExpansionExpr final : public Expr {
60536056

60546057
SourceLoc getLoc() const { return PoundLoc; }
60556058

6059+
ConcreteDeclRef getMacroRef() const { return macroRef; }
6060+
void setMacroRef(ConcreteDeclRef ref) { macroRef = ref; }
6061+
60566062
SourceRange getSourceRange() const;
60576063

60586064
static bool classof(const Expr *E) {

include/swift/AST/MacroDefinition.h

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//===--- MacroDefinition.h - Swift Macro Definition -------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 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 provides the definition of a macro, which gives access to its
14+
// implementation.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef SWIFT_AST_MACRO_DEFINITION_H
19+
#define SWIFT_AST_MACRO_DEFINITION_H
20+
21+
#include "llvm/ADT/PointerUnion.h"
22+
23+
namespace swift {
24+
25+
class CompilerPlugin;
26+
27+
/// Provides the definition of a macro.
28+
struct MacroDefinition {
29+
/// The kind of macro, which determines how it can be used in source code.
30+
enum Kind: uint8_t {
31+
/// An expression macro.
32+
Expression,
33+
};
34+
35+
/// Describes how the macro is implemented.
36+
enum class ImplementationKind: uint8_t {
37+
/// The macro is built-in to the compiler, linked against the same
38+
/// underlying syntax tree libraries.
39+
Builtin,
40+
41+
/// The macro was defined in a compiler plugin.
42+
Plugin,
43+
};
44+
45+
public:
46+
Kind kind;
47+
ImplementationKind implKind;
48+
49+
private:
50+
void *opaqueHandle;
51+
52+
MacroDefinition(Kind kind, ImplementationKind implKind, void *opaqueHandle)
53+
: kind(kind), implKind(implKind), opaqueHandle(opaqueHandle) { }
54+
55+
public:
56+
static MacroDefinition forInvalid() {
57+
return MacroDefinition{
58+
Kind::Expression, ImplementationKind::Builtin, nullptr
59+
};
60+
}
61+
62+
static MacroDefinition forBuiltin(Kind kind, void *opaqueHandle) {
63+
return MacroDefinition{kind, ImplementationKind::Builtin, opaqueHandle};
64+
}
65+
66+
static MacroDefinition forCompilerPlugin(Kind kind, CompilerPlugin *plugin) {
67+
return MacroDefinition{kind, ImplementationKind::Plugin, plugin};
68+
}
69+
70+
bool isInvalid() const { return opaqueHandle == nullptr; }
71+
72+
explicit operator bool() const { return !isInvalid(); }
73+
74+
void *getAsBuiltin() const {
75+
switch (implKind) {
76+
case ImplementationKind::Builtin:
77+
return opaqueHandle;
78+
79+
case ImplementationKind::Plugin:
80+
return nullptr;
81+
}
82+
}
83+
84+
CompilerPlugin *getAsCompilerPlugin() const {
85+
switch (implKind) {
86+
case ImplementationKind::Builtin:
87+
return nullptr;
88+
89+
case ImplementationKind::Plugin:
90+
return (CompilerPlugin *)opaqueHandle;
91+
}
92+
}
93+
};
94+
95+
}
96+
97+
#endif // SWIFT_AST_MACRO_DEFINITION_H

include/swift/AST/TypeCheckRequests.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class DefaultArgumentExpr;
4545
class DefaultArgumentType;
4646
class ClosureExpr;
4747
class GenericParamList;
48-
class Macro;
48+
struct MacroDefinition;
4949
class PrecedenceGroupDecl;
5050
class PropertyWrapperInitializerInfo;
5151
struct PropertyWrapperLValueness;
@@ -3715,22 +3715,23 @@ class GetTypeWrapperInitializer
37153715
bool isCached() const { return true; }
37163716
};
37173717

3718-
/// Lookup all macros with the given name that are visible from the given
3719-
/// module.
3720-
class MacroLookupRequest
3721-
: public SimpleRequest<MacroLookupRequest,
3722-
ArrayRef<MacroDecl *>(Identifier, ModuleDecl *),
3718+
/// Find the definition of a given macro.
3719+
class MacroDefinitionRequest
3720+
: public SimpleRequest<MacroDefinitionRequest,
3721+
MacroDefinition(MacroDecl *),
37233722
RequestFlags::Cached> {
37243723
public:
37253724
using SimpleRequest::SimpleRequest;
37263725

37273726
private:
37283727
friend SimpleRequest;
37293728

3730-
ArrayRef<MacroDecl *> evaluate(Evaluator &evaluator,
3731-
Identifier macroName, ModuleDecl *mod) const;
3729+
MacroDefinition evaluate(Evaluator &evaluator, MacroDecl *macro) const;
37323730

37333731
public:
3732+
// Source location
3733+
SourceLoc getNearestLoc() const;
3734+
37343735
bool isCached() const { return true; }
37353736
};
37363737

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,6 @@ SWIFT_REQUEST(TypeChecker, SynthesizeLocalVariableForTypeWrapperStorage,
437437
SWIFT_REQUEST(TypeChecker, GetTypeWrapperInitializer,
438438
ConstructorDecl *(NominalTypeDecl *),
439439
Cached, NoLocationInfo)
440-
SWIFT_REQUEST(TypeChecker, MacroLookupRequest,
441-
ArrayRef<Macro *>(Identifier, ModuleDecl *),
440+
SWIFT_REQUEST(TypeChecker, MacroDefinitionRequest,
441+
MacroDefinition(MacroDecl *),
442442
Cached, NoLocationInfo)

lib/AST/ASTScope.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ DEFINE_GET_CLASS_NAME(SpecializeAttributeScope)
150150
DEFINE_GET_CLASS_NAME(DifferentiableAttributeScope)
151151
DEFINE_GET_CLASS_NAME(SubscriptDeclScope)
152152
DEFINE_GET_CLASS_NAME(EnumElementScope)
153+
DEFINE_GET_CLASS_NAME(MacroDeclScope)
153154
DEFINE_GET_CLASS_NAME(IfStmtScope)
154155
DEFINE_GET_CLASS_NAME(WhileStmtScope)
155156
DEFINE_GET_CLASS_NAME(GuardStmtScope)

lib/AST/ASTScopeCreation.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,6 @@ class NodeAdder
289289
VISIT_AND_IGNORE(ParamDecl)
290290
VISIT_AND_IGNORE(PoundDiagnosticDecl)
291291
VISIT_AND_IGNORE(MissingMemberDecl)
292-
VISIT_AND_IGNORE(MacroDecl)
293292
VISIT_AND_IGNORE(MacroExpansionDecl)
294293

295294
// Only members of the active clause are in scope, and those
@@ -325,6 +324,7 @@ class NodeAdder
325324
VISIT_AND_CREATE(ForEachStmt, ForEachStmtScope)
326325
VISIT_AND_CREATE(CaseStmt, CaseStmtScope)
327326
VISIT_AND_CREATE(AbstractFunctionDecl, AbstractFunctionDeclScope)
327+
VISIT_AND_CREATE(MacroDecl, MacroDeclScope)
328328

329329
#undef VISIT_AND_CREATE
330330

@@ -682,6 +682,7 @@ NO_NEW_INSERTION_POINT(ForEachStmtScope)
682682
NO_NEW_INSERTION_POINT(IfStmtScope)
683683
NO_NEW_INSERTION_POINT(RepeatWhileScope)
684684
NO_NEW_INSERTION_POINT(SubscriptDeclScope)
685+
NO_NEW_INSERTION_POINT(MacroDeclScope)
685686
NO_NEW_INSERTION_POINT(SwitchStmtScope)
686687
NO_NEW_INSERTION_POINT(WhileStmtScope)
687688

@@ -1068,6 +1069,17 @@ void SubscriptDeclScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
10681069
scopeCreator.addChildrenForParsedAccessors(decl, leaf);
10691070
}
10701071

1072+
void MacroDeclScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
1073+
ScopeCreator &scopeCreator) {
1074+
scopeCreator.addChildrenForKnownAttributes(decl, this);
1075+
auto *leaf = scopeCreator.addNestedGenericParamScopesToTree(
1076+
decl, getPotentiallyOpaqueGenericParams(decl), this);
1077+
if (decl->parameterList) {
1078+
scopeCreator.constructExpandAndInsert<ParameterListScope>(
1079+
leaf, decl->parameterList, nullptr);
1080+
}
1081+
}
1082+
10711083
void CaptureListScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
10721084
ScopeCreator &scopeCreator) {
10731085
auto *closureExpr = expr->getClosureBody();

lib/AST/ASTScopeLookup.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ NullablePtr<const GenericParamList> GenericTypeScope::genericParams() const {
189189
NullablePtr<const GenericParamList> ExtensionScope::genericParams() const {
190190
return decl->getGenericParams();
191191
}
192+
NullablePtr<const GenericParamList> MacroDeclScope::genericParams() const {
193+
return decl->getParsedGenericParams();
194+
}
192195

193196
#pragma mark lookInMyGenericParameters
194197

lib/AST/ASTScopePrinting.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ void SubscriptDeclScope::printSpecifics(llvm::raw_ostream &out) const {
178178
decl->dumpRef(out);
179179
}
180180

181+
void MacroDeclScope::printSpecifics(llvm::raw_ostream &out) const {
182+
decl->dumpRef(out);
183+
}
184+
181185
void ConditionalClausePatternUseScope::printSpecifics(
182186
llvm::raw_ostream &out) const {
183187
sec.getPattern()->print(out);

lib/AST/ASTScopeSourceRange.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ SourceRange SubscriptDeclScope::getSourceRangeOfThisASTNode(
122122
return decl->getSourceRangeIncludingAttrs();
123123
}
124124

125+
SourceRange MacroDeclScope::getSourceRangeOfThisASTNode(
126+
const bool omitAssertions) const {
127+
return decl->getSourceRangeIncludingAttrs();
128+
}
129+
125130
SourceRange
126131
EnumElementScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
127132
return decl->getSourceRange();

0 commit comments

Comments
 (0)