Skip to content

Commit 94903f0

Browse files
authored
Merge pull request #65469 from DougGregor/macro-mangle-not-initializer-5.9
2 parents 5eb769e + b01b44f commit 94903f0

File tree

7 files changed

+111
-7
lines changed

7 files changed

+111
-7
lines changed

include/swift/AST/MacroDiscriminatorContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ struct MacroDiscriminatorContext
3131
static MacroDiscriminatorContext getParentOf(
3232
SourceLoc loc, DeclContext *origDC
3333
);
34+
35+
/// Return the innermost declaration context that is suitable for
36+
/// use in identifying a macro.
37+
static DeclContext *getInnermostMacroContext(DeclContext *dc);
3438
};
3539

3640
}

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: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3845,6 +3845,8 @@ std::string ASTMangler::mangleRuntimeAttributeGeneratorEntity(
38453845
void ASTMangler::appendMacroExpansionContext(
38463846
SourceLoc loc, DeclContext *origDC
38473847
) {
3848+
origDC = MacroDiscriminatorContext::getInnermostMacroContext(origDC);
3849+
38483850
if (loc.isInvalid())
38493851
return appendContext(origDC, StringRef());
38503852

@@ -3992,10 +3994,41 @@ void ASTMangler::appendMacroExpansionOperator(
39923994
}
39933995
}
39943996

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+
39954023
std::string ASTMangler::mangleMacroExpansion(
39964024
const MacroExpansionExpr *expansion) {
39974025
beginMangling();
39984026
appendMacroExpansionContext(expansion->getLoc(), expansion->getDeclContext());
4027+
auto privateDiscriminator = getPrivateDiscriminatorIfNecessary(expansion);
4028+
if (!privateDiscriminator.empty()) {
4029+
appendIdentifier(privateDiscriminator);
4030+
appendOperator("Ll");
4031+
}
39994032
appendMacroExpansionOperator(
40004033
expansion->getMacroName().getBaseName().userFacingName(),
40014034
MacroRole::Expression,

lib/AST/Decl.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10491,9 +10491,50 @@ ArrayRef<CustomAttr *> Decl::getRuntimeDiscoverableAttrs() const {
1049110491
nullptr);
1049210492
}
1049310493

10494+
/// Adjust the declaration context to find a point in the context hierarchy
10495+
/// that the macro can be anchored on.
10496+
DeclContext *
10497+
MacroDiscriminatorContext::getInnermostMacroContext(DeclContext *dc) {
10498+
switch (dc->getContextKind()) {
10499+
case DeclContextKind::SubscriptDecl:
10500+
case DeclContextKind::EnumElementDecl:
10501+
case DeclContextKind::AbstractFunctionDecl:
10502+
case DeclContextKind::SerializedLocal:
10503+
case DeclContextKind::Package:
10504+
case DeclContextKind::Module:
10505+
case DeclContextKind::FileUnit:
10506+
case DeclContextKind::GenericTypeDecl:
10507+
case DeclContextKind::ExtensionDecl:
10508+
case DeclContextKind::MacroDecl:
10509+
// These contexts are always fine
10510+
return dc;
10511+
10512+
case DeclContextKind::TopLevelCodeDecl:
10513+
// For top-level code, use the enclosing source file as the context.
10514+
return getInnermostMacroContext(dc->getParent());
10515+
10516+
case DeclContextKind::AbstractClosureExpr: {
10517+
// For closures, we can mangle the closure if we're in a context we can
10518+
// mangle. Check that context.
10519+
auto adjustedParentDC = getInnermostMacroContext(dc->getParent());
10520+
if (adjustedParentDC == dc->getParent())
10521+
return dc;
10522+
10523+
return adjustedParentDC;
10524+
}
10525+
10526+
case DeclContextKind::Initializer:
10527+
// Initializers can be part of inferring types for variables, so we need
10528+
// their context.
10529+
return getInnermostMacroContext(dc->getParent());
10530+
}
10531+
}
10532+
1049410533
/// Retrieve the parent discriminator context for the given macro.
1049510534
MacroDiscriminatorContext MacroDiscriminatorContext::getParentOf(
1049610535
SourceLoc loc, DeclContext *origDC) {
10536+
origDC = getInnermostMacroContext(origDC);
10537+
1049710538
if (loc.isInvalid())
1049810539
return origDC;
1049910540

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: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,15 @@
11
#anonymousTypes { "hello2" }
2+
3+
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: 9 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
@@ -64,3 +68,8 @@ struct HasInnerClosure {
6468
func testArbitraryAtGlobal() {
6569
_ = MyIntGlobal16()
6670
}
71+
72+
@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)