Skip to content

Commit d1705a5

Browse files
hborlarxwei
authored andcommitted
[Macros] Parse top-level freestanding macros as MacroExpansionDecls when not
in script mode.
1 parent 3495638 commit d1705a5

File tree

9 files changed

+53
-32
lines changed

9 files changed

+53
-32
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6928,6 +6928,9 @@ ERROR(literal_type_in_macro_expansion,none,
69286928
ERROR(invalid_macro_introduced_name,none,
69296929
"declaration name %0 is not covered by macro %1",
69306930
(DeclName, DeclName))
6931+
ERROR(global_freestanding_macro_script,none,
6932+
"global freestanding macros not yet supported in script mode",
6933+
())
69316934

69326935
//------------------------------------------------------------------------------
69336936
// MARK: Move Only Errors

lib/AST/ASTWalker.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,9 +1343,6 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
13431343
}
13441344
E->setRewritten(rewritten);
13451345
}
1346-
if (auto *decl = E->getSubstituteDecl())
1347-
if (doIt(decl))
1348-
return nullptr;
13491346
return E;
13501347
}
13511348

lib/AST/Module.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -275,23 +275,6 @@ void SourceLookupCache::addToUnqualifiedLookupCache(Range decls,
275275

276276
else if (auto *MED = dyn_cast<MacroExpansionDecl>(D))
277277
MayHaveAuxiliaryDecls.push_back(MED);
278-
279-
// Top-level macro expansion expressions can actually produce declarations,
280-
// when they resolve to a substitute macro expansion decl.
281-
else if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D)) {
282-
for (auto node : TLCD->getBody()->getElements()) {
283-
if (auto *E = node.dyn_cast<Expr *>()) {
284-
if (auto *MEE = dyn_cast<MacroExpansionExpr>(E)) {
285-
auto *MED = MEE->getSubstituteDecl();
286-
if (!MED) {
287-
MED = MEE->createSubstituteDecl();
288-
MEE->setSubstituteDecl(MED);
289-
}
290-
MayHaveAuxiliaryDecls.push_back(MED);
291-
}
292-
}
293-
}
294-
}
295278
}
296279
}
297280

