Skip to content

Commit 7c7459a

Browse files
authored
Merge pull request #64641 from DougGregor/macro-replacement-expansion
2 parents 06f5a96 + 68b367b commit 7c7459a

38 files changed

+697
-125
lines changed

include/swift/AST/ASTScope.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,6 +1215,26 @@ class MacroDeclScope final : public ASTScopeImpl {
12151215

12161216
protected:
12171217
NullablePtr<const GenericParamList> genericParams() const override;
1218+
bool lookupLocalsOrMembers(DeclConsumer) const override;
1219+
};
1220+
1221+
/// The scope introduced for the definition of a macro, which follows the `=`.
1222+
class MacroDefinitionScope final : public ASTScopeImpl {
1223+
public:
1224+
Expr *const definition;
1225+
1226+
MacroDefinitionScope(Expr *definition) : definition(definition) {}
1227+
1228+
virtual ~MacroDefinitionScope() {}
1229+
SourceRange
1230+
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
1231+
std::string getClassName() const override;
1232+
1233+
private:
1234+
void expandAScopeThatDoesNotCreateANewInsertionPoint(ScopeCreator &);
1235+
1236+
protected:
1237+
ASTScopeImpl *expandSpecifically(ScopeCreator &scopeCreator) override;
12181238
};
12191239

