Skip to content

Commit 6b2d4bd

Browse files
authored
Merge pull request #65476 from DougGregor/expression-macro-private-discriminator
[Macros] Use private discriminators for expression macros
2 parents cb6304c + 7c4547f commit 6b2d4bd

File tree

5 files changed

+60
-7
lines changed

5 files changed

+60
-7
lines changed

include/swift/AST/SourceFile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ class SourceFile final : public FileUnit {
496496
collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const override;
497497

498498
Identifier getDiscriminatorForPrivateDecl(const Decl *D) const override;
499-
Identifier getPrivateDiscriminator() const { return PrivateDiscriminator; }
499+
Identifier getPrivateDiscriminator(bool createIfMissing = false) const;
500500
Optional<ExternalSourceLocs::RawLocs>
501501
getExternalRawLocsForDecl(const Decl *D) const override;
502502

lib/AST/ASTMangler.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3994,10 +3994,41 @@ void ASTMangler::appendMacroExpansionOperator(
39943994
}
39953995
}
39963996

3997+
static StringRef getPrivateDiscriminatorIfNecessary(
3998+
const MacroExpansionExpr *expansion) {
3999+
auto dc = MacroDiscriminatorContext::getInnermostMacroContext(
4000+
expansion->getDeclContext());
4001+
auto decl = dc->getAsDecl();
4002+
if (decl && !decl->isOutermostPrivateOrFilePrivateScope())
4003+
return StringRef();
4004+
4005+
// Mangle non-local private declarations with a textual discriminator
4006+
// based on their enclosing file.
4007+
auto topLevelSubcontext = dc->getModuleScopeContext();
4008+
SourceFile *sf = dyn_cast<SourceFile>(topLevelSubcontext);
4009+
if (!sf)
4010+
return StringRef();
4011+
4012+
Identifier discriminator =
4013+
sf->getPrivateDiscriminator(/*createIfMissing=*/true);
4014+
assert(!discriminator.empty());
4015+
assert(!isNonAscii(discriminator.str()) &&
4016+
"discriminator contains non-ASCII characters");
4017+
(void)&isNonAscii;
4018+
assert(!clang::isDigit(discriminator.str().front()) &&
4019+
"not a valid identifier");
4020+
return discriminator.str();
4021+
}
4022+
39974023
std::string ASTMangler::mangleMacroExpansion(
39984024
const MacroExpansionExpr *expansion) {
39994025
beginMangling();
40004026
appendMacroExpansionContext(expansion->getLoc(), expansion->getDeclContext());
4027+
auto privateDiscriminator = getPrivateDiscriminatorIfNecessary(expansion);
4028+
if (!privateDiscriminator.empty()) {
4029+
appendIdentifier(privateDiscriminator);
4030+
appendOperator("Ll");
4031+
}
40014032
appendMacroExpansionOperator(
40024033
expansion->getMacroName().getBaseName().userFacingName(),
40034034
MacroRole::Expression,

lib/AST/Module.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3852,12 +3852,8 @@ ASTScope &SourceFile::getScope() {
38523852
return *Scope.get();
38533853
}
38543854

3855-
Identifier
3856-
SourceFile::getDiscriminatorForPrivateDecl(const Decl *D) const {
3857-
assert(D->getDeclContext()->getModuleScopeContext() == this ||
3858-
D->getDeclContext()->getModuleScopeContext() == getSynthesizedFile());
3859-
3860-
if (!PrivateDiscriminator.empty())
3855+
Identifier SourceFile::getPrivateDiscriminator(bool createIfMissing) const {
3856+
if (!PrivateDiscriminator.empty() || !createIfMissing)
38613857
return PrivateDiscriminator;
38623858

38633859
StringRef name = getFilename();
@@ -3894,6 +3890,13 @@ SourceFile::getDiscriminatorForPrivateDecl(const Decl *D) const {
38943890
return PrivateDiscriminator;
38953891
}
38963892

3893+
Identifier
3894+
SourceFile::getDiscriminatorForPrivateDecl(const Decl *D) const {
3895+
assert(D->getDeclContext()->getModuleScopeContext() == this ||
3896+
D->getDeclContext()->getModuleScopeContext() == getSynthesizedFile());
3897+
return getPrivateDiscriminator(/*createIfMissing=*/true);
3898+
}
3899+
38973900
SynthesizedFileUnit *FileUnit::getSynthesizedFile() const {
38983901
return cast_or_null<SynthesizedFileUnit>(SynthesizedFileAndKind.getPointer());
38993902
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
11
#anonymousTypes { "hello2" }
22

33
var globalVar = #stringify(1 + 1)
4+
var globalVar2 = { #stringify(1 + 1) }()
5+
6+
@available(*, deprecated)
7+
func deprecated() -> Int { 0 }
8+
9+
var globalVar3 = #stringify({ deprecated() })
10+
// expected-note@-1 2{{in expansion of macro 'stringify' here}}
11+
// expected-warning@-2{{'deprecated()' is deprecated}}
12+
13+
var globalVar4 = #stringify({ deprecated() })
14+
// expected-note@-1 2{{in expansion of macro 'stringify' here}}
15+
// expected-warning@-2{{'deprecated()' is deprecated}}

test/Macros/top_level_freestanding.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
// Type check testing
88
// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-experimental-feature FreestandingMacros -parse-as-library -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -swift-version 5 %S/Inputs/top_level_freestanding_other.swift
99

10+
// Check diagnostic buffer names
11+
// RUN: %target-swift-frontend -typecheck -swift-version 5 -enable-experimental-feature FreestandingMacros -parse-as-library -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -swift-version 5 %s %S/Inputs/top_level_freestanding_other.swift 2> %t.diags
12+
// RUN: %FileCheck -check-prefix DIAG_BUFFERS %s < %t.diags
13+
1014
// Execution testing
1115
// RUN: %target-build-swift -g -swift-version 5 -enable-experimental-feature FreestandingMacros -parse-as-library -load-plugin-library %t/%target-library-name(MacroDefinition) %s %S/Inputs/top_level_freestanding_other.swift -o %t/main -module-name MacroUser -swift-version 5
1216
// RUN: %target-codesign %t/main
@@ -66,3 +70,6 @@ func testArbitraryAtGlobal() {
6670
}
6771

6872
@freestanding(expression) macro stringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro")
73+
74+
// DIAG_BUFFERS: @__swiftmacro_9MacroUser33_{{.*}}9stringifyfMf1_{{.*}}warning: 'deprecated()' is deprecated
75+
// DIAG_BUFFERS: @__swiftmacro_9MacroUser33_{{.*}}9stringifyfMf2_{{.*}}warning: 'deprecated()' is deprecated

0 commit comments

Comments
 (0)