lib/Parse/ParseDecl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4687,6 +4687,7 @@ bool swift::isKeywordPossibleDeclStart(const LangOptions &options,
46874687
case tok::kw_subscript:
46884688
case tok::kw_typealias:
46894689
case tok::kw_var:
4690+
case tok::pound:
46904691
case tok::pound_if:
46914692
case tok::pound_warning:
46924693
case tok::pound_error:
@@ -4798,6 +4799,11 @@ bool Parser::isStartOfSwiftDecl(bool allowPoundIfAttributes) {
47984799
return isStartOfSwiftDecl(allowPoundIfAttributes);
47994800
}
48004801

4802+
if (Tok.is(tok::pound) && peekToken().is(tok::identifier)) {
4803+
// Macro expansions at the top level are declarations.
4804+
return CurDeclContext->isModuleScopeContext() && !allowTopLevelCode();
4805+
}
4806+
48014807
// Skip a #if that contains only attributes in all branches. These will be
48024808
// parsed as attributes of a declaration, not as separate declarations.
48034809
if (Tok.is(tok::pound_if) && allowPoundIfAttributes) {

lib/SILGen/SILGen.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,13 +1984,6 @@ void SILGenModule::visitTopLevelCodeDecl(TopLevelCodeDecl *td) {
19841984
if (auto *S = ESD.dyn_cast<Stmt*>()) {
19851985
TopLevelSGF->emitStmt(S);
19861986
} else if (auto *E = ESD.dyn_cast<Expr*>()) {
1987-
if (auto *MEE = dyn_cast<MacroExpansionExpr>(E)) {
1988-
if (auto *MED = MEE->getSubstituteDecl()) {
1989-
MED->visitAuxiliaryDecls([&](Decl *decl) {
1990-
visit(decl);
1991-
});
1992-
}
1993-
}
19941987
TopLevelSGF->emitIgnoredExpr(E);
19951988
} else {
19961989
TopLevelSGF->visit(ESD.get<Decl*>());

lib/SILGen/SILGenDecl.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,9 +1450,6 @@ void SILGenFunction::visitMacroExpansionDecl(MacroExpansionDecl *D) {
14501450
MacroScope scope(*this, CleanupLocation(D), D,
14511451
D->getMacroName().getBaseIdentifier().str(),
14521452
D->getMacroRef().getDecl());
1453-
D->visitAuxiliaryDecls([&](Decl *decl) {
1454-
visit(decl);
1455-
});
14561453
D->forEachExpandedExprOrStmt([&](ASTNode node) {
14571454
if (auto *expr = node.dyn_cast<Expr *>())
14581455
emitIgnoredExpr(expr);

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3791,5 +3791,12 @@ ExpandMacroExpansionDeclRequest::evaluate(Evaluator &evaluator,
37913791

37923792
// Otherwise, we treat it as a declaration macro.
37933793
assert(roles.contains(MacroRole::Declaration));
3794+
3795+
// For now, restrict global freestanding macros in script mode.
3796+
if (dc->isModuleScopeContext() &&
3797+
dc->getParentSourceFile()->isScriptMode()) {
3798+
MED->diagnose(diag::global_freestanding_macro_script);
3799+
}
3800+
37943801
return expandFreestandingMacro(MED);
37953802
}

test/Macros/Inputs/syntax_macro_definitions.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,7 +1178,6 @@ public struct DefineAnonymousTypesMacro: DeclarationMacro {
11781178
11791179
class \(context.createUniqueName("name")) {
11801180
func hello() {
1181-
\(body.statements)
11821181
}
11831182
}
11841183
""",
@@ -1189,7 +1188,6 @@ public struct DefineAnonymousTypesMacro: DeclarationMacro {
11891188
case banana
11901189
11911190
func hello() {
1192-
\(body.statements)
11931191
}
11941192
}
11951193
"""
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift -swift-version 5 -parse-as-library -enable-experimental-feature FreestandingMacros -I %swift-host-lib-dir -L %swift-host-lib-dir -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath
3+
// RUNx: %target-swift-frontend -enable-experimental-feature FreestandingMacros -parse-as-library -emit-sil -load-plugin-library %t/%target-library-name(MacroDefinition) -I %swift-host-lib-dir %s -module-name MacroUser 2>&1 | %FileCheck --check-prefix CHECK-SIL %s
4+
// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-experimental-feature FreestandingMacros -parse-as-library -load-plugin-library %t/%target-library-name(MacroDefinition) -I %swift-host-lib-dir -module-name MacroUser -DTEST_DIAGNOSTICS -swift-version 5
5+
// RUN: %target-build-swift -swift-version 5 -enable-experimental-feature FreestandingMacros -parse-as-library -load-plugin-library %t/%target-library-name(MacroDefinition) -I %swift-host-lib-dir -L %swift-host-lib-dir %s -o %t/main -module-name MacroUser -swift-version 5
6+
// RUN: %target-run %t/main | %FileCheck %s
7+
// REQUIRES: executable_test
8+
9+
// FIXME: Swift parser is not enabled on Linux CI yet.
10+
// REQUIRES: OS=macosx
11+
12+
// Test unqualified lookup from within a macro expansion
13+
@freestanding(declaration, names: named(StructWithUnqualifiedLookup))
14+
macro structWithUnqualifiedLookup() = #externalMacro(module: "MacroDefinition", type: "DefineStructWithUnqualifiedLookupMacro")
15+
16+
let world = 3 // to be used by the macro expansion below
17+
18+
#structWithUnqualifiedLookup
19+
20+
func lookupGlobalFreestandingExpansion() {
21+
// CHECK: 4
22+
print(StructWithUnqualifiedLookup().foo())
23+
}
24+
25+
@freestanding(declaration)
26+
macro anonymousTypes(_: () -> String) = #externalMacro(module: "MacroDefinition", type: "DefineAnonymousTypesMacro")
27+
28+
#anonymousTypes { "hello" }
29+
30+
// CHECK-SIL: sil hidden @$s9MacroUser03$s9A35User14anonymousTypesfMf0_4namefMu0_O5helloyyF : $@convention(method) ($s9MacroUser14anonymousTypesfMf0_4namefMu0_) -> () {
31+
32+
@main
33+
struct Main {
34+
static func main() {
35+
lookupGlobalFreestandingExpansion()
36+
}
37+
}

0 commit comments

Comments
 (0)