12201240
class AbstractStmtScope : public ASTScopeImpl {

include/swift/AST/CASTBridging.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,16 @@ typedef enum ENUM_EXTENSIBILITY_ATTR(open) BridgedDiagnosticSeverity : long {
102102

103103
typedef void* BridgedDiagnostic;
104104

105+
typedef enum ENUM_EXTENSIBILITY_ATTR(open) BridgedMacroDefinitionKind : ptrdiff_t {
106+
/// An expanded macro.
107+
BridgedExpandedMacro = 0,
108+
/// An external macro, spelled with either the old spelling (Module.Type)
109+
/// or the new spelling `#externalMacro(module: "Module", type: "Type")`.
110+
BridgedExternalMacro,
111+
/// The builtin definition for "externalMacro".
112+
BridgedBuiltinExternalMacro
113+
} BridgedMacroDefinitionKind;
114+
105115
#ifdef __cplusplus
106116
extern "C" {
107117

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7005,13 +7005,6 @@ ERROR(macro_unsupported,none,
70057005
"macros are not supported in this compiler", ())
70067006
ERROR(macro_recursive,none,
70077007
"recursive expansion of macro %0", (DeclName))
7008-
WARNING(macro_definition_old_style,none,
7009-
"external macro definitions are now written using #externalMacro", ())
7010-
WARNING(macro_definition_unknown_builtin,none,
7011-
"ignoring definition of unknown builtin macro %0", (Identifier))
7012-
ERROR(macro_definition_not_expansion,none,
7013-
"macro must itself be defined by a macro expansion such as "
7014-
"'#externalMacro(...)'", ())
70157008
ERROR(macro_definition_unsupported,none,
70167009
"macro definitions other than '#externalMacro(...)' are unsupported", ())
70177010
ERROR(external_macro_arg_not_type_name,none,

include/swift/AST/MacroDefinition.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
namespace swift {
2424

25+
class ASTContext;
26+
2527
/// A reference to an external macro definition that is understood by ASTGen.
2628
struct ExternalMacroDefinition {
2729
enum class PluginKind {
@@ -46,6 +48,35 @@ enum class BuiltinMacroKind: uint8_t {
4648
ExternalMacro,
4749
};
4850

51+
/// A single replacement
52+
struct ExpandedMacroReplacement {
53+
unsigned startOffset, endOffset;
54+
unsigned parameterIndex;
55+
};
56+
57+
/// An expansion of another macro.
58+
class ExpandedMacroDefinition {
59+
friend class MacroDefinition;
60+
61+
/// The expansion text, ASTContext-allocated.
62+
StringRef expansionText;
63+
64+
/// The macro replacements, ASTContext-allocated.
65+
ArrayRef<ExpandedMacroReplacement> replacements;
66+
67+
ExpandedMacroDefinition(
68+
StringRef expansionText,
69+
ArrayRef<ExpandedMacroReplacement> replacements
70+
) : expansionText(expansionText), replacements(replacements) { }
71+
72+
public:
73+
StringRef getExpansionText() const { return expansionText; }
74+
75+
ArrayRef<ExpandedMacroReplacement> getReplacements() const {
76+
return replacements;
77+
}
78+
};
79+
4980
/// Provides the definition of a macro.
5081
class MacroDefinition {
5182
public:
@@ -63,6 +94,9 @@ class MacroDefinition {
6394

6495
/// A builtin macro definition, which has a separate builtin kind.
6596
Builtin,
97+
98+
/// A macro that is defined as an expansion of another macro.
99+
Expanded,
66100
};
67101

68102
Kind kind;
@@ -71,6 +105,7 @@ class MacroDefinition {
71105
union Data {
72106
ExternalMacroReference external;
73107
BuiltinMacroKind builtin;
108+
ExpandedMacroDefinition expanded;
74109

75110
Data() : builtin(BuiltinMacroKind::ExternalMacro) { }
76111
} data;
@@ -85,6 +120,10 @@ class MacroDefinition {
85120
data.builtin = builtinKind;
86121
}
87122

123+
MacroDefinition(ExpandedMacroDefinition expanded) : kind(Kind::Expanded) {
124+
data.expanded = expanded;
125+
}
126+
88127
public:
89128
static MacroDefinition forInvalid() {
90129
return MacroDefinition(Kind::Invalid);
@@ -105,6 +144,13 @@ class MacroDefinition {
105144
return MacroDefinition(builtinKind);
106145
}
107146

147+
/// Create a representation of an expanded macro definition.
148+
static MacroDefinition forExpanded(
149+
ASTContext &ctx,
150+
StringRef expansionText,
151+
ArrayRef<ExpandedMacroReplacement> replacements
152+
);
153+
108154
/// Retrieve the external macro being referenced.
109155
ExternalMacroReference getExternalMacro() const {
110156
assert(kind == Kind::External);
@@ -117,6 +163,11 @@ class MacroDefinition {
117163
return data.builtin;
118164
}
119165

166+
ExpandedMacroDefinition getExpanded() const {
167+
assert(kind == Kind::Expanded);
168+
return data.expanded;
169+
}
170+
120171
operator Kind() const { return kind; }
121172
};
122173

include/swift/Basic/Features.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,11 @@ SUPPRESSIBLE_LANGUAGE_FEATURE(PrimaryAssociatedTypes2, 346, "Primary associated
9494
SUPPRESSIBLE_LANGUAGE_FEATURE(UnavailableFromAsync, 0, "@_unavailableFromAsync", true)
9595
SUPPRESSIBLE_LANGUAGE_FEATURE(NoAsyncAvailability, 340, "@available(*, noasync)", true)
9696
LANGUAGE_FEATURE(BuiltinIntLiteralAccessors, 368, "Builtin.IntLiteral accessors", true)
97-
LANGUAGE_FEATURE(Macros, 0, "Macros", true)
97+
LANGUAGE_FEATURE(Macros, 0, "Macros", hasSwiftSwiftParser)
9898
SUPPRESSIBLE_LANGUAGE_FEATURE(
9999
FreestandingExpressionMacros, 382, "Expression macros",
100-
true)
101-
LANGUAGE_FEATURE(AttachedMacros, 389, "Attached macros", true)
100+
hasSwiftSwiftParser)
101+
LANGUAGE_FEATURE(AttachedMacros, 389, "Attached macros", hasSwiftSwiftParser)
102102
LANGUAGE_FEATURE(MoveOnly, 390, "noncopyable types", true)
103103

104104
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)

include/swift/Basic/StringExtras.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ class NullTerminatedStringRef {
490490

491491
/// Create a null-terminated string, copying \p Str into \p A .
492492
template <typename Allocator>
493-
NullTerminatedStringRef(StringRef Str, Allocator &A) : Ref("") {
493+
NullTerminatedStringRef(StringRef Str, Allocator &A) : Ref() {
494494
if (Str.empty())
495495
return;
496496

lib/AST/ASTMangler.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3869,12 +3869,14 @@ void ASTMangler::appendMacroExpansionContext(
38693869
baseName = expr->getMacroName().getBaseName();
38703870
discriminator = expr->getDiscriminator();
38713871
role = MacroRole::Expression;
3872+
outerExpansionDC = expr->getDeclContext();
38723873
} else {
38733874
auto decl = cast<MacroExpansionDecl>(parent.get<Decl *>());
38743875
outerExpansionLoc = decl->getLoc();
38753876
baseName = decl->getMacroName().getBaseName();
38763877
discriminator = decl->getDiscriminator();
38773878
role = MacroRole::Declaration;
3879+
outerExpansionDC = decl->getDeclContext();
38783880
}
38793881
break;
38803882
}

lib/AST/ASTPrinter.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4758,8 +4758,8 @@ void PrintAST::visitMacroDecl(MacroDecl *decl) {
47584758

47594759
case MacroDefinition::Kind::External: {
47604760
auto external = def.getExternalMacro();
4761-
Printer << " = #externalMacro(module: \"" << external.moduleName << "\", "
4762-
<< "type: \"" << external.macroTypeName << "\")";
4761+
Printer << " = #externalMacro(module: \"" << external.moduleName
4762+
<< "\", " << "type: \"" << external.macroTypeName << "\")";
47634763
break;
47644764
}
47654765

@@ -4771,6 +4771,10 @@ void PrintAST::visitMacroDecl(MacroDecl *decl) {
47714771
break;
47724772
}
47734773
break;
4774+
4775+
case MacroDefinition::Kind::Expanded:
4776+
Printer << " = " << def.getExpanded().getExpansionText();
4777+
break;
47744778
}
47754779
}
47764780
}

lib/AST/ASTScope.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ DEFINE_GET_CLASS_NAME(DifferentiableAttributeScope)
151151
DEFINE_GET_CLASS_NAME(SubscriptDeclScope)
152152
DEFINE_GET_CLASS_NAME(EnumElementScope)
153153
DEFINE_GET_CLASS_NAME(MacroDeclScope)
154+
DEFINE_GET_CLASS_NAME(MacroDefinitionScope)
154155
DEFINE_GET_CLASS_NAME(IfStmtScope)
155156
DEFINE_GET_CLASS_NAME(WhileStmtScope)
156157
DEFINE_GET_CLASS_NAME(GuardStmtScope)

lib/AST/ASTScopeCreation.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,7 @@ NO_NEW_INSERTION_POINT(IfStmtScope)
723723
NO_NEW_INSERTION_POINT(RepeatWhileScope)
724724
NO_NEW_INSERTION_POINT(SubscriptDeclScope)
725725
NO_NEW_INSERTION_POINT(MacroDeclScope)
726+
NO_NEW_INSERTION_POINT(MacroDefinitionScope)
726727
NO_NEW_INSERTION_POINT(SwitchStmtScope)
727728
NO_NEW_INSERTION_POINT(WhileStmtScope)
728729

@@ -1115,9 +1116,19 @@ void MacroDeclScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
11151116
auto *leaf = scopeCreator.addNestedGenericParamScopesToTree(
11161117
decl, getPotentiallyOpaqueGenericParams(decl), this);
11171118
if (decl->parameterList) {
1118-
scopeCreator.constructExpandAndInsert<ParameterListScope>(
1119+
leaf = scopeCreator.constructExpandAndInsert<ParameterListScope>(
11191120
leaf, decl->parameterList, nullptr);
11201121
}
1122+
if (auto def = decl->definition) {
1123+
scopeCreator
1124+
.constructExpandAndInsert<MacroDefinitionScope>(leaf, def);
1125+
}
1126+
}
1127+
1128+
void
1129+
MacroDefinitionScope::expandAScopeThatDoesNotCreateANewInsertionPoint(
1130+
ScopeCreator &scopeCreator) {
1131+
scopeCreator.addToScopeTree(ASTNode(definition), this);
11211132
}
11221133

11231134
void CaptureListScope::expandAScopeThatDoesNotCreateANewInsertionPoint(

lib/AST/ASTScopeLookup.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,17 @@ NullablePtr<const GenericParamList> MacroDeclScope::genericParams() const {
260260
return decl->getParsedGenericParams();
261261
}
262262

263+
bool MacroDeclScope::lookupLocalsOrMembers(
264+
DeclConsumer consumer) const {
265+
if (auto *paramList = decl->parameterList) {
266+
for (auto *paramDecl : *paramList)
267+
if (consumer.consume({paramDecl}))
268+
return true;
269+
}
270+
271+
return false;
272+
}
273+
263274
#pragma mark lookInMyGenericParameters
264275

265276
std::pair<bool, NullablePtr<const GenericParamList>>

lib/AST/ASTScopeSourceRange.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,11 @@ SourceRange MacroDeclScope::getSourceRangeOfThisASTNode(
143143
return decl->getSourceRangeIncludingAttrs();
144144
}
145145

146+
SourceRange MacroDefinitionScope::getSourceRangeOfThisASTNode(
147+
const bool omitAssertions) const {
148+
return definition->getSourceRange();
149+
}
150+
146151
SourceRange
147152
EnumElementScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
148153
return decl->getSourceRange();

lib/AST/ASTVerifier.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ class Verifier : public ASTWalker {
477477
// For @objc enums, we serialize the pre-type-checked integer
478478
// literal raw values, and thus when they are deserialized
479479
// they do not have a type on them.
480-
if (!isa<IntegerLiteralExpr>(E)) {
480+
if (!isa<IntegerLiteralExpr>(E) && !isa<MacroExpansionExpr>(E)) {
481481
Out << "expression has no type\n";
482482
E->dump(Out);
483483
abort();
@@ -769,6 +769,7 @@ class Verifier : public ASTWalker {
769769
FUNCTION_LIKE(FuncDecl)
770770
FUNCTION_LIKE(EnumElementDecl)
771771
FUNCTION_LIKE(SubscriptDecl)
772+
FUNCTION_LIKE(MacroDecl)
772773
TYPE_LIKE(NominalTypeDecl)
773774
TYPE_LIKE(ExtensionDecl)
774775

lib/AST/ASTWalker.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,18 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
422422
return true;
423423
}
424424

425+
if (auto def = MD->definition) {
426+
// Don't walk into unchecked definitions.
427+
if (auto expansion = dyn_cast<MacroExpansionExpr>(def)) {
428+
if (!expansion->getType().isNull()) {
429+
if (auto newDef = doIt(def))
430+
MD->definition = newDef;
431+
else
432+
return true;
433+
}
434+
}
435+
}
436+
425437
// Visit trailing requirements
426438
if (WalkGenerics && visitTrailingRequirements(MD))
427439
return true;

lib/AST/Decl.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10326,6 +10326,15 @@ Optional<BuiltinMacroKind> MacroDecl::getBuiltinKind() const {
1032610326
return def.getBuiltinKind();
1032710327
}
1032810328

10329+
MacroDefinition MacroDefinition::forExpanded(
10330+
ASTContext &ctx,
10331+
StringRef expansionText,
10332+
ArrayRef<ExpandedMacroReplacement> replacements
10333+
) {
10334+
return ExpandedMacroDefinition{ctx.AllocateCopy(expansionText),
10335+
ctx.AllocateCopy(replacements)};
10336+
}
10337+
1032910338
MacroExpansionDecl::MacroExpansionDecl(
1033010339
DeclContext *dc, SourceLoc poundLoc, DeclNameRef macro,
1033110340
DeclNameLoc macroLoc, SourceLoc leftAngleLoc,

lib/AST/DistributedDecl.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
#include "clang/AST/Attr.h"
5757
#include "clang/AST/DeclObjC.h"
5858

59-
#include "InlinableText.h"
6059
#include <algorithm>
6160

6261
using namespace swift;

lib/ASTGen/Sources/ASTGen/Diagnostics.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,13 @@ extension SourceManager {
170170

171171
switch change {
172172
case .replace(let oldNode, let newNode):
173-
replaceStartLoc = cxxSourceLocation(for: oldNode)
173+
replaceStartLoc = cxxSourceLocation(
174+
for: oldNode,
175+
at: oldNode.positionAfterSkippingLeadingTrivia
176+
)
174177
replaceEndLoc = cxxSourceLocation(
175178
for: oldNode,
176-
at: oldNode.endPosition
179+
at: oldNode.endPositionBeforeTrailingTrivia
177180
)
178181
newText = newNode.description
179182

0 commit comments

Comments
 (0)