Skip to content

Commit 0eb095b

Browse files
committed
[Macros] Use private discriminators for expression macros
Expression macros ascribed to non-private contexts need private discriminators so they don't conflict with other uses of the same macro in other source files. Thank you, Richard, for noticing this omission!
1 parent 28d24a1 commit 0eb095b

File tree

4 files changed

+41
-8
lines changed

4 files changed

+41
-8
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() const;
500500
Optional<ExternalSourceLocs::RawLocs>
501501
getExternalRawLocsForDecl(const Decl *D) const override;
502502

lib/AST/ASTMangler.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3994,10 +3994,40 @@ 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 = sf->getPrivateDiscriminator();
4013+
assert(!discriminator.empty());
4014+
assert(!isNonAscii(discriminator.str()) &&
4015+
"discriminator contains non-ASCII characters");
4016+
(void)&isNonAscii;
4017+
assert(!clang::isDigit(discriminator.str().front()) &&
4018+
"not a valid identifier");
4019+
return discriminator.str();
4020+
}
4021+
39974022
std::string ASTMangler::mangleMacroExpansion(
39984023
const MacroExpansionExpr *expansion) {
39994024
beginMangling();
40004025
appendMacroExpansionContext(expansion->getLoc(), expansion->getDeclContext());
4026+
auto privateDiscriminator = getPrivateDiscriminatorIfNecessary(expansion);
4027+
if (!privateDiscriminator.empty()) {
4028+
appendIdentifier(privateDiscriminator);
4029+
appendOperator("Ll");
4030+
}
40014031
appendMacroExpansionOperator(
40024032
expansion->getMacroName().getBaseName().userFacingName(),
40034033
MacroRole::Expression,

lib/AST/Module.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3852,11 +3852,7 @@ 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-
3855+
Identifier SourceFile::getPrivateDiscriminator() const {
38603856
if (!PrivateDiscriminator.empty())
38613857
return PrivateDiscriminator;
38623858

@@ -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();
3898+
}
3899+
38973900
SynthesizedFileUnit *FileUnit::getSynthesizedFile() const {
38983901
return cast_or_null<SynthesizedFileUnit>(SynthesizedFileAndKind.getPointer());
38993902
}

test/Macros/top_level_freestanding.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,5 @@ func testArbitraryAtGlobal() {
7171

7272
@freestanding(expression) macro stringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro")
7373

74-
// DIAG_BUFFERS: @__swiftmacro_9MacroUser9stringifyfMf1_{{.*}}warning: 'deprecated()' is deprecated
75-
// DIAG_BUFFERS: @__swiftmacro_9MacroUser9stringifyfMf2_{{.*}}warning: 'deprecated()' is deprecated
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)